Compare commits

...

150 Commits

Author SHA1 Message Date
Sam Ricotta
28a7cbe97e wip 2022-11-25 16:15:04 +01:00
Sam Ricotta
f5bfacd2cf wip 2022-11-23 18:05:58 +01:00
Callum Waters
22d04dd19d fix up proto problems with orderbook 2022-11-22 14:24:43 +01:00
Callum Waters
5651a21adb add notes for testing 2022-11-18 16:54:32 +01:00
Callum Waters
bd75306a93 add more documentation 2022-11-18 16:49:33 +01:00
Callum Waters
b76eb6906c add hash and state meta tracking 2022-11-18 16:11:35 +01:00
Callum Waters
b0e07355bd add pairs to the database
Co-authored-by: samricotta <samricotta@users.noreply.github.com>
2022-11-18 14:18:52 +01:00
Callum Waters
f7184192a0 add execution components 2022-11-15 10:20:58 +01:00
Callum Waters
a0c68b4941 add signature verification to process proposal 2022-11-14 15:49:51 +01:00
Callum Waters
662517b0db add logic for signing and signature verification 2022-11-14 15:38:39 +01:00
Sam Ricotta
38897de6d7 orderbook example 2022-11-14 14:54:52 +01:00
Sam Ricotta
e1f3d5c58c wip test 2022-11-10 09:06:34 +01:00
Sam Ricotta
07804ea061 wip 2022-11-07 22:41:16 +01:00
Sam Ricotta
1f6a6176c0 Prepare and process proposal excecution 2022-10-28 16:20:59 +02:00
Sam Ricotta
b8162782c3 prepare proposal wip 2022-10-17 17:06:18 +03:00
Sam Ricotta
18382f97eb update 2022-10-17 17:04:40 +03:00
Sam Ricotta
5bfc6d7a3b process proposal checks 2022-10-17 17:00:06 +03:00
Callum Waters
43ce473402 add function 2022-10-17 16:57:28 +03:00
Callum Waters
3b4c1b903a split out types verification 2022-10-17 16:42:08 +03:00
Callum Waters
8a40180248 add more tests 2022-10-17 16:36:50 +03:00
Callum Waters
920c5ad813 fix some of the match functions and add more tests 2022-10-17 16:06:30 +03:00
Callum Waters
bbf1169aea add tests for market matching 2022-10-17 12:36:36 +03:00
Callum Waters
67d3a6e45b Merge branch 'sam/abci++-tutorial' of github.com:tendermint/tendermint into sam/abci++-tutorial 2022-10-17 12:16:21 +03:00
Callum Waters
0c2483e9f3 add match function 2022-10-17 12:14:40 +03:00
Sam Ricotta
b837ead457 Small fixes 2022-10-16 19:19:44 +03:00
Sam Ricotta
944e9ebdc0 sudo code updates 2022-10-16 18:58:40 +03:00
Callum Waters
28d47d9a38 update msg types 2022-10-16 18:53:39 +03:00
Sam Ricotta
7a81dd25bf update for pairng 2022-10-06 14:29:22 +02:00
Callum Waters
94c874da32 clean up and add descriptions to the protos 2022-10-06 10:37:16 +02:00
Callum Waters
e7e48024ca Start sketching out the orderbook app
Co-authored-by: samricotta <samricotta@users.noreply.github.com>
2022-10-06 09:31:50 +02:00
samricotta
abbeb919df Use evidence period when pruning (#9505)
* Added logic so when pruning, the evidence period is taken into consideration and only deletes unecessary data
2022-10-04 17:57:09 +02:00
Callum Waters
a02cc30e41 config: use a different source of versioning (#9486) 2022-10-04 15:01:32 +02:00
mmsqe
5c23ffb05b Remove the PEG query implementation. (#7336) (#9478) 2022-10-04 11:03:03 +02:00
dependabot[bot]
45518db3d0 build(deps): Bump styfle/cancel-workflow-action from 0.10.0 to 0.10.1 (#9501)
Bumps [styfle/cancel-workflow-action](https://github.com/styfle/cancel-workflow-action) from 0.10.0 to 0.10.1.
- [Release notes](https://github.com/styfle/cancel-workflow-action/releases)
- [Commits](https://github.com/styfle/cancel-workflow-action/compare/0.10.0...0.10.1)

---
updated-dependencies:
- dependency-name: styfle/cancel-workflow-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-03 11:03:48 +02:00
Thane Thomson
f76f6535b4 ci: Only notify on nightly E2E failures (#9495)
Signed-off-by: Thane Thomson <connect@thanethomson.com>

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-09-28 10:07:06 -04:00
dependabot[bot]
20ffe9e101 build(deps): Bump actions/stale from 5 to 6 (#9493)
Bumps [actions/stale](https://github.com/actions/stale) from 5 to 6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/actions/stale/releases">actions/stale's releases</a>.</em></p>
<blockquote>
<h2>v6.0.0</h2>
<p>⚠️ Breaking change ⚠️</p>
<p>Issues/PRs default <code>close-issue-reason</code> is now <code>not_planned</code>(<a href="https://github-redirect.dependabot.com/actions/stale/issues/789">#789</a>)</p>
<h2>V5.2.0</h2>
<p>Features:
New option <code>include-only-assigned</code> enables users to process only issues/PRs that are already assigned. If there is no assignees and this option is set, issue will not be processed per: <a href="https://github-redirect.dependabot.com/actions/stale/issues/596">issue/596</a></p>
<p>Fixes:
Fix date comparison edge case <a href="https://github-redirect.dependabot.com/actions/stale/pull/816">PR/816</a></p>
<p>Dependency Updates:
<a href="https://github-redirect.dependabot.com/actions/stale/pull/812">PR/812</a></p>
<h2>Fix issue when days-before-close is more than days-before-stale</h2>
<p>fixes a bug introduced in <a href="https://github-redirect.dependabot.com/actions/stale/issues/717">#717</a></p>
<p>fixed in <a href="https://github-redirect.dependabot.com/actions/stale/issues/775">#775</a></p>
<h2>v5.1.0</h2>
<h1>[5.1.0]</h1>
<p><a href="https://github-redirect.dependabot.com/actions/stale/issues/696">Don't process stale issues right after they're marked stale</a>
Add close-issue-reason option <a href="https://github-redirect.dependabot.com/actions/stale/pull/764">#764</a><a href="https://github-redirect.dependabot.com/actions/stale/pull/772">#772</a>
Various dependabot/dependency updates</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/actions/stale/blob/main/CHANGELOG.md">actions/stale's changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h1>[6.0.0]</h1>
<p>⚠️ Breaking change ⚠️</p>
<p>Issues/PRs default <code>close-issue-reason</code> is now <code>not_planned</code>(<a href="https://github-redirect.dependabot.com/actions/stale/issues/789">#789</a>)</p>
<h1>[5.1.0]</h1>
<p><a href="https://github-redirect.dependabot.com/actions/stale/issues/696">Don't process stale issues right after they're marked stale</a>
[Add close-issue-reason option]<a href="https://github-redirect.dependabot.com/actions/stale/pull/764">#764</a><a href="https://github-redirect.dependabot.com/actions/stale/pull/772">#772</a>
Various dependabot/dependency updates</p>
<h2><a href="https://github.com/actions/stale/compare/v3.0.19...v4.1.0">4.1.0</a> (2021-07-14)</h2>
<h2>Features</h2>
<ul>
<li><a href="9912fa74d1">Ability to exempt draft PRs</a></li>
</ul>
<h2><a href="https://github.com/actions/stale/compare/v3.0.19...v4.0.0">4.0.0</a> (2021-07-14)</h2>
<h3>Features</h3>
<ul>
<li><strong>options:</strong> simplify config by removing skip stale message options (<a href="https://github-redirect.dependabot.com/actions/stale/issues/457">#457</a>) (<a href="6ec637d238">6ec637d</a>), closes <a href="https://github-redirect.dependabot.com/actions/stale/issues/405">#405</a> <a href="https://github-redirect.dependabot.com/actions/stale/issues/455">#455</a></li>
<li><strong>output:</strong> print output parameters (<a href="https://github-redirect.dependabot.com/actions/stale/issues/458">#458</a>) (<a href="3e6d35b685">3e6d35b</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>dry-run:</strong> forbid mutations in dry-run (<a href="https://github-redirect.dependabot.com/actions/stale/issues/500">#500</a>) (<a href="f1017f33dd">f1017f3</a>), closes <a href="https://github-redirect.dependabot.com/actions/stale/issues/499">#499</a></li>
<li><strong>logs:</strong> coloured logs (<a href="https://github-redirect.dependabot.com/actions/stale/issues/465">#465</a>) (<a href="5fbbfba142">5fbbfba</a>)</li>
<li><strong>operations:</strong> fail fast the current batch to respect the operations limit (<a href="https://github-redirect.dependabot.com/actions/stale/issues/474">#474</a>) (<a href="5f6f311ca6">5f6f311</a>), closes <a href="https://github-redirect.dependabot.com/actions/stale/issues/466">#466</a></li>
<li><strong>label comparison</strong>: make label comparison case insensitive <a href="https://github-redirect.dependabot.com/actions/stale/pull/517">#517</a>, closes <a href="https://github-redirect.dependabot.com/actions/stale/pull/516">#516</a></li>
<li><strong>filtering comments by actor could have strange behavior</strong>: &quot;stale&quot; comments are now detected based on if the message is the stale message not <em>who</em> made the comment(<a href="https://github-redirect.dependabot.com/actions/stale/pull/519">#519</a>), fixes <a href="https://github-redirect.dependabot.com/actions/stale/pull/441">#441</a>, <a href="https://github-redirect.dependabot.com/actions/stale/pull/509">#509</a>, <a href="https://github-redirect.dependabot.com/actions/stale/pull/518">#518</a></li>
</ul>
<h3>Breaking Changes</h3>
<ul>
<li>The options <code>skip-stale-issue-message</code> and <code>skip-stale-pr-message</code> were removed. Instead, setting the options <code>stale-issue-message</code> and <code>stale-pr-message</code> will be enough to let the stale workflow add a comment. If the options are unset, a comment will not be added which was the equivalent of setting <code>skip-stale-issue-message</code> to <code>true</code>.</li>
<li>The <code>operations-per-run</code> option will be more effective. After migrating, you could face a failed-fast process workflow if you let the default value (30) or set it to a small number. In that case, you will see a warning at the end of the logs (if enabled) indicating that the workflow was stopped sooner to avoid consuming too much API calls. In most cases, you can just increase this limit to make sure to process everything in a single run.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="3de2653986"><code>3de2653</code></a> Update changelog for v6.0.0 (<a href="https://github-redirect.dependabot.com/actions/stale/issues/829">#829</a>)</li>
<li><a href="02e44c81cc"><code>02e44c8</code></a> fix(options)!: Make <code>not_planned</code> the default <code>close-issue-reason</code> (<a href="https://github-redirect.dependabot.com/actions/stale/issues/807">#807</a>)</li>
<li>See full diff in <a href="https://github.com/actions/stale/compare/v5...v6">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/stale&package-manager=github_actions&previous-version=5&new-version=6)](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-09-27 15:51:22 +00:00
Callum Waters
af5281d704 statesync: convert snapshot hashes to hex strings for logging (#9471) 2022-09-26 17:58:52 +02:00
Emmanuel T Odeke
ed68aadd2b .github/workflows: add cosmos/gosec vulnerability scanner for each Push/PR (#9464)
Adds a code vulnerability scanner that'll flag issues and issue advisories from cosmos/gosec https://github.com/cosmos/gosec
2022-09-23 20:26:55 +00:00
JayT106
e8ec611ed4 tools: use os home dir to instead of the hardcoded PATH (#9444)
porting PR #6498 to main

#### PR checklist

- [x] Tests written/updated, or no tests needed
- [x] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [x] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed
2022-09-23 20:15:19 +00:00
William Banfield
5fe1a72416 loadtime: add block time to the data point (#9484)
This pull request adds the block time as the unix time since the epoch to the `report` tool's csv output.

```csv
...
a7a8b903-1136-4da1-97aa-d25da7b4094f,1614226790,1663707084905417366,4,200,1024
a7a8b903-1136-4da1-97aa-d25da7b4094f,1614196724,1663707084905417366,4,200,1024
a7a8b903-1136-4da1-97aa-d25da7b4094f,1613097336,1663707084905417366,4,200,1024
a7a8b903-1136-4da1-97aa-d25da7b4094f,1609365168,1663707084905417366,4,200,1024
a7a8b903-1136-4da1-97aa-d25da7b4094f,1617199169,1663707084905417366,4,200,1024
a7a8b903-1136-4da1-97aa-d25da7b4094f,1615197134,1663707084905417366,4,200,1024
a7a8b903-1136-4da1-97aa-d25da7b4094f,1610399447,1663707084905417366,4,200,1024
...
```

#### PR checklist

- [ ] Tests written/updated, or no tests needed
- [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [ ] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed
2022-09-23 13:55:55 +00:00
Thane Thomson
b7f1e1f218 config: Add missing storage section when generating config (#9483) 2022-09-23 12:19:49 +02:00
Callum Waters
a0ed437942 config: cleaner separation of tests (#9421) 2022-09-22 12:42:25 +02:00
Callum Waters
561440a56d config: add version to the config file (#9413) 2022-09-22 10:49:31 +02:00
Thane Thomson
f1dc5811c3 Sync Vote.Verify() in spec with implementation (#9466) 2022-09-21 21:29:24 -04:00
Thane Thomson
e48d5a0294 docs: Use release badge in README instead of latest tag (#9475)
[Rendered](https://github.com/tendermint/tendermint/blob/thane/readme-release-badge/README.md)

The release tag currently shows `dev-v0.38.0`, which isn't useful to anyone.

---

#### PR checklist

- [x] Tests written/updated, or no tests needed
- [x] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [x] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed
2022-09-21 21:50:18 +00:00
William Banfield
f2c32c9b3e metrics: fix panic because of absent prometheus label (#9455)
Absence of this label causes a panic because the setters try to access the label despite it never being added to the metric. This PR adds the label to the metrics, thus preventing the panic.

#### PR checklist

- [ ] Tests written/updated, or no tests needed
- [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [ ] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed
2022-09-21 17:07:07 +00:00
Mark Rushakoff
84bc77cb1f Ensure Dockerfile stages use consistent Go version (#9462)
I noticed the tendermint image was running on Go 1.15. I assume that was just a missed search and replace when updating to go1.18.

Pull the go base image into a build arg so that the image is only defined once, and used consistently across all stages of the build.

#### PR checklist

- [x] Tests written/updated, or no tests needed
- [x] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [x] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed
2022-09-21 13:12:32 +00:00
Sergio Mena
fbcfecbc3a fix spec (#9467) 2022-09-21 14:33:29 +02:00
JayT106
fe0aa4d30e Normalise GenesisDoc before saving to state (#6059) (#9458) 2022-09-21 11:06:13 +02:00
JayT106
080dfab992 p2p/pex: reuse hash.Hasher per addrbook for speed (#6509) (#9445)
Cherry-picking PR #6509

By pre-creating the hasher, instead of creating new one everytime addrbook.hash is called.

```
name             old time/op    new time/op    delta
AddrBook_hash-8     181ns ±13%      80ns ± 1%  -56.08%  (p=0.000 n=10+10)

name             old alloc/op   new alloc/op   delta
AddrBook_hash-8      216B ± 0%        8B ± 0%  -96.30%  (p=0.000 n=10+10)

name             old allocs/op  new allocs/op  delta
AddrBook_hash-8      2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.000 n=10+10)
```

Fixed #6508



---

#### PR checklist

- [x] Tests written/updated, or no tests needed
- [x] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [x] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed
2022-09-21 08:34:14 +00:00
JayT106
ab4238a0e2 crypto/merkle: optimize merkle tree hashing (#6513) (#9446)
* crypto/merkle: optimize merkle tree hashing (#6513)

Upstream https://github.com/lazyledger/lazyledger-core/pull/351 to optimize merkle tree hashing

```
benchmark                                 old ns/op     new ns/op     delta
BenchmarkHashAlternatives/recursive-8     22914         21949         -4.21%
BenchmarkHashAlternatives/iterative-8     21634         21939         +1.41%

benchmark                                 old allocs     new allocs     delta
BenchmarkHashAlternatives/recursive-8     398            200            -49.75%
BenchmarkHashAlternatives/iterative-8     399            301            -24.56%

benchmark                                 old bytes     new bytes     delta
BenchmarkHashAlternatives/recursive-8     19088         6496          -65.97%
BenchmarkHashAlternatives/iterative-8     21776         13984         -35.78%
```

cc @odeke-em @cuonglm

* update pending log

Co-authored-by: Marko <marbar3778@yahoo.com>
2022-09-21 10:18:05 +02:00
JayT106
bfdeccd649 crypto/merkle: pre-allocate data slice in innherHash (#6443) (#9447)
Cherry-picking PR #6443

#### PR checklist

- [x] Tests written/updated, or no tests needed
- [x] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [x] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed
2022-09-21 08:00:53 +00:00
Callum Waters
e84d43ec93 cli: add --hard flag to rollback command to remove block as well (#9261)
Co-authored-by: Levi Aul <levi@leviaul.com>
2022-09-21 09:51:22 +02:00
Yawning Angel
2d1ada4d52 crypto: Upstream v0.35.x improvements (#9255)
* crypto: Use curve25519-voi

This switches the ed25519, sr25519 and merlin provider to curve25519-voi
and additionally adopts ZIP-215 semantics for ed25519 verification.

* crypto: Implement batch verification interface for ed25519 and sr25519

This commit adds the batch verification interface, but does not enable
it for anything.

* types: Use batch verification for verifying commits signatures
2022-09-21 09:34:04 +02:00
dependabot[bot]
c69ab68848 build(deps): Bump github.com/cosmos/gogoproto from 1.4.1 to 1.4.2 (#9451)
Bumps [github.com/cosmos/gogoproto](https://github.com/cosmos/gogoproto) from 1.4.1 to 1.4.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/cosmos/gogoproto/releases">github.com/cosmos/gogoproto's releases</a>.</em></p>
<blockquote>
<h2>v1.4.2</h2>
<h3>Features</h3>
<ul>
<li><a href="https://github-redirect.dependabot.com/cosmos/gogoproto/pull/13">#13</a> Add <code>AllFileDescriptors</code> function.</li>
</ul>
<h3>Improvements</h3>
<ul>
<li><a href="https://github-redirect.dependabot.com/cosmos/gogoproto/pull/8">#8</a> Fix typo in <code>doc.go</code>.</li>
<li><a href="https://github-redirect.dependabot.com/cosmos/gogoproto/pull/8">#8</a> Support for merging messages implementing Merger which are embedded by value.</li>
<li><a href="https://github-redirect.dependabot.com/cosmos/gogoproto/pull/8">#8</a> Use reflect.Value.String() for String kinds in proto equal.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/cosmos/gogoproto/blob/main/CHANGELOG.md">github.com/cosmos/gogoproto's changelog</a>.</em></p>
<blockquote>
<h2><a href="https://github.com/cosmos/gogoproto/releases/tag/v1.4.2">v1.4.2</a> - 2022-09-14</h2>
<h3>Features</h3>
<ul>
<li><a href="https://github-redirect.dependabot.com/cosmos/gogoproto/pull/13">#13</a> Add <code>AllFileDescriptors</code> function.</li>
</ul>
<h3>Improvements</h3>
<ul>
<li><a href="https://github-redirect.dependabot.com/cosmos/gogoproto/pull/8">#8</a> Fix typo in <code>doc.go</code>.</li>
<li><a href="https://github-redirect.dependabot.com/cosmos/gogoproto/pull/8">#8</a> Support for merging messages implementing Merger which are embedded by value.</li>
<li><a href="https://github-redirect.dependabot.com/cosmos/gogoproto/pull/8">#8</a> Use reflect.Value.String() for String kinds in proto equal.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="739310d858"><code>739310d</code></a> docs: add changelog (<a href="https://github-redirect.dependabot.com/cosmos/gogoproto/issues/15">#15</a>)</li>
<li><a href="4f8afe8bcd"><code>4f8afe8</code></a> feat: add AllFileDescriptors function (<a href="https://github-redirect.dependabot.com/cosmos/gogoproto/issues/13">#13</a>)</li>
<li><a href="27e5769808"><code>27e5769</code></a> ci: fix proto registry workflow (<a href="https://github-redirect.dependabot.com/cosmos/gogoproto/issues/12">#12</a>)</li>
<li><a href="c3a0399b5e"><code>c3a0399</code></a> feat: cherry-pick improvements from <code>gogo/protobuf</code> (<a href="https://github-redirect.dependabot.com/cosmos/gogoproto/issues/8">#8</a>)</li>
<li><a href="ed9594ccc9"><code>ed9594c</code></a> chore: bump protobuf (<a href="https://github-redirect.dependabot.com/cosmos/gogoproto/issues/9">#9</a>)</li>
<li>See full diff in <a href="https://github.com/cosmos/gogoproto/compare/v1.4.1...v1.4.2">compare view</a></li>
</ul>
</details>
<br />


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

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

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

---

<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-09-20 14:30:18 +00:00
dependabot[bot]
10d1156add build(deps): Bump github.com/bufbuild/buf from 1.7.0 to 1.8.0 (#9452)
Bumps [github.com/bufbuild/buf](https://github.com/bufbuild/buf) from 1.7.0 to 1.8.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/bufbuild/buf/releases">github.com/bufbuild/buf's releases</a>.</em></p>
<blockquote>
<h2>v1.8.0</h2>
<ul>
<li>Change default for <code>--origin</code> flag of <code>buf beta studio-agent</code> to <code>https://studio.buf.build</code></li>
<li>Change default for <code>--timeout</code> flag of <code>buf beta studio-agent</code> to <code>0</code> (no timeout). Before it was
<code>2m</code> (the default for all the other <code>buf</code> commands).</li>
<li>Add support for experimental code generation with the <code>plugin:</code> key in <code>buf.gen.yaml</code>.</li>
<li>Preserve single quotes with <code>buf format</code>.</li>
<li>Support <code>junit</code> format errors with <code>--error-format</code>.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/bufbuild/buf/blob/main/CHANGELOG.md">github.com/bufbuild/buf's changelog</a>.</em></p>
<blockquote>
<h2>[v1.8.0] - 2022-09-14</h2>
<ul>
<li>Change default for <code>--origin</code> flag of <code>buf beta studio-agent</code> to <code>https://studio.buf.build</code></li>
<li>Change default for <code>--timeout</code> flag of <code>buf beta studio-agent</code> to <code>0</code> (no timeout). Before it was
<code>2m</code> (the default for all the other <code>buf</code> commands).</li>
<li>Add support for experimental code generation with the <code>plugin:</code> key in <code>buf.gen.yaml</code>.</li>
<li>Preserve single quotes with <code>buf format</code>.</li>
<li>Support <code>junit</code> format errors with <code>--error-format</code>.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="dbd4a13a08"><code>dbd4a13</code></a> Update to v1.8.0</li>
<li><a href="4ab9fb1d82"><code>4ab9fb1</code></a> Add <code>LimitWriteBucket</code> (<a href="https://github-redirect.dependabot.com/bufbuild/buf/issues/1390">#1390</a>)</li>
<li><a href="95670a74cb"><code>95670a7</code></a> Rename repo member to contributor (<a href="https://github-redirect.dependabot.com/bufbuild/buf/issues/1402">#1402</a>)</li>
<li><a href="57e6293dda"><code>57e6293</code></a> fix comment to reference new command name (<a href="https://github-redirect.dependabot.com/bufbuild/buf/issues/1401">#1401</a>)</li>
<li><a href="382276c38e"><code>382276c</code></a> add httpserver.Run function (<a href="https://github-redirect.dependabot.com/bufbuild/buf/issues/1397">#1397</a>)</li>
<li><a href="f3fe91a9c0"><code>f3fe91a</code></a> fix local generation using plugin key (<a href="https://github-redirect.dependabot.com/bufbuild/buf/issues/1399">#1399</a>)</li>
<li><a href="59abf7924b"><code>59abf79</code></a> BSR-527 - Adds old visibility to repository visiblity changed event. (<a href="https://github-redirect.dependabot.com/bufbuild/buf/issues/1398">#1398</a>)</li>
<li><a href="0f5d198dac"><code>0f5d198</code></a> BSR-527 - Adds <code>PayloadRepositoryVisibilityChanged</code> (<a href="https://github-redirect.dependabot.com/bufbuild/buf/issues/1395">#1395</a>)</li>
<li><a href="5da7dc20c2"><code>5da7dc2</code></a> Add curated plugin search term (<a href="https://github-redirect.dependabot.com/bufbuild/buf/issues/1394">#1394</a>)</li>
<li><a href="495c5912fb"><code>495c591</code></a> implement protocol for negotiating supported features with plugin (<a href="https://github-redirect.dependabot.com/bufbuild/buf/issues/1360">#1360</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/bufbuild/buf/compare/v1.7.0...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/bufbuild/buf&package-manager=go_modules&previous-version=1.7.0&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-09-20 13:20:05 +00:00
dependabot[bot]
0f857047c5 build(deps): Bump bufbuild/buf-setup-action from 1.7.0 to 1.8.0 (#9450)
Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.7.0 to 1.8.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/bufbuild/buf-setup-action/releases">bufbuild/buf-setup-action's releases</a>.</em></p>
<blockquote>
<h2>v1.8.0</h2>
<ul>
<li>Set the default buf version to v1.8.0</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="ebfad693a1"><code>ebfad69</code></a> Update to v1.8.0</li>
<li><a href="9da1a4b683"><code>9da1a4b</code></a> upgrade dependencies (<a href="https://github-redirect.dependabot.com/bufbuild/buf-setup-action/issues/58">#58</a>)</li>
<li>See full diff in <a href="https://github.com/bufbuild/buf-setup-action/compare/v1.7.0...v1.8.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=bufbuild/buf-setup-action&package-manager=github_actions&previous-version=1.7.0&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-09-20 13:05:28 +00:00
JayT106
db26cff58f state: move pruneBlocks from consensus/state to state/execution (#9443) 2022-09-20 11:30:22 +02:00
William Banfield
a8efef1854 rfc: simplify mempool to support more broad tendermint uses (#9294)
For: #9240 

📖 [Rendered](https://github.com/tendermint/tendermint/blob/wb/app-side-mempool/docs/rfc/rfc-025-support-app-side-mempool.md)

#### PR checklist

- [ ] Tests written/updated, or no tests needed
- [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [ ] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed
2022-09-19 21:23:46 +00:00
Callum Waters
21a3bbda3f state: restore previous error message (#9435) 2022-09-16 14:49:51 +02:00
Thane Thomson
0c96f0b434 docs: Remove dev base tagging from release branch creation (#9434)
Signed-off-by: Thane Thomson <connect@thanethomson.com>

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-09-15 09:15:12 -04:00
Thane Thomson
3293ce6f94 docs: Enable build for v0.37.x branch (#9433) 2022-09-13 19:12:48 -04:00
dependabot[bot]
d67be51ef4 build(deps): Bump slackapi/slack-github-action from 1.21.0 to 1.22.0 (#9431)
Bumps [slackapi/slack-github-action](https://github.com/slackapi/slack-github-action) from 1.21.0 to 1.22.0.
- [Release notes](https://github.com/slackapi/slack-github-action/releases)
- [Commits](https://github.com/slackapi/slack-github-action/compare/v1.21.0...v1.22.0)

---
updated-dependencies:
- dependency-name: slackapi/slack-github-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-13 16:53:17 -04:00
Thane Thomson
10f3626e6f ci: Only allow automated security-related updates until v0.37.0 release (#9430)
As per discussion with @sergio-mena, this should disable all automated
dependency updates that are not security-related. We should make this
part of our standard practice when cutting new major releases, given
that our QA process for major releases is expensive at present and we
cannot re-run it for every dependency update.

Once we have cut a final major release, we can consider re-enabling
automated dependency updates here that can be rolled out in minor
releases.

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

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-09-13 16:46:34 -04:00
dependabot[bot]
7bd84cd8cc build(deps): Bump github.com/gofrs/uuid (#9406)
Bumps [github.com/gofrs/uuid](https://github.com/gofrs/uuid) from 4.2.0+incompatible to 4.3.0+incompatible.
- [Release notes](https://github.com/gofrs/uuid/releases)
- [Commits](https://github.com/gofrs/uuid/compare/v4.2.0...v4.3.0)

---
updated-dependencies:
- dependency-name: github.com/gofrs/uuid
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-13 16:31:30 -04:00
dependabot[bot]
7feb484765 build(deps): Bump gonum.org/v1/gonum from 0.8.2 to 0.12.0 (#9407)
Bumps gonum.org/v1/gonum from 0.8.2 to 0.12.0.


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=gonum.org/v1/gonum&package-manager=go_modules&previous-version=0.8.2&new-version=0.12.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-09-13 14:25:37 +00:00
dependabot[bot]
2d77374d4f build(deps): Bump github.com/lib/pq from 1.10.6 to 1.10.7 (#9405)
Bumps [github.com/lib/pq](https://github.com/lib/pq) from 1.10.6 to 1.10.7.
<details>
<summary>Commits</summary>
<ul>
<li><a href="d5affd5073"><code>d5affd5</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/lib/pq/issues/1088">#1088</a> from kelvich/sni_support</li>
<li><a href="d65e6ae4bd"><code>d65e6ae</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/lib/pq/issues/1083">#1083</a> from nhooyr/fix-receiver-51e2</li>
<li><a href="957fc0b401"><code>957fc0b</code></a> Set SNI for TSL connections</li>
<li><a href="89fee89644"><code>89fee89</code></a> Use pointer receiver on pq.Error.Error()</li>
<li>See full diff in <a href="https://github.com/lib/pq/compare/v1.10.6...v1.10.7">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/lib/pq&package-manager=go_modules&previous-version=1.10.6&new-version=1.10.7)](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-09-13 13:07:15 +00:00
dependabot[bot]
c1f163f39b build(deps): Bump github.com/spf13/viper from 1.12.0 to 1.13.0 (#9408)
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.12.0 to 1.13.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/spf13/viper/releases">github.com/spf13/viper's releases</a>.</em></p>
<blockquote>
<h2>v1.13.0</h2>
<p><strong>Important:</strong> This is the last release supporting Go 1.15.</p>
<h2>What's Changed</h2>
<h3>Exciting New Features 🎉</h3>
<ul>
<li>Add etcd3 to supported remote providers by <a href="https://github.com/franklinkim"><code>@​franklinkim</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1371">spf13/viper#1371</a></li>
</ul>
<h3>Enhancements 🚀</h3>
<ul>
<li>Fix go-staticcheck failures (ST1005) by <a href="https://github.com/mjmaisey"><code>@​mjmaisey</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1373">spf13/viper#1373</a></li>
<li>Use jsonc in markdown codeblocks for better readability by <a href="https://github.com/HurSungYun"><code>@​HurSungYun</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1393">spf13/viper#1393</a></li>
<li>Add Go 1.19 support by <a href="https://github.com/sagikazarmark"><code>@​sagikazarmark</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1424">spf13/viper#1424</a></li>
<li>Adds support for uint16 with <code>GetUint16</code> by <a href="https://github.com/oxisto"><code>@​oxisto</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1405">spf13/viper#1405</a></li>
<li>Add a DebugTo convenience funtion by <a href="https://github.com/bcrochet"><code>@​bcrochet</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1414">spf13/viper#1414</a></li>
</ul>
<h3>Bug Fixes 🐛</h3>
<ul>
<li>Recurse into arrays when converting keys to lowercase by <a href="https://github.com/awrichar"><code>@​awrichar</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1387">spf13/viper#1387</a></li>
</ul>
<h3>Dependency Updates ⬆️</h3>
<ul>
<li>build(deps): bump github.com/stretchr/testify from 1.7.1 to 1.7.2 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1374">spf13/viper#1374</a></li>
<li>build(deps): bump github.com/subosito/gotenv from 1.3.0 to 1.4.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1375">spf13/viper#1375</a></li>
<li>build(deps): bump github.com/pelletier/go-toml/v2 from 2.0.1 to 2.0.2 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1378">spf13/viper#1378</a></li>
<li>build(deps): bump gopkg.in/yaml.v3 from 3.0.0 to 3.0.1 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1360">spf13/viper#1360</a></li>
<li>build(deps): bump github.com/stretchr/testify from 1.7.2 to 1.7.3 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1381">spf13/viper#1381</a></li>
<li>build(deps): bump github.com/stretchr/testify from 1.7.3 to 1.7.4 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1384">spf13/viper#1384</a></li>
<li>build(deps): bump mheap/github-action-required-labels from 1 to 2 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1383">spf13/viper#1383</a></li>
<li>build(deps): bump github.com/stretchr/testify from 1.7.4 to 1.8.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1395">spf13/viper#1395</a></li>
<li>build(deps): bump github.com/subosito/gotenv from 1.4.0 to 1.4.1 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1420">spf13/viper#1420</a></li>
<li>build(deps): bump github.com/pelletier/go-toml/v2 from 2.0.2 to 2.0.5 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1422">spf13/viper#1422</a></li>
<li>build(deps): bump gopkg.in/ini.v1 from 1.66.4 to 1.67.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1412">spf13/viper#1412</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/mjmaisey"><code>@​mjmaisey</code></a> made their first contribution in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1373">spf13/viper#1373</a></li>
<li><a href="https://github.com/HurSungYun"><code>@​HurSungYun</code></a> made their first contribution in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1393">spf13/viper#1393</a></li>
<li><a href="https://github.com/franklinkim"><code>@​franklinkim</code></a> made their first contribution in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1371">spf13/viper#1371</a></li>
<li><a href="https://github.com/awrichar"><code>@​awrichar</code></a> made their first contribution in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1387">spf13/viper#1387</a></li>
<li><a href="https://github.com/oxisto"><code>@​oxisto</code></a> made their first contribution in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1405">spf13/viper#1405</a></li>
<li><a href="https://github.com/bcrochet"><code>@​bcrochet</code></a> made their first contribution in <a href="https://github-redirect.dependabot.com/spf13/viper/pull/1414">spf13/viper#1414</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/spf13/viper/compare/v1.12.0...v1.13.0">https://github.com/spf13/viper/compare/v1.12.0...v1.13.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="57cc9a000f"><code>57cc9a0</code></a> test: fix ini tests</li>
<li><a href="8030d5b976"><code>8030d5b</code></a> build(deps): bump gopkg.in/ini.v1 from 1.66.4 to 1.67.0</li>
<li><a href="312417a0c5"><code>312417a</code></a> Add a DebugTo convenience funtion</li>
<li><a href="202060b3a2"><code>202060b</code></a> Adds support for uint16 with <code>GetUint16</code></li>
<li><a href="97591f0083"><code>97591f0</code></a> build: fix lint violations</li>
<li><a href="9af8daeeab"><code>9af8dae</code></a> ci: upgrade golangci-lint</li>
<li><a href="7b4f2b27cd"><code>7b4f2b2</code></a> ci: add Go 1.19 to CI</li>
<li><a href="601ec815ba"><code>601ec81</code></a> test: fix toml tests</li>
<li><a href="d7f4832bd3"><code>d7f4832</code></a> build(deps): bump github.com/pelletier/go-toml/v2 from 2.0.2 to 2.0.5</li>
<li><a href="c2f42f3060"><code>c2f42f3</code></a> build(deps): bump github.com/subosito/gotenv from 1.4.0 to 1.4.1</li>
<li>Additional commits viewable in <a href="https://github.com/spf13/viper/compare/v1.12.0...v1.13.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/spf13/viper&package-manager=go_modules&previous-version=1.12.0&new-version=1.13.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-09-13 09:29:58 +00:00
mmsqe
e80dd00894 backport: performance improvements for the event query API (#7319) (#9334)
* Performance improvements for the event query API (#7319)

Rework the implementation of event query parsing and execution to
improve performance and reduce memory usage.

Previous memory and CPU profiles of the pubsub service showed query
processing as a significant hotspot. While we don't have evidence that
this is visibly hurting users, fixing it is fairly easy and self-contained.

Updates #6439.

Typical benchmark results comparing the original implementation (PEG) with the reworked implementation (Custom):
```
TEST                        TIME/OP  BYTES/OP  ALLOCS/OP  SPEEDUP   MEM SAVING
BenchmarkParsePEG-12       51716 ns  526832    27
BenchmarkParseCustom-12     2167 ns    4616    17         23.8x     99.1%
BenchmarkMatchPEG-12        3086 ns    1097    22
BenchmarkMatchCustom-12    294.2 ns      64     3         10.5x     94.1%
```
2022-09-13 10:42:14 +02:00
Callum Waters
93ead3d0e5 remove fast sync deprecation warning (#9414) 2022-09-13 10:18:52 +02:00
Riccardo Montagnin
8e90d294ca feat: support HTTPS inside websocket (#9416) 2022-09-13 10:02:19 +02:00
Thane Thomson
dfefd837e7 docs: Update ADRs for v0.37 (#9399)
* ADR-060 accepted -> proposed

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

* ADR-061 accepted -> proposed

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

* ADR-062 implemented -> proposed

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

* ADR-063 implemented -> accepted

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

* ADR-077: Update title and status to reflect current reality

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

* ADR-078: Update status to reflect current reality

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

* ADR-079: accepted

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

* ADR-068 and ADR-080: proposed

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

* ADR-065: implemented

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

* ADR-076: implemented

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

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-09-12 07:23:11 -04:00
Elias Naur
ac866e38d4 test/fuzz: bring changes from v0.34.x into main (#9299) 2022-09-11 16:27:42 +02:00
Wachiu Siu
0f45086c5f update btcec to v2 and use the latest btcutil (#9250)
* secp256k1: upgrade to latest btcec v2 and btcutil

* Update CHANGELOG_PENDING.md

Co-authored-by: Thane Thomson <connect@thanethomson.com>

* fix rebase

Co-authored-by: Thane Thomson <connect@thanethomson.com>
2022-09-09 07:32:23 -04:00
samricotta
5013bc3f4a Update to markdown links (#9384)
* first correction of markdown links

* Review updates
2022-09-08 10:31:35 +02:00
William Banfield
59a711eabe test: generate uuid on startup for load tool (#9383)
the `NewClient` method is called by the load test framework for each connection. This means that if multiple connections are instantiated, each connection will erroneously have its own UUID. This PR changes the UUID generation to happen at the _beginning_ of the script instead of on client creation so that each experimental run shares a UUID.

Caught while preparing the script for production readiness.

#### PR checklist

- [ ] Tests written/updated, or no tests needed
- [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [ ] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed
2022-09-08 01:00:07 +00:00
samricotta
43ebbed9c2 add redirect links (#9385) 2022-09-07 09:27:48 -04:00
Marko
ffce253273 print all versions of tendermint and its sub protocols (#9329) 2022-09-07 14:32:56 +02:00
Callum Waters
2ae117ef62 config: fix broken test (#9309) 2022-09-07 11:42:20 +02:00
dependabot[bot]
1944dfd873 build(deps): Bump gonum.org/v1/gonum from 0.11.0 to 0.12.0 (#9378) 2022-09-07 10:34:03 +02:00
Sergio Mena
d54ed6423f Add missing changes changelog files (#9376)
* Copy over v0.34.21 section of `CHANGELOG.md`

* Missing breaking changes in `CHANGELOG_PENDING.md`

* bump

* Fix doc link

* Fix doc link 2
2022-09-06 20:48:49 +02:00
William Banfield
1067ba1571 add separated runs by UUID (#9367)
This _should_ be the last piece needed for this tool.
This allows the tool to generate reports on multiple experimental runs that may have been performed against the same chain.

The `load` tool has been updated to generate a `UUID` on startup to uniquely identify each experimental run. The `report` tool separates all of the results it reads by `UUID` and performs separate calculations for each discovered experiment.

Sample output is as follows

```
Experiment ID: 6bd7d1e8-d82c-4dbe-a1b3-40ab99e4fa30

        Connections: 1
        Rate: 1000
        Size: 1024

        Total Valid Tx: 9000
        Total Negative Latencies: 0
        Minimum Latency: 86.632837ms
        Maximum Latency: 1.151089602s
        Average Latency: 813.759361ms
        Standard Deviation: 225.189977ms

Experiment ID: 453960af-6295-4282-aed6-367fc17c0de0

        Connections: 1
        Rate: 1000
        Size: 1024

        Total Valid Tx: 9000
        Total Negative Latencies: 0
        Minimum Latency: 79.312992ms
        Maximum Latency: 1.162446243s
        Average Latency: 422.755139ms
        Standard Deviation: 241.832475ms

Total Invalid Tx: 0
```

closes: #9352 

#### PR checklist

- [ ] Tests written/updated, or no tests needed
- [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [ ] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed
2022-09-06 14:38:08 +00:00
Julien Robert
101bf50e71 refactor: migrate to cosmos/gogoproto (#9356)
* refactor: migrate to `cosmos/gogoproto`

* add changelog

* Update Makefile

Co-authored-by: Thane Thomson <connect@thanethomson.com>

* update link

Co-authored-by: Thane Thomson <connect@thanethomson.com>
2022-09-06 07:28:37 -04:00
Thane Thomson
d7645628f1 ci: Remove "(WARNING: BETA SOFTWARE)" tagline from all upcoming releases (#9371)
This is by no means a signal that we offer any additional guarantees with our software. This warning seems somewhat pointless given that:
1. Our open source license clearly states that we offer no warranties with this software.
2. We are clearly still pre-1.0.

It also doesn't make sense to append "(WARNING: BETA SOFTWARE)" to pre-releases such as alpha releases, which are to be considered _more_ unstable than beta releases.

---

#### PR checklist

- [x] Tests written/updated, or no tests needed
- [x] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [x] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed
2022-09-03 14:59:29 +00:00
HaoTian
e667b855c7 fix(doc): wrong link address (#9370)
Signed-off-by: 117503445 <t117503445@gmail.com>

Signed-off-by: 117503445 <t117503445@gmail.com>
Co-authored-by: Thane Thomson <connect@thanethomson.com>
2022-09-03 08:39:13 -04:00
dependabot[bot]
c71efd1283 build(deps): Bump github.com/golangci/golangci-lint (#9323)
Bumps [github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint) from 1.48.0 to 1.49.0.
- [Release notes](https://github.com/golangci/golangci-lint/releases)
- [Changelog](https://github.com/golangci/golangci-lint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/golangci/golangci-lint/compare/v1.48.0...v1.49.0)

---
updated-dependencies:
- dependency-name: github.com/golangci/golangci-lint
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-03 08:29:35 -04:00
Thane Thomson
6bdc970377 ci: Pre-release workflows (#9366)
In preparation for the v0.37 release, this PR updates:
1. The [release guidelines](https://github.com/tendermint/tendermint/blob/thane/pre-release-workflows/RELEASES.md#pre-releases) regarding alpha and beta versions, as well as release candidates.
2. The GitHub workflows to build all 3 kinds of pre-releases for:
   1. Docker images
   2. Binaries (I'm still not 100% sure whether this is necessary, but it does act as a clear signal to users that a pre-release is available, and pre-built binaries could be useful for people running testnets who don't use Docker)
3. The Goreleaser config to auto-detect whether a tag is a pre-release and mark it as such as the release is created on GitHub.

---

#### PR checklist

- [x] Tests written/updated, or no tests needed
- [x] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [x] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed
2022-09-02 23:16:28 +00:00
William Banfield
8655080a0f test: add the loadtime report tool (#9351)
This pull request adds the report tool and modifies the loadtime libraries to better support its use.
2022-09-02 13:32:56 -04:00
Sergio Mena
bf73c7985e Update Tendermint version in main (#9360) 2022-09-02 13:01:14 -04:00
Jasmina Malicevic
6371f02810 spec: abci++ cleanup for v0.37 (#9288)
* v0.36 abci++ spec

* Basic concepts cleanup

* Resurrected beginBlock to EndBlock sequence

* Global Lock in Concurrency

* ResponseProcessProposal returns list of bytes

* Fixed broken links; added ExtendedCommitInfo and ExtendedVoteInfo

* Replace spec/abci with abci++ content

* Removed spec/abci

Co-authored-by: Sergio Mena <sergio@informal.systems>
Co-authored-by: Thane Thomson <connect@thanethomson.com>
2022-09-02 09:58:10 +02:00
Thane Thomson
b055535397 abci: Set version to 1.0.0 (#9341)
Signed-off-by: Thane Thomson <connect@thanethomson.com>

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-09-01 21:44:45 -04:00
samricotta
2ff11e5bc2 Update rpc client header (#9276)
* Update rpc client header
2022-09-01 14:35:07 +02:00
William Banfield
70fd943bdf test: add the loadtime tool (#9342)
This pull request adds the loadtime tool. This tool leverages the tm-load-test framework. Using the framework means that the only real logic that needs to be written is the logic for Tx generation. The framework does the rest.

The tool writes a set of metadata into the transaction, including the current transaction rate, number of connections, specified size of the transaction, and the current time.
2022-08-31 16:41:15 -04:00
Thane Thomson
f1835338d9 docs: Update RELEASES.md to reflect current process (#9339)
* docs: Update RELEASES.md to reflect current process

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

* Remove unnecessary asterisk

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

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-08-31 07:25:42 -04:00
Thane Thomson
bdf0217bd8 ci: Prepare for v0.37 release branch (#9338)
* Add nightly E2E tests on v0.37.x branch

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

* Add mergify config to backport to v0.37.x

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

* Update dependabot config for v0.37.x

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

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-08-30 22:53:12 -04:00
Thane Thomson
cceea4de22 chore: Format and fix lints (#9336)
* make format

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

* Fix linting directives

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

* make mockery

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

* Appease CI linter

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

* Appease CI linter

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

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-08-30 12:28:46 -04:00
Thane Thomson
7b40167f58 abci: Port EventAttribute field type change to main (#9335)
* types: Refactor EventAttribute (#6408)

Cherry-pick of 09a6ad7b1e

* Ensure context is honored

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

* Replace with tagged switch

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

* Ensure contexts are honored

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

* Add UPGRADING note about type change

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

* Remove unnecessary conversion

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

Signed-off-by: Thane Thomson <connect@thanethomson.com>
Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
2022-08-30 10:13:55 -04:00
dependabot[bot]
2313f35800 build(deps): Bump google.golang.org/grpc from 1.48.0 to 1.49.0 (#9322)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.48.0 to 1.49.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/grpc/grpc-go/releases">google.golang.org/grpc's releases</a>.</em></p>
<blockquote>
<h2>Release 1.49.0</h2>
<h1>New Features</h1>
<ul>
<li>gcp/observability: add support for Environment Variable <code>GRPC_CONFIG_OBSERVABILITY_JSON</code> (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5525">#5525</a>)</li>
<li>gcp/observability: add support for custom tags (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5565">#5565</a>)</li>
</ul>
<h1>Behavior Changes</h1>
<ul>
<li>server: reduce log level from Warning to Info for early connection establishment errors (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5524">#5524</a>)
<ul>
<li>Special Thanks: <a href="https://github.com/jpkrohling"><code>@​jpkrohling</code></a></li>
</ul>
</li>
</ul>
<h1>Bug Fixes</h1>
<ul>
<li>client: fix race in flow control that could lead to unexpected EOF errors (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5494">#5494</a>)</li>
<li>client: fix a race that could cause RPCs to time out instead of failing more quickly with UNAVAILABLE (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5503">#5503</a>)</li>
<li>client &amp; server: fix a panic caused by passing a <code>nil</code> stats handler to <code>grpc.WithStatsHandler</code> or <code>grpc.StatsHandler</code> (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5543">#5543</a>)</li>
<li>transport/server: fix a race that could cause a stray header to be sent (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5513">#5513</a>)</li>
<li>balancer: give precedence to <code>IDLE</code> over <code>TRANSIENT_FAILURE</code> when aggregating connectivity state (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5473">#5473</a>)</li>
<li>xds/xdsclient: request correct resource name when user specifies a new style resource name with empty authority (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5488">#5488</a>)</li>
<li>xds/xdsclient: NACK endpoint resources with zero weight (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5560">#5560</a>)</li>
<li>xds/xdsclient: fix bug that would reset resource version information after ADS stream restart (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5422">#5422</a>)</li>
<li>xds/xdsclient: fix goroutine leaks when load reporting is enabled (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5505">#5505</a>)</li>
<li>xds/ringhash: fix config update processing to recreate ring and picker when min/max ring size changes (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5557">#5557</a>)</li>
<li>xds/ringhash: avoid recreating subChannels when update doesn't change address weight information (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5431">#5431</a>)</li>
<li>xds/priority: fix bug which could cause priority LB to block all traffic after a config update (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5549">#5549</a>)</li>
<li>xds: fix bug when environment variable <code>GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION</code> is set to true (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5537">#5537</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="1c29e075ab"><code>1c29e07</code></a> Change version to 1.49.0 (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5583">#5583</a>)</li>
<li><a href="8e5a84e6b2"><code>8e5a84e</code></a> xds/resolver: generate channel ID randomly (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5603">#5603</a>)</li>
<li><a href="92cee3440f"><code>92cee34</code></a> gcp/observability: Add logging filters for logging, tracing, and metrics API ...</li>
<li><a href="c7fe135d12"><code>c7fe135</code></a> O11Y: Added support for custom tags (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5565">#5565</a>)</li>
<li><a href="7981af402b"><code>7981af4</code></a> test/kokoro: add missing image tagging to the xDS interop url map buildscript...</li>
<li><a href="6f34b7ad15"><code>6f34b7a</code></a> xdsclient: NACK endpoint resource if load_balancing_weight is specified and i...</li>
<li><a href="f9409d385f"><code>f9409d3</code></a> ringhash: handle config updates properly (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5557">#5557</a>)</li>
<li><a href="946dde008f"><code>946dde0</code></a> xdsclient: NACK endpoint resources with zero weight (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5560">#5560</a>)</li>
<li><a href="b89f49b0ff"><code>b89f49b</code></a> xdsclient: deflake Test/LDSWatch_PartialValid (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5552">#5552</a>)</li>
<li><a href="9bc72deba4"><code>9bc72de</code></a> grpc: remove mentions of WithBalancerName from comments (<a href="https://github-redirect.dependabot.com/grpc/grpc-go/issues/5555">#5555</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/grpc/grpc-go/compare/v1.48.0...v1.49.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=google.golang.org/grpc&package-manager=go_modules&previous-version=1.48.0&new-version=1.49.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-08-29 13:01:00 +00:00
Sergio Mena
3233568cee Added PrepareProposal and ProcessProposal data CHANGELOG_PENDING.md. Reworked UPGRADING.md (#9315)
* master-->main in `CONTRIBUTING.md`

* Added feature branches in `CONTRIBUTING.md`

* Fixes to `UPGRADING.md`

* [cherrypicked] docs: minor tweaks (#5404)

* docs: fix /validators description

Refs https://github.com/tendermint/spec/pull/169

* consensus: remove nil err from logging statement

* update UPGRADING.md

* note about LightBlocks

* Reworked "Unreleased" section of `UPGRADING.md`

* Added PrepareProposal and ProcessProposal to `CHANGELOG_PENDING.md`

* Apply suggestions from @thanethomson's code review

Co-authored-by: Thane Thomson <connect@thanethomson.com>

* Addressed @tychoish's comment

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
Co-authored-by: Thane Thomson <connect@thanethomson.com>
2022-08-26 23:53:13 +02:00
Thane Thomson
9f76e8da15 Temporarily revert #9175: remove lastresulthash from merklization in lastresult hash (#9313)
* Revert "remove lastresulthash from merklization in lastresult hash (#9175)"

This reverts commit bff63aec83.

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

* Clarify wording in ABCI upgrade guidelines

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

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-08-24 14:34:36 -04:00
Thane Thomson
28cfb039c9 docs: Add redirects to GitHub for spec links (#9311)
* Add spec redirects

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

* Use hack to make redirects work

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

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-08-24 10:14:54 -04:00
Callum Waters
5f932a53f0 e23: fix generation by considering evidence age in retain height (#9306) 2022-08-23 11:28:32 +02:00
Sergio Mena
50b5c23d88 Merge branch 'feature/abci++ppp' 2022-08-22 17:16:17 +02:00
Callum Waters
b37f062619 e2e: add evidence tests (#9292) 2022-08-22 13:33:47 +02:00
samricotta
aa303edaef Forward port discard abci responses change (#9286)
* Backport of sam/abci-responses (#9090) (#9159)

Signed-off-by: Thane Thomson <connect@thanethomson.com>
Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>
Co-authored-by: Thane Thomson <connect@thanethomson.com>
2022-08-22 12:53:01 +02:00
Callum Waters
2d8df1bd4e proto: deduplicate consensus params (#9287) 2022-08-22 10:50:21 +02:00
Thane Thomson
d886bc8fdd docs: Capture UX-oriented practices for changelog (#9284) 2022-08-20 10:02:39 -04:00
Thane Thomson
daaf5d6441 docs: Update all docs to prepare for v0.37 (#9243)
* Update docs references from master to main

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

* Update DOCS_README to reflect current reality

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

* Update vuepress config with current versions and updated discussions link

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

* Update generated docs versions

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

* Update docs build to use temp folder instead of home

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

* Document build-docs Makefile target

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

* Add serve-docs Makefile target to serve local build of docs

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

* Ensure 404 page is copied during docs build

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

* Redirect /master/ to /main/

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

* Attempt to resolve #7908

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

* Update OpenAPI references from master to main

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

* Update CHANGELOG references from master to main

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

* Update Docker readme references from master to main

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

* Update UPGRADING references from master to main

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

* Update package-specific documentation references from master to main

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

* Update spec references from master to main

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

* Update all code comment references to docs site from master to main

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

* Build v0.34.x as "latest"

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

* Explicitly mark v0.34 docs as latest in version selector

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

* Update all links from docs.tendermint.com/main to docs.tendermint.com/latest

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

* ci: Redeploy docs on pushes to v0.34.x

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

* Temporarily copy spec directory into docs while building

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

* Add nav link to main and clearly mark as unstable

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

* Revert to only publishing docs in nav for v0.34 and v0.33 with no latest

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

* Link to docs.tendermint.com/v0.34 from RFCs

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

* Rather just use main for all docs.tendermint.com references on main branch

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

* Rename GitHub tree links from master to main

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

* Update link for ABCI Rust client

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

* Update github links from master to main

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

* Update badges in root readme

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

* Remove codecov badge since we do not use it any more

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

* Remove Java and Kotlin tutorials

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

* Remove specs from docs build

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

* Migrate spec links to GitHub repo from docs site

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

* Remove references to non-existent PEX reactor spec

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

* Fix linting badge in README

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

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-08-19 13:18:33 -04:00
Thane Thomson
3cc976482d docs: Apply standard Apache 2.0 license (#9293)
Signed-off-by: Thane Thomson <connect@thanethomson.com>

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-08-19 11:36:29 -04:00
Callum Waters
0ca3a89c90 e2e: add abci delays (#9254) 2022-08-19 12:00:58 +02:00
William Banfield
1a4d9397e9 abci++: update PrepareProposal API to accept just a list of bytes (#9283)
This changes the ResponsePrepareProposal type, substituting the []TxRecord for just []bytes. This change is made in the .proto file and in all necessary additional places in the code.
2022-08-18 16:33:19 -04:00
fatcat22
c8302c5fcb consensus: fix round number when handling RoundStepNewRound timeout (#9252) 2022-08-18 10:24:06 +02:00
Sergio Mena
fb9afcc969 Restore e2e nightly workflow on feature/abci++ppp branch (#9280) 2022-08-17 21:05:53 +02:00
Sergio Mena
622b930e3a abci-cli: PrepareProposal and ProcessProposal (#9281)
* [cherrypicked] abci-cli: added `PrepareProposal` command to cli (#8656)

* Prepare prosal cli

* [cherrypicked + fixes] abci-cli: Add `process_proposal` command to abci-cli (#8901)

* Add `process_proposal` command to abci-cli

* Added process proposal to the 'tutorial' examples

* Added entry in CHANGELOG_PENDING.md

* Allow empty blocks in PrepareProposal, ProcessProposal, and FinalizeBlock

* Fix minimum arguments

* Add tests for empty block

* Updated abci-cli doc

Co-authored-by: Sergio Mena <sergio@informal.systems>
Co-authored-by: Jasmina Malicevic <jasmina.dustinac@gmail.com>

* Addressed @williambanfield's comment

Co-authored-by: Jasmina Malicevic <jasmina.dustinac@gmail.com>
Co-authored-by: Hernán Vanzetto <hernan.vanzetto@gmail.com>
2022-08-17 20:47:52 +02:00
William Banfield
1069ffc6aa config: backport the rename of fastsync to blocksync (#9259)
This is largely a cherry pick of #6755 with some additional fixups added where detected. 
This change moves the blockchain package to a package called blocksync. Additionally, it renames the relevant uses of the term `fastsync` to `blocksync`.

closes: #9227 

#### PR checklist

- [ ] Tests written/updated, or no tests needed
- [x] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [x] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed
2022-08-17 15:19:20 +00:00
William Banfield
7bd86ec004 consensus: backport abci and consensus metrics (#9273)
Partial backport of #8480
2022-08-17 09:37:45 -04:00
samricotta
9993514893 abci: Remove SetOption #5447 #9091 (#9266)
* Remove set option for abci
2022-08-16 22:58:04 +02:00
Igor Konnov
3003e05581 Update type annotations in the TLA+ spec of Tendermint for accountability (#9263)
* update Apalache type annotations and split evidence into 3 variables

* remove the duplicate of AllPrevotes, due to merge
2022-08-16 16:12:04 +02:00
AdamKorcz
498657f128 test/fuzz: fix OSS-Fuzz build (#9183) 2022-08-16 15:59:24 +02:00
William Banfield
c322b89b2a RFC-024: block structure consolidation (#8457)
This RFC lays out a proposed set of changes for consolidating the set of information that may be included in the block structure.

{{ [rendered](https://github.com/tendermint/tendermint/blob/wb/rfc-block-structure/docs/rfc/rfc-020-block-structure-consolidation.md) }}
2022-08-16 13:51:55 +00:00
Thane Thomson
cbc7a1abcf spec: Sync Light Client TLA+ code with master (#9238)
* Typo fix in README.md (#350)

* Updated Apalache type annotations (#395)

Co-authored-by: Prajjwol Gautam <prajjwol@gmail.com>
Co-authored-by: Kukovec <jure.kukovec@gmail.com>
2022-08-12 14:33:47 -04:00
Sergio Mena
670abbc330 Merge pull request #9236 from tendermint/sergio/merging-main-abci++ppp
Merge `main` into `feature/abci++ppp`
2022-08-12 15:55:47 +02:00
Sergio Mena
7dc4f934b0 Merge branch main into feature/abci++ppp 2022-08-12 13:59:19 +02:00
Sergio Mena
cb570f6672 ABCI types.proto. Handle remaining discrepancies (#9224)
* [cherrypicked] version: add abci version to handshake (#5706)

- add `AbciVersion` RequestInfo

Closes: #2804

* make proto-gen

* Bump ABCI version: Prepare and Process proposal

Co-authored-by: Marko <marbar3778@yahoo.com>
2022-08-12 11:57:13 +02:00
Marko
f36999e484 retract all of 0.35 (#9198) 2022-08-12 11:47:36 +02:00
Thane Thomson
ae1fc74f80 abci: Make ABCI and P2P wire-level length delimiters consistent (#9182)
* abci: use protoio for length delimitation (#5818)

Migrate ABCI to use protoio (uint64 length delimiters) instead of int64
length delimiters to be consistent with the approach used in the P2P
layer.

Closes: #5783

* Import ReadMsg interface change from #5868

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

* Convert PR number to link in UPGRADING

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

* Update Tendermint Socket Protocol docs to reflect length prefix encoding change

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

* Clarify that length delimiters are varints

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

Signed-off-by: Thane Thomson <connect@thanethomson.com>
Co-authored-by: Marko <marbar3778@yahoo.com>
2022-08-11 13:30:39 -04:00
Sergio Mena
c4eb6113a8 Remove unused code in internal directory (#9223) 2022-08-11 17:33:55 +02:00
Sergio Mena
25b0c7c78e PrepareProposal/ProcessProposal: Dealing with block data exposed to App (#9219)
* [cherrypicked] abci++: only include meaningful header fields in data passed-through to application (#8216)

* make proto-gen

* Fix kvstore tests

* Small changes to abci protobufs taken from v0.36.x

* make proto-gen (again)

* [Partial cherrypick] Restore `Commit` to the ABCI++ spec, and other late modifications (backport #8796) (#8936)

* Restore `Commit` to the ABCI++ spec, and other late modifications (#8796)

* Added VoteExtensionsEnableHeight

* Fix reference to `modified`

* Removed old pseudo-code, now included in spec

* Removed markdown warnings in abci++_basic_concepts_002_draft.md

* Restored `Commit` in the Methods section

* Addressed remaining markdown warnings

* Revisited intro and basic concepts section

* Extra pass at all spec sections to recover Commit, and other ABCI++ spec modifications

* Fixed links

* make proto-gen

* Remove _primes_ from spec notation

* Update proto/tendermint/abci/types.proto

Co-authored-by: Callum Waters <cmwaters19@gmail.com>

* Update spec/abci++/abci++_tmint_expected_behavior_002_draft.md

Co-authored-by: Callum Waters <cmwaters19@gmail.com>

* Addressed @cmwaters' comments

* Addressed @angbrav's and @mpoke's comments on spec

* make proto-gen

* Fix MD anchor reference

* Clarify throughout the spec when `ProcessProposal` and `VerifyVoteExtension` are called

* Update spec/abci++/abci++_app_requirements_002_draft.md

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>

* Update spec/abci++/abci++_app_requirements_002_draft.md

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>

* Update spec/abci++/abci++_app_requirements_002_draft.md

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Update spec/abci++/abci++_basic_concepts_002_draft.md

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Update spec/abci++/abci++_basic_concepts_002_draft.md

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>

* Update spec/abci++/abci++_basic_concepts_002_draft.md

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Update spec/abci++/abci++_methods_002_draft.md

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>

* Update spec/abci++/abci++_tmint_expected_behavior_002_draft.md

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Addresed comments

* Renamed 'draft' files

* Adatped links to new filenames

* Fixed links and minor cosmetic changes

* Renamed 'byzantine_validators' to 'misbehavior' in ABCI++ spec and protobufs

* make proto-gen

* Renamed 'byzantine_validators' to 'misbehavior' in the code

* Fixed link

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Addressed @cason's comments

* Clarified conditions for `ProcessProposal` call at proposer

Co-authored-by: Callum Waters <cmwaters19@gmail.com>
Co-authored-by: M. J. Fromberger <fromberger@interchain.io>
Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>
Co-authored-by: Daniel <daniel.cason@usi.ch>
(cherry picked from commit 331860c2a8)

* Fixed merge conflicts

Co-authored-by: Sergio Mena <sergio@informal.systems>

* make proto-gen (and again)

* make build

* fix UTs

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2022-08-11 11:21:43 +02:00
Jacob Gadikian
a6dde14ec4 do not use ioutil (#9206) 2022-08-10 14:35:14 -04:00
Sam Kleinman
152a2fa5c9 metrics: add metricsgen makefile target (#9172)
Follow on work as a missing piece of #9156, to make it possible to
generate metrics automatically using existing build infrastructure.
2022-08-09 21:00:55 +00:00
dependabot[bot]
f295b4d431 build(deps): Bump github.com/golangci/golangci-lint from 1.42.1 to 1.48.0 (#9203)
Bumps [github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint) from 1.42.1 to 1.48.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/golangci/golangci-lint/releases">github.com/golangci/golangci-lint's releases</a>.</em></p>
<blockquote>
<h2>v1.48.0</h2>
<h2>Changelog</h2>
<ul>
<li>368c41cd build(deps): bump github.com/daixiang0/gci from 0.5.0 to 0.6.0 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3035">#3035</a>)</li>
<li>2d8fea81 build(deps): bump github.com/daixiang0/gci from 0.6.0 to 0.6.2 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3058">#3058</a>)</li>
<li>aeb5860c build(deps): bump github.com/kisielk/errcheck from 1.6.1 to 1.6.2 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3059">#3059</a>)</li>
<li>0559b922 build(deps): bump revgrep to HEAD (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3054">#3054</a>)</li>
<li>6313fa9a contextcheck: disable linter (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3050">#3050</a>)</li>
<li>0ba1388a feat: add usestdlibvars (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3016">#3016</a>)</li>
<li>1557692e feat: go1.19 support  (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3037">#3037</a>)</li>
<li>15cba447 gci: add missing <code>custom-order</code> setting (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3052">#3052</a>)</li>
<li>9a1b9492 ifshort: deprecate linter (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3034">#3034</a>)</li>
<li>f8f8f9a6 nolint: drop allow-leading-space option and add &quot;nolint:all&quot; (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3002">#3002</a>)</li>
</ul>
<h2>v1.47.3</h2>
<h2>Changelog</h2>
<ul>
<li>72fc41ce build(deps): bump github.com/BurntSushi/toml from 1.1.0 to 1.2.0 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3009">#3009</a>)</li>
<li>57d61afb build(deps): bump github.com/GaijinEntertainment/go-exhaustruct/v2 from 2.2.0 to 2.2.2 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3030">#3030</a>)</li>
<li>9cb17e4f build(deps): bump github.com/alingse/asasalint from 0.0.10 to 0.0.11 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3003">#3003</a>)</li>
<li>2ab46788 build(deps): bump github.com/daixiang0/gci from 0.4.3 to 0.5.0 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3031">#3031</a>)</li>
<li>03d9b113 build(deps): bump github.com/ryancurrah/gomodguard from 1.2.3 to 1.2.4 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3029">#3029</a>)</li>
<li>e55f22c7 build(deps): bump github.com/sirupsen/logrus from 1.8.1 to 1.9.0 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3010">#3010</a>)</li>
<li>c7ed8b67 build(deps): bump github.com/sivchari/nosnakecase from 1.5.0 to 1.7.0 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3008">#3008</a>)</li>
<li>95d57d99 build(deps): bump gitlab.com/bosi/decorder from 0.2.2 to 0.2.3 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3033">#3033</a>)</li>
<li>d186efe9 build(deps): bump honnef.co/go/tools from 0.3.2 to 0.3.3 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3032">#3032</a>)</li>
<li>846fab81 cgo: fix linters ignoring Cgo files (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3025">#3025</a>)</li>
<li>d44cd49a feat: remove some go1.18 limitations (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3001">#3001</a>)</li>
<li>886fbd71 gci: fix panic with invalid configuration option (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3019">#3019</a>)</li>
</ul>
<h2>v1.47.2</h2>
<h2>Changelog</h2>
<ul>
<li>61673b34 revive: ignore slow rules (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/2999">#2999</a>)</li>
</ul>
<h2>v1.47.1</h2>
<h2>Changelog</h2>
<ul>
<li>a91463cd build(deps): bump github.com/daixiang0/gci from 0.4.2 to 0.4.3 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/2992">#2992</a>)</li>
<li>4c8bdc70 build(deps): bump github.com/sivchari/tenv from 1.6.0 to 1.7.0 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/2988">#2988</a>)</li>
<li>4e60e8a8 gci: fix options display (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/2989">#2989</a>)</li>
<li>fd87bd1e gci: remove the use of stdin (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/2984">#2984</a>)</li>
</ul>
<h2>v1.47.0</h2>
<h2>Changelog</h2>
<ul>
<li>b4154027 Add linter <code>asasalint</code> to lint pass []any as any (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/2968">#2968</a>)</li>
<li>1d8a15a0 add nosnakecase lint (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/2828">#2828</a>)</li>
<li>2a1edcef build(deps): bump github.com/Antonboom/errname from 0.1.6 to 0.1.7 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/2888">#2888</a>)</li>
<li>c766184c build(deps): bump github.com/GaijinEntertainment/go-exhaustruct/v2 from 2.1.0 to 2.2.0 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/2916">#2916</a>)</li>
<li>b8f1e2a5 build(deps): bump github.com/daixiang0/gci from 0.3.4 to 0.4.0 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/2965">#2965</a>)</li>
<li>5e183652 build(deps): bump github.com/daixiang0/gci from 0.4.0 to 0.4.1 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/2973">#2973</a>)</li>
<li>e60937a1 build(deps): bump github.com/daixiang0/gci from 0.4.1 to 0.4.2 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/2979">#2979</a>)</li>
</ul>

</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/golangci/golangci-lint/blob/master/CHANGELOG.md">github.com/golangci/golangci-lint's changelog</a>.</em></p>
<blockquote>
<h3>v1.48.0</h3>
<ol>
<li>new linters
<ul>
<li><code>usestdlibvars</code>:<a href="https://github.com/sashamelentyev/usestdlibvars">https://github.com/sashamelentyev/usestdlibvars</a></li>
</ul>
</li>
<li>updated linters
<ul>
<li><code>contextcheck</code>: disable linter</li>
<li><code>errcheck</code>: from 1.6.1 to 1.6.2</li>
<li><code>gci</code>: add missing <code>custom-order</code> setting</li>
<li><code>gci</code>: from 0.5.0 to 0.6.0</li>
<li><code>ifshort</code>: deprecate linter</li>
<li><code>nolint</code>: drop allow-leading-space option and add &quot;nolint:all&quot;</li>
<li><code>revgrep</code>: bump to HEAD</li>
</ul>
</li>
<li>documentation
<ul>
<li>remove outdated info on source install</li>
</ul>
</li>
<li>misc
<ul>
<li>go1.19 support</li>
</ul>
</li>
</ol>
<h3>v1.47.3</h3>
<ol>
<li>updated linters:
<ul>
<li>remove some go1.18 limitations</li>
<li><code>asasalint</code>: from 0.0.10 to 0.0.11</li>
<li><code>decorder</code>: from 0.2.2 to v0.2.3</li>
<li><code>gci</code>: fix panic with invalid configuration option</li>
<li><code>gci</code>: from 0.4.3 to v0.5.0</li>
<li><code>go-exhaustruct</code>: from 2.2.0 to 2.2.2</li>
<li><code>gomodguard</code>: from 1.2.3 to 1.2.4</li>
<li><code>nosnakecase</code>: from 1.5.0 to 1.7.0</li>
<li><code>honnef.co/go/tools</code>: from 0.3.2 to v0.3.3</li>
</ul>
</li>
<li>misc
<ul>
<li>cgo: fix linters ignoring CGo files</li>
</ul>
</li>
</ol>
<h3>v1.47.2</h3>
<ol>
<li>updated linters:
<ul>
<li><code>revive</code>: ignore slow rules</li>
</ul>
</li>
</ol>
<h3>v1.47.1</h3>
<ol>
<li>updated linters:
<ul>
<li><code>gci</code>: from 0.4.2 to 0.4.3</li>
<li><code>gci</code>: remove the use of stdin</li>
<li><code>gci</code>: fix options display</li>
<li><code>tenv</code>: from 1.6.0 to 1.7.0</li>
<li><code>unparam</code>: bump to HEAD</li>
</ul>
</li>
</ol>
<h3>v1.47.0</h3>
<ol>
<li>new linters:
<ul>
<li><code>asasalint</code>: <a href="https://github.com/alingse/asasalint">https://github.com/alingse/asasalint</a></li>
</ul>
</li>
</ol>

</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="2d8fea819e"><code>2d8fea8</code></a> build(deps): bump github.com/daixiang0/gci from 0.6.0 to 0.6.2 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3058">#3058</a>)</li>
<li><a href="aeb5860ca8"><code>aeb5860</code></a> build(deps): bump github.com/kisielk/errcheck from 1.6.1 to 1.6.2 (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3059">#3059</a>)</li>
<li><a href="0559b9220b"><code>0559b92</code></a> build(deps): bump revgrep to HEAD (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3054">#3054</a>)</li>
<li><a href="3ffde13a17"><code>3ffde13</code></a> dev: remove stable from actions/setup-go (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3055">#3055</a>)</li>
<li><a href="1557692e59"><code>1557692</code></a> feat: go1.19 support  (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3037">#3037</a>)</li>
<li><a href="6313fa9a67"><code>6313fa9</code></a> contextcheck: disable linter (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3050">#3050</a>)</li>
<li><a href="0ba1388a41"><code>0ba1388</code></a> feat: add usestdlibvars (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3016">#3016</a>)</li>
<li><a href="15cba447fd"><code>15cba44</code></a> gci: add missing <code>custom-order</code> setting (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3052">#3052</a>)</li>
<li><a href="452544a2e7"><code>452544a</code></a> build(deps): bump gatsby from 4.15.2 to 4.19.2 in /docs (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3046">#3046</a>)</li>
<li><a href="f9dfb687aa"><code>f9dfb68</code></a> build(deps): bump gatsby-transformer-yaml from 4.13.0 to 4.19.0 in /docs (<a href="https://github-redirect.dependabot.com/golangci/golangci-lint/issues/3045">#3045</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/golangci/golangci-lint/compare/v1.42.1...v1.48.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/golangci/golangci-lint&package-manager=go_modules&previous-version=1.42.1&new-version=1.48.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-08-09 15:21:16 +00:00
William Banfield
0bea0647fe tools: remove mockery from tools.go (#9196)
The `mockery` project recommends against using a binary of `mockery` that has been created using `go install`. https://github.com/vektra/mockery/pull/456. Developers of Tendermint wishing to generate mocks should avoid having a version of `mockery` on their path that does not match the version listed in  [mockery_generate.sh](10e1ac8fea/scripts/mockery_generate.sh (L11)). To make this easier for developers, the `mockery_generate.sh` script uses a containerized copy of `mockery` if `mockery` is not present on the developer's `PATH`. This containerized version of `mockery` uses the same version of mockery as our CI pipelines and allows all developers to automatically use the same version without having to manage it themselves. 

#### PR checklist

- [ ] Tests written/updated, or no tests needed
- [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [ ] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed
2022-08-09 15:12:31 +00:00
Callum Waters
f861062ee2 abci: implement process proposal to spec (#9122) 2022-08-09 15:15:18 +02:00
Sam Kleinman
d5ec276052 e2e: fix out of sync configuration (#9199)
The v0.34.x tests have been failing (or reporting failures, I don't
believe that this is a real failure,) because the CI configuration has
been out of sync with itself, likely due to a mistake during
backporting configs from the `master` branch.

The entire 0.34.x e2e test suite takes 26 minutes to run, plus about 7
minutes to build the docker image. Each split has to build the same
docker image, (and is therefore a cap on the amount of parallelism we
can get at the moment.) Having more groups, just seems like we'll be
burning money building the docker image with no really meaningful
difference in throughput. For a nightly test that people don't really
wait on, the current latency (time-to-completion) of roughly 19
minutes, isn't causing in friction.
2022-08-09 12:02:14 +00:00
Marko
bff63aec83 remove lastresulthash from merklization in lastresult hash (#9175)
remove gas from merklization in headers


Im not sure where to change docs since main points to the spec repo but that repo is archived. Maybe someone can help me?
2022-08-09 08:16:41 +00:00
William Banfield
69845bb44e metrics: fixup after cherry-pick (#9195)
* fixup after cherry-pick

* cherry-pick fixups
2022-08-08 15:55:01 -04:00
William Banfield
10e1ac8fea metrics: transition all metrics to using metricsgen generated constructors. (port of #8488) (#9178)
This pull request completes the change to the `metricsgen` metrics. It adds `go generate` directives to all of the files containing the `Metrics` structs.

Using the outputs of `metricsdiff` between these generated metrics and `main`, we can see that there is a minimal diff between the two sets of metrics when run locally. The diff here stems from removal of the word 'message' which was done in v0.36+ and is ultimately a better phrasing. This metric has not yet been released, so this phrasing is preferred.

```
./metricsdiff old new
Metric changes:
+++ tendermint_consensus_full_prevote_delay
+++ tendermint_consensus_quorum_prevote_delay
--- tendermint_consensus_full_prevote_message_delay
--- tendermint_consensus_quorum_prevote_message_delay
```

This change also adds parsing for a `metrics:` key in a field comment. If a comment line begins with `//metrics:` the rest of the line is interpreted to be the metric help text. Additionally, a bug where lists of labels were not properly quoted in the `metricsgen` rendered output was fixed.

In my view, docs and tests are not needed for this internal only change.

---
#### PR checklist

- [ ] Tests written/updated, or no tests needed
- [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [ ] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed

Ports #8488 to main
2022-08-08 16:53:00 +00:00
dependabot[bot]
74dd21eb89 build(deps): Bump docker/build-push-action from 3.1.0 to 3.1.1 (#9189)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3.1.0 to 3.1.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/docker/build-push-action/releases">docker/build-push-action's releases</a>.</em></p>
<blockquote>
<h2>v3.1.1</h2>
<ul>
<li>Fix GitHub token not passed with Git context if subdir defined by <a href="https://github.com/crazy-max"><code>@​crazy-max</code></a> (<a href="https://github-redirect.dependabot.com/docker/build-push-action/issues/663">#663</a>)</li>
<li>Replace deprecated <code>fs.rmdir</code> with <code>fs.rm</code> by <a href="https://github.com/bendrucker"><code>@​bendrucker</code></a> (<a href="https://github-redirect.dependabot.com/docker/build-push-action/issues/657">#657</a>)</li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/docker/build-push-action/compare/v3.1.0...v3.1.1">https://github.com/docker/build-push-action/compare/v3.1.0...v3.1.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="c84f382811"><code>c84f382</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/docker/build-push-action/issues/663">#663</a> from crazy-max/fix-git-token-cond</li>
<li><a href="cd5d0b79ea"><code>cd5d0b7</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/docker/build-push-action/issues/661">#661</a> from dud225/subdir_context</li>
<li><a href="30a32246ba"><code>30a3224</code></a> Fix GitHub token not passed with Git context if subdir defined</li>
<li><a href="1f19633b92"><code>1f19633</code></a> Update comment regarding the support of subdir context</li>
<li><a href="67af6dc1d3"><code>67af6dc</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/docker/build-push-action/issues/657">#657</a> from bendrucker/deprecated-fs-rmdir</li>
<li><a href="988cb093f2"><code>988cb09</code></a> replace deprecated <code>fs.rmdir</code> with <code>fs.rm</code></li>
<li>See full diff in <a href="https://github.com/docker/build-push-action/compare/v3.1.0...v3.1.1">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=docker/build-push-action&package-manager=github_actions&previous-version=3.1.0&new-version=3.1.1)](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-08-08 13:35:59 +00:00
dependabot[bot]
ad1f9b49bc build(deps): Bump github.com/prometheus/client_golang (#9190)
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.12.2 to 1.13.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.12.2...v1.13.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  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-08-08 09:34:21 -04:00
Thane Thomson
ef4e37b532 ci: Restore ToC check for ADRs/RFCs (#9180)
* Import presubmit TOC check script from master and fix warning

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

* Fix misspelled ADR link discovered by presubmit script

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

* Restore docs-toc workflow

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

* Create makefile target for docs ToC check

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

* Use makefile target in CI workflow for docs ToC check

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-08-06 13:19:05 -04:00
Thane Thomson
03c79b666d ci: Fix nightly E2E notifications (#9179)
Update the nightly E2E workflows to fix the notifications for the
v0.34.x branch while also simplifying the messages and making them more
readable.

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-08-06 10:17:21 -04:00
Thane Thomson
1148759a94 ci: Update nightly E2E notifications (#9177) 2022-08-05 21:38:14 -04:00
William Banfield
608933b73e consensus: additional timing metrics (port of #7849) (#9168)
This change introduces an additional set of metrics aimed at helping operators understand the timing for consensus.

This change adds the following metrics:

```
tendermint_consensus_round_duration_seconds_bucket{chain_id="test-chain-IrF74Y",le="0.1"} 29
tendermint_consensus_round_duration_seconds_bucket{chain_id="test-chain-IrF74Y",le="0.2682695795279726"} 29
tendermint_consensus_round_duration_seconds_bucket{chain_id="test-chain-IrF74Y",le="0.7196856730011522"} 29
tendermint_consensus_round_duration_seconds_bucket{chain_id="test-chain-IrF74Y",le="1.9306977288832508"} 29
tendermint_consensus_round_duration_seconds_bucket{chain_id="test-chain-IrF74Y",le="5.1794746792312125"} 29
tendermint_consensus_round_duration_seconds_bucket{chain_id="test-chain-IrF74Y",le="13.894954943731381"} 29
tendermint_consensus_round_duration_seconds_bucket{chain_id="test-chain-IrF74Y",le="37.27593720314942"} 29
tendermint_consensus_round_duration_seconds_bucket{chain_id="test-chain-IrF74Y",le="100.00000000000006"} 29
tendermint_consensus_round_duration_seconds_bucket{chain_id="test-chain-IrF74Y",le="+Inf"} 29
tendermint_consensus_round_duration_seconds_sum{chain_id="test-chain-IrF74Y"} 0.028651869999999996
tendermint_consensus_round_duration_seconds_count{chain_id="test-chain-IrF74Y"} 29
```

```
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Commit",le="0.1"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Commit",le="0.2682695795279726"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Commit",le="0.7196856730011522"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Commit",le="1.9306977288832508"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Commit",le="5.1794746792312125"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Commit",le="13.894954943731381"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Commit",le="37.27593720314942"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Commit",le="100.00000000000006"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Commit",le="+Inf"} 29
tendermint_consensus_step_duration_seconds_sum{chain_id="test-chain-IrF74Y",step="Commit"} 0.26650875
tendermint_consensus_step_duration_seconds_count{chain_id="test-chain-IrF74Y",step="Commit"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewHeight",le="0.1"} 0
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewHeight",le="0.2682695795279726"} 0
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewHeight",le="0.7196856730011522"} 0
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewHeight",le="1.9306977288832508"} 28
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewHeight",le="5.1794746792312125"} 28
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewHeight",le="13.894954943731381"} 28
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewHeight",le="37.27593720314942"} 28
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewHeight",le="100.00000000000006"} 28
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewHeight",le="+Inf"} 28
tendermint_consensus_step_duration_seconds_sum{chain_id="test-chain-IrF74Y",step="NewHeight"} 27.773921702
tendermint_consensus_step_duration_seconds_count{chain_id="test-chain-IrF74Y",step="NewHeight"} 28
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewRound",le="0.1"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewRound",le="0.2682695795279726"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewRound",le="0.7196856730011522"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewRound",le="1.9306977288832508"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewRound",le="5.1794746792312125"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewRound",le="13.894954943731381"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewRound",le="37.27593720314942"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewRound",le="100.00000000000006"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="NewRound",le="+Inf"} 29
tendermint_consensus_step_duration_seconds_sum{chain_id="test-chain-IrF74Y",step="NewRound"} 0.168961052
tendermint_consensus_step_duration_seconds_count{chain_id="test-chain-IrF74Y",step="NewRound"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Precommit",le="0.1"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Precommit",le="0.2682695795279726"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Precommit",le="0.7196856730011522"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Precommit",le="1.9306977288832508"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Precommit",le="5.1794746792312125"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Precommit",le="13.894954943731381"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Precommit",le="37.27593720314942"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Precommit",le="100.00000000000006"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Precommit",le="+Inf"} 29
tendermint_consensus_step_duration_seconds_sum{chain_id="test-chain-IrF74Y",step="Precommit"} 0.06414115999999999
tendermint_consensus_step_duration_seconds_count{chain_id="test-chain-IrF74Y",step="Precommit"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Prevote",le="0.1"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Prevote",le="0.2682695795279726"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Prevote",le="0.7196856730011522"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Prevote",le="1.9306977288832508"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Prevote",le="5.1794746792312125"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Prevote",le="13.894954943731381"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Prevote",le="37.27593720314942"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Prevote",le="100.00000000000006"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Prevote",le="+Inf"} 29
tendermint_consensus_step_duration_seconds_sum{chain_id="test-chain-IrF74Y",step="Prevote"} 0.177714525
tendermint_consensus_step_duration_seconds_count{chain_id="test-chain-IrF74Y",step="Prevote"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Propose",le="0.1"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Propose",le="0.2682695795279726"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Propose",le="0.7196856730011522"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Propose",le="1.9306977288832508"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Propose",le="5.1794746792312125"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Propose",le="13.894954943731381"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Propose",le="37.27593720314942"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Propose",le="100.00000000000006"} 29
tendermint_consensus_step_duration_seconds_bucket{chain_id="test-chain-IrF74Y",step="Propose",le="+Inf"} 29
tendermint_consensus_step_duration_seconds_sum{chain_id="test-chain-IrF74Y",step="Propose"} 0.221851927
tendermint_consensus_step_duration_seconds_count{chain_id="test-chain-IrF74Y",step="Propose"} 29
```


```
tendermint_consensus_block_gossip_parts_received{chain_id="test-chain-IrF74Y",matches_current="true"} 29
```


---

#### PR checklist

- [x] Tests written/updated, or no tests needed
- [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed
- [x] Updated relevant documentation (`docs/`) and code comments, or no
      documentation updates needed

Closes: #9166
2022-08-05 21:24:02 +00:00
William Banfield
b92a19b2ce proxy: add initial set of abci metrics (port of #7115) (#9169)
* internal/proxy: add initial set of abci metrics (#7115)

This PR adds an initial set of metrics for use ABCI. The initial metrics enable the calculation of timing histograms and call counts for each of the ABCI methods. The metrics are also labeled as either 'sync' or 'async' to determine if the method call was performed using ABCI's `*Async` methods.

An example of these metrics is included here for reference:
```
tendermint_abci_connection_method_timing_bucket{chain_id="ci",method="commit",type="sync",le="0.0001"} 0
tendermint_abci_connection_method_timing_bucket{chain_id="ci",method="commit",type="sync",le="0.0004"} 5
tendermint_abci_connection_method_timing_bucket{chain_id="ci",method="commit",type="sync",le="0.002"} 12
tendermint_abci_connection_method_timing_bucket{chain_id="ci",method="commit",type="sync",le="0.009"} 13
tendermint_abci_connection_method_timing_bucket{chain_id="ci",method="commit",type="sync",le="0.02"} 13
tendermint_abci_connection_method_timing_bucket{chain_id="ci",method="commit",type="sync",le="0.1"} 13
tendermint_abci_connection_method_timing_bucket{chain_id="ci",method="commit",type="sync",le="0.65"} 13
tendermint_abci_connection_method_timing_bucket{chain_id="ci",method="commit",type="sync",le="2"} 13
tendermint_abci_connection_method_timing_bucket{chain_id="ci",method="commit",type="sync",le="6"} 13
tendermint_abci_connection_method_timing_bucket{chain_id="ci",method="commit",type="sync",le="25"} 13
tendermint_abci_connection_method_timing_bucket{chain_id="ci",method="commit",type="sync",le="+Inf"} 13
tendermint_abci_connection_method_timing_sum{chain_id="ci",method="commit",type="sync"} 0.007802058000000001
tendermint_abci_connection_method_timing_count{chain_id="ci",method="commit",type="sync"} 13
```

These metrics can easily be graphed using prometheus's `histogram_quantile(...)` method to pick out a particular quantile to graph or examine. I chose buckets that were somewhat of an estimate of expected range of times for ABCI operations. They start at .0001 seconds and range to 25 seconds. The hope is that this range captures enough possible times to be useful for us and operators.

* fixup

* fixups

* docs: add abci timing metrics to the metrics docs (#7311)

* format table
2022-08-05 13:29:00 -04:00
William Banfield
6b499aeb31 DOCKER: use go 1.18 (#9170) 2022-08-04 17:57:53 -04:00
Sergio Mena
b2409b3345 Follow-up fixes to main PrepareProposal implementation (#9162)
* -----start------

* [cherrypicked] state: panic on ResponsePrepareProposal validation error (#8145)

* state: panic on ResponsePrepareProposal validation error

* lint++

Co-authored-by: Sam Kleinman <garen@tychoish.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>

* [cherrypicked] abci++: remove CheckTx call from PrepareProposal flow (#8176)

* [cherrypicked] abci++: correct max-size check to only operate on added and unmodified (#8242)

* [cherrypicked] Remove `ModifiedTxStatus` from the spec and the code (#8210)

* Outstanding abci-gen changes to 'pb.go' files

* Removed modified_tx_status from spec and protobufs

* Fix sed for OSX

* Regenerated abci protobufs with 'abci-proto-gen'

* Code changes. UTs e2e tests passing

* Recovered UT: TestPrepareProposalModifiedTxStatusFalse

* Adapted UT

* Fixed UT

* Revert "Fix sed for OSX"

This reverts commit e576708c61.

* Update internal/state/execution_test.go

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Update abci/example/kvstore/kvstore.go

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>

* Update internal/state/execution_test.go

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Update spec/abci++/abci++_tmint_expected_behavior_002_draft.md

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Addressed some comments

* Added one test that tests error at the ABCI client + Fixed some mock calls

* Addressed remaining comments

* Update abci/example/kvstore/kvstore.go

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Update abci/example/kvstore/kvstore.go

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Update abci/example/kvstore/kvstore.go

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Update spec/abci++/abci++_tmint_expected_behavior_002_draft.md

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Addressed William's latest comments

* Adressed Michael's comment

* Fixed UT

* Some md fixes

* More md fixes

* gofmt

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>
Co-authored-by: M. J. Fromberger <fromberger@interchain.io>

* make proto-gen

* Fixed testcase on PrepareProposal error

* mockery

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>
Co-authored-by: Sam Kleinman <garen@tychoish.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: M. J. Fromberger <fromberger@interchain.io>
2022-08-03 19:39:17 +02:00
Sergio Mena
d268e56383 Sync PrepareProposal with Spec. Main part (#9158)
* ----start----

* [PARTIAL cherry-pick] ABCI Vote Extension 2 (#6885)

* Cherry-picked #6567: state/types: refactor makeBlock, makeBlocks and makeTxs (#6567)

* [Cherrypicked] types: remove panic from block methods (#7501)

* [cherrypicked] abci++: synchronize PrepareProposal with the newest version of the spec (#8094)

This change implements the logic for the PrepareProposal ABCI++ method call. The main logic for creating and issuing the PrepareProposal request lives in execution.go and is tested in a set of new tests in execution_test.go. This change also updates the mempool mock to use a mockery generated version and removes much of the plumbing for the no longer used ABCIResponses.

* make proto-gen

* Backported EvidenceList's method ToABCI from #7961

* make build

* Fix mockery for Mempool

* mockery

* Backported abci Application mocks from #7961

* mockery2

* Fixed new PrepareProposal test cases in state/execution_test.go

* Fixed returned errors in consensus/state.go

* lint

* Addressed @cmwaters' comment

Co-authored-by: mconcat <monoidconcat@gmail.com>
Co-authored-by: JayT106 <JayT106@users.noreply.github.com>
Co-authored-by: Sam Kleinman <garen@tychoish.com>
Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>
2022-08-03 17:24:24 +02:00
Sergio Mena
2164883501 Old PrepareProposal and vote extension integration on feature/abci++ppp (#9117)
* abci: PrepareProposal-VoteExtension integration [2nd try] (#7821)

* PrepareProposal-VoteExtension integration (#6915)

* make proto-gen

* Fix protobuf crash in e2e nightly tests

* Update types/vote.go

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>

* Addressed @creachadair's comments

Co-authored-by: mconcat <monoidconcat@gmail.com>
Co-authored-by: M. J. Fromberger <fromberger@interchain.io>

* Proto changes

* make proto-gen

* Fixed UTs

* bump

* lint

* lint2

* lint3

* lint4

* lint5

* lint6

* no_lint

Co-authored-by: mconcat <monoidconcat@gmail.com>
Co-authored-by: M. J. Fromberger <fromberger@interchain.io>
2022-08-03 13:29:15 +02:00
Sergio Mena
61619ab072 Update feature/abci++ppp branch with latest infra changes in main (#9157)
* Update CODEOWNERS to use teams (#9129)

* Update CODEOWNERS to use teams

Update the `CODEOWNERS` file to use the
@tendermint/tendermint-engineering and @tendermint/tendermint-research
teams as opposed to adding people one by one. This makes repository
administration somewhat easier to manage, especially when
onboarding/offboarding people.

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

* Add Ethan as superuser

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

* Prepare `main` to become new default branch (#9095)

* Update Makefile with changes from #7372

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

* Sync main GitHub config with master and update

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

* Remove unnecesary dot folders

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

* Sync dotfiles

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

* Remove unused Jepsen tests for now

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

* tools: remove k8s (#6625)

Remove mintnet as discussed on team call.

closes #1941

* Restore nightly fuzz testing of P2P addrbook and pex

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

* Fix YAML lints

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

* Fix YAML formatting nits

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

* More YAML nits

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

* github: fix linter configuration errors and occluded errors (#6400)

* Minor fixes to OpenAPI spec to sync with structs on main

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

* Remove .github/auto-comment.yml - does not appear to be used

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

* Add issue config with link to discussions

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

* Adjust issue/PR templates to suit current process

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

* Remove unused RC branch config from release workflow

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

* Fix wildcard matching in build jobs config

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

* Document markdownlint config

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

* Restore manual E2E test group config

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

* Document linter workflow with local execution instructions

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

* Document and fix minor nit in Super-Linter markdownlint config

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

* Update .github/ISSUE_TEMPLATE/bug-report.md

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Update pull request template to add language around discussions/issues

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

* .golangci.yml: Deleted commented-out lines

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

* ci: Drop "-2" from e2e-nightly-fail workflow

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

* Address triviality concern in PR template

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

Co-authored-by: Marko <marbar3778@yahoo.com>
Co-authored-by: Sam Kleinman <garen@tychoish.com>
Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

Co-authored-by: Thane Thomson <connect@thanethomson.com>
Co-authored-by: Marko <marbar3778@yahoo.com>
Co-authored-by: Sam Kleinman <garen@tychoish.com>
Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>
2022-08-03 11:06:54 +02:00
Sergio Mena
58effdd8b3 Old PrepareProposal on feature/abci++ppp (#9106)
* [Rebased to v0.34.x] abci: PrepareProposal (#6544)

* fixed cherry-pick

* proto changes

* make proto-gen

* UT fixes

* generate Client directive

* mockery

* App fixes

* Disable 'modified tx' hack

* mockery

* Make format

* Fix lint

Co-authored-by: Marko <marbar3778@yahoo.com>
2022-07-27 15:09:02 +02:00
581 changed files with 25461 additions and 14101 deletions

View File

@@ -10,6 +10,16 @@ updates:
- T:dependencies
- S:automerge
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
target-branch: "v0.37.x"
open-pull-requests-limit: 10
labels:
- T:dependencies
- S:automerge
- package-ecosystem: github-actions
directory: "/"
schedule:
@@ -40,6 +50,18 @@ updates:
- T:dependencies
- S:automerge
- package-ecosystem: gomod
directory: "/"
schedule:
interval: weekly
target-branch: "v0.37.x"
# Only allow automated security-related dependency updates until we cut the
# final v0.37.0 release.
open-pull-requests-limit: 0
labels:
- T:dependencies
- S:automerge
- package-ecosystem: gomod
directory: "/"
schedule:

8
.github/mergify.yml vendored
View File

@@ -17,6 +17,14 @@ pull_request_rules:
{{ title }} (#{{ number }})
{{ body }}
- name: backport patches to v0.37.x branch
conditions:
- base=main
- label=S:backport-to-v0.37.x
actions:
backport:
branches:
- v0.37.x
- name: backport patches to v0.34.x branch
conditions:
- base=main

View File

@@ -18,7 +18,7 @@ jobs:
steps:
- uses: actions/setup-go@v3
with:
go-version: '1.18'
go-version: "1.18"
- uses: actions/checkout@v3
@@ -26,8 +26,6 @@ jobs:
run: |
set -euo pipefail
readonly MOCKERY=2.12.3 # N.B. no leading "v"
curl -sL "https://github.com/vektra/mockery/releases/download/v${MOCKERY}/mockery_${MOCKERY}_Linux_x86_64.tar.gz" | tar -C /usr/local/bin -xzf -
make mockery 2>/dev/null
if ! git diff --stat --exit-code ; then
@@ -44,11 +42,11 @@ jobs:
steps:
- uses: actions/setup-go@v3
with:
go-version: '1.18'
go-version: "1.18"
- uses: actions/checkout@v3
with:
fetch-depth: 1 # we need a .git directory to run git diff
fetch-depth: 1 # we need a .git directory to run git diff
- name: "Check protobuf generated code"
run: |
@@ -61,7 +59,7 @@ jobs:
export GOBIN="${tools}/bin"
go install github.com/bufbuild/buf/cmd/buf
go install github.com/gogo/protobuf/protoc-gen-gogofaster@latest
go install github.com/cosmos/gogoproto/protoc-gen-gogofaster@latest
make proto-gen

View File

@@ -6,8 +6,10 @@ on:
branches:
- main
tags:
- "v[0-9]+.[0-9]+.[0-9]+" # Push events to matching v*, i.e. v1.0, v20.15.10
- "v[0-9]+.[0-9]+.[0-9]+-rc*" # Push events to matching v*, i.e. v1.0-rc1, v20.15.10-rc5
- "v[0-9]+.[0-9]+.[0-9]+" # Push events to matching v*, i.e. v1.0, v20.15.10
- "v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+" # e.g. v0.37.0-alpha.1, v0.38.0-alpha.10
- "v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+" # e.g. v0.37.0-beta.1, v0.38.0-beta.10
- "v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+" # e.g. v0.37.0-rc1, v0.38.0-rc10
jobs:
build:
@@ -49,7 +51,7 @@ jobs:
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Publish to Docker Hub
uses: docker/build-push-action@v3.1.0
uses: docker/build-push-action@v3.1.1
with:
context: .
file: ./DOCKER/Dockerfile

View File

@@ -8,6 +8,7 @@ on:
push:
branches:
- main
- v0.34.x
paths:
- docs/**
- spec/**
@@ -40,7 +41,7 @@ jobs:
- uses: actions/upload-artifact@v3
with:
name: build-output
path: ~/output/
path: /tmp/tendermint-core-docs
deploy:
name: Deploy to GitHub Pages

View File

@@ -1,21 +1,20 @@
# TODO(thane): Re-enable once we've pulled in the ADRs and RFCs from master.
# Verify that important design docs have ToC entries.
#name: Check documentation ToC
#on:
# pull_request:
# push:
# branches:
# - main
#
#jobs:
# check:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v3
# - uses: technote-space/get-diff-action@v6
# with:
# PATTERNS: |
# docs/architecture/**
# docs/rfc/**
# - run: ./docs/presubmit.sh
# if: env.GIT_DIFF
name: Check documentation ToC
on:
pull_request:
push:
branches:
- main
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: technote-space/get-diff-action@v6
with:
PATTERNS: |
docs/architecture/**
docs/rfc/**
- run: make check-docs-toc
if: env.GIT_DIFF

View File

@@ -15,7 +15,7 @@ jobs:
strategy:
fail-fast: false
matrix:
group: ['00', '01', '02', '03', "04"]
group: ['00', '01']
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
@@ -27,6 +27,12 @@ jobs:
with:
ref: 'v0.34.x'
- name: Capture git repo info
id: git-info
run: |
echo "::set-output name=branch::`git branch --show-current`"
echo "::set-output name=commit::`git rev-parse HEAD`"
- name: Build
working-directory: test/e2e
# Run make jobs in parallel, since we can't run steps in parallel.
@@ -41,18 +47,33 @@ jobs:
working-directory: test/e2e
run: ./run-multiple.sh networks/nightly/*-group${{ matrix.group }}-*.toml
outputs:
git-branch: ${{ steps.git-info.outputs.branch }}
git-commit: ${{ steps.git-info.outputs.commit }}
e2e-nightly-fail:
needs: e2e-nightly-test
if: ${{ failure() }}
runs-on: ubuntu-latest
steps:
- name: Notify Slack on failure
uses: rtCamp/action-slack-notify@12e36fc18b0689399306c2e0b3e0f2978b7f1ee7
uses: slackapi/slack-github-action@v1.22.0
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_CHANNEL: tendermint-internal
SLACK_USERNAME: Nightly E2E Tests
SLACK_ICON_EMOJI: ':skull:'
SLACK_COLOR: danger
SLACK_MESSAGE: Nightly E2E tests failed on v0.34.x
SLACK_FOOTER: ''
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
BRANCH: ${{ needs.e2e-nightly-test.outputs.git-branch }}
RUN_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
COMMIT_URL: "${{ github.server_url }}/${{ github.repository }}/commit/${{ needs.e2e-nightly-test.outputs.git-commit }}"
with:
payload: |
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":skull: Nightly E2E tests for `${{ env.BRANCH }}` failed. See the <${{ env.RUN_URL }}|run details> and the <${{ env.COMMIT_URL }}|commit> that caused the failure."
}
}
]
}

79
.github/workflows/e2e-nightly-37x.yml vendored Normal file
View File

@@ -0,0 +1,79 @@
# Runs randomly generated E2E testnets nightly on the v0.37.x branch.
# !! This file should be kept in sync with the e2e-nightly-main.yml file,
# modulo changes to the version labels.
name: e2e-nightly-37x
on:
schedule:
- cron: '0 2 * * *'
jobs:
e2e-nightly-test:
# Run parallel jobs for the listed testnet groups (must match the
# ./build/generator -g flag)
strategy:
fail-fast: false
matrix:
group: ['00', '01', '02', '03', "04"]
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/setup-go@v3
with:
go-version: '1.18'
- uses: actions/checkout@v3
with:
ref: 'v0.37.x'
- name: Capture git repo info
id: git-info
run: |
echo "::set-output name=branch::`git branch --show-current`"
echo "::set-output name=commit::`git rev-parse HEAD`"
- name: Build
working-directory: test/e2e
# Run make jobs in parallel, since we can't run steps in parallel.
run: make -j2 docker generator runner tests
- name: Generate testnets
working-directory: test/e2e
# When changing -g, also change the matrix groups above
run: ./build/generator -g 5 -d networks/nightly/
- name: Run ${{ matrix.p2p }} p2p testnets
working-directory: test/e2e
run: ./run-multiple.sh networks/nightly/*-group${{ matrix.group }}-*.toml
outputs:
git-branch: ${{ steps.git-info.outputs.branch }}
git-commit: ${{ steps.git-info.outputs.commit }}
e2e-nightly-fail:
needs: e2e-nightly-test
if: ${{ failure() }}
runs-on: ubuntu-latest
steps:
- name: Notify Slack on failure
uses: slackapi/slack-github-action@v1.22.0
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
BRANCH: ${{ needs.e2e-nightly-test.outputs.git-branch }}
RUN_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
COMMIT_URL: "${{ github.server_url }}/${{ github.repository }}/commit/${{ needs.e2e-nightly-test.outputs.git-commit }}"
with:
payload: |
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":skull: Nightly E2E tests for `${{ env.BRANCH }}` failed. See the <${{ env.RUN_URL }}|run details> and the <${{ env.COMMIT_URL }}|commit> that caused the failure."
}
}
]
}

View File

@@ -46,28 +46,23 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Notify Slack on failure
uses: rtCamp/action-slack-notify@12e36fc18b0689399306c2e0b3e0f2978b7f1ee7
uses: slackapi/slack-github-action@v1.22.0
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_CHANNEL: tendermint-internal
SLACK_USERNAME: Nightly E2E Tests
SLACK_ICON_EMOJI: ':skull:'
SLACK_COLOR: danger
SLACK_MESSAGE: Nightly E2E tests failed on main
SLACK_FOOTER: ''
e2e-nightly-success: # may turn this off once they seem to pass consistently
needs: e2e-nightly-test
if: ${{ success() }}
runs-on: ubuntu-latest
steps:
- name: Notify Slack on success
uses: rtCamp/action-slack-notify@12e36fc18b0689399306c2e0b3e0f2978b7f1ee7
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_CHANNEL: tendermint-internal
SLACK_USERNAME: Nightly E2E Tests
SLACK_ICON_EMOJI: ':white_check_mark:'
SLACK_COLOR: good
SLACK_MESSAGE: Nightly E2E tests passed on main
SLACK_FOOTER: ''
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
BRANCH: ${{ github.ref_name }}
RUN_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
COMMIT_URL: "${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}"
with:
payload: |
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":skull: Nightly E2E tests for `${{ env.BRANCH }}` failed. See the <${{ env.RUN_URL }}|run details> and the <${{ env.COMMIT_URL }}|commit> that caused the failure."
}
}
]
}

View File

@@ -75,13 +75,24 @@ jobs:
if: ${{ needs.fuzz-nightly-test.outputs.crashers-count != 0 }}
runs-on: ubuntu-latest
steps:
- name: Notify Slack if any crashers
uses: rtCamp/action-slack-notify@12e36fc18b0689399306c2e0b3e0f2978b7f1ee7
- name: Notify Slack on failure
uses: slackapi/slack-github-action@v1.22.0
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_CHANNEL: tendermint-internal
SLACK_USERNAME: Nightly Fuzz Tests
SLACK_ICON_EMOJI: ':firecracker:'
SLACK_COLOR: danger
SLACK_MESSAGE: Crashers found in Nightly Fuzz tests
SLACK_FOOTER: ''
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
BRANCH: ${{ github.ref_name }}
CRASHERS: ${{ needs.fuzz-nightly-test.outputs.crashers-count }}
RUN_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
with:
payload: |
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":skull: Nightly fuzz tests for `${{ env.BRANCH }}` failed with ${{ env.CRASHERS }} crasher(s). See the <${{ env.RUN_URL }}|run details>."
}
}
]
}

41
.github/workflows/gosec.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Run Gosec
on:
pull_request:
paths:
- '**/*.go'
- 'go.mod'
- 'go.sum'
push:
branches:
- main
- 'feature/*'
- 'v0.37.x'
- 'v0.34.x'
paths:
- '**/*.go'
- 'go.mod'
- 'go.sum'
jobs:
Gosec:
permissions:
security-events: write
runs-on: ubuntu-latest
env:
GO111MODULE: on
steps:
- name: Checkout Source
uses: actions/checkout@v3
- name: Run Gosec Security Scanner
uses: cosmos/gosec@master
with:
# Let the report trigger a failure with the Github Security scanner features.
args: "-no-fail -fmt sarif -out results.sarif ./..."
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v2
with:
# Path to SARIF file relative to the root of the repository
sarif_file: results.sarif

View File

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

40
.github/workflows/pre-release.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: "Pre-release"
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+" # e.g. v0.37.0-alpha.1, v0.38.0-alpha.10
- "v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+" # e.g. v0.37.0-beta.1, v0.38.0-beta.10
- "v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+" # e.g. v0.37.0-rc1, v0.38.0-rc10
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-go@v3
with:
go-version: '1.18'
- name: Build
uses: goreleaser/goreleaser-action@v3
if: ${{ github.event_name == 'pull_request' }}
with:
version: latest
args: build --skip-validate # skip validate skips initial sanity checks in order to be able to fully run
# Link to CHANGELOG_PENDING.md as release notes.
- run: echo https://github.com/tendermint/tendermint/blob/${GITHUB_REF#refs/tags/}/CHANGELOG_PENDING.md > ../release_notes.md
- name: Release
uses: goreleaser/goreleaser-action@v3
if: startsWith(github.ref, 'refs/tags/')
with:
version: latest
args: release --rm-dist --release-notes=../release_notes.md
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

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

View File

@@ -7,7 +7,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v5
- uses: actions/stale@v6
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-pr-message: "This pull request has been automatically marked as stale because it has not had

2
.gitignore vendored
View File

@@ -38,6 +38,7 @@ terraform.tfstate
terraform.tfstate.backup
terraform.tfstate.d
test/app/grpc_client
test/loadtime/build
test/e2e/build
test/e2e/networks/*/
test/logs
@@ -51,7 +52,6 @@ proto/spec/**/*.pb.go
*.aux
*.bbl
*.blg
*.log
*.pdf
*.gz
*.dvi

View File

@@ -25,7 +25,8 @@ checksum:
algorithm: sha256
release:
name_template: "{{.Version}} (WARNING: BETA SOFTWARE)"
prerelease: auto
name_template: "{{.Version}}"
archives:
- files:

View File

@@ -2,6 +2,38 @@
Friendly reminder, we have a [bug bounty program](https://hackerone.com/cosmos).
## v0.34.21
Release highlights include:
- A new `[storage]` configuration section and flag `discard_abci_responses`,
which, if enabled, discards all ABCI responses except the latest one in order
to reduce disk space usage in the state store. When enabled, the
`block_results` RPC endpoint can no longer function and will return an error.
- A new CLI command, `reindex-event`, to re-index block and tx events to the
event sinks. You can run this command when the event store backend
dropped/disconnected or you want to replace the backend. When
`discard_abci_responses` is enabled, you will not be able to use this command.
Special thanks to external contributors on this release: @rootwarp & @animart
### FEATURES
- [cli] [\#9083](https://github.com/tendermint/tendermint/issues/9083) Backport command to reindex missed events (@cmwaters)
- [cli] [\#9107](https://github.com/tendermint/tendermint/issues/9107) Add the `p2p.external-address` argument to set the node P2P external address (@amimart)
### IMPROVEMENTS
- [config] [\#9054](https://github.com/tendermint/tendermint/issues/9054) `discard_abci_responses` flag added to discard all ABCI
responses except the last in order to save on storage space in the state
store (@samricotta)
### BUG FIXES
- [mempool] [\#9033](https://github.com/tendermint/tendermint/issues/9033) Rework lock discipline to mitigate callback deadlocks in the
priority mempool
- [cli] [\#9103](https://github.com/tendermint/tendermint/issues/9103) fix unsafe-reset-all for working with home path (@rootwarp)
## v0.34.20
Special thanks to external contributors on this release: @joeabbey @yihuang
@@ -438,7 +470,7 @@ Special thanks to external contributors on this release: @james-ray, @fedekunze,
- [abci] [\#5174](https://github.com/tendermint/tendermint/pull/5174) Remove `MockEvidence` in favor of testing with actual evidence types (`DuplicateVoteEvidence` & `LightClientAttackEvidence`) (@cmwaters)
- [abci] [\#5191](https://github.com/tendermint/tendermint/pull/5191) Add `InitChain.InitialHeight` field giving the initial block height (@erikgrinaker)
- [abci] [\#5227](https://github.com/tendermint/tendermint/pull/5227) Add `ResponseInitChain.app_hash` which is recorded in genesis block (@erikgrinaker)
- [config] [\#5147](https://github.com/tendermint/tendermint/pull/5147) Add `--consensus.double_sign_check_height` flag and `DoubleSignCheckHeight` config variable. See [ADR-51](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-051-double-signing-risk-reduction.md) (@dongsam)
- [config] [\#5147](https://github.com/tendermint/tendermint/pull/5147) Add `--consensus.double_sign_check_height` flag and `DoubleSignCheckHeight` config variable. See [ADR-51](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-051-double-signing-risk-reduction.md) (@dongsam)
- [db] [\#5233](https://github.com/tendermint/tendermint/pull/5233) Add support for `badgerdb` database backend (@erikgrinaker)
- [evidence] [\#4532](https://github.com/tendermint/tendermint/pull/4532) Handle evidence from light clients (@melekes)
- [evidence] [#4821](https://github.com/tendermint/tendermint/pull/4821) Amnesia (light client attack) evidence can be detected, verified and committed (@cmwaters)
@@ -452,7 +484,7 @@ Special thanks to external contributors on this release: @james-ray, @fedekunze,
- [rpc] [\#5017](https://github.com/tendermint/tendermint/pull/5017) Add `/check_tx` endpoint to check transactions without executing them or adding them to the mempool (@melekes)
- [rpc] [\#5108](https://github.com/tendermint/tendermint/pull/5108) Subscribe using the websocket for new evidence events (@cmwaters)
- [statesync] Add state sync support, where a new node can be rapidly bootstrapped by fetching state snapshots from peers instead of replaying blocks. See the `[statesync]` config section.
- [evidence] [\#5361](https://github.com/tendermint/tendermint/pull/5361) Add LightClientAttackEvidence and refactor evidence lifecycle - for more information see [ADR-059](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-059-evidence-composition-and-lifecycle.md) (@cmwaters)
- [evidence] [\#5361](https://github.com/tendermint/tendermint/pull/5361) Add LightClientAttackEvidence and refactor evidence lifecycle - for more information see [ADR-059](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-059-evidence-composition-and-lifecycle.md) (@cmwaters)
### IMPROVEMENTS
@@ -532,7 +564,7 @@ This security release fixes:
Tendermint 0.33.0 and above allow block proposers to include signatures for the
wrong block. This may happen naturally if you start a network, have it run for
some time and restart it **without changing the chainID**. (It is a
[misconfiguration](https://docs.tendermint.com/master/tendermint-core/using-tendermint.html)
[misconfiguration](https://docs.tendermint.com/v0.33/tendermint-core/using-tendermint.html)
to reuse chainIDs.) Correct block proposers will accidentally include signatures
for the wrong block if they see these signatures, and then commits won't validate,
making all proposed blocks invalid. A malicious validator (even with a minimal
@@ -831,7 +863,7 @@ and a validator address plus a timestamp. Note we may remove the validator
address & timestamp fields in the future (see ADR-25).
`lite2` package has been added to solve `lite` issues and introduce weak
subjectivity interface. Refer to the [spec](https://github.com/tendermint/spec/blob/master/spec/consensus/light-client.md) for complete details.
subjectivity interface. Refer to the [spec](https://github.com/tendermint/tendermint/tree/main/spec/consensus/light-client) for complete details.
`lite` package is now deprecated and will be removed in v0.34 release.
### BREAKING CHANGES:
@@ -1191,8 +1223,8 @@ Special thanks to external contributors on this release: @jon-certik, @gracenoah
*August 28, 2019*
@climber73 wrote the [Writing a Tendermint Core application in Java
(gRPC)](https://github.com/tendermint/tendermint/blob/master/docs/guides/java.md)
@climber73 wrote the [Writing a Tendermint Core application in Java
(gRPC)](https://docs.tendermint.com/v0.34/tutorials/java.html)
guide.
Special thanks to external contributors on this release:
@@ -1225,7 +1257,7 @@ Special thanks to external contributors on this release:
### FEATURES:
- [blockchain] [\#3561](https://github.com/tendermint/tendermint/issues/3561) Add early version of the new blockchain reactor, which is supposed to be more modular and testable compared to the old version. To try it, you'll have to change `version` in the config file, [here](https://github.com/tendermint/tendermint/blob/master/config/toml.go#L303) NOTE: It's not ready for a production yet. For further information, see [ADR-40](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-040-blockchain-reactor-refactor.md) & [ADR-43](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-043-blockchain-riri-org.md)
- [blockchain] [\#3561](https://github.com/tendermint/tendermint/issues/3561) Add early version of the new blockchain reactor, which is supposed to be more modular and testable compared to the old version. To try it, you'll have to change `version` in the config file, [here](https://github.com/tendermint/tendermint/blob/main/config/toml.go#L303) NOTE: It's not ready for a production yet. For further information, see [ADR-40](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-040-blockchain-reactor-refactor.md) & [ADR-43](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-043-blockchain-riri-org.md)
- [mempool] [\#3826](https://github.com/tendermint/tendermint/issues/3826) Make `max_msg_bytes` configurable(@bluele)
- [node] [\#3846](https://github.com/tendermint/tendermint/pull/3846) Allow replacing existing p2p.Reactor(s) using [`CustomReactors`
option](https://godoc.org/github.com/tendermint/tendermint/node#CustomReactors).
@@ -1542,7 +1574,7 @@ Special thanks to external contributors on this release:
- [libs/db] [\#3611](https://github.com/tendermint/tendermint/issues/3611) Conditional compilation
* Use `cleveldb` tag instead of `gcc` to compile Tendermint with CLevelDB or
use `make build_c` / `make install_c` (full instructions can be found at
https://docs.tendermint.com/master/introduction/install.html#compile-with-cleveldb-support)
<https://docs.tendermint.com>)
* Use `boltdb` tag to compile Tendermint with bolt db
- [node] [\#3362](https://github.com/tendermint/tendermint/issues/3362) Return an error if `persistent_peers` list is invalid (except
when IP lookup fails)
@@ -1766,7 +1798,7 @@ more details.
- [rpc] [\#3269](https://github.com/tendermint/tendermint/issues/2826) Limit number of unique clientIDs with open subscriptions. Configurable via `rpc.max_subscription_clients`
- [rpc] [\#3269](https://github.com/tendermint/tendermint/issues/2826) Limit number of unique queries a given client can subscribe to at once. Configurable via `rpc.max_subscriptions_per_client`.
- [rpc] [\#3435](https://github.com/tendermint/tendermint/issues/3435) Default ReadTimeout and WriteTimeout changed to 10s. WriteTimeout can increased by setting `rpc.timeout_broadcast_tx_commit` in the config.
- [rpc/client] [\#3269](https://github.com/tendermint/tendermint/issues/3269) Update `EventsClient` interface to reflect new pubsub/eventBus API [ADR-33](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-033-pubsub.md). This includes `Subscribe`, `Unsubscribe`, and `UnsubscribeAll` methods.
- [rpc/client] [\#3269](https://github.com/tendermint/tendermint/issues/3269) Update `EventsClient` interface to reflect new pubsub/eventBus API [ADR-33](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-033-pubsub.md). This includes `Subscribe`, `Unsubscribe`, and `UnsubscribeAll` methods.
* Apps
- [abci] [\#3403](https://github.com/tendermint/tendermint/issues/3403) Remove `time_iota_ms` from BlockParams. This is a
@@ -1819,7 +1851,7 @@ more details.
- [blockchain] [\#3358](https://github.com/tendermint/tendermint/pull/3358) Fix timer leak in `BlockPool` (@guagualvcha)
- [cmd] [\#3408](https://github.com/tendermint/tendermint/issues/3408) Fix `testnet` command's panic when creating non-validator configs (using `--n` flag) (@srmo)
- [libs/db/remotedb/grpcdb] [\#3402](https://github.com/tendermint/tendermint/issues/3402) Close Iterator/ReverseIterator after use
- [libs/pubsub] [\#951](https://github.com/tendermint/tendermint/issues/951), [\#1880](https://github.com/tendermint/tendermint/issues/1880) Use non-blocking send when dispatching messages [ADR-33](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-033-pubsub.md)
- [libs/pubsub] [\#951](https://github.com/tendermint/tendermint/issues/951), [\#1880](https://github.com/tendermint/tendermint/issues/1880) Use non-blocking send when dispatching messages [ADR-33](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-033-pubsub.md)
- [lite] [\#3364](https://github.com/tendermint/tendermint/issues/3364) Fix `/validators` and `/abci_query` proxy endpoints
(@guagualvcha)
- [p2p/conn] [\#3347](https://github.com/tendermint/tendermint/issues/3347) Reject all-zero shared secrets in the Diffie-Hellman step of secret-connection
@@ -2517,7 +2549,7 @@ Special thanks to external contributors on this release:
This release is mostly about the ConsensusParams - removing fields and enforcing MaxGas.
It also addresses some issues found via security audit, removes various unused
functions from `libs/common`, and implements
[ADR-012](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-012-peer-transport.md).
[ADR-012](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-012-peer-transport.md).
BREAKING CHANGES:
@@ -2582,7 +2614,7 @@ are affected by a change.
A few more breaking changes are in the works - each will come with a clear
Architecture Decision Record (ADR) explaining the change. You can review ADRs
[here](https://github.com/tendermint/tendermint/tree/develop/docs/architecture)
[here](https://github.com/tendermint/tendermint/tree/main/docs/architecture)
or in the [open Pull Requests](https://github.com/tendermint/tendermint/pulls).
You can also check in on the [issues marked as
breaking](https://github.com/tendermint/tendermint/issues?q=is%3Aopen+is%3Aissue+label%3Abreaking).
@@ -2598,7 +2630,7 @@ BREAKING CHANGES:
- [abci] Added address of the original proposer of the block to Header
- [abci] Change ABCI Header to match Tendermint exactly
- [abci] [\#2159](https://github.com/tendermint/tendermint/issues/2159) Update use of `Validator` (see
[ADR-018](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-018-ABCI-Validators.md)):
[ADR-018](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-018-ABCI-Validators.md)):
- Remove PubKey from `Validator` (so it's just Address and Power)
- Introduce `ValidatorUpdate` (with just PubKey and Power)
- InitChain and EndBlock use ValidatorUpdate
@@ -2620,7 +2652,7 @@ BREAKING CHANGES:
- [state] [\#1815](https://github.com/tendermint/tendermint/issues/1815) Validator set changes are now delayed by one block (!)
- Add NextValidatorSet to State, changes on-disk representation of state
- [state] [\#2184](https://github.com/tendermint/tendermint/issues/2184) Enforce ConsensusParams.BlockSize.MaxBytes (See
[ADR-020](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-020-block-size.md)).
[ADR-020](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-020-block-size.md)).
- Remove ConsensusParams.BlockSize.MaxTxs
- Introduce maximum sizes for all components of a block, including ChainID
- [types] Updates to the block Header:
@@ -2631,7 +2663,7 @@ BREAKING CHANGES:
- [consensus] [\#2203](https://github.com/tendermint/tendermint/issues/2203) Implement BFT time
- Timestamp in block must be monotonic and equal the median of timestamps in block's LastCommit
- [crypto] [\#2239](https://github.com/tendermint/tendermint/issues/2239) Secp256k1 signature changes (See
[ADR-014](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-014-secp-malleability.md)):
[ADR-014](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-014-secp-malleability.md)):
- format changed from DER to `r || s`, both little endian encoded as 32 bytes.
- malleability removed by requiring `s` to be in canonical form.
@@ -2861,7 +2893,7 @@ BREAKING CHANGES:
FEATURES
- [cmd] Added metrics (served under `/metrics` using a Prometheus client;
disabled by default). See the new `instrumentation` section in the config and
[metrics](https://tendermint.readthedocs.io/projects/tools/en/develop/metrics.html)
[metrics](https://github.com/tendermint/tendermint/blob/main/docs/tendermint-core/metrics.md)
guide.
- [p2p] Add IPv6 support to peering.
- [p2p] Add `external_address` to config to allow specifying the address for
@@ -2975,7 +3007,7 @@ BREAKING:
FEATURES
- [rpc] the RPC documentation is now published to https://tendermint.github.io/slate
- [rpc] the RPC documentation is now published to https://github.com/tendermint/tendermint/tree/main/spec/rpc
- [p2p] AllowDuplicateIP config option to refuse connections from same IP.
- true by default for now, false by default in next breaking release
- [docs] Add docs for query, tx indexing, events, pubsub
@@ -3431,7 +3463,7 @@ Also includes the Grand Repo-Merge of 2017.
BREAKING CHANGES:
- Config and Flags:
- The `config` map is replaced with a [`Config` struct](https://github.com/tendermint/tendermint/blob/master/config/config.go#L11),
- The `config` map is replaced with a [`Config` struct](https://github.com/tendermint/tendermint/blob/main/config/config.go#L11),
containing substructs: `BaseConfig`, `P2PConfig`, `MempoolConfig`, `ConsensusConfig`, `RPCConfig`
- This affects the following flags:
- `--seeds` is now `--p2p.seeds`
@@ -3454,7 +3486,7 @@ containing substructs: `BaseConfig`, `P2PConfig`, `MempoolConfig`, `ConsensusCon
- Logger
- Replace static `log15` logger with a simple interface, and provide a new implementation using `go-kit`.
See our new [logging library](https://github.com/tendermint/tmlibs/log) and [blog post](https://tendermint.com/blog/abstracting-the-logger-interface-in-go) for more details
See our new [logging library](https://github.com/tendermint/tendermint/blob/main/libs/log/logger.go) and [blog post](https://blog.cosmos.network/abstracting-the-logger-interface-in-go-4cf96bf90bb7) for more details
- Levels `warn` and `notice` are removed (you may need to change them in your `config.toml`!)
- Change some [function and method signatures](https://gist.github.com/ebuchman/640d5fc6c2605f73497992fe107ebe0b) to accept a logger

View File

@@ -1,5 +1,37 @@
# Unreleased Changes
## v0.38.0
### BREAKING CHANGES
- CLI/RPC/Config
- Apps
- P2P Protocol
- Go API
- Blockchain Protocol
- Data Storage
- [state] \#6541 Move pruneBlocks from consensus/state to state/execution. (@JayT106)
- Tooling
- [tools/tm-signer-harness] \#6498 Set OS home dir to instead of the hardcoded PATH. (@JayT106)
### FEATURES
### IMPROVEMENTS
- [pubsub] \#7319 Performance improvements for the event query API (@creachadair)
- [p2p/pex] \#6509 Improve addrBook.hash performance (@cuonglm)
- [crypto/merkle] \#6443 & \#6513 Improve HashAlternatives performance (@cuonglm, @marbar3778)
### BUG FIXES
- [docker] \#9462 ensure Docker image uses consistent version of Go
## v0.37.0
Special thanks to external contributors on this release:
@@ -9,24 +41,58 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi
### BREAKING CHANGES
- CLI/RPC/Config
- [config] \#9259 Rename the fastsync section and the fast_sync key blocksync and block_sync respectively
- Apps
- [abci/counter] \#6684 Delete counter example app
- [abci] \#5783 Make length delimiter encoding consistent (`uint64`) between ABCI and P2P wire-level protocols
- [abci] \#9145 Removes unused Response/Request `SetOption` from ABCI (@samricotta)
- [abci/params] \#9287 Deduplicate `ConsensusParams` and `BlockParams` so only `types` proto definitions are used (@cmwaters)
- Remove `TimeIotaMs` and use a hard-coded 1 millisecond value to ensure monotonically increasing block times.
- Rename `AppVersion` to `App` so as to not stutter.
- [types] \#9287 Reduce the use of protobuf types in core logic. (@cmwaters)
- `ConsensusParams`, `BlockParams`, `ValidatorParams`, `EvidenceParams`, `VersionParams` have become native types.
They still utilize protobuf when being sent over the wire or written to disk.
- Moved `ValidateConsensusParams` inside (now native type) `ConsensusParams`, and renamed it to `ValidateBasic`.
- [abci] \#9301 New ABCI methods `PrepareProposal` and `ProcessProposal` which give the app control over transactions proposed and allows for verification of proposed blocks.
- [abci] \#8216 Renamed `EvidenceType` to `MisbehaviorType` and `Evidence` to `Misbehavior` as a more accurate label of their contents. (@williambanfield, @sergio-mena)
- [abci] \#9122 Renamed `LastCommitInfo` to `CommitInfo` in preparation for vote extensions. (@cmwaters)
- [abci] \#8656, \#8901 Added cli commands for `PrepareProposal` and `ProcessProposal`. (@jmalicevic, @hvanz)
- [abci] \#6403 Change the `key` and `value` fields from `[]byte` to `string` in the `EventAttribute` type. (@alexanderbez)
- P2P Protocol
- Go API
- [all] [#9144] Change spelling from British English to American (@cmwaters)
- [all] \#9144 Change spelling from British English to American (@cmwaters)
- Rename "Subscription.Cancelled()" to "Subscription.Canceled()" in libs/pubsub
- [crypto/sr25519] \#6526 Do not re-execute the Ed25519-style key derivation step when doing signing and verification. The derivation is now done once and only once. This breaks `sr25519.GenPrivKeyFromSecret` output compatibility. (@Yawning)
- Blockchain Protocol
### FEATURES
- [abci] \#9301 New ABCI methods `PrepareProposal` and `ProcessProposal` which give the app control over transactions proposed and allows for verification of proposed blocks.
### IMPROVEMENTS
- [crypto] \#9250 Update to use btcec v2 and the latest btcutil. (@wcsiu)
- [cli] \#9171 add `--hard` flag to rollback command (and a boolean to the `RollbackState` method). This will rollback
state and remove the last block. This command can be triggered multiple times. The application must also rollback
state to the same height. (@tsutsu, @cmwaters)
- [proto] \#9356 Migrate from `gogo/protobuf` to `cosmos/gogoproto` (@julienrbrt)
- [rpc] \#9276 Added `header` and `header_by_hash` queries to the RPC client (@samricotta)
- [abci] \#5706 Added `AbciVersion` to `RequestInfo` allowing applications to check ABCI version when connecting to Tendermint. (@marbar3778)
- [node] \#6059 Validate and complete genesis doc before saving to state store (@silasdavis)
- [crypto/ed25519] \#5632 Adopt zip215 `ed25519` verification. (@marbar3778)
- [crypto/ed25519] \#6526 Use [curve25519-voi](https://github.com/oasisprotocol/curve25519-voi) for `ed25519` signing and verification. (@Yawning)
- [crypto/sr25519] \#6526 Use [curve25519-voi](https://github.com/oasisprotocol/curve25519-voi) for `sr25519` signing and verification. (@Yawning)
- [crypto] \#6120 Implement batch verification interface for ed25519 and sr25519. (@marbar3778 & @Yawning)
- [types] \#6120 use batch verification for verifying commits signatures. (@marbar3778 & @cmwaters & @Yawning)
- If the key type supports the batch verification API it will try to batch verify. If the verification fails we will single verify each signature.
- [state] \#9505 Added logic so when pruning, the evidence period is taken into consideration and only deletes unecessary data (@samricotta)
### BUG FIXES
[docker] \#9073 enable cross platform build using docker buildx
- [consensus] \#9229 fix round number of `enterPropose` when handling `RoundStepNewRound` timeout. (@fatcat22)
- [docker] \#9073 enable cross platform build using docker buildx

View File

@@ -7,7 +7,7 @@ support permissionless value-carrying networks. While all contributions are
welcome, contributors should bear this goal in mind in deciding if they should
target the main Tendermint project or a potential fork. When targeting the
main Tendermint project, the following process leads to the best chance of
landing changes in master.
landing changes in `main`.
All work on the code base should be motivated by a [Github
Issue](https://github.com/tendermint/tendermint/issues).
@@ -26,7 +26,7 @@ will indicate their support with a heartfelt emoji.
If the issue would benefit from thorough discussion, maintainers may
request that you create a [Request For
Comment](https://github.com/tendermint/spec/tree/master/rfc)
Comment](https://github.com/tendermint/tendermint/tree/main/docs/rfc)
in the Tendermint spec repo. Discussion
at the RFC stage will build collective understanding of the dimensions
of the problems and help structure conversations around trade-offs.
@@ -46,7 +46,7 @@ Find the largest existing ADR number and bump it by 1.
When the problem as well as proposed solution are well understood,
changes should start with a [draft
pull request](https://github.blog/2019-02-14-introducing-draft-pull-requests/)
against master. The draft signals that work is underway. When the work
against `main`. The draft signals that work is underway. When the work
is ready for feedback, hitting "Ready for Review" will signal to the
maintainers to take a look.
@@ -54,7 +54,7 @@ maintainers to take a look.
Each stage of the process is aimed at creating feedback cycles which align contributors and maintainers to make sure:
- Contributors dont waste their time implementing/proposing features which wont land in master.
- Contributors dont waste their time implementing/proposing features which wont land in `main`.
- Maintainers have the necessary context in order to support and review contributions.
## Forking
@@ -73,19 +73,19 @@ For instance, to create a fork and work on a branch of it, I would:
- `git remote add origin git@github.com:ebuchman/basecoin.git`
Now `origin` refers to my fork and `upstream` refers to the Tendermint version.
So I can `git push -u origin master` to update my fork, and make pull requests to tendermint from there.
So I can `git push -u origin main` to update my fork, and make pull requests to tendermint from there.
Of course, replace `ebuchman` with your git handle.
To pull in updates from the origin repo, run
- `git fetch upstream`
- `git rebase upstream/master` (or whatever branch you want)
- `git rebase upstream/main` (or whatever branch you want)
## Dependencies
We use [go modules](https://github.com/golang/go/wiki/Modules) to manage dependencies.
That said, the master branch of every Tendermint repository should just build
That said, the `main` branch of every Tendermint repository should just build
with `go get`, which means they should be kept up-to-date with their
dependencies so we can get away with telling people they can just `go get` our
software.
@@ -106,7 +106,7 @@ specify exactly the dependency you want to update, eg.
## Protobuf
We use [Protocol Buffers](https://developers.google.com/protocol-buffers) along
with [`gogoproto`](https://github.com/gogo/protobuf) to generate code for use
with [`gogoproto`](https://github.com/cosmos/gogoproto) to generate code for use
across Tendermint Core.
To generate proto stubs, lint, and check protos for breaking changes, you will
@@ -142,7 +142,6 @@ If you are a VS Code user, you may want to add the following to your `.vscode/se
"protoc": {
"options": [
"--proto_path=${workspaceRoot}/proto",
"--proto_path=${workspaceRoot}/third_party/proto"
]
}
}
@@ -153,10 +152,47 @@ If you are a VS Code user, you may want to add the following to your `.vscode/se
Every fix, improvement, feature, or breaking change should be made in a
pull-request that includes an update to the `CHANGELOG_PENDING.md` file.
A feature can also be worked on a feature branch, if its size and/or risk
justifies it (see #branching-model-and-release) below.
### What does a good changelog entry look like?
Changelog entries should answer the question: "what is important about this
change for users to know?" or "what problem does this solve for users?". It
should not simply be a reiteration of the title of the associated PR, unless the
title of the PR _very_ clearly explains the benefit of a change to a user.
Some good examples of changelog entry descriptions:
```md
- [consensus] \#1111 Small transaction throughput improvement (approximately
3-5\% from preliminary tests) through refactoring the way we use channels
- [mempool] \#1112 Refactor Go API to be able to easily swap out the current
mempool implementation in Tendermint forks
- [p2p] \#1113 Automatically ban peers when their messages are unsolicited or
are received too frequently
```
Some bad examples of changelog entry descriptions:
```md
- [consensus] \#1111 Refactor channel usage
- [mempool] \#1112 Make API generic
- [p2p] \#1113 Ban for PEX message abuse
```
For more on how to write good changelog entries, see:
- <https://keepachangelog.com>
- <https://docs.gitlab.com/ee/development/changelog.html#writing-good-changelog-entries>
- <https://depfu.com/blog/what-makes-a-good-changelog>
### Changelog entry format
Changelog entries should be formatted as follows:
```md
- [module] \#xxx Some description about the change (@contributor)
- [module] \#xxx Some description of the change (@contributor)
```
Here, `module` is the part of the code that changed (typically a
@@ -184,22 +220,31 @@ removed from the header in RPC responses as well.
## Branching Model and Release
The main development branch is master.
The main development branch is `main`.
Every release is maintained in a release branch named `vX.Y.Z`.
Pending minor releases have long-lived release candidate ("RC") branches. Minor release changes should be merged to these long-lived RC branches at the same time that the changes are merged to master.
Pending minor releases have long-lived release candidate ("RC") branches. Minor release changes should be merged to these long-lived RC branches at the same time that the changes are merged to `main`.
If a feature's size is big and/or its risk is high, it can be implemented in a feature branch.
While the feature work is in progress,
pull requests are open and squash merged against the feature branch.
Branch `main` is periodically merged (merge commit) into the feature branch,
to reduce branch divergence.
When the feature is complete, the feature branch is merged back (merge commit) into `main`.
The moment of the final merge can be carefully chosen
so as to land different features in different releases.
Note all pull requests should be squash merged except for merging to a release branch (named `vX.Y`). This keeps the commit history clean and makes it
easy to reference the pull request where a change was introduced.
### Development Procedure
The latest state of development is on `master`, which must never fail `make test`. _Never_ force push `master`, unless fixing broken git history (which we rarely do anyways).
The latest state of development is on `main`, which must never fail `make test`. _Never_ force push `main`, unless fixing broken git history (which we rarely do anyways).
To begin contributing, create a development branch either on `github.com/tendermint/tendermint`, or your fork (using `git remote add origin`).
Make changes, and before submitting a pull request, update the `CHANGELOG_PENDING.md` to record your change. Also, run either `git rebase` or `git merge` on top of the latest `master`. (Since pull requests are squash-merged, either is fine!)
Make changes, and before submitting a pull request, update the `CHANGELOG_PENDING.md` to record your change. Also, run either `git rebase` or `git merge` on top of the latest `main`. (Since pull requests are squash-merged, either is fine!)
Update the `UPGRADING.md` if the change you've made is breaking and the
instructions should be in place for a user on how he/she can upgrade it's
@@ -207,7 +252,7 @@ software (ABCI application, Tendermint-based blockchain, light client, wallet).
Once you have submitted a pull request label the pull request with either `R:minor`, if the change should be included in the next minor release, or `R:major`, if the change is meant for a major release.
Sometimes (often!) pull requests get out-of-date with master, as other people merge different pull requests to master. It is our convention that pull request authors are responsible for updating their branches with master. (This also means that you shouldn't update someone else's branch for them; even if it seems like you're doing them a favor, you may be interfering with their git flow in some way!)
Sometimes (often!) pull requests get out-of-date with `main`, as other people merge different pull requests to `main`. It is our convention that pull request authors are responsible for updating their branches with `main`. (This also means that you shouldn't update someone else's branch for them; even if it seems like you're doing them a favor, you may be interfering with their git flow in some way!)
#### Merging Pull Requests
@@ -215,20 +260,20 @@ It is also our convention that authors merge their own pull requests, when possi
Before merging a pull request:
- Ensure pull branch is up-to-date with a recent `master` (GitHub won't let you merge without this!)
- Ensure pull branch is up-to-date with a recent `main` (GitHub won't let you merge without this!)
- Run `make test` to ensure that all tests pass
- [Squash](https://stackoverflow.com/questions/5189560/squash-my-last-x-commits-together-using-git) merge pull request
#### Pull Requests for Minor Releases
If your change should be included in a minor release, please also open a PR against the long-lived minor release candidate branch (e.g., `rc1/v0.33.5`) _immediately after your change has been merged to master_.
If your change should be included in a minor release, please also open a PR against the long-lived minor release candidate branch (e.g., `rc1/v0.33.5`) _immediately after your change has been merged to main_.
You can do this by cherry-picking your commit off master:
You can do this by cherry-picking your commit off `main`:
```sh
$ git checkout rc1/v0.33.5
$ git checkout -b {new branch name}
$ git cherry-pick {commit SHA from master}
$ git cherry-pick {commit SHA from main}
# may need to fix conflicts, and then use git add and git cherry-pick --continue
$ git push origin {new branch name}
```
@@ -247,7 +292,7 @@ cmd/debug: execute p.Signal only when p is not nil
Fixes #nnnn
```
Each PR should have one commit once it lands on `master`; this can be accomplished by using the "squash and merge" button on Github. Be sure to edit your commit message, though!
Each PR should have one commit once it lands on `main`; this can be accomplished by using the "squash and merge" button on Github. Be sure to edit your commit message, though!
## Testing

View File

@@ -1,5 +1,9 @@
# Use a build arg to ensure that both stages use the same,
# hopefully current, go version.
ARG GOLANG_BASE_IMAGE=golang:1.18-alpine
# stage 1 Generate Tendermint Binary
FROM --platform=$BUILDPLATFORM golang:1.15-alpine as builder
FROM --platform=$BUILDPLATFORM $GOLANG_BASE_IMAGE as builder
RUN apk update && \
apk upgrade && \
apk --no-cache add make
@@ -8,7 +12,7 @@ WORKDIR /tendermint
RUN TARGETPLATFORM=$TARGETPLATFORM make build-linux
# stage 2
FROM golang:1.15-alpine
FROM $GOLANG_BASE_IMAGE
LABEL maintainer="hello@tendermint.com"
# Tendermint will be looking for the genesis file in /tendermint/config/genesis.json

View File

@@ -6,9 +6,9 @@ DockerHub tags for official releases are [here](https://hub.docker.com/r/tenderm
Official releases can be found [here](https://github.com/tendermint/tendermint/releases).
The Dockerfile for tendermint is not expected to change in the near future. The master file used for all builds can be found [here](https://raw.githubusercontent.com/tendermint/tendermint/master/DOCKER/Dockerfile).
The Dockerfile for Tendermint is not expected to change in the near future. The main file used for all builds can be found [here](https://raw.githubusercontent.com/tendermint/tendermint/main/DOCKER/Dockerfile).
Respective versioned files can be found <https://raw.githubusercontent.com/tendermint/tendermint/vX.XX.XX/DOCKER/Dockerfile> (replace the Xs with the version number).
Respective versioned files can be found at `https://raw.githubusercontent.com/tendermint/tendermint/vX.XX.XX/DOCKER/Dockerfile` (replace the Xs with the version number).
## Quick reference
@@ -20,9 +20,9 @@ Respective versioned files can be found <https://raw.githubusercontent.com/tende
Tendermint Core is Byzantine Fault Tolerant (BFT) middleware that takes a state transition machine, written in any programming language, and securely replicates it on many machines.
For more background, see the [the docs](https://docs.tendermint.com/master/introduction/#quick-start).
For more background, see the [the docs](https://docs.tendermint.com/main/introduction/#quick-start).
To get started developing applications, see the [application developers guide](https://docs.tendermint.com/master/introduction/quick-start.html).
To get started developing applications, see the [application developers guide](https://docs.tendermint.com/main/introduction/quick-start.html).
## How to use this image
@@ -37,7 +37,7 @@ docker run -it --rm -v "/tmp:/tendermint" tendermint/tendermint node --proxy_app
## Local cluster
To run a 4-node network, see the `Makefile` in the root of [the repo](https://github.com/tendermint/tendermint/blob/master/Makefile) and run:
To run a 4-node network, see the `Makefile` in the root of [the repo](https://github.com/tendermint/tendermint/blob/main/Makefile) and run:
```sh
make build-linux
@@ -49,8 +49,8 @@ Note that this will build and use a different image than the ones provided here.
## License
- Tendermint's license is [Apache 2.0](https://github.com/tendermint/tendermint/blob/master/LICENSE).
- Tendermint's license is [Apache 2.0](https://github.com/tendermint/tendermint/blob/main/LICENSE).
## Contributing
Contributions are most welcome! See the [contributing file](https://github.com/tendermint/tendermint/blob/master/CONTRIBUTING.md) for more information.
Contributions are most welcome! See the [contributing file](https://github.com/tendermint/tendermint/blob/main/CONTRIBUTING.md) for more information.

View File

@@ -1,5 +1,3 @@
Tendermint Core
License: Apache2.0
Apache License
Version 2.0, January 2004
@@ -181,7 +179,7 @@ License: Apache2.0
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
@@ -189,7 +187,7 @@ License: Apache2.0
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2016 All in Bits, Inc
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -4,14 +4,8 @@ OUTPUT?=$(BUILDDIR)/tendermint
BUILD_TAGS?=tendermint
# If building a release, please checkout the version tag to get the correct version setting
ifneq ($(shell git symbolic-ref -q --short HEAD),)
VERSION := unreleased-$(shell git symbolic-ref -q --short HEAD)-$(shell git rev-parse HEAD)
else
VERSION := $(shell git describe)
endif
LD_FLAGS = -X github.com/tendermint/tendermint/version.TMCoreSemVer=$(VERSION)
COMMIT_HASH := $(shell git rev-parse --short HEAD)
LD_FLAGS = -X github.com/tendermint/tendermint/version.TMGitCommitHash=$(COMMIT_HASH)
BUILD_FLAGS = -mod=readonly -ldflags "$(LD_FLAGS)"
HTTPS_GIT := https://github.com/tendermint/tendermint.git
CGO_ENABLED ?= 0
@@ -131,6 +125,20 @@ install:
CGO_ENABLED=$(CGO_ENABLED) go install $(BUILD_FLAGS) -tags $(BUILD_TAGS) ./cmd/tendermint
.PHONY: install
###############################################################################
### Metrics ###
###############################################################################
metrics: testdata-metrics
go generate -run="scripts/metricsgen" ./...
.PHONY: metrics
# By convention, the go tool ignores subdirectories of directories named
# 'testdata'. This command invokes the generate command on the folder directly
# to avoid this.
testdata-metrics:
ls ./scripts/metricsgen/testdata | xargs -I{} go generate -v -run="scripts/metricsgen" ./scripts/metricsgen/testdata/{}
.PHONY: testdata-metrics
###############################################################################
### Mocks ###
@@ -146,7 +154,7 @@ mockery:
check-proto-deps:
ifeq (,$(shell which protoc-gen-gogofaster))
@go install github.com/gogo/protobuf/protoc-gen-gogofaster@latest
@go install github.com/cosmos/gogoproto/protoc-gen-gogofaster@latest
endif
.PHONY: check-proto-deps
@@ -160,6 +168,7 @@ proto-gen: check-proto-deps
@echo "Generating Protobuf files"
@go run github.com/bufbuild/buf/cmd/buf generate
@mv ./proto/tendermint/abci/types.pb.go ./abci/types/
@cp ./proto/tendermint/rpc/grpc/types.pb.go ./rpc/grpc
.PHONY: proto-gen
# These targets are provided for convenience and are intended for local
@@ -271,16 +280,33 @@ DESTINATION = ./index.html.md
### Documentation ###
###############################################################################
DOCS_OUTPUT?=/tmp/tendermint-core-docs
# This builds a docs site for each branch/tag in `./docs/versions` and copies
# each site to a version prefixed path. The last entry inside the `versions`
# file will be the default root index.html. Only redirects that are built into
# the "redirects" folder of each of the branches will be copied out to the root
# of the build at the end.
build-docs:
@cd docs && \
while read -r branch path_prefix; do \
(git checkout $${branch} && npm ci && VUEPRESS_BASE="/$${path_prefix}/" npm run build) ; \
mkdir -p ~/output/$${path_prefix} ; \
cp -r .vuepress/dist/* ~/output/$${path_prefix}/ ; \
cp ~/output/$${path_prefix}/index.html ~/output ; \
mkdir -p $(DOCS_OUTPUT)/$${path_prefix} ; \
cp -r .vuepress/dist/* $(DOCS_OUTPUT)/$${path_prefix}/ ; \
cp $(DOCS_OUTPUT)/$${path_prefix}/index.html $(DOCS_OUTPUT) ; \
cp $(DOCS_OUTPUT)/$${path_prefix}/404.html $(DOCS_OUTPUT) ; \
cp -r $(DOCS_OUTPUT)/$${path_prefix}/redirects/* $(DOCS_OUTPUT) || true ; \
done < versions ;
.PHONY: build-docs
# Build and serve the local version of the docs on the current branch from
# http://0.0.0.0:8080
serve-docs:
@cd docs && \
npm ci && \
npm run serve
.PHONY: serve-docs
sync-docs:
cd ~/output && \
echo "role_arn = ${DEPLOYMENT_ROLE_ARN}" >> /root/.aws/config ; \
@@ -289,6 +315,11 @@ sync-docs:
aws cloudfront create-invalidation --distribution-id ${CF_DISTRIBUTION_ID} --profile terraform --path "/*" ;
.PHONY: sync-docs
# Verify that important design docs have ToC entries.
check-docs-toc:
@./docs/presubmit.sh
.PHONY: check-docs-toc
###############################################################################
### Docker image ###
###############################################################################
@@ -369,4 +400,4 @@ $(BUILDDIR)/packages.txt:$(GO_TEST_FILES) $(BUILDDIR)
split-test-packages:$(BUILDDIR)/packages.txt
split -d -n l/$(NUM_SPLIT) $< $<.
test-group-%:split-test-packages
cat $(BUILDDIR)/packages.txt.$* | xargs go test -mod=readonly -timeout=5m -race -coverprofile=$(BUILDDIR)/$*.profile.out
cat $(BUILDDIR)/packages.txt.$* | xargs go test -mod=readonly -timeout=15m -race -coverprofile=$(BUILDDIR)/$*.profile.out

View File

@@ -10,12 +10,11 @@
[![Go version][go-badge]][go-url]
[![Discord chat][discord-badge]][discord-url]
[![License][license-badge]][license-url]
[![tendermint/tendermint][loc-badge]][loc-url]
[![Sourcegraph][sg-badge]][sg-url]
| Branch | Tests | Coverage | Linting |
|--------|-----------------------|------------------------------------------|---------------------|
| main | ![Tests][tests-badge] | [![codecov][codecov-badge]][codecov-url] | ![Lint][lint-badge] |
| Branch | Tests | Linting |
|--------|------------------------------------|---------------------------------|
| main | [![Tests][tests-badge]][tests-url] | [![Lint][lint-badge]][lint-url] |
Tendermint Core is a Byzantine Fault Tolerant (BFT) middleware that takes a
state transition machine - written in any programming language - and securely
@@ -71,8 +70,8 @@ See the [install instructions](./docs/introduction/install.md).
### Quick Start
- [Single node](./docs/introduction/quick-start.md)
- [Local cluster using docker-compose](./docs/tools/docker-compose.md)
- [Remote cluster using Terraform and Ansible](./docs/tools/terraform-and-ansible.md)
- [Local cluster using docker-compose](./docs/networks/docker-compose.md)
- [Remote cluster using Terraform and Ansible](./docs/networks/terraform-and-ansible.md)
## Contributing
@@ -146,7 +145,7 @@ Upgrading instructions can be found in [UPGRADING.md](./UPGRADING.md).
## Join us!
Tendermint Core is maintained by [Interchain GmbH](https://interchain.berlin).
Tendermint Core is maintained by [Interchain GmbH](https://interchain.io).
If you'd like to work full-time on Tendermint Core,
[we're hiring](https://interchain-gmbh.breezy.hr/)!
@@ -155,25 +154,22 @@ Funding for Tendermint Core development comes primarily from the
Tendermint trademark is owned by [Tendermint Inc.](https://tendermint.com), the
for-profit entity that also maintains [tendermint.com](https://tendermint.com).
[bft]: https://en.wikipedia.org/wiki/Byzantine_fault_tolerance
[smr]: https://en.wikipedia.org/wiki/State_machine_replication
[Blockchain]: https://en.wikipedia.org/wiki/Blockchain
[version-badge]: https://img.shields.io/github/tag/tendermint/tendermint.svg
[version-badge]: https://img.shields.io/github/v/release/tendermint/tendermint.svg
[version-url]: https://github.com/tendermint/tendermint/releases/latest
[api-badge]: https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f676f6c616e672f6764646f3f7374617475732e737667
[api-url]: https://pkg.go.dev/github.com/tendermint/tendermint
[go-badge]: https://img.shields.io/badge/go-1.17-blue.svg
[go-badge]: https://img.shields.io/badge/go-1.18-blue.svg
[go-url]: https://github.com/moovweb/gvm
[discord-badge]: https://img.shields.io/discord/669268347736686612.svg
[discord-url]: https://discord.gg/cosmosnetwork
[license-badge]: https://img.shields.io/github/license/tendermint/tendermint.svg
[license-url]: https://github.com/tendermint/tendermint/blob/main/LICENSE
[loc-badge]: https://tokei.rs/b1/github/tendermint/tendermint?category=lines
[loc-url]: https://github.com/tendermint/tendermint
[sg-badge]: https://sourcegraph.com/github.com/tendermint/tendermint/-/badge.svg
[sg-url]: https://sourcegraph.com/github.com/tendermint/tendermint?badge
[tests-badge]: https://github.com/tendermint/tendermint/workflows/Tests/badge.svg?branch=main
[codecov-badge]: https://codecov.io/gh/tendermint/tendermint/branch/main/graph/badge.svg
[codecov-url]: https://codecov.io/gh/tendermint/tendermint
[lint-badge]: https://github.com/tendermint/tendermint/workflows/Lint/badge.svg
[tests-url]: https://github.com/tendermint/tendermint/actions/workflows/tests.yml
[tests-badge]: https://github.com/tendermint/tendermint/actions/workflows/tests.yml/badge.svg?branch=main
[lint-badge]: https://github.com/tendermint/tendermint/actions/workflows/lint.yml/badge.svg
[lint-url]: https://github.com/tendermint/tendermint/actions/workflows/lint.yml

View File

@@ -22,8 +22,8 @@ We use Mergify's [backport feature](https://mergify.io/features/backports) to
automatically backport to the needed branch. There should be a label for any
backport branch that you'll be targeting. To notify the bot to backport a pull
request, mark the pull request with the label corresponding to the correct
backport branch. For example, to backport to v0.35.x, add the label
`S:backport-to-v0.35.x`. Once the original pull request is merged, the bot will
backport branch. For example, to backport to v0.38.x, add the label
`S:backport-to-v0.38.x`. Once the original pull request is merged, the bot will
try to cherry-pick the pull request to the backport branch. If the bot fails to
backport, it will open a pull request. The author of the original pull request
is responsible for solving the conflicts and merging the pull request.
@@ -40,37 +40,52 @@ branches tags. See [#6072](https://github.com/tendermint/tendermint/pull/6072)
for more context.
In the following example, we'll assume that we're making a backport branch for
the 0.35.x line.
the 0.38.x line.
1. Start on `main`
2. Create and push the backport branch:
2. Ensure that there is a [branch protection
rule](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/managing-a-branch-protection-rule) for the
branch you are about to create (you will need admin access to the repository
in order to do this).
3. Create and push the backport branch:
```sh
git checkout -b v0.35.x
git push origin v0.35.x
git checkout -b v0.38.x
git push origin v0.38.x
```
3. Create a PR to update the documentation directory for the backport branch.
4. Create a PR to update the documentation directory for the backport branch.
We only maintain RFC and ADR documents on main, to avoid confusion. In
addition, we rewrite Markdown URLs pointing to main to point to the
backport branch, so that generated documentation will link to the correct
versions of files elsewhere in the repository. For context on the latter, see
https://github.com/tendermint/tendermint/issues/7675.
We rewrite any URLs pointing to `main` to point to the backport branch,
so that generated documentation will link to the correct versions of files
elsewhere in the repository. The following files are to be excluded from this
search:
To prepare the PR:
* [`README.md`](./README.md)
* [`CHANGELOG.md`](./CHANGELOG.md)
* [`UPGRADING.md`](./UPGRADING.md)
The following links are to always point to `main`, regardless of where they
occur in the codebase:
* `https://github.com/tendermint/tendermint/blob/main/LICENSE`
Be sure to search for all of the following links and replace `main` with your
corresponding branch label or version (e.g. `v0.38.x` or `v0.38`):
* `github.com/tendermint/tendermint/blob/main` ->
`github.com/tendermint/tendermint/blob/v0.38.x`
* `github.com/tendermint/tendermint/tree/main` ->
`github.com/tendermint/tendermint/tree/v0.38.x`
* `docs.tendermint.com/main` -> `docs.tendermint.com/v0.38`
Once you have updated all of the relevant documentation:
```sh
# Remove the RFC and ADR documents from the backport.
# We only maintain these on main to avoid confusion.
git rm -r docs/rfc docs/architecture
# Update absolute links to point to the backport.
go run ./scripts/linkpatch -recur -target v0.35.x -skip-path docs/DOCS_README.md,docs/README.md docs
# Create and push the PR.
git checkout -b update-docs-v035x
git commit -m "Update docs for v0.35.x backport branch." docs
git push -u origin update-docs-v035x
git checkout -b update-docs-v038x
git commit -m "Update docs for v0.38.x backport branch."
git push -u origin update-docs-v038x
```
Be sure to merge this PR before making other changes on the newly-created
@@ -78,69 +93,79 @@ the 0.35.x line.
After doing these steps, go back to `main` and do the following:
1. Tag `main` as the dev branch for the _next_ minor version release and push
it up to GitHub.
For example:
```sh
git tag -a v0.36.0-dev -m "Development base for Tendermint v0.36."
git push origin v0.36.0-dev
```
2. Create a new workflow to run e2e nightlies for the new backport branch. (See
1. Create a new workflow to run e2e nightlies for the new backport branch. (See
[e2e-nightly-main.yml][e2e] for an example.)
3. Add a new section to the Mergify config (`.github/mergify.yml`) to enable the
backport bot to work on this branch, and add a corresponding `S:backport-to-v0.35.x`
2. Add a new section to the Mergify config (`.github/mergify.yml`) to enable the
backport bot to work on this branch, and add a corresponding `S:backport-to-v0.38.x`
[label](https://github.com/tendermint/tendermint/labels) so the bot can be triggered.
4. Add a new section to the Dependabot config (`.github/dependabot.yml`) to
3. Add a new section to the Dependabot config (`.github/dependabot.yml`) to
enable automatic update of Go dependencies on this branch. Copy and edit one
of the existing branch configurations to set the correct `target-branch`.
[e2e]: https://github.com/tendermint/tendermint/blob/main/.github/workflows/e2e-nightly-main.yml
## Release candidates
## Pre-releases
Before creating an official release, especially a minor release, we may want to
create a release candidate (RC) for our friends and partners to test out. We use
git tags to create RCs, and we build them off of backport branches.
create an alpha or beta version, or release candidate (RC) for our friends and
partners to test out. We use git tags to create pre-releases, and we build them
off of backport branches, for example:
Tags for RCs should follow the "standard" release naming conventions, with
`-rcX` at the end (for example, `v0.35.0-rc0`).
- `v0.38.0-alpha.1` - The first alpha release of `v0.38.0`. Subsequent alpha
releases will be numbered `v0.38.0-alpha.2`, `v0.38.0-alpha.3`, etc.
Alpha releases are to be considered the _most_ unstable of pre-releases, and
are most likely not yet properly QA'd. These are made available to allow early
adopters to start integrating and testing new functionality before we're done
with QA.
- `v0.38.0-beta.1` - The first beta release of `v0.38.0`. Subsequent beta
releases will be numbered `v0.38.0-beta.2`, `v0.38.0-beta.3`, etc.
Beta releases can be considered more stable than alpha releases in that we
will have QA'd them better than alpha releases, but there still may be
minor breaking API changes if users have strong demands for such changes.
- `v0.38.0-rc1` - The first release candidate (RC) of `v0.38.0`. Subsequent RCs
will be numbered `v0.38.0-rc2`, `v0.38.0-rc3`, etc.
RCs are considered more stable than beta releases in that we will have
completed our QA on them. APIs will most likely be stable at this point. The
difference between an RC and a release is that there may still be small
changes (bug fixes, features) that may make their way into the series before
cutting a final release.
(Note that branches and tags _cannot_ have the same names, so it's important
that these branches have distinct names from the tags/release names.)
If this is the first RC for a minor release, you'll have to make a new backport
branch (see above). Otherwise:
If this is the first pre-release for a minor release, you'll have to make a new
backport branch (see above). Otherwise:
1. Start from the backport branch (e.g. `v0.35.x`).
2. Run the integration tests and the e2e nightlies
(which can be triggered from the Github UI;
e.g., https://github.com/tendermint/tendermint/actions/workflows/e2e-nightly-34x.yml).
3. Prepare the changelog:
- Move the changes included in `CHANGELOG_PENDING.md` into `CHANGELOG.md`. Each RC should have
it's own changelog section. These will be squashed when the final candidate is released.
- Run `python ./scripts/linkify_changelog.py CHANGELOG.md` to add links for
all PRs
1. Start from the backport branch (e.g. `v0.38.x`).
2. Run the integration tests and the E2E nightlies
(which can be triggered from the GitHub UI;
e.g., https://github.com/tendermint/tendermint/actions/workflows/e2e-nightly-37x.yml).
3. Prepare the pre-release documentation:
- Ensure that all relevant changes are in the `CHANGELOG_PENDING.md` file.
This file's contents must only be included in the `CHANGELOG.md` when we
cut final releases.
- Ensure that `UPGRADING.md` is up-to-date and includes notes on any breaking changes
or other upgrading flows.
4. Prepare the versioning:
- Bump TMVersionDefault version in `version.go`
- Bump P2P and block protocol versions in `version.go`, if necessary.
Check the changelog for breaking changes in these components.
- Bump ABCI protocol version in `version.go`, if necessary
4. Open a PR with these changes against the backport branch.
5. Once these changes have landed on the backport branch, be sure to pull them back down locally.
6. Once you have the changes locally, create the new tag, specifying a name and a tag "message":
`git tag -a v0.35.0-rc0 -m "Release Candidate v0.35.0-rc0`
7. Push the tag back up to origin:
`git push origin v0.35.0-rc0`
5. Open a PR with these changes against the backport branch.
6. Once these changes have landed on the backport branch, be sure to pull them back down locally.
7. Once you have the changes locally, create the new tag, specifying a name and a tag "message":
`git tag -a v0.38.0-rc1 -m "Release Candidate v0.38.0-rc1`
8. Push the tag back up to origin:
`git push origin v0.38.0-rc1`
Now the tag should be available on the repo's releases page.
8. Future RCs will continue to be built off of this branch.
Note that this process should only be used for "true" RCs -- release candidates
that, if successful, will be the next release. For more experimental "RCs,"
create a new, short-lived branch and tag that instead.
9. Future pre-releases will continue to be built off of this branch.
## Minor release
@@ -151,13 +176,14 @@ branch, as described above.
Before performing these steps, be sure the
[Minor Release Checklist](#minor-release-checklist) has been completed.
1. Start on the backport branch (e.g. `v0.35.x`)
1. Start on the backport branch (e.g. `v0.38.x`)
2. Run integration tests (`make test_integrations`) and the e2e nightlies.
3. Prepare the release:
- "Squash" changes from the changelog entries for the RCs into a single entry,
and add all changes included in `CHANGELOG_PENDING.md`.
(Squashing includes both combining all entries, as well as removing or simplifying
any intra-RC changes. It may also help to alphabetize the entries by package name.)
- "Squash" changes from the changelog entries for the pre-releases into a
single entry, and add all changes included in `CHANGELOG_PENDING.md`.
(Squashing includes both combining all entries, as well as removing or
simplifying any intra-pre-release changes. It may also help to alphabetize
the entries by package name.)
- Run `python ./scripts/linkify_changelog.py CHANGELOG.md` to add links for
all PRs
- Ensure that `UPGRADING.md` is up-to-date and includes notes on any breaking changes
@@ -167,12 +193,12 @@ Before performing these steps, be sure the
- Bump ABCI protocol version in `version.go`, if necessary
4. Open a PR with these changes against the backport branch.
5. Once these changes are on the backport branch, push a tag with prepared release details.
This will trigger the actual release `v0.35.0`.
- `git tag -a v0.35.0 -m 'Release v0.35.0'`
- `git push origin v0.35.0`
This will trigger the actual release `v0.38.0`.
- `git tag -a v0.38.0 -m 'Release v0.38.0'`
- `git push origin v0.38.0`
6. Make sure that `main` is updated with the latest `CHANGELOG.md`, `CHANGELOG_PENDING.md`, and `UPGRADING.md`.
7. Add the release to the documentation site generator config (see
[DOCS_README.md](./docs/DOCS_README.md) for more details). In summary:
[DOCS\_README.md](./docs/DOCS_README.md) for more details). In summary:
- Start on branch `main`.
- Add a new line at the bottom of [`docs/versions`](./docs/versions) to
ensure the newest release is the default for the landing page.
@@ -193,7 +219,7 @@ changes may merit a release candidate.
To create a patch release:
1. Checkout the long-lived backport branch: `git checkout v0.35.x`
1. Checkout the long-lived backport branch: `git checkout v0.38.x`
2. Run integration tests (`make test_integrations`) and the nightlies.
3. Check out a new branch and prepare the release:
- Copy `CHANGELOG_PENDING.md` to top of `CHANGELOG.md`
@@ -204,10 +230,10 @@ To create a patch release:
- Bump the ABCI version number, if necessary.
(Note that ABCI follows semver, and that ABCI versions are the only versions
which can change during patch releases, and only field additions are valid patch changes.)
4. Open a PR with these changes that will land them back on `v0.35.x`
4. Open a PR with these changes that will land them back on `v0.38.x`
5. Once this change has landed on the backport branch, make sure to pull it locally, then push a tag.
- `git tag -a v0.35.1 -m 'Release v0.35.1'`
- `git push origin v0.35.1`
- `git tag -a v0.38.1 -m 'Release v0.38.1'`
- `git push origin v0.38.1`
6. Create a pull request back to main with the CHANGELOG & version changes from the latest release.
- Remove all `R:patch` labels from the pull requests that were included in the release.
- Do not merge the backport branch into main.

View File

@@ -1,6 +1,36 @@
# Upgrading Tendermint Core
This guide provides instructions for upgrading to specific versions of Tendermint Core.
This guide provides instructions for upgrading to specific versions of
Tendermint Core.
## Unreleased
### ABCI Changes
* The `ABCIVersion` is now `1.0.0`.
* Added new ABCI methods `PrepareProposal` and `ProcessProposal`. For details,
please see the [spec](spec/abci/README.md). Applications upgrading to
v0.37.0 must implement these methods, at the very minimum, as described
[here](./spec/abci/abci++_app_requirements.md)
* Deduplicated `ConsensusParams` and `BlockParams`.
In the v0.34 branch they are defined both in `abci/types.proto` and `types/params.proto`.
The definitions in `abci/types.proto` have been removed.
In-process applications should make sure they are not using the deleted
version of those structures.
* In v0.34, messages on the wire used to be length-delimited with `int64` varint
values, which was inconsistent with the `uint64` varint length delimiters used
in the P2P layer. Both now consistently use `uint64` varint length delimiters.
* Added `AbciVersion` to `RequestInfo`.
Applications should check that Tendermint's ABCI version matches the one they expect
in order to ensure compatibility.
* The `SetOption` method has been removed from the ABCI `Client` interface.
The corresponding Protobuf types have been deprecated.
* The `key` and `value` fields in the `EventAttribute` type have been changed
from type `bytes` to `string`. As per the [Protocol Buffers updating
guidelines](https://developers.google.com/protocol-buffers/docs/proto3#updating),
this should have no effect on the wire-level encoding for UTF8-encoded
strings.
## v0.34.20
@@ -15,7 +45,7 @@ and gas cost).
Operators can enable the priority mempool by setting `mempool.version` to
`"v1"` in the `config.toml`. For more technical details about the priority
mempool, see [ADR 067: Mempool
Refactor](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-067-mempool-refactor.md).
Refactor](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-067-mempool-refactor.md).
## v0.34.0
@@ -23,7 +53,7 @@ Refactor](https://github.com/tendermint/tendermint/blob/master/docs/architecture
This release is not compatible with previous blockchains due to changes to
the encoding format (see "Protocol Buffers," below) and the block header (see "Blockchain Protocol").
Note also that Tendermint 0.34 also requires Go 1.15 or higher.
Note also that Tendermint 0.34 also requires Go 1.16 or higher.
### ABCI Changes
@@ -33,7 +63,7 @@ Note also that Tendermint 0.34 also requires Go 1.15 or higher.
were added to support the new State Sync feature.
Previously, syncing a new node to a preexisting network could take days; but with State Sync,
new nodes are able to join a network in a matter of seconds.
Read [the spec](https://docs.tendermint.com/master/spec/abci/apps.html#state-sync)
Read [the spec](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/abci/apps.md#state-sync)
if you want to learn more about State Sync, or if you'd like your application to use it.
(If you don't want to support State Sync in your application, you can just implement these new
ABCI methods as no-ops, leaving them empty.)
@@ -49,7 +79,7 @@ Note also that Tendermint 0.34 also requires Go 1.15 or higher.
Applications should be able to handle these evidence types
(i.e., through slashing or other accountability measures).
* The [`PublicKey` type](https://github.com/tendermint/tendermint/blob/master/proto/tendermint/crypto/keys.proto#L13-L15)
* The [`PublicKey` type](https://github.com/tendermint/tendermint/blob/main/proto/tendermint/crypto/keys.proto#L13-L15)
(used in ABCI as part of `ValidatorUpdate`) now uses a `oneof` protobuf type.
Note that since Tendermint only supports ed25519 validator keys, there's only one
option in the `oneof`. For more, see "Protocol Buffers," below.
@@ -64,12 +94,9 @@ directory. For more, see "Protobuf," below.
### Blockchain Protocol
* `Header#LastResultsHash` previously was the root hash of a Merkle tree built from `ResponseDeliverTx(Code, Data)` responses.
As of 0.34,`Header#LastResultsHash` is now the root hash of a Merkle tree built from:
* `BeginBlock#Events`
* Root hash of a Merkle tree built from `ResponseDeliverTx(Code, Data,
GasWanted, GasUsed, Events)` responses
* `BeginBlock#Events`
* `Header#LastResultsHash`, which is the root hash of a Merkle tree built from
`ResponseDeliverTx(Code, Data)` as of v0.34 also includes `GasWanted` and `GasUsed`
fields.
* Merkle hashes of empty trees previously returned nothing, but now return the hash of an empty input,
to conform with [RFC-6962](https://tools.ietf.org/html/rfc6962).
@@ -159,7 +186,7 @@ The `bech32` package has moved to the Cosmos SDK:
### CLI
The `tendermint lite` command has been renamed to `tendermint light` and has a slightly different API.
See [the docs](https://docs.tendermint.com/master/tendermint-core/light-client-protocol.html#http-proxy) for details.
See [the docs](https://docs.tendermint.com/v0.33/tendermint-core/light-client-protocol.html#http-proxy) for details.
### Light Client
@@ -173,6 +200,7 @@ Other user-relevant changes include:
* The `Verifier` was broken up into two pieces:
* Core verification logic (pure `VerifyX` functions)
* `Client` object, which represents the complete light client
* The new light client stores headers and validator sets as `LightBlock`s
* The RPC client can be found in the `/rpc` directory.
* The HTTP(S) proxy is located in the `/proxy` directory.
@@ -314,7 +342,7 @@ Evidence Params has been changed to include duration.
### RPC Changes
* `/validators` is now paginated (default: 30 vals per page)
* `/block_results` response format updated [see RPC docs for details](https://docs.tendermint.com/master/rpc/#/Info/block_results)
* `/block_results` response format updated [see RPC docs for details](https://docs.tendermint.com/v0.33/rpc/#/Info/block_results)
* Event suffix has been removed from the ID in event responses
* IDs are now integers not `json-client-XYZ`
@@ -433,7 +461,7 @@ the compilation tag:
Use `cleveldb` tag instead of `gcc` to compile Tendermint with CLevelDB or
use `make build_c` / `make install_c` (full instructions can be found at
<https://tendermint.com/docs/introduction/install.html#compile-with-cleveldb-support>)
<https://docs.tendermint.com/v0.33/introduction/install.html#compile-with-cleveldb-support>)
## v0.31.0
@@ -508,14 +536,14 @@ due to changes in how various data structures are hashed.
Any implementations of Tendermint blockchain verification, including lite clients,
will need to be updated. For specific details:
* [Merkle tree](https://github.com/tendermint/spec/blob/master/spec/blockchain/encoding.md#merkle-trees)
* [ConsensusParams](https://github.com/tendermint/spec/blob/master/spec/blockchain/state.md#consensusparams)
* [Merkle tree](https://github.com/tendermint/tendermint/blob/main/spec/blockchain/encoding.md#merkle-trees)
* [ConsensusParams](https://github.com/tendermint/tendermint/blob/main/spec/blockchain/state.md#consensusparams)
There was also a small change to field ordering in the vote struct. Any
implementations of an out-of-process validator (like a Key-Management Server)
will need to be updated. For specific details:
* [Vote](https://github.com/tendermint/spec/blob/master/spec/consensus/signing.md#votes)
* [Vote](https://github.com/tendermint/tendermint/blob/main/spec/consensus/signing.md#votes)
Finally, the proposer selection algorithm continues to evolve. See the
[work-in-progress

View File

@@ -19,8 +19,8 @@ To get up and running quickly, see the [getting started guide](../docs/app-dev/g
A detailed description of the ABCI methods and message types is contained in:
- [The main spec](https://github.com/tendermint/spec/blob/master/spec/abci/abci.md)
- [A protobuf file](./types/types.proto)
- [The main spec](https://github.com/tendermint/tendermint/blob/main/spec/abci/README.md)
- [A protobuf file](../proto/tendermint/types/types.proto)
- [A Go interface](./types/application.go)
## Protocol Buffers

View File

@@ -14,6 +14,8 @@ const (
echoRetryIntervalSeconds = 1
)
//go:generate ../../scripts/mockery_generate.sh Client
// Client defines an interface for an ABCI client.
// All `Async` methods return a `ReqRes` object.
// All `Sync` methods return the appropriate protobuf ResponseXxx struct and an error.
@@ -28,34 +30,36 @@ type Client interface {
FlushAsync() *ReqRes
EchoAsync(msg string) *ReqRes
InfoAsync(types.RequestInfo) *ReqRes
SetOptionAsync(types.RequestSetOption) *ReqRes
DeliverTxAsync(types.RequestDeliverTx) *ReqRes
CheckTxAsync(types.RequestCheckTx) *ReqRes
QueryAsync(types.RequestQuery) *ReqRes
CommitAsync() *ReqRes
InitChainAsync(types.RequestInitChain) *ReqRes
PrepareProposalAsync(types.RequestPrepareProposal) *ReqRes
BeginBlockAsync(types.RequestBeginBlock) *ReqRes
EndBlockAsync(types.RequestEndBlock) *ReqRes
ListSnapshotsAsync(types.RequestListSnapshots) *ReqRes
OfferSnapshotAsync(types.RequestOfferSnapshot) *ReqRes
LoadSnapshotChunkAsync(types.RequestLoadSnapshotChunk) *ReqRes
ApplySnapshotChunkAsync(types.RequestApplySnapshotChunk) *ReqRes
ProcessProposalAsync(types.RequestProcessProposal) *ReqRes
FlushSync() error
EchoSync(msg string) (*types.ResponseEcho, error)
InfoSync(types.RequestInfo) (*types.ResponseInfo, error)
SetOptionSync(types.RequestSetOption) (*types.ResponseSetOption, error)
DeliverTxSync(types.RequestDeliverTx) (*types.ResponseDeliverTx, error)
CheckTxSync(types.RequestCheckTx) (*types.ResponseCheckTx, error)
QuerySync(types.RequestQuery) (*types.ResponseQuery, error)
CommitSync() (*types.ResponseCommit, error)
InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error)
PrepareProposalSync(types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error)
BeginBlockSync(types.RequestBeginBlock) (*types.ResponseBeginBlock, error)
EndBlockSync(types.RequestEndBlock) (*types.ResponseEndBlock, error)
ListSnapshotsSync(types.RequestListSnapshots) (*types.ResponseListSnapshots, error)
OfferSnapshotSync(types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error)
LoadSnapshotChunkSync(types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error)
ApplySnapshotChunkSync(types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error)
ProcessProposalSync(types.RequestProcessProposal) (*types.ResponseProcessProposal, error)
}
//----------------------------------------

View File

@@ -192,15 +192,6 @@ func (cli *grpcClient) InfoAsync(params types.RequestInfo) *ReqRes {
return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Info{Info: res}})
}
func (cli *grpcClient) SetOptionAsync(params types.RequestSetOption) *ReqRes {
req := types.ToRequestSetOption(params)
res, err := cli.client.SetOption(context.Background(), req.GetSetOption(), grpc.WaitForReady(true))
if err != nil {
cli.StopForError(err)
}
return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_SetOption{SetOption: res}})
}
func (cli *grpcClient) DeliverTxAsync(params types.RequestDeliverTx) *ReqRes {
req := types.ToRequestDeliverTx(params)
res, err := cli.client.DeliverTx(context.Background(), req.GetDeliverTx(), grpc.WaitForReady(true))
@@ -300,6 +291,25 @@ func (cli *grpcClient) ApplySnapshotChunkAsync(params types.RequestApplySnapshot
return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_ApplySnapshotChunk{ApplySnapshotChunk: res}})
}
func (cli *grpcClient) PrepareProposalAsync(params types.RequestPrepareProposal) *ReqRes {
req := types.ToRequestPrepareProposal(params)
res, err := cli.client.PrepareProposal(context.Background(), req.GetPrepareProposal(), grpc.WaitForReady(true))
if err != nil {
cli.StopForError(err)
}
return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_PrepareProposal{PrepareProposal: res}})
}
func (cli *grpcClient) ProcessProposalAsync(params types.RequestProcessProposal) *ReqRes {
req := types.ToRequestProcessProposal(params)
res, err := cli.client.ProcessProposal(context.Background(), req.GetProcessProposal(), grpc.WaitForReady(true))
if err != nil {
cli.StopForError(err)
}
return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_ProcessProposal{ProcessProposal: res}})
}
// finishAsyncCall creates a ReqRes for an async call, and immediately populates it
// with the response. We don't complete it until it's been ordered via the channel.
func (cli *grpcClient) finishAsyncCall(req *types.Request, res *types.Response) *ReqRes {
@@ -356,11 +366,6 @@ func (cli *grpcClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, err
return cli.finishSyncCall(reqres).GetInfo(), cli.Error()
}
func (cli *grpcClient) SetOptionSync(req types.RequestSetOption) (*types.ResponseSetOption, error) {
reqres := cli.SetOptionAsync(req)
return reqres.Response.GetSetOption(), cli.Error()
}
func (cli *grpcClient) DeliverTxSync(params types.RequestDeliverTx) (*types.ResponseDeliverTx, error) {
reqres := cli.DeliverTxAsync(params)
return cli.finishSyncCall(reqres).GetDeliverTx(), cli.Error()
@@ -417,3 +422,14 @@ func (cli *grpcClient) ApplySnapshotChunkSync(
reqres := cli.ApplySnapshotChunkAsync(params)
return cli.finishSyncCall(reqres).GetApplySnapshotChunk(), cli.Error()
}
func (cli *grpcClient) PrepareProposalSync(
params types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) {
reqres := cli.PrepareProposalAsync(params)
return cli.finishSyncCall(reqres).GetPrepareProposal(), cli.Error()
}
func (cli *grpcClient) ProcessProposalSync(params types.RequestProcessProposal) (*types.ResponseProcessProposal, error) {
reqres := cli.ProcessProposalAsync(params)
return cli.finishSyncCall(reqres).GetProcessProposal(), cli.Error()
}

View File

@@ -75,17 +75,6 @@ func (app *localClient) InfoAsync(req types.RequestInfo) *ReqRes {
)
}
func (app *localClient) SetOptionAsync(req types.RequestSetOption) *ReqRes {
app.mtx.Lock()
defer app.mtx.Unlock()
res := app.Application.SetOption(req)
return app.callback(
types.ToRequestSetOption(req),
types.ToResponseSetOption(res),
)
}
func (app *localClient) DeliverTxAsync(params types.RequestDeliverTx) *ReqRes {
app.mtx.Lock()
defer app.mtx.Unlock()
@@ -207,6 +196,28 @@ func (app *localClient) ApplySnapshotChunkAsync(req types.RequestApplySnapshotCh
)
}
func (app *localClient) PrepareProposalAsync(req types.RequestPrepareProposal) *ReqRes {
app.mtx.Lock()
defer app.mtx.Unlock()
res := app.Application.PrepareProposal(req)
return app.callback(
types.ToRequestPrepareProposal(req),
types.ToResponsePrepareProposal(res),
)
}
func (app *localClient) ProcessProposalAsync(req types.RequestProcessProposal) *ReqRes {
app.mtx.Lock()
defer app.mtx.Unlock()
res := app.Application.ProcessProposal(req)
return app.callback(
types.ToRequestProcessProposal(req),
types.ToResponseProcessProposal(res),
)
}
//-------------------------------------------------------
func (app *localClient) FlushSync() error {
@@ -225,14 +236,6 @@ func (app *localClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, er
return &res, nil
}
func (app *localClient) SetOptionSync(req types.RequestSetOption) (*types.ResponseSetOption, error) {
app.mtx.Lock()
defer app.mtx.Unlock()
res := app.Application.SetOption(req)
return &res, nil
}
func (app *localClient) DeliverTxSync(req types.RequestDeliverTx) (*types.ResponseDeliverTx, error) {
app.mtx.Lock()
defer app.mtx.Unlock()
@@ -323,6 +326,22 @@ func (app *localClient) ApplySnapshotChunkSync(
return &res, nil
}
func (app *localClient) PrepareProposalSync(req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) {
app.mtx.Lock()
defer app.mtx.Unlock()
res := app.Application.PrepareProposal(req)
return &res, nil
}
func (app *localClient) ProcessProposalSync(req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) {
app.mtx.Lock()
defer app.mtx.Unlock()
res := app.Application.ProcessProposal(req)
return &res, nil
}
//-------------------------------------------------------
func (app *localClient) callback(req *types.Request, res *types.Response) *ReqRes {

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v1.1.1. DO NOT EDIT.
// Code generated by mockery. DO NOT EDIT.
package mocks
@@ -575,6 +575,84 @@ func (_m *Client) OnStop() {
_m.Called()
}
// PrepareProposalAsync provides a mock function with given fields: _a0
func (_m *Client) PrepareProposalAsync(_a0 types.RequestPrepareProposal) *abcicli.ReqRes {
ret := _m.Called(_a0)
var r0 *abcicli.ReqRes
if rf, ok := ret.Get(0).(func(types.RequestPrepareProposal) *abcicli.ReqRes); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*abcicli.ReqRes)
}
}
return r0
}
// PrepareProposalSync provides a mock function with given fields: _a0
func (_m *Client) PrepareProposalSync(_a0 types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) {
ret := _m.Called(_a0)
var r0 *types.ResponsePrepareProposal
if rf, ok := ret.Get(0).(func(types.RequestPrepareProposal) *types.ResponsePrepareProposal); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.ResponsePrepareProposal)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(types.RequestPrepareProposal) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ProcessProposalAsync provides a mock function with given fields: _a0
func (_m *Client) ProcessProposalAsync(_a0 types.RequestProcessProposal) *abcicli.ReqRes {
ret := _m.Called(_a0)
var r0 *abcicli.ReqRes
if rf, ok := ret.Get(0).(func(types.RequestProcessProposal) *abcicli.ReqRes); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*abcicli.ReqRes)
}
}
return r0
}
// ProcessProposalSync provides a mock function with given fields: _a0
func (_m *Client) ProcessProposalSync(_a0 types.RequestProcessProposal) (*types.ResponseProcessProposal, error) {
ret := _m.Called(_a0)
var r0 *types.ResponseProcessProposal
if rf, ok := ret.Get(0).(func(types.RequestProcessProposal) *types.ResponseProcessProposal); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.ResponseProcessProposal)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(types.RequestProcessProposal) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// QueryAsync provides a mock function with given fields: _a0
func (_m *Client) QueryAsync(_a0 types.RequestQuery) *abcicli.ReqRes {
ret := _m.Called(_a0)
@@ -649,45 +727,6 @@ func (_m *Client) SetLogger(_a0 log.Logger) {
_m.Called(_a0)
}
// SetOptionAsync provides a mock function with given fields: _a0
func (_m *Client) SetOptionAsync(_a0 types.RequestSetOption) *abcicli.ReqRes {
ret := _m.Called(_a0)
var r0 *abcicli.ReqRes
if rf, ok := ret.Get(0).(func(types.RequestSetOption) *abcicli.ReqRes); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*abcicli.ReqRes)
}
}
return r0
}
// SetOptionSync provides a mock function with given fields: _a0
func (_m *Client) SetOptionSync(_a0 types.RequestSetOption) (*types.ResponseSetOption, error) {
ret := _m.Called(_a0)
var r0 *types.ResponseSetOption
if rf, ok := ret.Get(0).(func(types.RequestSetOption) *types.ResponseSetOption); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.ResponseSetOption)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(types.RequestSetOption) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// SetResponseCallback provides a mock function with given fields: _a0
func (_m *Client) SetResponseCallback(_a0 abcicli.Callback) {
_m.Called(_a0)
@@ -734,3 +773,18 @@ func (_m *Client) String() string {
return r0
}
type mockConstructorTestingTNewClient interface {
mock.TestingT
Cleanup(func())
}
// NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func NewClient(t mockConstructorTestingTNewClient) *Client {
mock := &Client{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -231,10 +231,6 @@ func (cli *socketClient) InfoAsync(req types.RequestInfo) *ReqRes {
return cli.queueRequest(types.ToRequestInfo(req))
}
func (cli *socketClient) SetOptionAsync(req types.RequestSetOption) *ReqRes {
return cli.queueRequest(types.ToRequestSetOption(req))
}
func (cli *socketClient) DeliverTxAsync(req types.RequestDeliverTx) *ReqRes {
return cli.queueRequest(types.ToRequestDeliverTx(req))
}
@@ -279,6 +275,14 @@ func (cli *socketClient) ApplySnapshotChunkAsync(req types.RequestApplySnapshotC
return cli.queueRequest(types.ToRequestApplySnapshotChunk(req))
}
func (cli *socketClient) PrepareProposalAsync(req types.RequestPrepareProposal) *ReqRes {
return cli.queueRequest(types.ToRequestPrepareProposal(req))
}
func (cli *socketClient) ProcessProposalAsync(req types.RequestProcessProposal) *ReqRes {
return cli.queueRequest(types.ToRequestProcessProposal(req))
}
//----------------------------------------
func (cli *socketClient) FlushSync() error {
@@ -308,15 +312,6 @@ func (cli *socketClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, e
return reqres.Response.GetInfo(), cli.Error()
}
func (cli *socketClient) SetOptionSync(req types.RequestSetOption) (*types.ResponseSetOption, error) {
reqres := cli.queueRequest(types.ToRequestSetOption(req))
if err := cli.FlushSync(); err != nil {
return nil, err
}
return reqres.Response.GetSetOption(), cli.Error()
}
func (cli *socketClient) DeliverTxSync(req types.RequestDeliverTx) (*types.ResponseDeliverTx, error) {
reqres := cli.queueRequest(types.ToRequestDeliverTx(req))
if err := cli.FlushSync(); err != nil {
@@ -417,6 +412,24 @@ func (cli *socketClient) ApplySnapshotChunkSync(
return reqres.Response.GetApplySnapshotChunk(), cli.Error()
}
func (cli *socketClient) PrepareProposalSync(req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) {
reqres := cli.queueRequest(types.ToRequestPrepareProposal(req))
if err := cli.FlushSync(); err != nil {
return nil, err
}
return reqres.Response.GetPrepareProposal(), cli.Error()
}
func (cli *socketClient) ProcessProposalSync(req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) {
reqres := cli.queueRequest(types.ToRequestProcessProposal(req))
if err := cli.FlushSync(); err != nil {
return nil, err
}
return reqres.Response.GetProcessProposal(), cli.Error()
}
//----------------------------------------
func (cli *socketClient) queueRequest(req *types.Request) *ReqRes {
@@ -468,8 +481,6 @@ func resMatchesReq(req *types.Request, res *types.Response) (ok bool) {
_, ok = res.Value.(*types.Response_Flush)
case *types.Request_Info:
_, ok = res.Value.(*types.Response_Info)
case *types.Request_SetOption:
_, ok = res.Value.(*types.Response_SetOption)
case *types.Request_DeliverTx:
_, ok = res.Value.(*types.Response_DeliverTx)
case *types.Request_CheckTx:
@@ -492,6 +503,10 @@ func resMatchesReq(req *types.Request, res *types.Response) (ok bool) {
_, ok = res.Value.(*types.Response_ListSnapshots)
case *types.Request_OfferSnapshot:
_, ok = res.Value.(*types.Response_OfferSnapshot)
case *types.Request_PrepareProposal:
_, ok = res.Value.(*types.Response_PrepareProposal)
case *types.Request_ProcessProposal:
_, ok = res.Value.(*types.Response_ProcessProposal)
}
return ok
}

View File

@@ -83,10 +83,11 @@ var RootCmd = &cobra.Command{
// Structure for data passed to print response.
type response struct {
// generic abci response
Data []byte
Code uint32
Info string
Log string
Data []byte
Code uint32
Info string
Log string
Status int32
Query *queryResponse
}
@@ -138,12 +139,13 @@ func addCommands() {
RootCmd.AddCommand(consoleCmd)
RootCmd.AddCommand(echoCmd)
RootCmd.AddCommand(infoCmd)
RootCmd.AddCommand(setOptionCmd)
RootCmd.AddCommand(deliverTxCmd)
RootCmd.AddCommand(checkTxCmd)
RootCmd.AddCommand(commitCmd)
RootCmd.AddCommand(versionCmd)
RootCmd.AddCommand(testCmd)
RootCmd.AddCommand(prepareProposalCmd)
RootCmd.AddCommand(processProposalCmd)
addQueryFlags()
RootCmd.AddCommand(queryCmd)
@@ -164,7 +166,6 @@ you'd like to run:
where example.file looks something like:
set_option serial on
check_tx 0x00
check_tx 0xff
deliver_tx 0x00
@@ -186,7 +187,7 @@ This command opens an interactive console for running any of the other commands
without opening a new connection each time
`,
Args: cobra.ExactArgs(0),
ValidArgs: []string{"echo", "info", "set_option", "deliver_tx", "check_tx", "commit", "query"},
ValidArgs: []string{"echo", "info", "deliver_tx", "check_tx", "prepare_proposal", "process_proposal", "commit", "query"},
RunE: cmdConsole,
}
@@ -204,13 +205,6 @@ var infoCmd = &cobra.Command{
Args: cobra.ExactArgs(0),
RunE: cmdInfo,
}
var setOptionCmd = &cobra.Command{
Use: "set_option",
Short: "set an option on the application",
Long: "set an option on the application",
Args: cobra.ExactArgs(2),
RunE: cmdSetOption,
}
var deliverTxCmd = &cobra.Command{
Use: "deliver_tx",
@@ -247,6 +241,22 @@ var versionCmd = &cobra.Command{
},
}
var prepareProposalCmd = &cobra.Command{
Use: "prepare_proposal",
Short: "prepare proposal",
Long: "prepare proposal",
Args: cobra.MinimumNArgs(0),
RunE: cmdPrepareProposal,
}
var processProposalCmd = &cobra.Command{
Use: "process_proposal",
Short: "process proposal",
Long: "process proposal",
Args: cobra.MinimumNArgs(0),
RunE: cmdProcessProposal,
}
var queryCmd = &cobra.Command{
Use: "query",
Short: "query the application state",
@@ -304,7 +314,6 @@ func cmdTest(cmd *cobra.Command, args []string) error {
return compose(
[]func() error{
func() error { return servertest.InitChain(client) },
func() error { return servertest.SetOption(client, "serial", "on") },
func() error { return servertest.Commit(client, nil) },
func() error { return servertest.DeliverTx(client, []byte("abc"), code.CodeTypeBadNonce, nil) },
func() error { return servertest.Commit(client, nil) },
@@ -319,6 +328,16 @@ func cmdTest(cmd *cobra.Command, args []string) error {
return servertest.DeliverTx(client, []byte{0x00, 0x00, 0x06}, code.CodeTypeBadNonce, nil)
},
func() error { return servertest.Commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 5}) },
func() error {
return servertest.PrepareProposal(client, [][]byte{
{0x01},
}, [][]byte{{0x01}}, nil)
},
func() error {
return servertest.ProcessProposal(client, [][]byte{
{0x01},
}, types.ResponseProcessProposal_ACCEPT)
},
})
}
@@ -419,8 +438,10 @@ func muxOnCommands(cmd *cobra.Command, pArgs []string) error {
return cmdInfo(cmd, actualArgs)
case "query":
return cmdQuery(cmd, actualArgs)
case "set_option":
return cmdSetOption(cmd, actualArgs)
case "prepare_proposal":
return cmdPrepareProposal(cmd, actualArgs)
case "process_proposal":
return cmdProcessProposal(cmd, actualArgs)
default:
return cmdUnimplemented(cmd, pArgs)
}
@@ -444,7 +465,6 @@ func cmdUnimplemented(cmd *cobra.Command, args []string) error {
fmt.Printf("%s: %s\n", deliverTxCmd.Use, deliverTxCmd.Short)
fmt.Printf("%s: %s\n", queryCmd.Use, queryCmd.Short)
fmt.Printf("%s: %s\n", commitCmd.Use, commitCmd.Short)
fmt.Printf("%s: %s\n", setOptionCmd.Use, setOptionCmd.Short)
fmt.Println("Use \"[command] --help\" for more information about a command.")
return nil
@@ -484,25 +504,6 @@ func cmdInfo(cmd *cobra.Command, args []string) error {
const codeBad uint32 = 10
// Set an option on the application
func cmdSetOption(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
printResponse(cmd, args, response{
Code: codeBad,
Log: "want at least arguments of the form: <key> <value>",
})
return nil
}
key, val := args[0], args[1]
_, err := client.SetOptionSync(types.RequestSetOption{Key: key, Value: val})
if err != nil {
return err
}
printResponse(cmd, args, response{Log: "OK (SetOption doesn't return anything.)"}) // NOTE: Nothing to show...
return nil
}
// Append a new tx to application
func cmdDeliverTx(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
@@ -605,17 +606,75 @@ func cmdQuery(cmd *cobra.Command, args []string) error {
return nil
}
func cmdPrepareProposal(cmd *cobra.Command, args []string) error {
txsBytesArray := make([][]byte, len(args))
for i, arg := range args {
txBytes, err := stringOrHexToBytes(arg)
if err != nil {
return err
}
txsBytesArray[i] = txBytes
}
res, err := client.PrepareProposalSync(types.RequestPrepareProposal{
Txs: txsBytesArray,
// kvstore has to have this parameter in order not to reject a tx as the default value is 0
MaxTxBytes: 65536,
})
if err != nil {
return err
}
resps := make([]response, 0, len(res.Txs))
for _, tx := range res.Txs {
resps = append(resps, response{
Code: code.CodeTypeOK,
Log: "Succeeded. Tx: " + string(tx),
})
}
printResponse(cmd, args, resps...)
return nil
}
func cmdProcessProposal(cmd *cobra.Command, args []string) error {
txsBytesArray := make([][]byte, len(args))
for i, arg := range args {
txBytes, err := stringOrHexToBytes(arg)
if err != nil {
return err
}
txsBytesArray[i] = txBytes
}
res, err := client.ProcessProposalSync(types.RequestProcessProposal{
Txs: txsBytesArray,
})
if err != nil {
return err
}
printResponse(cmd, args, response{
Status: int32(res.Status),
})
return nil
}
func cmdKVStore(cmd *cobra.Command, args []string) error {
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
// Create the application - in memory or persisted to disk
var app types.Application
if flagPersist == "" {
app = kvstore.NewApplication()
} else {
app = kvstore.NewPersistentKVStoreApplication(flagPersist)
app.(*kvstore.PersistentKVStoreApplication).SetLogger(logger.With("module", "kvstore"))
var err error
flagPersist, err = os.MkdirTemp("", "persistent_kvstore_tmp")
if err != nil {
return err
}
}
app = kvstore.NewPersistentKVStoreApplication(flagPersist)
app.(*kvstore.PersistentKVStoreApplication).SetLogger(logger.With("module", "kvstore"))
// Start the listener
srv, err := server.NewServer(flagAddress, flagAbci, app)
@@ -641,44 +700,49 @@ func cmdKVStore(cmd *cobra.Command, args []string) error {
//--------------------------------------------------------------------------------
func printResponse(cmd *cobra.Command, args []string, rsp response) {
func printResponse(cmd *cobra.Command, args []string, rsps ...response) {
if flagVerbose {
fmt.Println(">", cmd.Use, strings.Join(args, " "))
}
// Always print the status code.
if rsp.Code == types.CodeTypeOK {
fmt.Printf("-> code: OK\n")
} else {
fmt.Printf("-> code: %d\n", rsp.Code)
for _, rsp := range rsps {
// Always print the status code.
if rsp.Code == types.CodeTypeOK {
fmt.Printf("-> code: OK\n")
} else {
fmt.Printf("-> code: %d\n", rsp.Code)
}
}
if len(rsp.Data) != 0 {
// Do no print this line when using the commit command
// because the string comes out as gibberish
if cmd.Use != "commit" {
fmt.Printf("-> data: %s\n", rsp.Data)
if len(rsp.Data) != 0 {
// Do no print this line when using the commit command
// because the string comes out as gibberish
if cmd.Use != "commit" {
fmt.Printf("-> data: %s\n", rsp.Data)
}
fmt.Printf("-> data.hex: 0x%X\n", rsp.Data)
}
if rsp.Log != "" {
fmt.Printf("-> log: %s\n", rsp.Log)
}
if cmd.Use == "process_proposal" {
fmt.Printf("-> status: %s\n", types.ResponseProcessProposal_ProposalStatus_name[rsp.Status])
}
fmt.Printf("-> data.hex: 0x%X\n", rsp.Data)
}
if rsp.Log != "" {
fmt.Printf("-> log: %s\n", rsp.Log)
}
if rsp.Query != nil {
fmt.Printf("-> height: %d\n", rsp.Query.Height)
if rsp.Query.Key != nil {
fmt.Printf("-> key: %s\n", rsp.Query.Key)
fmt.Printf("-> key.hex: %X\n", rsp.Query.Key)
}
if rsp.Query.Value != nil {
fmt.Printf("-> value: %s\n", rsp.Query.Value)
fmt.Printf("-> value.hex: %X\n", rsp.Query.Value)
}
if rsp.Query.ProofOps != nil {
fmt.Printf("-> proof: %#v\n", rsp.Query.ProofOps)
if rsp.Query != nil {
fmt.Printf("-> height: %d\n", rsp.Query.Height)
if rsp.Query.Key != nil {
fmt.Printf("-> key: %s\n", rsp.Query.Key)
fmt.Printf("-> key.hex: %X\n", rsp.Query.Key)
}
if rsp.Query.Value != nil {
fmt.Printf("-> value: %s\n", rsp.Query.Value)
fmt.Printf("-> value.hex: %X\n", rsp.Query.Value)
}
if rsp.Query.ProofOps != nil {
fmt.Printf("-> proof: %#v\n", rsp.Query.ProofOps)
}
}
}
}

View File

@@ -7,4 +7,5 @@ const (
CodeTypeBadNonce uint32 = 2
CodeTypeUnauthorized uint32 = 3
CodeTypeUnknownError uint32 = 4
CodeTypeExecuted uint32 = 5
)

View File

@@ -68,6 +68,7 @@ type Application struct {
state State
RetainBlocks int64 // blocks to retain after commit (via ResponseCommit.RetainHeight)
txToRemove map[string]struct{}
}
func NewApplication() *Application {
@@ -78,7 +79,7 @@ func NewApplication() *Application {
func (app *Application) Info(req types.RequestInfo) (resInfo types.ResponseInfo) {
return types.ResponseInfo{
Data: fmt.Sprintf("{\"size\":%v}", app.state.Size),
Version: version.ABCIVersion,
Version: version.ABCISemVer,
AppVersion: ProtocolVersion,
LastBlockHeight: app.state.Height,
LastBlockAppHash: app.state.AppHash,
@@ -87,15 +88,19 @@ func (app *Application) Info(req types.RequestInfo) (resInfo types.ResponseInfo)
// tx is either "key=value" or just arbitrary bytes
func (app *Application) DeliverTx(req types.RequestDeliverTx) types.ResponseDeliverTx {
var key, value []byte
if isReplacedTx(req.Tx) {
app.txToRemove[string(req.Tx)] = struct{}{}
}
var key, value string
parts := bytes.Split(req.Tx, []byte("="))
if len(parts) == 2 {
key, value = parts[0], parts[1]
key, value = string(parts[0]), string(parts[1])
} else {
key, value = req.Tx, req.Tx
key, value = string(req.Tx), string(req.Tx)
}
err := app.state.db.Set(prefixKey(key), value)
err := app.state.db.Set(prefixKey([]byte(key)), []byte(value))
if err != nil {
panic(err)
}
@@ -105,10 +110,10 @@ func (app *Application) DeliverTx(req types.RequestDeliverTx) types.ResponseDeli
{
Type: "app",
Attributes: []types.EventAttribute{
{Key: []byte("creator"), Value: []byte("Cosmoshi Netowoko"), Index: true},
{Key: []byte("key"), Value: key, Index: true},
{Key: []byte("index_key"), Value: []byte("index is working"), Index: true},
{Key: []byte("noindex_key"), Value: []byte("index is working"), Index: false},
{Key: "creator", Value: "Cosmoshi Netowoko", Index: true},
{Key: "key", Value: key, Index: true},
{Key: "index_key", Value: "index is working", Index: true},
{Key: "noindex_key", Value: "index is working", Index: false},
},
},
}
@@ -117,6 +122,11 @@ func (app *Application) DeliverTx(req types.RequestDeliverTx) types.ResponseDeli
}
func (app *Application) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx {
if req.Type == types.CheckTxType_Recheck {
if _, ok := app.txToRemove[string(req.Tx)]; ok {
return types.ResponseCheckTx{Code: code.CodeTypeExecuted, GasWanted: 1}
}
}
return types.ResponseCheckTx{Code: code.CodeTypeOK, GasWanted: 1}
}
@@ -126,6 +136,8 @@ func (app *Application) Commit() types.ResponseCommit {
binary.PutVarint(appHash, app.state.Size)
app.state.AppHash = appHash
app.state.Height++
// empty out the set of transactions to remove via rechecktx
saveState(app.state)
resp := types.ResponseCommit{Data: appHash}
@@ -170,3 +182,18 @@ func (app *Application) Query(reqQuery types.RequestQuery) (resQuery types.Respo
return resQuery
}
func (app *Application) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock {
app.txToRemove = map[string]struct{}{}
return types.ResponseBeginBlock{}
}
func (app *Application) ProcessProposal(
req types.RequestProcessProposal) types.ResponseProcessProposal {
for _, tx := range req.Txs {
if len(tx) == 0 {
return types.ResponseProcessProposal{Status: types.ResponseProcessProposal_REJECT}
}
}
return types.ResponseProcessProposal{Status: types.ResponseProcessProposal_ACCEPT}
}

View File

@@ -2,7 +2,7 @@ package kvstore
import (
"fmt"
"io/ioutil"
"os"
"sort"
"testing"
@@ -71,7 +71,7 @@ func TestKVStoreKV(t *testing.T) {
}
func TestPersistentKVStoreKV(t *testing.T) {
dir, err := ioutil.TempDir("/tmp", "abci-kvstore-test") // TODO
dir, err := os.MkdirTemp("/tmp", "abci-kvstore-test") // TODO
if err != nil {
t.Fatal(err)
}
@@ -87,7 +87,7 @@ func TestPersistentKVStoreKV(t *testing.T) {
}
func TestPersistentKVStoreInfo(t *testing.T) {
dir, err := ioutil.TempDir("/tmp", "abci-kvstore-test") // TODO
dir, err := os.MkdirTemp("/tmp", "abci-kvstore-test") // TODO
if err != nil {
t.Fatal(err)
}
@@ -119,7 +119,7 @@ func TestPersistentKVStoreInfo(t *testing.T) {
// add a validator, remove a validator, update a validator
func TestValUpdates(t *testing.T) {
dir, err := ioutil.TempDir("/tmp", "abci-kvstore-test") // TODO
dir, err := os.MkdirTemp("/tmp", "abci-kvstore-test") // TODO
if err != nil {
t.Fatal(err)
}
@@ -162,7 +162,7 @@ func TestValUpdates(t *testing.T) {
makeApplyBlock(t, kvstore, 2, diff, tx1, tx2, tx3)
vals1 = append(vals[:nInit-2], vals[nInit+1]) // nolint: gocritic
vals1 = append(vals[:nInit-2], vals[nInit+1]) //nolint: gocritic
vals2 = kvstore.Validators()
valsEqual(t, vals1, vals2)

View File

@@ -45,7 +45,10 @@ func NewPersistentKVStoreApplication(dbDir string) *PersistentKVStoreApplication
state := loadState(db)
return &PersistentKVStoreApplication{
app: &Application{state: state},
app: &Application{
state: state,
txToRemove: map[string]struct{}{},
},
valAddrToPubKeyMap: make(map[string]pc.PublicKey),
logger: log.NewNopLogger(),
}
@@ -62,10 +65,6 @@ func (app *PersistentKVStoreApplication) Info(req types.RequestInfo) types.Respo
return res
}
func (app *PersistentKVStoreApplication) SetOption(req types.RequestSetOption) types.ResponseSetOption {
return app.app.SetOption(req)
}
// tx is either "val:pubkey!power" or "key=value" or just arbitrary bytes
func (app *PersistentKVStoreApplication) DeliverTx(req types.RequestDeliverTx) types.ResponseDeliverTx {
// if it starts with "val:", update the validator set
@@ -76,6 +75,10 @@ func (app *PersistentKVStoreApplication) DeliverTx(req types.RequestDeliverTx) t
return app.execValidatorTx(req.Tx)
}
if isPrepareTx(req.Tx) {
return app.execPrepareTx(req.Tx)
}
// otherwise, update the key-value store
return app.app.DeliverTx(req)
}
@@ -126,7 +129,7 @@ func (app *PersistentKVStoreApplication) BeginBlock(req types.RequestBeginBlock)
// Punish validators who committed equivocation.
for _, ev := range req.ByzantineValidators {
if ev.Type == types.EvidenceType_DUPLICATE_VOTE {
if ev.Type == types.MisbehaviorType_DUPLICATE_VOTE {
addr := string(ev.Validator.Address)
if pubKey, ok := app.valAddrToPubKeyMap[addr]; ok {
app.updateValidator(types.ValidatorUpdate{
@@ -142,7 +145,7 @@ func (app *PersistentKVStoreApplication) BeginBlock(req types.RequestBeginBlock)
}
}
return types.ResponseBeginBlock{}
return app.app.BeginBlock(req)
}
// Update the validator set
@@ -170,6 +173,21 @@ func (app *PersistentKVStoreApplication) ApplySnapshotChunk(
return types.ResponseApplySnapshotChunk{Result: types.ResponseApplySnapshotChunk_ABORT}
}
func (app *PersistentKVStoreApplication) PrepareProposal(
req types.RequestPrepareProposal) types.ResponsePrepareProposal {
return types.ResponsePrepareProposal{Txs: app.substPrepareTx(req.Txs, req.MaxTxBytes)}
}
func (app *PersistentKVStoreApplication) ProcessProposal(
req types.RequestProcessProposal) types.ResponseProcessProposal {
for _, tx := range req.Txs {
if len(tx) == 0 || isPrepareTx(tx) {
return types.ResponseProcessProposal{Status: types.ResponseProcessProposal_REJECT}
}
}
return types.ResponseProcessProposal{Status: types.ResponseProcessProposal_ACCEPT}
}
//---------------------------------------------
// update validators
@@ -284,3 +302,42 @@ func (app *PersistentKVStoreApplication) updateValidator(v types.ValidatorUpdate
return types.ResponseDeliverTx{Code: code.CodeTypeOK}
}
// -----------------------------
const (
PreparePrefix = "prepare"
ReplacePrefix = "replace"
)
func isPrepareTx(tx []byte) bool { return bytes.HasPrefix(tx, []byte(PreparePrefix)) }
func isReplacedTx(tx []byte) bool {
return bytes.HasPrefix(tx, []byte(ReplacePrefix))
}
// execPrepareTx is noop. tx data is considered as placeholder
// and is substitute at the PrepareProposal.
func (app *PersistentKVStoreApplication) execPrepareTx(tx []byte) types.ResponseDeliverTx {
// noop
return types.ResponseDeliverTx{}
}
// substPrepareTx substitutes all the transactions prefixed with 'prepare' in the
// proposal for transactions with the prefix stripped.
func (app *PersistentKVStoreApplication) substPrepareTx(blockData [][]byte, maxTxBytes int64) [][]byte {
txs := make([][]byte, 0, len(blockData))
var totalBytes int64
for _, tx := range blockData {
txMod := tx
if isPrepareTx(tx) {
txMod = bytes.Replace(tx, []byte(PreparePrefix), []byte(ReplacePrefix), 1)
}
totalBytes += int64(len(txMod))
if totalBytes > maxTxBytes {
break
}
txs = append(txs, txMod)
}
return txs
}

View File

@@ -0,0 +1,573 @@
package orderbook
import (
"bytes"
"encoding/binary"
fmt "fmt"
"github.com/cosmos/gogoproto/proto"
dbm "github.com/tendermint/tm-db"
"github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/tmhash"
)
var _ types.Application = (*StateMachine)(nil)
const Version = 1
const (
// In tendermint a zero code is okay and all non zero codes are errors
StatusOK = iota
StatusErrDecoding
StatusErrUnknownMessage
StatusErrValidateBasic
StatusErrNoAccount
StatusErrAccountExists
StatusErrNoPair
StatusErrPairExists
StatusErrInvalidOrder
StatusErrUnacceptableMessage
StatusErrNoCommodity
)
var (
stateKey = []byte("state")
accountKey = []byte("account")
pairKey = []byte("pair")
)
// StateMachine is the main struct that encompasses the logic of the orderbook
type StateMachine struct {
// inherit all the abci methods so we don't have to implement everything
types.BaseApplication
// persisted state which is a key value store containing:
// accountID -> account
// pairID -> pair
db dbm.DB
// in-memory state
lastHeight int64 // the last height that was persisted
lastHash []byte // the last hash that was persisted
// list of accounts (this is used for the app hash)
accounts []*Account
pairs map[string]*Pair // lookup pairs
commodities map[string]struct{} // lookup commodities
publicKeys map[string]struct{} // lookup existence of an account
// a list of transactions that have been modified by the most recent block
// and will need to result in an update to the db
touchedAccounts map[uint64]struct{}
// new pairs added in this block which will needed to be added to the
// db on "Commit"
newPairs []*Pair
// app-side mempool (also emphemeral)
// this takes ask and bid transactions from `CheckTx`
// and matches them as a "MatchedOrder" which is
// then proposed in a block
//
// it's important to note that there is no garbage collection
// here. Bids and asks, potentially even invalid, will
// continue to stay here until matched
markets map[string]*Market // i.e. ATOM/USDC
}
// New creates a StateMachine from a given database. If the database is
// empty a fresh instance is created else the accounts, pairs and
// state are loaded into memory.
func New(db dbm.DB) (*StateMachine, error) {
// iterate over all the account keys
iter, err := db.Iterator(nil, nil)
if err != nil {
return nil, err
}
defer iter.Close()
var (
accounts = make([]*Account, 0)
publicKeys = make(map[string]struct{})
commodities = make(map[string]struct{})
pairs = make(map[string]*Pair)
markets = make(map[string]*Market)
lastHeight uint64
lastHash []byte
)
for ; iter.Valid(); iter.Next() {
if bytes.HasPrefix(iter.Key(), pairKey) {
var pair Pair
if err := proto.Unmarshal(iter.Value(), &pair); err != nil {
return nil, err
}
pairs[pair.String()] = &pair
commodities[pair.BuyersDenomination] = struct{}{}
markets[pair.String()] = NewMarket(&pair)
}
if bytes.HasPrefix(iter.Key(), accountKey) {
var acc Account
if err := proto.Unmarshal(iter.Value(), &acc); err != nil {
return nil, err
}
accounts = append(accounts, &acc)
publicKeys[string(acc.PublicKey)] = struct{}{}
}
if bytes.HasPrefix(iter.Key(), stateKey) {
state := iter.Value()
lastHeight = binary.BigEndian.Uint64(state[:4])
lastHash = state[4:]
}
}
return &StateMachine{
accounts: accounts,
pairs: pairs,
commodities: commodities,
publicKeys: publicKeys,
markets: markets,
lastHeight: int64(lastHeight),
lastHash: lastHash,
db: db,
touchedAccounts: make(map[uint64]struct{}),
newPairs: make([]*Pair, 0),
}, nil
}
// Info is used by Tendermint to understand the state of the application.
// This is useful for replay and syncing modes.
func (sm *StateMachine) Info(req types.RequestInfo) types.ResponseInfo {
return types.ResponseInfo{
AppVersion: Version,
LastBlockHeight: sm.lastHeight,
LastBlockAppHash: sm.lastHash,
}
}
// CheckTx indicates which transactions should be accepted in the mempool. It is
// not a perfect validity check because we're unsure of the state that the transaction
// will be executed against. We should treat this as a gatekeeper to the mempool.
// Apart from adding transactions to the app-side mempool, this check is stateless.
func (sm *StateMachine) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx {
var msg = new(Msg)
err := proto.Unmarshal(req.Tx, msg)
if err != nil {
return types.ResponseCheckTx{Code: StatusErrDecoding, Log: err.Error()} // decoding error
}
if err := msg.ValidateBasic(); err != nil {
return types.ResponseCheckTx{Code: StatusErrValidateBasic, Log: err.Error()}
}
// add either bids or asks to the market which will match them in PrepareProposal
switch m := msg.Sum.(type) {
case *Msg_MsgAsk:
market, ok := sm.markets[m.MsgAsk.Pair.String()]
if !ok {
return types.ResponseCheckTx{Code: StatusErrNoPair}
}
market.AddAsk(m.MsgAsk.AskOrder)
case *Msg_MsgBid:
market, ok := sm.markets[m.MsgBid.Pair.String()]
if !ok {
return types.ResponseCheckTx{Code: StatusErrNoPair}
}
market.AddBid(m.MsgBid.BidOrder)
}
return types.ResponseCheckTx{Code: StatusOK}
}
// ValidateTx validates the transactions against state.
func (sm *StateMachine) ValidateTx(msg *Msg) uint32 {
if err := msg.ValidateBasic(); err != nil {
return StatusErrValidateBasic
}
switch m := msg.Sum.(type) {
case *Msg_MsgRegisterPair:
pair := m.MsgRegisterPair.Pair
if _, ok := sm.pairs[pair.String()]; ok {
return StatusErrPairExists
}
reversePair := &Pair{BuyersDenomination: pair.SellersDenomination, SellersDenomination: pair.BuyersDenomination}
if _, ok := sm.pairs[reversePair.String()]; ok {
return StatusErrPairExists
}
case *Msg_MsgAsk, *Msg_MsgBid: // MsgAsk and MsgBid are not allowed individually - they need to be matched as a TradeSet
return StatusErrUnacceptableMessage //Todo add logic around msg ask and bid to allow
case *Msg_MsgCreateAccount:
// check for duplicate accounts in state machine
if _, ok := sm.publicKeys[string(m.MsgCreateAccount.PublicKey)]; ok {
return StatusErrAccountExists
}
// check that each of the commodities is present in at least one trading pair
for _, commodity := range m.MsgCreateAccount.Commodities {
if _, exists := sm.commodities[commodity.Denom]; !exists {
return StatusErrNoCommodity
}
}
case *Msg_MsgTradeSet:
// check the pair exists
if _, ok := sm.pairs[m.MsgTradeSet.TradeSet.Pair.String()]; !ok {
return StatusErrNoPair
}
for _, order := range m.MsgTradeSet.TradeSet.MatchedOrders {
// validate matched order i.e. users have funds and signatures are valid
if !sm.isMatchedOrderValid(order, m.MsgTradeSet.TradeSet.Pair) {
return StatusErrInvalidOrder
}
}
default:
return StatusErrUnknownMessage
}
return StatusOK
}
// PrepareProposal is called whenever the validator is the proposer for that round. First, it adds the non order
// transactions provided by tendermint. The orderbook then loops through each market and tries to match as many
// transactions as possible. For each new transaction it checks that the max bytes has not been exceeded.
func (sm *StateMachine) PrepareProposal(req types.RequestPrepareProposal) types.ResponsePrepareProposal {
// declare transaction with the size of 0
txs := make([][]byte, 0)
// go through the transactions passed up via Tendermint first
for _, tx := range req.Txs {
var msg = new(Msg)
err := proto.Unmarshal(tx, msg)
if err != nil {
panic(err)
}
// skip over the bids and asks that are proposed. We already have them
if _, ok := msg.Sum.(*Msg_MsgBid); ok {
continue
}
if _, ok := msg.Sum.(*Msg_MsgAsk); ok {
continue
}
// make sure we're proposing valid transactions
if status := sm.ValidateTx(msg); status != StatusOK {
continue
}
if len(txs)+len(tx) > int(req.MaxTxBytes) {
return types.ResponsePrepareProposal{Txs: txs}
}
txs = append(txs, tx)
}
// fetch and match all the bids and asks for each market and add these
for _, market := range sm.markets {
tradeSet := market.Match()
// tradesets into bytes and bytes into a transaction
if tradeSet == nil {
continue
}
fmt.Println("we have a tradeset")
tradeSet = sm.validateTradeSetAgainstState(tradeSet)
if tradeSet == nil || len(tradeSet.MatchedOrders) == 0 {
continue
}
fmt.Println("we have a valid tradeset")
// wrap this as a message typ
msgTradeSet := &MsgTradeSet{TradeSet: tradeSet}
bz, err := proto.Marshal(msgTradeSet)
if err != nil {
panic(err)
}
// check to see that we don't over populate the block
if len(txs)+len(bz) > int(req.MaxTxBytes) {
return types.ResponsePrepareProposal{Txs: txs}
}
txs = append(txs, bz)
}
return types.ResponsePrepareProposal{Txs: req.Txs}
}
// Process Proposal either rejects or accepts transactions
//
// It uses the same validity function for prepare proposal. This ensures the coherence property
// is adhered to i.e. all honest validators must accept a proposal by an honest proposer
func (sm *StateMachine) ProcessProposal(req types.RequestProcessProposal) types.ResponseProcessProposal {
for _, tx := range req.Txs {
var msg = new(Msg)
err := proto.Unmarshal(tx, msg)
if err != nil {
return rejectProposal()
}
if status := sm.ValidateTx(msg); status != StatusOK {
fmt.Printf("tx failed validation, status: %d\n", status)
return rejectProposal()
}
}
return acceptProposal()
}
func (sm *StateMachine) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock {
// reset the new pairs
sm.newPairs = make([]*Pair, 0)
return types.ResponseBeginBlock{}
}
// DeliverTx is called for each tx in a block once it has been finalized. This is where the
// execution code lives. Most importantly it's where we update the user accounts following
// a successful order.
func (sm *StateMachine) DeliverTx(req types.RequestDeliverTx) types.ResponseDeliverTx {
var msg = new(Msg)
err := proto.Unmarshal(req.Tx, msg)
if err != nil {
return types.ResponseDeliverTx{Code: StatusErrDecoding, Log: err.Error()} // decoding error
}
if status := sm.ValidateTx(msg); status != StatusOK {
return types.ResponseDeliverTx{Code: status}
}
switch m := msg.Sum.(type) {
case *Msg_MsgRegisterPair:
sm.markets[m.MsgRegisterPair.Pair.String()] = NewMarket(m.MsgRegisterPair.Pair)
sm.pairs[m.MsgRegisterPair.Pair.String()] = m.MsgRegisterPair.Pair
sm.commodities[m.MsgRegisterPair.Pair.BuyersDenomination] = struct{}{}
sm.commodities[m.MsgRegisterPair.Pair.SellersDenomination] = struct{}{}
sm.newPairs = append(sm.newPairs, m.MsgRegisterPair.Pair)
case *Msg_MsgCreateAccount:
nextAccountID := uint64(len(sm.accounts))
sm.accounts = append(sm.accounts, &Account{
Index: nextAccountID,
PublicKey: m.MsgCreateAccount.PublicKey,
Commodities: m.MsgCreateAccount.Commodities,
})
sm.touchedAccounts[nextAccountID] = struct{}{}
sm.publicKeys[string(m.MsgCreateAccount.PublicKey)] = struct{}{}
case *Msg_MsgTradeSet:
pair := m.MsgTradeSet.TradeSet.Pair
for _, order := range m.MsgTradeSet.TradeSet.MatchedOrders {
buyer := sm.accounts[order.OrderBid.OwnerId]
seller := sm.accounts[order.OrderAsk.OwnerId]
// the buyer gets quantity of the asset that the seller was selling
buyer.AddCommodity(NewCommodity(pair.SellersDenomination, order.OrderAsk.Quantity))
// the buyer gives up quantity * ask price of the buyers denomination
buyer.SubtractCommodity(NewCommodity(pair.BuyersDenomination, order.OrderAsk.Quantity*order.OrderAsk.AskPrice))
// the seller gets quantity * ask price of the asset that the buyer was paying with
seller.AddCommodity(NewCommodity(pair.BuyersDenomination, order.OrderAsk.Quantity*order.OrderAsk.AskPrice))
// the seller gives up quantity of the commodity they were selling
seller.SubtractCommodity(NewCommodity(pair.SellersDenomination, order.OrderAsk.Quantity))
// mark that these account have been touched
sm.touchedAccounts[order.OrderBid.OwnerId] = struct{}{}
sm.touchedAccounts[order.OrderAsk.OwnerId] = struct{}{}
}
default:
return types.ResponseDeliverTx{Code: StatusErrUnknownMessage}
}
return types.ResponseDeliverTx{Code: 0}
}
// EndBlock is used to update consensus params and the validator set. For the orderbook,
// we keep both the same for thw
func (sm *StateMachine) EndBlock(req types.RequestEndBlock) types.ResponseEndBlock {
return types.ResponseEndBlock{}
}
// Commit is called to tell the app it is safe to persist state to disk.
// We now take the in-memory representation and update the parts that have
// changed on to disk.
func (sm *StateMachine) Commit() types.ResponseCommit {
batch := sm.db.NewBatch()
// write to accounts that were modified by the last block
for accountID := range sm.touchedAccounts {
value, err := proto.Marshal(sm.accounts[accountID])
if err != nil {
panic(err)
}
key := binary.BigEndian.AppendUint64(accountKey, accountID)
if err := batch.Set(key, value); err != nil {
panic(err)
}
}
// write the new pairs that were added by the last block
pairID := len(sm.pairs) - len(sm.newPairs)
for id, pair := range sm.newPairs {
value, err := proto.Marshal(pair)
if err != nil {
panic(err)
}
key := binary.BigEndian.AppendUint64(pairKey, uint64(pairID+id))
if err := batch.Set(key, value); err != nil {
panic(err)
}
}
hash := sm.hash()
err := sm.updateState(batch, sm.lastHeight+1, hash)
if err != nil {
panic(err)
}
err = batch.WriteSync()
if err != nil {
panic(err)
}
return types.ResponseCommit{Data: hash}
}
// hash is just the the sha256 of the byte representation of all accounts.
// remember that this needs to be deterministic for all state machines
func (sm *StateMachine) hash() []byte {
digest := bytes.NewBuffer(nil)
for _, account := range sm.accounts {
bz, err := proto.Marshal(account)
if err != nil {
panic(err)
}
digest.Write(bz)
}
return tmhash.Sum(digest.Bytes())
}
func (sm *StateMachine) updateState(batch dbm.Batch, height int64, hash []byte) error {
sm.lastHash = hash
sm.lastHeight = height
heightBytes := make([]byte, 8)
binary.BigEndian.PutUint64(heightBytes, uint64(height))
return batch.Set(stateKey, append(heightBytes, hash...))
}
func (sm *StateMachine) validateTradeSetAgainstState(tradeSet *TradeSet) *TradeSet {
output := &TradeSet{Pair: tradeSet.Pair}
for _, matchedOrder := range tradeSet.MatchedOrders {
if !sm.isMatchedOrderValid(matchedOrder, tradeSet.Pair) {
continue
}
// yayy! this matched order is still valid and can be executed
output.MatchedOrders = append(output.MatchedOrders, matchedOrder)
}
return output
}
// isMatchedOrderValid is a check against current state to ensure that the order
// is valid and can execute.
//
// This method is also called when preparing a proposal since `CheckTx` doesn't have
// strict validity guarantees and there could be invalid transactions within the mempool
//
// Note: if one of the two orders are invalid we discard both. In the future we could
// improve this by adding back the part of the order that might still be valid.
func (sm *StateMachine) isMatchedOrderValid(order *MatchedOrder, pair *Pair) bool {
if int(order.OrderBid.OwnerId) >= len(sm.accounts) {
return false
}
bidOwner := sm.accounts[order.OrderBid.OwnerId]
if bidOwner == nil {
return false
}
if int(order.OrderAsk.OwnerId) >= len(sm.accounts) {
return false
}
askOwner := sm.accounts[order.OrderAsk.OwnerId]
if askOwner == nil {
return false
}
askCommodities := askOwner.FindCommidity(pair.SellersDenomination)
if askCommodities == nil {
return false
}
buyCommodities := bidOwner.FindCommidity(pair.BuyersDenomination)
if buyCommodities == nil {
return false
}
// Seller has enough of the commodity
if askCommodities.Quantity-order.OrderAsk.Quantity < 0 {
return false
}
// Buyer has enough of the buying commodity
if buyCommodities.Quantity-(order.OrderAsk.AskPrice*order.OrderAsk.Quantity) < 0 {
return false
}
if !order.OrderAsk.ValidateSignature(ed25519.PubKey(askOwner.PublicKey), pair) {
return false
}
if !order.OrderBid.ValidateSignature(ed25519.PubKey(bidOwner.PublicKey), pair) {
return false
}
return true
}
// InitDB takes an empty DB instance and populates it with the
// provided pairs and accounts. Note that the order here is important
func InitDB(db dbm.DB, pairs []*Pair, accounts []*Account) error {
batch := db.NewBatch()
for id, account := range accounts {
value, err := proto.Marshal(account)
if err != nil {
return err
}
key := binary.BigEndian.AppendUint64(accountKey, uint64(id))
if err := batch.Set(key, value); err != nil {
return err
}
}
for id, pair := range pairs {
value, err := proto.Marshal(pair)
if err != nil {
return err
}
key := binary.BigEndian.AppendUint64(pairKey, uint64(id))
fmt.Println(key)
if err := batch.Set(key, value); err != nil {
return err
}
}
return batch.WriteSync()
}
func rejectProposal() types.ResponseProcessProposal {
return types.ResponseProcessProposal{Status: types.ResponseProcessProposal_REJECT}
}
func acceptProposal() types.ResponseProcessProposal {
return types.ResponseProcessProposal{Status: types.ResponseProcessProposal_ACCEPT}
}

View File

@@ -0,0 +1,327 @@
package orderbook_test
import (
fmt "fmt"
"testing"
"github.com/cosmos/gogoproto/proto"
"github.com/stretchr/testify/require"
dbm "github.com/tendermint/tm-db"
"github.com/tendermint/tendermint/abci/example/orderbook"
"github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
params "github.com/tendermint/tendermint/types"
)
// TODO: we should also check that CheckTx adds bids and asks to the app-side mempool
func TestCheckTx(t *testing.T) {
db := dbm.NewMemDB()
require.NoError(t, orderbook.InitDB(db, []*orderbook.Pair{testPair}, nil))
app, err := orderbook.New(db)
require.NoError(t, err)
testCases := []struct {
name string
msg *orderbook.Msg
responseCode uint32
expOrderSize int
}{
{
name: "test empty tx",
msg: &orderbook.Msg{},
responseCode: orderbook.StatusErrValidateBasic,
expOrderSize: 0,
},
{
name: "test msg ask",
msg: &orderbook.Msg{
Sum: &orderbook.Msg_MsgAsk{
MsgAsk: &orderbook.MsgAsk{
Pair: testPair,
AskOrder: &orderbook.OrderAsk{
Quantity: 10,
AskPrice: 1,
OwnerId: 1,
Signature: crypto.CRandBytes(ed25519.SignatureSize),
},
},
},
},
responseCode: orderbook.StatusOK,
expOrderSize: 1,
},
{
name: "test msg ask wrong signature",
msg: &orderbook.Msg{
Sum: &orderbook.Msg_MsgAsk{
MsgAsk: &orderbook.MsgAsk{
Pair: testPair,
AskOrder: &orderbook.OrderAsk{
Quantity: 10,
AskPrice: 1,
OwnerId: 1,
Signature: crypto.CRandBytes(62),
},
},
},
},
responseCode: orderbook.StatusErrValidateBasic,
expOrderSize: 1,
},
{
name: "test msg bid",
msg: &orderbook.Msg{Sum: &orderbook.Msg_MsgBid{MsgBid: &orderbook.MsgBid{
Pair: testPair,
BidOrder: &orderbook.OrderBid{
MaxQuantity: 15,
MaxPrice: 5,
OwnerId: 1,
Signature: crypto.CRandBytes(ed25519.SignatureSize),
},
}}},
responseCode: orderbook.StatusOK,
expOrderSize: 2,
},
{
name: "test msg bid blank",
msg: &orderbook.Msg{Sum: &orderbook.Msg_MsgBid{MsgBid: &orderbook.MsgBid{
Pair: testPair,
BidOrder: &orderbook.OrderBid{
MaxQuantity: 0,
MaxPrice: 0,
OwnerId: 0,
Signature: crypto.CRandBytes(ed25519.SignatureSize),
},
}}},
responseCode: orderbook.StatusErrValidateBasic,
expOrderSize: 2,
},
{
name: "test msg register duplicate pair",
msg: &orderbook.Msg{Sum: &orderbook.Msg_MsgRegisterPair{MsgRegisterPair: &orderbook.MsgRegisterPair{
Pair: &orderbook.Pair{BuyersDenomination: "ATOM", SellersDenomination: "ATOM"},
}}},
responseCode: orderbook.StatusErrValidateBasic,
expOrderSize: 2,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
bz, err := proto.Marshal(tc.msg)
require.NoError(t, err)
resp := app.CheckTx(types.RequestCheckTx{Tx: bz})
require.Equal(t, tc.responseCode, resp.Code, resp.Log)
bids, asks := app.Orders(testPair)
require.Equal(t, tc.expOrderSize, len(bids)+len(asks))
})
}
}
// func ValidateTx(t *testing.T) {
// db := dbm.NewMemDB()
// require.NoError(t, orderbook.InitDB(db, []*orderbook.Pair{testPair}, nil))
// app, err := orderbook.New(db)
// require.NoError(t, err)
// for _, tc := range testCases {
// t.Run(tc.name, func(t *testing.T) {
// bz, err := proto.Marshal(tc.msg)
// require.NoError(t, err)
// resp := app.CheckTx(types.RequestCheckTx{Tx: bz})
// require.Equal(t, tc.responseCode, resp.Code, resp.Log)
// bids, asks := app.Orders(testPair)
// require.Equal(t, tc.expOrderSize, len(bids)+len(asks))
// })
// }
// }
// TODO: we should check that transactions in
// a market are being validated and added to the proposal
// // and that other transactions get in
// func TestPrepareProposal(t *testing.T) {
// db := dbm.NewMemDB()
// require.NoError(t, orderbook.InitDB(db, []*orderbook.Pair{testPair}, nil))
// app, err := orderbook.New(db)
// require.NoError(t, err)
// for _, tc := range testCases {
// t.Run(tc.name, func(t *testing.T) {
// bz, err := proto.Marshal(tc.msg)
// require.NoError(t, err)
// resp := app.CheckTx(types.RequestCheckTx{Tx: bz})
// require.Equal(t, tc.responseCode, resp.Code, resp.Log)
// bids, asks := app.Orders(testPair)
// require.Equal(t, tc.expOrderSize, len(bids)+len(asks))
// })
// }
// }
// {
// name: "test msg register pair",
// msg: &orderbook.Msg{Sum: &orderbook.Msg_MsgRegisterPair{MsgRegisterPair: &orderbook.MsgRegisterPair{
// Pair: &orderbook.Pair{BuyersDenomination: "ATOM", SellersDenomination: "AUD"},
// }}},
// responseCode: orderbook.StatusOK,
// expOrderSize: 2,
// pairSize: 2,
// },
// TODO: we should test that transactions are
// always valid i.e. ValidateTx. We could potentially
// combine this with PrepareProposal
// func TestProcessProposal(t *testing.T) {
// app := orderbook.New(dbm.NewMemDB())
// }
// TODO: we should test that a matched order
// correctly updates the accounts. We should
// also test that committing a block persists
// it to the database and that we can now
// query the new state
// func TestFinalizeBlock(t *testing.T) {
// app := orderbook.New(dbm.NewMemDB())
// }
// TODO: test that we can start from new
// and from existing state
// func TestNewStateMachine(t *testing.T) {}
func TestEndToEnd(t *testing.T) {
db := dbm.NewMemDB()
app, err := orderbook.New(db)
require.NoError(t, err)
var (
maxBytes = params.DefaultConsensusParams().Block.MaxBytes
commodityNZD = &orderbook.Commodity{Denom: "NZD", Quantity: 100}
commodityAUD = &orderbook.Commodity{Denom: "AUD", Quantity: 100}
registerPairMsg = newRegisterPair("NZD", "AUD")
pair = registerPairMsg.GetMsgRegisterPair().Pair
pkAlice = ed25519.GenPrivKey()
pkBob = ed25519.GenPrivKey()
pubKeyAlice = pkAlice.PubKey().Bytes()
pubKeyBob = pkBob.PubKey().Bytes()
registerAlice = newRegisterAccount(pubKeyAlice, []*orderbook.Commodity{commodityAUD})
registerBob = newRegisterAccount(pubKeyBob, []*orderbook.Commodity{commodityNZD})
// bob is asking for 25 AUD for 5 NZD
ask = &orderbook.Msg{Sum: &orderbook.Msg_MsgAsk{MsgAsk: orderbook.NewMsgAsk(pair, 5, 5, 1)}}
// alice is bidding for 5 NZD for 25 AUD
bid = &orderbook.Msg{Sum: &orderbook.Msg_MsgBid{MsgBid: orderbook.NewMsgBid(pair, 5, 5, 0)}}
)
require.NoError(t, ask.GetMsgAsk().Sign(pkBob))
require.NoError(t, bid.GetMsgBid().Sign(pkAlice))
testCases := []struct {
txs [][]byte
accepted bool
// assertions to be made about the state of the application
// after each block
assertions func(t *testing.T, app *orderbook.StateMachine)
}{
{
// block 1 sets up the trading pair
txs: asTxs(registerPairMsg),
accepted: true,
assertions: func(t *testing.T, app *orderbook.StateMachine) {
pairs := app.Pairs()
require.Len(t, pairs, 1)
require.Equal(t, pair, &pairs[0])
},
},
{
// block 2 registers two accounts: alice and bob
txs: asTxs(registerAlice, registerBob),
accepted: true,
assertions: func(t *testing.T, app *orderbook.StateMachine) {
alice := app.Account(0)
require.False(t, alice.IsEmpty(), alice)
require.Equal(t, pubKeyAlice, alice.PublicKey)
require.Len(t, alice.Commodities, 1)
require.Equal(t, alice.Commodities[0], commodityAUD)
bob := app.Account(1)
require.False(t, bob.IsEmpty(), bob)
require.Equal(t, pubKeyBob, bob.PublicKey)
require.Len(t, bob.Commodities, 1)
require.Equal(t, bob.Commodities[0], commodityNZD)
require.True(t, app.Account(2).IsEmpty())
},
},
{
// block 3 performs a trade between alice and bob
txs: asTxs(ask, bid),
accepted: true,
assertions: func(t *testing.T, app *orderbook.StateMachine) {
alice := app.Account(0)
require.Equal(t, alice.Commodities[0].Quantity, 75) // 75 AUD
require.Equal(t, alice.Commodities[1].Quantity, 5) // 5 NZD
bob := app.Account(1)
require.Equal(t, bob.Commodities[0].Quantity, 95) // 95 NZD
require.Equal(t, bob.Commodities[0].Quantity, 5) // 5 AUD
},
},
}
for idx, tc := range testCases {
for _, tx := range tc.txs {
resp := app.CheckTx(types.RequestCheckTx{Tx: tx})
require.EqualValues(t, orderbook.StatusOK, resp.Code)
}
txs := app.PrepareProposal(types.RequestPrepareProposal{MaxTxBytes: maxBytes, Txs: tc.txs}).Txs
require.Equal(t, txs, tc.txs)
if idx == 2 {
fmt.Print(tc.txs)
fmt.Println()
fmt.Print(txs)
}
result := app.ProcessProposal(types.RequestProcessProposal{Txs: txs})
if tc.accepted {
require.Equal(t, types.ResponseProcessProposal_ACCEPT, result.Status)
} else {
require.Equal(t, types.ResponseProcessProposal_REJECT, result.Status)
continue
}
app.BeginBlock(types.RequestBeginBlock{})
for _, tx := range txs {
app.DeliverTx(types.RequestDeliverTx{Tx: tx})
}
app.EndBlock(types.RequestEndBlock{})
app.Commit()
if tc.assertions != nil {
tc.assertions(t, app)
}
}
}
func asTxs(msgs ...*orderbook.Msg) [][]byte {
output := make([][]byte, len(msgs))
for i, msg := range msgs {
bz, err := proto.Marshal(msg)
if err != nil {
panic(err)
}
output[i] = bz
}
return output
}
func newRegisterPair(d1, d2 string) *orderbook.Msg {
return &orderbook.Msg{Sum: &orderbook.Msg_MsgRegisterPair{MsgRegisterPair: &orderbook.MsgRegisterPair{
Pair: &orderbook.Pair{BuyersDenomination: d1, SellersDenomination: d2},
}}}
}
func newRegisterAccount(pubkey []byte, commodities []*orderbook.Commodity) *orderbook.Msg {
return &orderbook.Msg{Sum: &orderbook.Msg_MsgCreateAccount{MsgCreateAccount: &orderbook.MsgCreateAccount{
PublicKey: pubkey,
Commodities: commodities,
}}}
}

View File

@@ -0,0 +1,9 @@
version: v1
plugins:
- name: gogofaster
out: .
opt:
- Mgoogle/protobuf/timestamp.proto=github.com/cosmos/gogoproto/types
- Mgoogle/protobuf/duration.proto=github.com/golang/protobuf/ptypes/duration
- plugins=grpc
- paths=source_relative

View File

@@ -0,0 +1,243 @@
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/abci/example/orderbook"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/libs/log"
tmos "github.com/tendermint/tendermint/libs/os"
tmrand "github.com/tendermint/tendermint/libs/rand"
"github.com/tendermint/tendermint/node"
"github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/privval"
"github.com/tendermint/tendermint/proxy"
"github.com/tendermint/tendermint/types"
tmtime "github.com/tendermint/tendermint/types/time"
)
func main() {
NewCLI().Run()
}
type CLI struct {
root *cobra.Command
config *cfg.Config
}
func NewCLI() *CLI {
cli := &CLI{}
cli.root = &cobra.Command{
Use: "orderbook",
Short: "orderbook abci++ example",
}
cli.root.AddCommand(&cobra.Command{
Use: "init",
Short: "initialize the file system for an orderbook node",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
root, err := os.Getwd()
if err != nil {
return err
}
viper.AddConfigPath(filepath.Join(root, "config"))
viper.SetConfigName("config")
config := cfg.DefaultConfig()
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// Config file not found; use default
// This often happens when initializing a config for the first time
} else {
return err
}
} else {
if err := viper.Unmarshal(config); err != nil {
return err
}
}
config.SetRoot(root)
cli.config = config
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
privValKeyFile := cli.config.PrivValidatorKeyFile()
privValStateFile := cli.config.PrivValidatorStateFile()
var pv *privval.FilePV
if tmos.FileExists(privValKeyFile) {
pv = privval.LoadFilePV(privValKeyFile, privValStateFile)
fmt.Print("found private validator", "keyFile", privValKeyFile,
"stateFile", privValStateFile)
} else {
pv = privval.GenFilePV(privValKeyFile, privValStateFile)
pv.Save()
fmt.Print("Generated private validator", "keyFile", privValKeyFile,
"stateFile", privValStateFile)
}
nodeKeyFile := cli.config.NodeKeyFile()
if tmos.FileExists(nodeKeyFile) {
fmt.Print("Found node key", "path", nodeKeyFile)
} else {
if _, err := p2p.LoadOrGenNodeKey(nodeKeyFile); err != nil {
return err
}
fmt.Print("Generated node key", "path", nodeKeyFile)
}
// genesis file
genFile := cli.config.GenesisFile()
if tmos.FileExists(genFile) {
fmt.Print("Found genesis file", "path", genFile)
} else {
genDoc := types.GenesisDoc{
ChainID: fmt.Sprintf("orderbook-chain-%v", tmrand.Int()),
GenesisTime: tmtime.Now(),
ConsensusParams: types.DefaultConsensusParams(),
}
pubKey, err := pv.GetPubKey()
if err != nil {
return fmt.Errorf("can't get pubkey: %w", err)
}
genDoc.Validators = []types.GenesisValidator{{
Address: pubKey.Address(),
PubKey: pubKey,
Power: 10,
}}
if err := genDoc.SaveAs(genFile); err != nil {
return err
}
fmt.Print("Generated genesis file", "path", genFile)
}
return nil
},
})
cli.root.AddCommand(&cobra.Command{
Use: "run",
Short: "runs an orderbook node",
RunE: func(cmd *cobra.Command, args []string) error {
dbProvider := node.DefaultDBProvider
appDB, err := dbProvider(&node.DBContext{"orderbook", cli.config})
if err != nil {
return err
}
app, err := orderbook.New(appDB)
if err != nil {
return err
}
nodeKey, err := p2p.LoadOrGenNodeKey(cli.config.NodeKeyFile())
if err != nil {
return fmt.Errorf("failed to load or gen node key %s: %w", cli.config.NodeKeyFile(), err)
}
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
n, err := node.NewNode(
cli.config,
privval.LoadOrGenFilePV(cli.config.PrivValidatorKeyFile(), cli.config.PrivValidatorStateFile()),
nodeKey,
proxy.NewLocalClientCreator(app),
node.DefaultGenesisDocProviderFunc(cli.config),
dbProvider,
node.DefaultMetricsProvider(cli.config.Instrumentation),
logger,
)
if err != nil {
return err
}
if err := n.Start(); err != nil {
return err
}
tmos.TrapSignal(logger, func() {
if err := n.Stop(); err != nil {
logger.Error("unable to stop the node", "error", err)
}
})
return nil
},
})
cli.root.AddCommand(&cobra.Command{
Use: "create-account [commodities...]",
Short: "creates a new account message and submits it to the chain",
Example: "create-account 500BTC 10000USD",
RunE: func(cmd *cobra.Command, args []string) error {
return nil
},
})
cli.root.AddCommand(&cobra.Command{
Use: "create-pair buyers-denomination sellers-denomination",
Short: "creates a new pair message and submits it to the chain",
Example: "create-pair BTC USD",
RunE: func(cmd *cobra.Command, args []string) error {
return nil
},
})
cli.root.AddCommand(&cobra.Command{
Use: "bid buying-commodity price",
Short: "creates a bid message and submits it to the chain",
Example: "bid 10BTC 15000BTC/USD",
RunE: func(cmd *cobra.Command, args []string) error {
return nil
},
})
cli.root.AddCommand(&cobra.Command{
Use: "ask selling-commodity price",
Short: "creates an ask message and submits it to the chain",
Example: "ask 5BTC 12000BTC/USD",
RunE: func(cmd *cobra.Command, args []string) error {
return nil
},
})
querySubcommand := &cobra.Command{
Use: "query",
Short: "query the bal",
RunE: func(cmd *cobra.Command, args []string) error {
return nil
},
}
querySubcommand.AddCommand(&cobra.Command{
Use: "account pubkey|id",
Short: "query the balance of an account",
RunE: func(cmd *cobra.Command, args []string) error {
return nil
},
})
querySubcommand.AddCommand(&cobra.Command{
Use: "pairs",
Short: "list all the trading pairs",
RunE: func(cmd *cobra.Command, args []string) error {
return nil
},
})
querySubcommand.AddCommand(&cobra.Command{
Use: "orders pair",
Short: "list all current orders for a given pair",
Example: "orders BTC/USD",
RunE: func(cmd *cobra.Command, args []string) error {
return nil
},
})
cli.root.AddCommand(querySubcommand)
return cli
}
// Run runs the CLI.
func (cli *CLI) Run() {
if err := cli.root.Execute(); err != nil {
fmt.Print(err)
os.Exit(1)
}
}

View File

@@ -0,0 +1,19 @@
//go:generate go install github.com/bufbuild/buf/cmd/buf
//go:generate buf generate
// The orderbook presents a more advanced example of a Tendermint application than the simple kvstore
//
// An orderbook is a tool used in financial markets for enabling trading of various commodities. Without
// delving into too much detail, an orderbook is made of two types of transactions: Bids and Asks. An Ask
// is an offer by a seller for n amount of a commodity at an AskPrice and a bid is an offer from a buyer
// for m amount of a commodity at a BidPrice. When the bid price exceeds the ask price, and the buyer quantity
// is less than or equal to the sellers quantity, the order is matched. In actual terms, we neglect the
// underlying denomination (i.e. USD) and effectively both participants are simultaneously a buyer and seller.
//
// This example falls far short of being a decentralized orderbook, but demonstrates how one can build an
// app-side mempool, how one can use PrepareProposal and ProcessProposal to craft complex transactions,
// how we can use signatures and validate transactions against state. How applications can manage concurrency,
// and demonstrate the lifecycle of transactions from RPC -> CheckTx -> Mempool -> PrepareProposal -> ProcessProposal
// -> DeliverTx -> Commit -> Querying
package orderbook

View File

@@ -0,0 +1,254 @@
package orderbook
import (
"container/heap"
sync "sync"
)
type Market struct {
// immutable
pair *Pair // i.e. EUR/USD (a market is bidirectional)
mtx sync.RWMutex
askOrders *AskOrders // i.e. buying EUR for USD
lowestAsk float64
bidOrders *BidOrders // i.e. selling EUR for USD or buying USD for EUR
highestBid float64
}
func NewMarket(p *Pair) *Market {
askOrders := make(AskOrders, 0)
bidOrders := make(BidOrders, 0)
return &Market{pair: p, askOrders: &askOrders, bidOrders: &bidOrders}
}
func (m *Market) AddBid(b *OrderBid) {
m.mtx.Lock()
defer m.mtx.Unlock()
heap.Push(m.bidOrders, b)
if b.MaxPrice > m.highestBid {
m.highestBid = b.MaxPrice
}
}
func (m *Market) AddAsk(a *OrderAsk) {
m.mtx.Lock()
defer m.mtx.Unlock()
heap.Push(m.askOrders, a)
if a.AskPrice < m.lowestAsk || m.lowestAsk == 0 {
m.lowestAsk = a.AskPrice
}
}
// Match takes the set of bids and asks and matches them together.
// A bid matches an ask when the MaxPrice is greater than the AskPrice
// and the MaxQuantity is greater than the quantity.
func (m *Market) Match() *TradeSet {
m.mtx.Lock()
defer m.mtx.Unlock()
// if one side doesn't have any orders than there is nothing to match
// and we return early
if m.askOrders.Len() == 0 || m.bidOrders.Len() == 0 {
return nil
}
if m.highestBid < m.lowestAsk {
// no orders match, we return early.
return nil
}
t := &TradeSet{Pair: m.pair}
bids := make([]*OrderBid, 0)
asks := make([]*OrderAsk, 0)
// get all the bids that are greater than the lowest ask. In order from heighest bid to lowest bid
for m.bidOrders.Len() > 0 {
bid := heap.Pop(m.bidOrders).(*OrderBid)
if bid.MaxPrice < m.lowestAsk {
// we've reached the limit, push the bid back and break the loop
heap.Push(m.bidOrders, bid)
break
} else {
bids = append(bids, bid)
}
}
// get all the asks that are lower than the highest bid in the bids set. Ordered from lowest to highest ask
for m.askOrders.Len() > 0 {
ask := heap.Pop(m.askOrders).(*OrderAsk)
if ask.AskPrice > bids[0].MaxPrice {
// the ask price is greater than the highest bid; push the ask back and break theh loop
heap.Push(m.askOrders, ask)
break
} else {
asks = append(asks, ask)
}
}
// this is to keep track of the index of the bids that have been matched
reserved := make(map[int]struct{})
// start from the highest ask and the highest bid and for each ask loop downwards through the slice of
// bids until one is matched
OUTER_LOOP:
for i := len(asks) - 1; i >= 0; i-- {
ask := asks[i]
// start with the highest bid and increment down since we're more likely to find a match
for j := len(bids) - 1; j >= 0; j-- {
if _, ok := reserved[j]; ok {
// skip over the bids that have already been reserved
continue
}
bid := bids[j]
if bid.MaxPrice >= ask.AskPrice {
if bid.MaxQuantity >= ask.Quantity {
// yay! we have a match
t.AddFilledOrder(ask, bid)
// reserve the bid so we don't rematch it with another ask
reserved[j] = struct{}{}
continue OUTER_LOOP
}
} else {
// once we've dropped below the ask price there are no more possible bids and so we break
break
}
}
// as we go from highest to lowest, asks that aren't matched become the new lowest ask price
m.lowestAsk = ask.AskPrice
// no match found, add the ask order back into the heap
heap.Push(m.askOrders, ask)
}
// if all available asks were matched then
// we never have the opportunity to update the lowest ask.
// Now we reset it to 0
if m.askOrders.Len() == 0 {
m.lowestAsk = 0
}
// add back the unmatched bids to the heap so they can be matched again in a later round.
// We also neeed to recalculate the new highest bid. First we tackle an edge case whereby all
// selected bids were matched. In this case we grab the next highest and set that as the new
// highest bid
m.highestBid = 0
if len(reserved) == len(bids) && m.bidOrders.Len() > 0 {
newHighestBid := heap.Pop(m.bidOrders).(*OrderBid)
m.highestBid = newHighestBid.MaxPrice
heap.Push(m.bidOrders, newHighestBid)
}
for j := 0; j < len(bids); j++ {
if _, ok := reserved[j]; !ok {
if bids[j].MaxPrice > m.highestBid {
m.highestBid = bids[j].MaxPrice
}
heap.Push(m.bidOrders, bids[j])
}
}
if len(t.MatchedOrders) == 0 {
return nil
}
return t
}
func (m Market) LowestAsk() float64 {
m.mtx.RLock()
defer m.mtx.RUnlock()
return m.lowestAsk
}
func (m Market) HighestBid() float64 {
m.mtx.RLock()
defer m.mtx.RUnlock()
return m.highestBid
}
func (m Market) GetBids() []OrderBid {
m.mtx.RLock()
defer m.mtx.RUnlock()
orders := make([]OrderBid, m.bidOrders.Len())
for idx, order := range *m.bidOrders {
orders[idx] = *order
}
return orders
}
func (m Market) GetAsks() []OrderAsk {
m.mtx.RLock()
defer m.mtx.RUnlock()
orders := make([]OrderAsk, m.askOrders.Len())
for idx, order := range *m.askOrders {
orders[idx] = *order
}
return orders
}
// Heap ordered by lowest price
type AskOrders []*OrderAsk
var _ heap.Interface = (*AskOrders)(nil)
func (a AskOrders) Len() int { return len(a) }
func (a AskOrders) Less(i, j int) bool {
return a[i].AskPrice < a[j].AskPrice
}
func (a AskOrders) Swap(i, j int) {
a[i], a[j] = a[j], a[i]
}
func (a *AskOrders) Push(x any) {
item := x.(*OrderAsk)
*a = append(*a, item)
}
func (a *AskOrders) Pop() any {
old := *a
n := len(old)
item := old[n-1]
old[n-1] = nil
*a = old[0 : n-1]
return item
}
// Heap ordered by highest price
type BidOrders []*OrderBid
var _ heap.Interface = (*BidOrders)(nil)
func (b BidOrders) Len() int { return len(b) }
func (b BidOrders) Less(i, j int) bool {
return b[i].MaxPrice > b[j].MaxPrice
}
func (b BidOrders) Swap(i, j int) {
b[i], b[j] = b[j], b[i]
}
func (b *BidOrders) Push(x any) {
item := x.(*OrderBid)
*b = append(*b, item)
}
func (b *BidOrders) Pop() any {
old := *b
n := len(old)
item := old[n-1]
old[n-1] = nil
*b = old[0 : n-1]
return item
}
func (t *TradeSet) AddFilledOrder(ask *OrderAsk, bid *OrderBid) {
t.MatchedOrders = append(t.MatchedOrders, &MatchedOrder{
OrderAsk: ask,
OrderBid: bid,
})
}

View File

@@ -0,0 +1,179 @@
package orderbook_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/abci/example/orderbook"
)
var testPair = &orderbook.Pair{BuyersDenomination: "ATOM", SellersDenomination: "USD"}
func testBid(price, quantity float64) *orderbook.OrderBid {
return &orderbook.OrderBid{
MaxPrice: price,
MaxQuantity: quantity,
}
}
func testAsk(price, quantity float64) *orderbook.OrderAsk {
return &orderbook.OrderAsk{
AskPrice: price,
Quantity: quantity,
}
}
func TestTrackLowestAndHighestPrices(t *testing.T) {
market := orderbook.NewMarket(testPair)
require.Zero(t, market.LowestAsk())
require.Zero(t, market.HighestBid())
market.AddBid(testBid(100, 10))
require.EqualValues(t, 100, market.HighestBid())
market.AddAsk(testAsk(50, 10))
require.EqualValues(t, 50, market.LowestAsk())
market.AddAsk(testAsk(30, 10))
require.EqualValues(t, 30, market.LowestAsk())
market.AddAsk(testAsk(40, 10))
require.EqualValues(t, 30, market.LowestAsk())
}
func TestSimpleOrderMatching(t *testing.T) {
testcases := []struct {
bid *orderbook.OrderBid
ask *orderbook.OrderAsk
match bool
}{
{
bid: testBid(50, 10),
ask: testAsk(50, 10),
match: true,
},
{
bid: testBid(60, 10),
ask: testAsk(50, 10),
match: true,
},
{
bid: testBid(50, 10),
ask: testAsk(60, 10),
match: false,
},
{
bid: testBid(50, 5),
ask: testAsk(40, 10),
match: false,
},
{
bid: testBid(50, 15),
ask: testAsk(40, 10),
match: true,
},
}
for idx, tc := range testcases {
market := orderbook.NewMarket(testPair)
market.AddAsk(tc.ask)
market.AddBid(tc.bid)
resp := market.Match()
if tc.match {
require.Len(t, resp.MatchedOrders, 1, idx)
} else {
require.Nil(t, resp)
}
}
}
func TestMultiOrderMatching(t *testing.T) {
testcases := []struct {
bids []*orderbook.OrderBid
asks []*orderbook.OrderAsk
expected []*orderbook.MatchedOrder
expectedLowestAsk float64
expectedHighestBid float64
}{
{
bids: []*orderbook.OrderBid{
testBid(50, 20),
testBid(40, 10),
testBid(30, 15),
},
asks: []*orderbook.OrderAsk{
testAsk(30, 15),
testAsk(30, 5),
},
expected: []*orderbook.MatchedOrder{
{
OrderAsk: testAsk(30, 5),
OrderBid: testBid(30, 15),
},
{
OrderAsk: testAsk(30, 15),
OrderBid: testBid(50, 20),
},
},
expectedLowestAsk: 0,
expectedHighestBid: 40,
},
{
bids: []*orderbook.OrderBid{
testBid(60, 20),
testBid(80, 5),
},
asks: []*orderbook.OrderAsk{
testAsk(60, 15),
testAsk(70, 10),
testAsk(50, 20),
},
expected: []*orderbook.MatchedOrder{
{
OrderAsk: testAsk(60, 15),
OrderBid: testBid(60, 20),
},
},
expectedLowestAsk: 50,
expectedHighestBid: 80,
},
{
bids: []*orderbook.OrderBid{
testBid(60, 20),
testBid(80, 5),
},
asks: []*orderbook.OrderAsk{},
expected: []*orderbook.MatchedOrder{},
expectedLowestAsk: 0,
expectedHighestBid: 80,
},
{
bids: []*orderbook.OrderBid{},
asks: []*orderbook.OrderAsk{
testAsk(70, 10),
testAsk(50, 20),
},
expected: []*orderbook.MatchedOrder{},
expectedLowestAsk: 50,
expectedHighestBid: 0,
},
}
for idx, tc := range testcases {
market := orderbook.NewMarket(testPair)
for _, ask := range tc.asks {
market.AddAsk(ask)
}
for _, bid := range tc.bids {
market.AddBid(bid)
}
resp := market.Match()
if len(tc.expected) == 0 {
require.Nil(t, resp, idx)
} else {
require.Equal(t, tc.expected, resp.MatchedOrders, idx)
}
require.EqualValues(t, tc.expectedLowestAsk, market.LowestAsk(), idx)
require.EqualValues(t, tc.expectedHighestBid, market.HighestBid(), idx)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
syntax = "proto3";
package orderbook;
option go_package = "github.com/tendermint/tendermint/abci/example/orderbook";
import "wire.proto";
message MsgBid {
Pair pair = 1;
OrderBid bid_order = 2;
}
message MsgAsk {
Pair pair = 1;
OrderAsk ask_order = 2;
}
message MsgCreateAccount {
bytes public_key = 1;
repeated Commodity commodities = 2;
}
message MsgRegisterPair {
Pair pair = 1;
}
message MsgTradeSet {
TradeSet trade_set = 1;
}
message Msg {
//a Msg has to be one of the below
oneof sum {
MsgBid msg_bid = 1;
MsgAsk msg_ask = 2;
MsgRegisterPair msg_register_pair = 3;
MsgCreateAccount msg_create_account = 4;
MsgTradeSet msg_trade_set = 5;
}
}

BIN
abci/example/orderbook/orderbook Executable file

Binary file not shown.

View File

@@ -0,0 +1,31 @@
package orderbook
// Query the state of an account (returns a concrete copy)
func (sm *StateMachine) Account(id uint64) Account {
if int(id) >= len(sm.accounts) {
return Account{}
}
return *sm.accounts[id]
}
// Query all the pairs that the orderbook has (returns a concrete copy)
func (sm *StateMachine) Pairs() []Pair {
pairs := make([]Pair, len(sm.pairs))
idx := 0
for _, pair := range sm.pairs {
pairs[idx] = *pair
idx++
}
return pairs
}
// Query the current orders for a pair (returns concrete copies)
func (sm *StateMachine) Orders(pair *Pair) ([]OrderBid, []OrderAsk) {
market, ok := sm.markets[pair.String()]
if !ok {
return nil, nil
}
return market.GetBids(), market.GetAsks()
}
func (sm *StateMachine) Height() int64 { return sm.lastHeight }

View File

@@ -0,0 +1,299 @@
package orderbook
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"math"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
)
func NewMsgBid(pair *Pair, maxPrice, maxQuantity float64, ownerId uint64) *MsgBid {
return &MsgBid{
Pair: pair,
BidOrder: &OrderBid{
MaxPrice: maxPrice,
MaxQuantity: maxQuantity,
OwnerId: ownerId,
},
}
}
func (msg *MsgBid) Sign(pk crypto.PrivKey) error {
sig, err := pk.Sign(msg.BidOrder.DeterministicSignatureBytes(msg.Pair))
if err != nil {
return err
}
msg.BidOrder.Signature = sig
return nil
}
func (msg *MsgBid) ValidateBasic() error {
if err := msg.BidOrder.ValidateBasic(); err != nil {
return err
}
if err := msg.Pair.ValidateBasic(); err != nil {
return err
}
if len(msg.BidOrder.Signature) != ed25519.SignatureSize {
return errors.New("invalid signature size")
}
return nil
}
func NewMsgAsk(pair *Pair, askPrice, quantity float64, ownerId uint64) *MsgAsk {
return &MsgAsk{
Pair: pair,
AskOrder: &OrderAsk{
AskPrice: askPrice,
Quantity: quantity,
OwnerId: ownerId,
},
}
}
func (msg *MsgAsk) Sign(pk crypto.PrivKey) error {
sig, err := pk.Sign(msg.AskOrder.DeterministicSignatureBytes(msg.Pair))
if err != nil {
return err
}
msg.AskOrder.Signature = sig
return nil
}
func (msg *MsgAsk) ValidateBasic() error {
if err := msg.AskOrder.ValidateBasic(); err != nil {
return err
}
if err := msg.Pair.ValidateBasic(); err != nil {
return err
}
return nil
}
func NewMsgCreateAccount(commodities ...*Commodity) (*MsgCreateAccount, crypto.PrivKey) {
pk := ed25519.GenPrivKey()
return &MsgCreateAccount{
PublicKey: pk.PubKey().Bytes(),
Commodities: commodities,
}, pk
}
func (msg *MsgCreateAccount) ValidateBasic() error {
if len(msg.PublicKey) != ed25519.PubKeySize {
return errors.New("invalid pub key size")
}
uniqueMap := make(map[string]struct{}, len(msg.Commodities))
for _, c := range msg.Commodities {
if err := c.ValidateBasic(); err != nil {
return err
}
if _, ok := uniqueMap[c.Denom]; ok {
return fmt.Errorf("commodity %s declared twice", c.Denom)
}
uniqueMap[c.Denom] = struct{}{}
}
return nil
}
func NewMsgRegisterPair(pair *Pair) *MsgRegisterPair {
return &MsgRegisterPair{Pair: pair}
}
func (msg *MsgRegisterPair) ValidateBasic() error {
return msg.Pair.ValidateBasic()
}
func NewCommodity(denom string, quantity float64) *Commodity {
return &Commodity{
Denom: denom,
Quantity: quantity,
}
}
func (c *Commodity) ValidateBasic() error {
if c.Quantity <= 0 {
return errors.New("quantity must be greater than zero")
}
return nil
}
func (p *Pair) ValidateBasic() error {
if p.BuyersDenomination == "" || p.SellersDenomination == "" {
return errors.New("inbound and outbound commodities must be present")
}
if p.BuyersDenomination == p.SellersDenomination {
return errors.New("commodities must not be the same")
}
return nil
}
func (o *OrderBid) ValidateBasic() error {
if o.MaxQuantity == 0 {
return errors.New("max quantity must be non zero")
}
if o.MaxPrice <= 0 {
return errors.New("min price must be greater than 0")
}
if len(o.Signature) != ed25519.SignatureSize {
return errors.New("invalid signature size")
}
return nil
}
func (o *OrderBid) ValidateSignature(pk crypto.PubKey, pair *Pair) bool {
return pk.VerifySignature(o.DeterministicSignatureBytes(pair), o.Signature)
}
func (o *OrderBid) DeterministicSignatureBytes(pair *Pair) []byte {
buf := bytes.NewBuffer(nil)
buf.WriteString(pair.SellersDenomination)
buf.WriteString(pair.BuyersDenomination)
bz := buf.Bytes()
bz = binary.BigEndian.AppendUint64(bz, math.Float64bits(o.MaxQuantity))
bz = binary.BigEndian.AppendUint64(bz, math.Float64bits(o.MaxPrice))
return bz
}
func (m *MatchedOrder) ValidateBasic() error {
if err := m.OrderAsk.ValidateBasic(); err != nil {
return err
}
if err := m.OrderBid.ValidateBasic(); err != nil {
return err
}
return nil
}
func (t *TradeSet) ValidateBasic() error {
for _, matchedOrder := range t.MatchedOrders {
if err := matchedOrder.ValidateBasic(); err != nil {
return err
}
// checking if there is an account
if matchedOrder.OrderAsk.OwnerId == 0 {
return errors.New("must have an owner id more than zero")
}
}
// validate the pairs are valid
if err := t.Pair.ValidateBasic(); err != nil {
return err
}
return nil
}
func (o *OrderAsk) ValidateBasic() error {
if o.Quantity == 0 {
return errors.New("quantity outbound must be non zero")
}
if o.AskPrice <= 0 {
return errors.New("min price must be greater than 0")
}
if len(o.Signature) != ed25519.SignatureSize {
return errors.New("invalid signature size")
}
return nil
}
func (o *OrderAsk) ValidateSignature(pk crypto.PubKey, pair *Pair) bool {
return pk.VerifySignature(o.DeterministicSignatureBytes(pair), o.Signature)
}
func (o *OrderAsk) DeterministicSignatureBytes(pair *Pair) []byte {
buf := bytes.NewBuffer(nil)
buf.WriteString(pair.BuyersDenomination)
buf.WriteString(pair.SellersDenomination)
bz := buf.Bytes()
bz = binary.BigEndian.AppendUint64(bz, math.Float64bits(o.Quantity))
bz = binary.BigEndian.AppendUint64(bz, math.Float64bits(o.AskPrice))
return bz
}
func (a Account) IsEmpty() bool {
return len(a.PublicKey) == 0
}
func (a *Account) FindCommidity(denom string) *Commodity {
for _, c := range a.Commodities {
if c.Denom == denom {
return c
}
}
return nil
}
func (a *Account) AddCommodity(c *Commodity) {
curr := a.FindCommidity(c.Denom)
if curr == nil {
a.Commodities = append(a.Commodities, c)
} else {
curr.Quantity += c.Quantity
}
}
func (a *Account) SubtractCommodity(c *Commodity) {
curr := a.FindCommidity(c.Denom)
if curr == nil {
panic("trying to remove a commodity the account does not have")
}
curr.Quantity -= c.Quantity
}
func (msg *Msg) ValidateBasic() error {
switch m := msg.Sum.(type) {
case *Msg_MsgRegisterPair:
if err := m.MsgRegisterPair.ValidateBasic(); err != nil {
return err
}
case *Msg_MsgCreateAccount:
if err := m.MsgCreateAccount.ValidateBasic(); err != nil {
return err
}
case *Msg_MsgBid:
if err := m.MsgBid.ValidateBasic(); err != nil {
return err
}
case *Msg_MsgAsk:
if err := m.MsgAsk.ValidateBasic(); err != nil {
return err
}
case *Msg_MsgTradeSet:
if err := m.MsgTradeSet.TradeSet.ValidateBasic(); err != nil {
return err
}
default:
return errors.New("unknown tx")
}
return nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,52 @@
syntax = "proto3";
package orderbook;
option go_package = "github.com/tendermint/tendermint/abci/example/orderbook";
message OrderAsk {
double quantity = 1;
double ask_price = 2;
uint64 owner_id = 3;
bytes signature = 4;
}
message OrderBid {
double max_quantity = 1;
double max_price = 2;
uint64 owner_id = 3;
bytes signature = 4;
}
message Pair {
// the denomination that the buyer receives i.e. EUR
string buyers_denomination = 1;
// the denomination that the seller receives i.e. USD
string sellers_denomination = 2;
}
message Commodity {
string denom = 1;
double quantity = 2;
}
// Accounts is the atomic piece of information that is persisted to disk.
message Account {
uint64 index = 1;
bytes public_key = 2;
// the set of commodities that the account has
repeated Commodity commodities = 3;
}
// TradeSet is the transaction that eventually is committed in a block
// It is derived from a group of MsgBid and MsgAsk's
message TradeSet {
Pair pair = 1; // i.e. EUR/USD
// the set of matched trades for that peer
repeated MatchedOrder matched_orders = 2;
}
message MatchedOrder {
OrderAsk order_ask = 1;
OrderBid order_bid = 2;
}

View File

@@ -2,9 +2,8 @@
Package server is used to start a new ABCI server.
It contains two server implementation:
* gRPC server
* socket server
- gRPC server
- socket server
*/
package server

View File

@@ -200,9 +200,6 @@ func (s *SocketServer) handleRequest(req *types.Request, responses chan<- *types
case *types.Request_Info:
res := s.app.Info(*r.Info)
responses <- types.ToResponseInfo(res)
case *types.Request_SetOption:
res := s.app.SetOption(*r.SetOption)
responses <- types.ToResponseSetOption(res)
case *types.Request_DeliverTx:
res := s.app.DeliverTx(*r.DeliverTx)
responses <- types.ToResponseDeliverTx(res)
@@ -230,6 +227,12 @@ func (s *SocketServer) handleRequest(req *types.Request, responses chan<- *types
case *types.Request_OfferSnapshot:
res := s.app.OfferSnapshot(*r.OfferSnapshot)
responses <- types.ToResponseOfferSnapshot(res)
case *types.Request_PrepareProposal:
res := s.app.PrepareProposal(*r.PrepareProposal)
responses <- types.ToResponsePrepareProposal(res)
case *types.Request_ProcessProposal:
res := s.app.ProcessProposal(*r.ProcessProposal)
responses <- types.ToResponseProcessProposal(res)
case *types.Request_LoadSnapshotChunk:
res := s.app.LoadSnapshotChunk(*r.LoadSnapshotChunk)
responses <- types.ToResponseLoadSnapshotChunk(res)

View File

@@ -29,17 +29,6 @@ func InitChain(client abcicli.Client) error {
return nil
}
func SetOption(client abcicli.Client, key, value string) error {
_, err := client.SetOptionSync(types.RequestSetOption{Key: key, Value: value})
if err != nil {
fmt.Println("Failed test: SetOption")
fmt.Printf("error while setting %v=%v: \nerror: %v\n", key, value, err)
return err
}
fmt.Println("Passed test: SetOption")
return nil
}
func Commit(client abcicli.Client, hashExp []byte) error {
res, err := client.CommitSync()
data := res.Data
@@ -76,6 +65,32 @@ func DeliverTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []
return nil
}
func PrepareProposal(client abcicli.Client, txBytes [][]byte, txExpected [][]byte, dataExp []byte) error {
res, _ := client.PrepareProposalSync(types.RequestPrepareProposal{Txs: txBytes})
for i, tx := range res.Txs {
if !bytes.Equal(tx, txExpected[i]) {
fmt.Println("Failed test: PrepareProposal")
fmt.Printf("PrepareProposal transaction was unexpected. Got %x expected %x.",
tx, txExpected[i])
return errors.New("PrepareProposal error")
}
}
fmt.Println("Passed test: PrepareProposal")
return nil
}
func ProcessProposal(client abcicli.Client, txBytes [][]byte, statusExp types.ResponseProcessProposal_ProposalStatus) error {
res, _ := client.ProcessProposalSync(types.RequestProcessProposal{Txs: txBytes})
if res.Status != statusExp {
fmt.Println("Failed test: ProcessProposal")
fmt.Printf("ProcessProposal response status was unexpected. Got %v expected %v.",
res.Status, statusExp)
return errors.New("ProcessProposal error")
}
fmt.Println("Passed test: ProcessProposal")
return nil
}
func CheckTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) error {
res, _ := client.CheckTxSync(types.RequestCheckTx{Tx: txBytes})
code, data, log := res.Code, res.Data, res.Log

View File

@@ -1,5 +1,7 @@
echo hello
info
prepare_proposal "abc"
process_proposal "abc"
commit
deliver_tx "abc"
info
@@ -8,3 +10,9 @@ query "abc"
deliver_tx "def=xyz"
commit
query "def"
prepare_proposal "preparedef"
process_proposal "replacedef"
process_proposal "preparedef"
prepare_proposal
process_proposal
commit

View File

@@ -8,6 +8,14 @@
-> data: {"size":0}
-> data.hex: 0x7B2273697A65223A307D
> prepare_proposal "abc"
-> code: OK
-> log: Succeeded. Tx: abc
> process_proposal "abc"
-> code: OK
-> status: ACCEPT
> commit
-> code: OK
-> data.hex: 0x0000000000000000
@@ -49,3 +57,25 @@
-> value: xyz
-> value.hex: 78797A
> prepare_proposal "preparedef"
-> code: OK
-> log: Succeeded. Tx: replacedef
> process_proposal "replacedef"
-> code: OK
-> status: ACCEPT
> process_proposal "preparedef"
-> code: OK
-> status: REJECT
> prepare_proposal
> process_proposal
-> code: OK
-> status: ACCEPT
> commit
-> code: OK
-> data.hex: 0x0400000000000000

View File

@@ -1,4 +1,3 @@
set_option serial on
check_tx 0x00
check_tx 0xff
deliver_tx 0x00

View File

@@ -1,7 +1,3 @@
> set_option serial on
-> code: OK
-> log: OK (SetOption doesn't return anything.)
> check_tx 0x00
-> code: OK
@@ -12,18 +8,16 @@
-> code: OK
> check_tx 0x00
-> code: 2
-> log: Invalid nonce. Expected >= 1, got 0
-> code: OK
> deliver_tx 0x01
-> code: OK
> deliver_tx 0x04
-> code: 2
-> log: Invalid nonce. Expected 2, got 4
-> code: OK
> info
-> code: OK
-> data: {"hashes":0,"txs":2}
-> data.hex: 0x7B22686173686573223A302C22747873223A327D
-> data: {"size":3}
-> data.hex: 0x7B2273697A65223A337D

View File

@@ -30,6 +30,8 @@ function testExample() {
cat "${INPUT}.out.new"
echo "Expected:"
cat "${INPUT}.out"
echo "Diff:"
diff "${INPUT}.out" "${INPUT}.out.new"
exit 1
fi
@@ -37,6 +39,7 @@ function testExample() {
}
testExample 1 tests/test_cli/ex1.abci abci-cli kvstore
testExample 2 tests/test_cli/ex2.abci abci-cli kvstore
echo ""
echo "PASS"

View File

@@ -4,21 +4,24 @@ import (
context "golang.org/x/net/context"
)
//go:generate ../../scripts/mockery_generate.sh Application
// Application is an interface that enables any finite, deterministic state machine
// to be driven by a blockchain-based replication engine via the ABCI.
// All methods take a RequestXxx argument and return a ResponseXxx argument,
// except CheckTx/DeliverTx, which take `tx []byte`, and `Commit`, which takes nothing.
type Application interface {
// Info/Query Connection
Info(RequestInfo) ResponseInfo // Return application info
SetOption(RequestSetOption) ResponseSetOption // Set application option
Query(RequestQuery) ResponseQuery // Query for state
Info(RequestInfo) ResponseInfo // Return application info
Query(RequestQuery) ResponseQuery // Query for state
// Mempool Connection
CheckTx(RequestCheckTx) ResponseCheckTx // Validate a tx for the mempool
// Consensus Connection
InitChain(RequestInitChain) ResponseInitChain // Initialize blockchain w validators/other info from TendermintCore
InitChain(RequestInitChain) ResponseInitChain // Initialize blockchain w validators/other info from TendermintCore
PrepareProposal(RequestPrepareProposal) ResponsePrepareProposal
ProcessProposal(RequestProcessProposal) ResponseProcessProposal
BeginBlock(RequestBeginBlock) ResponseBeginBlock // Signals the beginning of a block
DeliverTx(RequestDeliverTx) ResponseDeliverTx // Deliver a tx for full processing
EndBlock(RequestEndBlock) ResponseEndBlock // Signals the end of a block, returns changes to the validator set
@@ -47,10 +50,6 @@ func (BaseApplication) Info(req RequestInfo) ResponseInfo {
return ResponseInfo{}
}
func (BaseApplication) SetOption(req RequestSetOption) ResponseSetOption {
return ResponseSetOption{}
}
func (BaseApplication) DeliverTx(req RequestDeliverTx) ResponseDeliverTx {
return ResponseDeliverTx{Code: CodeTypeOK}
}
@@ -95,6 +94,24 @@ func (BaseApplication) ApplySnapshotChunk(req RequestApplySnapshotChunk) Respons
return ResponseApplySnapshotChunk{}
}
func (BaseApplication) PrepareProposal(req RequestPrepareProposal) ResponsePrepareProposal {
txs := make([][]byte, 0, len(req.Txs))
var totalBytes int64
for _, tx := range req.Txs {
totalBytes += int64(len(tx))
if totalBytes > req.MaxTxBytes {
break
}
txs = append(txs, tx)
}
return ResponsePrepareProposal{Txs: txs}
}
func (BaseApplication) ProcessProposal(req RequestProcessProposal) ResponseProcessProposal {
return ResponseProcessProposal{
Status: ResponseProcessProposal_ACCEPT}
}
//-------------------------------------------------------
// GRPCApplication is a GRPC wrapper for Application
@@ -119,11 +136,6 @@ func (app *GRPCApplication) Info(ctx context.Context, req *RequestInfo) (*Respon
return &res, nil
}
func (app *GRPCApplication) SetOption(ctx context.Context, req *RequestSetOption) (*ResponseSetOption, error) {
res := app.app.SetOption(*req)
return &res, nil
}
func (app *GRPCApplication) DeliverTx(ctx context.Context, req *RequestDeliverTx) (*ResponseDeliverTx, error) {
res := app.app.DeliverTx(*req)
return &res, nil
@@ -182,3 +194,15 @@ func (app *GRPCApplication) ApplySnapshotChunk(
res := app.app.ApplySnapshotChunk(*req)
return &res, nil
}
func (app *GRPCApplication) PrepareProposal(
ctx context.Context, req *RequestPrepareProposal) (*ResponsePrepareProposal, error) {
res := app.app.PrepareProposal(*req)
return &res, nil
}
func (app *GRPCApplication) ProcessProposal(
ctx context.Context, req *RequestProcessProposal) (*ResponseProcessProposal, error) {
res := app.app.ProcessProposal(*req)
return &res, nil
}

View File

@@ -1,11 +1,10 @@
package types
import (
"bufio"
"encoding/binary"
"io"
"github.com/gogo/protobuf/proto"
"github.com/cosmos/gogoproto/proto"
"github.com/tendermint/tendermint/libs/protoio"
)
const (
@@ -14,57 +13,19 @@ const (
// WriteMessage writes a varint length-delimited protobuf message.
func WriteMessage(msg proto.Message, w io.Writer) error {
bz, err := proto.Marshal(msg)
protoWriter := protoio.NewDelimitedWriter(w)
_, err := protoWriter.WriteMsg(msg)
if err != nil {
return err
}
return encodeByteSlice(w, bz)
return nil
}
// ReadMessage reads a varint length-delimited protobuf message.
func ReadMessage(r io.Reader, msg proto.Message) error {
return readProtoMsg(r, msg, maxMsgSize)
}
func readProtoMsg(r io.Reader, msg proto.Message, maxSize int) error {
// binary.ReadVarint takes an io.ByteReader, eg. a bufio.Reader
reader, ok := r.(*bufio.Reader)
if !ok {
reader = bufio.NewReader(r)
}
length64, err := binary.ReadVarint(reader)
if err != nil {
return err
}
length := int(length64)
if length < 0 || length > maxSize {
return io.ErrShortBuffer
}
buf := make([]byte, length)
if _, err := io.ReadFull(reader, buf); err != nil {
return err
}
return proto.Unmarshal(buf, msg)
}
//-----------------------------------------------------------------------
// NOTE: we copied wire.EncodeByteSlice from go-wire rather than keep
// go-wire as a dep
func encodeByteSlice(w io.Writer, bz []byte) (err error) {
err = encodeVarint(w, int64(len(bz)))
if err != nil {
return
}
_, err = w.Write(bz)
return
}
func encodeVarint(w io.Writer, i int64) (err error) {
var buf [10]byte
n := binary.PutVarint(buf[:], i)
_, err = w.Write(buf[0:n])
return
_, err := protoio.NewDelimitedReader(r, maxMsgSize).ReadMsg(msg)
return err
}
//----------------------------------------
@@ -87,12 +48,6 @@ func ToRequestInfo(req RequestInfo) *Request {
}
}
func ToRequestSetOption(req RequestSetOption) *Request {
return &Request{
Value: &Request_SetOption{&req},
}
}
func ToRequestDeliverTx(req RequestDeliverTx) *Request {
return &Request{
Value: &Request_DeliverTx{&req},
@@ -159,6 +114,18 @@ func ToRequestApplySnapshotChunk(req RequestApplySnapshotChunk) *Request {
}
}
func ToRequestPrepareProposal(req RequestPrepareProposal) *Request {
return &Request{
Value: &Request_PrepareProposal{&req},
}
}
func ToRequestProcessProposal(req RequestProcessProposal) *Request {
return &Request{
Value: &Request_ProcessProposal{&req},
}
}
//----------------------------------------
func ToResponseException(errStr string) *Response {
@@ -185,12 +152,6 @@ func ToResponseInfo(res ResponseInfo) *Response {
}
}
func ToResponseSetOption(res ResponseSetOption) *Response {
return &Response{
Value: &Response_SetOption{&res},
}
}
func ToResponseDeliverTx(res ResponseDeliverTx) *Response {
return &Response{
Value: &Response_DeliverTx{&res},
@@ -256,3 +217,15 @@ func ToResponseApplySnapshotChunk(res ResponseApplySnapshotChunk) *Response {
Value: &Response_ApplySnapshotChunk{&res},
}
}
func ToResponsePrepareProposal(res ResponsePrepareProposal) *Response {
return &Response{
Value: &Response_PrepareProposal{&res},
}
}
func ToResponseProcessProposal(res ResponseProcessProposal) *Response {
return &Response{
Value: &Response_ProcessProposal{&res},
}
}

View File

@@ -6,7 +6,7 @@ import (
"strings"
"testing"
"github.com/gogo/protobuf/proto"
"github.com/cosmos/gogoproto/proto"
"github.com/stretchr/testify/assert"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
@@ -25,7 +25,7 @@ func TestMarshalJSON(t *testing.T) {
{
Type: "testEvent",
Attributes: []EventAttribute{
{Key: []byte("pho"), Value: []byte("bo")},
{Key: "pho", Value: "bo"},
},
},
},
@@ -92,7 +92,7 @@ func TestWriteReadMessage2(t *testing.T) {
{
Type: "testEvent",
Attributes: []EventAttribute{
{Key: []byte("abc"), Value: []byte("def")},
{Key: "abc", Value: "def"},
},
},
},

View File

@@ -0,0 +1,224 @@
// Code generated by mockery. DO NOT EDIT.
package mocks
import (
mock "github.com/stretchr/testify/mock"
types "github.com/tendermint/tendermint/abci/types"
)
// Application is an autogenerated mock type for the Application type
type Application struct {
mock.Mock
}
// ApplySnapshotChunk provides a mock function with given fields: _a0
func (_m *Application) ApplySnapshotChunk(_a0 types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk {
ret := _m.Called(_a0)
var r0 types.ResponseApplySnapshotChunk
if rf, ok := ret.Get(0).(func(types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(types.ResponseApplySnapshotChunk)
}
return r0
}
// BeginBlock provides a mock function with given fields: _a0
func (_m *Application) BeginBlock(_a0 types.RequestBeginBlock) types.ResponseBeginBlock {
ret := _m.Called(_a0)
var r0 types.ResponseBeginBlock
if rf, ok := ret.Get(0).(func(types.RequestBeginBlock) types.ResponseBeginBlock); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(types.ResponseBeginBlock)
}
return r0
}
// CheckTx provides a mock function with given fields: _a0
func (_m *Application) CheckTx(_a0 types.RequestCheckTx) types.ResponseCheckTx {
ret := _m.Called(_a0)
var r0 types.ResponseCheckTx
if rf, ok := ret.Get(0).(func(types.RequestCheckTx) types.ResponseCheckTx); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(types.ResponseCheckTx)
}
return r0
}
// Commit provides a mock function with given fields:
func (_m *Application) Commit() types.ResponseCommit {
ret := _m.Called()
var r0 types.ResponseCommit
if rf, ok := ret.Get(0).(func() types.ResponseCommit); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(types.ResponseCommit)
}
return r0
}
// DeliverTx provides a mock function with given fields: _a0
func (_m *Application) DeliverTx(_a0 types.RequestDeliverTx) types.ResponseDeliverTx {
ret := _m.Called(_a0)
var r0 types.ResponseDeliverTx
if rf, ok := ret.Get(0).(func(types.RequestDeliverTx) types.ResponseDeliverTx); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(types.ResponseDeliverTx)
}
return r0
}
// EndBlock provides a mock function with given fields: _a0
func (_m *Application) EndBlock(_a0 types.RequestEndBlock) types.ResponseEndBlock {
ret := _m.Called(_a0)
var r0 types.ResponseEndBlock
if rf, ok := ret.Get(0).(func(types.RequestEndBlock) types.ResponseEndBlock); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(types.ResponseEndBlock)
}
return r0
}
// Info provides a mock function with given fields: _a0
func (_m *Application) Info(_a0 types.RequestInfo) types.ResponseInfo {
ret := _m.Called(_a0)
var r0 types.ResponseInfo
if rf, ok := ret.Get(0).(func(types.RequestInfo) types.ResponseInfo); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(types.ResponseInfo)
}
return r0
}
// InitChain provides a mock function with given fields: _a0
func (_m *Application) InitChain(_a0 types.RequestInitChain) types.ResponseInitChain {
ret := _m.Called(_a0)
var r0 types.ResponseInitChain
if rf, ok := ret.Get(0).(func(types.RequestInitChain) types.ResponseInitChain); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(types.ResponseInitChain)
}
return r0
}
// ListSnapshots provides a mock function with given fields: _a0
func (_m *Application) ListSnapshots(_a0 types.RequestListSnapshots) types.ResponseListSnapshots {
ret := _m.Called(_a0)
var r0 types.ResponseListSnapshots
if rf, ok := ret.Get(0).(func(types.RequestListSnapshots) types.ResponseListSnapshots); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(types.ResponseListSnapshots)
}
return r0
}
// LoadSnapshotChunk provides a mock function with given fields: _a0
func (_m *Application) LoadSnapshotChunk(_a0 types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk {
ret := _m.Called(_a0)
var r0 types.ResponseLoadSnapshotChunk
if rf, ok := ret.Get(0).(func(types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(types.ResponseLoadSnapshotChunk)
}
return r0
}
// OfferSnapshot provides a mock function with given fields: _a0
func (_m *Application) OfferSnapshot(_a0 types.RequestOfferSnapshot) types.ResponseOfferSnapshot {
ret := _m.Called(_a0)
var r0 types.ResponseOfferSnapshot
if rf, ok := ret.Get(0).(func(types.RequestOfferSnapshot) types.ResponseOfferSnapshot); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(types.ResponseOfferSnapshot)
}
return r0
}
// PrepareProposal provides a mock function with given fields: _a0
func (_m *Application) PrepareProposal(_a0 types.RequestPrepareProposal) types.ResponsePrepareProposal {
ret := _m.Called(_a0)
var r0 types.ResponsePrepareProposal
if rf, ok := ret.Get(0).(func(types.RequestPrepareProposal) types.ResponsePrepareProposal); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(types.ResponsePrepareProposal)
}
return r0
}
// ProcessProposal provides a mock function with given fields: _a0
func (_m *Application) ProcessProposal(_a0 types.RequestProcessProposal) types.ResponseProcessProposal {
ret := _m.Called(_a0)
var r0 types.ResponseProcessProposal
if rf, ok := ret.Get(0).(func(types.RequestProcessProposal) types.ResponseProcessProposal); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(types.ResponseProcessProposal)
}
return r0
}
// Query provides a mock function with given fields: _a0
func (_m *Application) Query(_a0 types.RequestQuery) types.ResponseQuery {
ret := _m.Called(_a0)
var r0 types.ResponseQuery
if rf, ok := ret.Get(0).(func(types.RequestQuery) types.ResponseQuery); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(types.ResponseQuery)
}
return r0
}
type mockConstructorTestingTNewApplication interface {
mock.TestingT
Cleanup(func())
}
// NewApplication creates a new instance of Application. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func NewApplication(t mockConstructorTestingTNewApplication) *Application {
mock := &Application{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

187
abci/types/mocks/base.go Normal file
View File

@@ -0,0 +1,187 @@
package mocks
import (
types "github.com/tendermint/tendermint/abci/types"
)
// BaseMock provides a wrapper around the generated Application mock and a BaseApplication.
// BaseMock first tries to use the mock's implementation of the method.
// If no functionality was provided for the mock by the user, BaseMock dispatches
// to the BaseApplication and uses its functionality.
// BaseMock allows users to provide mocked functionality for only the methods that matter
// for their test while avoiding a panic if the code calls Application methods that are
// not relevant to the test.
type BaseMock struct {
base *types.BaseApplication
*Application
}
func NewBaseMock() BaseMock {
return BaseMock{
base: types.NewBaseApplication(),
Application: new(Application),
}
}
// Info/Query Connection
// Return application info
func (m BaseMock) Info(input types.RequestInfo) types.ResponseInfo {
var ret types.ResponseInfo
defer func() {
if r := recover(); r != nil {
ret = m.base.Info(input)
}
}()
ret = m.Application.Info(input)
return ret
}
func (m BaseMock) Query(input types.RequestQuery) types.ResponseQuery {
var ret types.ResponseQuery
defer func() {
if r := recover(); r != nil {
ret = m.base.Query(input)
}
}()
ret = m.Application.Query(input)
return ret
}
// Mempool Connection
// Validate a tx for the mempool
func (m BaseMock) CheckTx(input types.RequestCheckTx) types.ResponseCheckTx {
var ret types.ResponseCheckTx
defer func() {
if r := recover(); r != nil {
ret = m.base.CheckTx(input)
}
}()
ret = m.Application.CheckTx(input)
return ret
}
// Consensus Connection
// Initialize blockchain w validators/other info from TendermintCore
func (m BaseMock) InitChain(input types.RequestInitChain) types.ResponseInitChain {
var ret types.ResponseInitChain
defer func() {
if r := recover(); r != nil {
ret = m.base.InitChain(input)
}
}()
ret = m.Application.InitChain(input)
return ret
}
func (m BaseMock) PrepareProposal(input types.RequestPrepareProposal) types.ResponsePrepareProposal {
var ret types.ResponsePrepareProposal
defer func() {
if r := recover(); r != nil {
ret = m.base.PrepareProposal(input)
}
}()
ret = m.Application.PrepareProposal(input)
return ret
}
func (m BaseMock) ProcessProposal(input types.RequestProcessProposal) types.ResponseProcessProposal {
var ret types.ResponseProcessProposal
defer func() {
if r := recover(); r != nil {
ret = m.base.ProcessProposal(input)
}
}()
ret = m.Application.ProcessProposal(input)
return ret
}
// Commit the state and return the application Merkle root hash
func (m BaseMock) Commit() types.ResponseCommit {
var ret types.ResponseCommit
defer func() {
if r := recover(); r != nil {
ret = m.base.Commit()
}
}()
ret = m.Application.Commit()
return ret
}
// State Sync Connection
// List available snapshots
func (m BaseMock) ListSnapshots(input types.RequestListSnapshots) types.ResponseListSnapshots {
var ret types.ResponseListSnapshots
defer func() {
if r := recover(); r != nil {
ret = m.base.ListSnapshots(input)
}
}()
ret = m.Application.ListSnapshots(input)
return ret
}
func (m BaseMock) OfferSnapshot(input types.RequestOfferSnapshot) types.ResponseOfferSnapshot {
var ret types.ResponseOfferSnapshot
defer func() {
if r := recover(); r != nil {
ret = m.base.OfferSnapshot(input)
}
}()
ret = m.Application.OfferSnapshot(input)
return ret
}
func (m BaseMock) LoadSnapshotChunk(input types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk {
var ret types.ResponseLoadSnapshotChunk
defer func() {
if r := recover(); r != nil {
ret = m.base.LoadSnapshotChunk(input)
}
}()
ret = m.Application.LoadSnapshotChunk(input)
return ret
}
func (m BaseMock) ApplySnapshotChunk(input types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk {
var ret types.ResponseApplySnapshotChunk
defer func() {
if r := recover(); r != nil {
ret = m.base.ApplySnapshotChunk(input)
}
}()
ret = m.Application.ApplySnapshotChunk(input)
return ret
}
func (m BaseMock) BeginBlock(input types.RequestBeginBlock) types.ResponseBeginBlock {
var ret types.ResponseBeginBlock
defer func() {
if r := recover(); r != nil {
ret = m.base.BeginBlock(input)
}
}()
ret = m.Application.BeginBlock(input)
return ret
}
func (m BaseMock) DeliverTx(input types.RequestDeliverTx) types.ResponseDeliverTx {
var ret types.ResponseDeliverTx
defer func() {
if r := recover(); r != nil {
ret = m.base.DeliverTx(input)
}
}()
ret = m.Application.DeliverTx(input)
return ret
}
func (m BaseMock) EndBlock(input types.RequestEndBlock) types.ResponseEndBlock {
var ret types.ResponseEndBlock
defer func() {
if r := recover(); r != nil {
ret = m.base.EndBlock(input)
}
}()
ret = m.Application.EndBlock(input)
return ret
}

View File

@@ -4,7 +4,7 @@ import (
"bytes"
"encoding/json"
"github.com/gogo/protobuf/jsonpb"
"github.com/cosmos/gogoproto/jsonpb"
)
const (
@@ -41,6 +41,16 @@ func (r ResponseQuery) IsErr() bool {
return r.Code != CodeTypeOK
}
// IsAccepted returns true if Code is ACCEPT
func (r ResponseProcessProposal) IsAccepted() bool {
return r.Status == ResponseProcessProposal_ACCEPT
}
// IsStatusUnknown returns true if Code is UNKNOWN
func (r ResponseProcessProposal) IsStatusUnknown() bool {
return r.Status == ResponseProcessProposal_UNKNOWN
}
//---------------------------------------------------------------------------
// override JSON marshaling so we emit defaults (ie. disable omitempty)
@@ -52,16 +62,6 @@ var (
jsonpbUnmarshaller = jsonpb.Unmarshaler{}
)
func (r *ResponseSetOption) MarshalJSON() ([]byte, error) {
s, err := jsonpbMarshaller.MarshalToString(r)
return []byte(s), err
}
func (r *ResponseSetOption) UnmarshalJSON(b []byte) error {
reader := bytes.NewBuffer(b)
return jsonpbUnmarshaller.Unmarshal(reader, r)
}
func (r *ResponseCheckTx) MarshalJSON() ([]byte, error) {
s, err := jsonpbMarshaller.MarshalToString(r)
return []byte(s), err
@@ -126,6 +126,5 @@ var _ jsonRoundTripper = (*ResponseCommit)(nil)
var _ jsonRoundTripper = (*ResponseQuery)(nil)
var _ jsonRoundTripper = (*ResponseDeliverTx)(nil)
var _ jsonRoundTripper = (*ResponseCheckTx)(nil)
var _ jsonRoundTripper = (*ResponseSetOption)(nil)
var _ jsonRoundTripper = (*EventAttribute)(nil)

File diff suppressed because it is too large Load Diff

View File

@@ -6,4 +6,4 @@ import (
// TODO: eliminate this after some version refactor
const Version = version.ABCIVersion
const Version = version.ABCISemVer

View File

@@ -1,12 +1,12 @@
package blockchain
package blocksync
import (
"errors"
"fmt"
"github.com/gogo/protobuf/proto"
"github.com/cosmos/gogoproto/proto"
bcproto "github.com/tendermint/tendermint/proto/tendermint/blockchain"
bcproto "github.com/tendermint/tendermint/proto/tendermint/blocksync"
"github.com/tendermint/tendermint/types"
)

View File

@@ -1,15 +1,16 @@
package blockchain
package blocksync_test
import (
"encoding/hex"
"math"
"testing"
"github.com/gogo/protobuf/proto"
"github.com/cosmos/gogoproto/proto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
bcproto "github.com/tendermint/tendermint/proto/tendermint/blockchain"
"github.com/tendermint/tendermint/blocksync"
bcproto "github.com/tendermint/tendermint/proto/tendermint/blocksync"
"github.com/tendermint/tendermint/types"
)
@@ -28,7 +29,7 @@ func TestBcBlockRequestMessageValidateBasic(t *testing.T) {
tc := tc
t.Run(tc.testName, func(t *testing.T) {
request := bcproto.BlockRequest{Height: tc.requestHeight}
assert.Equal(t, tc.expectErr, ValidateMsg(&request) != nil, "Validate Basic had an unexpected result")
assert.Equal(t, tc.expectErr, blocksync.ValidateMsg(&request) != nil, "Validate Basic had an unexpected result")
})
}
}
@@ -48,14 +49,14 @@ func TestBcNoBlockResponseMessageValidateBasic(t *testing.T) {
tc := tc
t.Run(tc.testName, func(t *testing.T) {
nonResponse := bcproto.NoBlockResponse{Height: tc.nonResponseHeight}
assert.Equal(t, tc.expectErr, ValidateMsg(&nonResponse) != nil, "Validate Basic had an unexpected result")
assert.Equal(t, tc.expectErr, blocksync.ValidateMsg(&nonResponse) != nil, "Validate Basic had an unexpected result")
})
}
}
func TestBcStatusRequestMessageValidateBasic(t *testing.T) {
request := bcproto.StatusRequest{}
assert.NoError(t, ValidateMsg(&request))
assert.NoError(t, blocksync.ValidateMsg(&request))
}
func TestBcStatusResponseMessageValidateBasic(t *testing.T) {
@@ -73,12 +74,12 @@ func TestBcStatusResponseMessageValidateBasic(t *testing.T) {
tc := tc
t.Run(tc.testName, func(t *testing.T) {
response := bcproto.StatusResponse{Height: tc.responseHeight}
assert.Equal(t, tc.expectErr, ValidateMsg(&response) != nil, "Validate Basic had an unexpected result")
assert.Equal(t, tc.expectErr, blocksync.ValidateMsg(&response) != nil, "Validate Basic had an unexpected result")
})
}
}
// nolint:lll // ignore line length in tests
//nolint:lll // ignore line length in tests
func TestBlockchainMessageVectors(t *testing.T) {
block := types.MakeBlock(int64(3), []types.Tx{types.Tx("Hello World")}, nil, nil)
block.Version.Block = 11 // overwrite updated protocol version

View File

@@ -1,4 +1,4 @@
package blockchain
package blocksync
import (
"errors"
@@ -58,7 +58,7 @@ var peerTimeout = 15 * time.Second // not const so we can override with tests
are not at peer limits, we can probably switch to consensus reactor
*/
// BlockPool keeps track of the fast sync peers, block requests and block responses.
// BlockPool keeps track of the block sync peers, block requests and block responses.
type BlockPool struct {
service.BaseService
startTime time.Time
@@ -410,6 +410,7 @@ func (pool *BlockPool) sendError(err error, peerID p2p.ID) {
}
// for debugging purposes
//
//nolint:unused
func (pool *BlockPool) debug() string {
pool.mtx.Lock()

View File

@@ -1,4 +1,4 @@
package blockchain
package blocksync
import (
"fmt"

View File

@@ -1,4 +1,4 @@
package blockchain
package blocksync
import (
"fmt"
@@ -7,15 +7,15 @@ import (
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/p2p"
bcproto "github.com/tendermint/tendermint/proto/tendermint/blockchain"
bcproto "github.com/tendermint/tendermint/proto/tendermint/blocksync"
sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/store"
"github.com/tendermint/tendermint/types"
)
const (
// BlockchainChannel is a channel for blocks and status updates (`BlockStore` height)
BlockchainChannel = byte(0x40)
// BlocksyncChannel is a channel for blocks and status updates (`BlockStore` height)
BlocksyncChannel = byte(0x40)
trySyncIntervalMS = 10
@@ -30,7 +30,7 @@ const (
)
type consensusReactor interface {
// for when we switch from blockchain reactor and fast sync to
// for when we switch from blockchain reactor and block sync to
// the consensus machine
SwitchToConsensus(state sm.State, skipWAL bool)
}
@@ -54,7 +54,7 @@ type Reactor struct {
blockExec *sm.BlockExecutor
store *store.BlockStore
pool *BlockPool
fastSync bool
blockSync bool
requestsCh <-chan BlockRequest
errorsCh <-chan peerError
@@ -62,7 +62,7 @@ type Reactor struct {
// NewReactor returns new reactor instance.
func NewReactor(state sm.State, blockExec *sm.BlockExecutor, store *store.BlockStore,
fastSync bool) *Reactor {
blockSync bool) *Reactor {
if state.LastBlockHeight != store.Height() {
panic(fmt.Sprintf("state (%v) and store (%v) height mismatch", state.LastBlockHeight,
@@ -85,7 +85,7 @@ func NewReactor(state sm.State, blockExec *sm.BlockExecutor, store *store.BlockS
blockExec: blockExec,
store: store,
pool: pool,
fastSync: fastSync,
blockSync: blockSync,
requestsCh: requestsCh,
errorsCh: errorsCh,
}
@@ -101,7 +101,7 @@ func (bcR *Reactor) SetLogger(l log.Logger) {
// OnStart implements service.Service.
func (bcR *Reactor) OnStart() error {
if bcR.fastSync {
if bcR.blockSync {
err := bcR.pool.Start()
if err != nil {
return err
@@ -111,9 +111,9 @@ func (bcR *Reactor) OnStart() error {
return nil
}
// SwitchToFastSync is called by the state sync reactor when switching to fast sync.
func (bcR *Reactor) SwitchToFastSync(state sm.State) error {
bcR.fastSync = true
// SwitchToBlockSync is called by the state sync reactor when switching to block sync.
func (bcR *Reactor) SwitchToBlockSync(state sm.State) error {
bcR.blockSync = true
bcR.initialState = state
bcR.pool.height = state.LastBlockHeight + 1
@@ -127,7 +127,7 @@ func (bcR *Reactor) SwitchToFastSync(state sm.State) error {
// OnStop implements service.Service.
func (bcR *Reactor) OnStop() {
if bcR.fastSync {
if bcR.blockSync {
if err := bcR.pool.Stop(); err != nil {
bcR.Logger.Error("Error stopping pool", "err", err)
}
@@ -138,7 +138,7 @@ func (bcR *Reactor) OnStop() {
func (bcR *Reactor) GetChannels() []*p2p.ChannelDescriptor {
return []*p2p.ChannelDescriptor{
{
ID: BlockchainChannel,
ID: BlocksyncChannel,
Priority: 5,
SendQueueCapacity: 1000,
RecvBufferCapacity: 50 * 4096,
@@ -157,7 +157,7 @@ func (bcR *Reactor) AddPeer(peer p2p.Peer) {
return
}
peer.Send(BlockchainChannel, msgBytes)
peer.Send(BlocksyncChannel, msgBytes)
// it's OK if send fails. will try later in poolRoutine
// peer is added to the pool once we receive the first
@@ -188,7 +188,7 @@ func (bcR *Reactor) respondToPeer(msg *bcproto.BlockRequest,
return false
}
return src.TrySend(BlockchainChannel, msgBytes)
return src.TrySend(BlocksyncChannel, msgBytes)
}
bcR.Logger.Info("Peer asking for a block we don't have", "src", src, "height", msg.Height)
@@ -199,7 +199,7 @@ func (bcR *Reactor) respondToPeer(msg *bcproto.BlockRequest,
return false
}
return src.TrySend(BlockchainChannel, msgBytes)
return src.TrySend(BlocksyncChannel, msgBytes)
}
// Receive implements Reactor by handling 4 types of messages (look below).
@@ -239,7 +239,7 @@ func (bcR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
bcR.Logger.Error("could not convert msg to protobut", "err", err)
return
}
src.TrySend(BlockchainChannel, msgBytes)
src.TrySend(BlocksyncChannel, msgBytes)
case *bcproto.StatusResponse:
// Got a peer status. Unverified.
bcR.pool.SetPeerRange(src.ID(), msg.Base, msg.Height)
@@ -291,7 +291,7 @@ func (bcR *Reactor) poolRoutine(stateSynced bool) {
continue
}
queued := peer.TrySend(BlockchainChannel, msgBytes)
queued := peer.TrySend(BlocksyncChannel, msgBytes)
if !queued {
bcR.Logger.Debug("Send queue is full, drop block request", "peer", peer.ID(), "height", request.Height)
}
@@ -303,7 +303,7 @@ func (bcR *Reactor) poolRoutine(stateSynced bool) {
case <-statusUpdateTicker.C:
// ask for status updates
go bcR.BroadcastStatusRequest() // nolint: errcheck
go bcR.BroadcastStatusRequest() //nolint: errcheck
}
}
@@ -359,14 +359,20 @@ FOR_LOOP:
didProcessCh <- struct{}{}
}
firstParts := first.MakePartSet(types.BlockPartSizeBytes)
firstParts, err := first.MakePartSet(types.BlockPartSizeBytes)
if err != nil {
bcR.Logger.Error("failed to make ",
"height", first.Height,
"err", err.Error())
break FOR_LOOP
}
firstPartSetHeader := firstParts.Header()
firstID := types.BlockID{Hash: first.Hash(), PartSetHeader: firstPartSetHeader}
// Finally, verify the first block using the second's commit
// NOTE: we can probably make this more efficient, but note that calling
// first.Hash() doesn't verify the tx contents, so MakePartSet() is
// currently necessary.
err := state.Validators.VerifyCommitLight(
err = state.Validators.VerifyCommitLight(
chainID, firstID, first.Height, second.LastCommit)
if err == nil {
@@ -400,7 +406,7 @@ FOR_LOOP:
// TODO: same thing for app - but we would need a way to
// get the hash without persisting the state
state, _, err = bcR.blockExec.ApplyBlock(state, firstID, first)
state, err = bcR.blockExec.ApplyBlock(state, firstID, first)
if err != nil {
// TODO This is bad, are we zombie?
panic(fmt.Sprintf("Failed to process committed block (%d:%X): %v", first.Height, first.Hash(), err))
@@ -409,7 +415,7 @@ FOR_LOOP:
if blocksSynced%100 == 0 {
lastRate = 0.9*lastRate + 0.1*(100/time.Since(lastHundred).Seconds())
bcR.Logger.Info("Fast Sync Rate", "height", bcR.pool.height,
bcR.Logger.Info("Block Sync Rate", "height", bcR.pool.height,
"max_peer_height", bcR.pool.MaxPeerHeight(), "blocks/s", lastRate)
lastHundred = time.Now()
}
@@ -430,7 +436,7 @@ func (bcR *Reactor) BroadcastStatusRequest() error {
return fmt.Errorf("could not convert msg to proto: %w", err)
}
bcR.Switch.Broadcast(BlockchainChannel, bm)
bcR.Switch.Broadcast(BlocksyncChannel, bm)
return nil
}

View File

@@ -1,4 +1,4 @@
package blockchain
package blocksync
import (
"fmt"
@@ -8,14 +8,16 @@ import (
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
dbm "github.com/tendermint/tm-db"
abci "github.com/tendermint/tendermint/abci/types"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/internal/test"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/mempool/mock"
mpmocks "github.com/tendermint/tendermint/mempool/mocks"
"github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/proxy"
sm "github.com/tendermint/tendermint/state"
@@ -41,7 +43,7 @@ func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.G
return &types.GenesisDoc{
GenesisTime: tmtime.Now(),
ChainID: config.ChainID(),
ChainID: test.DefaultTestChainID,
Validators: validators,
}, privValidators
}
@@ -52,6 +54,7 @@ type ReactorPair struct {
}
func newReactor(
t *testing.T,
logger log.Logger,
genDoc *types.GenesisDoc,
privVals []types.PrivValidator,
@@ -62,7 +65,7 @@ func newReactor(
app := &testApp{}
cc := proxy.NewLocalClientCreator(app)
proxyApp := proxy.NewAppConns(cc)
proxyApp := proxy.NewAppConns(cc, proxy.NopMetrics())
err := proxyApp.Start()
if err != nil {
panic(fmt.Errorf("error start app: %w", err))
@@ -70,7 +73,9 @@ func newReactor(
blockDB := dbm.NewMemDB()
stateDB := dbm.NewMemDB()
stateStore := sm.NewStore(stateDB)
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
DiscardABCIResponses: false,
})
blockStore := store.NewBlockStore(blockDB)
state, err := stateStore.LoadFromDBOrGenesisDoc(genDoc)
@@ -78,14 +83,28 @@ func newReactor(
panic(fmt.Errorf("error constructing state from genesis file: %w", err))
}
mp := &mpmocks.Mempool{}
mp.On("Lock").Return()
mp.On("Unlock").Return()
mp.On("FlushAppConn", mock.Anything).Return(nil)
mp.On("Update",
mock.Anything,
mock.Anything,
mock.Anything,
mock.Anything,
mock.Anything,
mock.Anything).Return(nil)
// Make the Reactor itself.
// NOTE we have to create and commit the blocks first because
// pool.height is determined from the store.
fastSync := true
db := dbm.NewMemDB()
stateStore = sm.NewStore(db)
stateStore = sm.NewStore(db, sm.StoreOptions{
DiscardABCIResponses: false,
})
blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(),
mock.Mempool{}, sm.EmptyEvidencePool{})
mp, sm.EmptyEvidencePool{}, blockStore)
if err = stateStore.Save(state); err != nil {
panic(err)
}
@@ -112,12 +131,13 @@ func newReactor(
lastBlockMeta.BlockID, []types.CommitSig{vote.CommitSig()})
}
thisBlock := makeBlock(blockHeight, state, lastCommit)
thisBlock := state.MakeBlock(blockHeight, nil, lastCommit, nil, state.Validators.Proposer.Address)
thisParts := thisBlock.MakePartSet(types.BlockPartSizeBytes)
thisParts, err := thisBlock.MakePartSet(types.BlockPartSizeBytes)
require.NoError(t, err)
blockID := types.BlockID{Hash: thisBlock.Hash(), PartSetHeader: thisParts.Header()}
state, _, err = blockExec.ApplyBlock(state, blockID, thisBlock)
state, err = blockExec.ApplyBlock(state, blockID, thisBlock)
if err != nil {
panic(fmt.Errorf("error apply block: %w", err))
}
@@ -132,7 +152,7 @@ func newReactor(
}
func TestNoBlockResponse(t *testing.T) {
config = cfg.ResetTestRoot("blockchain_reactor_test")
config = test.ResetTestRoot("blockchain_reactor_test")
defer os.RemoveAll(config.RootDir)
genDoc, privVals := randGenesisDoc(1, false, 30)
@@ -140,8 +160,8 @@ func TestNoBlockResponse(t *testing.T) {
reactorPairs := make([]ReactorPair, 2)
reactorPairs[0] = newReactor(log.TestingLogger(), genDoc, privVals, maxBlockHeight)
reactorPairs[1] = newReactor(log.TestingLogger(), genDoc, privVals, 0)
reactorPairs[0] = newReactor(t, log.TestingLogger(), genDoc, privVals, maxBlockHeight)
reactorPairs[1] = newReactor(t, log.TestingLogger(), genDoc, privVals, 0)
p2p.MakeConnectedSwitches(config.P2P, 2, func(i int, s *p2p.Switch) *p2p.Switch {
s.AddReactor("BLOCKCHAIN", reactorPairs[i].reactor)
@@ -194,7 +214,7 @@ func TestNoBlockResponse(t *testing.T) {
// Alternatively we could actually dial a TCP conn but
// that seems extreme.
func TestBadBlockStopsPeer(t *testing.T) {
config = cfg.ResetTestRoot("blockchain_reactor_test")
config = test.ResetTestRoot("blockchain_reactor_test")
defer os.RemoveAll(config.RootDir)
genDoc, privVals := randGenesisDoc(1, false, 30)
@@ -202,7 +222,7 @@ func TestBadBlockStopsPeer(t *testing.T) {
// Other chain needs a different validator set
otherGenDoc, otherPrivVals := randGenesisDoc(1, false, 30)
otherChain := newReactor(log.TestingLogger(), otherGenDoc, otherPrivVals, maxBlockHeight)
otherChain := newReactor(t, log.TestingLogger(), otherGenDoc, otherPrivVals, maxBlockHeight)
defer func() {
err := otherChain.reactor.Stop()
@@ -213,10 +233,10 @@ func TestBadBlockStopsPeer(t *testing.T) {
reactorPairs := make([]ReactorPair, 4)
reactorPairs[0] = newReactor(log.TestingLogger(), genDoc, privVals, maxBlockHeight)
reactorPairs[1] = newReactor(log.TestingLogger(), genDoc, privVals, 0)
reactorPairs[2] = newReactor(log.TestingLogger(), genDoc, privVals, 0)
reactorPairs[3] = newReactor(log.TestingLogger(), genDoc, privVals, 0)
reactorPairs[0] = newReactor(t, log.TestingLogger(), genDoc, privVals, maxBlockHeight)
reactorPairs[1] = newReactor(t, log.TestingLogger(), genDoc, privVals, 0)
reactorPairs[2] = newReactor(t, log.TestingLogger(), genDoc, privVals, 0)
reactorPairs[3] = newReactor(t, log.TestingLogger(), genDoc, privVals, 0)
switches := p2p.MakeConnectedSwitches(config.P2P, 4, func(i int, s *p2p.Switch) *p2p.Switch {
s.AddReactor("BLOCKCHAIN", reactorPairs[i].reactor)
@@ -254,7 +274,7 @@ func TestBadBlockStopsPeer(t *testing.T) {
// race, but can't be easily avoided.
reactorPairs[3].reactor.store = otherChain.reactor.store
lastReactorPair := newReactor(log.TestingLogger(), genDoc, privVals, 0)
lastReactorPair := newReactor(t, log.TestingLogger(), genDoc, privVals, 0)
reactorPairs = append(reactorPairs, lastReactorPair)
switches = append(switches, p2p.MakeConnectedSwitches(config.P2P, 1, func(i int, s *p2p.Switch) *p2p.Switch {
@@ -278,21 +298,6 @@ func TestBadBlockStopsPeer(t *testing.T) {
assert.True(t, lastReactorPair.reactor.Switch.Peers().Size() < len(reactorPairs)-1)
}
//----------------------------------------------
// utility funcs
func makeTxs(height int64) (txs []types.Tx) {
for i := 0; i < 10; i++ {
txs = append(txs, types.Tx([]byte{byte(height), byte(i)}))
}
return txs
}
func makeBlock(height int64, state sm.State, lastCommit *types.Commit) *types.Block {
block, _ := state.MakeBlock(height, makeTxs(height), lastCommit, nil, state.Validators.GetProposer().Address)
return block
}
type testApp struct {
abci.BaseApplication
}

View File

@@ -3,7 +3,7 @@ plugins:
- name: gogofaster
out: ./proto/
opt:
- Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types
- Mgoogle/protobuf/timestamp.proto=github.com/cosmos/gogoproto/types
- Mgoogle/protobuf/duration.proto=github.com/golang/protobuf/ptypes/duration
- plugins=grpc
- paths=source_relative

View File

@@ -1,7 +1,6 @@
build:
roots:
- proto
- third_party/proto
lint:
use:
- BASIC

View File

@@ -3,7 +3,6 @@ package debug
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"time"
@@ -82,7 +81,7 @@ func dumpCmdHandler(_ *cobra.Command, args []string) error {
func dumpDebugData(outDir string, conf *cfg.Config, rpc *rpchttp.HTTP) {
start := time.Now().UTC()
tmpDir, err := ioutil.TempDir(outDir, "tendermint_debug_tmp")
tmpDir, err := os.MkdirTemp(outDir, "tendermint_debug_tmp")
if err != nil {
logger.Error("failed to create temporary directory", "dir", tmpDir, "error", err)
return

View File

@@ -5,7 +5,6 @@ import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"path/filepath"
@@ -111,5 +110,5 @@ func writeStateJSONToFile(state interface{}, dir, filename string) error {
return fmt.Errorf("failed to encode state dump: %w", err)
}
return ioutil.WriteFile(path.Join(dir, filename), stateJSON, os.ModePerm)
return os.WriteFile(path.Join(dir, filename), stateJSON, os.ModePerm)
}

View File

@@ -3,7 +3,6 @@ package debug
import (
"errors"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -56,7 +55,7 @@ func killCmdHandler(cmd *cobra.Command, args []string) error {
// Create a temporary directory which will contain all the state dumps and
// relevant files and directories that will be compressed into a file.
tmpDir, err := ioutil.TempDir(os.TempDir(), "tendermint_debug_tmp")
tmpDir, err := os.MkdirTemp(os.TempDir(), "tendermint_debug_tmp")
if err != nil {
return fmt.Errorf("failed to create temporary directory: %w", err)
}
@@ -105,7 +104,7 @@ func killProc(pid uint64, dir string) error {
// pipe STDERR output from tailing the Tendermint process to a file
//
// NOTE: This will only work on UNIX systems.
cmd := exec.Command("tail", "-f", fmt.Sprintf("/proc/%d/fd/2", pid)) // nolint: gosec
cmd := exec.Command("tail", "-f", fmt.Sprintf("/proc/%d/fd/2", pid)) //nolint: gosec
outFile, err := os.Create(filepath.Join(dir, "stacktrace.out"))
if err != nil {

View File

@@ -3,7 +3,7 @@ package debug
import (
"context"
"fmt"
"io/ioutil"
"io"
"net/http"
"os"
"path"
@@ -67,16 +67,16 @@ func copyConfig(home, dir string) error {
func dumpProfile(dir, addr, profile string, debug int) error {
endpoint := fmt.Sprintf("%s/debug/pprof/%s?debug=%d", addr, profile, debug)
resp, err := http.Get(endpoint) // nolint: gosec
resp, err := http.Get(endpoint) //nolint: gosec
if err != nil {
return fmt.Errorf("failed to query for %s profile: %w", profile, err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read %s profile response body: %w", profile, err)
}
return ioutil.WriteFile(path.Join(dir, fmt.Sprintf("%s.out", profile)), body, os.ModePerm)
return os.WriteFile(path.Join(dir, fmt.Sprintf("%s.out", profile)), body, os.ModePerm)
}

View File

@@ -40,6 +40,9 @@ replace the backend. The default start-height is 0, meaning the tooling will sta
reindex from the base block height(inclusive); and the default end-height is 0, meaning
the tooling will reindex until the latest block height(inclusive). User can omit
either or both arguments.
Note: This operation requires ABCI Responses. Do not set DiscardABCIResponses to true if you
want to use this command.
`,
Example: `
tendermint reindex-event
@@ -54,12 +57,18 @@ either or both arguments.
return
}
state, err := ss.Load()
if err != nil {
fmt.Println(reindexFailed, err)
return
}
if err := checkValidHeight(bs); err != nil {
fmt.Println(reindexFailed, err)
return
}
bi, ti, err := loadEventSinks(config)
bi, ti, err := loadEventSinks(config, state.ChainID)
if err != nil {
fmt.Println(reindexFailed, err)
return
@@ -91,7 +100,7 @@ func init() {
ReIndexEventCmd.Flags().Int64Var(&endHeight, "end-height", 0, "the block height would like to finish for re-index")
}
func loadEventSinks(cfg *tmcfg.Config) (indexer.BlockIndexer, txindex.TxIndexer, error) {
func loadEventSinks(cfg *tmcfg.Config, chainID string) (indexer.BlockIndexer, txindex.TxIndexer, error) {
switch strings.ToLower(cfg.TxIndex.Indexer) {
case "null":
return nil, nil, errors.New("found null event sink, please check the tx-index section in the config.toml")
@@ -100,7 +109,7 @@ func loadEventSinks(cfg *tmcfg.Config) (indexer.BlockIndexer, txindex.TxIndexer,
if conn == "" {
return nil, nil, errors.New("the psql connection settings cannot be empty")
}
es, err := psql.NewEventSink(conn, cfg.ChainID())
es, err := psql.NewEventSink(conn, chainID)
if err != nil {
return nil, nil, err
}

View File

@@ -9,14 +9,16 @@ import (
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
dbm "github.com/tendermint/tm-db"
abcitypes "github.com/tendermint/tendermint/abci/types"
tmcfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/internal/test"
prototmstate "github.com/tendermint/tendermint/proto/tendermint/state"
blockmocks "github.com/tendermint/tendermint/state/indexer/mocks"
"github.com/tendermint/tendermint/state/mocks"
txmocks "github.com/tendermint/tendermint/state/txindex/mocks"
"github.com/tendermint/tendermint/types"
dbm "github.com/tendermint/tm-db"
)
const (
@@ -97,7 +99,7 @@ func TestLoadEventSink(t *testing.T) {
cfg := tmcfg.TestConfig()
cfg.TxIndex.Indexer = tc.sinks
cfg.TxIndex.PsqlConn = tc.connURL
_, _, err := loadEventSinks(cfg)
_, _, err := loadEventSinks(cfg, test.DefaultTestChainID)
if tc.loadErr {
require.Error(t, err, idx)
} else {

View File

@@ -14,6 +14,12 @@ import (
"github.com/tendermint/tendermint/store"
)
var removeBlock bool = false
func init() {
RollbackStateCmd.Flags().BoolVar(&removeBlock, "hard", false, "remove last block as well as state")
}
var RollbackStateCmd = &cobra.Command{
Use: "rollback",
Short: "rollback tendermint state by one height",
@@ -21,17 +27,23 @@ var RollbackStateCmd = &cobra.Command{
A state rollback is performed to recover from an incorrect application state transition,
when Tendermint has persisted an incorrect app hash and is thus unable to make
progress. Rollback overwrites a state at height n with the state at height n - 1.
The application should also roll back to height n - 1. No blocks are removed, so upon
restarting Tendermint the transactions in block n will be re-executed against the
application.
The application should also roll back to height n - 1. If the --hard flag is not used,
no blocks will be removed so upon restarting Tendermint the transactions in block n will be
re-executed against the application. Using --hard will also remove block n. This can
be done multiple times.
`,
RunE: func(cmd *cobra.Command, args []string) error {
height, hash, err := RollbackState(config)
height, hash, err := RollbackState(config, removeBlock)
if err != nil {
return fmt.Errorf("failed to rollback state: %w", err)
}
fmt.Printf("Rolled back state to height %d and hash %v", height, hash)
if removeBlock {
fmt.Printf("Rolled back both state and block to height %d and hash %X\n", height, hash)
} else {
fmt.Printf("Rolled back state to height %d and hash %X\n", height, hash)
}
return nil
},
}
@@ -39,7 +51,7 @@ application.
// RollbackState takes the state at the current height n and overwrites it with the state
// at height n - 1. Note state here refers to tendermint state not application state.
// Returns the latest state height and app hash alongside an error if there was one.
func RollbackState(config *cfg.Config) (int64, []byte, error) {
func RollbackState(config *cfg.Config, removeBlock bool) (int64, []byte, error) {
// use the parsed config to load the block and state store
blockStore, stateStore, err := loadStateAndBlockStore(config)
if err != nil {
@@ -51,7 +63,7 @@ func RollbackState(config *cfg.Config) (int64, []byte, error) {
}()
// rollback the last state
return state.Rollback(blockStore, stateStore)
return state.Rollback(blockStore, stateStore, removeBlock)
}
func loadStateAndBlockStore(config *cfg.Config) (*store.BlockStore, state.Store, error) {
@@ -77,7 +89,9 @@ func loadStateAndBlockStore(config *cfg.Config) (*store.BlockStore, state.Store,
if err != nil {
return nil, nil, err
}
stateStore := state.NewStore(stateDB)
stateStore := state.NewStore(stateDB, state.StoreOptions{
DiscardABCIResponses: config.Storage.DiscardABCIResponses,
})
return blockStore, stateStore, nil
}

View File

@@ -53,6 +53,11 @@ func ParseConfig(cmd *cobra.Command) (*cfg.Config, error) {
if err := conf.ValidateBasic(); err != nil {
return nil, fmt.Errorf("error in config file: %v", err)
}
if warnings := conf.CheckDeprecated(); len(warnings) > 0 {
for _, warning := range warnings {
logger.Info("deprecated usage found in configuration file", "usage", warning)
}
}
return conf, nil
}

View File

@@ -2,7 +2,6 @@ package commands
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
@@ -168,5 +167,5 @@ func WriteConfigVals(dir string, vals map[string]string) error {
data += fmt.Sprintf("%s = \"%s\"\n", k, v)
}
cfile := filepath.Join(dir, "config.toml")
return ioutil.WriteFile(cfile, []byte(data), 0600)
return os.WriteFile(cfile, []byte(data), 0600)
}

View File

@@ -31,7 +31,7 @@ func AddNodeFlags(cmd *cobra.Command) {
"socket address to listen on for connections from external priv_validator process")
// node flags
cmd.Flags().Bool("fast_sync", config.FastSyncMode, "fast blockchain syncing")
cmd.Flags().Bool("block_sync", config.BlockSyncMode, "sync the block chain using the blocksync algorithm")
cmd.Flags().BytesHexVar(
&genesisHash,
"genesis_hash",

View File

@@ -1,6 +1,7 @@
package commands
import (
"encoding/json"
"fmt"
"github.com/spf13/cobra"
@@ -13,6 +14,30 @@ var VersionCmd = &cobra.Command{
Use: "version",
Short: "Show version info",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(version.TMCoreSemVer)
tmVersion := version.TMCoreSemVer
if version.TMGitCommitHash != "" {
tmVersion += "+" + version.TMGitCommitHash
}
if verbose {
values, _ := json.MarshalIndent(struct {
Tendermint string `json:"tendermint"`
ABCI string `json:"abci"`
BlockProtocol uint64 `json:"block_protocol"`
P2PProtocol uint64 `json:"p2p_protocol"`
}{
Tendermint: tmVersion,
ABCI: version.ABCISemVer,
BlockProtocol: version.BlockProtocol,
P2PProtocol: version.P2PProtocol,
}, "", " ")
fmt.Println(string(values))
} else {
fmt.Println(tmVersion)
}
},
}
func init() {
VersionCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Show protocol and library versions")
}

View File

@@ -7,7 +7,10 @@ import (
"net/http"
"os"
"path/filepath"
"regexp"
"time"
"github.com/tendermint/tendermint/version"
)
const (
@@ -28,6 +31,19 @@ const (
// Default is v0.
MempoolV0 = "v0"
MempoolV1 = "v1"
DefaultTendermintDir = ".tendermint"
DefaultConfigDir = "config"
DefaultDataDir = "data"
DefaultConfigFileName = "config.toml"
DefaultGenesisJSONName = "genesis.json"
DefaultPrivValKeyName = "priv_validator_key.json"
DefaultPrivValStateName = "priv_validator_state.json"
DefaultNodeKeyName = "node_key.json"
DefaultAddrBookName = "addrbook.json"
)
// NOTE: Most of the structs & relevant comments + the
@@ -37,29 +53,19 @@ const (
// config/toml.go
// NOTE: libs/cli must know to look in the config dir!
var (
DefaultTendermintDir = ".tendermint"
defaultConfigDir = "config"
defaultDataDir = "data"
defaultConfigFilePath = filepath.Join(DefaultConfigDir, DefaultConfigFileName)
defaultGenesisJSONPath = filepath.Join(DefaultConfigDir, DefaultGenesisJSONName)
defaultPrivValKeyPath = filepath.Join(DefaultConfigDir, DefaultPrivValKeyName)
defaultPrivValStatePath = filepath.Join(DefaultDataDir, DefaultPrivValStateName)
defaultConfigFileName = "config.toml"
defaultGenesisJSONName = "genesis.json"
defaultPrivValKeyName = "priv_validator_key.json"
defaultPrivValStateName = "priv_validator_state.json"
defaultNodeKeyName = "node_key.json"
defaultAddrBookName = "addrbook.json"
defaultConfigFilePath = filepath.Join(defaultConfigDir, defaultConfigFileName)
defaultGenesisJSONPath = filepath.Join(defaultConfigDir, defaultGenesisJSONName)
defaultPrivValKeyPath = filepath.Join(defaultConfigDir, defaultPrivValKeyName)
defaultPrivValStatePath = filepath.Join(defaultDataDir, defaultPrivValStateName)
defaultNodeKeyPath = filepath.Join(defaultConfigDir, defaultNodeKeyName)
defaultAddrBookPath = filepath.Join(defaultConfigDir, defaultAddrBookName)
defaultNodeKeyPath = filepath.Join(DefaultConfigDir, DefaultNodeKeyName)
defaultAddrBookPath = filepath.Join(DefaultConfigDir, DefaultAddrBookName)
minSubscriptionBufferSize = 100
defaultSubscriptionBufferSize = 200
// taken from https://semver.org/
semverRegexp = regexp.MustCompile(`^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`)
)
// Config defines the top level configuration for a Tendermint node
@@ -72,8 +78,9 @@ type Config struct {
P2P *P2PConfig `mapstructure:"p2p"`
Mempool *MempoolConfig `mapstructure:"mempool"`
StateSync *StateSyncConfig `mapstructure:"statesync"`
FastSync *FastSyncConfig `mapstructure:"fastsync"`
BlockSync *BlockSyncConfig `mapstructure:"blocksync"`
Consensus *ConsensusConfig `mapstructure:"consensus"`
Storage *StorageConfig `mapstructure:"storage"`
TxIndex *TxIndexConfig `mapstructure:"tx_index"`
Instrumentation *InstrumentationConfig `mapstructure:"instrumentation"`
}
@@ -86,8 +93,9 @@ func DefaultConfig() *Config {
P2P: DefaultP2PConfig(),
Mempool: DefaultMempoolConfig(),
StateSync: DefaultStateSyncConfig(),
FastSync: DefaultFastSyncConfig(),
BlockSync: DefaultBlockSyncConfig(),
Consensus: DefaultConsensusConfig(),
Storage: DefaultStorageConfig(),
TxIndex: DefaultTxIndexConfig(),
Instrumentation: DefaultInstrumentationConfig(),
}
@@ -101,8 +109,9 @@ func TestConfig() *Config {
P2P: TestP2PConfig(),
Mempool: TestMempoolConfig(),
StateSync: TestStateSyncConfig(),
FastSync: TestFastSyncConfig(),
BlockSync: TestBlockSyncConfig(),
Consensus: TestConsensusConfig(),
Storage: TestStorageConfig(),
TxIndex: TestTxIndexConfig(),
Instrumentation: TestInstrumentationConfig(),
}
@@ -136,8 +145,8 @@ func (cfg *Config) ValidateBasic() error {
if err := cfg.StateSync.ValidateBasic(); err != nil {
return fmt.Errorf("error in [statesync] section: %w", err)
}
if err := cfg.FastSync.ValidateBasic(); err != nil {
return fmt.Errorf("error in [fastsync] section: %w", err)
if err := cfg.BlockSync.ValidateBasic(); err != nil {
return fmt.Errorf("error in [blocksync] section: %w", err)
}
if err := cfg.Consensus.ValidateBasic(); err != nil {
return fmt.Errorf("error in [consensus] section: %w", err)
@@ -148,13 +157,21 @@ func (cfg *Config) ValidateBasic() error {
return nil
}
// CheckDeprecated returns any deprecation warnings. These are printed to the operator on startup
func (cfg *Config) CheckDeprecated() []string {
var warnings []string
return warnings
}
//-----------------------------------------------------------------------------
// BaseConfig
// BaseConfig defines the base configuration for a Tendermint node
type BaseConfig struct { //nolint: maligned
// chainID is unexposed and immutable but here for convenience
chainID string
// The version of the Tendermint binary that created
// or last modified the config file
Version string `mapstructure:"version"`
// The root directory for all data.
// This should be set in viper so it can unmarshal into this struct
@@ -167,10 +184,10 @@ type BaseConfig struct { //nolint: maligned
// A custom human readable name for this node
Moniker string `mapstructure:"moniker"`
// If this node is many blocks behind the tip of the chain, FastSync
// If this node is many blocks behind the tip of the chain, Blocksync
// allows them to catchup quickly by downloading blocks in parallel
// and verifying their commits
FastSyncMode bool `mapstructure:"fast_sync"`
BlockSyncMode bool `mapstructure:"block_sync"`
// Database backend: goleveldb | cleveldb | boltdb | rocksdb
// * goleveldb (github.com/syndtr/goleveldb - most popular implementation)
@@ -229,6 +246,7 @@ type BaseConfig struct { //nolint: maligned
// DefaultBaseConfig returns a default base configuration for a Tendermint node
func DefaultBaseConfig() BaseConfig {
return BaseConfig{
Version: version.TMCoreSemVer,
Genesis: defaultGenesisJSONPath,
PrivValidatorKey: defaultPrivValKeyPath,
PrivValidatorState: defaultPrivValStatePath,
@@ -238,27 +256,22 @@ func DefaultBaseConfig() BaseConfig {
ABCI: "socket",
LogLevel: DefaultLogLevel,
LogFormat: LogFormatPlain,
FastSyncMode: true,
BlockSyncMode: true,
FilterPeers: false,
DBBackend: "goleveldb",
DBPath: "data",
DBPath: DefaultDataDir,
}
}
// TestBaseConfig returns a base configuration for testing a Tendermint node
func TestBaseConfig() BaseConfig {
cfg := DefaultBaseConfig()
cfg.chainID = "tendermint_test"
cfg.ProxyApp = "kvstore"
cfg.FastSyncMode = false
cfg.BlockSyncMode = false
cfg.DBBackend = "memdb"
return cfg
}
func (cfg BaseConfig) ChainID() string {
return cfg.chainID
}
// GenesisFile returns the full path to the genesis.json file
func (cfg BaseConfig) GenesisFile() string {
return rootify(cfg.Genesis, cfg.RootDir)
@@ -287,6 +300,12 @@ func (cfg BaseConfig) DBDir() string {
// ValidateBasic performs basic validation (checking param bounds, etc.) and
// returns an error if any check fails.
func (cfg BaseConfig) ValidateBasic() error {
// version on old config files aren't set so we can't expect it
// always to exist
if cfg.Version != "" && !semverRegexp.MatchString(cfg.Version) {
return fmt.Errorf("invalid version string: %s", cfg.Version)
}
switch cfg.LogFormat {
case LogFormatPlain, LogFormatJSON:
default:
@@ -492,7 +511,7 @@ func (cfg RPCConfig) KeyFile() string {
if filepath.IsAbs(path) {
return path
}
return rootify(filepath.Join(defaultConfigDir, path), cfg.RootDir)
return rootify(filepath.Join(DefaultConfigDir, path), cfg.RootDir)
}
func (cfg RPCConfig) CertFile() string {
@@ -500,7 +519,7 @@ func (cfg RPCConfig) CertFile() string {
if filepath.IsAbs(path) {
return path
}
return rootify(filepath.Join(defaultConfigDir, path), cfg.RootDir)
return rootify(filepath.Join(DefaultConfigDir, path), cfg.RootDir)
}
func (cfg RPCConfig) IsTLSEnabled() bool {
@@ -817,7 +836,7 @@ func DefaultStateSyncConfig() *StateSyncConfig {
}
}
// TestFastSyncConfig returns a default configuration for the state sync service
// TestStateSyncConfig returns a default configuration for the state sync service
func TestStateSyncConfig() *StateSyncConfig {
return DefaultStateSyncConfig()
}
@@ -873,34 +892,34 @@ func (cfg *StateSyncConfig) ValidateBasic() error {
}
//-----------------------------------------------------------------------------
// FastSyncConfig
// BlockSyncConfig
// FastSyncConfig defines the configuration for the Tendermint fast sync service
type FastSyncConfig struct {
// BlockSyncConfig (formerly known as FastSync) defines the configuration for the Tendermint block sync service
type BlockSyncConfig struct {
Version string `mapstructure:"version"`
}
// DefaultFastSyncConfig returns a default configuration for the fast sync service
func DefaultFastSyncConfig() *FastSyncConfig {
return &FastSyncConfig{
// DefaultBlockSyncConfig returns a default configuration for the block sync service
func DefaultBlockSyncConfig() *BlockSyncConfig {
return &BlockSyncConfig{
Version: "v0",
}
}
// TestFastSyncConfig returns a default configuration for the fast sync.
func TestFastSyncConfig() *FastSyncConfig {
return DefaultFastSyncConfig()
// TestBlockSyncConfig returns a default configuration for the block sync.
func TestBlockSyncConfig() *BlockSyncConfig {
return DefaultBlockSyncConfig()
}
// ValidateBasic performs basic validation.
func (cfg *FastSyncConfig) ValidateBasic() error {
func (cfg *BlockSyncConfig) ValidateBasic() error {
switch cfg.Version {
case "v0":
return nil
case "v1", "v2":
return fmt.Errorf("fast sync version %s has been deprecated. Please use v0 instead", cfg.Version)
return fmt.Errorf("blocksync version %s has been deprecated. Please use v0 instead", cfg.Version)
default:
return fmt.Errorf("unknown fastsync version %s", cfg.Version)
return fmt.Errorf("unknown blocksync version %s", cfg.Version)
}
}
@@ -949,7 +968,7 @@ type ConsensusConfig struct {
// DefaultConsensusConfig returns a default configuration for the consensus service
func DefaultConsensusConfig() *ConsensusConfig {
return &ConsensusConfig{
WalPath: filepath.Join(defaultDataDir, "cs.wal", "wal"),
WalPath: filepath.Join(DefaultDataDir, "cs.wal", "wal"),
TimeoutPropose: 3000 * time.Millisecond,
TimeoutProposeDelta: 500 * time.Millisecond,
TimeoutPrevote: 1000 * time.Millisecond,
@@ -1069,11 +1088,41 @@ func (cfg *ConsensusConfig) ValidateBasic() error {
}
//-----------------------------------------------------------------------------
// StorageConfig
// StorageConfig allows more fine-grained control over certain storage-related
// behavior.
type StorageConfig struct {
// Set to false to ensure ABCI responses are persisted. ABCI responses are
// required for `/block_results` RPC queries, and to reindex events in the
// command-line tool.
DiscardABCIResponses bool `mapstructure:"discard_abci_responses"`
}
// DefaultStorageConfig returns the default configuration options relating to
// Tendermint storage optimization.
func DefaultStorageConfig() *StorageConfig {
return &StorageConfig{
DiscardABCIResponses: false,
}
}
// TestStorageConfig returns storage configuration that can be used for
// testing.
func TestStorageConfig() *StorageConfig {
return &StorageConfig{
DiscardABCIResponses: false,
}
}
// -----------------------------------------------------------------------------
// TxIndexConfig
// Remember that Event has the following structure:
// type: [
// key: value,
// ...
//
// key: value,
// ...
//
// ]
//
// CompositeKeys are constructed by `type.key`

View File

@@ -1,4 +1,4 @@
package config
package config_test
import (
"reflect"
@@ -7,13 +7,15 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/config"
)
func TestDefaultConfig(t *testing.T) {
assert := assert.New(t)
// set up some defaults
cfg := DefaultConfig()
cfg := config.DefaultConfig()
assert.NotNil(cfg.P2P)
assert.NotNil(cfg.Mempool)
assert.NotNil(cfg.Consensus)
@@ -31,7 +33,7 @@ func TestDefaultConfig(t *testing.T) {
}
func TestConfigValidateBasic(t *testing.T) {
cfg := DefaultConfig()
cfg := config.DefaultConfig()
assert.NoError(t, cfg.ValidateBasic())
// tamper with timeout_propose
@@ -41,7 +43,7 @@ func TestConfigValidateBasic(t *testing.T) {
func TestTLSConfiguration(t *testing.T) {
assert := assert.New(t)
cfg := DefaultConfig()
cfg := config.DefaultConfig()
cfg.SetRoot("/home/user")
cfg.RPC.TLSCertFile = "file.crt"
@@ -56,7 +58,7 @@ func TestTLSConfiguration(t *testing.T) {
}
func TestBaseConfigValidateBasic(t *testing.T) {
cfg := TestBaseConfig()
cfg := config.TestBaseConfig()
assert.NoError(t, cfg.ValidateBasic())
// tamper with log format
@@ -65,7 +67,7 @@ func TestBaseConfigValidateBasic(t *testing.T) {
}
func TestRPCConfigValidateBasic(t *testing.T) {
cfg := TestRPCConfig()
cfg := config.TestRPCConfig()
assert.NoError(t, cfg.ValidateBasic())
fieldsToTest := []string{
@@ -86,7 +88,7 @@ func TestRPCConfigValidateBasic(t *testing.T) {
}
func TestP2PConfigValidateBasic(t *testing.T) {
cfg := TestP2PConfig()
cfg := config.TestP2PConfig()
assert.NoError(t, cfg.ValidateBasic())
fieldsToTest := []string{
@@ -106,7 +108,7 @@ func TestP2PConfigValidateBasic(t *testing.T) {
}
func TestMempoolConfigValidateBasic(t *testing.T) {
cfg := TestMempoolConfig()
cfg := config.TestMempoolConfig()
assert.NoError(t, cfg.ValidateBasic())
fieldsToTest := []string{
@@ -124,12 +126,12 @@ func TestMempoolConfigValidateBasic(t *testing.T) {
}
func TestStateSyncConfigValidateBasic(t *testing.T) {
cfg := TestStateSyncConfig()
cfg := config.TestStateSyncConfig()
require.NoError(t, cfg.ValidateBasic())
}
func TestFastSyncConfigValidateBasic(t *testing.T) {
cfg := TestFastSyncConfig()
func TestBlockSyncConfigValidateBasic(t *testing.T) {
cfg := config.TestBlockSyncConfig()
assert.NoError(t, cfg.ValidateBasic())
// tamper with version
@@ -141,35 +143,35 @@ func TestFastSyncConfigValidateBasic(t *testing.T) {
}
func TestConsensusConfig_ValidateBasic(t *testing.T) {
// nolint: lll
//nolint: lll
testcases := map[string]struct {
modify func(*ConsensusConfig)
modify func(*config.ConsensusConfig)
expectErr bool
}{
"TimeoutPropose": {func(c *ConsensusConfig) { c.TimeoutPropose = time.Second }, false},
"TimeoutPropose negative": {func(c *ConsensusConfig) { c.TimeoutPropose = -1 }, true},
"TimeoutProposeDelta": {func(c *ConsensusConfig) { c.TimeoutProposeDelta = time.Second }, false},
"TimeoutProposeDelta negative": {func(c *ConsensusConfig) { c.TimeoutProposeDelta = -1 }, true},
"TimeoutPrevote": {func(c *ConsensusConfig) { c.TimeoutPrevote = time.Second }, false},
"TimeoutPrevote negative": {func(c *ConsensusConfig) { c.TimeoutPrevote = -1 }, true},
"TimeoutPrevoteDelta": {func(c *ConsensusConfig) { c.TimeoutPrevoteDelta = time.Second }, false},
"TimeoutPrevoteDelta negative": {func(c *ConsensusConfig) { c.TimeoutPrevoteDelta = -1 }, true},
"TimeoutPrecommit": {func(c *ConsensusConfig) { c.TimeoutPrecommit = time.Second }, false},
"TimeoutPrecommit negative": {func(c *ConsensusConfig) { c.TimeoutPrecommit = -1 }, true},
"TimeoutPrecommitDelta": {func(c *ConsensusConfig) { c.TimeoutPrecommitDelta = time.Second }, false},
"TimeoutPrecommitDelta negative": {func(c *ConsensusConfig) { c.TimeoutPrecommitDelta = -1 }, true},
"TimeoutCommit": {func(c *ConsensusConfig) { c.TimeoutCommit = time.Second }, false},
"TimeoutCommit negative": {func(c *ConsensusConfig) { c.TimeoutCommit = -1 }, true},
"PeerGossipSleepDuration": {func(c *ConsensusConfig) { c.PeerGossipSleepDuration = time.Second }, false},
"PeerGossipSleepDuration negative": {func(c *ConsensusConfig) { c.PeerGossipSleepDuration = -1 }, true},
"PeerQueryMaj23SleepDuration": {func(c *ConsensusConfig) { c.PeerQueryMaj23SleepDuration = time.Second }, false},
"PeerQueryMaj23SleepDuration negative": {func(c *ConsensusConfig) { c.PeerQueryMaj23SleepDuration = -1 }, true},
"DoubleSignCheckHeight negative": {func(c *ConsensusConfig) { c.DoubleSignCheckHeight = -1 }, true},
"TimeoutPropose": {func(c *config.ConsensusConfig) { c.TimeoutPropose = time.Second }, false},
"TimeoutPropose negative": {func(c *config.ConsensusConfig) { c.TimeoutPropose = -1 }, true},
"TimeoutProposeDelta": {func(c *config.ConsensusConfig) { c.TimeoutProposeDelta = time.Second }, false},
"TimeoutProposeDelta negative": {func(c *config.ConsensusConfig) { c.TimeoutProposeDelta = -1 }, true},
"TimeoutPrevote": {func(c *config.ConsensusConfig) { c.TimeoutPrevote = time.Second }, false},
"TimeoutPrevote negative": {func(c *config.ConsensusConfig) { c.TimeoutPrevote = -1 }, true},
"TimeoutPrevoteDelta": {func(c *config.ConsensusConfig) { c.TimeoutPrevoteDelta = time.Second }, false},
"TimeoutPrevoteDelta negative": {func(c *config.ConsensusConfig) { c.TimeoutPrevoteDelta = -1 }, true},
"TimeoutPrecommit": {func(c *config.ConsensusConfig) { c.TimeoutPrecommit = time.Second }, false},
"TimeoutPrecommit negative": {func(c *config.ConsensusConfig) { c.TimeoutPrecommit = -1 }, true},
"TimeoutPrecommitDelta": {func(c *config.ConsensusConfig) { c.TimeoutPrecommitDelta = time.Second }, false},
"TimeoutPrecommitDelta negative": {func(c *config.ConsensusConfig) { c.TimeoutPrecommitDelta = -1 }, true},
"TimeoutCommit": {func(c *config.ConsensusConfig) { c.TimeoutCommit = time.Second }, false},
"TimeoutCommit negative": {func(c *config.ConsensusConfig) { c.TimeoutCommit = -1 }, true},
"PeerGossipSleepDuration": {func(c *config.ConsensusConfig) { c.PeerGossipSleepDuration = time.Second }, false},
"PeerGossipSleepDuration negative": {func(c *config.ConsensusConfig) { c.PeerGossipSleepDuration = -1 }, true},
"PeerQueryMaj23SleepDuration": {func(c *config.ConsensusConfig) { c.PeerQueryMaj23SleepDuration = time.Second }, false},
"PeerQueryMaj23SleepDuration negative": {func(c *config.ConsensusConfig) { c.PeerQueryMaj23SleepDuration = -1 }, true},
"DoubleSignCheckHeight negative": {func(c *config.ConsensusConfig) { c.DoubleSignCheckHeight = -1 }, true},
}
for desc, tc := range testcases {
tc := tc // appease linter
t.Run(desc, func(t *testing.T) {
cfg := DefaultConsensusConfig()
cfg := config.DefaultConsensusConfig()
tc.modify(cfg)
err := cfg.ValidateBasic()
@@ -183,7 +185,7 @@ func TestConsensusConfig_ValidateBasic(t *testing.T) {
}
func TestInstrumentationConfigValidateBasic(t *testing.T) {
cfg := TestInstrumentationConfig()
cfg := config.TestInstrumentationConfig()
assert.NoError(t, cfg.ValidateBasic())
// tamper with maximum open connections

View File

@@ -2,8 +2,6 @@ package config
import (
"bytes"
"fmt"
"io/ioutil"
"path/filepath"
"strings"
"text/template"
@@ -34,10 +32,10 @@ func EnsureRoot(rootDir string) {
if err := tmos.EnsureDir(rootDir, DefaultDirPerm); err != nil {
panic(err.Error())
}
if err := tmos.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil {
if err := tmos.EnsureDir(filepath.Join(rootDir, DefaultConfigDir), DefaultDirPerm); err != nil {
panic(err.Error())
}
if err := tmos.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil {
if err := tmos.EnsureDir(filepath.Join(rootDir, DefaultDataDir), DefaultDirPerm); err != nil {
panic(err.Error())
}
@@ -76,6 +74,10 @@ const defaultConfigTemplate = `# This is a TOML config file.
# "$HOME/.tendermint" by default, but could be changed via $TMHOME env variable
# or --home cmd flag.
# The version of the Tendermint binary that created or
# last modified the config file. Do not modify this.
version = "{{ .BaseConfig.Version }}"
#######################################################################
### Main Base Config Options ###
#######################################################################
@@ -87,10 +89,10 @@ proxy_app = "{{ .BaseConfig.ProxyApp }}"
# A custom human readable name for this node
moniker = "{{ .BaseConfig.Moniker }}"
# If this node is many blocks behind the tip of the chain, FastSync
# If this node is many blocks behind the tip of the chain, BlockSync
# allows them to catchup quickly by downloading blocks in parallel
# and verifying their commits
fast_sync = {{ .BaseConfig.FastSyncMode }}
block_sync = {{ .BaseConfig.BlockSyncMode }}
# Database backend: goleveldb | cleveldb | boltdb | rocksdb | badgerdb
# * goleveldb (github.com/syndtr/goleveldb - most popular implementation)
@@ -429,17 +431,17 @@ chunk_request_timeout = "{{ .StateSync.ChunkRequestTimeout }}"
chunk_fetchers = "{{ .StateSync.ChunkFetchers }}"
#######################################################
### Fast Sync Configuration Connections ###
### Block Sync Configuration Options ###
#######################################################
[fastsync]
[blocksync]
# Fast Sync version to use:
# Block Sync version to use:
#
# In v0.37, v1 and v2 of the fast sync protocol were deprecated.
# In v0.37, v1 and v2 of the block sync protocols were deprecated.
# Please use v0 instead.
#
# 1) "v0" - the default fast sync implementation
version = "{{ .FastSync.Version }}"
# 1) "v0" - the default block sync implementation
version = "{{ .BlockSync.Version }}"
#######################################################
### Consensus Configuration Options ###
@@ -482,6 +484,17 @@ create_empty_blocks_interval = "{{ .Consensus.CreateEmptyBlocksInterval }}"
peer_gossip_sleep_duration = "{{ .Consensus.PeerGossipSleepDuration }}"
peer_query_maj23_sleep_duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}"
#######################################################
### Storage Configuration Options ###
#######################################################
[storage]
# Set to true to discard ABCI responses from the state store, which can save a
# considerable amount of disk space. Set to false to ensure ABCI responses are
# persisted. ABCI responses are required for /block_results RPC queries, and to
# reindex events in the command-line tool.
discard_abci_responses = {{ .Storage.DiscardABCIResponses}}
#######################################################
### Transaction Indexer Configuration Options ###
#######################################################
@@ -526,101 +539,3 @@ max_open_connections = {{ .Instrumentation.MaxOpenConnections }}
# Instrumentation namespace
namespace = "{{ .Instrumentation.Namespace }}"
`
/****** these are for test settings ***********/
func ResetTestRoot(testName string) *Config {
return ResetTestRootWithChainID(testName, "")
}
func ResetTestRootWithChainID(testName string, chainID string) *Config {
// create a unique, concurrency-safe test directory under os.TempDir()
rootDir, err := ioutil.TempDir("", fmt.Sprintf("%s-%s_", chainID, testName))
if err != nil {
panic(err)
}
// ensure config and data subdirs are created
if err := tmos.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil {
panic(err)
}
if err := tmos.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil {
panic(err)
}
baseConfig := DefaultBaseConfig()
configFilePath := filepath.Join(rootDir, defaultConfigFilePath)
genesisFilePath := filepath.Join(rootDir, baseConfig.Genesis)
privKeyFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorKey)
privStateFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorState)
// Write default config file if missing.
if !tmos.FileExists(configFilePath) {
writeDefaultConfigFile(configFilePath)
}
if !tmos.FileExists(genesisFilePath) {
if chainID == "" {
chainID = "tendermint_test"
}
testGenesis := fmt.Sprintf(testGenesisFmt, chainID)
tmos.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644)
}
// we always overwrite the priv val
tmos.MustWriteFile(privKeyFilePath, []byte(testPrivValidatorKey), 0644)
tmos.MustWriteFile(privStateFilePath, []byte(testPrivValidatorState), 0644)
config := TestConfig().SetRoot(rootDir)
return config
}
var testGenesisFmt = `{
"genesis_time": "2018-10-10T08:20:13.695936996Z",
"chain_id": "%s",
"initial_height": "1",
"consensus_params": {
"block": {
"max_bytes": "22020096",
"max_gas": "-1",
"time_iota_ms": "10"
},
"evidence": {
"max_age_num_blocks": "100000",
"max_age_duration": "172800000000000",
"max_bytes": "1048576"
},
"validator": {
"pub_key_types": [
"ed25519"
]
},
"version": {}
},
"validators": [
{
"pub_key": {
"type": "tendermint/PubKeyEd25519",
"value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="
},
"power": "10",
"name": ""
}
],
"app_hash": ""
}`
var testPrivValidatorKey = `{
"address": "A3258DCBF45DCA0DF052981870F2D1441A36D145",
"pub_key": {
"type": "tendermint/PubKeyEd25519",
"value": "AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="
},
"priv_key": {
"type": "tendermint/PrivKeyEd25519",
"value": "EVkqJO/jIXp3rkASXfh9YnyToYXRXhBr6g9cQVxPFnQBP/5povV4HTjvsy530kybxKHwEi85iU8YL0qQhSYVoQ=="
}
}`
var testPrivValidatorState = `{
"height": "0",
"round": 0,
"step": 0
}`

View File

@@ -1,21 +1,22 @@
package config
package config_test
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/internal/test"
)
func ensureFiles(t *testing.T, rootDir string, files ...string) {
for _, f := range files {
p := rootify(rootDir, f)
p := filepath.Join(rootDir, f)
_, err := os.Stat(p)
assert.Nil(t, err, p)
assert.NoError(t, err, p)
}
}
@@ -23,20 +24,18 @@ func TestEnsureRoot(t *testing.T) {
require := require.New(t)
// setup temp dir for test
tmpDir, err := ioutil.TempDir("", "config-test")
tmpDir, err := os.MkdirTemp("", "config-test")
require.Nil(err)
defer os.RemoveAll(tmpDir)
// create root dir
EnsureRoot(tmpDir)
config.EnsureRoot(tmpDir)
// make sure config is set properly
data, err := ioutil.ReadFile(filepath.Join(tmpDir, defaultConfigFilePath))
data, err := os.ReadFile(filepath.Join(tmpDir, config.DefaultConfigDir, config.DefaultConfigFileName))
require.Nil(err)
if !checkConfig(string(data)) {
t.Fatalf("config file missing some information")
}
assertValidConfig(t, string(data))
ensureFiles(t, tmpDir, "data")
}
@@ -44,35 +43,30 @@ func TestEnsureRoot(t *testing.T) {
func TestEnsureTestRoot(t *testing.T) {
require := require.New(t)
testName := "ensureTestRoot"
// create root dir
cfg := ResetTestRoot(testName)
cfg := test.ResetTestRoot("ensureTestRoot")
defer os.RemoveAll(cfg.RootDir)
rootDir := cfg.RootDir
// make sure config is set properly
data, err := ioutil.ReadFile(filepath.Join(rootDir, defaultConfigFilePath))
data, err := os.ReadFile(filepath.Join(rootDir, config.DefaultConfigDir, config.DefaultConfigFileName))
require.Nil(err)
if !checkConfig(string(data)) {
t.Fatalf("config file missing some information")
}
assertValidConfig(t, string(data))
// TODO: make sure the cfg returned and testconfig are the same!
baseConfig := DefaultBaseConfig()
ensureFiles(t, rootDir, defaultDataDir, baseConfig.Genesis, baseConfig.PrivValidatorKey, baseConfig.PrivValidatorState)
baseConfig := config.DefaultBaseConfig()
ensureFiles(t, rootDir, config.DefaultDataDir, baseConfig.Genesis, baseConfig.PrivValidatorKey, baseConfig.PrivValidatorState)
}
func checkConfig(configFile string) bool {
var valid bool
func assertValidConfig(t *testing.T, configFile string) {
t.Helper()
// list of words we expect in the config
var elems = []string{
"moniker",
"seeds",
"proxy_app",
"fast_sync",
"block_sync",
"create_empty_blocks",
"peer",
"timeout",
@@ -85,11 +79,6 @@ func checkConfig(configFile string) bool {
"genesis",
}
for _, e := range elems {
if !strings.Contains(configFile, e) {
valid = false
} else {
valid = true
}
assert.Contains(t, configFile, e)
}
return valid
}

View File

@@ -1,3 +1,3 @@
# Consensus
See the [consensus spec](https://github.com/tendermint/spec/tree/master/spec/consensus) and the [reactor consensus spec](https://github.com/tendermint/spec/tree/master/spec/reactors/consensus) for more information.
See the [consensus spec](https://github.com/tendermint/tendermint/tree/main/spec/consensus) for more information.

View File

@@ -50,7 +50,9 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
for i := 0; i < nValidators; i++ {
logger := consensusLogger().With("test", "byzantine", "validator", i)
stateDB := dbm.NewMemDB() // each state needs its own db
stateStore := sm.NewStore(stateDB)
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
DiscardABCIResponses: false,
})
state, _ := stateStore.LoadFromDBOrGenesisDoc(genDoc)
thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i))
defer os.RemoveAll(thisConfig.RootDir)
@@ -98,7 +100,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
evpool.SetLogger(logger.With("module", "evidence"))
// Make State
blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyAppConnCon, mempool, evpool)
blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyAppConnCon, mempool, evpool, blockStore)
cs := NewState(thisConfig.Consensus, state, blockExec, blockStore, mempool, evpool)
cs.SetLogger(cs.Logger)
// set private validator
@@ -211,9 +213,11 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
}
proposerAddr := lazyProposer.privValidatorPubKey.Address()
block, blockParts := lazyProposer.blockExec.CreateProposalBlock(
lazyProposer.Height, lazyProposer.state, commit, proposerAddr,
)
block, err := lazyProposer.blockExec.CreateProposalBlock(
lazyProposer.Height, lazyProposer.state, commit, proposerAddr, nil)
require.NoError(t, err)
blockParts, err := block.MakePartSet(types.BlockPartSizeBytes)
require.NoError(t, err)
// Flush the WAL. Otherwise, we may not recompute the same proposal to sign,
// and the privValidator will refuse to sign anything.
@@ -461,7 +465,10 @@ func byzantineDecideProposalFunc(t *testing.T, height int64, round int32, cs *St
// Avoid sending on internalMsgQueue and running consensus state.
// Create a new proposal block from state/txs from the mempool.
block1, blockParts1 := cs.createProposalBlock()
block1, err := cs.createProposalBlock()
require.NoError(t, err)
blockParts1, err := block1.MakePartSet(types.BlockPartSizeBytes)
require.NoError(t, err)
polRound, propBlockID := cs.ValidRound, types.BlockID{Hash: block1.Hash(), PartSetHeader: blockParts1.Header()}
proposal1 := types.NewProposal(height, round, polRound, propBlockID)
p1 := proposal1.ToProto()
@@ -475,7 +482,10 @@ func byzantineDecideProposalFunc(t *testing.T, height int64, round int32, cs *St
deliverTxsRange(cs, 0, 1)
// Create a new proposal block from state/txs from the mempool.
block2, blockParts2 := cs.createProposalBlock()
block2, err := cs.createProposalBlock()
require.NoError(t, err)
blockParts2, err := block2.MakePartSet(types.BlockPartSizeBytes)
require.NoError(t, err)
polRound, propBlockID = cs.ValidRound, types.BlockID{Hash: block2.Hash(), PartSetHeader: blockParts2.Header()}
proposal2 := types.NewProposal(height, round, polRound, propBlockID)
p2 := proposal2.ToProto()

View File

@@ -4,7 +4,6 @@ import (
"bytes"
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sort"
@@ -13,6 +12,7 @@ import (
"time"
"github.com/go-kit/log/term"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"path"
@@ -24,6 +24,7 @@ import (
abci "github.com/tendermint/tendermint/abci/types"
cfg "github.com/tendermint/tendermint/config"
cstypes "github.com/tendermint/tendermint/consensus/types"
"github.com/tendermint/tendermint/internal/test"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
"github.com/tendermint/tendermint/libs/log"
tmos "github.com/tendermint/tendermint/libs/os"
@@ -63,7 +64,7 @@ func ensureDir(dir string, mode os.FileMode) {
}
func ResetConfig(name string) *cfg.Config {
return cfg.ResetTestRoot(name)
return test.ResetTestRoot(name)
}
//-------------------------------------------------------------------------------
@@ -108,7 +109,7 @@ func (vs *validatorStub) signVote(
BlockID: types.BlockID{Hash: hash, PartSetHeader: header},
}
v := vote.ToProto()
if err := vs.PrivValidator.SignVote(config.ChainID(), v); err != nil {
if err := vs.PrivValidator.SignVote(test.DefaultTestChainID, v); err != nil {
return nil, fmt.Errorf("sign vote failed: %w", err)
}
@@ -200,13 +201,17 @@ func startTestRound(cs *State, height int64, round int32) {
// Create proposal block from cs1 but sign it with vs.
func decideProposal(
t *testing.T,
cs1 *State,
vs *validatorStub,
height int64,
round int32,
) (proposal *types.Proposal, block *types.Block) {
cs1.mtx.Lock()
block, blockParts := cs1.createProposalBlock()
block, err := cs1.createProposalBlock()
require.NoError(t, err)
blockParts, err := block.MakePartSet(types.BlockPartSizeBytes)
require.NoError(t, err)
validRound := cs1.ValidRound
chainID := cs1.state.ChainID
cs1.mtx.Unlock()
@@ -365,7 +370,7 @@ func subscribeToVoter(cs *State, addr []byte) <-chan tmpubsub.Message {
// consensus states
func newState(state sm.State, pv types.PrivValidator, app abci.Application) *State {
config := cfg.ResetTestRoot("consensus_state_test")
config := test.ResetTestRoot("consensus_state_test")
return newStateWithConfig(config, state, pv, app)
}
@@ -427,12 +432,14 @@ func newStateWithConfigAndBlockStore(
// Make State
stateDB := blockDB
stateStore := sm.NewStore(stateDB)
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
DiscardABCIResponses: false,
})
if err := stateStore.Save(state); err != nil { // for save height 1's validators info
panic(err)
}
blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyAppConnCon, mempool, evpool)
blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyAppConnCon, mempool, evpool, blockStore)
cs := NewState(thisConfig.Consensus, state, blockExec, blockStore, mempool, evpool)
cs.SetLogger(log.TestingLogger().With("module", "consensus"))
cs.SetPrivValidator(pv)
@@ -457,12 +464,16 @@ func loadPrivValidator(config *cfg.Config) *privval.FilePV {
}
func randState(nValidators int) (*State, []*validatorStub) {
return randStateWithApp(nValidators, kvstore.NewApplication())
}
func randStateWithApp(nValidators int, app abci.Application) (*State, []*validatorStub) {
// Get State
state, privVals := randGenesisState(nValidators, false, 10)
vss := make([]*validatorStub, nValidators)
cs := newState(state, privVals[0], kvstore.NewApplication())
cs := newState(state, privVals[0], app)
for i := 0; i < nValidators; i++ {
vss[i] = newValidatorStub(privVals[i], int32(i))
@@ -677,6 +688,33 @@ func ensureVote(voteCh <-chan tmpubsub.Message, height int64, round int32,
}
}
func ensurePrevoteMatch(t *testing.T, voteCh <-chan tmpubsub.Message, height int64, round int32, hash []byte) {
t.Helper()
ensureVoteMatch(t, voteCh, height, round, hash, tmproto.PrevoteType)
}
func ensureVoteMatch(t *testing.T, voteCh <-chan tmpubsub.Message, height int64, round int32, hash []byte, voteType tmproto.SignedMsgType) {
t.Helper()
select {
case <-time.After(ensureTimeout):
t.Fatal("Timeout expired while waiting for NewVote event")
case msg := <-voteCh:
voteEvent, ok := msg.Data().(types.EventDataVote)
require.True(t, ok, "expected a EventDataVote, got %T. Wrong subscription channel?",
msg.Data())
vote := voteEvent.Vote
assert.Equal(t, height, vote.Height, "expected height %d, but got %d", height, vote.Height)
assert.Equal(t, round, vote.Round, "expected round %d, but got %d", round, vote.Round)
assert.Equal(t, voteType, vote.Type, "expected type %s, but got %s", voteType, vote.Type)
if hash == nil {
require.Nil(t, vote.BlockID.Hash, "Expected prevote to be for nil, got %X", vote.BlockID.Hash)
} else {
require.True(t, bytes.Equal(vote.BlockID.Hash, hash), "Expected prevote to be for %X, got %X", hash, vote.BlockID.Hash)
}
}
}
func ensurePrecommitTimeout(ch <-chan tmpubsub.Message) {
select {
case <-time.After(ensureTimeout):
@@ -717,7 +755,9 @@ func randConsensusNet(nValidators int, testName string, tickerFunc func() Timeou
configRootDirs := make([]string, 0, nValidators)
for i := 0; i < nValidators; i++ {
stateDB := dbm.NewMemDB() // each state needs its own db
stateStore := sm.NewStore(stateDB)
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
DiscardABCIResponses: false,
})
state, _ := stateStore.LoadFromDBOrGenesisDoc(genDoc)
thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i))
configRootDirs = append(configRootDirs, thisConfig.RootDir)
@@ -755,7 +795,9 @@ func randConsensusNetWithPeers(
configRootDirs := make([]string, 0, nPeers)
for i := 0; i < nPeers; i++ {
stateDB := dbm.NewMemDB() // each state needs its own db
stateStore := sm.NewStore(stateDB)
stateStore := sm.NewStore(stateDB, sm.StoreOptions{
DiscardABCIResponses: false,
})
state, _ := stateStore.LoadFromDBOrGenesisDoc(genDoc)
thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i))
configRootDirs = append(configRootDirs, thisConfig.RootDir)
@@ -767,11 +809,11 @@ func randConsensusNetWithPeers(
if i < nValidators {
privVal = privVals[i]
} else {
tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
tempKeyFile, err := os.CreateTemp("", "priv_validator_key_")
if err != nil {
panic(err)
}
tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
tempStateFile, err := os.CreateTemp("", "priv_validator_state_")
if err != nil {
panic(err)
}
@@ -827,7 +869,7 @@ func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.G
return &types.GenesisDoc{
GenesisTime: tmtime.Now(),
InitialHeight: 1,
ChainID: config.ChainID(),
ChainID: test.DefaultTestChainID,
Validators: validators,
}, privValidators
}
@@ -887,7 +929,7 @@ func (m *mockTicker) Chan() <-chan timeoutInfo {
func (*mockTicker) SetLogger(log.Logger) {}
func newPersistentKVStore() abci.Application {
dir, err := ioutil.TempDir("", "persistent-kvstore")
dir, err := os.MkdirTemp("", "persistent-kvstore")
if err != nil {
panic(err)
}

View File

@@ -113,7 +113,7 @@ func deliverTxsRange(cs *State, start, end int) {
func TestMempoolTxConcurrentWithCommit(t *testing.T) {
state, privVals := randGenesisState(1, false, 10)
blockDB := dbm.NewMemDB()
stateStore := sm.NewStore(blockDB)
stateStore := sm.NewStore(blockDB, sm.StoreOptions{DiscardABCIResponses: false})
cs := newStateWithConfigAndBlockStore(config, state, privVals[0], NewCounterApplication(), blockDB)
err := stateStore.Save(state)
require.NoError(t, err)
@@ -138,7 +138,7 @@ func TestMempoolRmBadTx(t *testing.T) {
state, privVals := randGenesisState(1, false, 10)
app := NewCounterApplication()
blockDB := dbm.NewMemDB()
stateStore := sm.NewStore(blockDB)
stateStore := sm.NewStore(blockDB, sm.StoreOptions{DiscardABCIResponses: false})
cs := newStateWithConfigAndBlockStore(config, state, privVals[0], app, blockDB)
err := stateStore.Save(state)
require.NoError(t, err)
@@ -256,3 +256,22 @@ func (app *CounterApplication) Commit() abci.ResponseCommit {
binary.BigEndian.PutUint64(hash, uint64(app.txCount))
return abci.ResponseCommit{Data: hash}
}
func (app *CounterApplication) PrepareProposal(
req abci.RequestPrepareProposal) abci.ResponsePrepareProposal {
txs := make([][]byte, 0, len(req.Txs))
var totalBytes int64
for _, tx := range req.Txs {
totalBytes += int64(len(tx))
if totalBytes > req.MaxTxBytes {
break
}
txs = append(txs, tx)
}
return abci.ResponsePrepareProposal{Txs: txs}
}
func (app *CounterApplication) ProcessProposal(
req abci.RequestProcessProposal) abci.ResponseProcessProposal {
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}
}

223
consensus/metrics.gen.go Normal file
View File

@@ -0,0 +1,223 @@
// Code generated by metricsgen. DO NOT EDIT.
package consensus
import (
"github.com/go-kit/kit/metrics/discard"
prometheus "github.com/go-kit/kit/metrics/prometheus"
stdprometheus "github.com/prometheus/client_golang/prometheus"
)
func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics {
labels := []string{}
for i := 0; i < len(labelsAndValues); i += 2 {
labels = append(labels, labelsAndValues[i])
}
return &Metrics{
Height: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "height",
Help: "Height of the chain.",
}, labels).With(labelsAndValues...),
ValidatorLastSignedHeight: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "validator_last_signed_height",
Help: "Last height signed by this validator if the node is a validator.",
}, append(labels, "validator_address")).With(labelsAndValues...),
Rounds: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "rounds",
Help: "Number of rounds.",
}, labels).With(labelsAndValues...),
RoundDurationSeconds: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "round_duration_seconds",
Help: "Histogram of round duration.",
Buckets: stdprometheus.ExponentialBucketsRange(0.1, 100, 8),
}, labels).With(labelsAndValues...),
Validators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "validators",
Help: "Number of validators.",
}, labels).With(labelsAndValues...),
ValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "validators_power",
Help: "Total power of all validators.",
}, labels).With(labelsAndValues...),
ValidatorPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "validator_power",
Help: "Power of a validator.",
}, append(labels, "validator_address")).With(labelsAndValues...),
ValidatorMissedBlocks: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "validator_missed_blocks",
Help: "Amount of blocks missed per validator.",
}, append(labels, "validator_address")).With(labelsAndValues...),
MissingValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "missing_validators",
Help: "Number of validators who did not sign.",
}, labels).With(labelsAndValues...),
MissingValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "missing_validators_power",
Help: "Total power of the missing validators.",
}, labels).With(labelsAndValues...),
ByzantineValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "byzantine_validators",
Help: "Number of validators who tried to double sign.",
}, labels).With(labelsAndValues...),
ByzantineValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "byzantine_validators_power",
Help: "Total power of the byzantine validators.",
}, labels).With(labelsAndValues...),
BlockIntervalSeconds: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "block_interval_seconds",
Help: "Time between this and the last block.",
}, labels).With(labelsAndValues...),
NumTxs: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "num_txs",
Help: "Number of transactions.",
}, labels).With(labelsAndValues...),
BlockSizeBytes: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "block_size_bytes",
Help: "Size of the block.",
}, labels).With(labelsAndValues...),
TotalTxs: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "total_txs",
Help: "Total number of transactions.",
}, labels).With(labelsAndValues...),
CommittedHeight: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "latest_block_height",
Help: "The latest block height.",
}, labels).With(labelsAndValues...),
BlockSyncing: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "block_syncing",
Help: "Whether or not a node is block syncing. 1 if yes, 0 if no.",
}, labels).With(labelsAndValues...),
StateSyncing: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "state_syncing",
Help: "Whether or not a node is state syncing. 1 if yes, 0 if no.",
}, labels).With(labelsAndValues...),
BlockParts: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "block_parts",
Help: "Number of block parts transmitted by each peer.",
}, append(labels, "peer_id")).With(labelsAndValues...),
StepDurationSeconds: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "step_duration_seconds",
Help: "Histogram of durations for each step in the consensus protocol.",
Buckets: stdprometheus.ExponentialBucketsRange(0.1, 100, 8),
}, append(labels, "step")).With(labelsAndValues...),
BlockGossipPartsReceived: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "block_gossip_parts_received",
Help: "Number of block parts received by the node, separated by whether the part was relevant to the block the node is trying to gather or not.",
}, append(labels, "matches_current")).With(labelsAndValues...),
QuorumPrevoteDelay: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "quorum_prevote_delay",
Help: "Interval in seconds between the proposal timestamp and the timestamp of the earliest prevote that achieved a quorum.",
}, append(labels, "proposer_address")).With(labelsAndValues...),
FullPrevoteDelay: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "full_prevote_delay",
Help: "Interval in seconds between the proposal timestamp and the timestamp of the latest prevote in a round where all validators voted.",
}, append(labels, "proposer_address")).With(labelsAndValues...),
ProposalReceiveCount: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "proposal_receive_count",
Help: "ProposalReceiveCount is the total number of proposals received by this node since process start. The metric is annotated by the status of the proposal from the application, either 'accepted' or 'rejected'.",
}, append(labels, "status")).With(labelsAndValues...),
ProposalCreateCount: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "proposal_create_count",
Help: "ProposalCreationCount is the total number of proposals created by this node since process start.",
}, labels).With(labelsAndValues...),
RoundVotingPowerPercent: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "round_voting_power_percent",
Help: "RoundVotingPowerPercent is the percentage of the total voting power received with a round. The value begins at 0 for each round and approaches 1.0 as additional voting power is observed. The metric is labeled by vote type.",
}, append(labels, "vote_type")).With(labelsAndValues...),
LateVotes: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "late_votes",
Help: "LateVotes stores the number of votes that were received by this node that correspond to earlier heights and rounds than this node is currently in.",
}, append(labels, "vote_type")).With(labelsAndValues...),
}
}
func NopMetrics() *Metrics {
return &Metrics{
Height: discard.NewGauge(),
ValidatorLastSignedHeight: discard.NewGauge(),
Rounds: discard.NewGauge(),
RoundDurationSeconds: discard.NewHistogram(),
Validators: discard.NewGauge(),
ValidatorsPower: discard.NewGauge(),
ValidatorPower: discard.NewGauge(),
ValidatorMissedBlocks: discard.NewGauge(),
MissingValidators: discard.NewGauge(),
MissingValidatorsPower: discard.NewGauge(),
ByzantineValidators: discard.NewGauge(),
ByzantineValidatorsPower: discard.NewGauge(),
BlockIntervalSeconds: discard.NewHistogram(),
NumTxs: discard.NewGauge(),
BlockSizeBytes: discard.NewGauge(),
TotalTxs: discard.NewGauge(),
CommittedHeight: discard.NewGauge(),
BlockSyncing: discard.NewGauge(),
StateSyncing: discard.NewGauge(),
BlockParts: discard.NewCounter(),
StepDurationSeconds: discard.NewHistogram(),
BlockGossipPartsReceived: discard.NewCounter(),
QuorumPrevoteDelay: discard.NewGauge(),
FullPrevoteDelay: discard.NewGauge(),
ProposalReceiveCount: discard.NewCounter(),
ProposalCreateCount: discard.NewCounter(),
RoundVotingPowerPercent: discard.NewGauge(),
LateVotes: discard.NewCounter(),
}
}

View File

@@ -1,11 +1,14 @@
package consensus
import (
"github.com/go-kit/kit/metrics"
"github.com/go-kit/kit/metrics/discard"
"strings"
"time"
prometheus "github.com/go-kit/kit/metrics/prometheus"
stdprometheus "github.com/prometheus/client_golang/prometheus"
"github.com/go-kit/kit/metrics"
cstypes "github.com/tendermint/tendermint/consensus/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/tendermint/tendermint/types"
)
const (
@@ -14,25 +17,30 @@ const (
MetricsSubsystem = "consensus"
)
//go:generate go run ../scripts/metricsgen -struct=Metrics
// Metrics contains metrics exposed by this package.
type Metrics struct {
// Height of the chain.
Height metrics.Gauge
// ValidatorLastSignedHeight of a validator.
ValidatorLastSignedHeight metrics.Gauge
// Last height signed by this validator if the node is a validator.
ValidatorLastSignedHeight metrics.Gauge `metrics_labels:"validator_address"`
// Number of rounds.
Rounds metrics.Gauge
// Histogram of round duration.
RoundDurationSeconds metrics.Histogram `metrics_buckettype:"exprange" metrics_bucketsizes:"0.1, 100, 8"`
// Number of validators.
Validators metrics.Gauge
// Total power of all validators.
ValidatorsPower metrics.Gauge
// Power of a validator.
ValidatorPower metrics.Gauge
// Amount of blocks missed by a validator.
ValidatorMissedBlocks metrics.Gauge
ValidatorPower metrics.Gauge `metrics_labels:"validator_address"`
// Amount of blocks missed per validator.
ValidatorMissedBlocks metrics.Gauge `metrics_labels:"validator_address"`
// Number of validators who did not sign.
MissingValidators metrics.Gauge
// Total power of the missing validators.
@@ -52,14 +60,22 @@ type Metrics struct {
// Total number of transactions.
TotalTxs metrics.Gauge
// The latest block height.
CommittedHeight metrics.Gauge
// Whether or not a node is fast syncing. 1 if yes, 0 if no.
FastSyncing metrics.Gauge
CommittedHeight metrics.Gauge `metrics_name:"latest_block_height"`
// Whether or not a node is block syncing. 1 if yes, 0 if no.
BlockSyncing metrics.Gauge
// Whether or not a node is state syncing. 1 if yes, 0 if no.
StateSyncing metrics.Gauge
// Number of blockparts transmitted by peer.
BlockParts metrics.Counter
// Number of block parts transmitted by each peer.
BlockParts metrics.Counter `metrics_labels:"peer_id"`
// Histogram of durations for each step in the consensus protocol.
StepDurationSeconds metrics.Histogram `metrics_labels:"step" metrics_buckettype:"exprange" metrics_bucketsizes:"0.1, 100, 8"`
stepStart time.Time
// Number of block parts received by the node, separated by whether the part
// was relevant to the block the node is trying to gather or not.
BlockGossipPartsReceived metrics.Counter `metrics_labels:"matches_current"`
// QuroumPrevoteMessageDelay is the interval in seconds between the proposal
// timestamp and the timestamp of the earliest prevote that achieved a quorum
@@ -70,183 +86,74 @@ type Metrics struct {
// be above 2/3 of the total voting power of the network defines the endpoint
// the endpoint of the interval. Subtract the proposal timestamp from this endpoint
// to obtain the quorum delay.
QuorumPrevoteMessageDelay metrics.Gauge
//metrics:Interval in seconds between the proposal timestamp and the timestamp of the earliest prevote that achieved a quorum.
QuorumPrevoteDelay metrics.Gauge `metrics_labels:"proposer_address"`
// FullPrevoteMessageDelay is the interval in seconds between the proposal
// FullPrevoteDelay is the interval in seconds between the proposal
// timestamp and the timestamp of the latest prevote in a round where 100%
// of the voting power on the network issued prevotes.
FullPrevoteMessageDelay metrics.Gauge
//metrics:Interval in seconds between the proposal timestamp and the timestamp of the latest prevote in a round where all validators voted.
FullPrevoteDelay metrics.Gauge `metrics_labels:"proposer_address"`
// ProposalReceiveCount is the total number of proposals received by this node
// since process start.
// The metric is annotated by the status of the proposal from the application,
// either 'accepted' or 'rejected'.
ProposalReceiveCount metrics.Counter `metrics_labels:"status"`
// ProposalCreationCount is the total number of proposals created by this node
// since process start.
ProposalCreateCount metrics.Counter
// RoundVotingPowerPercent is the percentage of the total voting power received
// with a round. The value begins at 0 for each round and approaches 1.0 as
// additional voting power is observed. The metric is labeled by vote type.
RoundVotingPowerPercent metrics.Gauge `metrics_labels:"vote_type"`
// LateVotes stores the number of votes that were received by this node that
// correspond to earlier heights and rounds than this node is currently
// in.
LateVotes metrics.Counter `metrics_labels:"vote_type"`
}
// PrometheusMetrics returns Metrics build using Prometheus client library.
// Optionally, labels can be provided along with their values ("foo",
// "fooValue").
func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics {
labels := []string{}
for i := 0; i < len(labelsAndValues); i += 2 {
labels = append(labels, labelsAndValues[i])
}
return &Metrics{
Height: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "height",
Help: "Height of the chain.",
}, labels).With(labelsAndValues...),
Rounds: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "rounds",
Help: "Number of rounds.",
}, labels).With(labelsAndValues...),
Validators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "validators",
Help: "Number of validators.",
}, labels).With(labelsAndValues...),
ValidatorLastSignedHeight: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "validator_last_signed_height",
Help: "Last signed height for a validator",
}, append(labels, "validator_address")).With(labelsAndValues...),
ValidatorMissedBlocks: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "validator_missed_blocks",
Help: "Total missed blocks for a validator",
}, append(labels, "validator_address")).With(labelsAndValues...),
ValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "validators_power",
Help: "Total power of all validators.",
}, labels).With(labelsAndValues...),
ValidatorPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "validator_power",
Help: "Power of a validator",
}, append(labels, "validator_address")).With(labelsAndValues...),
MissingValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "missing_validators",
Help: "Number of validators who did not sign.",
}, labels).With(labelsAndValues...),
MissingValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "missing_validators_power",
Help: "Total power of the missing validators.",
}, labels).With(labelsAndValues...),
ByzantineValidators: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "byzantine_validators",
Help: "Number of validators who tried to double sign.",
}, labels).With(labelsAndValues...),
ByzantineValidatorsPower: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "byzantine_validators_power",
Help: "Total power of the byzantine validators.",
}, labels).With(labelsAndValues...),
BlockIntervalSeconds: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "block_interval_seconds",
Help: "Time between this and the last block.",
}, labels).With(labelsAndValues...),
NumTxs: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "num_txs",
Help: "Number of transactions.",
}, labels).With(labelsAndValues...),
BlockSizeBytes: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "block_size_bytes",
Help: "Size of the block.",
}, labels).With(labelsAndValues...),
TotalTxs: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "total_txs",
Help: "Total number of transactions.",
}, labels).With(labelsAndValues...),
CommittedHeight: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "latest_block_height",
Help: "The latest block height.",
}, labels).With(labelsAndValues...),
FastSyncing: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "fast_syncing",
Help: "Whether or not a node is fast syncing. 1 if yes, 0 if no.",
}, labels).With(labelsAndValues...),
StateSyncing: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "state_syncing",
Help: "Whether or not a node is state syncing. 1 if yes, 0 if no.",
}, labels).With(labelsAndValues...),
BlockParts: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "block_parts",
Help: "Number of blockparts transmitted by peer.",
}, append(labels, "peer_id")).With(labelsAndValues...),
QuorumPrevoteMessageDelay: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "quorum_prevote_message_delay",
Help: "Difference in seconds between the proposal timestamp and the timestamp " +
"of the latest prevote that achieved a quorum in the prevote step.",
}, labels).With(labelsAndValues...),
FullPrevoteMessageDelay: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "full_prevote_message_delay",
Help: "Difference in seconds between the proposal timestamp and the timestamp " +
"of the latest prevote that achieved 100% of the voting power in the prevote step.",
}, labels).With(labelsAndValues...),
}
// RecordConsMetrics uses for recording the block related metrics during fast-sync.
func (m *Metrics) RecordConsMetrics(block *types.Block) {
m.NumTxs.Set(float64(len(block.Data.Txs)))
m.TotalTxs.Add(float64(len(block.Data.Txs)))
m.BlockSizeBytes.Set(float64(block.Size()))
m.CommittedHeight.Set(float64(block.Height))
}
// NopMetrics returns no-op Metrics.
func NopMetrics() *Metrics {
return &Metrics{
Height: discard.NewGauge(),
ValidatorLastSignedHeight: discard.NewGauge(),
Rounds: discard.NewGauge(),
Validators: discard.NewGauge(),
ValidatorsPower: discard.NewGauge(),
ValidatorPower: discard.NewGauge(),
ValidatorMissedBlocks: discard.NewGauge(),
MissingValidators: discard.NewGauge(),
MissingValidatorsPower: discard.NewGauge(),
ByzantineValidators: discard.NewGauge(),
ByzantineValidatorsPower: discard.NewGauge(),
BlockIntervalSeconds: discard.NewHistogram(),
NumTxs: discard.NewGauge(),
BlockSizeBytes: discard.NewGauge(),
TotalTxs: discard.NewGauge(),
CommittedHeight: discard.NewGauge(),
FastSyncing: discard.NewGauge(),
StateSyncing: discard.NewGauge(),
BlockParts: discard.NewCounter(),
QuorumPrevoteMessageDelay: discard.NewGauge(),
FullPrevoteMessageDelay: discard.NewGauge(),
func (m *Metrics) MarkProposalProcessed(accepted bool) {
status := "accepted"
if !accepted {
status = "rejected"
}
m.ProposalReceiveCount.With("status", status).Add(1)
}
func (m *Metrics) MarkVoteReceived(vt tmproto.SignedMsgType, power, totalPower int64) {
p := float64(power) / float64(totalPower)
n := strings.ToLower(strings.TrimPrefix(vt.String(), "SIGNED_MSG_TYPE_"))
m.RoundVotingPowerPercent.With("vote_type", n).Add(p)
}
func (m *Metrics) MarkRound(r int32, st time.Time) {
m.Rounds.Set(float64(r))
roundTime := time.Since(st).Seconds()
m.RoundDurationSeconds.Observe(roundTime)
}
func (m *Metrics) MarkLateVote(vt tmproto.SignedMsgType) {
n := strings.ToLower(strings.TrimPrefix(vt.String(), "SIGNED_MSG_TYPE_"))
m.LateVotes.With("vote_type", n).Add(1)
}
func (m *Metrics) MarkStep(s cstypes.RoundStepType) {
if !m.stepStart.IsZero() {
stepTime := time.Since(m.stepStart).Seconds()
stepName := strings.TrimPrefix(s.String(), "RoundStep")
m.StepDurationSeconds.With("step", stepName).Observe(stepTime)
}
m.stepStart = time.Now()
}

View File

@@ -4,7 +4,7 @@ import (
"errors"
"fmt"
"github.com/gogo/protobuf/proto"
"github.com/cosmos/gogoproto/proto"
cstypes "github.com/tendermint/tendermint/consensus/types"
"github.com/tendermint/tendermint/libs/bits"

View File

@@ -6,7 +6,7 @@ import (
"testing"
"time"
"github.com/gogo/protobuf/proto"
"github.com/cosmos/gogoproto/proto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -314,7 +314,7 @@ func TestWALMsgProto(t *testing.T) {
}
}
// nolint:lll //ignore line length for tests
//nolint:lll //ignore line length for tests
func TestConsMsgsVectors(t *testing.T) {
date := time.Date(2018, 8, 30, 12, 0, 0, 0, time.UTC)
psh := types.PartSetHeader{

View File

@@ -7,7 +7,7 @@ import (
"sync"
"time"
"github.com/gogo/protobuf/proto"
"github.com/cosmos/gogoproto/proto"
cstypes "github.com/tendermint/tendermint/consensus/types"
"github.com/tendermint/tendermint/libs/bits"
@@ -72,7 +72,7 @@ func NewReactor(consensusState *State, waitSync bool, options ...ReactorOption)
}
// OnStart implements BaseService by subscribing to events, which later will be
// broadcasted to other peers and starting state if we're not in fast sync.
// broadcasted to other peers and starting state if we're not in block sync.
func (conR *Reactor) OnStart() error {
conR.Logger.Info("Reactor ", "waitSync", conR.WaitSync())
@@ -104,8 +104,8 @@ func (conR *Reactor) OnStop() {
}
}
// SwitchToConsensus switches from fast_sync mode to consensus mode.
// It resets the state, turns off fast_sync, and starts the consensus state-machine
// SwitchToConsensus switches from block_sync mode to consensus mode.
// It resets the state, turns off block_sync, and starts the consensus state-machine
func (conR *Reactor) SwitchToConsensus(state sm.State, skipWAL bool) {
conR.Logger.Info("SwitchToConsensus")
@@ -121,7 +121,7 @@ func (conR *Reactor) SwitchToConsensus(state sm.State, skipWAL bool) {
conR.mtx.Lock()
conR.waitSync = false
conR.mtx.Unlock()
conR.Metrics.FastSyncing.Set(0)
conR.Metrics.BlockSyncing.Set(0)
conR.Metrics.StateSyncing.Set(0)
if skipWAL {
@@ -198,7 +198,7 @@ func (conR *Reactor) AddPeer(peer p2p.Peer) {
go conR.queryMaj23Routine(peer, peerState)
// Send our state to peer.
// If we're fast_syncing, broadcast a RoundStepMessage later upon SwitchToConsensus().
// If we're block_syncing, broadcast a RoundStepMessage later upon SwitchToConsensus().
if !conR.WaitSync() {
conR.sendNewRoundStepMessage(peer)
}
@@ -218,7 +218,7 @@ func (conR *Reactor) RemovePeer(peer p2p.Peer, reason interface{}) {
}
// Receive implements Reactor
// NOTE: We process these messages even when we're fast_syncing.
// NOTE: We process these messages even when we're block_syncing.
// Messages affect either a peer state or the consensus state.
// Peer state updates can happen in parallel, but processing of
// proposals, block parts, and votes are ordered by the receiveRoutine
@@ -386,7 +386,7 @@ func (conR *Reactor) SetEventBus(b *types.EventBus) {
conR.conS.SetEventBus(b)
}
// WaitSync returns whether the consensus reactor is waiting for state/fast sync.
// WaitSync returns whether the consensus reactor is waiting for state/block sync.
func (conR *Reactor) WaitSync() bool {
conR.mtx.RLock()
defer conR.mtx.RUnlock()

Some files were not shown because too many files have changed in this diff Show More