How I personally check cosmos chain quality

Checking Code Quality in Cosmos

…including highly opinionated stuff that people I respect might disagree with

Steps 1-8 are below, and cover the easy, boring stuff that everyone should attend to regardless.

  1. the chain should specify the latest version of go in go.mod – this ensures that all validators are using the latest version of go. Long-run this means that the chain won’t rando apphash for stuff like the crypto changes between 1.18 and 1.19.

Alos devs have latest. use it. Currently, this means that a new chain should be using go v1.20. This means it may be necessary to bump the golang in one of the older proto-builder containers, that you can find here:

  1. lint with golangci-lint

if you enable gofumpt (usually by replacing gofmt and goimports) in .golangci.yml, then you can fumpt and fix common issues like:

golangci-lint run ./… --fix

now your editor warns more. Typicially you’ll want a .golangci.yml file that includes:

  tests: true
  timeout: 10m
  sort-results: true
  allow-parallel-runners: true
    - "legacy_ibc_testing"
    - "testutil" 

  disable-all: true
    - depguard
    - dogsled
    - exportloopref
    - goconst
    - gocritic
    - gofumpt
    - gosec
    - gosimple
    - govet
    - ineffassign
    - misspell
    - nakedret
    - nolintlint
    - staticcheck
    - revive
    - stylecheck
    - typecheck
    - thelper
    - unconvert
    - unused

    extra-rules: true
    - text: "Use of weak random number generator"
        - gosec
    - text: "leading space"
        - nolintlint

  max-issues-per-linter: 10000
  max-same-issues: 10000

      - appendAssign
    max-blank-identifiers: 3
    # print struct with more effective memory layout or not, false by default
    suggest-new: true
    allow-unused: false
    allow-leading-space: true
    require-explanation: false
    require-specific: false

By specifying extra in gofumpt, you are asking it to format the code even more tightly. By giving it the module path, it can see the module paths.

4) Module Versions

4) go.mod: versions

I have the current versions of ecosystem modules burned into working memory

  • tendermint v0.34.28 (if sdk 46 or 45) or v0.37.1 (if sdk 47)
  • cosmos-sdk or v0.46.12 or v0.47.2 – you should bias towards the newer release for a new chain
  • iavl v0.20.0
  • cosmos-proto alpha8
  • ibc-go v6.1.0 if on sdk 46 and ibc-go 7.0.0 if on sdk 47

6) Annotate replace statements in go.mod

like this:

replace (
	// osmosis-patched wasmd. => v0.31.0-osmo-v16
	// dragonberry => v0.8.0
	// Our cosmos-sdk branch is:, current branch: v16.x. Direct commit link: => v0.45.1-0.20230326212251-7a2cf2993434

	// N.B. v0.19.5 contains a breaking change to the IAVL API v0.19.5 => v0.19.4
	// use cosmos-compatible protobufs => v1.3.3-alpha.regen.1

	// Informal Tendermint fork => v0.34.24
	// use grpc compatible with cosmos protobufs => v1.33.2


You should annotate the replace statements so that you and others checking your chain know where they refer to specifically, and why they are there.

5) Dependabot

As your chain matures, you will want to upgrade it to the latest ecosystem modules. Dependabot is a tool that makes that easier by making those PR’s for you. Watch out, as it may sometimes suggest breaking changes. If that happens, you’ll want to figure out if the suggested changes will be beneficial to you or not.

# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:

version: 2
  - package-ecosystem: "gomod" # See documentation for possible values
    directory: "/" # Location of package manifests
      interval: "daily"
  - package-ecosystem: "github-actions" # See documentation for possible values
    directory: "/" # Location of package manifests
      interval: "daily"

Thats what I recommend nearly universally.

  1. Don’t let green checkmarks lie to you
  • use the standard github action for golangci-lint…
  • run tests in ci
  • build in ci
  • containerize in ci
  • sdk&gaia had lying greens. it hacks optic nerve. you feel safe. They took a long time to fix because the teams said “look, the checkmark was green” but in fact neither repo had been linted in a long time because CI has malfunctioned and the green check mark is a lie
  • don’t use a diff as conditional in ci

7) Check over app.go carefully

In app.go we “wire” a chain together. You should check this file very carefully, and you SHOULD use upstream sources to help you to verify your work.

8) less is more


is kinda god tier here. You can do less in the chain, and more there, and it really does work out very well. No matter your goals, minimize the code (usually can import what you need & splice) viz:

9) Essential CI Jobs

The CI jobs that you’ll want at minimum are:

Great insight! At CryptoCrew we’re adopting these steps, additionally we’re working with Notional and SG-1 on a best-practice guideline for consumer-chains and sovereign chains

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.