Compare commits

..

26 Commits

Author SHA1 Message Date
William Banfield
738457a63f p2p: make queue read and write simultaneously 2022-07-01 18:55:46 -04:00
dependabot[bot]
6d8079559b build(deps): Bump github.com/vektra/mockery/v2 from 2.13.1 to 2.14.0 (#8924)
Bumps [github.com/vektra/mockery/v2](https://github.com/vektra/mockery) from 2.13.1 to 2.14.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/vektra/mockery/releases">github.com/vektra/mockery/v2's releases</a>.</em></p>
<blockquote>
<h2>v2.14.0</h2>
<h2>Changelog</h2>
<ul>
<li>8582bd6 Add test for getLocalizedPath</li>
<li>686b90c Apply PR comments</li>
<li>de0cade Merge pull request <a href="https://github-redirect.dependabot.com/vektra/mockery/issues/474">#474</a> from RSid/add-flag-documentation</li>
<li>1fa7d2f Merge pull request <a href="https://github-redirect.dependabot.com/vektra/mockery/issues/480">#480</a> from vektra/LandonTClipp-patch-1</li>
<li>4d1f925 Merge pull request <a href="https://github-redirect.dependabot.com/vektra/mockery/issues/484">#484</a> from LouisBrunner/fix_generics_with_expecter</li>
<li>519a84f Merge pull request <a href="https://github-redirect.dependabot.com/vektra/mockery/issues/486">#486</a> from abhinavnair/replace-ioutil</li>
<li>2ca0b83 Merge pull request <a href="https://github-redirect.dependabot.com/vektra/mockery/issues/488">#488</a> from vektra/getLocalizedPath_test</li>
<li>cc82d49 Replace deprecated ioutil pkg with os &amp; io</li>
<li>a420307 Update README.md</li>
<li>4e4a96b Update issue template</li>
<li>fa182fe add documentation to readme</li>
<li>e4954a2 fix: add support for with-expecter when using generics</li>
<li>ca9ddd4 update issue template</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="4d1f925ad5"><code>4d1f925</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/vektra/mockery/issues/484">#484</a> from LouisBrunner/fix_generics_with_expecter</li>
<li><a href="de0cade475"><code>de0cade</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/vektra/mockery/issues/474">#474</a> from RSid/add-flag-documentation</li>
<li><a href="2ca0b83ade"><code>2ca0b83</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/vektra/mockery/issues/488">#488</a> from vektra/getLocalizedPath_test</li>
<li><a href="8582bd63c8"><code>8582bd6</code></a> Add test for getLocalizedPath</li>
<li><a href="519a84f8de"><code>519a84f</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/vektra/mockery/issues/486">#486</a> from abhinavnair/replace-ioutil</li>
<li><a href="cc82d49a73"><code>cc82d49</code></a> Replace deprecated ioutil pkg with os &amp; io</li>
<li><a href="e4954a2411"><code>e4954a2</code></a> fix: add support for with-expecter when using generics</li>
<li><a href="ca9ddd4e97"><code>ca9ddd4</code></a> update issue template</li>
<li><a href="686b90cccf"><code>686b90c</code></a> Apply PR comments</li>
<li><a href="1fa7d2f723"><code>1fa7d2f</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/vektra/mockery/issues/480">#480</a> from vektra/LandonTClipp-patch-1</li>
<li>Additional commits viewable in <a href="https://github.com/vektra/mockery/compare/v2.13.1...v2.14.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/vektra/mockery/v2&package-manager=go_modules&previous-version=2.13.1&new-version=2.14.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>
2022-07-01 14:17:45 +00:00
Ian Jungyong Um
1d96faa35a p2p: fix typo (#8922)
Fix minor typos in peermanager
2022-07-01 12:44:39 +00:00
William Banfield
921530c352 p2p: use correct context error (#8916)
handshakeCtx is the internal context carrying the timeout. Its error should be used for the error return.
2022-06-30 22:02:59 +00:00
William Banfield
5274f80de4 p2p: fix flakey test due to disconnect cooldown (#8917)
This test was made flakey by #8839. The cooldown period means that the node in the test will not try to reconnect as quickly as the test expects. This change makes the cooldown shorter in the test so that the node quickly reconnects.
2022-06-30 21:48:10 +00:00
William Banfield
47cb30fc1d p2p: set outgoing connections to around 20% of total connections (#8913) 2022-06-30 16:51:16 -04:00
dependabot[bot]
5c26db733b build(deps): Bump github.com/stretchr/testify from 1.7.5 to 1.8.0 (#8907)
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.7.5 to 1.8.0.
<details>
<summary>Commits</summary>
<ul>
<li><a href="181cea6eab"><code>181cea6</code></a> impr: <code>CallerInfo</code> should print full paths to the terminal (<a href="https://github-redirect.dependabot.com/stretchr/testify/issues/1201">#1201</a>)</li>
<li><a href="cf1284f8dd"><code>cf1284f</code></a> Allow mock expectations to be ordered (<a href="https://github-redirect.dependabot.com/stretchr/testify/issues/1106">#1106</a>)</li>
<li><a href="66eef0ef3a"><code>66eef0e</code></a> fix: assert.MapSubset (or just support maps in assert.Subset) (<a href="https://github-redirect.dependabot.com/stretchr/testify/issues/1178">#1178</a>)</li>
<li><a href="2fab6dffcf"><code>2fab6df</code></a> Add WithinTimeRange method (<a href="https://github-redirect.dependabot.com/stretchr/testify/issues/1188">#1188</a>)</li>
<li>See full diff in <a href="https://github.com/stretchr/testify/compare/v1.7.5...v1.8.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/stretchr/testify&package-manager=go_modules&previous-version=1.7.5&new-version=1.8.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>
2022-06-30 16:34:43 +00:00
Sam Kleinman
60881f1d06 p2p: stop mconn channel sends without timeout (#8906) 2022-06-30 09:01:02 -04:00
Thane Thomson
3bec1668c6 e2e: Extract Docker-specific functionality (#8754)
* e2e: Extract Docker-specific functionality

Extract Docker-specific functionality and put it behind an interface
that should hopefully, without too much modification, allow us to
implement a Digital Ocean-based infrastructure provider.

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Thread contexts through all potentially long-running functions

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Drop the "API" from interface/struct/var naming

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Simplify function returns

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Rename GenerateConfig to Setup to make it more generic

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Consolidate all infra functions into a single interface

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Localize linter directives

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Look up and use complete node in ShowNodeLogs and TailNodeLogs calls

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Restructure infra provider API into a separate package

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Rename interface again

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Rename exec functions for readability

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Relocate staticcheck lint directive

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Remove staticcheck lint directive

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Make testnet infra struct private

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Only pass testnetDir to Cleanup function

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-06-29 08:02:05 -04:00
Sam Kleinman
37f9d59969 log: do not pre-process log results (#8895)
I was digging around in the zero log functions, and the following
functions using the `Fields()` method directly in zerolog, 

- https://github.com/rs/zerolog/blob/v1.27.0/event.go#L161
- e9344a8c50/fields.go (L15)

Have meaningfully equivalent semantics and our pre-processing of
values is getting us much (except forcing zerolog to always sort our
keys, and nooping in the case when you miss the last field.)

With this change also, we can pass maps (or, pratically a single map)
to the logger, which might be a less wacky seeming interface.
2022-06-28 14:40:16 +00:00
Sam Kleinman
013b46a6c3 libs/strings: move to internal (#8890)
I think we were leaving this library public because the SDK dependend
upon it, but the function the SDK was using was one that we'd removed
because *we* weren't using it any more, and I made a PR agasint the
SDK to clean that up.

ref: https://github.com/cosmos/cosmos-sdk/pull/12368
2022-06-27 21:44:50 +00:00
dependabot[bot]
373b262f35 build(deps): Bump styfle/cancel-workflow-action from 0.9.1 to 0.10.0 (#8881)
Bumps [styfle/cancel-workflow-action](https://github.com/styfle/cancel-workflow-action) from 0.9.1 to 0.10.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/styfle/cancel-workflow-action/releases">styfle/cancel-workflow-action's releases</a>.</em></p>
<blockquote>
<h2>0.10.0</h2>
<h3>Changes</h3>
<ul>
<li>Feat(all):support for considering all workflows with one term: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/165">#165</a></li>
<li>Chore: rebuild: 74a81dc1a9321342ebc12fa8670cc91600c8c494</li>
<li>Chore: update <code>main.yml</code>: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/78">#78</a></li>
<li>Bump <code>@​vercel/ncc</code> from 0.28.6 to 0.29.1: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/106">#106</a></li>
<li>Bump <code>@​vercel/ncc</code> from 0.29.1 to 0.29.2: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/109">#109</a></li>
<li>Bump <code>@​vercel/ncc</code> from 0.29.2 to 0.30.0: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/112">#112</a></li>
<li>Bump husky from 7.0.1 to 7.0.2: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/110">#110</a></li>
<li>Bump prettier from 2.3.2 to 2.4.0: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/116">#116</a></li>
<li>Bump <code>@​vercel/ncc</code> from 0.30.0 to 0.31.1: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/115">#115</a></li>
<li>Bump typescript from 4.3.5 to 4.4.3: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/114">#114</a></li>
<li>Bump prettier from 2.4.0 to 2.4.1: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/117">#117</a></li>
<li>Bump <code>@​actions/github</code> from 4.0.0 to 5.0.0: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/89">#89</a></li>
<li>Bump <code>@​actions/core</code> from 1.3.0 to 1.6.0: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/118">#118</a></li>
<li>Bump typescript from 4.4.3 to 4.4.4: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/119">#119</a></li>
<li>Bump husky from 7.0.2 to 7.0.4: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/120">#120</a></li>
<li>Bump typescript from 4.4.4 to 4.5.2: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/124">#124</a></li>
<li>Bump <code>@​vercel/ncc</code> from 0.31.1 to 0.32.0: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/123">#123</a></li>
<li>Bump prettier from 2.4.1 to 2.5.0: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/125">#125</a></li>
<li>Bump prettier from 2.5.0 to 2.5.1: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/126">#126</a></li>
<li>Bump <code>@​vercel/ncc</code> from 0.32.0 to 0.33.0: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/127">#127</a></li>
<li>Bump typescript from 4.5.2 to 4.5.3: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/128">#128</a></li>
<li>Bump <code>@​vercel/ncc</code> from 0.33.0 to 0.33.1: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/130">#130</a></li>
<li>Bump typescript from 4.5.3 to 4.5.4: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/129">#129</a></li>
<li>Bump typescript from 4.5.4 to 4.5.5: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/131">#131</a></li>
<li>Bump node-fetch from 2.6.5 to 2.6.7: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/132">#132</a></li>
<li>Bump <code>@​vercel/ncc</code> from 0.33.1 to 0.33.3: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/138">#138</a></li>
<li>Bump actions/setup-node from 2 to 3.0.0: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/140">#140</a></li>
<li>Bump actions/checkout from 2 to 3: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/141">#141</a></li>
<li>Bump typescript from 4.5.5 to 4.6.2: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/142">#142</a></li>
<li>Bump prettier from 2.5.1 to 2.6.0: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/143">#143</a></li>
<li>Bump prettier from 2.6.0 to 2.6.1: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/145">#145</a></li>
<li>Bump actions/setup-node from 3.0.0 to 3.1.0: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/146">#146</a></li>
<li>Bump typescript from 4.6.2 to 4.6.3: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/144">#144</a></li>
<li>Bump prettier from 2.6.1 to 2.6.2: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/147">#147</a></li>
<li>Bump <code>@​actions/github</code> from 5.0.0 to 5.0.1: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/148">#148</a></li>
<li>Bump actions/setup-node from 3.1.0 to 3.1.1: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/149">#149</a></li>
<li>Bump <code>@​vercel/ncc</code> from 0.33.3 to 0.33.4: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/151">#151</a></li>
<li>Bump <code>@​actions/core</code> from 1.6.0 to 1.7.0: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/153">#153</a></li>
<li>Bump typescript from 4.6.3 to 4.6.4: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/154">#154</a></li>
<li>Bump husky from 7.0.4 to 8.0.1: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/155">#155</a></li>
<li>Bump <code>@​actions/core</code> from 1.7.0 to 1.8.0: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/156">#156</a></li>
<li>Bump actions/setup-node from 3.1.1 to 3.2.0: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/159">#159</a></li>
<li>Bump <code>@​actions/github</code> from 5.0.1 to 5.0.3: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/157">#157</a></li>
<li>Bump <code>@​actions/core</code> from 1.8.0 to 1.8.2: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/158">#158</a></li>
<li>Bump typescript from 4.6.4 to 4.7.2: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/160">#160</a></li>
<li>Bump <code>@​vercel/ncc</code> from 0.33.4 to 0.34.0: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/161">#161</a></li>
<li>Bump typescript from 4.7.2 to 4.7.3: <a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/163">#163</a></li>
</ul>

</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="bb6001c4ea"><code>bb6001c</code></a> 0.10.0</li>
<li><a href="74a81dc1a9"><code>74a81dc</code></a> chore: rebuild</li>
<li><a href="d2d941c239"><code>d2d941c</code></a> feat(all):support for considering all workflows with one term (<a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/165">#165</a>)</li>
<li><a href="9cd53caff9"><code>9cd53ca</code></a> Bump <code>@​actions/core</code> from 1.8.2 to 1.9.0 (<a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/166">#166</a>)</li>
<li><a href="4d9b633214"><code>4d9b633</code></a> Bump prettier from 2.6.2 to 2.7.1 (<a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/168">#168</a>)</li>
<li><a href="89c9307adc"><code>89c9307</code></a> Bump typescript from 4.7.3 to 4.7.4 (<a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/167">#167</a>)</li>
<li><a href="f680a0158a"><code>f680a01</code></a> Bump actions/setup-node from 3.2.0 to 3.3.0 (<a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/164">#164</a>)</li>
<li><a href="4ba58d5728"><code>4ba58d5</code></a> Bump typescript from 4.7.2 to 4.7.3 (<a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/163">#163</a>)</li>
<li><a href="0d0a9a5ae6"><code>0d0a9a5</code></a> Bump <code>@​vercel/ncc</code> from 0.33.4 to 0.34.0 (<a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/161">#161</a>)</li>
<li><a href="8ca5a00083"><code>8ca5a00</code></a> Bump typescript from 4.6.4 to 4.7.2 (<a href="https://github-redirect.dependabot.com/styfle/cancel-workflow-action/issues/160">#160</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/styfle/cancel-workflow-action/compare/0.9.1...0.10.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=styfle/cancel-workflow-action&package-manager=github_actions&previous-version=0.9.1&new-version=0.10.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>
2022-06-27 13:15:29 +00:00
dependabot[bot]
463cff456b build(deps): Bump bufbuild/buf-setup-action from 1.5.0 to 1.6.0 (#8883)
Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.5.0 to 1.6.0.
- [Release notes](https://github.com/bufbuild/buf-setup-action/releases)
- [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.5.0...v1.6.0)

---
updated-dependencies:
- dependency-name: bufbuild/buf-setup-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-27 09:13:25 -04:00
Sergio Mena
27ff2f46b8 Add @sergio-mena and @jmalicevic to list of spec reviewers (#8870)
Co-authored-by: Callum Waters <cmwaters19@gmail.com>
2022-06-24 20:53:31 +02:00
Sam Kleinman
52b6dc19ba p2p: remove dial sleep and provide disconnect cooldown (#8839)
Alternative proposal for #8826
2022-06-24 17:57:49 +00:00
Callum Waters
c4d24eed7d e2e: disable another network test (#8862)
Follow up on: https://github.com/tendermint/tendermint/pull/8849
2022-06-24 16:31:30 +00:00
William Banfield
409e057d73 fix light client select statement (#8871) 2022-06-24 12:10:27 -04:00
dependabot[bot]
6b5053046a build(deps): Bump github.com/stretchr/testify from 1.7.2 to 1.7.5 (#8864)
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.7.2 to 1.7.5.
<details>
<summary>Commits</summary>
<ul>
<li><a href="b5ce165710"><code>b5ce165</code></a> fixing panic in calls to assertion with nil m.mutex (<a href="https://github-redirect.dependabot.com/stretchr/testify/issues/1212">#1212</a>)</li>
<li><a href="c206b2e823"><code>c206b2e</code></a> Mock can be deadlocked by a panic (<a href="https://github-redirect.dependabot.com/stretchr/testify/issues/1157">#1157</a>)</li>
<li><a href="1b73601ae8"><code>1b73601</code></a> suite: correctly set stats on test panic (<a href="https://github-redirect.dependabot.com/stretchr/testify/issues/1195">#1195</a>)</li>
<li><a href="ba1076d8b3"><code>ba1076d</code></a> Add .Unset method to mock (<a href="https://github-redirect.dependabot.com/stretchr/testify/issues/982">#982</a>)</li>
<li><a href="c31ea0312f"><code>c31ea03</code></a> Support comparing byte slice (<a href="https://github-redirect.dependabot.com/stretchr/testify/issues/1202">#1202</a>)</li>
<li><a href="48391ba5eb"><code>48391ba</code></a> Fix panic in AssertExpectations for mocks without expectations (<a href="https://github-redirect.dependabot.com/stretchr/testify/issues/1207">#1207</a>)</li>
<li><a href="840cb80149"><code>840cb80</code></a> arrays value types in a zero-initialized state are considered empty (<a href="https://github-redirect.dependabot.com/stretchr/testify/issues/1126">#1126</a>)</li>
<li><a href="07dc7ee5ab"><code>07dc7ee</code></a> Bump actions/setup-go from 3.1.0 to 3.2.0 (<a href="https://github-redirect.dependabot.com/stretchr/testify/issues/1191">#1191</a>)</li>
<li><a href="c33fc8d30d"><code>c33fc8d</code></a> Bump actions/checkout from 2 to 3 (<a href="https://github-redirect.dependabot.com/stretchr/testify/issues/1163">#1163</a>)</li>
<li><a href="3c33e07c4c"><code>3c33e07</code></a> Added Go 1.18.1 as a build/supported version (<a href="https://github-redirect.dependabot.com/stretchr/testify/issues/1182">#1182</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/stretchr/testify/compare/v1.7.2...v1.7.5">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/stretchr/testify&package-manager=go_modules&previous-version=1.7.2&new-version=1.7.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>
2022-06-24 13:12:17 +00:00
William Banfield
5f5e74798b p2p: set empty timeouts to small values. (#8847)
These timeouts default to 'do not time out' if they are not set. This times up resources, potentially indefinitely. If node on the other side of the the handshake is up but unresponsive, the[ handshake call](edec79448a/internal/p2p/router.go (L720)) will _never_ return.

These are proposed values that have not been validated. I intend to validate them in a production setting.
2022-06-23 22:33:21 +00:00
Callum Waters
fb209136f8 e2e: add tolerance to peer discovery test (#8849) 2022-06-23 19:11:21 +02:00
Sam Kleinman
436a38f876 p2p: track peers by address (#8841) 2022-06-23 10:03:10 -04:00
Sam Kleinman
52b2efb827 e2e: report peer heights in error message (#8843) 2022-06-23 08:40:36 -04:00
Ian Jungyong Um
2e11760fbe p2p: fix typo (#8836) 2022-06-22 09:30:11 +02:00
William Banfield
8860e027a8 p2p: more dial routines (#8827)
The dial routines perform network i/o, which is a blocking call into the kernel. These routines are completely unable to do anything else while the dial occurs, so for most of their lifecycle they are sitting idle waiting for the tcp stack to hand them data. We should increase this value by _a lot_ to enable more concurrent dials. This is unlikely to cause CPU starvation because these routines sit idle most of the time. The current value causes dials to occur _way_ too slowly. 

Below is a graph demonstrating the before and after of this change in a testnetwork with many dead peers. You can observe that the rate that we connect to new, valid peers, is _much_ higher than previously. Change was deployed around the 31 minute mark on the graph.

![image](https://user-images.githubusercontent.com/4561443/174919007-50e4453a-edd8-41d0-97ee-dea8853d57f7.png)
2022-06-22 00:51:09 +00:00
Sam Kleinman
cfd13825e2 p2p: add eviction metrics and cleanup dialing error handling (#8819) 2022-06-21 20:44:14 +00:00
dependabot[bot]
6f168df7e4 build(deps): Bump github.com/spf13/cobra from 1.4.0 to 1.5.0 (#8812)
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.4.0 to 1.5.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/spf13/cobra/releases">github.com/spf13/cobra's releases</a>.</em></p>
<blockquote>
<h2>v1.5.0</h2>
<h2>Spring 2022 Release 🌥️</h2>
<p>Hello everyone! Welcome to another release of cobra. Completions continue to get better and better. This release adds a few really cool new features. We also continue to patch versions of our dependencies as they become available via dependabot. Happy coding!</p>
<h2>Active help 👐🏼</h2>
<p>Shout out to <a href="https://github.com/marckhouzam"><code>@​marckhouzam</code></a> for a big value add: Active Help <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1482">spf13/cobra#1482</a>. With active help, a program can provide some inline warnings or hints for users as they hit tab. Now, your CLIs can be even more intuitive to use!</p>
<p>Currently active help is only supported for bash V2 and zsh. Marc wrote a whole guide on how to do this, so make sure to give it a good read to learn how you can add this to your cobra code! <a href="https://github.com/spf13/cobra/blob/master/active_help.md">https://github.com/spf13/cobra/blob/master/active_help.md</a></p>
<h2>Group flags 🧑🏼‍🤝‍🧑🏼</h2>
<p>Cobra now has the ability to mark flags as required or exclusive as a <strong><em>group</em></strong>. Shout out to our newest maintainer <a href="https://github.com/johnSchnake"><code>@​johnSchnake</code></a> for this! <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1654">spf13/cobra#1654</a> Let's say you have a <code>username</code> flag that <em><strong>MUST</strong></em> be partnered with a <code>password</code> flag. Well, now, you can enforce those as being required together:</p>
<pre lang="go"><code>rootCmd.Flags().StringVarP(&amp;u, &quot;username&quot;, &quot;u&quot;, &quot;&quot;, &quot;Username (required if password is set)&quot;)
rootCmd.Flags().StringVarP(&amp;pw, &quot;password&quot;, &quot;p&quot;, &quot;&quot;, &quot;Password (required if username is set)&quot;)
rootCmd.MarkFlagsRequiredTogether(&quot;username&quot;, &quot;password&quot;)
</code></pre>
<p>Flags may also be marked as &quot;mutally exclusive&quot; with the <code>MarkFlagsMutuallyExclusive(string, string ... )</code> command API. Refer to our <a href="https://github.com/spf13/cobra/blob/master/user_guide.md">user guide documentation</a> for further info!</p>
<h2>Completions 👀</h2>
<ul>
<li>Add backwards-compatibility tests for legacyArgs() by <a href="https://github.com/marckhouzam"><code>@​marckhouzam</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1547">spf13/cobra#1547</a></li>
<li>feat: Add how to load completions in your current zsh session by <a href="https://github.com/ondrejsika"><code>@​ondrejsika</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1608">spf13/cobra#1608</a></li>
<li>Introduce FixedCompletions by <a href="https://github.com/emersion"><code>@​emersion</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1574">spf13/cobra#1574</a></li>
<li>Add shell completion to flag groups by <a href="https://github.com/marckhouzam"><code>@​marckhouzam</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1659">spf13/cobra#1659</a></li>
<li>Modify brew prefix path in macOS system by <a href="https://github.com/imxw"><code>@​imxw</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1719">spf13/cobra#1719</a></li>
<li>perf(bash-v2): use backslash escape string expansion for tab by <a href="https://github.com/scop"><code>@​scop</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1682">spf13/cobra#1682</a></li>
<li>style(bash-v2): out is not an array variable, do not refer to it as such by <a href="https://github.com/scop"><code>@​scop</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1681">spf13/cobra#1681</a></li>
<li>perf(bash-v2): standard completion optimizations by <a href="https://github.com/scop"><code>@​scop</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1683">spf13/cobra#1683</a></li>
<li>style(bash): out is not an array variable, do not refer to it as such by <a href="https://github.com/scop"><code>@​scop</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1684">spf13/cobra#1684</a></li>
<li>perf(bash-v2): short-circuit descriptionless candidate lists by <a href="https://github.com/scop"><code>@​scop</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1686">spf13/cobra#1686</a></li>
<li>perf(bash-v2): speed up filtering entries with descriptions by <a href="https://github.com/scop"><code>@​scop</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1689">spf13/cobra#1689</a></li>
<li>perf(bash-v2): speed up filtering menu-complete descriptions by <a href="https://github.com/scop"><code>@​scop</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1692">spf13/cobra#1692</a></li>
<li>fix(bash-v2): skip empty completions when filtering descriptions by <a href="https://github.com/scop"><code>@​scop</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1691">spf13/cobra#1691</a></li>
<li>perf(bash-v2): read directly to COMPREPLY on descriptionless short circuit by <a href="https://github.com/scop"><code>@​scop</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1700">spf13/cobra#1700</a></li>
<li>fix: Don't complete _command on zsh by <a href="https://github.com/twpayne"><code>@​twpayne</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1690">spf13/cobra#1690</a></li>
<li>Improve fish_completions code quality by <a href="https://github.com/t29kida"><code>@​t29kida</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1515">spf13/cobra#1515</a></li>
<li>Fix handling of descriptions for bash v3 by <a href="https://github.com/marckhouzam"><code>@​marckhouzam</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1735">spf13/cobra#1735</a></li>
<li>undefined or nil Args default to ArbitraryArgs by <a href="https://github.com/umarcor"><code>@​umarcor</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1612">spf13/cobra#1612</a></li>
<li>Add Command.SetContext by <a href="https://github.com/joshcarp"><code>@​joshcarp</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1551">spf13/cobra#1551</a></li>
<li>Wrap printf tab with quotes by <a href="https://github.com/PapaCharlie"><code>@​PapaCharlie</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1665">spf13/cobra#1665</a></li>
</ul>
<h2>Documentation 📝</h2>
<ul>
<li>Fixed typos in completions docs - <a href="https://github.com/cuishuang"><code>@​cuishuang</code></a> <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1625">spf13/cobra#1625</a></li>
<li>Removed <code>CHANGELOG.md</code> as it isn't updated - <a href="https://github.com/johnSchnake"><code>@​johnSchnake</code></a> <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1634">spf13/cobra#1634</a></li>
<li>Minor typo fix in <code>shell_completion.md</code> - <a href="https://github.com/danieldn"><code>@​danieldn</code></a> <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1678">spf13/cobra#1678</a></li>
<li>Changed branch name in the cobra generator link to 'main' - <a href="https://github.com/skywalker2909"><code>@​skywalker2909</code></a> <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1645">spf13/cobra#1645</a></li>
<li>Fix Command.Context comment by <a href="https://github.com/katexochen"><code>@​katexochen</code></a> in <a href="https://github-redirect.dependabot.com/spf13/cobra/pull/1639">spf13/cobra#1639</a></li>
</ul>

</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="06b06a9dc9"><code>06b06a9</code></a> Bump golangci/golangci-lint-action from 3.1.0 to 3.2.0 (<a href="https://github-redirect.dependabot.com/spf13/cobra/issues/1697">#1697</a>)</li>
<li><a href="5f2ec3c897"><code>5f2ec3c</code></a> Update shell completion to respect flag groups (<a href="https://github-redirect.dependabot.com/spf13/cobra/issues/1659">#1659</a>)</li>
<li><a href="b9ca5949e2"><code>b9ca594</code></a> use errors.Is() to check for errors (<a href="https://github-redirect.dependabot.com/spf13/cobra/issues/1730">#1730</a>)</li>
<li><a href="ea94a3db55"><code>ea94a3d</code></a> undefined or nil Args default to ArbitraryArgs (<a href="https://github-redirect.dependabot.com/spf13/cobra/issues/1612">#1612</a>)</li>
<li><a href="7c9831d376"><code>7c9831d</code></a> Fix handling of descriptions for bash v3 (<a href="https://github-redirect.dependabot.com/spf13/cobra/issues/1735">#1735</a>)</li>
<li><a href="ed7bb9dda4"><code>ed7bb9d</code></a> Add unit test for fish completion (<a href="https://github-redirect.dependabot.com/spf13/cobra/issues/1515">#1515</a>)</li>
<li><a href="f464d6c82e"><code>f464d6c</code></a> Add Active Help support (<a href="https://github-redirect.dependabot.com/spf13/cobra/issues/1482">#1482</a>)</li>
<li><a href="7dc8b004e6"><code>7dc8b00</code></a> Bump actions/setup-go from 2 to 3 (<a href="https://github-redirect.dependabot.com/spf13/cobra/issues/1660">#1660</a>)</li>
<li><a href="87ea1807f7"><code>87ea180</code></a> Modify brew prefix path in macOS system (<a href="https://github-redirect.dependabot.com/spf13/cobra/issues/1719">#1719</a>)</li>
<li><a href="ca8e3c2779"><code>ca8e3c2</code></a> Add Pulumi as a project using cobra (<a href="https://github-redirect.dependabot.com/spf13/cobra/issues/1720">#1720</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/spf13/cobra/compare/v1.4.0...v1.5.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/spf13/cobra&package-manager=go_modules&previous-version=1.4.0&new-version=1.5.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>
2022-06-21 17:46:01 +00:00
46 changed files with 747 additions and 503 deletions

2
.github/CODEOWNERS vendored
View File

@@ -10,4 +10,4 @@
* @ebuchman @cmwaters @tychoish @williambanfield @creachadair @sergio-mena @jmalicevic @thanethomson @ancazamfir
# Spec related changes can be approved by the protocol design team
/spec @josef-widder @milosevic @cason
/spec @josef-widder @milosevic @cason @sergio-mena @jmalicevic

View File

@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 3
steps:
- uses: styfle/cancel-workflow-action@0.9.1
- uses: styfle/cancel-workflow-action@0.10.0
with:
workflow_id: 1041851,1401230,2837803
access_token: ${{ github.token }}

View File

@@ -15,7 +15,7 @@ jobs:
timeout-minutes: 5
steps:
- uses: actions/checkout@v3
- uses: bufbuild/buf-setup-action@v1.5.0
- uses: bufbuild/buf-setup-action@v1.6.0
- uses: bufbuild/buf-lint-action@v1
with:
input: 'proto'

View File

@@ -671,7 +671,7 @@ func DefaultP2PConfig() *P2PConfig {
ExternalAddress: "",
UPNP: false,
MaxConnections: 64,
MaxOutgoingConnections: 32,
MaxOutgoingConnections: 12,
MaxIncomingConnectionAttempts: 100,
FlushThrottleTimeout: 100 * time.Millisecond,
// The MTU (Maximum Transmission Unit) for Ethernet is 1500 bytes.

10
go.mod
View File

@@ -25,9 +25,9 @@ require (
github.com/rs/cors v1.8.2
github.com/rs/zerolog v1.27.0
github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa
github.com/spf13/cobra v1.4.0
github.com/spf13/cobra v1.5.0
github.com/spf13/viper v1.12.0
github.com/stretchr/testify v1.7.2
github.com/stretchr/testify v1.8.0
github.com/tendermint/tm-db v0.6.6
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9
@@ -42,7 +42,7 @@ require (
github.com/creachadair/taskgroup v0.3.2
github.com/golangci/golangci-lint v1.46.0
github.com/google/go-cmp v0.5.8
github.com/vektra/mockery/v2 v2.13.1
github.com/vektra/mockery/v2 v2.14.0
gotest.tools v2.2.0+incompatible
)
@@ -74,7 +74,7 @@ require (
github.com/charithe/durationcheck v0.0.9 // indirect
github.com/chavacava/garif v0.0.0-20220316182200-5cad0b5181d4 // indirect
github.com/containerd/continuity v0.3.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/daixiang0/gci v0.3.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/denis-tingaikin/go-header v0.4.3 // indirect
@@ -199,7 +199,7 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect
github.com/stretchr/objx v0.1.1 // indirect
github.com/stretchr/objx v0.4.0 // indirect
github.com/subosito/gotenv v1.4.0 // indirect
github.com/sylvia7788/contextcheck v1.0.4 // indirect
github.com/tdakkota/asciicheck v0.1.1 // indirect

16
go.sum
View File

@@ -234,8 +234,9 @@ github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creachadair/atomicfile v0.2.6 h1:FgYxYvGcqREApTY8Nxg8msM6P/KVKK3ob5h9FaRUTNg=
github.com/creachadair/atomicfile v0.2.6/go.mod h1:BRq8Une6ckFneYXZQ+kO7p1ZZP3I2fzVzf28JxrIkBc=
github.com/creachadair/command v0.0.0-20220426235536-a748effdf6a1/go.mod h1:bAM+qFQb/KwWyCc9MLC4U1jvn3XyakqP5QRkds5T6cY=
@@ -1040,8 +1041,9 @@ github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q=
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
@@ -1062,8 +1064,9 @@ github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3
github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/handy v0.0.0-20200128134331-0f66f006fb2e/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/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@@ -1073,8 +1076,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs=
github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs=
@@ -1122,8 +1126,8 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus=
github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/vektra/mockery/v2 v2.13.1 h1:Lqs7aZiC7TwZO76fJ/4Zsb3NaO4F7cuuz0mZLYeNwtQ=
github.com/vektra/mockery/v2 v2.13.1/go.mod h1:bnD1T8tExSgPD1ripLkDbr60JA9VtQeu12P3wgLZd7M=
github.com/vektra/mockery/v2 v2.14.0 h1:KZ1p5Hrn8tiY+LErRMr14HHle6khxo+JKOXLBW/yfqs=
github.com/vektra/mockery/v2 v2.14.0/go.mod h1:bnD1T8tExSgPD1ripLkDbr60JA9VtQeu12P3wgLZd7M=
github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=

View File

@@ -10,13 +10,13 @@ import (
"github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/internal/eventbus"
"github.com/tendermint/tendermint/internal/inspect/rpc"
tmstrings "github.com/tendermint/tendermint/internal/libs/strings"
rpccore "github.com/tendermint/tendermint/internal/rpc/core"
"github.com/tendermint/tendermint/internal/state"
"github.com/tendermint/tendermint/internal/state/indexer"
"github.com/tendermint/tendermint/internal/state/indexer/sink"
"github.com/tendermint/tendermint/internal/store"
"github.com/tendermint/tendermint/libs/log"
tmstrings "github.com/tendermint/tendermint/libs/strings"
"github.com/tendermint/tendermint/types"
"golang.org/x/sync/errgroup"

View File

@@ -100,7 +100,8 @@ type MConnection struct {
// used to ensure FlushStop and OnStop
// are safe to call concurrently.
stopMtx sync.Mutex
stopMtx sync.Mutex
stopSignal <-chan struct{}
cancel context.CancelFunc
@@ -207,6 +208,7 @@ func (c *MConnection) OnStart(ctx context.Context) error {
c.quitSendRoutine = make(chan struct{})
c.doneSendRoutine = make(chan struct{})
c.quitRecvRoutine = make(chan struct{})
c.stopSignal = ctx.Done()
c.setRecvLastMsgAt(time.Now())
go c.sendRoutine(ctx)
go c.recvRoutine(ctx)
@@ -681,6 +683,8 @@ func (ch *channel) sendBytes(bytes []byte) bool {
return true
case <-time.After(defaultSendTimeout):
return false
case <-ch.conn.stopSignal:
return false
}
}

View File

@@ -74,6 +74,12 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics {
Name: "peers_connected_outgoing",
Help: "Number of peers connected as a result of the peer dialing this node.",
}, labels).With(labelsAndValues...),
PeersEvicted: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "peers_evicted",
Help: "Number of peers evicted by this node.",
}, labels).With(labelsAndValues...),
RouterPeerQueueRecv: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
@@ -119,6 +125,7 @@ func NopMetrics() *Metrics {
PeersConnectedFailure: discard.NewCounter(),
PeersConnectedIncoming: discard.NewGauge(),
PeersConnectedOutgoing: discard.NewGauge(),
PeersEvicted: discard.NewCounter(),
RouterPeerQueueRecv: discard.NewHistogram(),
RouterPeerQueueSend: discard.NewHistogram(),
RouterChannelQueueSend: discard.NewHistogram(),

View File

@@ -51,6 +51,9 @@ type Metrics struct {
// this node.
PeersConnectedOutgoing metrics.Gauge
// Number of peers evicted by this node.
PeersEvicted metrics.Counter
// RouterPeerQueueRecv defines the time taken to read off of a peer's queue
// before sending on the connection.
//metrics:The time taken to read off of a peer's queue before sending on the connection.

View File

@@ -13,6 +13,8 @@ import (
p2p "github.com/tendermint/tendermint/internal/p2p"
time "time"
types "github.com/tendermint/tendermint/types"
)
@@ -35,20 +37,20 @@ func (_m *Connection) Close() error {
return r0
}
// Handshake provides a mock function with given fields: _a0, _a1, _a2
func (_m *Connection) Handshake(_a0 context.Context, _a1 types.NodeInfo, _a2 crypto.PrivKey) (types.NodeInfo, crypto.PubKey, error) {
ret := _m.Called(_a0, _a1, _a2)
// Handshake provides a mock function with given fields: _a0, _a1, _a2, _a3
func (_m *Connection) Handshake(_a0 context.Context, _a1 time.Duration, _a2 types.NodeInfo, _a3 crypto.PrivKey) (types.NodeInfo, crypto.PubKey, error) {
ret := _m.Called(_a0, _a1, _a2, _a3)
var r0 types.NodeInfo
if rf, ok := ret.Get(0).(func(context.Context, types.NodeInfo, crypto.PrivKey) types.NodeInfo); ok {
r0 = rf(_a0, _a1, _a2)
if rf, ok := ret.Get(0).(func(context.Context, time.Duration, types.NodeInfo, crypto.PrivKey) types.NodeInfo); ok {
r0 = rf(_a0, _a1, _a2, _a3)
} else {
r0 = ret.Get(0).(types.NodeInfo)
}
var r1 crypto.PubKey
if rf, ok := ret.Get(1).(func(context.Context, types.NodeInfo, crypto.PrivKey) crypto.PubKey); ok {
r1 = rf(_a0, _a1, _a2)
if rf, ok := ret.Get(1).(func(context.Context, time.Duration, types.NodeInfo, crypto.PrivKey) crypto.PubKey); ok {
r1 = rf(_a0, _a1, _a2, _a3)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(crypto.PubKey)
@@ -56,8 +58,8 @@ func (_m *Connection) Handshake(_a0 context.Context, _a1 types.NodeInfo, _a2 cry
}
var r2 error
if rf, ok := ret.Get(2).(func(context.Context, types.NodeInfo, crypto.PrivKey) error); ok {
r2 = rf(_a0, _a1, _a2)
if rf, ok := ret.Get(2).(func(context.Context, time.Duration, types.NodeInfo, crypto.PrivKey) error); ok {
r2 = rf(_a0, _a1, _a2, _a3)
} else {
r2 = ret.Error(2)
}

View File

@@ -252,12 +252,13 @@ func (n *Network) MakeNode(ctx context.Context, t *testing.T, opts NodeOptions)
require.NotNil(t, ep, "transport not listening an endpoint")
peerManager, err := p2p.NewPeerManager(nodeID, dbm.NewMemDB(), p2p.PeerManagerOptions{
MinRetryTime: 10 * time.Millisecond,
MaxRetryTime: 100 * time.Millisecond,
RetryTimeJitter: time.Millisecond,
MaxPeers: opts.MaxPeers,
MaxConnected: opts.MaxConnected,
Metrics: p2p.NopMetrics(),
MinRetryTime: 10 * time.Millisecond,
DisconnectCooldownPeriod: 10 * time.Millisecond,
MaxRetryTime: 100 * time.Millisecond,
RetryTimeJitter: time.Millisecond,
MaxPeers: opts.MaxPeers,
MaxConnected: opts.MaxConnected,
Metrics: p2p.NopMetrics(),
})
require.NoError(t, err)
@@ -269,7 +270,7 @@ func (n *Network) MakeNode(ctx context.Context, t *testing.T, opts NodeOptions)
func() *types.NodeInfo { return &nodeInfo },
transport,
ep,
p2p.RouterOptions{DialSleep: func(_ context.Context) {}},
p2p.RouterOptions{},
)
require.NoError(t, err)

View File

@@ -144,6 +144,10 @@ type PeerManagerOptions struct {
// retry times, to avoid thundering herds. 0 disables jitter.
RetryTimeJitter time.Duration
// DisconnectCooldownPeriod is the amount of time after we
// disconnect from a peer before we'll consider dialing a new peer
DisconnectCooldownPeriod time.Duration
// PeerScores sets fixed scores for specific peers. It is mainly used
// for testing. A score of 0 is ignored.
PeerScores map[types.NodeID]PeerScore
@@ -217,11 +221,11 @@ func (o *PeerManagerOptions) Validate() error {
return nil
}
// isPersistentPeer checks if a peer is in PersistentPeers. It will panic
// isPersistent checks if a peer is in PersistentPeers. It will panic
// if called before optimize().
func (o *PeerManagerOptions) isPersistent(id types.NodeID) bool {
if o.persistentPeers == nil {
panic("isPersistentPeer() called before optimize()")
panic("isPersistent() called before optimize()")
}
return o.persistentPeers[id]
}
@@ -513,12 +517,13 @@ func (m *PeerManager) HasDialedMaxPeers() bool {
// returned peer.
func (m *PeerManager) DialNext(ctx context.Context) (NodeAddress, error) {
for {
address := m.TryDialNext()
if (address != NodeAddress{}) {
if address := m.TryDialNext(); (address != NodeAddress{}) {
return address, nil
}
select {
case <-m.dialWaker.Sleep():
continue
case <-ctx.Done():
return NodeAddress{}, ctx.Err()
}
@@ -548,11 +553,19 @@ func (m *PeerManager) TryDialNext() NodeAddress {
continue
}
if !peer.LastDisconnected.IsZero() && time.Since(peer.LastDisconnected) < m.options.DisconnectCooldownPeriod {
continue
}
for _, addressInfo := range peer.AddressInfo {
if time.Since(addressInfo.LastDialFailure) < m.retryDelay(addressInfo.DialFailures, peer.Persistent) {
continue
}
if id, ok := m.store.Resolve(addressInfo.Address); ok && (m.isConnected(id) || m.dialing[id]) {
continue
}
// We now have an eligible address to dial. If we're full but have
// upgrade capacity (as checked above), we find a lower-scored peer
// we can replace and mark it as upgrading so noone else claims it.
@@ -680,8 +693,7 @@ func (m *PeerManager) Dialed(address NodeAddress) error {
return err
}
if upgradeFromPeer != "" && m.options.MaxConnected > 0 &&
len(m.connected) >= int(m.options.MaxConnected) {
if upgradeFromPeer != "" && m.options.MaxConnected > 0 && len(m.connected) >= int(m.options.MaxConnected) {
// Look for an even lower-scored peer that may have appeared since we
// started the upgrade.
if p, ok := m.store.Get(upgradeFromPeer); ok {
@@ -690,11 +702,11 @@ func (m *PeerManager) Dialed(address NodeAddress) error {
}
}
m.evict[upgradeFromPeer] = true
m.evictWaker.Wake()
}
m.metrics.PeersConnectedOutgoing.Add(1)
m.connected[peer.ID] = peerConnectionOutgoing
m.evictWaker.Wake()
return nil
}
@@ -863,6 +875,22 @@ func (m *PeerManager) Disconnected(ctx context.Context, peerID types.NodeID) {
delete(m.evicting, peerID)
delete(m.ready, peerID)
if peer, ok := m.store.Get(peerID); ok {
peer.LastDisconnected = time.Now()
_ = m.store.Set(peer)
// launch a thread to ping the dialWaker when the
// disconnected peer can be dialed again.
go func() {
timer := time.NewTimer(m.options.DisconnectCooldownPeriod)
defer timer.Stop()
select {
case <-timer.C:
m.dialWaker.Wake()
case <-ctx.Done():
}
}()
}
if ready {
m.broadcast(ctx, PeerUpdate{
NodeID: peerID,
@@ -1235,6 +1263,7 @@ func (m *PeerManager) retryDelay(failures uint32, persistent bool) time.Duration
type peerStore struct {
db dbm.DB
peers map[types.NodeID]*peerInfo
index map[NodeAddress]types.NodeID
ranked []*peerInfo // cache for Ranked(), nil invalidates cache
}
@@ -1254,6 +1283,7 @@ func newPeerStore(db dbm.DB) (*peerStore, error) {
// loadPeers loads all peers from the database into memory.
func (s *peerStore) loadPeers() error {
peers := map[types.NodeID]*peerInfo{}
addrs := map[NodeAddress]types.NodeID{}
start, end := keyPeerInfoRange()
iter, err := s.db.Iterator(start, end)
@@ -1273,11 +1303,18 @@ func (s *peerStore) loadPeers() error {
return fmt.Errorf("invalid peer data: %w", err)
}
peers[peer.ID] = peer
for addr := range peer.AddressInfo {
// TODO maybe check to see if we've seen this
// addr before for a different peer, there
// could be duplicates.
addrs[addr] = peer.ID
}
}
if iter.Error() != nil {
return iter.Error()
}
s.peers = peers
s.index = addrs
s.ranked = nil // invalidate cache if populated
return nil
}
@@ -1289,6 +1326,12 @@ func (s *peerStore) Get(id types.NodeID) (peerInfo, bool) {
return peer.Copy(), ok
}
// Resolve returns the peer ID for a given node address if known.
func (s *peerStore) Resolve(addr NodeAddress) (types.NodeID, bool) {
id, ok := s.index[addr]
return id, ok
}
// Set stores peer data. The input data will be copied, and can safely be reused
// by the caller.
func (s *peerStore) Set(peer peerInfo) error {
@@ -1317,20 +1360,29 @@ func (s *peerStore) Set(peer peerInfo) error {
// update the existing pointer address.
*current = peer
}
for addr := range peer.AddressInfo {
s.index[addr] = peer.ID
}
return nil
}
// Delete deletes a peer, or does nothing if it does not exist.
func (s *peerStore) Delete(id types.NodeID) error {
if _, ok := s.peers[id]; !ok {
peer, ok := s.peers[id]
if !ok {
return nil
}
if err := s.db.Delete(keyPeerInfo(id)); err != nil {
return err
for _, addr := range peer.AddressInfo {
delete(s.index, addr.Address)
}
delete(s.peers, id)
s.ranked = nil
if err := s.db.Delete(keyPeerInfo(id)); err != nil {
return err
}
return nil
}
@@ -1419,9 +1471,10 @@ func (s *peerStore) Size() int {
// peerInfo contains peer information stored in a peerStore.
type peerInfo struct {
ID types.NodeID
AddressInfo map[NodeAddress]*peerAddressInfo
LastConnected time.Time
ID types.NodeID
AddressInfo map[NodeAddress]*peerAddressInfo
LastConnected time.Time
LastDisconnected time.Time
// These fields are ephemeral, i.e. not persisted to the database.
Persistent bool
@@ -1461,8 +1514,8 @@ func peerInfoFromProto(msg *p2pproto.PeerInfo) (*peerInfo, error) {
func (p *peerInfo) ToProto() *p2pproto.PeerInfo {
msg := &p2pproto.PeerInfo{
ID: string(p.ID),
LastConnected: &p.LastConnected,
Inactive: p.Inactive,
LastConnected: &p.LastConnected,
}
for _, addressInfo := range p.AddressInfo {
msg.AddressInfo = append(msg.AddressInfo, addressInfo.ToProto())
@@ -1470,6 +1523,7 @@ func (p *peerInfo) ToProto() *p2pproto.PeerInfo {
if msg.LastConnected.IsZero() {
msg.LastConnected = nil
}
return msg
}

View File

@@ -384,16 +384,14 @@ func TestPeerManager_DialNext_WakeOnDialFailed(t *testing.T) {
added, err := peerManager.Add(a)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, a, dial)
// Add b. We shouldn't be able to dial it, due to MaxConnected.
added, err = peerManager.Add(b)
require.NoError(t, err)
require.True(t, added)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Zero(t, dial)
// Spawn a goroutine to fail a's dial attempt.
@@ -427,8 +425,7 @@ func TestPeerManager_DialNext_WakeOnDialFailedRetry(t *testing.T) {
added, err := peerManager.Add(a)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, a, dial)
require.NoError(t, peerManager.DialFailed(ctx, dial))
failed := time.Now()
@@ -458,8 +455,7 @@ func TestPeerManager_DialNext_WakeOnDisconnected(t *testing.T) {
err = peerManager.Accepted(a.NodeID)
require.NoError(t, err)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Zero(t, dial)
dctx, dcancel := context.WithTimeout(ctx, 300*time.Millisecond)
@@ -490,8 +486,7 @@ func TestPeerManager_TryDialNext_MaxConnected(t *testing.T) {
added, err := peerManager.Add(a)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, a, dial)
require.NoError(t, peerManager.Dialed(a))
@@ -499,16 +494,14 @@ func TestPeerManager_TryDialNext_MaxConnected(t *testing.T) {
added, err = peerManager.Add(b)
require.NoError(t, err)
require.True(t, added)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Equal(t, b, dial)
// At this point, adding c will not allow dialing it.
added, err = peerManager.Add(c)
require.NoError(t, err)
require.True(t, added)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Zero(t, dial)
}
@@ -540,7 +533,7 @@ func TestPeerManager_TryDialNext_MaxConnectedUpgrade(t *testing.T) {
added, err := peerManager.Add(a)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
dial := peerManager.TryDialNext()
require.NoError(t, err)
require.Equal(t, a, dial)
require.NoError(t, peerManager.Dialed(a))
@@ -549,8 +542,7 @@ func TestPeerManager_TryDialNext_MaxConnectedUpgrade(t *testing.T) {
added, err = peerManager.Add(b)
require.NoError(t, err)
require.True(t, added)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Equal(t, b, dial)
// Even though we are at capacity, we should be allowed to dial c for an
@@ -558,8 +550,7 @@ func TestPeerManager_TryDialNext_MaxConnectedUpgrade(t *testing.T) {
added, err = peerManager.Add(c)
require.NoError(t, err)
require.True(t, added)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Equal(t, c, dial)
// However, since we're using all upgrade slots now, we can't add and dial
@@ -567,16 +558,14 @@ func TestPeerManager_TryDialNext_MaxConnectedUpgrade(t *testing.T) {
added, err = peerManager.Add(d)
require.NoError(t, err)
require.True(t, added)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Zero(t, dial)
// We go through with c's upgrade.
require.NoError(t, peerManager.Dialed(c))
// Still can't dial d.
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Zero(t, dial)
// Now, if we disconnect a, we should be allowed to dial d because we have a
@@ -592,8 +581,7 @@ func TestPeerManager_TryDialNext_MaxConnectedUpgrade(t *testing.T) {
added, err = peerManager.Add(e)
require.NoError(t, err)
require.True(t, added)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Zero(t, dial)
}
@@ -613,8 +601,7 @@ func TestPeerManager_TryDialNext_UpgradeReservesPeer(t *testing.T) {
added, err := peerManager.Add(a)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, a, dial)
require.NoError(t, peerManager.Dialed(a))
@@ -622,8 +609,7 @@ func TestPeerManager_TryDialNext_UpgradeReservesPeer(t *testing.T) {
added, err = peerManager.Add(b)
require.NoError(t, err)
require.True(t, added)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Equal(t, b, dial)
// Adding c and dialing it will fail, because a is the only connected
@@ -631,8 +617,7 @@ func TestPeerManager_TryDialNext_UpgradeReservesPeer(t *testing.T) {
added, err = peerManager.Add(c)
require.NoError(t, err)
require.True(t, added)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Empty(t, dial)
}
@@ -653,22 +638,19 @@ func TestPeerManager_TryDialNext_DialingConnected(t *testing.T) {
added, err := peerManager.Add(a)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, a, dial)
// Adding a's TCP address will not dispense a, since it's already dialing.
added, err = peerManager.Add(aTCP)
require.NoError(t, err)
require.True(t, added)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Zero(t, dial)
// Marking a as dialed will still not dispense it.
require.NoError(t, peerManager.Dialed(a))
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Zero(t, dial)
// Adding b and accepting a connection from it will not dispense it either.
@@ -676,8 +658,7 @@ func TestPeerManager_TryDialNext_DialingConnected(t *testing.T) {
require.NoError(t, err)
require.True(t, added)
require.NoError(t, peerManager.Accepted(bID))
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Zero(t, dial)
}
@@ -706,16 +687,14 @@ func TestPeerManager_TryDialNext_Multiple(t *testing.T) {
// All addresses should be dispensed as long as dialing them has failed.
dial := []p2p.NodeAddress{}
for range addresses {
address, err := peerManager.TryDialNext()
require.NoError(t, err)
address := peerManager.TryDialNext()
require.NotZero(t, address)
require.NoError(t, peerManager.DialFailed(ctx, address))
dial = append(dial, address)
}
require.ElementsMatch(t, dial, addresses)
address, err := peerManager.TryDialNext()
require.NoError(t, err)
address := peerManager.TryDialNext()
require.Zero(t, address)
}
@@ -740,15 +719,14 @@ func TestPeerManager_DialFailed(t *testing.T) {
// Dialing and then calling DialFailed with a different address (same
// NodeID) should unmark as dialing and allow us to dial the other address
// again, but not register the failed address.
dial, err := peerManager.TryDialNext()
dial := peerManager.TryDialNext()
require.NoError(t, err)
require.Equal(t, a, dial)
require.NoError(t, peerManager.DialFailed(ctx, p2p.NodeAddress{
Protocol: "tcp", NodeID: aID, Hostname: "localhost"}))
require.Equal(t, []p2p.NodeAddress{a}, peerManager.Addresses(aID))
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Equal(t, a, dial)
// Calling DialFailed on same address twice should be fine.
@@ -782,8 +760,7 @@ func TestPeerManager_DialFailed_UnreservePeer(t *testing.T) {
added, err := peerManager.Add(a)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, a, dial)
require.NoError(t, peerManager.Dialed(a))
@@ -791,8 +768,7 @@ func TestPeerManager_DialFailed_UnreservePeer(t *testing.T) {
added, err = peerManager.Add(b)
require.NoError(t, err)
require.True(t, added)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Equal(t, b, dial)
// Adding c and dialing it will fail, even though it could upgrade a and we
@@ -801,14 +777,12 @@ func TestPeerManager_DialFailed_UnreservePeer(t *testing.T) {
added, err = peerManager.Add(c)
require.NoError(t, err)
require.True(t, added)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Empty(t, dial)
// Failing b's dial will now make c available for dialing.
require.NoError(t, peerManager.DialFailed(ctx, b))
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Equal(t, c, dial)
}
@@ -823,8 +797,7 @@ func TestPeerManager_Dialed_Connected(t *testing.T) {
added, err := peerManager.Add(a)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, a, dial)
require.NoError(t, peerManager.Dialed(a))
@@ -834,8 +807,7 @@ func TestPeerManager_Dialed_Connected(t *testing.T) {
added, err = peerManager.Add(b)
require.NoError(t, err)
require.True(t, added)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Equal(t, b, dial)
require.NoError(t, peerManager.Accepted(b.NodeID))
@@ -864,8 +836,7 @@ func TestPeerManager_Dialed_MaxConnected(t *testing.T) {
added, err := peerManager.Add(a)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, a, dial)
// Marking b as dialed in the meanwhile (even without TryDialNext)
@@ -907,8 +878,7 @@ func TestPeerManager_Dialed_MaxConnectedUpgrade(t *testing.T) {
added, err = peerManager.Add(c)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, c, dial)
require.NoError(t, peerManager.Dialed(c))
@@ -952,8 +922,7 @@ func TestPeerManager_Dialed_Upgrade(t *testing.T) {
added, err = peerManager.Add(b)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, b, dial)
require.NoError(t, peerManager.Dialed(b))
@@ -962,8 +931,7 @@ func TestPeerManager_Dialed_Upgrade(t *testing.T) {
added, err = peerManager.Add(c)
require.NoError(t, err)
require.True(t, added)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Empty(t, dial)
// a should now be evicted.
@@ -1009,8 +977,7 @@ func TestPeerManager_Dialed_UpgradeEvenLower(t *testing.T) {
added, err = peerManager.Add(c)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, c, dial)
// In the meanwhile, a disconnects and d connects. d is even lower-scored
@@ -1063,7 +1030,7 @@ func TestPeerManager_Dialed_UpgradeNoEvict(t *testing.T) {
added, err = peerManager.Add(c)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
dial := peerManager.TryDialNext()
require.NoError(t, err)
require.Equal(t, c, dial)
@@ -1109,8 +1076,7 @@ func TestPeerManager_Accepted(t *testing.T) {
added, err = peerManager.Add(c)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, c, dial)
require.NoError(t, peerManager.Accepted(c.NodeID))
require.Error(t, peerManager.Dialed(c))
@@ -1119,8 +1085,7 @@ func TestPeerManager_Accepted(t *testing.T) {
added, err = peerManager.Add(d)
require.NoError(t, err)
require.True(t, added)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Equal(t, d, dial)
require.NoError(t, peerManager.Dialed(d))
require.Error(t, peerManager.Accepted(d.NodeID))
@@ -1271,8 +1236,7 @@ func TestPeerManager_Accepted_UpgradeDialing(t *testing.T) {
added, err = peerManager.Add(b)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, b, dial)
// a has already been claimed as an upgrade of a, so accepting
@@ -1446,8 +1410,7 @@ func TestPeerManager_EvictNext_WakeOnUpgradeDialed(t *testing.T) {
added, err := peerManager.Add(b)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, b, dial)
require.NoError(t, peerManager.Dialed(b))
}()
@@ -1581,13 +1544,11 @@ func TestPeerManager_Disconnected(t *testing.T) {
// Disconnecting a dialing peer does not unmark it as dialing, to avoid
// dialing it multiple times in parallel.
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, a, dial)
peerManager.Disconnected(ctx, a.NodeID)
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Zero(t, dial)
}
@@ -1660,8 +1621,7 @@ func TestPeerManager_Subscribe(t *testing.T) {
require.Equal(t, p2p.PeerUpdate{NodeID: a.NodeID, Status: p2p.PeerStatusDown}, <-sub.Updates())
// Outbound connection with peer error and eviction.
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, a, dial)
require.Empty(t, sub.Updates())
@@ -1684,8 +1644,7 @@ func TestPeerManager_Subscribe(t *testing.T) {
require.Equal(t, p2p.PeerUpdate{NodeID: a.NodeID, Status: p2p.PeerStatusDown}, <-sub.Updates())
// Outbound connection with dial failure.
dial, err = peerManager.TryDialNext()
require.NoError(t, err)
dial = peerManager.TryDialNext()
require.Equal(t, a, dial)
require.Empty(t, sub.Updates())
@@ -1790,8 +1749,7 @@ func TestPeerManager_Close(t *testing.T) {
added, err := peerManager.Add(a)
require.NoError(t, err)
require.True(t, added)
dial, err := peerManager.TryDialNext()
require.NoError(t, err)
dial := peerManager.TryDialNext()
require.Equal(t, a, dial)
require.NoError(t, peerManager.DialFailed(ctx, a))
}

View File

@@ -151,7 +151,9 @@ func (s *pqScheduler) closed() <-chan struct{} { return s.done }
// non-empty, we pop the top Envelope and send it on the dequeueCh.
func (s *pqScheduler) process(ctx context.Context) {
defer close(s.done)
dequeueReady := make(chan struct{}, 1)
LOOP:
for {
select {
case e := <-s.enqueueCh:
@@ -239,28 +241,36 @@ func (s *pqScheduler) process(ctx context.Context) {
)
}
}
// dequeue
select {
case dequeueReady <- struct{}{}:
default:
}
case <-dequeueReady:
for s.pq.Len() > 0 {
pqEnv = heap.Pop(s.pq).(*pqEnvelope)
s.size -= pqEnv.size
// deduct the Envelope size from all the relevant cumulative sizes
for i := 0; i < len(s.chDescs) && pqEnv.priority <= uint(s.chDescs[i].Priority); i++ {
s.sizes[uint(s.chDescs[i].Priority)] -= pqEnv.size
}
s.metrics.PeerSendBytesTotal.With(
"chID", chIDStr,
"peer_id", string(pqEnv.envelope.To),
"message_type", s.lc.ValueToMetricLabel(pqEnv.envelope.Message)).Add(float64(pqEnv.size))
s.metrics.PeerPendingSendBytes.With(
"peer_id", string(pqEnv.envelope.To)).Add(float64(-pqEnv.size))
pqEnv := heap.Pop(s.pq).(*pqEnvelope)
select {
case s.dequeueCh <- pqEnv.envelope:
case <-s.closeCh:
return
s.size -= pqEnv.size
// deduct the Envelope size from all the relevant cumulative sizes
for i := 0; i < len(s.chDescs) && pqEnv.priority <= uint(s.chDescs[i].Priority); i++ {
s.sizes[uint(s.chDescs[i].Priority)] -= pqEnv.size
}
chIDStr := strconv.Itoa(int(pqEnv.envelope.ChannelID))
s.metrics.PeerSendBytesTotal.With(
"chID", chIDStr,
"peer_id", string(pqEnv.envelope.To),
"message_type", s.lc.ValueToMetricLabel(pqEnv.envelope.Message)).Add(float64(pqEnv.size))
s.metrics.PeerPendingSendBytes.With(
"peer_id", string(pqEnv.envelope.To)).Add(float64(-pqEnv.size))
default:
heap.Push(s.pq, pqEnv)
select {
case dequeueReady <- struct{}{}:
default:
}
continue LOOP
}
}
case <-ctx.Done():

View File

@@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"io"
"math/rand"
"net"
"runtime"
"sync"
@@ -62,12 +61,6 @@ type RouterOptions struct {
// return an error to reject the peer.
FilterPeerByID func(context.Context, types.NodeID) error
// DialSleep controls the amount of time that the router
// sleeps between dialing peers. If not set, a default value
// is used that sleeps for a (random) amount of time up to 3
// seconds between submitting each peer to be dialed.
DialSleep func(context.Context)
// NumConcrruentDials controls how many parallel go routines
// are used to dial peers. This defaults to the value of
// runtime.NumCPU.
@@ -310,11 +303,7 @@ func (r *Router) routeChannel(
) {
for {
select {
case envelope, ok := <-outCh:
if !ok {
return
}
case envelope := <-outCh:
// Mark the envelope with the channel ID to allow sendPeer() to pass
// it on to Transport.SendMessage().
envelope.ChannelID = chID
@@ -391,20 +380,22 @@ func (r *Router) routeChannel(
}
}
case peerError, ok := <-errCh:
if !ok {
return
}
shouldEvict := peerError.Fatal || r.peerManager.HasMaxPeerCapacity()
case peerError := <-errCh:
maxPeerCapacity := r.peerManager.HasMaxPeerCapacity()
r.logger.Error("peer error",
"peer", peerError.NodeID,
"err", peerError.Err,
"evicting", shouldEvict,
"disconnecting", peerError.Fatal || maxPeerCapacity,
)
if shouldEvict {
if peerError.Fatal || maxPeerCapacity {
// if the error is fatal or all peer
// slots are in use, we can error
// (disconnect) from the peer.
r.peerManager.Errored(peerError.NodeID, peerError.Err)
} else {
// this just decrements the peer
// score.
r.peerManager.processPeerEvent(ctx, PeerUpdate{
NodeID: peerError.NodeID,
Status: PeerStatusBad,
@@ -419,7 +410,7 @@ func (r *Router) routeChannel(
func (r *Router) numConcurrentDials() int {
if r.options.NumConcurrentDials == nil {
return runtime.NumCPU()
return runtime.NumCPU() * 32
}
return r.options.NumConcurrentDials()
@@ -441,38 +432,6 @@ func (r *Router) filterPeersID(ctx context.Context, id types.NodeID) error {
return r.options.FilterPeerByID(ctx, id)
}
func (r *Router) dialSleep(ctx context.Context) {
if r.options.DialSleep == nil {
// the connTracker (on the other side) only rate
// limits peers for dialing more than once every 10ms,
// so these numbers are safe.
const (
maxDialerInterval = 500 // ms
minDialerInterval = 100 // ms
)
// nolint:gosec // G404: Use of weak random number generator
dur := time.Duration(rand.Int63n(maxDialerInterval-minDialerInterval+1) + minDialerInterval)
timer := time.NewTimer(dur * time.Millisecond)
defer timer.Stop()
select {
case <-ctx.Done():
case <-timer.C:
}
return
}
r.options.DialSleep(ctx)
if !r.peerManager.HasDialedMaxPeers() {
r.peerManager.dialWaker.Wake()
}
}
// acceptPeers accepts inbound connections from peers on the given transport,
// and spawns goroutines that route messages to/from them.
func (r *Router) acceptPeers(ctx context.Context, transport Transport) {
@@ -591,19 +550,13 @@ LOOP:
switch {
case errors.Is(err, context.Canceled):
break LOOP
case err != nil:
r.logger.Error("failed to find next peer to dial", "err", err)
break LOOP
case address == NodeAddress{}:
continue LOOP
}
select {
case addresses <- address:
// this jitters the frequency that we call
// DialNext and prevents us from attempting to
// create connections too quickly.
r.dialSleep(ctx)
continue
continue LOOP
case <-ctx.Done():
close(addresses)
break LOOP
@@ -642,6 +595,7 @@ func (r *Router) connectPeer(ctx context.Context, address NodeAddress) {
if err := r.runWithPeerMutex(func() error { return r.peerManager.Dialed(address) }); err != nil {
r.logger.Error("failed to dial peer", "op", "outgoing/dialing", "peer", address.NodeID, "err", err)
r.peerManager.dialWaker.Wake()
conn.Close()
return
}
@@ -717,14 +671,8 @@ func (r *Router) handshakePeer(
expectID types.NodeID,
) (types.NodeInfo, error) {
if r.options.HandshakeTimeout > 0 {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, r.options.HandshakeTimeout)
defer cancel()
}
nodeInfo := r.nodeInfoProducer()
peerInfo, peerKey, err := conn.Handshake(ctx, *nodeInfo, r.privKey)
peerInfo, peerKey, err := conn.Handshake(ctx, r.options.HandshakeTimeout, *nodeInfo, r.privKey)
if err != nil {
return peerInfo, err
}
@@ -937,6 +885,8 @@ func (r *Router) evictPeers(ctx context.Context) {
queue, ok := r.peerQueues[peerID]
r.peerMtx.RUnlock()
r.metrics.PeersEvicted.Add(1)
if ok {
queue.close()
}

View File

@@ -385,7 +385,7 @@ func TestRouter_AcceptPeers(t *testing.T) {
connCtx, connCancel := context.WithCancel(context.Background())
mockConnection := &mocks.Connection{}
mockConnection.On("String").Maybe().Return("mock")
mockConnection.On("Handshake", mock.Anything, selfInfo, selfKey).
mockConnection.On("Handshake", mock.Anything, mock.Anything, selfInfo, selfKey).
Return(tc.peerInfo, tc.peerKey, nil)
mockConnection.On("Close").Run(func(_ mock.Arguments) { connCancel() }).Return(nil).Maybe()
mockConnection.On("RemoteEndpoint").Return(p2p.Endpoint{})
@@ -500,7 +500,7 @@ func TestRouter_AcceptPeers_HeadOfLineBlocking(t *testing.T) {
mockConnection := &mocks.Connection{}
mockConnection.On("String").Maybe().Return("mock")
mockConnection.On("Handshake", mock.Anything, selfInfo, selfKey).
mockConnection.On("Handshake", mock.Anything, mock.Anything, selfInfo, selfKey).
WaitUntil(closeCh).Return(types.NodeInfo{}, nil, io.EOF)
mockConnection.On("Close").Return(nil)
mockConnection.On("RemoteEndpoint").Return(p2p.Endpoint{})
@@ -588,7 +588,7 @@ func TestRouter_DialPeers(t *testing.T) {
mockConnection := &mocks.Connection{}
mockConnection.On("String").Maybe().Return("mock")
if tc.dialErr == nil {
mockConnection.On("Handshake", mock.Anything, selfInfo, selfKey).
mockConnection.On("Handshake", mock.Anything, mock.Anything, selfInfo, selfKey).
Return(tc.peerInfo, tc.peerKey, nil)
mockConnection.On("Close").Run(func(_ mock.Arguments) { connCancel() }).Return(nil).Maybe()
}
@@ -674,7 +674,7 @@ func TestRouter_DialPeers_Parallel(t *testing.T) {
mockConnection := &mocks.Connection{}
mockConnection.On("String").Maybe().Return("mock")
mockConnection.On("Handshake", mock.Anything, selfInfo, selfKey).
mockConnection.On("Handshake", mock.Anything, mock.Anything, selfInfo, selfKey).
WaitUntil(closeCh).Return(types.NodeInfo{}, nil, io.EOF)
mockConnection.On("Close").Return(nil)
@@ -715,7 +715,6 @@ func TestRouter_DialPeers_Parallel(t *testing.T) {
mockTransport,
nil,
p2p.RouterOptions{
DialSleep: func(_ context.Context) {},
NumConcurrentDials: func() int {
ncpu := runtime.NumCPU()
if ncpu <= 3 {
@@ -757,7 +756,7 @@ func TestRouter_EvictPeers(t *testing.T) {
mockConnection := &mocks.Connection{}
mockConnection.On("String").Maybe().Return("mock")
mockConnection.On("Handshake", mock.Anything, selfInfo, selfKey).
mockConnection.On("Handshake", mock.Anything, mock.Anything, selfInfo, selfKey).
Return(peerInfo, peerKey.PubKey(), nil)
mockConnection.On("ReceiveMessage", mock.Anything).WaitUntil(closeCh).Return(chID, nil, io.EOF)
mockConnection.On("RemoteEndpoint").Return(p2p.Endpoint{})
@@ -826,7 +825,7 @@ func TestRouter_ChannelCompatability(t *testing.T) {
mockConnection := &mocks.Connection{}
mockConnection.On("String").Maybe().Return("mock")
mockConnection.On("Handshake", mock.Anything, selfInfo, selfKey).
mockConnection.On("Handshake", mock.Anything, mock.Anything, selfInfo, selfKey).
Return(incompatiblePeer, peerKey.PubKey(), nil)
mockConnection.On("RemoteEndpoint").Return(p2p.Endpoint{})
mockConnection.On("Close").Return(nil)
@@ -877,7 +876,7 @@ func TestRouter_DontSendOnInvalidChannel(t *testing.T) {
mockConnection := &mocks.Connection{}
mockConnection.On("String").Maybe().Return("mock")
mockConnection.On("Handshake", mock.Anything, selfInfo, selfKey).
mockConnection.On("Handshake", mock.Anything, mock.Anything, selfInfo, selfKey).
Return(peer, peerKey.PubKey(), nil)
mockConnection.On("RemoteEndpoint").Return(p2p.Endpoint{})
mockConnection.On("Close").Return(nil)

View File

@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net"
"time"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/types"
@@ -81,7 +82,7 @@ type Connection interface {
// FIXME: The handshake should really be the Router's responsibility, but
// that requires the connection interface to be byte-oriented rather than
// message-oriented (see comment above).
Handshake(context.Context, types.NodeInfo, crypto.PrivKey) (types.NodeInfo, crypto.PubKey, error)
Handshake(context.Context, time.Duration, types.NodeInfo, crypto.PrivKey) (types.NodeInfo, crypto.PubKey, error)
// ReceiveMessage returns the next message received on the connection,
// blocking until one is available. Returns io.EOF if closed.

View File

@@ -9,6 +9,7 @@ import (
"net"
"strconv"
"sync"
"time"
"golang.org/x/net/netutil"
@@ -274,6 +275,7 @@ func newMConnConnection(
// Handshake implements Connection.
func (c *mConnConnection) Handshake(
ctx context.Context,
timeout time.Duration,
nodeInfo types.NodeInfo,
privKey crypto.PrivKey,
) (types.NodeInfo, crypto.PubKey, error) {
@@ -283,6 +285,12 @@ func (c *mConnConnection) Handshake(
peerKey crypto.PubKey
errCh = make(chan error, 1)
)
handshakeCtx := ctx
if timeout > 0 {
var cancel context.CancelFunc
handshakeCtx, cancel = context.WithTimeout(ctx, timeout)
defer cancel()
}
// To handle context cancellation, we need to do the handshake in a
// goroutine and abort the blocking network calls by closing the connection
// when the context is canceled.
@@ -295,25 +303,29 @@ func (c *mConnConnection) Handshake(
}
}()
var err error
mconn, peerInfo, peerKey, err = c.handshake(ctx, nodeInfo, privKey)
mconn, peerInfo, peerKey, err = c.handshake(handshakeCtx, nodeInfo, privKey)
select {
case errCh <- err:
case <-ctx.Done():
case <-handshakeCtx.Done():
}
}()
select {
case <-ctx.Done():
case <-handshakeCtx.Done():
_ = c.Close()
return types.NodeInfo{}, nil, ctx.Err()
return types.NodeInfo{}, nil, handshakeCtx.Err()
case err := <-errCh:
if err != nil {
return types.NodeInfo{}, nil, err
}
c.mconn = mconn
// Start must not use the handshakeCtx. The handshakeCtx may have a
// timeout set that is intended to terminate only the handshake procedure.
// The context passed to Start controls the entire lifecycle of the
// mconn.
if err = c.mconn.Start(ctx); err != nil {
return types.NodeInfo{}, nil, err
}

View File

@@ -7,6 +7,7 @@ import (
"io"
"net"
"sync"
"time"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/log"
@@ -273,9 +274,16 @@ func (c *MemoryConnection) RemoteEndpoint() Endpoint {
// Handshake implements Connection.
func (c *MemoryConnection) Handshake(
ctx context.Context,
timeout time.Duration,
nodeInfo types.NodeInfo,
privKey crypto.PrivKey,
) (types.NodeInfo, crypto.PubKey, error) {
if timeout > 0 {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, timeout)
defer cancel()
}
select {
case c.sendCh <- memoryMessage{nodeInfo: &nodeInfo, pubKey: privKey.PubKey()}:
c.logger.Debug("sent handshake", "nodeInfo", nodeInfo)

View File

@@ -296,7 +296,7 @@ func TestConnection_Handshake(t *testing.T) {
errCh := make(chan error, 1)
go func() {
// Must use assert due to goroutine.
peerInfo, peerKey, err := ba.Handshake(ctx, bInfo, bKey)
peerInfo, peerKey, err := ba.Handshake(ctx, 0, bInfo, bKey)
if err == nil {
assert.Equal(t, aInfo, peerInfo)
assert.Equal(t, aKey.PubKey(), peerKey)
@@ -307,7 +307,7 @@ func TestConnection_Handshake(t *testing.T) {
}
}()
peerInfo, peerKey, err := ab.Handshake(ctx, aInfo, aKey)
peerInfo, peerKey, err := ab.Handshake(ctx, 0, aInfo, aKey)
require.NoError(t, err)
require.Equal(t, bInfo, peerInfo)
require.Equal(t, bKey.PubKey(), peerKey)
@@ -328,7 +328,7 @@ func TestConnection_HandshakeCancel(t *testing.T) {
ab, ba := dialAccept(ctx, t, a, b)
timeoutCtx, cancel := context.WithTimeout(ctx, 1*time.Minute)
cancel()
_, _, err := ab.Handshake(timeoutCtx, types.NodeInfo{}, ed25519.GenPrivKey())
_, _, err := ab.Handshake(timeoutCtx, 0, types.NodeInfo{}, ed25519.GenPrivKey())
require.Error(t, err)
require.Equal(t, context.Canceled, err)
_ = ab.Close()
@@ -338,7 +338,7 @@ func TestConnection_HandshakeCancel(t *testing.T) {
ab, ba = dialAccept(ctx, t, a, b)
timeoutCtx, cancel = context.WithTimeout(ctx, 200*time.Millisecond)
defer cancel()
_, _, err = ab.Handshake(timeoutCtx, types.NodeInfo{}, ed25519.GenPrivKey())
_, _, err = ab.Handshake(timeoutCtx, 0, types.NodeInfo{}, ed25519.GenPrivKey())
require.Error(t, err)
require.Equal(t, context.DeadlineExceeded, err)
_ = ab.Close()
@@ -642,13 +642,13 @@ func dialAcceptHandshake(ctx context.Context, t *testing.T, a, b p2p.Transport)
go func() {
privKey := ed25519.GenPrivKey()
nodeInfo := types.NodeInfo{NodeID: types.NodeIDFromPubKey(privKey.PubKey())}
_, _, err := ba.Handshake(ctx, nodeInfo, privKey)
_, _, err := ba.Handshake(ctx, 0, nodeInfo, privKey)
errCh <- err
}()
privKey := ed25519.GenPrivKey()
nodeInfo := types.NodeInfo{NodeID: types.NodeIDFromPubKey(privKey.PubKey())}
_, _, err := ab.Handshake(ctx, nodeInfo, privKey)
_, _, err := ab.Handshake(ctx, 0, nodeInfo, privKey)
require.NoError(t, err)
timer := time.NewTimer(2 * time.Second)

View File

@@ -18,6 +18,7 @@ import (
"github.com/tendermint/tendermint/internal/consensus"
"github.com/tendermint/tendermint/internal/eventbus"
"github.com/tendermint/tendermint/internal/eventlog"
"github.com/tendermint/tendermint/internal/libs/strings"
"github.com/tendermint/tendermint/internal/mempool"
"github.com/tendermint/tendermint/internal/p2p"
tmpubsub "github.com/tendermint/tendermint/internal/pubsub"
@@ -26,7 +27,6 @@ import (
"github.com/tendermint/tendermint/internal/state/indexer"
"github.com/tendermint/tendermint/internal/statesync"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/libs/strings"
"github.com/tendermint/tendermint/rpc/coretypes"
rpcserver "github.com/tendermint/tendermint/rpc/jsonrpc/server"
"github.com/tendermint/tendermint/types"

View File

@@ -61,20 +61,20 @@ func NewDefaultLogger(format, level string) (Logger, error) {
}
func (l defaultLogger) Info(msg string, keyVals ...interface{}) {
l.Logger.Info().Fields(getLogFields(keyVals...)).Msg(msg)
l.Logger.Info().Fields(keyVals).Msg(msg)
}
func (l defaultLogger) Error(msg string, keyVals ...interface{}) {
l.Logger.Error().Fields(getLogFields(keyVals...)).Msg(msg)
l.Logger.Error().Fields(keyVals).Msg(msg)
}
func (l defaultLogger) Debug(msg string, keyVals ...interface{}) {
l.Logger.Debug().Fields(getLogFields(keyVals...)).Msg(msg)
l.Logger.Debug().Fields(keyVals).Msg(msg)
}
func (l defaultLogger) With(keyVals ...interface{}) Logger {
return &defaultLogger{
Logger: l.Logger.With().Fields(getLogFields(keyVals...)).Logger(),
Logger: l.Logger.With().Fields(keyVals).Logger(),
}
}
@@ -99,16 +99,3 @@ func OverrideWithNewLogger(logger Logger, format, level string) error {
ol.Logger = nl.Logger
return nil
}
func getLogFields(keyVals ...interface{}) map[string]interface{} {
if len(keyVals)%2 != 0 {
return nil
}
fields := make(map[string]interface{}, len(keyVals))
for i := 0; i < len(keyVals); i += 2 {
fields[fmt.Sprint(keyVals[i])] = keyVals[i+1]
}
return fields
}

View File

@@ -1034,7 +1034,12 @@ func (c *Client) findNewPrimary(ctx context.Context, height int64, remove bool)
// process all the responses as they come in
for i := 0; i < cap(witnessResponsesC); i++ {
response := <-witnessResponsesC
var response witnessResponse
select {
case response = <-witnessResponsesC:
case <-ctx.Done():
return nil, ctx.Err()
}
switch response.err {
// success! We have found a new primary
case nil:
@@ -1063,10 +1068,6 @@ func (c *Client) findNewPrimary(ctx context.Context, height int64, remove bool)
// return the light block that new primary responded with
return response.lb, nil
// catch canceled contexts or deadlines
case context.Canceled, context.DeadlineExceeded:
return nil, response.err
// process benign errors by logging them only
case provider.ErrNoResponse, provider.ErrLightBlockNotFound, provider.ErrHeightTooHigh:
lastError = response.err

View File

@@ -715,7 +715,9 @@ func loadStateFromDBOrGenesisDocProvider(stateStore sm.Store, genDoc *types.Gene
func getRouterConfig(conf *config.Config, appClient abciclient.Client) p2p.RouterOptions {
opts := p2p.RouterOptions{
QueueType: conf.P2P.QueueType,
QueueType: conf.P2P.QueueType,
HandshakeTimeout: conf.P2P.HandshakeTimeout,
DialTimeout: conf.P2P.DialTimeout,
}
if conf.FilterPeers && appClient != nil {

View File

@@ -17,6 +17,7 @@ import (
"github.com/tendermint/tendermint/internal/consensus"
"github.com/tendermint/tendermint/internal/eventbus"
"github.com/tendermint/tendermint/internal/evidence"
tmstrings "github.com/tendermint/tendermint/internal/libs/strings"
"github.com/tendermint/tendermint/internal/mempool"
"github.com/tendermint/tendermint/internal/p2p"
"github.com/tendermint/tendermint/internal/p2p/conn"
@@ -28,7 +29,6 @@ import (
"github.com/tendermint/tendermint/libs/log"
tmnet "github.com/tendermint/tendermint/libs/net"
"github.com/tendermint/tendermint/libs/service"
tmstrings "github.com/tendermint/tendermint/libs/strings"
"github.com/tendermint/tendermint/privval"
tmgrpc "github.com/tendermint/tendermint/privval/grpc"
"github.com/tendermint/tendermint/types"
@@ -235,17 +235,18 @@ func createPeerManager(
maxUpgradeConns := uint16(4)
options := p2p.PeerManagerOptions{
SelfAddress: selfAddr,
MaxConnected: maxConns,
MaxOutgoingConnections: maxOutgoingConns,
MaxConnectedUpgrade: maxUpgradeConns,
MaxPeers: maxUpgradeConns + 4*maxConns,
MinRetryTime: 250 * time.Millisecond,
MaxRetryTime: 30 * time.Minute,
MaxRetryTimePersistent: 5 * time.Minute,
RetryTimeJitter: 5 * time.Second,
PrivatePeers: privatePeerIDs,
Metrics: metrics,
SelfAddress: selfAddr,
MaxConnected: maxConns,
MaxOutgoingConnections: maxOutgoingConns,
MaxConnectedUpgrade: maxUpgradeConns,
DisconnectCooldownPeriod: 2 * time.Second,
MaxPeers: maxUpgradeConns + 4*maxConns,
MinRetryTime: 250 * time.Millisecond,
MaxRetryTime: 30 * time.Minute,
MaxRetryTimePersistent: 5 * time.Minute,
RetryTimeJitter: 5 * time.Second,
PrivatePeers: privatePeerIDs,
Metrics: metrics,
}
peers := []p2p.NodeAddress{}

View File

@@ -1,4 +1,3 @@
//nolint: gosec
package main
import (
@@ -77,6 +76,8 @@ func (cli *CLI) generate() error {
return err
}
// nolint: gosec
// G404: Use of weak random number generator (math/rand instead of crypto/rand)
manifests, err := Generate(rand.New(rand.NewSource(randomSeed)), cli.opts)
if err != nil {
return err

34
test/e2e/pkg/exec/exec.go Normal file
View File

@@ -0,0 +1,34 @@
package exec
import (
"context"
"fmt"
"os"
osexec "os/exec"
)
// Command executes a shell command.
func Command(ctx context.Context, args ...string) error {
// nolint: gosec
// G204: Subprocess launched with a potential tainted input or cmd arguments
cmd := osexec.CommandContext(ctx, args[0], args[1:]...)
out, err := cmd.CombinedOutput()
switch err := err.(type) {
case nil:
return nil
case *osexec.ExitError:
return fmt.Errorf("failed to run %q:\n%v", args, string(out))
default:
return err
}
}
// CommandVerbose executes a shell command while displaying its output.
func CommandVerbose(ctx context.Context, args ...string) error {
// nolint: gosec
// G204: Subprocess launched with a potential tainted input or cmd arguments
cmd := osexec.CommandContext(ctx, args[0], args[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}

View File

@@ -0,0 +1,69 @@
package docker
import (
"bytes"
"text/template"
e2e "github.com/tendermint/tendermint/test/e2e/pkg"
)
// makeDockerCompose generates a Docker Compose config for a testnet.
func makeDockerCompose(testnet *e2e.Testnet) ([]byte, error) {
// Must use version 2 Docker Compose format, to support IPv6.
tmpl, err := template.New("docker-compose").Funcs(template.FuncMap{
"addUint32": func(x, y uint32) uint32 {
return x + y
},
"isBuiltin": func(protocol e2e.Protocol, mode e2e.Mode) bool {
return mode == e2e.ModeLight || protocol == e2e.ProtocolBuiltin
},
}).Parse(`version: '2.4'
networks:
{{ .Name }}:
labels:
e2e: true
driver: bridge
{{- if .IPv6 }}
enable_ipv6: true
{{- end }}
ipam:
driver: default
config:
- subnet: {{ .IP }}
services:
{{- range .Nodes }}
{{ .Name }}:
labels:
e2e: true
container_name: {{ .Name }}
image: tendermint/e2e-node
{{- if isBuiltin $.ABCIProtocol .Mode }}
entrypoint: /usr/bin/entrypoint-builtin
{{- else if .LogLevel }}
command: start --log-level {{ .LogLevel }}
{{- end }}
init: true
ports:
- 26656
- {{ if .ProxyPort }}{{ addUint32 .ProxyPort 1000 }}:{{ end }}26660
- {{ if .ProxyPort }}{{ .ProxyPort }}:{{ end }}26657
- 6060
volumes:
- ./{{ .Name }}:/tendermint
networks:
{{ $.Name }}:
ipv{{ if $.IPv6 }}6{{ else }}4{{ end}}_address: {{ .IP }}
{{end}}`)
if err != nil {
return nil, err
}
var buf bytes.Buffer
err = tmpl.Execute(&buf, testnet)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}

View File

@@ -0,0 +1,27 @@
package docker
import (
"context"
"path/filepath"
"github.com/tendermint/tendermint/test/e2e/pkg/exec"
)
// execCompose runs a Docker Compose command for a testnet.
func execCompose(ctx context.Context, dir string, args ...string) error {
return exec.Command(ctx, append(
[]string{"docker-compose", "--ansi=never", "-f", filepath.Join(dir, "docker-compose.yml")},
args...)...)
}
// execComposeVerbose runs a Docker Compose command for a testnet and displays its output.
func execComposeVerbose(ctx context.Context, dir string, args ...string) error {
return exec.CommandVerbose(ctx, append(
[]string{"docker-compose", "--ansi=never", "-f", filepath.Join(dir, "docker-compose.yml")},
args...)...)
}
// execDocker runs a Docker command.
func execDocker(ctx context.Context, args ...string) error {
return exec.Command(ctx, append([]string{"docker"}, args...)...)
}

View File

@@ -0,0 +1,140 @@
package docker
import (
"context"
"fmt"
"os"
"path/filepath"
"github.com/tendermint/tendermint/libs/log"
e2e "github.com/tendermint/tendermint/test/e2e/pkg"
"github.com/tendermint/tendermint/test/e2e/pkg/exec"
"github.com/tendermint/tendermint/test/e2e/pkg/infra"
)
// testnetInfra provides an API for provisioning and manipulating
// infrastructure for a Docker-based testnet.
type testnetInfra struct {
logger log.Logger
testnet *e2e.Testnet
}
var _ infra.TestnetInfra = &testnetInfra{}
// NewTestnetInfra constructs an infrastructure provider that allows for Docker-based
// testnet infrastructure.
func NewTestnetInfra(logger log.Logger, testnet *e2e.Testnet) infra.TestnetInfra {
return &testnetInfra{
logger: logger,
testnet: testnet,
}
}
func (ti *testnetInfra) Setup(ctx context.Context) error {
compose, err := makeDockerCompose(ti.testnet)
if err != nil {
return err
}
// nolint: gosec
// G306: Expect WriteFile permissions to be 0600 or less
err = os.WriteFile(filepath.Join(ti.testnet.Dir, "docker-compose.yml"), compose, 0644)
if err != nil {
return err
}
return nil
}
func (ti *testnetInfra) StartNode(ctx context.Context, node *e2e.Node) error {
return execCompose(ctx, ti.testnet.Dir, "up", "-d", node.Name)
}
func (ti *testnetInfra) DisconnectNode(ctx context.Context, node *e2e.Node) error {
return execDocker(ctx, "network", "disconnect", ti.testnet.Name+"_"+ti.testnet.Name, node.Name)
}
func (ti *testnetInfra) ConnectNode(ctx context.Context, node *e2e.Node) error {
return execDocker(ctx, "network", "connect", ti.testnet.Name+"_"+ti.testnet.Name, node.Name)
}
func (ti *testnetInfra) KillNodeProcess(ctx context.Context, node *e2e.Node) error {
return execCompose(ctx, ti.testnet.Dir, "kill", "-s", "SIGKILL", node.Name)
}
func (ti *testnetInfra) StartNodeProcess(ctx context.Context, node *e2e.Node) error {
return execCompose(ctx, ti.testnet.Dir, "start", node.Name)
}
func (ti *testnetInfra) PauseNodeProcess(ctx context.Context, node *e2e.Node) error {
return execCompose(ctx, ti.testnet.Dir, "pause", node.Name)
}
func (ti *testnetInfra) UnpauseNodeProcess(ctx context.Context, node *e2e.Node) error {
return execCompose(ctx, ti.testnet.Dir, "unpause", node.Name)
}
func (ti *testnetInfra) TerminateNodeProcess(ctx context.Context, node *e2e.Node) error {
return execCompose(ctx, ti.testnet.Dir, "kill", "-s", "SIGTERM", node.Name)
}
func (ti *testnetInfra) Stop(ctx context.Context) error {
return execCompose(ctx, ti.testnet.Dir, "down")
}
func (ti *testnetInfra) Pause(ctx context.Context) error {
return execCompose(ctx, ti.testnet.Dir, "pause")
}
func (ti *testnetInfra) Unpause(ctx context.Context) error {
return execCompose(ctx, ti.testnet.Dir, "unpause")
}
func (ti *testnetInfra) ShowLogs(ctx context.Context) error {
return execComposeVerbose(ctx, ti.testnet.Dir, "logs", "--no-color")
}
func (ti *testnetInfra) ShowNodeLogs(ctx context.Context, node *e2e.Node) error {
return execComposeVerbose(ctx, ti.testnet.Dir, "logs", "--no-color", node.Name)
}
func (ti *testnetInfra) TailLogs(ctx context.Context) error {
return execComposeVerbose(ctx, ti.testnet.Dir, "logs", "--follow")
}
func (ti *testnetInfra) TailNodeLogs(ctx context.Context, node *e2e.Node) error {
return execComposeVerbose(ctx, ti.testnet.Dir, "logs", "--follow", node.Name)
}
func (ti *testnetInfra) Cleanup(ctx context.Context) error {
ti.logger.Info("Removing Docker containers and networks")
// GNU xargs requires the -r flag to not run when input is empty, macOS
// does this by default. Ugly, but works.
xargsR := `$(if [[ $OSTYPE == "linux-gnu"* ]]; then echo -n "-r"; fi)`
err := exec.Command(ctx, "bash", "-c", fmt.Sprintf(
"docker container ls -qa --filter label=e2e | xargs %v docker container rm -f", xargsR))
if err != nil {
return err
}
err = exec.Command(ctx, "bash", "-c", fmt.Sprintf(
"docker network ls -q --filter label=e2e | xargs %v docker network rm", xargsR))
if err != nil {
return err
}
// On Linux, some local files in the volume will be owned by root since Tendermint
// runs as root inside the container, so we need to clean them up from within a
// container running as root too.
absDir, err := filepath.Abs(ti.testnet.Dir)
if err != nil {
return err
}
err = execDocker(ctx, "run", "--rm", "--entrypoint", "", "-v", fmt.Sprintf("%v:/network", absDir),
"tendermint/e2e-node", "sh", "-c", "rm -rf /network/*/")
if err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,84 @@
package infra
import (
"context"
e2e "github.com/tendermint/tendermint/test/e2e/pkg"
)
// TestnetInfra provides an API for manipulating the infrastructure of a
// specific testnet.
type TestnetInfra interface {
//
// Overarching testnet infrastructure management.
//
// Setup generates any necessary configuration for the infrastructure
// provider during testnet setup.
Setup(ctx context.Context) error
// Stop will stop all running processes throughout the testnet without
// destroying any infrastructure.
Stop(ctx context.Context) error
// Pause will pause all processes in the testnet.
Pause(ctx context.Context) error
// Unpause will resume a paused testnet.
Unpause(ctx context.Context) error
// ShowLogs prints all logs for the whole testnet to stdout.
ShowLogs(ctx context.Context) error
// TailLogs tails the logs for all nodes in the testnet, if this is
// supported by the infrastructure provider.
TailLogs(ctx context.Context) error
// Cleanup stops and destroys all running testnet infrastructure and
// deletes any generated files.
Cleanup(ctx context.Context) error
//
// Node management, including node infrastructure.
//
// StartNode provisions infrastructure for the given node and starts it.
StartNode(ctx context.Context, node *e2e.Node) error
// DisconnectNode modifies the specified node's network configuration such
// that it becomes bidirectionally disconnected from the network (it cannot
// see other nodes, and other nodes cannot see it).
DisconnectNode(ctx context.Context, node *e2e.Node) error
// ConnectNode modifies the specified node's network configuration such
// that it can become bidirectionally connected.
ConnectNode(ctx context.Context, node *e2e.Node) error
// ShowNodeLogs prints all logs for the node with the give ID to stdout.
ShowNodeLogs(ctx context.Context, node *e2e.Node) error
// TailNodeLogs tails the logs for a single node, if this is supported by
// the infrastructure provider.
TailNodeLogs(ctx context.Context, node *e2e.Node) error
//
// Node process management.
//
// KillNodeProcess sends SIGKILL to a node's process.
KillNodeProcess(ctx context.Context, node *e2e.Node) error
// StartNodeProcess will start a stopped node's process. Assumes that the
// node's infrastructure has previously been provisioned using
// ProvisionNode.
StartNodeProcess(ctx context.Context, node *e2e.Node) error
// PauseNodeProcess sends a signal to the node's process to pause it.
PauseNodeProcess(ctx context.Context, node *e2e.Node) error
// UnpauseNodeProcess resumes a paused node's process.
UnpauseNodeProcess(ctx context.Context, node *e2e.Node) error
// TerminateNodeProcess sends SIGTERM to a node's process.
TerminateNodeProcess(ctx context.Context, node *e2e.Node) error
}

View File

@@ -1,4 +1,3 @@
//nolint: gosec
package e2e
import (
@@ -467,7 +466,7 @@ func (n Node) AddressRPC() string {
// Client returns an RPC client for a node.
func (n Node) Client() (*rpchttp.HTTP, error) {
return rpchttp.New(fmt.Sprintf("http://127.0.0.1:%v", n.ProxyPort))
return rpchttp.New(fmt.Sprintf("http://%s", n.AddressRPC()))
}
// Stateless returns true if the node is either a seed node or a light node
@@ -481,6 +480,8 @@ type keyGenerator struct {
}
func newKeyGenerator(seed int64) *keyGenerator {
// nolint: gosec
// G404: Use of weak random number generator (math/rand instead of crypto/rand)
return &keyGenerator{
random: rand.New(rand.NewSource(seed)),
}

View File

@@ -1,70 +1,32 @@
package main
import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"github.com/tendermint/tendermint/libs/log"
e2e "github.com/tendermint/tendermint/test/e2e/pkg"
"github.com/tendermint/tendermint/test/e2e/pkg/infra"
)
// Cleanup removes the Docker Compose containers and testnet directory.
func Cleanup(logger log.Logger, testnet *e2e.Testnet) error {
err := cleanupDocker(logger)
if err != nil {
return err
// Cleanup destroys all infrastructure and removes all generated testnet files.
func Cleanup(ctx context.Context, logger log.Logger, testnetDir string, ti infra.TestnetInfra) error {
if testnetDir == "" {
return errors.New("no testnet directory set")
}
return cleanupDir(logger, testnet.Dir)
}
// cleanupDocker removes all E2E resources (with label e2e=True), regardless
// of testnet.
func cleanupDocker(logger log.Logger) error {
logger.Info("Removing Docker containers and networks")
// GNU xargs requires the -r flag to not run when input is empty, macOS
// does this by default. Ugly, but works.
xargsR := `$(if [[ $OSTYPE == "linux-gnu"* ]]; then echo -n "-r"; fi)`
err := exec("bash", "-c", fmt.Sprintf(
"docker container ls -qa --filter label=e2e | xargs %v docker container rm -f", xargsR))
if err != nil {
if err := ti.Cleanup(ctx); err != nil {
return err
}
return exec("bash", "-c", fmt.Sprintf(
"docker network ls -q --filter label=e2e | xargs %v docker network rm", xargsR))
}
// cleanupDir cleans up a testnet directory
func cleanupDir(logger log.Logger, dir string) error {
if dir == "" {
return errors.New("no directory set")
}
_, err := os.Stat(dir)
_, err := os.Stat(testnetDir)
if os.IsNotExist(err) {
return nil
} else if err != nil {
return err
}
logger.Info(fmt.Sprintf("Removing testnet directory %q", dir))
// On Linux, some local files in the volume will be owned by root since Tendermint
// runs as root inside the container, so we need to clean them up from within a
// container running as root too.
absDir, err := filepath.Abs(dir)
if err != nil {
return err
}
err = execDocker("run", "--rm", "--entrypoint", "", "-v", fmt.Sprintf("%v:/network", absDir),
"tendermint/e2e-node", "sh", "-c", "rm -rf /network/*/")
if err != nil {
return err
}
return os.RemoveAll(dir)
logger.Info(fmt.Sprintf("Removing testnet directory %q", testnetDir))
return os.RemoveAll(testnetDir)
}

View File

@@ -1,50 +0,0 @@
//nolint: gosec
package main
import (
"fmt"
"os"
osexec "os/exec"
"path/filepath"
)
// execute executes a shell command.
func exec(args ...string) error {
cmd := osexec.Command(args[0], args[1:]...)
out, err := cmd.CombinedOutput()
switch err := err.(type) {
case nil:
return nil
case *osexec.ExitError:
return fmt.Errorf("failed to run %q:\n%v", args, string(out))
default:
return err
}
}
// execVerbose executes a shell command while displaying its output.
func execVerbose(args ...string) error {
cmd := osexec.Command(args[0], args[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
// execCompose runs a Docker Compose command for a testnet.
func execCompose(dir string, args ...string) error {
return exec(append(
[]string{"docker-compose", "--ansi=never", "-f", filepath.Join(dir, "docker-compose.yml")},
args...)...)
}
// execComposeVerbose runs a Docker Compose command for a testnet and displays its output.
func execComposeVerbose(dir string, args ...string) error {
return execVerbose(append(
[]string{"docker-compose", "--ansi=never", "-f", filepath.Join(dir, "docker-compose.yml")},
args...)...)
}
// execDocker runs a Docker command.
func execDocker(args ...string) error {
return exec(append([]string{"docker"}, args...)...)
}

View File

@@ -13,6 +13,8 @@ import (
"github.com/tendermint/tendermint/libs/log"
e2e "github.com/tendermint/tendermint/test/e2e/pkg"
"github.com/tendermint/tendermint/test/e2e/pkg/infra"
"github.com/tendermint/tendermint/test/e2e/pkg/infra/docker"
)
const randomSeed = 2308084734268
@@ -33,6 +35,7 @@ func main() {
type CLI struct {
root *cobra.Command
testnet *e2e.Testnet
infra infra.TestnetInfra
preserve bool
}
@@ -53,12 +56,23 @@ func NewCLI(logger log.Logger) *CLI {
if err != nil {
return err
}
providerID, err := cmd.Flags().GetString("provider")
if err != nil {
return err
}
switch providerID {
case "docker":
cli.infra = docker.NewTestnetInfra(logger, testnet)
logger.Info("Using Docker-based infrastructure provider")
default:
return fmt.Errorf("unrecognized infrastructure provider ID: %s", providerID)
}
cli.testnet = testnet
return nil
},
RunE: func(cmd *cobra.Command, args []string) (err error) {
if err = Cleanup(logger, cli.testnet); err != nil {
if err = Cleanup(cmd.Context(), logger, cli.testnet.Dir, cli.infra); err != nil {
return err
}
defer func() {
@@ -67,11 +81,11 @@ func NewCLI(logger log.Logger) *CLI {
} else if err != nil {
logger.Info("Preserving testnet that encountered error",
"err", err)
} else if err := Cleanup(logger, cli.testnet); err != nil {
} else if err := Cleanup(cmd.Context(), logger, cli.testnet.Dir, cli.infra); err != nil {
logger.Error("error cleaning up testnet contents", "err", err)
}
}()
if err = Setup(logger, cli.testnet); err != nil {
if err = Setup(cmd.Context(), logger, cli.testnet, cli.infra); err != nil {
return err
}
@@ -87,7 +101,7 @@ func NewCLI(logger log.Logger) *CLI {
chLoadResult <- Load(lctx, logger, r, cli.testnet)
}()
startAt := time.Now()
if err = Start(ctx, logger, cli.testnet); err != nil {
if err = Start(ctx, logger, cli.testnet, cli.infra); err != nil {
return err
}
@@ -96,7 +110,7 @@ func NewCLI(logger log.Logger) *CLI {
}
if cli.testnet.HasPerturbations() {
if err = Perturb(ctx, logger, cli.testnet); err != nil {
if err = Perturb(ctx, logger, cli.testnet, cli.infra); err != nil {
return err
}
if err = Wait(ctx, logger, cli.testnet, 5); err != nil { // allow some txs to go through
@@ -134,7 +148,7 @@ func NewCLI(logger log.Logger) *CLI {
if err = Wait(ctx, logger, cli.testnet, 5); err != nil { // wait for network to settle before tests
return err
}
if err := Test(cli.testnet); err != nil {
if err := Test(ctx, cli.testnet); err != nil {
return err
}
return nil
@@ -144,6 +158,8 @@ func NewCLI(logger log.Logger) *CLI {
cli.root.PersistentFlags().StringP("file", "f", "", "Testnet TOML manifest")
_ = cli.root.MarkPersistentFlagRequired("file")
cli.root.PersistentFlags().String("provider", "docker", "Which infrastructure provider to use")
cli.root.Flags().BoolVarP(&cli.preserve, "preserve", "p", false,
"Preserves the running of the test net after tests are completed")
@@ -156,7 +172,7 @@ func NewCLI(logger log.Logger) *CLI {
Use: "setup",
Short: "Generates the testnet directory and configuration",
RunE: func(cmd *cobra.Command, args []string) error {
return Setup(logger, cli.testnet)
return Setup(cmd.Context(), logger, cli.testnet, cli.infra)
},
})
@@ -166,12 +182,12 @@ func NewCLI(logger log.Logger) *CLI {
RunE: func(cmd *cobra.Command, args []string) error {
_, err := os.Stat(cli.testnet.Dir)
if os.IsNotExist(err) {
err = Setup(logger, cli.testnet)
err = Setup(cmd.Context(), logger, cli.testnet, cli.infra)
}
if err != nil {
return err
}
return Start(cmd.Context(), logger, cli.testnet)
return Start(cmd.Context(), logger, cli.testnet, cli.infra)
},
})
@@ -179,7 +195,7 @@ func NewCLI(logger log.Logger) *CLI {
Use: "perturb",
Short: "Perturbs the Docker testnet, e.g. by restarting or disconnecting nodes",
RunE: func(cmd *cobra.Command, args []string) error {
return Perturb(cmd.Context(), logger, cli.testnet)
return Perturb(cmd.Context(), logger, cli.testnet, cli.infra)
},
})
@@ -196,7 +212,7 @@ func NewCLI(logger log.Logger) *CLI {
Short: "Stops the Docker testnet",
RunE: func(cmd *cobra.Command, args []string) error {
logger.Info("Stopping testnet")
return execCompose(cli.testnet.Dir, "down")
return cli.infra.Stop(cmd.Context())
},
})
@@ -205,7 +221,7 @@ func NewCLI(logger log.Logger) *CLI {
Short: "Pauses the Docker testnet",
RunE: func(cmd *cobra.Command, args []string) error {
logger.Info("Pausing testnet")
return execCompose(cli.testnet.Dir, "pause")
return cli.infra.Pause(cmd.Context())
},
})
@@ -214,7 +230,7 @@ func NewCLI(logger log.Logger) *CLI {
Short: "Resumes the Docker testnet",
RunE: func(cmd *cobra.Command, args []string) error {
logger.Info("Resuming testnet")
return execCompose(cli.testnet.Dir, "unpause")
return cli.infra.Unpause(cmd.Context())
},
})
@@ -259,7 +275,7 @@ func NewCLI(logger log.Logger) *CLI {
Use: "test",
Short: "Runs test cases against a running testnet",
RunE: func(cmd *cobra.Command, args []string) error {
return Test(cli.testnet)
return Test(cmd.Context(), cli.testnet)
},
})
@@ -267,17 +283,24 @@ func NewCLI(logger log.Logger) *CLI {
Use: "cleanup",
Short: "Removes the testnet directory",
RunE: func(cmd *cobra.Command, args []string) error {
return Cleanup(logger, cli.testnet)
return Cleanup(cmd.Context(), logger, cli.testnet.Dir, cli.infra)
},
})
cli.root.AddCommand(&cobra.Command{
Use: "logs [node]",
Short: "Shows the testnet or a specefic node's logs",
Short: "Shows the testnet or a specific node's logs",
Example: "runner logs validator03",
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return execComposeVerbose(cli.testnet.Dir, append([]string{"logs", "--no-color"}, args...)...)
if len(args) > 0 {
node := cli.testnet.LookupNode(args[0])
if node == nil {
return fmt.Errorf("no such node: %s", args[0])
}
return cli.infra.ShowNodeLogs(cmd.Context(), node)
}
return cli.infra.ShowLogs(cmd.Context())
},
})
@@ -287,9 +310,13 @@ func NewCLI(logger log.Logger) *CLI {
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 1 {
return execComposeVerbose(cli.testnet.Dir, "logs", "--follow", args[0])
node := cli.testnet.LookupNode(args[0])
if node == nil {
return fmt.Errorf("no such node: %s", args[0])
}
return cli.infra.TailNodeLogs(cmd.Context(), node)
}
return execComposeVerbose(cli.testnet.Dir, "logs", "--follow")
return cli.infra.TailLogs(cmd.Context())
},
})
@@ -302,20 +329,20 @@ func NewCLI(logger log.Logger) *CLI {
Min Block Interval
Max Block Interval
over a 100 block sampling period.
Does not run any perbutations.
`,
RunE: func(cmd *cobra.Command, args []string) error {
if err := Cleanup(logger, cli.testnet); err != nil {
if err := Cleanup(cmd.Context(), logger, cli.testnet.Dir, cli.infra); err != nil {
return err
}
defer func() {
if err := Cleanup(logger, cli.testnet); err != nil {
if err := Cleanup(cmd.Context(), logger, cli.testnet.Dir, cli.infra); err != nil {
logger.Error("error cleaning up testnet contents", "err", err)
}
}()
if err := Setup(logger, cli.testnet); err != nil {
if err := Setup(cmd.Context(), logger, cli.testnet, cli.infra); err != nil {
return err
}
@@ -331,7 +358,7 @@ Does not run any perbutations.
chLoadResult <- Load(lctx, logger, r, cli.testnet)
}()
if err := Start(ctx, logger, cli.testnet); err != nil {
if err := Start(ctx, logger, cli.testnet, cli.infra); err != nil {
return err
}

View File

@@ -8,10 +8,11 @@ import (
"github.com/tendermint/tendermint/libs/log"
rpctypes "github.com/tendermint/tendermint/rpc/coretypes"
e2e "github.com/tendermint/tendermint/test/e2e/pkg"
"github.com/tendermint/tendermint/test/e2e/pkg/infra"
)
// Perturbs a running testnet.
func Perturb(ctx context.Context, logger log.Logger, testnet *e2e.Testnet) error {
func Perturb(ctx context.Context, logger log.Logger, testnet *e2e.Testnet, ti infra.TestnetInfra) error {
timer := time.NewTimer(0) // first tick fires immediately; reset below
defer timer.Stop()
@@ -21,7 +22,7 @@ func Perturb(ctx context.Context, logger log.Logger, testnet *e2e.Testnet) error
case <-ctx.Done():
return ctx.Err()
case <-timer.C:
_, err := PerturbNode(ctx, logger, node, perturbation)
_, err := PerturbNode(ctx, logger, node, perturbation, ti)
if err != nil {
return err
}
@@ -36,46 +37,45 @@ func Perturb(ctx context.Context, logger log.Logger, testnet *e2e.Testnet) error
// PerturbNode perturbs a node with a given perturbation, returning its status
// after recovering.
func PerturbNode(ctx context.Context, logger log.Logger, node *e2e.Node, perturbation e2e.Perturbation) (*rpctypes.ResultStatus, error) {
testnet := node.Testnet
func PerturbNode(ctx context.Context, logger log.Logger, node *e2e.Node, perturbation e2e.Perturbation, ti infra.TestnetInfra) (*rpctypes.ResultStatus, error) {
switch perturbation {
case e2e.PerturbationDisconnect:
logger.Info(fmt.Sprintf("Disconnecting node %v...", node.Name))
if err := execDocker("network", "disconnect", testnet.Name+"_"+testnet.Name, node.Name); err != nil {
if err := ti.DisconnectNode(ctx, node); err != nil {
return nil, err
}
time.Sleep(10 * time.Second)
if err := execDocker("network", "connect", testnet.Name+"_"+testnet.Name, node.Name); err != nil {
if err := ti.ConnectNode(ctx, node); err != nil {
return nil, err
}
case e2e.PerturbationKill:
logger.Info(fmt.Sprintf("Killing node %v...", node.Name))
if err := execCompose(testnet.Dir, "kill", "-s", "SIGKILL", node.Name); err != nil {
if err := ti.KillNodeProcess(ctx, node); err != nil {
return nil, err
}
time.Sleep(10 * time.Second)
if err := execCompose(testnet.Dir, "start", node.Name); err != nil {
if err := ti.StartNodeProcess(ctx, node); err != nil {
return nil, err
}
case e2e.PerturbationPause:
logger.Info(fmt.Sprintf("Pausing node %v...", node.Name))
if err := execCompose(testnet.Dir, "pause", node.Name); err != nil {
if err := ti.PauseNodeProcess(ctx, node); err != nil {
return nil, err
}
time.Sleep(10 * time.Second)
if err := execCompose(testnet.Dir, "unpause", node.Name); err != nil {
if err := ti.UnpauseNodeProcess(ctx, node); err != nil {
return nil, err
}
case e2e.PerturbationRestart:
logger.Info(fmt.Sprintf("Restarting node %v...", node.Name))
if err := execCompose(testnet.Dir, "kill", "-s", "SIGTERM", node.Name); err != nil {
if err := ti.TerminateNodeProcess(ctx, node); err != nil {
return nil, err
}
time.Sleep(10 * time.Second)
if err := execCompose(testnet.Dir, "start", node.Name); err != nil {
if err := ti.StartNodeProcess(ctx, node); err != nil {
return nil, err
}

View File

@@ -23,7 +23,7 @@ func waitForHeight(ctx context.Context, testnet *e2e.Testnet, height int64) (*ty
clients = map[string]*rpchttp.HTTP{}
lastHeight int64
lastIncrease = time.Now()
nodesAtHeight = map[string]struct{}{}
nodesAtHeight = map[string]int64{}
numRunningNodes int
)
if height == 0 {
@@ -85,7 +85,7 @@ func waitForHeight(ctx context.Context, testnet *e2e.Testnet, height int64) (*ty
// add this node to the set of target
// height nodes
nodesAtHeight[node.Name] = struct{}{}
nodesAtHeight[node.Name] = result.SyncInfo.LatestBlockHeight
// if not all of the nodes that we
// have clients for have reached the

View File

@@ -1,8 +1,8 @@
// nolint: gosec
package main
import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"errors"
@@ -12,7 +12,6 @@ import (
"regexp"
"sort"
"strings"
"text/template"
"time"
"github.com/BurntSushi/toml"
@@ -22,6 +21,7 @@ import (
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/privval"
e2e "github.com/tendermint/tendermint/test/e2e/pkg"
"github.com/tendermint/tendermint/test/e2e/pkg/infra"
"github.com/tendermint/tendermint/types"
)
@@ -39,7 +39,7 @@ const (
)
// Setup sets up the testnet configuration.
func Setup(logger log.Logger, testnet *e2e.Testnet) error {
func Setup(ctx context.Context, logger log.Logger, testnet *e2e.Testnet, ti infra.TestnetInfra) error {
logger.Info(fmt.Sprintf("Generating testnet files in %q", testnet.Dir))
err := os.MkdirAll(testnet.Dir, os.ModePerm)
@@ -47,15 +47,6 @@ func Setup(logger log.Logger, testnet *e2e.Testnet) error {
return err
}
compose, err := MakeDockerCompose(testnet)
if err != nil {
return err
}
err = os.WriteFile(filepath.Join(testnet.Dir, "docker-compose.yml"), compose, 0644)
if err != nil {
return err
}
genesis, err := MakeGenesis(testnet)
if err != nil {
return err
@@ -92,6 +83,8 @@ func Setup(logger log.Logger, testnet *e2e.Testnet) error {
if err != nil {
return err
}
// nolint: gosec
// G306: Expect WriteFile permissions to be 0600 or less
err = os.WriteFile(filepath.Join(nodeDir, "config", "app.toml"), appCfg, 0644)
if err != nil {
return err
@@ -131,70 +124,13 @@ func Setup(logger log.Logger, testnet *e2e.Testnet) error {
}
}
if err := ti.Setup(ctx); err != nil {
return err
}
return nil
}
// MakeDockerCompose generates a Docker Compose config for a testnet.
func MakeDockerCompose(testnet *e2e.Testnet) ([]byte, error) {
// Must use version 2 Docker Compose format, to support IPv6.
tmpl, err := template.New("docker-compose").Funcs(template.FuncMap{
"addUint32": func(x, y uint32) uint32 {
return x + y
},
"isBuiltin": func(protocol e2e.Protocol, mode e2e.Mode) bool {
return mode == e2e.ModeLight || protocol == e2e.ProtocolBuiltin
},
}).Parse(`version: '2.4'
networks:
{{ .Name }}:
labels:
e2e: true
driver: bridge
{{- if .IPv6 }}
enable_ipv6: true
{{- end }}
ipam:
driver: default
config:
- subnet: {{ .IP }}
services:
{{- range .Nodes }}
{{ .Name }}:
labels:
e2e: true
container_name: {{ .Name }}
image: tendermint/e2e-node
{{- if isBuiltin $.ABCIProtocol .Mode }}
entrypoint: /usr/bin/entrypoint-builtin
{{- else if .LogLevel }}
command: start --log-level {{ .LogLevel }}
{{- end }}
init: true
ports:
- 26656
- {{ if .ProxyPort }}{{ addUint32 .ProxyPort 1000 }}:{{ end }}26660
- {{ if .ProxyPort }}{{ .ProxyPort }}:{{ end }}26657
- 6060
volumes:
- ./{{ .Name }}:/tendermint
networks:
{{ $.Name }}:
ipv{{ if $.IPv6 }}6{{ else }}4{{ end}}_address: {{ .IP }}
{{end}}`)
if err != nil {
return nil, err
}
var buf bytes.Buffer
err = tmpl.Execute(&buf, testnet)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// MakeGenesis generates a genesis document.
func MakeGenesis(testnet *e2e.Testnet) (types.GenesisDoc, error) {
genesis := types.GenesisDoc{
@@ -421,5 +357,7 @@ func UpdateConfigStateSync(node *e2e.Node, height int64, hash []byte) error {
}
bz = regexp.MustCompile(`(?m)^trust-height =.*`).ReplaceAll(bz, []byte(fmt.Sprintf(`trust-height = %v`, height)))
bz = regexp.MustCompile(`(?m)^trust-hash =.*`).ReplaceAll(bz, []byte(fmt.Sprintf(`trust-hash = "%X"`, hash)))
// nolint: gosec
// G306: Expect WriteFile permissions to be 0600 or less
return os.WriteFile(cfgPath, bz, 0644)
}

View File

@@ -8,9 +8,10 @@ import (
"github.com/tendermint/tendermint/libs/log"
e2e "github.com/tendermint/tendermint/test/e2e/pkg"
"github.com/tendermint/tendermint/test/e2e/pkg/infra"
)
func Start(ctx context.Context, logger log.Logger, testnet *e2e.Testnet) error {
func Start(ctx context.Context, logger log.Logger, testnet *e2e.Testnet, ti infra.TestnetInfra) error {
if len(testnet.Nodes) == 0 {
return fmt.Errorf("no nodes in testnet")
}
@@ -44,7 +45,7 @@ func Start(ctx context.Context, logger log.Logger, testnet *e2e.Testnet) error {
for len(nodeQueue) > 0 && nodeQueue[0].StartAt == 0 {
node := nodeQueue[0]
nodeQueue = nodeQueue[1:]
if err := execCompose(testnet.Dir, "up", "-d", node.Name); err != nil {
if err := ti.StartNode(ctx, node); err != nil {
return err
}
@@ -58,7 +59,7 @@ func Start(ctx context.Context, logger log.Logger, testnet *e2e.Testnet) error {
return err
}
node.HasStarted = true
logger.Info(fmt.Sprintf("Node %v up on http://127.0.0.1:%v", node.Name, node.ProxyPort))
logger.Info(fmt.Sprintf("Node %v up on http://%v:%v", node.IP, node.Name, node.ProxyPort))
}
networkHeight := testnet.InitialHeight
@@ -106,7 +107,7 @@ func Start(ctx context.Context, logger log.Logger, testnet *e2e.Testnet) error {
}
}
if err := execCompose(testnet.Dir, "up", "-d", node.Name); err != nil {
if err := ti.StartNode(ctx, node); err != nil {
return err
}
@@ -128,8 +129,8 @@ func Start(ctx context.Context, logger log.Logger, testnet *e2e.Testnet) error {
} else {
lastNodeHeight = status.SyncInfo.LatestBlockHeight
}
logger.Info(fmt.Sprintf("Node %v up on http://127.0.0.1:%v at height %v",
node.Name, node.ProxyPort, lastNodeHeight))
logger.Info(fmt.Sprintf("Node %v up on http://%v:%v at height %v",
node.IP, node.Name, node.ProxyPort, lastNodeHeight))
}
return nil

View File

@@ -1,17 +1,19 @@
package main
import (
"context"
"os"
e2e "github.com/tendermint/tendermint/test/e2e/pkg"
"github.com/tendermint/tendermint/test/e2e/pkg/exec"
)
// Test runs test cases under tests/
func Test(testnet *e2e.Testnet) error {
func Test(ctx context.Context, testnet *e2e.Testnet) error {
err := os.Setenv("E2E_MANIFEST", testnet.File)
if err != nil {
return err
}
return execVerbose("./build/tests", "-test.count=1")
return exec.CommandVerbose(ctx, "./build/tests", "-test.count=1")
}

View File

@@ -18,6 +18,8 @@ func TestNet_Peers(t *testing.T) {
netInfo, err := client.NetInfo(ctx)
require.NoError(t, err)
// FIXME: https://github.com/tendermint/tendermint/issues/8848
// We should be able to assert that we can discover all peers in a network
expectedPeers := len(node.Testnet.Nodes)
peers := make(map[string]*e2e.Node, 0)
seen := map[string]bool{}
@@ -31,7 +33,7 @@ func TestNet_Peers(t *testing.T) {
seen[n.Name] = false
}
require.Equal(t, expectedPeers, netInfo.NPeers,
require.GreaterOrEqual(t, netInfo.NPeers, expectedPeers-1,
"node is not fully meshed with peers")
for _, peerInfo := range netInfo.Peers {
@@ -43,8 +45,10 @@ func TestNet_Peers(t *testing.T) {
seen[peer.Name] = true
}
for name := range seen {
require.True(t, seen[name], "node %v not peered with %v", node.Name, name)
}
// FIXME: https://github.com/tendermint/tendermint/issues/8848
// We should be able to assert that we can discover all peers in a network
// for name := range seen {
// require.True(t, seen[name], "node %v not peered with %v", node.Name, name)
// }
})
}

View File

@@ -7,8 +7,8 @@ import (
"strconv"
"strings"
tmstrings "github.com/tendermint/tendermint/internal/libs/strings"
"github.com/tendermint/tendermint/libs/bytes"
tmstrings "github.com/tendermint/tendermint/libs/strings"
tmp2p "github.com/tendermint/tendermint/proto/tendermint/p2p"
)

View File

@@ -9,7 +9,7 @@ import (
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/secp256k1"
"github.com/tendermint/tendermint/crypto/sr25519"
tmstrings "github.com/tendermint/tendermint/libs/strings"
tmstrings "github.com/tendermint/tendermint/internal/libs/strings"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)