From da8813071ba3cb9ecd3a78e5ff2e6ecd1468d4c7 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Sun, 16 Feb 2020 01:07:48 +0500 Subject: [PATCH 01/12] Docs staging (#4407) * update theme * Update version * Updated Questions section in the footer * Remove links to Riot chat * Typo * Add Discord link Co-authored-by: Marko --- docs/.vuepress/config.js | 16 +---- .../adr-051-double-signing-risk-reduction.md | 2 +- docs/architecture/adr-052-tendermint-mode.md | 2 +- docs/package-lock.json | 62 +++++++++---------- docs/package.json | 11 ++-- 5 files changed, 35 insertions(+), 58 deletions(-) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index dc7a200ce..55613252f 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -19,12 +19,6 @@ module.exports = { gutter: { title: "Help & Support", editLink: true, - chat: { - title: "Riot Chat", - text: "Chat with Tendermint developers on Riot Chat.", - url: "https://riot.im/app/#/room/#tendermint:matrix.org", - bg: "#222" - }, forum: { title: "Tendermint Forum", text: "Join the Tendermint forum to learn more", @@ -38,6 +32,7 @@ module.exports = { } }, footer: { + questionsText: "Chat with Cosmos developers in [Discord](https://discordapp.com/channels/669268347736686612) or reach out on the [SDK Developer Forum](https://forum.cosmos.network/c/tendermint) to learn more.", logo: "/logo-bw.svg", textLink: { text: "tendermint.com", @@ -95,10 +90,6 @@ module.exports = { { title: "Forum", url: "https://forum.cosmos.network/c/tendermint" - }, - { - title: "Chat", - url: "https://riot.im/app/#/room/#tendermint:matrix.org" } ] }, @@ -138,11 +129,6 @@ module.exports = { } ] }, - markdown: { - anchor: { - permalinkSymbol: "" - } - }, plugins: [ [ "@vuepress/google-analytics", diff --git a/docs/architecture/adr-051-double-signing-risk-reduction.md b/docs/architecture/adr-051-double-signing-risk-reduction.md index 04ee41a67..ae663e8b5 100644 --- a/docs/architecture/adr-051-double-signing-risk-reduction.md +++ b/docs/architecture/adr-051-double-signing-risk-reduction.md @@ -27,7 +27,7 @@ We would like to suggest a double signing risk reduction method. 2. If there exists votes from the validator's consensus key, exit state machine program - Configuration - We would like to suggest by introducing `double_sign_check_height` parameter in `config.toml` and cli, how many blocks state machine looks back to check votes - - `double_sign_check_height = {{ .Consensus.DoubleSignCheckHeight }}` in `config.toml` + - `double_sign_check_height = {{ .Consensus.DoubleSignCheckHeight }}` in `config.toml` - `tendermint node --double_sign_check_height` in cli - State machine ignore checking procedure when `vote-check-height == 0` diff --git a/docs/architecture/adr-052-tendermint-mode.md b/docs/architecture/adr-052-tendermint-mode.md index edf217a06..acd5028b4 100644 --- a/docs/architecture/adr-052-tendermint-mode.md +++ b/docs/architecture/adr-052-tendermint-mode.md @@ -42,7 +42,7 @@ We would like to suggest a simple Tendermint mode abstraction. These modes will - p2p/pex - Configuration, cli command - We would like to suggest by introducing `mode` parameter in `config.toml` and cli - - `mode = "{{ .BaseConfig.Mode }}"` in `config.toml` + - `mode = "{{ .BaseConfig.Mode }}"` in `config.toml` - `tendermint node --mode validator` in cli - fullnode | validator | seed (default: "fullnode") - RPC modification diff --git a/docs/package-lock.json b/docs/package-lock.json index e5e653713..a5e8c0880 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -1157,12 +1157,6 @@ "lodash.debounce": "^4.0.8" } }, - "@vuepress/plugin-google-analytics": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-google-analytics/-/plugin-google-analytics-1.2.0.tgz", - "integrity": "sha512-0zol5D4Efb5GKel7ADO/s65MLtKSLnOEGkeWzuipkWomSQPzP7TJ3+/RcYBnGdyBFHd1BSpTUHGK0b/IGwM3UA==", - "dev": true - }, "@vuepress/plugin-last-updated": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@vuepress/plugin-last-updated/-/plugin-last-updated-1.3.0.tgz", @@ -2378,9 +2372,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001023", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001023.tgz", - "integrity": "sha512-C5TDMiYG11EOhVOA62W1p3UsJ2z4DsHtMBQtjzp3ZsUglcQn62WOUgW0y795c7A5uZ+GCEIvzkMatLIlAsbNTA==" + "version": "1.0.30001027", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001027.tgz", + "integrity": "sha512-7xvKeErvXZFtUItTHgNtLgS9RJpVnwBlWX8jSo/BO8VsF6deszemZSkJJJA1KOKrXuzZH4WALpAJdq5EyfgMLg==" }, "caseless": { "version": "0.12.0", @@ -3571,9 +3565,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.344", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.344.tgz", - "integrity": "sha512-tvbx2Wl8WBR+ym3u492D0L6/jH+8NoQXqe46+QhbWH3voVPauGuZYeb1QAXYoOAWuiP2dbSvlBx0kQ1F3hu/Mw==" + "version": "1.3.346", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.346.tgz", + "integrity": "sha512-Yy4jF5hJd57BWmGPt0KjaXc25AmWZeQK75kdr4zIzksWVtiT6DwaNtvTb9dt+LkQKwUpvBfCyyPsXXtbY/5GYw==" }, "elliptic": { "version": "6.5.2", @@ -6086,9 +6080,9 @@ "integrity": "sha512-xLIjLQmtym3QpoY9llBgApknl7pxAcN3WDRc2d3rwpl+/YvDZHPmKscGs+L6E05xf2KrCXPBvosWt7MZukwSpQ==" }, "markdown-it-attrs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-3.0.1.tgz", - "integrity": "sha512-fcpdmxdEsctDVJEunPyrirVtU/6zcTMxPxAu4Ofz51PKAa8vRMpmGQXsmXx1HTdIdUPoDonm/RhS/+jTNywj/Q==" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-3.0.2.tgz", + "integrity": "sha512-q45vdXU9TSWaHgFkWEFM97YHEoCmOyG9csLLdv3oVC6ARjT77u4wfng9rRtSOMb5UpxzT7zTX5GBbwm15H40dw==" }, "markdown-it-chain": { "version": "1.3.0", @@ -6559,9 +6553,9 @@ } }, "node-releases": { - "version": "1.1.47", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.47.tgz", - "integrity": "sha512-k4xjVPx5FpwBUj0Gw7uvFOTF4Ep8Hok1I6qjwL3pLfwe7Y0REQSAqOwwv9TWBCUtMHxcXfY4PgRLRozcChvTcA==", + "version": "1.1.48", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.48.tgz", + "integrity": "sha512-Hr8BbmUl1ujAST0K0snItzEA5zkJTQup8VNTKNfT6Zw8vTJkIiagUPNfxHmgDOyfFYNfKAul40sD0UEYTvwebw==", "requires": { "semver": "^6.3.0" } @@ -7630,11 +7624,11 @@ } }, "postcss-safe-parser": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.1.tgz", - "integrity": "sha512-xZsFA3uX8MO3yAda03QrG3/Eg1LN3EPfjjf07vke/46HERLZyHrTsQ9E1r1w1W//fWEhtYNndo2hQplN2cVpCQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", + "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", "requires": { - "postcss": "^7.0.0" + "postcss": "^7.0.26" } }, "postcss-selector-parser": { @@ -8276,9 +8270,9 @@ "integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc=" }, "resolve": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz", - "integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", "requires": { "path-parse": "^1.0.6" } @@ -10096,9 +10090,9 @@ } }, "vuepress-theme-cosmos": { - "version": "1.0.148", - "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.148.tgz", - "integrity": "sha512-IVzX339e9k25YNC62UZPfkLg50IGCctvlI/TQF6s63eCdh+ayHOPLTFq5zAiYTpP09Dbz4tSC74cQyO3fUyPOQ==", + "version": "1.0.150", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.150.tgz", + "integrity": "sha512-f4McVndkB+CqJ6mWpOG4UZSR14LJyXqwcgwoDoDUx149g2PKU3qI/AF5AcrM25+4UKMCXFKcJloQCl/aWq+1ig==", "requires": { "@cosmos-ui/vue": "^0.5.20", "axios": "^0.19.0", @@ -10181,9 +10175,9 @@ } }, "webpack-chain": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-6.3.1.tgz", - "integrity": "sha512-PLWPY92p5Vj0hOylUGjRoRY7Kgrns5vmPFAQ9BpSHnBbVbh2akRQVUlbRb2mmGYRSY1FklTULtyVChNmcQjIVg==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-6.4.0.tgz", + "integrity": "sha512-f97PYqxU+9/u0IUqp/ekAHRhBD1IQwhBv3wlJo2nvyELpr2vNnUqO3XQEk+qneg0uWGP54iciotszpjfnEExFA==", "requires": { "deepmerge": "^1.5.2", "javascript-stringify": "^2.0.1" @@ -10209,9 +10203,9 @@ } }, "webpack-dev-server": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.10.2.tgz", - "integrity": "sha512-pxZKPYb+n77UN8u9YxXT4IaIrGcNtijh/mi8TXbErHmczw0DtPnMTTjHj+eNjkqLOaAZM/qD7V59j/qJsEiaZA==", + "version": "3.10.3", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.10.3.tgz", + "integrity": "sha512-e4nWev8YzEVNdOMcNzNeCN947sWJNd43E5XvsJzbAL08kGc2frm1tQ32hTJslRS+H65LCb/AaUCYU7fjHCpDeQ==", "requires": { "ansi-html": "0.0.7", "bonjour": "^3.5.0", diff --git a/docs/package.json b/docs/package.json index 962531efd..8ce869057 100644 --- a/docs/package.json +++ b/docs/package.json @@ -4,19 +4,16 @@ "description": "Welcome to the Tendermint Core documentation!", "main": "index.js", "dependencies": { - "vuepress-theme-cosmos": "^1.0.148" - }, - "devDependencies": { - "@vuepress/plugin-google-analytics": "^1.2.0" + "vuepress-theme-cosmos": "^1.0.150" }, "scripts": { "preserve": "./pre.sh", - "serve": "trap 'exit 0' SIGINT; vuepress dev", + "serve": "trap 'exit 0' SIGINT; vuepress dev --no-cache", "postserve": "./post.sh", "prebuild": "./pre.sh", - "build": "trap 'exit 0' SIGINT; vuepress build", + "build": "trap 'exit 0' SIGINT; vuepress build --no-cache", "postbuild": "./post.sh" }, "author": "", "license": "ISC" -} +} \ No newline at end of file From 5ea1ff94d1317f9ea130a36333c27a7dc7a61186 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 17 Feb 2020 14:00:56 +0700 Subject: [PATCH 02/12] rpc: fix issue with multiple subscriptions (#4406) Using the WebSocket server, when the same client calls multiple time the subscribe method, only the last subscription receives all the events of the previous ones. example: subscription1 = tm.event = 'NewBlock' subscription2 = tm.event = 'Tx' In this case, subscription2 will receive the new blocks but subscription1 will not. This came from the WebSocket handler that had the declaration of the rpcrequest moved and so overridden for every request and given in the JSONReq client context (so the id of the subscription was not the right one). This fixes the issue by simply declaring the rpcrequest inside the loop so every request will create a new object without overwriting the previous one. --- CHANGELOG_PENDING.md | 2 ++ rpc/lib/server/ws_handler.go | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index bf41c1b5b..3eea4b2a0 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -20,3 +20,5 @@ program](https://hackerone.com/tendermint). ### IMPROVEMENTS: ### BUG FIXES: + +- [rpc] [\#4406](https://github.com/tendermint/tendermint/pull/4406) Fix issue with multiple subscriptions on the websocket (@antho1404) diff --git a/rpc/lib/server/ws_handler.go b/rpc/lib/server/ws_handler.go index 548a244cb..07f424b48 100644 --- a/rpc/lib/server/ws_handler.go +++ b/rpc/lib/server/ws_handler.go @@ -299,8 +299,6 @@ func (wsc *wsConnection) Context() context.Context { // Read from the socket and subscribe to or unsubscribe from events func (wsc *wsConnection) readRoutine() { - var request types.RPCRequest - defer func() { if r := recover(); r != nil { err, ok := r.(error) @@ -308,7 +306,7 @@ func (wsc *wsConnection) readRoutine() { err = fmt.Errorf("WSJSONRPC: %v", r) } wsc.Logger.Error("Panic in WSJSONRPC handler", "err", err, "stack", string(debug.Stack())) - wsc.WriteRPCResponse(types.RPCInternalError(request.ID, err)) + wsc.WriteRPCResponse(types.RPCInternalError(types.JSONRPCIntID(-1), err)) go wsc.readRoutine() } }() @@ -339,6 +337,7 @@ func (wsc *wsConnection) readRoutine() { return } + var request types.RPCRequest err = json.Unmarshal(in, &request) if err != nil { wsc.WriteRPCResponse(types.RPCParseError(errors.Wrap(err, "error unmarshaling request"))) From f5901ea460e471d926c3f6875c19726526951a79 Mon Sep 17 00:00:00 2001 From: Callum Waters Date: Tue, 18 Feb 2020 16:10:04 +0100 Subject: [PATCH 03/12] lite2: divide verify functions (#4412) Closes #4398 * divided verify functions * extacted method * renamed functions. Created standard Verify function * checked non-adjacency. separated VerifyCommit * lint fixes * fix godoc documentation for VerifyAdjacent and VerifyNonAdjacent * add a comment about VerifyCommit being the last check Co-authored-by: Anton Kaliaev --- lite2/client.go | 6 +- lite2/verifier.go | 183 +++++++++++++++++++++++++++-------------- lite2/verifier_test.go | 11 +-- 3 files changed, 131 insertions(+), 69 deletions(-) diff --git a/lite2/client.go b/lite2/client.go index 717623cbb..3c0a299d8 100644 --- a/lite2/client.go +++ b/lite2/client.go @@ -682,8 +682,8 @@ func (c *Client) sequence( "lastHash", c.trustedHeader.Hash(), "newHeight", interimHeader.Height, "newHash", interimHeader.Hash()) - err = Verify(c.chainID, trustedHeader, trustedNextVals, interimHeader, trustedNextVals, - c.trustingPeriod, now, c.trustLevel) + err = VerifyAdjacent(c.chainID, trustedHeader, interimHeader, trustedNextVals, + c.trustingPeriod, now) if err != nil { return errors.Wrapf(err, "failed to verify the header #%d", height) } @@ -705,7 +705,7 @@ func (c *Client) sequence( } // 2) Verify the new header. - return Verify(c.chainID, c.trustedHeader, c.trustedNextVals, newHeader, newVals, c.trustingPeriod, now, c.trustLevel) + return VerifyAdjacent(c.chainID, c.trustedHeader, newHeader, newVals, c.trustingPeriod, now) } // see VerifyHeader diff --git a/lite2/verifier.go b/lite2/verifier.go index d2f656e41..5491c8d91 100644 --- a/lite2/verifier.go +++ b/lite2/verifier.go @@ -11,106 +11,167 @@ import ( ) var ( - // DefaultTrustLevel - new header can be trusted if at least one correct old + // DefaultTrustLevel - new header can be trusted if at least one correct // validator signed it. DefaultTrustLevel = tmmath.Fraction{Numerator: 1, Denominator: 3} ) -// Verify verifies the new header (h2) against the old header (h1). It ensures that: +// VerifyNonAdjacent verifies non-adjacent untrustedHeader against +// trustedHeader. It ensures that: // -// a) h1 can still be trusted (if not, ErrOldHeaderExpired is returned); -// b) h2 is valid; -// c) either h2.ValidatorsHash equals h1NextVals.Hash() -// OR trustLevel ([1/3, 1]) of last trusted validators (h1NextVals) signed -// correctly (if not, ErrNewValSetCantBeTrusted is returned); -// c) more than 2/3 of new validators (h2Vals) have signed h2 (if not, -// ErrNotEnoughVotingPowerSigned is returned). -func Verify( +// a) trustedHeader can still be trusted (if not, ErrOldHeaderExpired is returned); +// b) untrustedHeader is valid; +// c) trustLevel ([1/3, 1]) of trustedHeaderNextVals signed correctly +// (if not, ErrNewValSetCantBeTrusted is returned); +// d) more than 2/3 of untrustedVals have signed h2 (if not, +// ErrNotEnoughVotingPowerSigned is returned); +// e) headers are non-adjacent. +func VerifyNonAdjacent( chainID string, - h1 *types.SignedHeader, - h1NextVals *types.ValidatorSet, - h2 *types.SignedHeader, - h2Vals *types.ValidatorSet, + trustedHeader *types.SignedHeader, // height=X + trustedNextVals *types.ValidatorSet, // height=X+1 + untrustedHeader *types.SignedHeader, // height=Y + untrustedVals *types.ValidatorSet, // height=Y trustingPeriod time.Duration, now time.Time, trustLevel tmmath.Fraction) error { - if err := ValidateTrustLevel(trustLevel); err != nil { + if untrustedHeader.Height == trustedHeader.Height+1 { + return errors.New("headers must be non adjacent in height") + } + + if HeaderExpired(trustedHeader, trustingPeriod, now) { + return ErrOldHeaderExpired{trustedHeader.Time.Add(trustingPeriod), now} + } + + if err := verifyNewHeaderAndVals(chainID, untrustedHeader, untrustedVals, trustedHeader, now); err != nil { return err } - // Ensure last header can still be trusted. - if HeaderExpired(h1, trustingPeriod, now) { - return ErrOldHeaderExpired{h1.Time.Add(trustingPeriod), now} - } - - if err := verifyNewHeaderAndVals(chainID, h2, h2Vals, h1, now); err != nil { - return err - } - - if h2.Height == h1.Height+1 { - if !bytes.Equal(h2.ValidatorsHash, h1NextVals.Hash()) { - err := errors.Errorf("expected old header next validators (%X) to match those from new header (%X)", - h1NextVals.Hash(), - h2.ValidatorsHash, - ) - return err - } - } else { - // Ensure that +`trustLevel` (default 1/3) or more of last trusted validators signed correctly. - err := h1NextVals.VerifyCommitTrusting(chainID, h2.Commit.BlockID, h2.Height, h2.Commit, trustLevel) - if err != nil { - switch e := err.(type) { - case types.ErrNotEnoughVotingPowerSigned: - return ErrNewValSetCantBeTrusted{e} - default: - return e - } + // Ensure that +`trustLevel` (default 1/3) or more of last trusted validators signed correctly. + err := trustedNextVals.VerifyCommitTrusting(chainID, untrustedHeader.Commit.BlockID, untrustedHeader.Height, + untrustedHeader.Commit, trustLevel) + if err != nil { + switch e := err.(type) { + case types.ErrNotEnoughVotingPowerSigned: + return ErrNewValSetCantBeTrusted{e} + default: + return e } } // Ensure that +2/3 of new validators signed correctly. - err := h2Vals.VerifyCommit(chainID, h2.Commit.BlockID, h2.Height, h2.Commit) - if err != nil { + // + // NOTE: this should always be the last check because untrustedVals can be + // intentionaly made very large to DOS the light client. not the case for + // VerifyAdjacent, where validator set is known in advance. + if err := untrustedVals.VerifyCommit(chainID, untrustedHeader.Commit.BlockID, untrustedHeader.Height, + untrustedHeader.Commit); err != nil { return err } return nil } -func verifyNewHeaderAndVals( +// VerifyAdjacent verifies directly adjacent untrustedHeader against +// trustedHeader. It ensures that: +// +// a) trustedHeader can still be trusted (if not, ErrOldHeaderExpired is returned); +// b) untrustedHeader is valid; +// c) untrustedHeader.ValidatorsHash equals trustedHeaderNextVals.Hash() +// d) more than 2/3 of new validators (untrustedVals) have signed h2 (if not, +// ErrNotEnoughVotingPowerSigned is returned); +// e) headers are adjacent. +func VerifyAdjacent( chainID string, - h2 *types.SignedHeader, - h2Vals *types.ValidatorSet, - h1 *types.SignedHeader, + trustedHeader *types.SignedHeader, // height=X + untrustedHeader *types.SignedHeader, // height=X+1 + untrustedVals *types.ValidatorSet, // height=X+1 + trustingPeriod time.Duration, now time.Time) error { - if err := h2.ValidateBasic(chainID); err != nil { - return errors.Wrap(err, "h2.ValidateBasic failed") + if untrustedHeader.Height != trustedHeader.Height+1 { + return errors.New("headers must be adjacent in height") } - if h2.Height <= h1.Height { + if HeaderExpired(trustedHeader, trustingPeriod, now) { + return ErrOldHeaderExpired{trustedHeader.Time.Add(trustingPeriod), now} + } + + if err := verifyNewHeaderAndVals(chainID, untrustedHeader, untrustedVals, trustedHeader, now); err != nil { + return err + } + + // Check the validator hashes are the same + if !bytes.Equal(untrustedHeader.ValidatorsHash, trustedHeader.NextValidatorsHash) { + err := errors.Errorf("expected old header next validators (%X) to match those from new header (%X)", + trustedHeader.NextValidatorsHash, + untrustedHeader.ValidatorsHash, + ) + return err + } + + // Ensure that +2/3 of new validators signed correctly. + if err := untrustedVals.VerifyCommit(chainID, untrustedHeader.Commit.BlockID, untrustedHeader.Height, + untrustedHeader.Commit); err != nil { + return err + } + + return nil +} + +// Verify combines both VerifyAdjacent and VerifyNonAdjacent functions. +func Verify( + chainID string, + trustedHeader *types.SignedHeader, // height=X + trustedNextVals *types.ValidatorSet, // height=X+1 + untrustedHeader *types.SignedHeader, // height=Y + untrustedVals *types.ValidatorSet, // height=Y + trustingPeriod time.Duration, + now time.Time, + trustLevel tmmath.Fraction) error { + + if untrustedHeader.Height != trustedHeader.Height+1 { + return VerifyNonAdjacent(chainID, trustedHeader, trustedNextVals, untrustedHeader, untrustedVals, + trustingPeriod, now, trustLevel) + } + + return VerifyAdjacent(chainID, trustedHeader, untrustedHeader, untrustedVals, trustingPeriod, now) +} + +func verifyNewHeaderAndVals( + chainID string, + untrustedHeader *types.SignedHeader, + untrustedVals *types.ValidatorSet, + trustedHeader *types.SignedHeader, + now time.Time) error { + + if err := untrustedHeader.ValidateBasic(chainID); err != nil { + return errors.Wrap(err, "untrustedHeader.ValidateBasic failed") + } + + if untrustedHeader.Height <= trustedHeader.Height { return errors.Errorf("expected new header height %d to be greater than one of old header %d", - h2.Height, - h1.Height) + untrustedHeader.Height, + trustedHeader.Height) } - if !h2.Time.After(h1.Time) { + if !untrustedHeader.Time.After(trustedHeader.Time) { return errors.Errorf("expected new header time %v to be after old header time %v", - h2.Time, - h1.Time) + untrustedHeader.Time, + trustedHeader.Time) } - if !h2.Time.Before(now) { + if !untrustedHeader.Time.Before(now) { return errors.Errorf("new header has a time from the future %v (now: %v)", - h2.Time, + untrustedHeader.Time, now) } - if !bytes.Equal(h2.ValidatorsHash, h2Vals.Hash()) { + if !bytes.Equal(untrustedHeader.ValidatorsHash, untrustedVals.Hash()) { return errors.Errorf("expected new header validators (%X) to match those that were supplied (%X)", - h2.ValidatorsHash, - h2Vals.Hash(), + untrustedHeader.ValidatorsHash, + untrustedVals.Hash(), ) } diff --git a/lite2/verifier_test.go b/lite2/verifier_test.go index 1625213cc..6e118d7ae 100644 --- a/lite2/verifier_test.go +++ b/lite2/verifier_test.go @@ -42,7 +42,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) { 3 * time.Hour, bTime.Add(2 * time.Hour), nil, - "expected new header height 1 to be greater than one of old header 1", + "headers must be adjacent in height", }, // different chainID -> error 1: { @@ -52,7 +52,8 @@ func TestVerifyAdjacentHeaders(t *testing.T) { 3 * time.Hour, bTime.Add(2 * time.Hour), nil, - "h2.ValidateBasic failed: signedHeader belongs to another chain 'different-chainID' not 'TestVerifyAdjacentHeaders'", + "untrustedHeader.ValidateBasic failed: signedHeader belongs to another chain 'different-chainID' not" + + " 'TestVerifyAdjacentHeaders'", }, // new header's time is before old header's time -> error 2: { @@ -139,8 +140,7 @@ func TestVerifyAdjacentHeaders(t *testing.T) { for i, tc := range testCases { tc := tc t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) { - err := Verify(chainID, header, vals, tc.newHeader, tc.newVals, tc.trustingPeriod, tc.now, DefaultTrustLevel) - + err := VerifyAdjacent(chainID, header, tc.newHeader, tc.newVals, tc.trustingPeriod, tc.now) switch { case tc.expErr != nil && assert.Error(t, err): assert.Equal(t, tc.expErr, err) @@ -254,7 +254,8 @@ func TestVerifyNonAdjacentHeaders(t *testing.T) { for i, tc := range testCases { tc := tc t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) { - err := Verify(chainID, header, vals, tc.newHeader, tc.newVals, tc.trustingPeriod, tc.now, DefaultTrustLevel) + err := VerifyNonAdjacent(chainID, header, vals, tc.newHeader, tc.newVals, tc.trustingPeriod, tc.now, + DefaultTrustLevel) switch { case tc.expErr != nil && assert.Error(t, err): From 6c67e246c308a1606706d5cf1280ad6f538feecf Mon Sep 17 00:00:00 2001 From: Marko Date: Tue, 18 Feb 2020 16:20:02 +0100 Subject: [PATCH 04/12] dep: bump gokit dep (#4424) * dep: bump gokitdep: bump gokitdep: bump gokitdep: bump gokitdep: bump gokitdep: bump gokitdep: bump gokitdep: bump gokitdep: bump gokit- Signedoff-by: Marko Baricevic * go mod tidy * test go version change * combination of multiple cmds Co-authored-by: Anton Kaliaev --- go.mod | 16 ++-- go.sum | 247 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 241 insertions(+), 22 deletions(-) diff --git a/go.mod b/go.mod index b52f7ca4b..87cab15d0 100644 --- a/go.mod +++ b/go.mod @@ -1,36 +1,32 @@ module github.com/tendermint/tendermint -go 1.12 +go 1.13 require ( github.com/ChainSafe/go-schnorrkel v0.0.0-20200102211924-4bcbc698314f - github.com/VividCortex/gohistogram v1.0.0 // indirect github.com/Workiva/go-datastructures v1.0.50 github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a github.com/fortytw2/leaktest v1.3.0 - github.com/go-kit/kit v0.9.0 + github.com/go-kit/kit v0.10.0 github.com/go-logfmt/logfmt v0.5.0 github.com/gogo/protobuf v1.3.1 github.com/golang/protobuf v1.3.3 - github.com/google/gofuzz v1.0.0 // indirect github.com/gorilla/websocket v1.4.1 github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f - github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/libp2p/go-buffer-pool v0.0.2 github.com/magiconair/properties v1.8.1 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v0.9.3 - github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165 + github.com/prometheus/client_golang v1.3.0 + github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a github.com/rs/cors v1.7.0 github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa - github.com/spf13/cobra v0.0.1 + github.com/spf13/cobra v0.0.3 github.com/spf13/viper v1.6.2 github.com/stretchr/testify v1.4.0 github.com/tendermint/go-amino v0.14.1 github.com/tendermint/tm-db v0.4.0 golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 - golang.org/x/net v0.0.0-20190628185345-da137c7871d7 - golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a // indirect + golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 google.golang.org/grpc v1.27.1 ) diff --git a/go.sum b/go.sum index 19cfd4cb8..eb2868125 100644 --- a/go.sum +++ b/go.sum @@ -1,21 +1,40 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/ChainSafe/go-schnorrkel v0.0.0-20200102211924-4bcbc698314f h1:4O1om+UVU+Hfcihr1timk8YNXHxzZWgCo7ofnrZRApw= github.com/ChainSafe/go-schnorrkel v0.0.0-20200102211924-4bcbc698314f/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +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/Workiva/go-datastructures v1.0.50 h1:slDmfW6KCHcC7U+LP3DDBbm4fqTwZGn1beOFPfGaLvo= github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= 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/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d h1:xG8Pj6Y6J760xwETNmMzmlt38QSwz0BLp1cZ09g27uw= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= @@ -26,22 +45,40 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM= @@ -52,8 +89,11 @@ github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojt github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y= github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -61,22 +101,29 @@ github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-logfmt/logfmt v0.3.0 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2ic= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= 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= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -84,36 +131,75 @@ github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f h1:8N8XWLZelZNibkhM1FuF+3Ad3YIbgirjdMiVA0eUkaM= github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +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.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +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/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= @@ -131,56 +217,121 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.0 h1:J8lpUdobwIeCI7OiSxHqEwJUKvJwicL5+3v1oe2Yb4k= -github.com/pkg/errors v0.9.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1 h1:K47Rk0v/fkEfwfQet2KWhscE0cJzjgCCDBG2KHZoVno= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0 h1:miYCvYqFXtl/J9FIy8eNpBfYthAEFg+Ys0XyUVEcDsc= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0 h1:ElTg5tNp4DqfV7UQjDqv2+RJlNzsDtvNAWccbItceIE= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d h1:GoAlyOgbOEIFdaDqxJVlbOQ1DtGmZWs/Qau0hIlk+WQ= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165 h1:nkcn14uNmFEuGCb2mBZbBb24RdNRL08b/wb+xBOYpuk= -github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= @@ -188,26 +339,30 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa h1:YJfZp12Z3AFhSBeXOlv4BO55RMwPn2NoQeDsrdWnBtY= github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.1 h1:zZh3X5aZbdnoj+4XkaBxKfhO4ot82icYdhhREIAXIj8= -github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk= -github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E= github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= @@ -220,76 +375,136 @@ github.com/tendermint/go-amino v0.14.1 h1:o2WudxNfdLNBwMyl2dqOJxiro5rfrEaU0Ugs6o github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso= github.com/tendermint/tm-db v0.4.0 h1:iPbCcLbf4nwDFhS39Zo1lpdS1X/cT9CkTlUx17FHQgA= github.com/tendermint/tm-db v0.4.0/go.mod h1:+Cwhgowrf7NBGXmsqFMbwEtbo80XmyrlY5Jsk95JubQ= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f h1:68K/z8GLUxV76xGSqwTWw2gyk/jwn79LUL43rES2g8o= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -297,13 +512,17 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -311,5 +530,9 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= From 68f37fff65102ef9d5ff51df2cd0f43489fc20c1 Mon Sep 17 00:00:00 2001 From: Erik Grinaker Date: Wed, 19 Feb 2020 12:28:34 +0100 Subject: [PATCH 05/12] Use uint64 for consensus.Reactor.SwitchToConsensus() blocksSynced (#4433) --- blockchain/v0/reactor.go | 4 ++-- blockchain/v1/reactor.go | 4 ++-- blockchain/v1/reactor_test.go | 2 +- consensus/reactor.go | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/blockchain/v0/reactor.go b/blockchain/v0/reactor.go index c35a3e6a9..d47e892c2 100644 --- a/blockchain/v0/reactor.go +++ b/blockchain/v0/reactor.go @@ -41,7 +41,7 @@ const ( type consensusReactor interface { // for when we switch from blockchain reactor and fast sync to // the consensus machine - SwitchToConsensus(sm.State, int) + SwitchToConsensus(sm.State, uint64) } type peerError struct { @@ -214,7 +214,7 @@ func (bcR *BlockchainReactor) poolRoutine() { statusUpdateTicker := time.NewTicker(statusUpdateIntervalSeconds * time.Second) switchToConsensusTicker := time.NewTicker(switchToConsensusIntervalSeconds * time.Second) - blocksSynced := 0 + blocksSynced := uint64(0) chainID := bcR.initialState.ChainID state := bcR.initialState diff --git a/blockchain/v1/reactor.go b/blockchain/v1/reactor.go index c1932d406..b57901789 100644 --- a/blockchain/v1/reactor.go +++ b/blockchain/v1/reactor.go @@ -43,7 +43,7 @@ var ( type consensusReactor interface { // for when we switch from blockchain reactor and fast sync to // the consensus machine - SwitchToConsensus(sm.State, int) + SwitchToConsensus(sm.State, uint64) } // BlockchainReactor handles long-term catchup syncing. @@ -59,7 +59,7 @@ type BlockchainReactor struct { fastSync bool fsm *BcReactorFSM - blocksSynced int + blocksSynced uint64 // Receive goroutine forwards messages to this channel to be processed in the context of the poolRoutine. messagesForFSMCh chan bcReactorMessage diff --git a/blockchain/v1/reactor_test.go b/blockchain/v1/reactor_test.go index 2add11df1..deb73ad6d 100644 --- a/blockchain/v1/reactor_test.go +++ b/blockchain/v1/reactor_test.go @@ -157,7 +157,7 @@ type consensusReactorTest struct { mtx sync.Mutex } -func (conR *consensusReactorTest) SwitchToConsensus(state sm.State, blocksSynced int) { +func (conR *consensusReactorTest) SwitchToConsensus(state sm.State, blocksSynced uint64) { conR.mtx.Lock() defer conR.mtx.Unlock() conR.switchedToConsensus = true diff --git a/consensus/reactor.go b/consensus/reactor.go index 40868ff9d..0f2dad743 100644 --- a/consensus/reactor.go +++ b/consensus/reactor.go @@ -98,7 +98,7 @@ func (conR *Reactor) OnStop() { // SwitchToConsensus switches from fast_sync mode to consensus mode. // It resets the state, turns off fast_sync, and starts the consensus state-machine -func (conR *Reactor) SwitchToConsensus(state sm.State, blocksSynced int) { +func (conR *Reactor) SwitchToConsensus(state sm.State, blocksSynced uint64) { conR.Logger.Info("SwitchToConsensus") conR.conS.reconstructLastCommit(state) // NOTE: The line below causes broadcastNewRoundStepRoutine() to From c680507bab100382ebab5b7d49d1f007b8f5c3cf Mon Sep 17 00:00:00 2001 From: Marko Date: Wed, 19 Feb 2020 13:11:17 +0100 Subject: [PATCH 06/12] dep: maunally bump dep (#4436) replaces #4434 Signed-off-by: Marko Baricevic --- go.mod | 2 +- go.sum | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 87cab15d0..7b669b1db 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/libp2p/go-buffer-pool v0.0.2 github.com/magiconair/properties v1.8.1 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.3.0 + github.com/prometheus/client_golang v1.4.1 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a github.com/rs/cors v1.7.0 github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa diff --git a/go.sum b/go.sum index eb2868125..e606cd3fa 100644 --- a/go.sum +++ b/go.sum @@ -141,6 +141,8 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= @@ -200,6 +202,7 @@ github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlT github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= @@ -294,6 +297,8 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0 h1:miYCvYqFXtl/J9FIy8eNpBfYthAEFg+Ys0XyUVEcDsc= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.4.1 h1:FFSuS004yOQEtDdTq+TAOLP5xUq63KqAFYyOi8zA+Y8= +github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -303,6 +308,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCb github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0 h1:ElTg5tNp4DqfV7UQjDqv2+RJlNzsDtvNAWccbItceIE= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= @@ -310,6 +317,8 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d h1:GoAlyOgbOEIFdaDqxJVlbOQ1DtGmZWs/Qau0hIlk+WQ= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -462,6 +471,8 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f h1:68K/z8GLUxV76xGSqwTWw2gyk/jwn79LUL43rES2g8o= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= @@ -485,6 +496,8 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -512,6 +525,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= @@ -530,6 +545,8 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From b09cdaf1afc7b8ed9c9a1685b36ac27986da87e3 Mon Sep 17 00:00:00 2001 From: Erik Grinaker Date: Wed, 19 Feb 2020 14:01:42 +0100 Subject: [PATCH 07/12] rpc: fix tx_search pagination with ordered results (#4437) --- CHANGELOG_PENDING.md | 2 ++ rpc/client/rpc_test.go | 57 ++++++++++++++++++++++++++++-------- rpc/core/tx.go | 66 ++++++++++++++++++++---------------------- 3 files changed, 79 insertions(+), 46 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 3eea4b2a0..a2fc85ee0 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -21,4 +21,6 @@ program](https://hackerone.com/tendermint). ### BUG FIXES: +- [rpc] [\#4437](https://github.com/tendermint/tendermint/pull/4437) Fix tx_search pagination with ordered results (@erikgrinaker) + - [rpc] [\#4406](https://github.com/tendermint/tendermint/pull/4406) Fix issue with multiple subscriptions on the websocket (@antho1404) diff --git a/rpc/client/rpc_test.go b/rpc/client/rpc_test.go index 55c7755ac..cd27ee4d7 100644 --- a/rpc/client/rpc_test.go +++ b/rpc/client/rpc_test.go @@ -17,6 +17,7 @@ import ( "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/tmhash" + tmbytes "github.com/tendermint/tendermint/libs/bytes" "github.com/tendermint/tendermint/libs/log" tmmath "github.com/tendermint/tendermint/libs/math" mempl "github.com/tendermint/tendermint/mempool" @@ -414,14 +415,25 @@ func TestTx(t *testing.T) { } func TestTxSearch(t *testing.T) { - // first we broadcast a tx c := getHTTPClient() - _, _, tx := MakeTxKV() - bres, err := c.BroadcastTxCommit(tx) - require.Nil(t, err) - txHeight := bres.Height - txHash := bres.Hash + // first we broadcast a few txs + var tx []byte + var txHeight int64 + var txHash tmbytes.HexBytes + for i := 0; i < 10; i++ { + _, _, tx = MakeTxKV() + res, err := c.BroadcastTxCommit(tx) + require.NoError(t, err) + txHeight = res.Height + txHash = res.Hash + } + + // Since we're not using an isolated test server, we'll have lingering transactions + // from other tests as well + result, err := c.TxSearch("tx.height >= 0", true, 1, 100, "asc") + require.NoError(t, err) + txCount := len(result.Txs) anotherTxHash := types.Tx("a different tx").Hash() @@ -433,6 +445,7 @@ func TestTxSearch(t *testing.T) { result, err := c.TxSearch(fmt.Sprintf("tx.hash='%v'", txHash), true, 1, 30, "asc") require.Nil(t, err) require.Len(t, result.Txs, 1) + require.Equal(t, txHash, result.Txs[0].Hash) ptx := result.Txs[0] assert.EqualValues(t, txHeight, ptx.Height) @@ -476,12 +489,7 @@ func TestTxSearch(t *testing.T) { require.Nil(t, err) require.Len(t, result.Txs, 0) - // broadcast another transaction to make sure we have at least two. - _, _, tx2 := MakeTxKV() - _, err = c.BroadcastTxCommit(tx2) - require.Nil(t, err) - - // chech sorting + // check sorting result, err = c.TxSearch(fmt.Sprintf("tx.height >= 1"), false, 1, 30, "asc") require.Nil(t, err) for k := 0; k < len(result.Txs)-1; k++ { @@ -495,6 +503,31 @@ func TestTxSearch(t *testing.T) { require.GreaterOrEqual(t, result.Txs[k].Height, result.Txs[k+1].Height) require.GreaterOrEqual(t, result.Txs[k].Index, result.Txs[k+1].Index) } + + // check pagination + seen := map[int64]bool{} + maxHeight := int64(0) + perPage := 3 + pages := txCount/perPage + 1 + for page := 1; page <= pages; page++ { + result, err = c.TxSearch("tx.height >= 1", false, page, perPage, "asc") + require.NoError(t, err) + if page < pages { + require.Len(t, result.Txs, perPage) + } else { + require.LessOrEqual(t, len(result.Txs), perPage) + } + require.Equal(t, txCount, result.TotalCount) + for _, tx := range result.Txs { + require.False(t, seen[tx.Height], + "Found duplicate height %v in page %v", tx.Height, page) + require.Greater(t, tx.Height, maxHeight, + "Found decreasing height %v (max seen %v) in page %v", tx.Height, maxHeight, page) + seen[tx.Height] = true + maxHeight = tx.Height + } + } + require.Len(t, seen, txCount) } } diff --git a/rpc/core/tx.go b/rpc/core/tx.go index cd6306060..f894424b7 100644 --- a/rpc/core/tx.go +++ b/rpc/core/tx.go @@ -72,6 +72,27 @@ func TxSearch(ctx *rpctypes.Context, query string, prove bool, page, perPage int return nil, err } + // sort results (must be done before pagination) + switch orderBy { + case "desc": + sort.Slice(results, func(i, j int) bool { + if results[i].Height == results[j].Height { + return results[i].Index > results[j].Index + } + return results[i].Height > results[j].Height + }) + case "asc", "": + sort.Slice(results, func(i, j int) bool { + if results[i].Height == results[j].Height { + return results[i].Index < results[j].Index + } + return results[i].Height < results[j].Height + }) + default: + return nil, errors.New("expected order_by to be either `asc` or `desc` or empty") + } + + // paginate results totalCount := len(results) perPage = validatePerPage(perPage) page, err = validatePage(page, perPage, totalCount) @@ -79,49 +100,26 @@ func TxSearch(ctx *rpctypes.Context, query string, prove bool, page, perPage int return nil, err } skipCount := validateSkipCount(page, perPage) + pageSize := tmmath.MinInt(perPage, totalCount-skipCount) - apiResults := make([]*ctypes.ResultTx, tmmath.MinInt(perPage, totalCount-skipCount)) - var proof types.TxProof - // if there's no tx in the results array, we don't need to loop through the apiResults array - for i := 0; i < len(apiResults); i++ { - r := results[skipCount+i] - height := r.Height - index := r.Index + apiResults := make([]*ctypes.ResultTx, 0, pageSize) + for i := skipCount; i < skipCount+pageSize; i++ { + r := results[i] + var proof types.TxProof if prove { - block := blockStore.LoadBlock(height) - proof = block.Data.Txs.Proof(int(index)) // XXX: overflow on 32-bit machines + block := blockStore.LoadBlock(r.Height) + proof = block.Data.Txs.Proof(int(r.Index)) // XXX: overflow on 32-bit machines } - apiResults[i] = &ctypes.ResultTx{ + apiResults = append(apiResults, &ctypes.ResultTx{ Hash: r.Tx.Hash(), - Height: height, - Index: index, + Height: r.Height, + Index: r.Index, TxResult: r.Result, Tx: r.Tx, Proof: proof, - } - } - - if len(apiResults) > 1 { - switch orderBy { - case "desc": - sort.Slice(apiResults, func(i, j int) bool { - if apiResults[i].Height == apiResults[j].Height { - return apiResults[i].Index > apiResults[j].Index - } - return apiResults[i].Height > apiResults[j].Height - }) - case "asc", "": - sort.Slice(apiResults, func(i, j int) bool { - if apiResults[i].Height == apiResults[j].Height { - return apiResults[i].Index < apiResults[j].Index - } - return apiResults[i].Height < apiResults[j].Height - }) - default: - return nil, errors.New("expected order_by to be either `asc` or `desc` or empty") - } + }) } return &ctypes.ResultTxSearch{Txs: apiResults, TotalCount: totalCount}, nil From 1874a971706380275d86a53b337a51f55ad83c17 Mon Sep 17 00:00:00 2001 From: Callum Waters Date: Wed, 19 Feb 2020 15:18:52 +0100 Subject: [PATCH 08/12] lite: modified bisection to loop (#4400) refs #4329 As opposed to using recursion to implement the bisection method of verifying a header, which could have problems with memory allocation (especially for smaller devices), the bisection algorithm now uses a for loop. * modified bisection to loop * made lint changes * made lint changes * move note to VerifyHeader since it applies both for sequence and bisection * test bisection jumps to header signed by 1/3+ of old validator set * update labels in debug log calls * copy tc Co-authored-by: Anton Kaliaev --- lite2/client.go | 115 +++++++++++++-------------- lite2/client_test.go | 179 +++++++++++++++++++++++++++++------------- lite2/test_helpers.go | 10 +-- 3 files changed, 184 insertions(+), 120 deletions(-) diff --git a/lite2/client.go b/lite2/client.go index 3c0a299d8..2c487f9c9 100644 --- a/lite2/client.go +++ b/lite2/client.go @@ -294,8 +294,8 @@ func (c *Client) checkTrustedHeaderUsingOptions(options TrustOptions) error { case options.Height < c.trustedHeader.Height: c.logger.Info("Client initialized with old header (trusted is more recent)", "old", options.Height, - "trusted", c.trustedHeader.Height, - "trusted-hash", hash2str(c.trustedHeader.Hash())) + "trustedHeight", c.trustedHeader.Height, + "trustedHash", hash2str(c.trustedHeader.Hash())) action := fmt.Sprintf( "Rollback to %d (%X)? Note this will remove newer headers up to %d (%X)", @@ -373,14 +373,14 @@ func (c *Client) initializeWithTrustOptions(options TrustOptions) error { } // 3) Fetch and verify the next vals (verification happens in - // updateTrustedHeaderAndVals). + // updateTrustedHeaderAndNextVals). nextVals, err := c.validatorSetFromPrimary(options.Height + 1) if err != nil { return err } // 4) Persist both of them and continue. - return c.updateTrustedHeaderAndVals(h, nextVals) + return c.updateTrustedHeaderAndNextVals(h, nextVals) } // Start starts two processes: 1) auto updating 2) removing outdated headers. @@ -560,6 +560,10 @@ func (c *Client) VerifyHeaderAtHeight(height int64, now time.Time) (*types.Signe // If, at any moment, SignedHeader or ValidatorSet are not found by the primary // provider, provider.ErrSignedHeaderNotFound / // provider.ErrValidatorSetNotFound error is returned. +// +// NOTE: although newVals is entered as input, trustedStore will only store the +// validator set at height newHeader.Height+1 (i.e. +// newHeader.NextValidatorsHash). func (c *Client) VerifyHeader(newHeader *types.SignedHeader, newVals *types.ValidatorSet, now time.Time) error { c.logger.Info("VerifyHeader", "height", newHeader.Height, "hash", hash2str(newHeader.Hash()), "vals", hash2str(newVals.Hash())) @@ -592,7 +596,7 @@ func (c *Client) VerifyHeader(newHeader *types.SignedHeader, newVals *types.Vali if err != nil { return err } - return c.updateTrustedHeaderAndVals(newHeader, nextVals) + return c.updateTrustedHeaderAndNextVals(newHeader, nextVals) } // Primary returns the primary provider. @@ -678,10 +682,10 @@ func (c *Client) sequence( } c.logger.Debug("Verify newHeader against trustedHeader", - "lastHeight", c.trustedHeader.Height, - "lastHash", c.trustedHeader.Hash(), + "trustedHeight", c.trustedHeader.Height, + "trustedHash", hash2str(c.trustedHeader.Hash()), "newHeight", interimHeader.Height, - "newHash", interimHeader.Hash()) + "newHash", hash2str(interimHeader.Hash())) err = VerifyAdjacent(c.chainID, trustedHeader, interimHeader, trustedNextVals, c.trustingPeriod, now) if err != nil { @@ -697,7 +701,7 @@ func (c *Client) sequence( return errors.Wrapf(err, "failed to obtain the vals #%d", height+1) } } - err = c.updateTrustedHeaderAndVals(interimHeader, interimNextVals) + err = c.updateTrustedHeaderAndNextVals(interimHeader, interimNextVals) if err != nil { return errors.Wrapf(err, "failed to update trusted state #%d", height) } @@ -710,62 +714,55 @@ func (c *Client) sequence( // see VerifyHeader func (c *Client) bisection( - lastHeader *types.SignedHeader, - lastVals *types.ValidatorSet, - newHeader *types.SignedHeader, - newVals *types.ValidatorSet, + trustedHeader *types.SignedHeader, // height h + trustedNextVals *types.ValidatorSet, // height h + 1 + newHeader *types.SignedHeader, // height g + newVals *types.ValidatorSet, // height g now time.Time) error { - c.logger.Debug("Verify newHeader against lastHeader", - "lastHeight", lastHeader.Height, - "lastHash", lastHeader.Hash(), - "newHeight", newHeader.Height, - "newHash", newHeader.Hash()) - err := Verify(c.chainID, lastHeader, lastVals, newHeader, newVals, c.trustingPeriod, now, c.trustLevel) - switch err.(type) { - case nil: - return nil - case ErrNewValSetCantBeTrusted: - // continue bisection - default: - return errors.Wrapf(err, "failed to verify the header #%d", newHeader.Height) - } + interimVals := newVals + interimHeader := newHeader - pivot := (c.trustedHeader.Height + newHeader.Header.Height) / 2 - pivotHeader, pivotVals, err := c.fetchHeaderAndValsAtHeight(pivot) - if err != nil { - return err - } + for trustedHeader.Height < newHeader.Height { + c.logger.Debug("Verify newHeader against trustedHeader", + "trustedHeight", trustedHeader.Height, + "trustedHash", hash2str(trustedHeader.Hash()), + "newHeight", newHeader.Height, + "newHash", hash2str(newHeader.Hash())) + err := Verify(c.chainID, trustedHeader, trustedNextVals, interimHeader, interimVals, c.trustingPeriod, now, + c.trustLevel) + switch err.(type) { + case nil: + // Update the lower bound to the previous upper bound + trustedHeader = interimHeader + trustedNextVals, err = c.validatorSetFromPrimary(interimHeader.Height + 1) + if err != nil { + return err + } + if !bytes.Equal(trustedHeader.NextValidatorsHash, trustedNextVals.Hash()) { + return errors.Errorf("expected next validator's hash %X, but got %X (height #%d)", + trustedHeader.NextValidatorsHash, + trustedNextVals.Hash(), + trustedHeader.Height) + } - // left branch - { - err := c.bisection(lastHeader, lastVals, pivotHeader, pivotVals, now) - if err != nil { - return errors.Wrapf(err, "bisection of #%d and #%d", lastHeader.Height, pivot) - } - } + err = c.updateTrustedHeaderAndNextVals(trustedHeader, trustedNextVals) + if err != nil { + return err + } - // right branch - { - nextVals, err := c.validatorSetFromPrimary(pivot + 1) - if err != nil { - return errors.Wrapf(err, "failed to obtain the vals #%d", pivot+1) - } - if !bytes.Equal(pivotHeader.NextValidatorsHash, nextVals.Hash()) { - return errors.Errorf("expected next validator's hash %X, but got %X (height #%d)", - pivotHeader.NextValidatorsHash, - nextVals.Hash(), - pivot) - } + // Update the upper bound to the untrustedHeader + interimHeader, interimVals = newHeader, newVals - err = c.updateTrustedHeaderAndVals(pivotHeader, nextVals) - if err != nil { - return errors.Wrapf(err, "failed to update trusted state #%d", pivot) - } + case ErrNewValSetCantBeTrusted: + pivotHeight := (interimHeader.Height + trustedHeader.Height) / 2 + interimHeader, interimVals, err = c.fetchHeaderAndValsAtHeight(pivotHeight) + if err != nil { + return err + } - err = c.bisection(pivotHeader, nextVals, newHeader, newVals, now) - if err != nil { - return errors.Wrapf(err, "bisection of #%d and #%d", pivot, newHeader.Height) + default: + return errors.Wrapf(err, "failed to verify the header #%d", newHeader.Height) } } @@ -773,7 +770,7 @@ func (c *Client) bisection( } // persist header and next validators to trustedStore. -func (c *Client) updateTrustedHeaderAndVals(h *types.SignedHeader, nextVals *types.ValidatorSet) error { +func (c *Client) updateTrustedHeaderAndNextVals(h *types.SignedHeader, nextVals *types.ValidatorSet) error { if !bytes.Equal(h.NextValidatorsHash, nextVals.Hash()) { return errors.Errorf("expected next validator's hash %X, but got %X", h.NextValidatorsHash, nextVals.Hash()) } diff --git a/lite2/client_test.go b/lite2/client_test.go index e2931f323..d8f44adc6 100644 --- a/lite2/client_test.go +++ b/lite2/client_test.go @@ -27,8 +27,10 @@ var ( bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z") h1 = keys.GenSignedHeader(chainID, 1, bTime, nil, vals, vals, []byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys)) + // 3/3 signed h2 = keys.GenSignedHeaderLastBlockID(chainID, 2, bTime.Add(30*time.Minute), nil, vals, vals, []byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys), types.BlockID{Hash: h1.Hash()}) + // 3/3 signed h3 = keys.GenSignedHeaderLastBlockID(chainID, 3, bTime.Add(1*time.Hour), nil, vals, vals, []byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(keys), types.BlockID{Hash: h2.Hash()}) trustPeriod = 4 * time.Hour @@ -56,13 +58,14 @@ var ( func TestClient_SequentialVerification(t *testing.T) { testCases := []struct { + name string otherHeaders map[int64]*types.SignedHeader // all except ^ vals map[int64]*types.ValidatorSet initErr bool verifyErr bool }{ - // good { + "good", map[int64]*types.SignedHeader{ // trusted header 1: h1, @@ -80,8 +83,8 @@ func TestClient_SequentialVerification(t *testing.T) { false, false, }, - // bad: different first header { + "bad: different first header", map[int64]*types.SignedHeader{ // different header 1: keys.GenSignedHeader(chainID, 1, bTime.Add(1*time.Hour), nil, vals, vals, @@ -93,8 +96,8 @@ func TestClient_SequentialVerification(t *testing.T) { true, false, }, - // bad: 1/3 signed interim header { + "bad: 1/3 signed interim header", map[int64]*types.SignedHeader{ // trusted header 1: h1, @@ -114,8 +117,8 @@ func TestClient_SequentialVerification(t *testing.T) { false, true, }, - // bad: 1/3 signed last header { + "bad: 1/3 signed last header", map[int64]*types.SignedHeader{ // trusted header 1: h1, @@ -138,39 +141,42 @@ func TestClient_SequentialVerification(t *testing.T) { } for _, tc := range testCases { - c, err := NewClient( - chainID, - trustOptions, - mockp.New( + tc := tc + t.Run(tc.name, func(t *testing.T) { + c, err := NewClient( chainID, - tc.otherHeaders, - tc.vals, - ), - []provider.Provider{mockp.New( - chainID, - tc.otherHeaders, - tc.vals, - )}, - dbs.New(dbm.NewMemDB(), chainID), - SequentialVerification(), - ) + trustOptions, + mockp.New( + chainID, + tc.otherHeaders, + tc.vals, + ), + []provider.Provider{mockp.New( + chainID, + tc.otherHeaders, + tc.vals, + )}, + dbs.New(dbm.NewMemDB(), chainID), + SequentialVerification(), + ) + + if tc.initErr { + require.Error(t, err) + return + } - if tc.initErr { - require.Error(t, err) - continue - } else { require.NoError(t, err) - } - err = c.Start() - require.NoError(t, err) - defer c.Stop() + err = c.Start() + require.NoError(t, err) + defer c.Stop() - _, err = c.VerifyHeaderAtHeight(3, bTime.Add(3*time.Hour)) - if tc.verifyErr { - assert.Error(t, err) - } else { - assert.NoError(t, err) - } + _, err = c.VerifyHeaderAtHeight(3, bTime.Add(3*time.Hour)) + if tc.verifyErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) } } @@ -179,12 +185,19 @@ func TestClient_SkippingVerification(t *testing.T) { newKeys := genPrivKeys(4) newVals := newKeys.ToValidators(10, 1) + // 1/3+ of vals, 2/3- of newVals + transitKeys := keys.Extend(3) + transitVals := transitKeys.ToValidators(10, 1) + testCases := []struct { + name string otherHeaders map[int64]*types.SignedHeader // all except ^ vals map[int64]*types.ValidatorSet + initErr bool + verifyErr bool }{ - // good { + "good", map[int64]*types.SignedHeader{ // trusted header 1: h1, @@ -197,9 +210,28 @@ func TestClient_SkippingVerification(t *testing.T) { 3: vals, 4: vals, }, + false, + false, }, - // good, val set changes 100% at height 2 { + "good, but val set changes by 2/3 (1/3 of vals is still present)", + map[int64]*types.SignedHeader{ + // trusted header + 1: h1, + 3: transitKeys.GenSignedHeader(chainID, 3, bTime.Add(2*time.Hour), nil, transitVals, transitVals, + []byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(transitKeys)), + }, + map[int64]*types.ValidatorSet{ + 1: vals, + 2: vals, + 3: transitVals, + 4: transitVals, + }, + false, + false, + }, + { + "good, but val set changes 100% at height 2", map[int64]*types.SignedHeader{ // trusted header 1: h1, @@ -216,33 +248,68 @@ func TestClient_SkippingVerification(t *testing.T) { 3: newVals, 4: newVals, }, + false, + false, + }, + { + "bad: last header signed by newVals, interim header has no signers", + map[int64]*types.SignedHeader{ + // trusted header + 1: h1, + // last header (0/4 of the original val set signed) + 2: keys.GenSignedHeader(chainID, 2, bTime.Add(1*time.Hour), nil, vals, newVals, + []byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, 0), + // last header (0/4 of the original val set signed) + 3: newKeys.GenSignedHeader(chainID, 3, bTime.Add(2*time.Hour), nil, newVals, newVals, + []byte("app_hash"), []byte("cons_hash"), []byte("results_hash"), 0, len(newKeys)), + }, + map[int64]*types.ValidatorSet{ + 1: vals, + 2: vals, + 3: newVals, + 4: newVals, + }, + false, + true, }, } for _, tc := range testCases { - c, err := NewClient( - chainID, - trustOptions, - mockp.New( + tc := tc + t.Run(tc.name, func(t *testing.T) { + c, err := NewClient( chainID, - tc.otherHeaders, - tc.vals, - ), - []provider.Provider{mockp.New( - chainID, - tc.otherHeaders, - tc.vals, - )}, - dbs.New(dbm.NewMemDB(), chainID), - SkippingVerification(DefaultTrustLevel), - ) - require.NoError(t, err) - err = c.Start() - require.NoError(t, err) - defer c.Stop() + trustOptions, + mockp.New( + chainID, + tc.otherHeaders, + tc.vals, + ), + []provider.Provider{mockp.New( + chainID, + tc.otherHeaders, + tc.vals, + )}, + dbs.New(dbm.NewMemDB(), chainID), + SkippingVerification(DefaultTrustLevel), + ) + if tc.initErr { + require.Error(t, err) + return + } - _, err = c.VerifyHeaderAtHeight(3, bTime.Add(3*time.Hour)) - assert.NoError(t, err) + require.NoError(t, err) + err = c.Start() + require.NoError(t, err) + defer c.Stop() + + _, err = c.VerifyHeaderAtHeight(3, bTime.Add(3*time.Hour)) + if tc.verifyErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) } } diff --git a/lite2/test_helpers.go b/lite2/test_helpers.go index 11074f8c0..cc1bf4eb9 100644 --- a/lite2/test_helpers.go +++ b/lite2/test_helpers.go @@ -36,11 +36,11 @@ func genPrivKeys(n int) privKeys { // return res // } -// // Extend adds n more keys (to remove, just take a slice). -// func (pkz privKeys) Extend(n int) privKeys { -// extra := genPrivKeys(n) -// return append(pkz, extra...) -// } +// Extend adds n more keys (to remove, just take a slice). +func (pkz privKeys) Extend(n int) privKeys { + extra := genPrivKeys(n) + return append(pkz, extra...) +} // // GenSecpPrivKeys produces an array of secp256k1 private keys to generate commits. // func GenSecpPrivKeys(n int) privKeys { From 403f43a4770b74546664f2c77720c64234300717 Mon Sep 17 00:00:00 2001 From: Erik Grinaker Date: Wed, 19 Feb 2020 15:36:15 +0100 Subject: [PATCH 09/12] rpc: fix txsearch tests (#4438) --- rpc/client/rpc_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rpc/client/rpc_test.go b/rpc/client/rpc_test.go index cd27ee4d7..c1418c816 100644 --- a/rpc/client/rpc_test.go +++ b/rpc/client/rpc_test.go @@ -3,6 +3,7 @@ package client_test import ( "bytes" "fmt" + "math" "math/rand" "net/http" "strings" @@ -508,7 +509,7 @@ func TestTxSearch(t *testing.T) { seen := map[int64]bool{} maxHeight := int64(0) perPage := 3 - pages := txCount/perPage + 1 + pages := int(math.Ceil(float64(txCount) / float64(perPage))) for page := 1; page <= pages; page++ { result, err = c.TxSearch("tx.height >= 1", false, page, perPage, "asc") require.NoError(t, err) From ee993ba8ff9893ab4c46b269987a3138ead223ff Mon Sep 17 00:00:00 2001 From: Sean Braithwaite Date: Wed, 19 Feb 2020 16:00:15 +0100 Subject: [PATCH 10/12] blockchain: add v2 reactor (#4361) The work includes the reactor which ties together all the seperate routines involved in the design of the blockchain v2 refactor. This PR replaces #4067 which got far too large and messy after a failed attempt to rebase. ## Commits: * Blockchainv 2 reactor: + I cleaner copy of the work done in #4067 which fell too far behind and was a nightmare to rebase. + The work includes the reactor which ties together all the seperate routines involved in the design of the blockchain v2 refactor. * fixes after merge * reorder iIO interface methodset * change iO -> IO * panic before send nil block * rename switchToConsensus -> trySwitchToConsensus * rename tdState -> tmState * Update blockchain/v2/reactor.go Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> * remove peer when it sends a block unsolicited * check for not ready in markReceived * fix error * fix the pcFinished event * typo fix * add documentation for processor fields * simplify time.Since * try and make the linter happy * some doc updates * fix channel diagram * Update adr-043-blockchain-riri-org.md * panic on nil switch * liting fixes * account for nil block in bBlockResponseMessage * panic on duplicate block enqueued by processor * linting * goimport reactor_test.go Co-authored-by: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com> Co-authored-by: Anca Zamfir Co-authored-by: Marko Co-authored-by: Anton Kaliaev --- behaviour/reporter.go | 2 +- blockchain/v1/reactor.go | 4 +- blockchain/v2/codec.go | 13 + blockchain/v2/io.go | 111 ++++ blockchain/v2/metrics.go | 1 + blockchain/v2/processor.go | 126 ++--- blockchain/v2/processor_context.go | 51 +- blockchain/v2/processor_test.go | 179 +++--- blockchain/v2/reactor.go | 521 ++++++++++++++++-- blockchain/v2/reactor_test.go | 513 ++++++++++++++++- blockchain/v2/routine.go | 5 +- blockchain/v2/scheduler.go | 203 +++---- blockchain/v2/scheduler_test.go | 519 +++++++---------- blockchain/v2/types.go | 1 + .../adr-043-blockchain-riri-org.md | 11 +- .../img/blockchain-reactor-v2.png | Bin 120617 -> 171024 bytes .../img/blockchain-v2-channels.png | Bin 0 -> 109340 bytes 17 files changed, 1546 insertions(+), 714 deletions(-) create mode 100644 blockchain/v2/codec.go create mode 100644 blockchain/v2/io.go create mode 100644 docs/architecture/img/blockchain-v2-channels.png diff --git a/behaviour/reporter.go b/behaviour/reporter.go index 96ce32994..1f16b9bb3 100644 --- a/behaviour/reporter.go +++ b/behaviour/reporter.go @@ -19,7 +19,7 @@ type SwitchReporter struct { } // NewSwitchReporter return a new SwitchReporter instance which wraps the Switch. -func NewSwitcReporter(sw *p2p.Switch) *SwitchReporter { +func NewSwitchReporter(sw *p2p.Switch) *SwitchReporter { return &SwitchReporter{ sw: sw, } diff --git a/blockchain/v1/reactor.go b/blockchain/v1/reactor.go index b57901789..1aba26b35 100644 --- a/blockchain/v1/reactor.go +++ b/blockchain/v1/reactor.go @@ -103,7 +103,7 @@ func NewBlockchainReactor(state sm.State, blockExec *sm.BlockExecutor, store *st fsm := NewFSM(startHeight, bcR) bcR.fsm = fsm bcR.BaseReactor = *p2p.NewBaseReactor("BlockchainReactor", bcR) - //bcR.swReporter = behaviour.NewSwitcReporter(bcR.BaseReactor.Switch) + //bcR.swReporter = behaviour.NewSwitchReporter(bcR.BaseReactor.Switch) return bcR } @@ -141,7 +141,7 @@ func (bcR *BlockchainReactor) SetLogger(l log.Logger) { // OnStart implements service.Service. func (bcR *BlockchainReactor) OnStart() error { - bcR.swReporter = behaviour.NewSwitcReporter(bcR.BaseReactor.Switch) + bcR.swReporter = behaviour.NewSwitchReporter(bcR.BaseReactor.Switch) if bcR.fastSync { go bcR.poolRoutine() } diff --git a/blockchain/v2/codec.go b/blockchain/v2/codec.go new file mode 100644 index 000000000..f970d115f --- /dev/null +++ b/blockchain/v2/codec.go @@ -0,0 +1,13 @@ +package v2 + +import ( + amino "github.com/tendermint/go-amino" + "github.com/tendermint/tendermint/types" +) + +var cdc = amino.NewCodec() + +func init() { + RegisterBlockchainMessages(cdc) + types.RegisterBlockAmino(cdc) +} diff --git a/blockchain/v2/io.go b/blockchain/v2/io.go new file mode 100644 index 000000000..3db48c8c0 --- /dev/null +++ b/blockchain/v2/io.go @@ -0,0 +1,111 @@ +package v2 + +import ( + "fmt" + + "github.com/tendermint/tendermint/p2p" + "github.com/tendermint/tendermint/state" + "github.com/tendermint/tendermint/types" +) + +type iIO interface { + sendBlockRequest(peerID p2p.ID, height int64) error + sendBlockToPeer(block *types.Block, peerID p2p.ID) error + sendBlockNotFound(height int64, peerID p2p.ID) error + sendStatusResponse(height int64, peerID p2p.ID) error + + broadcastStatusRequest(height int64) + + trySwitchToConsensus(state state.State, blocksSynced int) +} + +type switchIO struct { + sw *p2p.Switch +} + +func newSwitchIo(sw *p2p.Switch) *switchIO { + return &switchIO{ + sw: sw, + } +} + +const ( + // BlockchainChannel is a channel for blocks and status updates (`BlockStore` height) + BlockchainChannel = byte(0x40) +) + +type consensusReactor interface { + // for when we switch from blockchain reactor and fast sync to + // the consensus machine + SwitchToConsensus(state.State, int) +} + +func (sio *switchIO) sendBlockRequest(peerID p2p.ID, height int64) error { + peer := sio.sw.Peers().Get(peerID) + if peer == nil { + return fmt.Errorf("peer not found") + } + + msgBytes := cdc.MustMarshalBinaryBare(&bcBlockRequestMessage{Height: height}) + queued := peer.TrySend(BlockchainChannel, msgBytes) + if !queued { + return fmt.Errorf("send queue full") + } + return nil +} + +func (sio *switchIO) sendStatusResponse(height int64, peerID p2p.ID) error { + peer := sio.sw.Peers().Get(peerID) + if peer == nil { + return fmt.Errorf("peer not found") + } + msgBytes := cdc.MustMarshalBinaryBare(&bcStatusResponseMessage{Height: height}) + + if queued := peer.TrySend(BlockchainChannel, msgBytes); !queued { + return fmt.Errorf("peer queue full") + } + + return nil +} + +func (sio *switchIO) sendBlockToPeer(block *types.Block, peerID p2p.ID) error { + peer := sio.sw.Peers().Get(peerID) + if peer == nil { + return fmt.Errorf("peer not found") + } + if block == nil { + panic("trying to send nil block") + } + msgBytes := cdc.MustMarshalBinaryBare(&bcBlockResponseMessage{Block: block}) + if queued := peer.TrySend(BlockchainChannel, msgBytes); !queued { + return fmt.Errorf("peer queue full") + } + + return nil +} + +func (sio *switchIO) sendBlockNotFound(height int64, peerID p2p.ID) error { + peer := sio.sw.Peers().Get(peerID) + if peer == nil { + return fmt.Errorf("peer not found") + } + msgBytes := cdc.MustMarshalBinaryBare(&bcNoBlockResponseMessage{Height: height}) + if queued := peer.TrySend(BlockchainChannel, msgBytes); !queued { + return fmt.Errorf("peer queue full") + } + + return nil +} + +func (sio *switchIO) trySwitchToConsensus(state state.State, blocksSynced int) { + conR, ok := sio.sw.Reactor("CONSENSUS").(consensusReactor) + if ok { + conR.SwitchToConsensus(state, blocksSynced) + } +} + +func (sio *switchIO) broadcastStatusRequest(height int64) { + msgBytes := cdc.MustMarshalBinaryBare(&bcStatusRequestMessage{height}) + // XXX: maybe we should use an io specific peer list here + sio.sw.Broadcast(BlockchainChannel, msgBytes) +} diff --git a/blockchain/v2/metrics.go b/blockchain/v2/metrics.go index d865e7360..c68ec6447 100644 --- a/blockchain/v2/metrics.go +++ b/blockchain/v2/metrics.go @@ -37,6 +37,7 @@ type Metrics struct { ErrorsShed metrics.Counter } +// PrometheusMetrics returns metrics for in and out events, errors, etc. handled by routines. // Can we burn in the routine name here? func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { labels := []string{} diff --git a/blockchain/v2/processor.go b/blockchain/v2/processor.go index e33b36058..d6a2fe1e8 100644 --- a/blockchain/v2/processor.go +++ b/blockchain/v2/processor.go @@ -4,23 +4,12 @@ import ( "fmt" "github.com/tendermint/tendermint/p2p" - tdState "github.com/tendermint/tendermint/state" + tmState "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" ) -type peerError struct { - priorityHigh - peerID p2p.ID -} - -type pcDuplicateBlock struct { - priorityNormal -} - -type pcShortBlock struct { - priorityNormal -} - +// Events generated by the processor: +// block execution failure, event will indicate the peer(s) that caused the error type pcBlockVerificationFailure struct { priorityNormal height int64 @@ -28,24 +17,18 @@ type pcBlockVerificationFailure struct { secondPeerID p2p.ID } +// successful block execution type pcBlockProcessed struct { priorityNormal height int64 peerID p2p.ID } -type pcProcessBlock struct { - priorityNormal -} - -type pcStop struct { - priorityNormal -} - +// processor has finished type pcFinished struct { priorityNormal - height int64 - blocksSynced int64 + blocksSynced int + tmState tmState.State } func (p pcFinished) Error() string { @@ -60,37 +43,38 @@ type queueItem struct { type blockQueue map[int64]queueItem type pcState struct { - height int64 // height of the last synced block - queue blockQueue // blocks waiting to be processed - chainID string - blocksSynced int64 - draining bool - tdState tdState.State - context processorContext + // blocks waiting to be processed + queue blockQueue + + // draining indicates that the next rProcessBlock event with a queue miss constitutes completion + draining bool + + // the number of blocks successfully synced by the processor + blocksSynced int + + // the processorContext which contains the processor dependencies + context processorContext } func (state *pcState) String() string { return fmt.Sprintf("height: %d queue length: %d draining: %v blocks synced: %d", - state.height, len(state.queue), state.draining, state.blocksSynced) + state.height(), len(state.queue), state.draining, state.blocksSynced) } // newPcState returns a pcState initialized with the last verified block enqueued -func newPcState(initHeight int64, tdState tdState.State, chainID string, context processorContext) *pcState { +func newPcState(context processorContext) *pcState { return &pcState{ - height: initHeight, queue: blockQueue{}, - chainID: chainID, draining: false, blocksSynced: 0, context: context, - tdState: tdState, } } // nextTwo returns the next two unverified blocks func (state *pcState) nextTwo() (queueItem, queueItem, error) { - if first, ok := state.queue[state.height+1]; ok { - if second, ok := state.queue[state.height+2]; ok { + if first, ok := state.queue[state.height()+1]; ok { + if second, ok := state.queue[state.height()+2]; ok { return first, second, nil } } @@ -102,18 +86,15 @@ func (state *pcState) synced() bool { return len(state.queue) <= 1 } -func (state *pcState) advance() { - state.height++ - delete(state.queue, state.height) - state.blocksSynced++ -} - -func (state *pcState) enqueue(peerID p2p.ID, block *types.Block, height int64) error { +func (state *pcState) enqueue(peerID p2p.ID, block *types.Block, height int64) { if _, ok := state.queue[height]; ok { - return fmt.Errorf("duplicate queue item") + panic("duplicate block enqueued by processor") } state.queue[height] = queueItem{block: block, peerID: peerID} - return nil +} + +func (state *pcState) height() int64 { + return state.context.tmState().LastBlockHeight } // purgePeer moves all unprocessed blocks from the queue @@ -129,23 +110,34 @@ func (state *pcState) purgePeer(peerID p2p.ID) { // handle processes FSM events func (state *pcState) handle(event Event) (Event, error) { switch event := event.(type) { - case *scBlockReceived: + case scFinishedEv: + if state.synced() { + return pcFinished{tmState: state.context.tmState(), blocksSynced: state.blocksSynced}, nil + } + state.draining = true + return noOp, nil + + case scPeerError: + state.purgePeer(event.peerID) + return noOp, nil + + case scBlockReceived: if event.block == nil { - panic("processor received an event with a nil block") - } - if event.block.Height <= state.height { - return pcShortBlock{}, nil - } - err := state.enqueue(event.peerID, event.block, event.block.Height) - if err != nil { - return pcDuplicateBlock{}, nil + return noOp, nil } - case pcProcessBlock: + // enqueue block if height is higher than state height, else ignore it + if event.block.Height > state.height() { + state.enqueue(event.peerID, event.block, event.block.Height) + } + return noOp, nil + + case rProcessBlock: + tmState := state.context.tmState() firstItem, secondItem, err := state.nextTwo() if err != nil { if state.draining { - return noOp, pcFinished{height: state.height} + return pcFinished{tmState: tmState, blocksSynced: state.blocksSynced}, nil } return noOp, nil } @@ -155,7 +147,7 @@ func (state *pcState) handle(event Event) (Event, error) { firstPartsHeader := firstParts.Header() firstID := types.BlockID{Hash: first.Hash(), PartsHeader: firstPartsHeader} - err = state.context.verifyCommit(state.chainID, firstID, first.Height, second.LastCommit) + err = state.context.verifyCommit(tmState.ChainID, firstID, first.Height, second.LastCommit) if err != nil { state.purgePeer(firstItem.peerID) state.purgePeer(secondItem.peerID) @@ -166,21 +158,15 @@ func (state *pcState) handle(event Event) (Event, error) { state.context.saveBlock(first, firstParts, second.LastCommit) - state.tdState, err = state.context.applyBlock(state.tdState, firstID, first) - if err != nil { + if err := state.context.applyBlock(firstID, first); err != nil { panic(fmt.Sprintf("failed to process committed block (%d:%X): %v", first.Height, first.Hash(), err)) } - state.advance() + + delete(state.queue, first.Height) + state.blocksSynced++ + return pcBlockProcessed{height: first.Height, peerID: firstItem.peerID}, nil - case *peerError: - state.purgePeer(event.peerID) - - case pcStop: - if state.synced() { - return noOp, pcFinished{height: state.height, blocksSynced: state.blocksSynced} - } - state.draining = true } return noOp, nil diff --git a/blockchain/v2/processor_context.go b/blockchain/v2/processor_context.go index c4c8770cd..7e96a3a69 100644 --- a/blockchain/v2/processor_context.go +++ b/blockchain/v2/processor_context.go @@ -4,37 +4,41 @@ import ( "fmt" "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/store" "github.com/tendermint/tendermint/types" ) type processorContext interface { - applyBlock(state state.State, blockID types.BlockID, block *types.Block) (state.State, error) + applyBlock(blockID types.BlockID, block *types.Block) error verifyCommit(chainID string, blockID types.BlockID, height int64, commit *types.Commit) error saveBlock(block *types.Block, blockParts *types.PartSet, seenCommit *types.Commit) + tmState() state.State } -// nolint:unused type pContext struct { - store *store.BlockStore - executor *state.BlockExecutor - state *state.State + store blockStore + applier blockApplier + state state.State } -// nolint:unused,deadcode -func newProcessorContext(st *store.BlockStore, ex *state.BlockExecutor, s *state.State) *pContext { +func newProcessorContext(st blockStore, ex blockApplier, s state.State) *pContext { return &pContext{ - store: st, - executor: ex, - state: s, + store: st, + applier: ex, + state: s, } } -func (pc *pContext) applyBlock(state state.State, blockID types.BlockID, block *types.Block) (state.State, error) { - return pc.executor.ApplyBlock(state, blockID, block) +func (pc *pContext) applyBlock(blockID types.BlockID, block *types.Block) error { + newState, err := pc.applier.ApplyBlock(pc.state, blockID, block) + pc.state = newState + return err } -func (pc *pContext) verifyCommit(chainID string, blockID types.BlockID, height int64, commit *types.Commit) error { +func (pc pContext) tmState() state.State { + return pc.state +} + +func (pc pContext) verifyCommit(chainID string, blockID types.BlockID, height int64, commit *types.Commit) error { return pc.state.Validators.VerifyCommit(chainID, blockID, height, commit) } @@ -45,22 +49,28 @@ func (pc *pContext) saveBlock(block *types.Block, blockParts *types.PartSet, see type mockPContext struct { applicationBL []int64 verificationBL []int64 + state state.State } -func newMockProcessorContext(verificationBlackList []int64, applicationBlackList []int64) *mockPContext { +func newMockProcessorContext( + state state.State, + verificationBlackList []int64, + applicationBlackList []int64) *mockPContext { return &mockPContext{ applicationBL: applicationBlackList, verificationBL: verificationBlackList, + state: state, } } -func (mpc *mockPContext) applyBlock(state state.State, blockID types.BlockID, block *types.Block) (state.State, error) { +func (mpc *mockPContext) applyBlock(blockID types.BlockID, block *types.Block) error { for _, h := range mpc.applicationBL { if h == block.Height { - return state, fmt.Errorf("generic application error") + return fmt.Errorf("generic application error") } } - return state, nil + mpc.state.LastBlockHeight = block.Height + return nil } func (mpc *mockPContext) verifyCommit(chainID string, blockID types.BlockID, height int64, commit *types.Commit) error { @@ -73,4 +83,9 @@ func (mpc *mockPContext) verifyCommit(chainID string, blockID types.BlockID, hei } func (mpc *mockPContext) saveBlock(block *types.Block, blockParts *types.PartSet, seenCommit *types.Commit) { + +} + +func (mpc *mockPContext) tmState() state.State { + return mpc.state } diff --git a/blockchain/v2/processor_test.go b/blockchain/v2/processor_test.go index 61be23663..fc35c4c72 100644 --- a/blockchain/v2/processor_test.go +++ b/blockchain/v2/processor_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/tendermint/tendermint/p2p" - tdState "github.com/tendermint/tendermint/state" + tmState "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" ) @@ -19,7 +19,7 @@ type pcBlock struct { type params struct { height int64 items []pcBlock - blocksSynced int64 + blocksSynced int verBL []int64 appBL []int64 draining bool @@ -33,13 +33,13 @@ func makePcBlock(height int64) *types.Block { // makeState takes test parameters and creates a specific processor state. func makeState(p *params) *pcState { var ( - tdState = tdState.State{} - context = newMockProcessorContext(p.verBL, p.appBL) + tmState = tmState.State{LastBlockHeight: p.height} + context = newMockProcessorContext(tmState, p.verBL, p.appBL) ) - state := newPcState(p.height, tdState, "test", context) + state := newPcState(context) for _, item := range p.items { - _ = state.enqueue(p2p.ID(item.pid), makePcBlock(item.height), item.height) + state.enqueue(p2p.ID(item.pid), makePcBlock(item.height), item.height) } state.blocksSynced = p.blocksSynced @@ -47,8 +47,8 @@ func makeState(p *params) *pcState { return state } -func mBlockResponse(peerID p2p.ID, height int64) *scBlockReceived { - return &scBlockReceived{ +func mBlockResponse(peerID p2p.ID, height int64) scBlockReceived { + return scBlockReceived{ peerID: peerID, block: makePcBlock(height), } @@ -101,9 +101,37 @@ func executeProcessorTests(t *testing.T, tests []testFields) { } } +func TestRProcessPeerError(t *testing.T) { + tests := []testFields{ + { + name: "error for existing peer", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}}, + event: scPeerError{peerID: "P2"}, + wantState: ¶ms{items: []pcBlock{{"P1", 1}}}, + wantNextEvent: noOp, + }, + }, + }, + { + name: "error for unknown peer", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}}, + event: scPeerError{peerID: "P3"}, + wantState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}}, + wantNextEvent: noOp, + }, + }, + }, + } + + executeProcessorTests(t, tests) +} + func TestPcBlockResponse(t *testing.T) { tests := []testFields{ - { name: "add one block", steps: []pcFsmMakeStateValues{ @@ -113,6 +141,7 @@ func TestPcBlockResponse(t *testing.T) { }, }, }, + { name: "add two blocks", steps: []pcFsmMakeStateValues{ @@ -126,62 +155,18 @@ func TestPcBlockResponse(t *testing.T) { }, }, }, - { - name: "add duplicate block from same peer", - steps: []pcFsmMakeStateValues{ - { - currentState: ¶ms{}, event: mBlockResponse("P1", 3), - wantState: ¶ms{items: []pcBlock{{"P1", 3}}}, wantNextEvent: noOp, - }, - { // use previous wantState as currentState, - event: mBlockResponse("P1", 3), - wantState: ¶ms{items: []pcBlock{{"P1", 3}}}, wantNextEvent: pcDuplicateBlock{}, - }, - }, - }, - { - name: "add duplicate block from different peer", - steps: []pcFsmMakeStateValues{ - { - currentState: ¶ms{}, event: mBlockResponse("P1", 3), - wantState: ¶ms{items: []pcBlock{{"P1", 3}}}, wantNextEvent: noOp, - }, - { // use previous wantState as currentState, - event: mBlockResponse("P2", 3), - wantState: ¶ms{items: []pcBlock{{"P1", 3}}}, wantNextEvent: pcDuplicateBlock{}, - }, - }, - }, - { - name: "attempt to add block with height equal to state.height", - steps: []pcFsmMakeStateValues{ - { - currentState: ¶ms{height: 2, items: []pcBlock{{"P1", 3}}}, event: mBlockResponse("P1", 2), - wantState: ¶ms{height: 2, items: []pcBlock{{"P1", 3}}}, wantNextEvent: pcShortBlock{}, - }, - }, - }, - { - name: "attempt to add block with height smaller than state.height", - steps: []pcFsmMakeStateValues{ - { - currentState: ¶ms{height: 2, items: []pcBlock{{"P1", 3}}}, event: mBlockResponse("P1", 1), - wantState: ¶ms{height: 2, items: []pcBlock{{"P1", 3}}}, wantNextEvent: pcShortBlock{}, - }, - }, - }, } executeProcessorTests(t, tests) } -func TestPcProcessBlockSuccess(t *testing.T) { +func TestRProcessBlockSuccess(t *testing.T) { tests := []testFields{ { name: "noop - no blocks over current height", steps: []pcFsmMakeStateValues{ { - currentState: ¶ms{}, event: pcProcessBlock{}, + currentState: ¶ms{}, event: rProcessBlock{}, wantState: ¶ms{}, wantNextEvent: noOp, }, }, @@ -190,7 +175,7 @@ func TestPcProcessBlockSuccess(t *testing.T) { name: "noop - high new blocks", steps: []pcFsmMakeStateValues{ { - currentState: ¶ms{height: 5, items: []pcBlock{{"P1", 30}, {"P2", 31}}}, event: pcProcessBlock{}, + currentState: ¶ms{height: 5, items: []pcBlock{{"P1", 30}, {"P2", 31}}}, event: rProcessBlock{}, wantState: ¶ms{height: 5, items: []pcBlock{{"P1", 30}, {"P2", 31}}}, wantNextEvent: noOp, }, }, @@ -199,7 +184,7 @@ func TestPcProcessBlockSuccess(t *testing.T) { name: "blocks H+1 and H+2 present", steps: []pcFsmMakeStateValues{ { - currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}}, event: pcProcessBlock{}, + currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}}, event: rProcessBlock{}, wantState: ¶ms{height: 1, items: []pcBlock{{"P2", 2}}, blocksSynced: 1}, wantNextEvent: pcBlockProcessed{height: 1, peerID: "P1"}, }, @@ -209,20 +194,20 @@ func TestPcProcessBlockSuccess(t *testing.T) { name: "blocks H+1 and H+2 present after draining", steps: []pcFsmMakeStateValues{ { // some contiguous blocks - on stop check draining is set - currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}, {"P1", 4}}}, event: pcStop{}, + currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}, {"P1", 4}}}, + event: scFinishedEv{}, wantState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}, {"P1", 4}}, draining: true}, wantNextEvent: noOp, }, { - event: pcProcessBlock{}, + event: rProcessBlock{}, wantState: ¶ms{height: 1, items: []pcBlock{{"P2", 2}, {"P1", 4}}, blocksSynced: 1, draining: true}, wantNextEvent: pcBlockProcessed{height: 1, peerID: "P1"}, }, { // finish when H+1 or/and H+2 are missing - event: pcProcessBlock{}, + event: rProcessBlock{}, wantState: ¶ms{height: 1, items: []pcBlock{{"P2", 2}, {"P1", 4}}, blocksSynced: 1, draining: true}, - wantNextEvent: noOp, - wantErr: pcFinished{height: 1}, + wantNextEvent: pcFinished{tmState: tmState.State{LastBlockHeight: 1}, blocksSynced: 1}, }, }, }, @@ -231,13 +216,13 @@ func TestPcProcessBlockSuccess(t *testing.T) { executeProcessorTests(t, tests) } -func TestPcProcessBlockFailures(t *testing.T) { +func TestRProcessBlockFailures(t *testing.T) { tests := []testFields{ { name: "blocks H+1 and H+2 present from different peers - H+1 verification fails ", steps: []pcFsmMakeStateValues{ { - currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}, verBL: []int64{1}}, event: pcProcessBlock{}, + currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}, verBL: []int64{1}}, event: rProcessBlock{}, wantState: ¶ms{items: []pcBlock{}, verBL: []int64{1}}, wantNextEvent: pcBlockVerificationFailure{height: 1, firstPeerID: "P1", secondPeerID: "P2"}, }, @@ -247,7 +232,7 @@ func TestPcProcessBlockFailures(t *testing.T) { name: "blocks H+1 and H+2 present from same peer - H+1 applyBlock fails ", steps: []pcFsmMakeStateValues{ { - currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}, appBL: []int64{1}}, event: pcProcessBlock{}, + currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}, appBL: []int64{1}}, event: rProcessBlock{}, wantState: ¶ms{items: []pcBlock{}, appBL: []int64{1}}, wantPanic: true, }, }, @@ -256,9 +241,9 @@ func TestPcProcessBlockFailures(t *testing.T) { name: "blocks H+1 and H+2 present from same peers - H+1 verification fails ", steps: []pcFsmMakeStateValues{ { - currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P1", 2}, {"P2", 3}}, verBL: []int64{1}}, - event: pcProcessBlock{}, - wantState: ¶ms{items: []pcBlock{{"P2", 3}}, verBL: []int64{1}}, + currentState: ¶ms{height: 0, items: []pcBlock{{"P1", 1}, {"P1", 2}, {"P2", 3}}, + verBL: []int64{1}}, event: rProcessBlock{}, + wantState: ¶ms{height: 0, items: []pcBlock{{"P2", 3}}, verBL: []int64{1}}, wantNextEvent: pcBlockVerificationFailure{height: 1, firstPeerID: "P1", secondPeerID: "P1"}, }, }, @@ -268,7 +253,7 @@ func TestPcProcessBlockFailures(t *testing.T) { steps: []pcFsmMakeStateValues{ { currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}, {"P2", 3}}, appBL: []int64{1}}, - event: pcProcessBlock{}, + event: rProcessBlock{}, wantState: ¶ms{items: []pcBlock{{"P2", 3}}, appBL: []int64{1}}, wantPanic: true, }, }, @@ -278,53 +263,15 @@ func TestPcProcessBlockFailures(t *testing.T) { executeProcessorTests(t, tests) } -func TestPcPeerError(t *testing.T) { - tests := []testFields{ - { - name: "peer not present", - steps: []pcFsmMakeStateValues{ - { - currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}}, event: &peerError{peerID: "P3"}, - wantState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}}, - wantNextEvent: noOp, - }, - }, - }, - { - name: "some blocks are from errored peer", - steps: []pcFsmMakeStateValues{ - { - currentState: ¶ms{items: []pcBlock{{"P1", 100}, {"P1", 99}, {"P2", 101}}}, event: &peerError{peerID: "P1"}, - wantState: ¶ms{items: []pcBlock{{"P2", 101}}}, - wantNextEvent: noOp, - }, - }, - }, - { - name: "all blocks are from errored peer", - steps: []pcFsmMakeStateValues{ - { - currentState: ¶ms{items: []pcBlock{{"P1", 100}, {"P1", 99}}}, event: &peerError{peerID: "P1"}, - wantState: ¶ms{}, - wantNextEvent: noOp, - }, - }, - }, - } - - executeProcessorTests(t, tests) -} - -func TestStop(t *testing.T) { +func TestScFinishedEv(t *testing.T) { tests := []testFields{ { name: "no blocks", steps: []pcFsmMakeStateValues{ { - currentState: ¶ms{height: 100, items: []pcBlock{}, blocksSynced: 100}, event: pcStop{}, + currentState: ¶ms{height: 100, items: []pcBlock{}, blocksSynced: 100}, event: scFinishedEv{}, wantState: ¶ms{height: 100, items: []pcBlock{}, blocksSynced: 100}, - wantNextEvent: noOp, - wantErr: pcFinished{height: 100, blocksSynced: 100}, + wantNextEvent: pcFinished{tmState: tmState.State{LastBlockHeight: 100}, blocksSynced: 100}, }, }, }, @@ -332,10 +279,10 @@ func TestStop(t *testing.T) { name: "maxHeight+1 block present", steps: []pcFsmMakeStateValues{ { - currentState: ¶ms{height: 100, items: []pcBlock{{"P1", 101}}, blocksSynced: 100}, event: pcStop{}, + currentState: ¶ms{height: 100, items: []pcBlock{ + {"P1", 101}}, blocksSynced: 100}, event: scFinishedEv{}, wantState: ¶ms{height: 100, items: []pcBlock{{"P1", 101}}, blocksSynced: 100}, - wantNextEvent: noOp, - wantErr: pcFinished{height: 100, blocksSynced: 100}, + wantNextEvent: pcFinished{tmState: tmState.State{LastBlockHeight: 100}, blocksSynced: 100}, }, }, }, @@ -343,8 +290,10 @@ func TestStop(t *testing.T) { name: "more blocks present", steps: []pcFsmMakeStateValues{ { - currentState: ¶ms{height: 100, items: []pcBlock{{"P1", 101}, {"P1", 102}}, blocksSynced: 100}, event: pcStop{}, - wantState: ¶ms{height: 100, items: []pcBlock{{"P1", 101}, {"P1", 102}}, blocksSynced: 100, draining: true}, + currentState: ¶ms{height: 100, items: []pcBlock{ + {"P1", 101}, {"P1", 102}}, blocksSynced: 100}, event: scFinishedEv{}, + wantState: ¶ms{height: 100, items: []pcBlock{ + {"P1", 101}, {"P1", 102}}, blocksSynced: 100, draining: true}, wantNextEvent: noOp, wantErr: nil, }, diff --git a/blockchain/v2/reactor.go b/blockchain/v2/reactor.go index 8f7143083..767e59819 100644 --- a/blockchain/v2/reactor.go +++ b/blockchain/v2/reactor.go @@ -1,118 +1,529 @@ package v2 import ( + "errors" "fmt" + "sync" "time" + "github.com/tendermint/go-amino" + "github.com/tendermint/tendermint/behaviour" "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/p2p" + "github.com/tendermint/tendermint/state" + "github.com/tendermint/tendermint/types" ) -type timeCheck struct { - priorityHigh - time time.Time +//------------------------------------- + +type bcBlockRequestMessage struct { + Height int64 } -func schedulerHandle(event Event) (Event, error) { - if _, ok := event.(timeCheck); ok { - fmt.Println("scheduler handle timeCheck") +// ValidateBasic performs basic validation. +func (m *bcBlockRequestMessage) ValidateBasic() error { + if m.Height < 0 { + return errors.New("negative Height") } - return noOp, nil + return nil } -func processorHandle(event Event) (Event, error) { - if _, ok := event.(timeCheck); ok { - fmt.Println("processor handle timeCheck") +func (m *bcBlockRequestMessage) String() string { + return fmt.Sprintf("[bcBlockRequestMessage %v]", m.Height) +} + +type bcNoBlockResponseMessage struct { + Height int64 +} + +// ValidateBasic performs basic validation. +func (m *bcNoBlockResponseMessage) ValidateBasic() error { + if m.Height < 0 { + return errors.New("negative Height") } - return noOp, nil - + return nil } -type Reactor struct { - events chan Event +func (m *bcNoBlockResponseMessage) String() string { + return fmt.Sprintf("[bcNoBlockResponseMessage %d]", m.Height) +} + +//------------------------------------- + +type bcBlockResponseMessage struct { + Block *types.Block +} + +// ValidateBasic performs basic validation. +func (m *bcBlockResponseMessage) ValidateBasic() error { + if m.Block == nil { + return errors.New("block response message has nil block") + } + + return m.Block.ValidateBasic() +} + +func (m *bcBlockResponseMessage) String() string { + return fmt.Sprintf("[bcBlockResponseMessage %v]", m.Block.Height) +} + +//------------------------------------- + +type bcStatusRequestMessage struct { + Height int64 +} + +// ValidateBasic performs basic validation. +func (m *bcStatusRequestMessage) ValidateBasic() error { + if m.Height < 0 { + return errors.New("negative Height") + } + return nil +} + +func (m *bcStatusRequestMessage) String() string { + return fmt.Sprintf("[bcStatusRequestMessage %v]", m.Height) +} + +//------------------------------------- + +type bcStatusResponseMessage struct { + Height int64 +} + +// ValidateBasic performs basic validation. +func (m *bcStatusResponseMessage) ValidateBasic() error { + if m.Height < 0 { + return errors.New("negative Height") + } + return nil +} + +func (m *bcStatusResponseMessage) String() string { + return fmt.Sprintf("[bcStatusResponseMessage %v]", m.Height) +} + +type blockStore interface { + LoadBlock(height int64) *types.Block + SaveBlock(*types.Block, *types.PartSet, *types.Commit) + Height() int64 +} + +// BlockchainReactor handles fast sync protocol. +type BlockchainReactor struct { + p2p.BaseReactor + + events chan Event // XXX: Rename eventsFromPeers stopDemux chan struct{} scheduler *Routine processor *Routine - ticker *time.Ticker logger log.Logger + + mtx sync.RWMutex + maxPeerHeight int64 + syncHeight int64 + + reporter behaviour.Reporter + io iIO + store blockStore } -func NewReactor(bufferSize int) *Reactor { - return &Reactor{ +//nolint:unused,deadcode +type blockVerifier interface { + VerifyCommit(chainID string, blockID types.BlockID, height int64, commit *types.Commit) error +} + +//nolint:deadcode +type blockApplier interface { + ApplyBlock(state state.State, blockID types.BlockID, block *types.Block) (state.State, error) +} + +// XXX: unify naming in this package around tmState +// XXX: V1 stores a copy of state as initialState, which is never mutated. Is that nessesary? +func newReactor(state state.State, store blockStore, reporter behaviour.Reporter, + blockApplier blockApplier, bufferSize int) *BlockchainReactor { + scheduler := newScheduler(state.LastBlockHeight, time.Now()) + pContext := newProcessorContext(store, blockApplier, state) + // TODO: Fix naming to just newProcesssor + // newPcState requires a processorContext + processor := newPcState(pContext) + + return &BlockchainReactor{ events: make(chan Event, bufferSize), stopDemux: make(chan struct{}), - scheduler: newRoutine("scheduler", schedulerHandle, bufferSize), - processor: newRoutine("processor", processorHandle, bufferSize), - ticker: time.NewTicker(1 * time.Second), + scheduler: newRoutine("scheduler", scheduler.handle, bufferSize), + processor: newRoutine("processor", processor.handle, bufferSize), + store: store, + reporter: reporter, logger: log.NewNopLogger(), } } -// nolint:unused -func (r *Reactor) setLogger(logger log.Logger) { +// NewBlockchainReactor creates a new reactor instance. +func NewBlockchainReactor( + state state.State, + blockApplier blockApplier, + store blockStore, + fastSync bool) *BlockchainReactor { + reporter := behaviour.NewMockReporter() + return newReactor(state, store, reporter, blockApplier, 1000) +} + +// SetSwitch implements Reactor interface. +func (r *BlockchainReactor) SetSwitch(sw *p2p.Switch) { + if sw == nil { + panic("set nil switch") + } + + r.Switch = sw + r.io = newSwitchIo(sw) +} + +func (r *BlockchainReactor) setMaxPeerHeight(height int64) { + r.mtx.Lock() + defer r.mtx.Unlock() + if height > r.maxPeerHeight { + r.maxPeerHeight = height + } +} + +func (r *BlockchainReactor) setSyncHeight(height int64) { + r.mtx.Lock() + defer r.mtx.Unlock() + r.syncHeight = height +} + +// SyncHeight returns the height to which the BlockchainReactor has synced. +func (r *BlockchainReactor) SyncHeight() int64 { + r.mtx.RLock() + defer r.mtx.RUnlock() + return r.syncHeight +} + +// SetLogger sets the logger of the reactor. +func (r *BlockchainReactor) SetLogger(logger log.Logger) { r.logger = logger r.scheduler.setLogger(logger) r.processor.setLogger(logger) } -func (r *Reactor) Start() { +// Start implements cmn.Service interface +func (r *BlockchainReactor) Start() error { + r.reporter = behaviour.NewSwitchReporter(r.BaseReactor.Switch) go r.scheduler.start() go r.processor.start() go r.demux() - - <-r.scheduler.ready() - <-r.processor.ready() - - go func() { - for t := range r.ticker.C { - r.events <- timeCheck{time: t} - } - }() + return nil } -// XXX: How to make this deterministic? -// XXX: Would it be possible here to provide some kind of type safety for the types -// of events that each routine can produce and consume? -func (r *Reactor) demux() { +// reactor generated ticker events: +// ticker for cleaning peers +type rTryPrunePeer struct { + priorityHigh + time time.Time +} + +func (e rTryPrunePeer) String() string { + return fmt.Sprintf(": %v", e.time) +} + +// ticker event for scheduling block requests +type rTrySchedule struct { + priorityHigh + time time.Time +} + +func (e rTrySchedule) String() string { + return fmt.Sprintf(": %v", e.time) +} + +// ticker for block processing +type rProcessBlock struct { + priorityNormal +} + +// reactor generated events based on blockchain related messages from peers: +// blockResponse message received from a peer +type bcBlockResponse struct { + priorityNormal + time time.Time + peerID p2p.ID + size int64 + block *types.Block +} + +// blockNoResponse message received from a peer +type bcNoBlockResponse struct { + priorityNormal + time time.Time + peerID p2p.ID + height int64 +} + +// statusResponse message received from a peer +type bcStatusResponse struct { + priorityNormal + time time.Time + peerID p2p.ID + height int64 +} + +// new peer is connected +type bcAddNewPeer struct { + priorityNormal + peerID p2p.ID +} + +// existing peer is removed +type bcRemovePeer struct { + priorityHigh + peerID p2p.ID + reason interface{} +} + +func (r *BlockchainReactor) demux() { + var lastRate = 0.0 + var lastHundred = time.Now() + + var ( + processBlockFreq = 20 * time.Millisecond + doProcessBlockCh = make(chan struct{}, 1) + doProcessBlockTk = time.NewTicker(processBlockFreq) + + prunePeerFreq = 1 * time.Second + doPrunePeerCh = make(chan struct{}, 1) + doPrunePeerTk = time.NewTicker(prunePeerFreq) + + scheduleFreq = 20 * time.Millisecond + doScheduleCh = make(chan struct{}, 1) + doScheduleTk = time.NewTicker(scheduleFreq) + + statusFreq = 10 * time.Second + doStatusCh = make(chan struct{}, 1) + doStatusTk = time.NewTicker(statusFreq) + ) + + // XXX: Extract timers to make testing atemporal for { select { + // Pacers: send at most per frequency but don't saturate + case <-doProcessBlockTk.C: + select { + case doProcessBlockCh <- struct{}{}: + default: + } + case <-doPrunePeerTk.C: + select { + case doPrunePeerCh <- struct{}{}: + default: + } + case <-doScheduleTk.C: + select { + case doScheduleCh <- struct{}{}: + default: + } + case <-doStatusTk.C: + select { + case doStatusCh <- struct{}{}: + default: + } + + // Tickers: perform tasks periodically + case <-doScheduleCh: + r.scheduler.send(rTrySchedule{time: time.Now()}) + case <-doPrunePeerCh: + r.scheduler.send(rTryPrunePeer{time: time.Now()}) + case <-doProcessBlockCh: + r.processor.send(rProcessBlock{}) + case <-doStatusCh: + r.io.broadcastStatusRequest(r.SyncHeight()) + + // Events from peers case event := <-r.events: - // XXX: check for backpressure - r.scheduler.send(event) - r.processor.send(event) + switch event := event.(type) { + case bcStatusResponse: + r.setMaxPeerHeight(event.height) + r.scheduler.send(event) + case bcAddNewPeer, bcRemovePeer, bcBlockResponse, bcNoBlockResponse: + r.scheduler.send(event) + } + + // Incremental events form scheduler + case event := <-r.scheduler.next(): + switch event := event.(type) { + case scBlockReceived: + r.processor.send(event) + case scPeerError: + r.processor.send(event) + r.reporter.Report(behaviour.BadMessage(event.peerID, "scPeerError")) + case scBlockRequest: + r.io.sendBlockRequest(event.peerID, event.height) + case scFinishedEv: + r.processor.send(event) + r.scheduler.stop() + } + + // Incremental events from processor + case event := <-r.processor.next(): + switch event := event.(type) { + case pcBlockProcessed: + r.setSyncHeight(event.height) + if r.syncHeight%100 == 0 { + lastRate = 0.9*lastRate + 0.1*(100/time.Since(lastHundred).Seconds()) + r.logger.Info("Fast Syncc Rate", "height", r.syncHeight, + "max_peer_height", r.maxPeerHeight, "blocks/s", lastRate) + lastHundred = time.Now() + } + r.scheduler.send(event) + case pcBlockVerificationFailure: + r.scheduler.send(event) + case pcFinished: + r.io.trySwitchToConsensus(event.tmState, event.blocksSynced) + r.processor.stop() + } + + // Terminal events from scheduler + case err := <-r.scheduler.final(): + r.logger.Info(fmt.Sprintf("scheduler final %s", err)) + // send the processor stop? + + // Terminal event from processor + case event := <-r.processor.final(): + r.logger.Info(fmt.Sprintf("processor final %s", event)) + case <-r.stopDemux: r.logger.Info("demuxing stopped") return - case event := <-r.scheduler.next(): - r.processor.send(event) - case event := <-r.processor.next(): - r.scheduler.send(event) - case err := <-r.scheduler.final(): - r.logger.Info(fmt.Sprintf("scheduler final %s", err)) - case err := <-r.processor.final(): - r.logger.Info(fmt.Sprintf("processor final %s", err)) - // XXX: switch to consensus } } } -func (r *Reactor) Stop() { +// Stop implements cmn.Service interface. +func (r *BlockchainReactor) Stop() error { r.logger.Info("reactor stopping") - r.ticker.Stop() r.scheduler.stop() r.processor.stop() close(r.stopDemux) close(r.events) r.logger.Info("reactor stopped") + return nil } -func (r *Reactor) Receive(event Event) { - // XXX: decode and serialize write events - // TODO: backpressure +const ( + // NOTE: keep up to date with bcBlockResponseMessage + bcBlockResponseMessagePrefixSize = 4 + bcBlockResponseMessageFieldKeySize = 1 + maxMsgSize = types.MaxBlockSizeBytes + + bcBlockResponseMessagePrefixSize + + bcBlockResponseMessageFieldKeySize +) + +// BlockchainMessage is a generic message for this reactor. +type BlockchainMessage interface { + ValidateBasic() error +} + +// RegisterBlockchainMessages registers the fast sync messages for amino encoding. +func RegisterBlockchainMessages(cdc *amino.Codec) { + cdc.RegisterInterface((*BlockchainMessage)(nil), nil) + cdc.RegisterConcrete(&bcBlockRequestMessage{}, "tendermint/blockchain/BlockRequest", nil) + cdc.RegisterConcrete(&bcBlockResponseMessage{}, "tendermint/blockchain/BlockResponse", nil) + cdc.RegisterConcrete(&bcNoBlockResponseMessage{}, "tendermint/blockchain/NoBlockResponse", nil) + cdc.RegisterConcrete(&bcStatusResponseMessage{}, "tendermint/blockchain/StatusResponse", nil) + cdc.RegisterConcrete(&bcStatusRequestMessage{}, "tendermint/blockchain/StatusRequest", nil) +} + +func decodeMsg(bz []byte) (msg BlockchainMessage, err error) { + if len(bz) > maxMsgSize { + return msg, fmt.Errorf("msg exceeds max size (%d > %d)", len(bz), maxMsgSize) + } + err = cdc.UnmarshalBinaryBare(bz, &msg) + return +} + +// Receive implements Reactor by handling different message types. +func (r *BlockchainReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) { + msg, err := decodeMsg(msgBytes) + if err != nil { + r.logger.Error("error decoding message", + "src", src.ID(), "chId", chID, "msg", msg, "err", err, "bytes", msgBytes) + _ = r.reporter.Report(behaviour.BadMessage(src.ID(), err.Error())) + return + } + + if err = msg.ValidateBasic(); err != nil { + r.logger.Error("peer sent us invalid msg", "peer", src, "msg", msg, "err", err) + _ = r.reporter.Report(behaviour.BadMessage(src.ID(), err.Error())) + return + } + + r.logger.Debug("Receive", "src", src.ID(), "chID", chID, "msg", msg) + + switch msg := msg.(type) { + case *bcStatusRequestMessage: + if err := r.io.sendStatusResponse(r.store.Height(), src.ID()); err != nil { + r.logger.Error("Could not send status message to peer", "src", src) + } + + case *bcBlockRequestMessage: + block := r.store.LoadBlock(msg.Height) + if block != nil { + if err = r.io.sendBlockToPeer(block, src.ID()); err != nil { + r.logger.Error("Could not send block message to peer: ", err) + } + } else { + r.logger.Info("peer asking for a block we don't have", "src", src, "height", msg.Height) + peerID := src.ID() + if err = r.io.sendBlockNotFound(msg.Height, peerID); err != nil { + r.logger.Error("Couldn't send block not found: ", err) + } + } + + case *bcStatusResponseMessage: + r.events <- bcStatusResponse{peerID: src.ID(), height: msg.Height} + + case *bcBlockResponseMessage: + r.events <- bcBlockResponse{ + peerID: src.ID(), + block: msg.Block, + size: int64(len(msgBytes)), + time: time.Now(), + } + + case *bcNoBlockResponseMessage: + r.events <- bcNoBlockResponse{peerID: src.ID(), height: msg.Height, time: time.Now()} + } +} + +// AddPeer implements Reactor interface +func (r *BlockchainReactor) AddPeer(peer p2p.Peer) { + err := r.io.sendStatusResponse(r.store.Height(), peer.ID()) + if err != nil { + r.logger.Error("Could not send status message to peer new", "src", peer.ID, "height", r.SyncHeight()) + } + r.events <- bcAddNewPeer{peerID: peer.ID()} +} + +// RemovePeer implements Reactor interface. +func (r *BlockchainReactor) RemovePeer(peer p2p.Peer, reason interface{}) { + event := bcRemovePeer{ + peerID: peer.ID(), + reason: reason, + } r.events <- event } -func (r *Reactor) AddPeer() { - // TODO: add peer event and send to demuxer +// GetChannels implements Reactor +func (r *BlockchainReactor) GetChannels() []*p2p.ChannelDescriptor { + return []*p2p.ChannelDescriptor{ + { + ID: BlockchainChannel, + Priority: 10, + SendQueueCapacity: 2000, + RecvBufferCapacity: 50 * 4096, + RecvMessageCapacity: maxMsgSize, + }, + } } diff --git a/blockchain/v2/reactor_test.go b/blockchain/v2/reactor_test.go index 46a2e60c6..10457cdb0 100644 --- a/blockchain/v2/reactor_test.go +++ b/blockchain/v2/reactor_test.go @@ -1,22 +1,517 @@ package v2 import ( + "net" + "os" + "sort" + "sync" "testing" + "time" + + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/behaviour" + cfg "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/libs/service" + "github.com/tendermint/tendermint/mock" + "github.com/tendermint/tendermint/p2p" + "github.com/tendermint/tendermint/p2p/conn" + "github.com/tendermint/tendermint/proxy" + sm "github.com/tendermint/tendermint/state" + "github.com/tendermint/tendermint/store" + "github.com/tendermint/tendermint/types" + tmtime "github.com/tendermint/tendermint/types/time" + dbm "github.com/tendermint/tm-db" ) -func TestReactor(t *testing.T) { +type mockPeer struct { + service.Service + id p2p.ID +} + +func (mp mockPeer) FlushStop() {} +func (mp mockPeer) ID() p2p.ID { return mp.id } +func (mp mockPeer) RemoteIP() net.IP { return net.IP{} } +func (mp mockPeer) RemoteAddr() net.Addr { return &net.TCPAddr{IP: mp.RemoteIP(), Port: 8800} } + +func (mp mockPeer) IsOutbound() bool { return true } +func (mp mockPeer) IsPersistent() bool { return true } +func (mp mockPeer) CloseConn() error { return nil } + +func (mp mockPeer) NodeInfo() p2p.NodeInfo { + return p2p.DefaultNodeInfo{ + DefaultNodeID: "", + ListenAddr: "", + } +} +func (mp mockPeer) Status() conn.ConnectionStatus { return conn.ConnectionStatus{} } +func (mp mockPeer) SocketAddr() *p2p.NetAddress { return &p2p.NetAddress{} } + +func (mp mockPeer) Send(byte, []byte) bool { return true } +func (mp mockPeer) TrySend(byte, []byte) bool { return true } + +func (mp mockPeer) Set(string, interface{}) {} +func (mp mockPeer) Get(string) interface{} { return struct{}{} } + +//nolint:unused +type mockBlockStore struct { + blocks map[int64]*types.Block +} + +func (ml *mockBlockStore) Height() int64 { + return int64(len(ml.blocks)) +} + +func (ml *mockBlockStore) LoadBlock(height int64) *types.Block { + return ml.blocks[height] +} + +func (ml *mockBlockStore) SaveBlock(block *types.Block, part *types.PartSet, commit *types.Commit) { + ml.blocks[block.Height] = block +} + +type mockBlockApplier struct { +} + +// XXX: Add whitelist/blacklist? +func (mba *mockBlockApplier) ApplyBlock(state sm.State, blockID types.BlockID, block *types.Block) (sm.State, error) { + state.LastBlockHeight++ + return state, nil +} + +type mockSwitchIo struct { + mtx sync.Mutex + switchedToConsensus bool + numStatusResponse int + numBlockResponse int + numNoBlockResponse int +} + +func (sio *mockSwitchIo) sendBlockRequest(peerID p2p.ID, height int64) error { + return nil +} + +func (sio *mockSwitchIo) sendStatusResponse(height int64, peerID p2p.ID) error { + sio.mtx.Lock() + defer sio.mtx.Unlock() + sio.numStatusResponse++ + return nil +} + +func (sio *mockSwitchIo) sendBlockToPeer(block *types.Block, peerID p2p.ID) error { + sio.mtx.Lock() + defer sio.mtx.Unlock() + sio.numBlockResponse++ + return nil +} + +func (sio *mockSwitchIo) sendBlockNotFound(height int64, peerID p2p.ID) error { + sio.mtx.Lock() + defer sio.mtx.Unlock() + sio.numNoBlockResponse++ + return nil +} + +func (sio *mockSwitchIo) trySwitchToConsensus(state sm.State, blocksSynced int) { + sio.mtx.Lock() + defer sio.mtx.Unlock() + sio.switchedToConsensus = true +} + +func (sio *mockSwitchIo) hasSwitchedToConsensus() bool { + sio.mtx.Lock() + defer sio.mtx.Unlock() + return sio.switchedToConsensus +} + +func (sio *mockSwitchIo) broadcastStatusRequest(height int64) { +} + +type testReactorParams struct { + logger log.Logger + genDoc *types.GenesisDoc + privVals []types.PrivValidator + startHeight int64 + bufferSize int + mockA bool +} + +func newTestReactor(p testReactorParams) *BlockchainReactor { + store, state, _ := newReactorStore(p.genDoc, p.privVals, p.startHeight) + reporter := behaviour.NewMockReporter() + + var appl blockApplier + + if p.mockA { + appl = &mockBlockApplier{} + } else { + app := &testApp{} + cc := proxy.NewLocalClientCreator(app) + proxyApp := proxy.NewAppConns(cc) + err := proxyApp.Start() + if err != nil { + panic(errors.Wrap(err, "error start app")) + } + db := dbm.NewMemDB() + appl = sm.NewBlockExecutor(db, p.logger, proxyApp.Consensus(), mock.Mempool{}, sm.MockEvidencePool{}) + sm.SaveState(db, state) + } + + r := newReactor(state, store, reporter, appl, p.bufferSize) + logger := log.TestingLogger() + r.SetLogger(logger.With("module", "blockchain")) + + return r +} + +func TestReactorTerminationScenarios(t *testing.T) { + + config := cfg.ResetTestRoot("blockchain_reactor_v2_test") + defer os.RemoveAll(config.RootDir) + genDoc, privVals := randGenesisDoc(config.ChainID(), 1, false, 30) + refStore, _, _ := newReactorStore(genDoc, privVals, 20) + + params := testReactorParams{ + logger: log.TestingLogger(), + genDoc: genDoc, + privVals: privVals, + startHeight: 10, + bufferSize: 100, + mockA: true, + } + + type testEvent struct { + evType string + peer string + height int64 + } + + tests := []struct { + name string + params testReactorParams + msgs []testEvent + }{ + { + name: "simple termination on max peer height - one peer", + params: params, + msgs: []testEvent{ + {evType: "AddPeer", peer: "P1"}, + {evType: "ReceiveS", peer: "P1", height: 13}, + {evType: "BlockReq"}, + {evType: "ReceiveB", peer: "P1", height: 11}, + {evType: "BlockReq"}, + {evType: "BlockReq"}, + {evType: "ReceiveB", peer: "P1", height: 12}, + {evType: "Process"}, + {evType: "ReceiveB", peer: "P1", height: 13}, + {evType: "Process"}, + }, + }, + { + name: "simple termination on max peer height - two peers", + params: params, + msgs: []testEvent{ + {evType: "AddPeer", peer: "P1"}, + {evType: "AddPeer", peer: "P2"}, + {evType: "ReceiveS", peer: "P1", height: 13}, + {evType: "ReceiveS", peer: "P2", height: 15}, + {evType: "BlockReq"}, + {evType: "BlockReq"}, + {evType: "ReceiveB", peer: "P1", height: 11}, + {evType: "ReceiveB", peer: "P2", height: 12}, + {evType: "Process"}, + {evType: "BlockReq"}, + {evType: "BlockReq"}, + {evType: "ReceiveB", peer: "P1", height: 13}, + {evType: "Process"}, + {evType: "ReceiveB", peer: "P2", height: 14}, + {evType: "Process"}, + {evType: "BlockReq"}, + {evType: "ReceiveB", peer: "P2", height: 15}, + {evType: "Process"}, + }, + }, + { + name: "termination on max peer height - two peers, noBlock error", + params: params, + msgs: []testEvent{ + {evType: "AddPeer", peer: "P1"}, + {evType: "AddPeer", peer: "P2"}, + {evType: "ReceiveS", peer: "P1", height: 13}, + {evType: "ReceiveS", peer: "P2", height: 15}, + {evType: "BlockReq"}, + {evType: "BlockReq"}, + {evType: "ReceiveNB", peer: "P1", height: 11}, + {evType: "BlockReq"}, + {evType: "ReceiveB", peer: "P2", height: 12}, + {evType: "ReceiveB", peer: "P2", height: 11}, + {evType: "Process"}, + {evType: "BlockReq"}, + {evType: "BlockReq"}, + {evType: "ReceiveB", peer: "P2", height: 13}, + {evType: "Process"}, + {evType: "ReceiveB", peer: "P2", height: 14}, + {evType: "Process"}, + {evType: "BlockReq"}, + {evType: "ReceiveB", peer: "P2", height: 15}, + {evType: "Process"}, + }, + }, + { + name: "termination on max peer height - two peers, remove one peer", + params: params, + msgs: []testEvent{ + {evType: "AddPeer", peer: "P1"}, + {evType: "AddPeer", peer: "P2"}, + {evType: "ReceiveS", peer: "P1", height: 13}, + {evType: "ReceiveS", peer: "P2", height: 15}, + {evType: "BlockReq"}, + {evType: "BlockReq"}, + {evType: "RemovePeer", peer: "P1"}, + {evType: "BlockReq"}, + {evType: "ReceiveB", peer: "P2", height: 12}, + {evType: "ReceiveB", peer: "P2", height: 11}, + {evType: "Process"}, + {evType: "BlockReq"}, + {evType: "BlockReq"}, + {evType: "ReceiveB", peer: "P2", height: 13}, + {evType: "Process"}, + {evType: "ReceiveB", peer: "P2", height: 14}, + {evType: "Process"}, + {evType: "BlockReq"}, + {evType: "ReceiveB", peer: "P2", height: 15}, + {evType: "Process"}, + }, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + reactor := newTestReactor(params) + reactor.Start() + reactor.reporter = behaviour.NewMockReporter() + mockSwitch := &mockSwitchIo{switchedToConsensus: false} + reactor.io = mockSwitch + // time for go routines to start + time.Sleep(time.Millisecond) + + for _, step := range tt.msgs { + switch step.evType { + case "AddPeer": + reactor.scheduler.send(bcAddNewPeer{peerID: p2p.ID(step.peer)}) + case "RemovePeer": + reactor.scheduler.send(bcRemovePeer{peerID: p2p.ID(step.peer)}) + case "ReceiveS": + reactor.scheduler.send(bcStatusResponse{ + peerID: p2p.ID(step.peer), + height: step.height, + time: time.Now(), + }) + case "ReceiveB": + reactor.scheduler.send(bcBlockResponse{ + peerID: p2p.ID(step.peer), + block: refStore.LoadBlock(step.height), + size: 10, + time: time.Now(), + }) + case "ReceiveNB": + reactor.scheduler.send(bcNoBlockResponse{ + peerID: p2p.ID(step.peer), + height: step.height, + time: time.Now(), + }) + case "BlockReq": + reactor.scheduler.send(rTrySchedule{time: time.Now()}) + case "Process": + reactor.processor.send(rProcessBlock{}) + } + // give time for messages to propagate between routines + time.Sleep(time.Millisecond) + } + + // time for processor to finish and reactor to switch to consensus + time.Sleep(20 * time.Millisecond) + assert.True(t, mockSwitch.hasSwitchedToConsensus()) + reactor.Stop() + }) + } +} + +func TestReactorHelperMode(t *testing.T) { var ( - bufferSize = 10 - reactor = NewReactor(bufferSize) + channelID = byte(0x40) ) - reactor.Start() - script := []Event{ - // TODO + config := cfg.ResetTestRoot("blockchain_reactor_v2_test") + defer os.RemoveAll(config.RootDir) + genDoc, privVals := randGenesisDoc(config.ChainID(), 1, false, 30) + + params := testReactorParams{ + logger: log.TestingLogger(), + genDoc: genDoc, + privVals: privVals, + startHeight: 20, + bufferSize: 100, + mockA: true, } - for _, event := range script { - reactor.Receive(event) + type testEvent struct { + peer string + event interface{} + } + + tests := []struct { + name string + params testReactorParams + msgs []testEvent + }{ + { + name: "status request", + params: params, + msgs: []testEvent{ + {"P1", bcStatusRequestMessage{}}, + {"P1", bcBlockRequestMessage{Height: 13}}, + {"P1", bcBlockRequestMessage{Height: 20}}, + {"P1", bcBlockRequestMessage{Height: 22}}, + }, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + reactor := newTestReactor(params) + reactor.Start() + mockSwitch := &mockSwitchIo{switchedToConsensus: false} + reactor.io = mockSwitch + + for i := 0; i < len(tt.msgs); i++ { + step := tt.msgs[i] + switch ev := step.event.(type) { + case bcStatusRequestMessage: + old := mockSwitch.numStatusResponse + reactor.Receive(channelID, mockPeer{id: p2p.ID(step.peer)}, cdc.MustMarshalBinaryBare(ev)) + assert.Equal(t, old+1, mockSwitch.numStatusResponse) + case bcBlockRequestMessage: + if ev.Height > params.startHeight { + old := mockSwitch.numNoBlockResponse + reactor.Receive(channelID, mockPeer{id: p2p.ID(step.peer)}, cdc.MustMarshalBinaryBare(ev)) + assert.Equal(t, old+1, mockSwitch.numNoBlockResponse) + } else { + old := mockSwitch.numBlockResponse + reactor.Receive(channelID, mockPeer{id: p2p.ID(step.peer)}, cdc.MustMarshalBinaryBare(ev)) + assert.Equal(t, old+1, mockSwitch.numBlockResponse) + } + } + } + reactor.Stop() + }) } - reactor.Stop() +} + +//---------------------------------------------- +// utility funcs + +func makeTxs(height int64) (txs []types.Tx) { + for i := 0; i < 10; i++ { + txs = append(txs, types.Tx([]byte{byte(height), byte(i)})) + } + return txs +} + +func makeBlock(height int64, state sm.State, lastCommit *types.Commit) *types.Block { + block, _ := state.MakeBlock(height, makeTxs(height), lastCommit, nil, state.Validators.GetProposer().Address) + return block +} + +type testApp struct { + abci.BaseApplication +} + +func randGenesisDoc(chainID string, numValidators int, randPower bool, minPower int64) ( + *types.GenesisDoc, []types.PrivValidator) { + validators := make([]types.GenesisValidator, numValidators) + privValidators := make([]types.PrivValidator, numValidators) + for i := 0; i < numValidators; i++ { + val, privVal := types.RandValidator(randPower, minPower) + validators[i] = types.GenesisValidator{ + PubKey: val.PubKey, + Power: val.VotingPower, + } + privValidators[i] = privVal + } + sort.Sort(types.PrivValidatorsByAddress(privValidators)) + + return &types.GenesisDoc{ + GenesisTime: tmtime.Now(), + ChainID: chainID, + Validators: validators, + }, privValidators +} + +// Why are we importing the entire blockExecutor dependency graph here +// when we have the facilities to +func newReactorStore( + genDoc *types.GenesisDoc, + privVals []types.PrivValidator, + maxBlockHeight int64) (*store.BlockStore, sm.State, *sm.BlockExecutor) { + if len(privVals) != 1 { + panic("only support one validator") + } + app := &testApp{} + cc := proxy.NewLocalClientCreator(app) + proxyApp := proxy.NewAppConns(cc) + err := proxyApp.Start() + if err != nil { + panic(errors.Wrap(err, "error start app")) + } + + stateDB := dbm.NewMemDB() + blockStore := store.NewBlockStore(dbm.NewMemDB()) + + state, err := sm.LoadStateFromDBOrGenesisDoc(stateDB, genDoc) + if err != nil { + panic(errors.Wrap(err, "error constructing state from genesis file")) + } + + db := dbm.NewMemDB() + blockExec := sm.NewBlockExecutor(db, log.TestingLogger(), proxyApp.Consensus(), + mock.Mempool{}, sm.MockEvidencePool{}) + sm.SaveState(db, state) + + // add blocks in + for blockHeight := int64(1); blockHeight <= maxBlockHeight; blockHeight++ { + lastCommit := types.NewCommit(blockHeight-1, 0, types.BlockID{}, nil) + if blockHeight > 1 { + lastBlockMeta := blockStore.LoadBlockMeta(blockHeight - 1) + lastBlock := blockStore.LoadBlock(blockHeight - 1) + vote, err := types.MakeVote( + lastBlock.Header.Height, + lastBlockMeta.BlockID, + state.Validators, + privVals[0], + lastBlock.Header.ChainID) + if err != nil { + panic(err) + } + lastCommit = types.NewCommit(vote.Height, vote.Round, + lastBlockMeta.BlockID, []types.CommitSig{vote.CommitSig()}) + } + + thisBlock := makeBlock(blockHeight, state, lastCommit) + + thisParts := thisBlock.MakePartSet(types.BlockPartSizeBytes) + blockID := types.BlockID{Hash: thisBlock.Hash(), PartsHeader: thisParts.Header()} + + state, err = blockExec.ApplyBlock(state, blockID, thisBlock) + if err != nil { + panic(errors.Wrap(err, "error apply block")) + } + + blockStore.SaveBlock(thisBlock, thisParts, lastCommit) + } + return blockStore, state, blockExec } diff --git a/blockchain/v2/routine.go b/blockchain/v2/routine.go index 897dd738c..1a883c3c4 100644 --- a/blockchain/v2/routine.go +++ b/blockchain/v2/routine.go @@ -10,7 +10,7 @@ import ( type handleFunc = func(event Event) (Event, error) -// Routines are a structure which model a finite state machine as serialized +// Routine is a structure that models a finite state machine as serialized // stream of events processed by a handle function. This Routine structure // handles the concurrency and messaging guarantees. Events are sent via // `send` are handled by the `handle` function to produce an iterator @@ -80,7 +80,7 @@ func (rt *Routine) start() { return } rt.metrics.EventsOut.With("routine", rt.name).Add(1) - rt.logger.Debug(fmt.Sprintf("%s produced %T %+v\n", rt.name, oEvent, oEvent)) + rt.logger.Debug(fmt.Sprintf("%s: produced %T %+v\n", rt.name, oEvent, oEvent)) rt.out <- oEvent } @@ -98,6 +98,7 @@ func (rt *Routine) send(event Event) bool { rt.logger.Info(fmt.Sprintf("%s: send failed, queue was full/stopped \n", rt.name)) return false } + rt.metrics.EventsSent.With("routine", rt.name).Add(1) return true } diff --git a/blockchain/v2/scheduler.go b/blockchain/v2/scheduler.go index ab3892dc5..3cf0b2468 100644 --- a/blockchain/v2/scheduler.go +++ b/blockchain/v2/scheduler.go @@ -11,52 +11,11 @@ import ( "github.com/tendermint/tendermint/types" ) -// Events - -// XXX: The handle API would be much simpler if it return a single event, an -// Event, which embeds a terminationEvent if it wants to terminate the routine. - -// Input events into the scheduler: -// ticker event for cleaning peers -type tryPrunePeer struct { - priorityHigh - time time.Time -} - -// ticker event for scheduling block requests -type trySchedule struct { - priorityHigh - time time.Time -} - -// blockResponse message received from a peer -type bcBlockResponse struct { - priorityNormal - time time.Time - peerID p2p.ID - height int64 - size int64 - block *types.Block -} - -// statusResponse message received from a peer -type bcStatusResponse struct { - priorityNormal - time time.Time - peerID p2p.ID - height int64 -} - -// new peer is connected -type addNewPeer struct { - priorityNormal - peerID p2p.ID -} - -// Output events issued by the scheduler: +// Events generated by the scheduler: // all blocks have been processed type scFinishedEv struct { priorityNormal + reason string } // send a blockRequest message @@ -80,6 +39,10 @@ type scPeerError struct { reason error } +func (e scPeerError) String() string { + return fmt.Sprintf("scPeerError - peerID %s, err %s", e.peerID, e.reason) +} + // scheduler removed a set of peers (timed out or slow peer) type scPeersPruned struct { priorityHigh @@ -160,9 +123,10 @@ func (p scPeer) String() string { func newScPeer(peerID p2p.ID) *scPeer { return &scPeer{ - peerID: peerID, - state: peerStateNew, - height: -1, + peerID: peerID, + state: peerStateNew, + height: -1, + lastTouched: time.Time{}, } } @@ -176,11 +140,17 @@ type scheduler struct { // in Processed state. height int64 + // lastAdvance tracks the last time a block execution happened. + // syncTimeout is the maximum time the scheduler waits to advance in the fast sync process before finishing. + // This covers the cases where there are no peers or all peers have a lower height. + lastAdvance time.Time + syncTimeout time.Duration + // a map of peerID to scheduler specific peer struct `scPeer` used to keep // track of peer specific state peers map[p2p.ID]*scPeer - peerTimeout time.Duration - minRecvRate int64 // minimum receive rate from peer otherwise prune + peerTimeout time.Duration // maximum response time from a peer otherwise prune + minRecvRate int64 // minimum receive rate from peer otherwise prune // the maximum number of blocks that should be New, Received or Pending at any point // in time. This is used to enforce a limit on the blockStates map. @@ -204,15 +174,20 @@ func (sc scheduler) String() string { sc.initHeight, sc.blockStates, sc.peers, sc.pendingBlocks, sc.pendingTime, sc.receivedBlocks) } -func newScheduler(initHeight int64) *scheduler { +func newScheduler(initHeight int64, startTime time.Time) *scheduler { sc := scheduler{ initHeight: initHeight, + lastAdvance: startTime, + syncTimeout: 60 * time.Second, height: initHeight + 1, blockStates: make(map[int64]blockState), peers: make(map[p2p.ID]*scPeer), pendingBlocks: make(map[int64]p2p.ID), pendingTime: make(map[int64]time.Time), receivedBlocks: make(map[int64]p2p.ID), + targetPending: 10, // TODO - pass as param + peerTimeout: 15 * time.Second, // TODO - pass as param + minRecvRate: 0, //int64(7680), TODO - pass as param } return &sc @@ -316,6 +291,7 @@ func (sc *scheduler) setPeerHeight(peerID p2p.ID, height int64) error { } if height < peer.height { + sc.removePeer(peerID) return fmt.Errorf("cannot move peer height lower. from %d to %d", peer.height, height) } @@ -327,7 +303,7 @@ func (sc *scheduler) setPeerHeight(peerID p2p.ID, height int64) error { } func (sc *scheduler) getStateAtHeight(height int64) blockState { - if height <= sc.initHeight { + if height < sc.height { return blockStateProcessed } else if state, ok := sc.blockStates[height]; ok { return state @@ -349,41 +325,8 @@ func (sc *scheduler) getPeersAtHeightOrAbove(height int64) []p2p.ID { return peers } -func (sc *scheduler) peersInactiveSince(duration time.Duration, now time.Time) []p2p.ID { - peers := []p2p.ID{} - for _, peer := range sc.peers { - if peer.state != peerStateReady { - continue - } - if now.Sub(peer.lastTouched) > duration { - peers = append(peers, peer.peerID) - } - } - - // Ensure the order is deterministic for testing - sort.Sort(PeerByID(peers)) - return peers -} - -// will return peers who's lastRate i slower than minSpeed denominated in bytes -func (sc *scheduler) peersSlowerThan(minSpeed int64) []p2p.ID { - peers := []p2p.ID{} - for peerID, peer := range sc.peers { - if peer.state != peerStateReady { - continue - } - if peer.lastRate < minSpeed { - peers = append(peers, peerID) - } - } - - // Ensure the order is deterministic for testing - sort.Sort(PeerByID(peers)) - return peers -} - func (sc *scheduler) prunablePeers(peerTimout time.Duration, minRecvRate int64, now time.Time) []p2p.ID { - prunable := []p2p.ID{} + prunable := make([]p2p.ID, 0) for peerID, peer := range sc.peers { if peer.state != peerStateReady { continue @@ -407,8 +350,8 @@ func (sc *scheduler) markReceived(peerID p2p.ID, height int64, size int64, now t return fmt.Errorf("couldn't find peer %s", peerID) } - if peer.state == peerStateRemoved { - return fmt.Errorf("cannot receive blocks from removed peer %s", peerID) + if peer.state != peerStateReady { + return fmt.Errorf("cannot receive blocks from not ready peer %s", peerID) } if state := sc.getStateAtHeight(height); state != blockStatePending || sc.pendingBlocks[height] != peerID { @@ -454,14 +397,13 @@ func (sc *scheduler) markPending(peerID p2p.ID, height int64, time time.Time) er sc.setStateAtHeight(height, blockStatePending) sc.pendingBlocks[height] = peerID - // XXX: to make this more accurate we can introduce a message from - // the IO routine which indicates the time the request was put on the wire sc.pendingTime[height] = time return nil } func (sc *scheduler) markProcessed(height int64) error { + sc.lastAdvance = time.Now() state := sc.getStateAtHeight(height) if state != blockStateReceived { return fmt.Errorf("cannot mark height %d received from block state %s", height, state) @@ -476,6 +418,9 @@ func (sc *scheduler) markProcessed(height int64) error { } func (sc *scheduler) allBlocksProcessed() bool { + if len(sc.peers) == 0 { + return false + } return sc.height >= sc.maxHeight() } @@ -486,7 +431,7 @@ func (sc *scheduler) maxHeight() int64 { if peer.state != peerStateReady { continue } - if peer.height > max { + if max < peer.height { max = peer.height } } @@ -532,15 +477,15 @@ func (sc *scheduler) selectPeer(height int64) (p2p.ID, error) { } // find the set of peers with minimum number of pending requests. - minPending := math.MaxInt64 + var minPending int64 = math.MaxInt64 for mp := range pendingFrom { - if mp < minPending { - minPending = mp + if int64(mp) < minPending { + minPending = int64(mp) } } - sort.Sort(PeerByID(pendingFrom[minPending])) - return pendingFrom[minPending][0], nil + sort.Sort(PeerByID(pendingFrom[int(minPending)])) + return pendingFrom[int(minPending)][0], nil } // PeerByID is a list of peers sorted by peerID. @@ -570,12 +515,30 @@ func (sc *scheduler) handleBlockResponse(event bcBlockResponse) (Event, error) { err = sc.markReceived(event.peerID, event.block.Height, event.size, event.time) if err != nil { + _ = sc.removePeer(event.peerID) return scPeerError{peerID: event.peerID, reason: err}, nil } return scBlockReceived{peerID: event.peerID, block: event.block}, nil } +func (sc *scheduler) handleNoBlockResponse(event bcNoBlockResponse) (Event, error) { + if len(sc.peers) == 0 { + return noOp, nil + } + + peer, ok := sc.peers[event.peerID] + if !ok || peer.state == peerStateRemoved { + return noOp, nil + } + // The peer may have been just removed due to errors, low speed or timeouts. + _ = sc.removePeer(event.peerID) + + return scPeerError{peerID: event.peerID, + reason: fmt.Errorf("peer %v with height %d claims no block for %d", + event.peerID, peer.height, event.height)}, nil +} + func (sc *scheduler) handleBlockProcessed(event pcBlockProcessed) (Event, error) { if event.height != sc.height { panic(fmt.Sprintf("processed height %d but expected height %d", event.height, sc.height)) @@ -584,12 +547,12 @@ func (sc *scheduler) handleBlockProcessed(event pcBlockProcessed) (Event, error) if err != nil { // It is possible that a peer error or timeout is handled after the processor // has processed the block but before the scheduler received this event, - // so when pcBlockProcessed event is received the block had been requested again + // so when pcBlockProcessed event is received the block had been requested again. return scSchedulerFail{reason: err}, nil } if sc.allBlocksProcessed() { - return scFinishedEv{}, nil + return scFinishedEv{reason: "processed all blocks"}, nil } return noOp, nil @@ -608,13 +571,13 @@ func (sc *scheduler) handleBlockProcessError(event pcBlockVerificationFailure) ( } if sc.allBlocksProcessed() { - return scFinishedEv{}, nil + return scFinishedEv{reason: "error on last block"}, nil } return noOp, nil } -func (sc *scheduler) handleAddNewPeer(event addNewPeer) (Event, error) { +func (sc *scheduler) handleAddNewPeer(event bcAddNewPeer) (Event, error) { err := sc.addPeer(event.peerID) if err != nil { return scSchedulerFail{reason: err}, nil @@ -622,8 +585,7 @@ func (sc *scheduler) handleAddNewPeer(event addNewPeer) (Event, error) { return noOp, nil } -// XXX: unify types peerError -func (sc *scheduler) handlePeerError(event peerError) (Event, error) { +func (sc *scheduler) handleRemovePeer(event bcRemovePeer) (Event, error) { err := sc.removePeer(event.peerID) if err != nil { // XXX - It is possible that the removePeer fails here for legitimate reasons @@ -631,12 +593,23 @@ func (sc *scheduler) handlePeerError(event peerError) (Event, error) { return scSchedulerFail{reason: err}, nil } if sc.allBlocksProcessed() { - return scFinishedEv{}, nil + return scFinishedEv{reason: "removed peer"}, nil } return noOp, nil } -func (sc *scheduler) handleTryPrunePeer(event tryPrunePeer) (Event, error) { +func (sc *scheduler) handleTryPrunePeer(event rTryPrunePeer) (Event, error) { + + // Check behavior of peer responsible to deliver block at sc.height. + timeHeightAsked, ok := sc.pendingTime[sc.height] + if ok && time.Since(timeHeightAsked) > sc.peerTimeout { + // A request was sent to a peer for block at sc.height but a response was not received + // from that peer within sc.peerTimeout. Remove the peer. This is to ensure that a peer + // will be timed out even if it sends blocks at higher heights but prevents progress by + // not sending the block at current height. + sc.removePeer(sc.pendingBlocks[sc.height]) + } + prunablePeers := sc.prunablePeers(sc.peerTimeout, sc.minRecvRate, event.time) if len(prunablePeers) == 0 { return noOp, nil @@ -649,17 +622,19 @@ func (sc *scheduler) handleTryPrunePeer(event tryPrunePeer) (Event, error) { } } - // If all blocks are processed we should finish even some peers were pruned. + // If all blocks are processed we should finish. if sc.allBlocksProcessed() { - return scFinishedEv{}, nil + return scFinishedEv{reason: "after try prune"}, nil } return scPeersPruned{peers: prunablePeers}, nil } -// TODO - Schedule multiple block requests -func (sc *scheduler) handleTrySchedule(event trySchedule) (Event, error) { +func (sc *scheduler) handleTrySchedule(event rTrySchedule) (Event, error) { + if time.Since(sc.lastAdvance) > sc.syncTimeout { + return scFinishedEv{reason: "timeout, no advance"}, nil + } nextHeight := sc.nextHeightToSchedule() if nextHeight == -1 { @@ -693,17 +668,20 @@ func (sc *scheduler) handle(event Event) (Event, error) { case bcBlockResponse: nextEvent, err := sc.handleBlockResponse(event) return nextEvent, err - case trySchedule: + case bcNoBlockResponse: + nextEvent, err := sc.handleNoBlockResponse(event) + return nextEvent, err + case rTrySchedule: nextEvent, err := sc.handleTrySchedule(event) return nextEvent, err - case addNewPeer: + case bcAddNewPeer: nextEvent, err := sc.handleAddNewPeer(event) return nextEvent, err - case tryPrunePeer: - nextEvent, err := sc.handleTryPrunePeer(event) + case bcRemovePeer: + nextEvent, err := sc.handleRemovePeer(event) return nextEvent, err - case peerError: - nextEvent, err := sc.handlePeerError(event) + case rTryPrunePeer: + nextEvent, err := sc.handleTryPrunePeer(event) return nextEvent, err case pcBlockProcessed: nextEvent, err := sc.handleBlockProcessed(event) @@ -714,5 +692,4 @@ func (sc *scheduler) handle(event Event) (Event, error) { default: return scSchedulerFail{reason: fmt.Errorf("unknown event %v", event)}, nil } - //return noOp, nil } diff --git a/blockchain/v2/scheduler_test.go b/blockchain/v2/scheduler_test.go index a3a6db672..445ba51a7 100644 --- a/blockchain/v2/scheduler_test.go +++ b/blockchain/v2/scheduler_test.go @@ -23,6 +23,8 @@ type scTestParams struct { peerTimeout time.Duration minRecvRate int64 targetPending int + startTime time.Time + syncTimeout time.Duration } func verifyScheduler(sc *scheduler) { @@ -37,8 +39,9 @@ func verifyScheduler(sc *scheduler) { func newTestScheduler(params scTestParams) *scheduler { peers := make(map[p2p.ID]*scPeer) + var maxHeight int64 - sc := newScheduler(params.initHeight) + sc := newScheduler(params.initHeight, params.startTime) if params.height != 0 { sc.height = params.height } @@ -46,6 +49,9 @@ func newTestScheduler(params scTestParams) *scheduler { for id, peer := range params.peers { peer.peerID = p2p.ID(id) peers[p2p.ID(id)] = peer + if maxHeight < peer.height { + maxHeight = peer.height + } } for _, h := range params.allB { sc.blockStates[h] = blockStateNew @@ -64,6 +70,12 @@ func newTestScheduler(params scTestParams) *scheduler { sc.peers = peers sc.peerTimeout = params.peerTimeout + if params.syncTimeout == 0 { + sc.syncTimeout = 10 * time.Second + } else { + sc.syncTimeout = params.syncTimeout + } + if params.targetPending == 0 { sc.targetPending = 10 } else { @@ -80,7 +92,7 @@ func newTestScheduler(params scTestParams) *scheduler { func TestScInit(t *testing.T) { var ( initHeight int64 = 5 - sc = newScheduler(initHeight) + sc = newScheduler(initHeight, time.Now()) ) assert.Equal(t, blockStateProcessed, sc.getStateAtHeight(initHeight)) assert.Equal(t, blockStateUnknown, sc.getStateAtHeight(initHeight+1)) @@ -181,21 +193,21 @@ func TestScAddPeer(t *testing.T) { name: "add first peer", fields: scTestParams{}, args: args{peerID: "P1"}, - wantFields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateNew, height: -1}}}, + wantFields: scTestParams{peers: map[string]*scPeer{"P1": {height: -1, state: peerStateNew}}}, }, { name: "add second peer", - fields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateNew, height: -1}}}, + fields: scTestParams{peers: map[string]*scPeer{"P1": {height: -1, state: peerStateNew}}}, args: args{peerID: "P2"}, wantFields: scTestParams{peers: map[string]*scPeer{ - "P1": {state: peerStateNew, height: -1}, - "P2": {state: peerStateNew, height: -1}}}, + "P1": {height: -1, state: peerStateNew}, + "P2": {height: -1, state: peerStateNew}}}, }, { name: "attempt to add duplicate peer", - fields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateNew, height: -1}}}, + fields: scTestParams{peers: map[string]*scPeer{"P1": {height: -1}}}, args: args{peerID: "P1"}, - wantFields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateNew, height: -1}}}, + wantFields: scTestParams{peers: map[string]*scPeer{"P1": {height: -1}}}, wantErr: true, }, { @@ -271,8 +283,8 @@ func TestScTouchPeer(t *testing.T) { name: "touch peer in state Ready", fields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateReady, lastTouched: now}}}, args: args{peerID: "P1", time: now.Add(3 * time.Second)}, - wantFields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateReady, - lastTouched: now.Add(3 * time.Second)}}}, + wantFields: scTestParams{peers: map[string]*scPeer{ + "P1": {state: peerStateReady, lastTouched: now.Add(3 * time.Second)}}}, }, } @@ -289,195 +301,6 @@ func TestScTouchPeer(t *testing.T) { } } -func TestScPeersInactiveSince(t *testing.T) { - now := time.Now() - - type args struct { - threshold time.Duration - time time.Time - } - - tests := []struct { - name string - fields scTestParams - args args - wantResult []p2p.ID - }{ - { - name: "no peers", - fields: scTestParams{peers: map[string]*scPeer{}}, - args: args{threshold: time.Second, time: now}, - wantResult: []p2p.ID{}, - }, - { - name: "one active peer", - fields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateReady, lastTouched: now}}}, - args: args{threshold: time.Second, time: now}, - wantResult: []p2p.ID{}, - }, - { - name: "one inactive peer", - fields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateReady, lastTouched: now}}}, - args: args{threshold: time.Second, time: now.Add(time.Second + time.Millisecond)}, - wantResult: []p2p.ID{"P1"}, - }, - { - name: "one active and one inactive peer", - fields: scTestParams{peers: map[string]*scPeer{ - "P1": {state: peerStateReady, lastTouched: now}, - "P2": {state: peerStateReady, lastTouched: now.Add(time.Second)}}}, - args: args{threshold: time.Second, time: now.Add(time.Second + time.Millisecond)}, - wantResult: []p2p.ID{"P1"}, - }, - { - name: "one New peer", - fields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateNew}}}, - args: args{threshold: time.Second, time: now.Add(time.Millisecond)}, - wantResult: []p2p.ID{}, - }, - { - name: "one Removed peer", - fields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateRemoved, lastTouched: now}}}, - args: args{threshold: time.Second, time: now.Add(time.Millisecond)}, - wantResult: []p2p.ID{}, - }, - { - name: "one Ready active peer and one New", - fields: scTestParams{peers: map[string]*scPeer{ - "P1": {state: peerStateRemoved, lastTouched: now}, - "P2": {state: peerStateReady, lastTouched: now.Add(time.Millisecond)}}}, - args: args{threshold: time.Second, time: now.Add(2 * time.Millisecond)}, - wantResult: []p2p.ID{}, - }, - { - name: "one Ready inactive peer and one New", - fields: scTestParams{peers: map[string]*scPeer{ - "P1": {state: peerStateRemoved, lastTouched: now}, - "P2": {state: peerStateReady, lastTouched: now.Add(time.Millisecond)}}}, - args: args{threshold: time.Second, time: now.Add(time.Second + 2*time.Millisecond)}, - wantResult: []p2p.ID{"P2"}, - }, - { - name: "combination of New, Removed and, active and non active Ready peers", - fields: scTestParams{peers: map[string]*scPeer{ - "P1": {state: peerStateNew}, - "P2": {state: peerStateRemoved, lastTouched: now}, - "P3": {state: peerStateRemoved, lastTouched: now.Add(time.Second)}, - "P4": {state: peerStateReady, lastTouched: now.Add(time.Millisecond)}, - "P5": {state: peerStateReady, lastTouched: now.Add(3 * time.Millisecond)}}}, - args: args{threshold: time.Second, time: now.Add(time.Second + 2*time.Millisecond)}, - wantResult: []p2p.ID{"P4"}, - }, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - sc := newTestScheduler(tt.fields) - // peersInactiveSince should not mutate the scheduler - wantSc := sc - res := sc.peersInactiveSince(tt.args.threshold, tt.args.time) - sort.Sort(PeerByID(res)) - assert.Equal(t, tt.wantResult, res) - assert.Equal(t, wantSc, sc) - }) - } -} - -func TestScPeersSlowerThan(t *testing.T) { - type args struct { - minSpeed int64 - } - - tests := []struct { - name string - fields scTestParams - args args - wantResult []p2p.ID - }{ - { - name: "no peers", - fields: scTestParams{peers: map[string]*scPeer{}}, - args: args{minSpeed: 100}, - wantResult: []p2p.ID{}, - }, - { - name: "one Ready faster peer", - fields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateReady, lastRate: 101}}}, - args: args{minSpeed: 100}, - wantResult: []p2p.ID{}, - }, - { - name: "one Ready equal peer", - fields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateReady, lastRate: 100}}}, - args: args{minSpeed: 100}, - wantResult: []p2p.ID{}, - }, - { - name: "one Ready slow peer", - fields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateReady, lastRate: 99}}}, - args: args{minSpeed: 100}, - wantResult: []p2p.ID{"P1"}, - }, - { - name: "one Removed faster peer", - fields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateRemoved, lastRate: 101}}}, - args: args{minSpeed: 100}, - wantResult: []p2p.ID{}, - }, { - name: "one Removed equal peer", - fields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateRemoved, lastRate: 100}}}, - args: args{minSpeed: 100}, - wantResult: []p2p.ID{}, - }, - { - name: "one Removed slow peer", - fields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateRemoved, lastRate: 99}}}, - args: args{minSpeed: 100}, - wantResult: []p2p.ID{}, - }, - { - name: "one New peer", - fields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateNew}}}, - args: args{minSpeed: 100}, - wantResult: []p2p.ID{}, - }, - { - name: "one New peer", - fields: scTestParams{peers: map[string]*scPeer{"P1": {state: peerStateNew}}}, - args: args{minSpeed: 100}, - wantResult: []p2p.ID{}, - }, - { - name: "mixed peers", - fields: scTestParams{peers: map[string]*scPeer{ - "P1": {state: peerStateRemoved, lastRate: 101}, - "P2": {state: peerStateReady, lastRate: 101}, - "P3": {state: peerStateRemoved, lastRate: 100}, - "P4": {state: peerStateReady, lastRate: 100}, - "P5": {state: peerStateReady, lastRate: 99}, - "P6": {state: peerStateNew}, - "P7": {state: peerStateRemoved, lastRate: 99}, - "P8": {state: peerStateReady, lastRate: 99}, - }}, - args: args{minSpeed: 100}, - wantResult: []p2p.ID{"P5", "P8"}, - }, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - sc := newTestScheduler(tt.fields) - // peersSlowerThan should not mutate the scheduler - wantSc := sc - res := sc.peersSlowerThan(tt.args.minSpeed) - assert.Equal(t, tt.wantResult, res) - assert.Equal(t, wantSc, sc) - }) - } -} - func TestScPrunablePeers(t *testing.T) { now := time.Now() @@ -716,8 +539,8 @@ func TestScSetPeerHeight(t *testing.T) { allB: []int64{1, 2, 3, 4}}, args: args{peerID: "P1", height: 2}, wantFields: scTestParams{ - peers: map[string]*scPeer{"P1": {height: 4, state: peerStateReady}}, - allB: []int64{1, 2, 3, 4}}, + peers: map[string]*scPeer{"P1": {height: 4, state: peerStateRemoved}}, + allB: []int64{}}, wantErr: true, }, { @@ -845,7 +668,7 @@ func TestScGetPeersAtHeight(t *testing.T) { tt := tt t.Run(tt.name, func(t *testing.T) { sc := newTestScheduler(tt.fields) - // getPeersAtHeightOrAbove should not mutate the scheduler + // getPeersAtHeight should not mutate the scheduler wantSc := sc res := sc.getPeersAtHeightOrAbove(tt.args.height) sort.Sort(PeerByID(res)) @@ -1082,8 +905,11 @@ func TestScMarkReceived(t *testing.T) { tt := tt t.Run(tt.name, func(t *testing.T) { sc := newTestScheduler(tt.fields) - if err := sc.markReceived(tt.args.peerID, - tt.args.height, tt.args.size, now.Add(time.Second)); (err != nil) != tt.wantErr { + if err := sc.markReceived( + tt.args.peerID, + tt.args.height, + tt.args.size, + now.Add(time.Second)); (err != nil) != tt.wantErr { t.Errorf("markReceived() wantErr %v, error = %v", tt.wantErr, err) } wantSc := newTestScheduler(tt.wantFields) @@ -1145,11 +971,17 @@ func TestScMarkProcessed(t *testing.T) { tt := tt t.Run(tt.name, func(t *testing.T) { sc := newTestScheduler(tt.fields) + oldBlockState := sc.getStateAtHeight(tt.args.height) if err := sc.markProcessed(tt.args.height); (err != nil) != tt.wantErr { t.Errorf("markProcessed() wantErr %v, error = %v", tt.wantErr, err) } + if tt.wantErr { + assert.Equal(t, oldBlockState, sc.getStateAtHeight(tt.args.height)) + } else { + assert.Equal(t, blockStateProcessed, sc.getStateAtHeight(tt.args.height)) + } wantSc := newTestScheduler(tt.wantFields) - assert.Equal(t, wantSc, sc) + checkSameScheduler(t, wantSc, sc) }) } } @@ -1163,9 +995,9 @@ func TestScAllBlocksProcessed(t *testing.T) { wantResult bool }{ { - name: "no blocks", + name: "no blocks, no peers", fields: scTestParams{}, - wantResult: true, + wantResult: false, }, { name: "only New blocks", @@ -1225,7 +1057,7 @@ func TestScAllBlocksProcessed(t *testing.T) { wantSc := sc res := sc.allBlocksProcessed() assert.Equal(t, tt.wantResult, res) - assert.Equal(t, wantSc, sc) + checkSameScheduler(t, wantSc, sc) }) } } @@ -1305,8 +1137,7 @@ func TestScNextHeightToSchedule(t *testing.T) { resMin := sc.nextHeightToSchedule() assert.Equal(t, tt.wantHeight, resMin) - assert.Equal(t, wantSc, sc) - + checkSameScheduler(t, wantSc, sc) }) } } @@ -1414,7 +1245,7 @@ func TestScSelectPeer(t *testing.T) { res, err := sc.selectPeer(tt.args.height) assert.Equal(t, tt.wantResult, res) assert.Equal(t, tt.wantError, err != nil) - assert.Equal(t, wantSc, sc) + checkSameScheduler(t, wantSc, sc) }) } } @@ -1424,6 +1255,20 @@ func makeScBlock(height int64) *types.Block { return &types.Block{Header: types.Header{Height: height}} } +// used in place of assert.Equal(t, want, actual) to avoid failures due to +// scheduler.lastAdvanced timestamp inequalities. +func checkSameScheduler(t *testing.T, want *scheduler, actual *scheduler) { + assert.Equal(t, want.initHeight, actual.initHeight) + assert.Equal(t, want.height, actual.height) + assert.Equal(t, want.peers, actual.peers) + assert.Equal(t, want.blockStates, actual.blockStates) + assert.Equal(t, want.pendingBlocks, actual.pendingBlocks) + assert.Equal(t, want.pendingTime, actual.pendingTime) + assert.Equal(t, want.blockStates, actual.blockStates) + assert.Equal(t, want.receivedBlocks, actual.receivedBlocks) + assert.Equal(t, want.blockStates, actual.blockStates) +} + // checkScResults checks scheduler handler test results func checkScResults(t *testing.T, wantErr bool, err error, wantEvent Event, event Event) { if (err != nil) != wantErr { @@ -1439,8 +1284,6 @@ func checkScResults(t *testing.T, wantErr bool, err error, wantEvent Event, even assert.Equal(t, wantEvent.block, event.(scBlockReceived).block) case scSchedulerFail: assert.Equal(t, wantEvent.reason != nil, event.(scSchedulerFail).reason != nil) - default: - assert.Equal(t, wantEvent, event) } } @@ -1449,7 +1292,6 @@ func TestScHandleBlockResponse(t *testing.T) { block6FromP1 := bcBlockResponse{ time: now.Add(time.Millisecond), peerID: p2p.ID("P1"), - height: 6, size: 100, block: makeScBlock(6), } @@ -1530,6 +1372,82 @@ func TestScHandleBlockResponse(t *testing.T) { } } +func TestScHandleNoBlockResponse(t *testing.T) { + now := time.Now() + noBlock6FromP1 := bcNoBlockResponse{ + time: now.Add(time.Millisecond), + peerID: p2p.ID("P1"), + height: 6, + } + + tests := []struct { + name string + fields scTestParams + wantEvent Event + wantFields scTestParams + wantErr bool + }{ + { + name: "empty scheduler", + fields: scTestParams{}, + wantEvent: noOpEvent{}, + wantFields: scTestParams{}, + }, + { + name: "noBlock from removed peer", + fields: scTestParams{peers: map[string]*scPeer{"P1": {height: 8, state: peerStateRemoved}}}, + wantEvent: noOpEvent{}, + wantFields: scTestParams{peers: map[string]*scPeer{"P1": {height: 8, state: peerStateRemoved}}}, + }, + { + name: "for block we haven't asked for", + fields: scTestParams{ + peers: map[string]*scPeer{"P1": {height: 8, state: peerStateReady}}, + allB: []int64{1, 2, 3, 4, 5, 6, 7, 8}}, + wantEvent: scPeerError{peerID: "P1", reason: fmt.Errorf("some error")}, + wantFields: scTestParams{peers: map[string]*scPeer{"P1": {height: 8, state: peerStateRemoved}}}, + }, + { + name: "noBlock from peer we don't have", + fields: scTestParams{ + peers: map[string]*scPeer{"P2": {height: 8, state: peerStateReady}}, + allB: []int64{1, 2, 3, 4, 5, 6, 7, 8}, + pending: map[int64]p2p.ID{6: "P2"}, + pendingTime: map[int64]time.Time{6: now}, + }, + wantEvent: noOpEvent{}, + wantFields: scTestParams{ + peers: map[string]*scPeer{"P2": {height: 8, state: peerStateReady}}, + allB: []int64{1, 2, 3, 4, 5, 6, 7, 8}, + pending: map[int64]p2p.ID{6: "P2"}, + pendingTime: map[int64]time.Time{6: now}, + }, + }, + { + name: "noBlock from existing peer", + fields: scTestParams{ + peers: map[string]*scPeer{"P1": {height: 8, state: peerStateReady}}, + allB: []int64{1, 2, 3, 4, 5, 6, 7, 8}, + pending: map[int64]p2p.ID{6: "P1"}, + pendingTime: map[int64]time.Time{6: now}, + }, + wantEvent: scPeerError{peerID: "P1", reason: fmt.Errorf("some error")}, + wantFields: scTestParams{peers: map[string]*scPeer{"P1": {height: 8, state: peerStateRemoved}}}, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + sc := newTestScheduler(tt.fields) + event, err := sc.handleNoBlockResponse(noBlock6FromP1) + checkScResults(t, tt.wantErr, err, tt.wantEvent, event) + wantSc := newTestScheduler(tt.wantFields) + assert.Equal(t, wantSc, sc) + }) + } +} + func TestScHandleBlockProcessed(t *testing.T) { now := time.Now() processed6FromP1 := pcBlockProcessed{ @@ -1702,11 +1620,11 @@ func TestScHandleBlockVerificationFailure(t *testing.T) { } func TestScHandleAddNewPeer(t *testing.T) { - addP1 := addNewPeer{ + addP1 := bcAddNewPeer{ peerID: p2p.ID("P1"), } type args struct { - event addNewPeer + event bcAddNewPeer } tests := []struct { @@ -1754,76 +1672,14 @@ func TestScHandleAddNewPeer(t *testing.T) { } } -func TestScHandlePeerError(t *testing.T) { - errP1 := peerError{ - peerID: p2p.ID("P1"), - } - type args struct { - event peerError - } - - tests := []struct { - name string - fields scTestParams - args args - wantEvent Event - wantErr bool - }{ - { - name: "no peers", - fields: scTestParams{}, - args: args{event: errP1}, - wantEvent: scSchedulerFail{reason: fmt.Errorf("some error")}, - }, - { - name: "error finds no peer", - fields: scTestParams{ - height: 6, - peers: map[string]*scPeer{"P2": {height: 8, state: peerStateReady}}, - allB: []int64{6, 7, 8}, - }, - args: args{event: errP1}, - wantEvent: scSchedulerFail{reason: fmt.Errorf("some error")}, - }, - { - name: "error finds peer, only peer is removed", - fields: scTestParams{ - height: 6, - peers: map[string]*scPeer{"P1": {height: 8, state: peerStateReady}}, - allB: []int64{6, 7, 8}, - }, - args: args{event: errP1}, - wantEvent: scFinishedEv{}, - }, - { - name: "error finds peer, one of two peers are removed", - fields: scTestParams{ - peers: map[string]*scPeer{"P1": {height: 8, state: peerStateReady}, "P2": {height: 8, state: peerStateReady}}, - allB: []int64{1, 2, 3, 4, 5, 6, 7, 8}, - }, - args: args{event: errP1}, - wantEvent: noOpEvent{}, - }, - } - - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - sc := newTestScheduler(tt.fields) - event, err := sc.handlePeerError(tt.args.event) - checkScResults(t, tt.wantErr, err, tt.wantEvent, event) - }) - } -} - func TestScHandleTryPrunePeer(t *testing.T) { now := time.Now() - pruneEv := tryPrunePeer{ + pruneEv := rTryPrunePeer{ time: now.Add(time.Second + time.Millisecond), } type args struct { - event tryPrunePeer + event rTryPrunePeer } tests := []struct { @@ -1914,14 +1770,14 @@ func TestScHandleTryPrunePeer(t *testing.T) { } } -func TestHandleTrySchedule(t *testing.T) { +func TestScHandleTrySchedule(t *testing.T) { now := time.Now() - tryEv := trySchedule{ + tryEv := rTrySchedule{ time: now.Add(time.Second + time.Millisecond), } type args struct { - event trySchedule + event rTrySchedule } tests := []struct { name string @@ -1932,41 +1788,44 @@ func TestHandleTrySchedule(t *testing.T) { }{ { name: "no peers", - fields: scTestParams{peers: map[string]*scPeer{}}, + fields: scTestParams{startTime: now, peers: map[string]*scPeer{}}, args: args{event: tryEv}, wantEvent: noOpEvent{}, }, { name: "only new peers", - fields: scTestParams{peers: map[string]*scPeer{"P1": {height: -1, state: peerStateNew}}}, + fields: scTestParams{startTime: now, peers: map[string]*scPeer{"P1": {height: -1, state: peerStateNew}}}, args: args{event: tryEv}, wantEvent: noOpEvent{}, }, { name: "only Removed peers", - fields: scTestParams{peers: map[string]*scPeer{"P1": {height: 4, state: peerStateRemoved}}}, + fields: scTestParams{startTime: now, peers: map[string]*scPeer{"P1": {height: 4, state: peerStateRemoved}}}, args: args{event: tryEv}, wantEvent: noOpEvent{}, }, { name: "one Ready shorter peer", fields: scTestParams{ - height: 6, - peers: map[string]*scPeer{"P1": {height: 4, state: peerStateReady}}}, + startTime: now, + height: 6, + peers: map[string]*scPeer{"P1": {height: 4, state: peerStateReady}}}, args: args{event: tryEv}, wantEvent: noOpEvent{}, }, { name: "one Ready equal peer", fields: scTestParams{ - peers: map[string]*scPeer{"P1": {height: 4, state: peerStateReady}}, - allB: []int64{1, 2, 3, 4}}, + startTime: now, + peers: map[string]*scPeer{"P1": {height: 4, state: peerStateReady}}, + allB: []int64{1, 2, 3, 4}}, args: args{event: tryEv}, wantEvent: scBlockRequest{peerID: "P1", height: 1}, }, { name: "many Ready higher peers with different number of pending requests", fields: scTestParams{ + startTime: now, peers: map[string]*scPeer{ "P1": {height: 4, state: peerStateReady}, "P2": {height: 5, state: peerStateReady}}, @@ -1983,6 +1842,7 @@ func TestHandleTrySchedule(t *testing.T) { { name: "many Ready higher peers with same number of pending requests", fields: scTestParams{ + startTime: now, peers: map[string]*scPeer{ "P2": {height: 8, state: peerStateReady}, "P1": {height: 8, state: peerStateReady}, @@ -2084,6 +1944,8 @@ func TestScHandleStatusResponse(t *testing.T) { } func TestScHandle(t *testing.T) { + now := time.Now() + type unknownEv struct { priorityNormal } @@ -2123,24 +1985,27 @@ func TestScHandle(t *testing.T) { name: "single peer, sync 3 blocks", steps: []scStep{ { // add P1 - currentSc: &scTestParams{peers: map[string]*scPeer{}, height: 1}, - args: args{event: addNewPeer{peerID: "P1"}}, + currentSc: &scTestParams{startTime: now, peers: map[string]*scPeer{}, height: 1}, + args: args{event: bcAddNewPeer{peerID: "P1"}}, wantEvent: noOpEvent{}, - wantSc: &scTestParams{peers: map[string]*scPeer{"P1": {height: -1, state: peerStateNew}}, height: 1}, + wantSc: &scTestParams{startTime: now, peers: map[string]*scPeer{ + "P1": {height: -1, state: peerStateNew}}, height: 1}, }, { // set height of P1 args: args{event: bcStatusResponse{peerID: "P1", time: tick[0], height: 3}}, wantEvent: noOpEvent{}, wantSc: &scTestParams{ - peers: map[string]*scPeer{"P1": {height: 3, state: peerStateReady}}, - allB: []int64{1, 2, 3}, - height: 1, + startTime: now, + peers: map[string]*scPeer{"P1": {height: 3, state: peerStateReady}}, + allB: []int64{1, 2, 3}, + height: 1, }, }, { // schedule block 1 - args: args{event: trySchedule{time: tick[1]}}, + args: args{event: rTrySchedule{time: tick[1]}}, wantEvent: scBlockRequest{peerID: "P1", height: 1}, wantSc: &scTestParams{ + startTime: now, peers: map[string]*scPeer{"P1": {height: 3, state: peerStateReady}}, allB: []int64{1, 2, 3}, pending: map[int64]p2p.ID{1: "P1"}, @@ -2149,9 +2014,10 @@ func TestScHandle(t *testing.T) { }, }, { // schedule block 2 - args: args{event: trySchedule{time: tick[2]}}, + args: args{event: rTrySchedule{time: tick[2]}}, wantEvent: scBlockRequest{peerID: "P1", height: 2}, wantSc: &scTestParams{ + startTime: now, peers: map[string]*scPeer{"P1": {height: 3, state: peerStateReady}}, allB: []int64{1, 2, 3}, pending: map[int64]p2p.ID{1: "P1", 2: "P1"}, @@ -2160,9 +2026,10 @@ func TestScHandle(t *testing.T) { }, }, { // schedule block 3 - args: args{event: trySchedule{time: tick[3]}}, + args: args{event: rTrySchedule{time: tick[3]}}, wantEvent: scBlockRequest{peerID: "P1", height: 3}, wantSc: &scTestParams{ + startTime: now, peers: map[string]*scPeer{"P1": {height: 3, state: peerStateReady}}, allB: []int64{1, 2, 3}, pending: map[int64]p2p.ID{1: "P1", 2: "P1", 3: "P1"}, @@ -2171,9 +2038,10 @@ func TestScHandle(t *testing.T) { }, }, { // block response 1 - args: args{event: bcBlockResponse{peerID: "P1", height: 1, time: tick[4], size: 100, block: makeScBlock(1)}}, + args: args{event: bcBlockResponse{peerID: "P1", time: tick[4], size: 100, block: makeScBlock(1)}}, wantEvent: scBlockReceived{peerID: "P1", block: makeScBlock(1)}, wantSc: &scTestParams{ + startTime: now, peers: map[string]*scPeer{"P1": {height: 3, state: peerStateReady, lastTouched: tick[4]}}, allB: []int64{1, 2, 3}, pending: map[int64]p2p.ID{2: "P1", 3: "P1"}, @@ -2183,9 +2051,10 @@ func TestScHandle(t *testing.T) { }, }, { // block response 2 - args: args{event: bcBlockResponse{peerID: "P1", height: 2, time: tick[5], size: 100, block: makeScBlock(2)}}, + args: args{event: bcBlockResponse{peerID: "P1", time: tick[5], size: 100, block: makeScBlock(2)}}, wantEvent: scBlockReceived{peerID: "P1", block: makeScBlock(2)}, wantSc: &scTestParams{ + startTime: now, peers: map[string]*scPeer{"P1": {height: 3, state: peerStateReady, lastTouched: tick[5]}}, allB: []int64{1, 2, 3}, pending: map[int64]p2p.ID{3: "P1"}, @@ -2195,33 +2064,36 @@ func TestScHandle(t *testing.T) { }, }, { // block response 3 - args: args{event: bcBlockResponse{peerID: "P1", height: 3, time: tick[6], size: 100, block: makeScBlock(3)}}, + args: args{event: bcBlockResponse{peerID: "P1", time: tick[6], size: 100, block: makeScBlock(3)}}, wantEvent: scBlockReceived{peerID: "P1", block: makeScBlock(3)}, wantSc: &scTestParams{ - peers: map[string]*scPeer{"P1": {height: 3, state: peerStateReady, lastTouched: tick[6]}}, - allB: []int64{1, 2, 3}, - received: map[int64]p2p.ID{1: "P1", 2: "P1", 3: "P1"}, - height: 1, + startTime: now, + peers: map[string]*scPeer{"P1": {height: 3, state: peerStateReady, lastTouched: tick[6]}}, + allB: []int64{1, 2, 3}, + received: map[int64]p2p.ID{1: "P1", 2: "P1", 3: "P1"}, + height: 1, }, }, { // processed block 1 args: args{event: pcBlockProcessed{peerID: p2p.ID("P1"), height: 1}}, wantEvent: noOpEvent{}, wantSc: &scTestParams{ - peers: map[string]*scPeer{"P1": {height: 3, state: peerStateReady, lastTouched: tick[6]}}, - allB: []int64{2, 3}, - received: map[int64]p2p.ID{2: "P1", 3: "P1"}, - height: 2, + startTime: now, + peers: map[string]*scPeer{"P1": {height: 3, state: peerStateReady, lastTouched: tick[6]}}, + allB: []int64{2, 3}, + received: map[int64]p2p.ID{2: "P1", 3: "P1"}, + height: 2, }, }, { // processed block 2 args: args{event: pcBlockProcessed{peerID: p2p.ID("P1"), height: 2}}, wantEvent: scFinishedEv{}, wantSc: &scTestParams{ - peers: map[string]*scPeer{"P1": {height: 3, state: peerStateReady, lastTouched: tick[6]}}, - allB: []int64{3}, - received: map[int64]p2p.ID{3: "P1"}, - height: 3, + startTime: now, + peers: map[string]*scPeer{"P1": {height: 3, state: peerStateReady, lastTouched: tick[6]}}, + allB: []int64{3}, + received: map[int64]p2p.ID{3: "P1"}, + height: 3, }, }, }, @@ -2231,6 +2103,7 @@ func TestScHandle(t *testing.T) { steps: []scStep{ { // failure processing block 1 currentSc: &scTestParams{ + startTime: now, peers: map[string]*scPeer{ "P1": {height: 4, state: peerStateReady, lastTouched: tick[6]}, "P2": {height: 3, state: peerStateReady, lastTouched: tick[6]}}, @@ -2241,6 +2114,7 @@ func TestScHandle(t *testing.T) { args: args{event: pcBlockVerificationFailure{height: 1, firstPeerID: "P1", secondPeerID: "P1"}}, wantEvent: noOpEvent{}, wantSc: &scTestParams{ + startTime: now, peers: map[string]*scPeer{ "P1": {height: 4, state: peerStateRemoved, lastTouched: tick[6]}, "P2": {height: 3, state: peerStateReady, lastTouched: tick[6]}}, @@ -2249,19 +2123,6 @@ func TestScHandle(t *testing.T) { height: 1, }, }, - /* - { // processed block 2 - args: args{event: pcBlockProcessed{peerID: p2p.ID("P1"), height: 2}}, - wantEvent: scFinishedEv{}, - wantSc: &scTestParams{ - peers: map[string]*scPeer{"P1": {height: 3, state: peerStateReady, lastTouched: tick[6]}}, - allB: []int64{3}, - received: map[int64]p2p.ID{3: "P1"}, - height: 3, - }, - }, - - */ }, }, } @@ -2280,8 +2141,10 @@ func TestScHandle(t *testing.T) { } nextEvent, err := sc.handle(step.args.event) - assert.Equal(t, newTestScheduler(*step.wantSc), sc) + wantSc := newTestScheduler(*step.wantSc) + t.Logf("step %d(%v): %s", i, step.args.event, sc) + checkSameScheduler(t, wantSc, sc) checkScResults(t, step.wantErr, err, step.wantEvent, nextEvent) diff --git a/blockchain/v2/types.go b/blockchain/v2/types.go index 836e87fd8..7a73728e4 100644 --- a/blockchain/v2/types.go +++ b/blockchain/v2/types.go @@ -4,6 +4,7 @@ import ( "github.com/Workiva/go-datastructures/queue" ) +// Event is the type that can be added to the priority queue. type Event queue.Item type priority interface { diff --git a/docs/architecture/adr-043-blockchain-riri-org.md b/docs/architecture/adr-043-blockchain-riri-org.md index 8daef1817..6bb018f51 100644 --- a/docs/architecture/adr-043-blockchain-riri-org.md +++ b/docs/architecture/adr-043-blockchain-riri-org.md @@ -4,6 +4,7 @@ * 18-06-2019: Initial draft * 08-07-2019: Reviewed * 29-11-2019: Implemented +* 14-02-2020: Updated with the implementation details ## Context @@ -27,7 +28,15 @@ This ADR is meant to specify the missing components and control necessary to ach Partition the responsibilities of the blockchain reactor into a set of components which communicate exclusively with events. Events will contain timestamps allowing each component to track time as internal state. The internal state will be mutated by a set of `handle*` which will produce event(s). The integration between components will happen in the reactor and reactor tests will then become integration tests between components. This design will be known as `v2`. ![v2 Blockchain Reactor Architecture -Diagram](https://github.com/tendermint/tendermint/blob/f9e556481654a24aeb689bdadaf5eab3ccd66829/docs/architecture/img/blockchain-reactor-v2.png) +Diagram](https://github.com/tendermint/tendermint/blob/584e67ac3fac220c5c3e0652e3582eca8231e814/docs/architecture/img/blockchain-reactor-v2.png) + +### Fast Sync Related Communication Channels + +The diagram below shows the fast sync routines and the types of channels and queues used to communicate with each other. +In addition the per reactor channels used by the sendRoutine to send messages over the Peer MConnection are shown. + +![v2 Blockchain Channels and Queues +Diagram](https://github.com/tendermint/tendermint/blob/5cf570690f989646fb3b615b734da503f038891f/docs/architecture/img/blockchain-v2-channels.png) ### Reactor changes in detail diff --git a/docs/architecture/img/blockchain-reactor-v2.png b/docs/architecture/img/blockchain-reactor-v2.png index 086bf71bd88d47e02fc4f47b563ebe365695836a..5f15333a0080cd93d01496d7b711e00d84d2083e 100644 GIT binary patch literal 171024 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%0AyOZVkp1ilOu3?*@M!GZ| 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 B=v@E+ literal 120617 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

Ah*9Vo97=Fg^|9GhFQ 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 diff --git a/docs/architecture/img/blockchain-v2-channels.png b/docs/architecture/img/blockchain-v2-channels.png new file mode 100644 index 0000000000000000000000000000000000000000..69886da95d6b00b974c241fb54a29d422f769a9d GIT binary patch literal 109340 zcmaHS3p~^R_kWa%ltLk;+)6^buuTfP+Ldi=vy}?l*nMVZTQ|~8xhIi|P|`(3sYK~c z=&C|Dg)Y)fDRle4rqB2L`ThQn|Ks07V|%~%x}4X!JkRr-cPc$NXtLQ%voT}FOePU= z%rRrek;jZNJ~eSX_{4fjd-a$x7Pr;-aJ5V;6iEeRT;bTif4RaSv5I)LD;(zvgC!;= zdhu0}iC!WFcn2=Y6nv3TB;fzO41>TRo)DNP)H@6YafPG3k>CY_@`6DjyubHH#t7v9 zj73xEMN(;`D~#ad1p!03(ITToajG#QYjU11W^=`+Asjm+G`+EC$LE(nkLnDQeD$)NK#;`k$Kou`i$p3B*3iCo57HYU4P)El6{gjEJs^ema z;XEOCr2r$)ymcoQ_RNH(3thoMJ#(l#jOtO-IKBqYa`!QaD1sH0KGPb{Y3$>6t6#q^2hCW1j=!E`}1O)TIG64a7lTp~iA5DTNLgj}*L z0R`m}VT5obQ5VZq31ob}KrBPT5>Wy2p zUP*!oG#nH%7*6+&^$q36BjDUH0t|-o4h7nVq3X3VETEtG0Q<54Vi9VCoP|s!79FnC66297NFoOxE+NstK@-3w z@Cwn1@KO|(h~r3Ou`0Y0mmmQb$S84?mczve`FL6)mK?;@GAU|?Lh36bu;L~0RNo*S z6h`un_2EVZYvn97OTr?0t6~Vqm|z+!DwrjT6vuNhk@({Uf5?VqaqYc6%L8;Ng zV2V)1q$!CBLEboTWfUs}+=WMlk6RYQd@kH9h5SA(gj}`NnP&`(W zNW?`kqQzncO~a9~iBVCANF|O4RwUx6fZ<_;dK8Z;OF&TBz&gP9(Y`3~8ZW~sed6RH zC>o4JiWDb^LZX*9>Vn&hwwx}2#h>I9D@_1G(0pGA0>rrV+g(~sT>j# z5{(wI!H5tAhl=s$#0u%)4cUi*mr0?CA}JBZ4g8!VxO>BU58e5@}k)R&77SOO0+gc6c&jL^A5r&!M*YE!K^4c4tU*(lP^34T8g8&6q{dsr3gzi}K`Heh4v<$I<8+p*~c!UYkH= z!DICyu`oUdhTs81V@3zd6j32!j*KZoM`Jm`8Xq#22oENbArv-2h2bUg@m#t{i$thl z=wN1OES0PdPYf5+*^p=)MHL$y6B8K|rl5<%!)3fMHHIz~Nb#W{1mWQ*JdK45gJX3% z6hcLnFbE-XPC^im3?PCeR6!2H$x$*XlP6b^$ðMKVH-S72~TqLj|jQJGP`(K0d7 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

