Go to file
blazeroni 4fc1f73c8e
perf: Amortize clearing unsorted cache entries (Juno genesis fix) (#12885)
This change fixes a bounty by the Juno team.  Juno's invariant checks took 10 hours during their most recent chain halt. This PR cuts that down to 30 seconds.  See https://github.com/CosmosContracts/bounties#improve-speed-of-invariant-checks.

The root problem is deep in the `can-withdraw` invariant check, which calls this repeatedly: https://github.com/cosmos/cosmos-sdk/blob/main/x/distribution/keeper/store.go#L337.  Iterators have a chain of parents and in this case creates an iterator from the `cachekv` store.  For the genesis file, it has a cache of 500,000+ unsorted entries, which are sorted as strings here: https://github.com/cosmos/cosmos-sdk/blob/main/store/cachekv/store.go#L314.  Each delegation from `can-withdraw` uses this cache and many of the cache checks miss or are a very small range.  This means very few entries get removed from the unsorted cache and they have to be re-sorted on the next call.  With a full cache it takes about 180ms on my machine to sort them.

This change introduce a minimum number of entries that will get processed and removed from the unsorted list. It's set at the same value that directs the code to sort them in the first place.  This ensures the unsorted values get removed in a relative short amount of time, and amortizes the cost to ensure an individual check does not have to process the entire cache.

## Benchmarks
On running the benchmarks included in this change produces:
```shell
name                    old time/op    new time/op    delta
LargeUnsortedMisses-32     21.2s ± 9%      0.0s ± 1%   -99.91%  (p=0.000 n=20+17)

name                    old alloc/op   new alloc/op   delta
LargeUnsortedMisses-32    1.64GB ± 0%    0.00GB ± 0%   -99.83%  (p=0.000 n=19+19)

name                    old allocs/op  new allocs/op  delta
LargeUnsortedMisses-32     20.0k ± 0%     41.1k ± 0%  +105.23%  (p=0.000 n=19+20)
```

## Invariant checks results
This is what the invariant checks for Juno look like with this change (on a Hetzner AX101):

```shell
INF starting node with ABCI Tendermint in-process
4:11PM INF Starting multiAppConn service impl=multiAppConn module=proxy
4:11PM INF Starting localClient service connection=query impl=localClient module=abci-client
4:11PM INF Starting localClient service connection=snapshot impl=localClient module=abci-client
4:11PM INF Starting localClient service connection=mempool impl=localClient module=abci-client
4:11PM INF Starting localClient service connection=consensus impl=localClient module=abci-client
4:11PM INF Starting EventBus service impl=EventBus module=events
4:11PM INF Starting PubSub service impl=PubSub module=pubsub
4:11PM INF Starting IndexerService service impl=IndexerService module=txindex
4:11PM INF ABCI Handshake App Info hash= height=0 module=consensus protocol-version=0 software-version=v9.0.0-36-g8fd6f16
4:11PM INF ABCI Replay Blocks appHeight=0 module=consensus stateHeight=0 storeHeight=0
4:12PM INF asserting crisis invariants inv=1/11 module=x/crisis name=gov/module-account
4:12PM INF asserting crisis invariants inv=2/11 module=x/crisis name=distribution/nonnegative-outstanding
4:12PM INF asserting crisis invariants inv=3/11 module=x/crisis name=distribution/can-withdraw
4:12PM INF asserting crisis invariants inv=4/11 module=x/crisis name=distribution/reference-count
4:12PM INF asserting crisis invariants inv=5/11 module=x/crisis name=distribution/module-account
4:12PM INF asserting crisis invariants inv=6/11 module=x/crisis name=bank/nonnegative-outstanding
4:12PM INF asserting crisis invariants inv=7/11 module=x/crisis name=bank/total-supply
4:12PM INF asserting crisis invariants inv=8/11 module=x/crisis name=staking/module-accounts
4:12PM INF asserting crisis invariants inv=9/11 module=x/crisis name=staking/nonnegative-power
4:12PM INF asserting crisis invariants inv=10/11 module=x/crisis name=staking/positive-delegation
4:12PM INF asserting crisis invariants inv=11/11 module=x/crisis name=staking/delegator-shares
4:12PM INF asserted all invariants duration=28383.559601 height=4136532 module=x/crisis
```

## Alternatives
There is another PR which fixes this problem for the Juno genesis file https://github.com/cosmos/cosmos-sdk/pull/12886. However, because of its concurrent nature, it happens to hit a large range relatively early, clearing the unsorted entries and allowing the rest of the checks to not sort it.
2022-08-18 15:13:39 +00:00
.github build: ensure GOWORK=off make test passes (#12951) 2022-08-18 15:20:27 +02:00
api build: ensure GOWORK=off make test passes (#12951) 2022-08-18 15:20:27 +02:00
baseapp chore: fix linting issues exposed by fixing golangci-lint (#12895) 2022-08-11 22:00:24 +02:00
client build: ensure GOWORK=off make test passes (#12951) 2022-08-18 15:20:27 +02:00
codec chore: fix linting issues exposed by fixing golangci-lint (#12895) 2022-08-11 22:00:24 +02:00
contrib Revert "update-ci-only" (#12882) 2022-08-10 09:04:24 +02:00
core build: ensure GOWORK=off make test passes (#12951) 2022-08-18 15:20:27 +02:00
cosmovisor chore: go work sync & gofumpt (#12946) 2022-08-17 16:03:28 +00:00
crypto feat: display attempts left in keyring passphrase prompt (#12924) 2022-08-15 18:48:30 +02:00
db build: ensure GOWORK=off make test passes (#12951) 2022-08-18 15:20:27 +02:00
depinject chore: fix linting issues exposed by fixing golangci-lint (#12895) 2022-08-11 22:00:24 +02:00
docs feat: Make extension snapshotter interface safer to use (#11825) 2022-08-18 09:33:55 +02:00
errors build: ensure GOWORK=off make test passes (#12951) 2022-08-18 15:20:27 +02:00
fuzz test: re-enable FuzzStoreInternalProofsCreateNonmembershipProof (#12176) 2022-06-08 18:44:51 +00:00
internal chore: Db linting (#12141) 2022-06-08 19:02:01 +02:00
math chore: fix linting issues exposed by fixing golangci-lint (#12895) 2022-08-11 22:00:24 +02:00
orm build: ensure GOWORK=off make test passes (#12951) 2022-08-18 15:20:27 +02:00
proto refactor!: Remove proposer-based rewards (#12876) 2022-08-16 08:53:00 -04:00
pruning chore: sdk.Int to math.Int (#12132) 2022-06-03 12:17:02 +00:00
runtime chore: fix linting issues exposed by fixing golangci-lint (#12895) 2022-08-11 22:00:24 +02:00
scripts build: ensure GOWORK=off make test passes (#12951) 2022-08-18 15:20:27 +02:00
server refactor: helper method for register swagger api (#12955) 2022-08-18 12:19:27 +02:00
simapp refactor: helper method for register swagger api (#12955) 2022-08-18 12:19:27 +02:00
snapshots feat: Make extension snapshotter interface safer to use (#11825) 2022-08-18 09:33:55 +02:00
std fix: register evidence regression (#10595) 2021-12-14 14:25:31 +00:00
store perf: Amortize clearing unsorted cache entries (Juno genesis fix) (#12885) 2022-08-18 15:13:39 +00:00
telemetry refactor!: Keyring migration (#9695) 2021-09-20 12:02:15 +00:00
tests refactor: use mocks for x/slashing (#12937) 2022-08-17 14:40:41 -04:00
testutil chore: fix linting issues exposed by fixing golangci-lint (#12895) 2022-08-11 22:00:24 +02:00
third_party/proto feat: full api module building alongside gogo proto files with buf schema registry support (#10669) 2022-01-06 14:57:55 -05:00
tools chore: simplify and refactor linting (#12318) 2022-06-21 17:49:36 +00:00
tx build: ensure GOWORK=off make test passes (#12951) 2022-08-18 15:20:27 +02:00
types chore: go work sync & gofumpt (#12946) 2022-08-17 16:03:28 +00:00
version chore: fix linting issues exposed by fixing golangci-lint (#12895) 2022-08-11 22:00:24 +02:00
x build: ensure GOWORK=off make test passes (#12951) 2022-08-18 15:20:27 +02:00
.build.sh fix library file path (#8301) 2021-01-12 10:08:42 +00:00
.clang-format chore: improve proto formatting (#12656) 2022-07-21 10:56:31 +00:00
.codecov.yml CI: Fix codecov flag project config (#7994) 2020-11-20 09:13:25 -05:00
.deepsource.toml chore: refactor code quality issues (#8932) 2021-03-22 09:30:27 +00:00
.dockerignore Add basic Dockerfile to build all binaries and export gaiad 2018-04-10 12:39:47 +02:00
.gitattributes Merge PR #6426: Migrate API Server 2020-06-15 13:39:09 -04:00
.gitignore feat: deprecate x/params usage in x/gov (#12631) 2022-08-01 16:53:04 +00:00
.gitpod.yml Create .gitpod.yml (#12662) 2022-08-15 15:18:30 +02:00
.golangci.yml chore: update make format (#12892) 2022-08-10 18:49:07 +02:00
.goreleaser.yml ci: fix release notes not populated by goreleaser 2022-08-13 20:41:27 +02:00
.markdownlint.json docs: Code blocks in SDK docs are broken (#11189) 2022-02-14 23:39:35 +01:00
.markdownlintignore docs: Improve markdownlint configuration (#11104) 2022-02-10 12:07:01 +00:00
.mergify.yml chore: master -> main (#11730) 2022-04-24 10:19:04 -04:00
buf.work.yaml feat: full api module building alongside gogo proto files with buf schema registry support (#10669) 2022-01-06 14:57:55 -05:00
CHANGELOG.md perf: Amortize clearing unsorted cache entries (Juno genesis fix) (#12885) 2022-08-18 15:13:39 +00:00
CODE_OF_CONDUCT.md Update CODE_OF_CONDUCT.md (#7381) 2020-09-28 11:28:30 +02:00
CODING_GUIDELINES.md docs: Improve markdownlint configuration (#11104) 2022-02-10 12:07:01 +00:00
CONTRIBUTING.md chore: fix #12674 changelog (#12746) 2022-07-27 16:11:11 +00:00
docker-compose.yml build: add remote debugging with delve (#10587) 2021-12-01 12:44:54 +00:00
Dockerfile Revert "update-ci-only" (#12882) 2022-08-10 09:04:24 +02:00
go.mod build: ensure GOWORK=off make test passes (#12951) 2022-08-18 15:20:27 +02:00
go.sum build: ensure GOWORK=off make test passes (#12951) 2022-08-18 15:20:27 +02:00
go.work fix: re-add cosmovisor in go.work to fix make test (#12884) 2022-08-10 15:12:23 +02:00
go.work.sum build: ensure GOWORK=off make test passes (#12951) 2022-08-18 15:20:27 +02:00
LICENSE chore: update license copyright (#12542) 2022-07-13 10:19:10 +00:00
Makefile chore: update make format (#12892) 2022-08-10 18:49:07 +02:00
README.md fix: Go badge (#12928) 2022-08-15 22:21:51 +02:00
RELEASE_PROCESS.md docs: updates outdated docs (#12014) 2022-05-31 08:59:38 -04:00
SECURITY.md docs: updates outdated docs (#12014) 2022-05-31 08:59:38 -04:00
UPGRADING.md chore: move section in upgrading.md (#12942) 2022-08-17 15:01:27 +00:00

Cosmos SDK

banner

The Cosmos SDK is a framework for building blockchain applications. Tendermint Core (BFT Consensus) and the Cosmos SDK are written in the Golang programming language. Cosmos SDK is used to build Gaia, the first implementation of the Cosmos Hub.

WARNING: The Cosmos SDK has mostly stabilized, but we are still making some breaking changes.

Note: Requires Go 1.18+

Quick Start

To learn how the Cosmos SDK works from a high-level perspective, see the Cosmos SDK High-Level Intro.

If you want to get started quickly and learn how to build on top of Cosmos SDK, visit Cosmos SDK Tutorials. You can also fork the tutorial's repository to get started building your own Cosmos SDK application.

For more information, see the Cosmos SDK Documentation.

Contributing

See CONTRIBUTING.md for details how to contribute and participate in our dev calls. If you want to follow the updates or learn more about the latest design then join our Discord.

Tools and Frameworks

The Cosmos ecosystem is vast. We will only make a few notable mentions here.

  • Tools: notable frameworks and modules.
  • CosmJS: the Swiss Army knife to power JavaScript based client solutions.

Cosmos Hub Mainnet

The Cosmos Hub application, gaia, has moved to its own cosmos/gaia repository. Go there to join the Cosmos Hub mainnet and more.

Inter-Blockchain Communication (IBC)

The IBC module for the Cosmos SDK has moved to its own cosmos/ibc-go repository. Go there to build and integrate with the IBC module.

Ignite CLI

Ignite CLI is the all-in-one platform to build, launch, and maintain any crypto application on a sovereign and secured blockchain. If you are building a new app or a new module, use Ignite CLI to get started and speed up development.

Disambiguation

This Cosmos SDK project is not related to the React-Cosmos project (yet). Many thanks to Evan Coury and Ovidiu (@skidding) for this Github organization name. As per our agreement, this disambiguation notice will stay here.