_Ec~xce+}wz*Lw6oPvO3LR@35LX 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 Date: Wed, 19 Feb 2020 15:21:27 +0000 Subject: [PATCH 11/12] consensus: reduce log severity for ErrVoteNonDeterministicSignature (#4431) from error to debug Closes #3583 --- consensus/state.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/consensus/state.go b/consensus/state.go index 05c70b652..d543c9c84 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -1661,6 +1661,8 @@ func (cs *State) tryAddVote(vote *types.Vote, peerID p2p.ID) (bool, error) { } cs.evpool.AddEvidence(voteErr.DuplicateVoteEvidence) return added, err + } else if err == types.ErrVoteNonDeterministicSignature { + cs.Logger.Debug("Vote has non-deterministic signature", "err", err) } else { // Either // 1) bad peer OR From 7ab81a7fdd8ed266cb4ccd49abd0d72df4d92f52 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 19 Feb 2020 17:26:23 +0100 Subject: [PATCH 12/12] deps: bump github.com/stretchr/testify from 1.4.0 to 1.5.0 (#4435) Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.4.0...v1.5.0) Signed-off-by: dependabot-preview[bot] --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 7b669b1db..b828c3c4f 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa github.com/spf13/cobra v0.0.3 github.com/spf13/viper v1.6.2 - github.com/stretchr/testify v1.4.0 + github.com/stretchr/testify v1.5.0 github.com/tendermint/go-amino v0.14.1 github.com/tendermint/tm-db v0.4.0 golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 diff --git a/go.sum b/go.sum index e606cd3fa..ff0cf1d88 100644 --- a/go.sum +++ b/go.sum @@ -374,6 +374,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.0 h1:DMOzIV76tmoDNE9pX6RSN0aDtCYeCg5VueieJaAo1uw= +github.com/stretchr/testify v1.5.0/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d h1:gZZadD8H+fF+n9CmNhYL1Y0dJB+kLOmKd7FbPJLeGHs=