diff --git a/.build.sh b/.build.sh deleted file mode 100755 index 69a743ca064..00000000000 --- a/.build.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -set -ue - -# Expect the following envvars to be set: -# - APP -# - VERSION -# - COMMIT -# - TARGET_OS -# - LEDGER_ENABLED -# - DEBUG - -# Source builder's functions library -. /usr/local/share/osmosis/buildlib.sh - -# These variables are now available -# - BASEDIR -# - OUTDIR - -# Build for each os-architecture pair -for platform in ${TARGET_PLATFORMS} ; do - # This function sets GOOS, GOARCH, and OS_FILE_EXT environment variables - # according to the build target platform. OS_FILE_EXT is empty in all - # cases except when the target platform is 'windows'. - setup_build_env_for_platform "${platform}" - - echo Building for $(go env GOOS)/$(go env GOARCH) >&2 - GOROOT_FINAL="$(go env GOROOT)" \ - make build \ - LDFLAGS=-buildid=${VERSION} \ - VERSION=${VERSION} \ - COMMIT=${COMMIT} \ - LEDGER_ENABLED=${LEDGER_ENABLED} \ - LINK_STATICALLY=true \ - BUILD_TAGS=muslc - mv ./build/${APP}${OS_FILE_EXT} ${OUTDIR}/${APP}-${VERSION}-$(go env GOOS)-$(go env GOARCH)${OS_FILE_EXT} - - # This function restore the build environment variables to their - # original state. - restore_build_env -done - -# Generate and display build report. -generate_build_report -cat ${OUTDIR}/build_report diff --git a/.codecov.yml b/.codecov.yml deleted file mode 100644 index 861b5a40d8f..00000000000 --- a/.codecov.yml +++ /dev/null @@ -1,27 +0,0 @@ -codecov: -require_ci_to_pass: yes - -coverage: - precision: 2 - round: down - range: "70...100" - -parsers: - gcov: - branch_detection: - conditional: yes - loop: yes - method: no - macro: no - -comment: - layout: "reach,diff,flags,files,footer" - behavior: default - require_changes: no - -ignore: - - "*.md" - - "**/*.pb.go" - - "types/*.pb.go" - - "x/**/*.pb.go" - - "x/**/test_common.go" diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1108256374b..7d2488faf47 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,7 +3,7 @@ updates: - package-ecosystem: gomod directory: "/" schedule: - interval: daily + interval: weekly ignore: - dependency-name: "github.com/tendermint/tendermint" update-types: ["version-update:semver-major", "version-update:semver-minor"] diff --git a/.github/labeler.yml b/.github/labeler.yml index 49370713b54..9c8b9afcf07 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -9,6 +9,13 @@ - app/upgrades/**/* # Also match any module.go update - x/**/module.go +"C:simulator": + # Match all of simulation & tests/simulator folder + - simulation/**/* + - simulation/**/**/* + - tests/simulator/** + # Match any module update + - x/**/simulation/*.go "C:wasm": - app/wasm/**/* "C:x/claim": @@ -31,6 +38,9 @@ - x/txfees/**/* "C:x/tokenfactory": - x/tokenfactory/**/* +"C:x/twap": + - x/twap/* + - x/twap/**/* "T:build": - Makefile - Dockerfile diff --git a/.github/.mergify.yml b/.github/mergify.yml similarity index 83% rename from .github/.mergify.yml rename to .github/mergify.yml index 2ed0f5835e2..84ed8e8cbd0 100644 --- a/.github/.mergify.yml +++ b/.github/mergify.yml @@ -85,4 +85,20 @@ pull_request_rules: actions: backport: branches: - - v10.x \ No newline at end of file + - v10.x + - name: backport patches to v11.x branch + conditions: + - base=main + - label=A:backport/v11.x + actions: + backport: + branches: + - v11.x + - name: backport patches to v12.x branch + conditions: + - base=main + - label=A:backport/v12.x + actions: + backport: + branches: + - v12.x diff --git a/.github/workflows/check-generated.yml b/.github/workflows/check-generated.yml new file mode 100644 index 00000000000..ac4e43ceb93 --- /dev/null +++ b/.github/workflows/check-generated.yml @@ -0,0 +1,30 @@ +# Verify that generated code is up-to-date. +# +# Note that we run these checks regardless whether the input files have +# changed, because generated code can change in response to toolchain updates +# even if no files in the repository are modified. +name: Check generated code +on: + workflow_dispatch: + pull_request: + branches: + - '*' + +permissions: + contents: read + +jobs: + check-proto: + runs-on: ubuntu-latest + steps: + - + uses: actions/setup-go@v3 + with: + go-version: '1.18' + - + uses: actions/checkout@v3 + with: + fetch-depth: 1 # we need a .git directory to run git diff + - + name: "Check protobuf generated code" + run: scripts/ci/check-generated.sh diff --git a/.github/workflows/contracts.yml b/.github/workflows/contracts.yml new file mode 100644 index 00000000000..f5f5301c31b --- /dev/null +++ b/.github/workflows/contracts.yml @@ -0,0 +1,123 @@ +name: Cosmwasm Contracts +on: + pull_request: + branches: + - "**" + push: + branches: + - "main" + - "v[0-9]**" + workflow_dispatch: + + +jobs: + test: + name: Test Suite + runs-on: ubuntu-latest + strategy: + matrix: + contract: [{workdir: ./x/ibc-rate-limit/, output: testdata/rate_limiter.wasm, build: artifacts/rate_limiter-x86_64.wasm, name: rate_limiter}] + + steps: + - name: Checkout sources + uses: actions/checkout@v2 + - uses: technote-space/get-diff-action@v6.0.1 + with: + PATTERNS: | + **/**.rs + **/**.go + go.mod + **/**cargo.toml + - name: Install toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + target: wasm32-unknown-unknown + + - name: Add the wasm target + working-directory: ${{ matrix.contract.workdir }} + run: > + rustup target add wasm32-unknown-unknown; + + + - name: Build + working-directory: ${{ matrix.contract.workdir }} + run: > + cargo build --release --target wasm32-unknown-unknown + + - name: Test + working-directory: ${{ matrix.contract.workdir }} + run: > + cargo test + + - name: Set latest cw-optimizoor version + run: > + echo "CW_OPTIMIZOOR_VERSION=`cargo search cw-optimizoor -q | cut -d '"' -f 2`" >> $GITHUB_ENV + + - name: Cache cw-optimizoor + id: cache-cw-optimizoor + uses: actions/cache@v3 + env: + cache-name: cache-cw-optimizoor + with: + # cargo bin files are stored in `~/.cargo/bin/` on Linux/macOS + path: ~/.cargo/bin/cargo-cw-optimizoor + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.CW_OPTIMIZOOR_VERSION }} + + - if: ${{ steps.cache-cw-optimizoor.outputs.cache-hit != 'true' }} + name: Install cw-optimizoor + continue-on-error: true + run: > + cargo install cw-optimizoor + + - name: Optimize + working-directory: ${{ matrix.contract.workdir }} + run: > + cargo cw-optimizoor + + - name: 'Upload optimized contract artifact' + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.contract.name }} + path: ${{ matrix.contract.workdir }}${{ matrix.contract.build }} + retention-days: 1 + +# - name: Check Test Data +# working-directory: ${{ matrix.contract.workdir }} +# if: ${{ matrix.contract.output != null }} +# run: > +# diff ${{ matrix.contract.output }} ${{ matrix.contract.build }} + + + lints: + name: Cosmwasm Lints + runs-on: ubuntu-latest + strategy: + matrix: + workdir: [./x/ibc-rate-limit] + + steps: + - name: Checkout sources + uses: actions/checkout@v2 + - uses: technote-space/get-diff-action@v6.0.1 + with: + PATTERNS: | + **/**.rs + - name: Install toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: nightly + override: true + components: rustfmt, clippy + + - name: Format + working-directory: ${{ matrix.workdir }} + run: > + cargo fmt --all -- --check + + - name: run cargo clippy + working-directory: ${{ matrix.workdir }} + run: > + cargo clippy -- -D warnings + diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 955bd5fe19d..c4f16ac0c11 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,4 +1,25 @@ -name: docker +# This workflow pushes new osmosis docker images on every new tag. +# +# On every new `vX.Y.Z` tag the following images are pushed: +# +# osmolabs/osmosis:X.Y.Z # is pushed +# osmolabs/osmosis:X.Y # is updated to X.Y.Z +# osmolabs/osmosis:X # is updated to X.Y.Z +# osmolabs/osmosis:latest # is updated to X.Y.Z +# +# The same osmosisd binary is copied in different base runner images: +# +# - `osmolabs/osmosis:X.Y.Z` uses `gcr.io/distroless/static` +# - `osmolabs/osmosis:X.Y.Z-distroless` uses `gcr.io/distroless/static` +# - `osmolabs/osmosis:X.Y.Z-nonroot` uses `gcr.io/distroless/static:nonroot` +# - `osmolabs/osmosis:X.Y.Z-alpine` uses `alpine:3.16` +# +# All the images above have support for linux/amd64 and linux/arm64. +# +# Due to QEMU virtualization used to build multi-platform docker images +# this workflow might take a while to complete. + +name: Push Docker Images on: push: @@ -7,6 +28,9 @@ on: env: DOCKER_REPOSITORY: osmolabs/osmosis + RUNNER_BASE_IMAGE_DISTROLESS: gcr.io/distroless/static + RUNNER_BASE_IMAGE_NONROOT: gcr.io/distroless/static:nonroot + RUNNER_BASE_IMAGE_ALPINE: alpine:3.16 jobs: docker: @@ -17,19 +41,27 @@ jobs: uses: actions/checkout@v2 - name: Set up QEMU - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Login to DockerHub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Docker meta - id: meta + name: Find go version + id: find_go_version + run: | + GO_VERSION=$(cat go.mod | grep -E 'go [0-9].[0-9]+' | cut -d ' ' -f 2) + echo "::set-output name=go_version::$(echo ${GO_VERSION})" + + # Distroless Docker image (default) + - + name: Docker meta (distroless) + id: meta_distroless uses: docker/metadata-action@v3 with: images: ${{ env.DOCKER_REPOSITORY }} @@ -37,16 +69,75 @@ jobs: type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} + type=semver,pattern={{version}}-distroless + type=semver,pattern={{major}}.{{minor}}-distroless + type=semver,pattern={{major}}-distroless - - name: Build and push + name: Build and push (distroless) + id: build_push_distroless uses: docker/build-push-action@v2 with: file: Dockerfile context: . push: true platforms: linux/amd64,linux/arm64 - tags: ${{ steps.meta.outputs.tags }} + build-args: | + GO_VERSION=${{ steps.find_go_version.outputs.go_version }} + RUNNER_IMAGE=${{ env.RUNNER_BASE_IMAGE_DISTROLESS }} + tags: ${{ steps.meta_distroless.outputs.tags }} + # Distroless nonroot Docker image + - + name: Docker meta (nonroot) + id: meta_nonroot + uses: docker/metadata-action@v3 + with: + images: ${{ env.DOCKER_REPOSITORY }} + flavor: | + latest=false + suffix=-nonroot + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + - + name: Build and push (nonroot) + id: build_push_nonroot + uses: docker/build-push-action@v2 + with: + file: Dockerfile + context: . + push: true + platforms: linux/amd64,linux/arm64 + build-args: | + GO_VERSION=${{ steps.find_go_version.outputs.go_version }} + RUNNER_IMAGE=${{ env.RUNNER_BASE_IMAGE_NONROOT }} + tags: ${{ steps.meta_nonroot.outputs.tags }} + + # Alpine Docker image + - + name: Docker meta (alpine) + id: meta_alpine + uses: docker/metadata-action@v3 + with: + images: ${{ env.DOCKER_REPOSITORY }} + flavor: | + latest=false + suffix=-alpine + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} - - name: Image digest - run: echo ${{ steps.docker_build.outputs.digest }} \ No newline at end of file + name: Build and push (alpine) + id: build_push_alpine + uses: docker/build-push-action@v2 + with: + file: Dockerfile + context: . + push: true + platforms: linux/amd64,linux/arm64 + build-args: | + GO_VERSION=${{ steps.find_go_version.outputs.go_version }} + RUNNER_IMAGE=${{ env.RUNNER_BASE_IMAGE_ALPINE }} + tags: ${{ steps.meta_alpine.outputs.tags }} diff --git a/.github/workflows/import_paths.yml b/.github/workflows/import_paths.yml new file mode 100644 index 00000000000..b268b1508a3 --- /dev/null +++ b/.github/workflows/import_paths.yml @@ -0,0 +1,75 @@ +# This is a manua workflow that does the following when trigerred: +# - Runs a script to find and replace Go import path major version with given version. +# - Commits and pushes changes to the source-branch. +# - Opens a PR from the source branch to the target-branch. + +name: Update Go Import Paths + +on: + workflow_dispatch: + inputs: + version: + description: 'Current Version that we want to change' + default: '10' + required: true + target-branch: + description: 'Target Branch' + default: 'main' + required: true + source-branch: + description: 'Source Branch' + default: 'update-paths' + required: true + +jobs: + update-import-paths: + runs-on: ubuntu-latest + + steps: + - + name: Check out repository code + uses: actions/checkout@v2 + with: + ref: ${{ inputs.target-branch }} + - + name: Setup Golang + uses: actions/setup-go@v2.1.4 + with: + go-version: 1.18 + - + name: Display go version + run: go version + - + name: Get data from build cache + uses: actions/cache@v2 + with: + # In order: + # * Module download cache + # * Build cache (Linux) + # * Build cache (Mac) + # * Build cache (Windows) + path: | + ~/go/pkg/mod + ~/.cache/go-build + ~/Library/Caches/go-build + ~\AppData\Local\go-build + key: ${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go-${{ matrix.go-version }}- + - + name: Run find & replace script + run: ./scripts/replace_import_paths.sh ${{ inputs.version }} + - name: Create Pull Request + uses: peter-evans/create-pull-request@v4 + with: + token: ${{ secrets.COMMIT_TO_BRANCH }} + title: "auto: update Go import paths to v${{ inputs.version }} on branch ${{ inputs.target-branch }}" + commit-message: "auto: update Go import paths to v${{ inputs.version }}" + body: "**Automated pull request**\n\nUpdating Go import paths to v${{ inputs.version }}" + base: ${{ inputs.target-branch }} + branch-suffix: random + branch: ${{ inputs.source-branch }} + delete-branch: true + assignees: ${{ github.actor }} + draft: true + labels: T:auto,T:code-hygiene diff --git a/.github/workflows/mutest-issue-generate.yml b/.github/workflows/mutest-issue-generate.yml new file mode 100644 index 00000000000..44ac6559e39 --- /dev/null +++ b/.github/workflows/mutest-issue-generate.yml @@ -0,0 +1,55 @@ +name: Generate Mutation Test Errors + +on: + schedule: + - cron: '0 13 * * 1' # Every Monday at 1PM UTC (9AM EST) + +jobs: + test: + runs-on: ubuntu-latest + steps: + - + name: checkout repo + uses: actions/checkout@v2 + - + name: Setup Golang + uses: actions/setup-go@v2.1.4 + with: + go-version: 1.18 + - + name: Display go version + run: go version + - + name: Run mutation test + continue-on-error: true + run: make test-mutation $MODULES + env: + MODULES: tokenfactory,twap + - + name: Execute mutation test format script + id: mutest-formatted + run: | + cat mutation_test_result.txt | grep -Ev "PASS" | grep -Ev "SKIP" | tee mutation_test_result.txt + - + name: Generate code blocks + id: gen-code-blocks + run: | + cat mutation_test_result.txt | sed "s# @@# @@\n\`\`\`go\n#g " | sed "s#FAIL#\`\`\`\nFAIL\n\n\n#g " > go_mutation_test_result.txt + - + name: Get today's date + id: date + run: | + echo "::set-output name=today::$(date "+%Y/%m/%d")" + - + name: Read mutation_test_txt file + id: result + uses: juliangruber/read-file-action@v1 + with: + path: go_mutation_test_result.txt + - + name: Create an mutation test output issue + uses: dacbd/create-issue-action@main + with: + token: ${{ secrets.GITHUB_TOKEN }} + title: Mutation test ${{ steps.date.outputs.today }} + body: ${{ steps.result.outputs.content }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index caeef52e7c7..00000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Create a release folder with the osmosis binaries -# This workflow runs on every new tag or when manually triggered -# It will create a release folder that it's served as an workflow artifact - -name: Release Osmosis - -on: - push: - tags: - - 'v*' - workflow_dispatch: - -jobs: - release: - runs-on: ubuntu-latest - steps: - - - name: Check out the repo - uses: actions/checkout@v2 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - - name: Launch release process - run: | - make -f contrib/images/osmobuilder/Makefile release - - - name: Upload release folder - uses: actions/upload-artifact@v2 - with: - name: release - path: release diff --git a/.github/workflows/sim.yml b/.github/workflows/sim.yml index cf2b59c99dd..78df7c18c96 100644 --- a/.github/workflows/sim.yml +++ b/.github/workflows/sim.yml @@ -16,6 +16,9 @@ jobs: go-version: 1.18 - name: Display go version run: go version - - name: Run simulation + - name: Run full application simulation run: | - make test-sim + make test-sim-app + - name: Run simulation determinism check + run: | + make test-sim-determinism diff --git a/.github/workflows/stalebot.yml b/.github/workflows/stalebot.yml new file mode 100644 index 00000000000..5202e47f86a --- /dev/null +++ b/.github/workflows/stalebot.yml @@ -0,0 +1,27 @@ +name: "Close stale pull requests" +on: + schedule: + - cron: "0 0 * * *" + +permissions: + contents: read + +jobs: + stale: + permissions: + issues: write # for actions/stale to close stale issues + pull-requests: write # for actions/stale to close stale PRs + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v5 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-pr-message: > + This pull request has been automatically marked as stale because it + has not had any recent activity. It will be closed if no further + activity occurs. Thank you! + days-before-stale: -1 + days-before-close: -1 + days-before-pr-stale: 14 + days-before-pr-close: 6 + exempt-pr-labels: "security, proposal, blocked" diff --git a/.github/workflows/state-compatibility-check.yml b/.github/workflows/state-compatibility-check.yml new file mode 100644 index 00000000000..dc6b98070b3 --- /dev/null +++ b/.github/workflows/state-compatibility-check.yml @@ -0,0 +1,156 @@ +# This workflow checks that a specific commit / branch / tag is state compatible +# with the latest osmosis version by: + +# - building the new `osmosisd` binary with the latest changes +# - replaying a configurable number of previous blocks from chain history + +# Currently, the node starts from a snapshot taken some blocks before the last epoch +# and waits `DELTA_HALT_HEIGHT` blocks after epoch before finally halting. + +# Important Caveat: + +# The fact that this workflow succeeds and the binary doesn't fail doesn't +# directly imply that the new binary is state-compatible. +# It could be that the binary is not state-compatible, but the condition +# which would break state compatibility was not present in the chunk of block history used. + +# On the other hand, if the workflow fails, the binary is not state-compatible. + +name: Check state compatibility + +# ************************************ NOTE ************************************ +# +# DO NOT TRIGGER THIS WORKFLOW ON PUBLIC FORKS +# +# This workflow runs on a self-hosted runner and forks to this repository +# can potentially run dangerous code on the self-hosted runner machine +# by creating a pull request that executes the code in a workflow. +# +# ****************************************************************************** + +on: + pull_request: + branches: + - 'v[0-9]+.x' + +env: + GOLANG_VERSION: 1.18 + GENESIS_URL: https://github.com/osmosis-labs/networks/raw/main/osmosis-1/genesis.json + SNAPSHOT_BUCKET: https://osmosis-snapshot.sfo3.cdn.digitaloceanspaces.com + RPC_ENDPOINT: https://rpc.osmosis.zone + LCD_ENDPOINT: https://lcd.osmosis.zone + DELTA_HALT_HEIGHT: 50 + +jobs: + + check_state_compatibility: + # DO NOT CHANGE THIS: please read the note above + if: ${{ github.event.pull_request.head.repo.full_name == 'osmosis-labs/osmosis' }} + runs-on: self-hosted + steps: + - + name: Checkout branch + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - + name: 🐿 Setup Golang + uses: actions/setup-go@v3 + with: + go-version: '^${{ env.GOLANG_VERSION }}' + - + name: 🔨 Build the osmosisd binary + run: | + make build + build/osmosisd version + - + name: 🧪 Initialize Osmosis Node + run: | + rm -rf $HOME/.osmosisd/ || true + build/osmosisd init runner -o + + # Download genesis file if not present + mkdir -p /mnt/data/genesis/osmosis-1/ + if [ ! -f "/mnt/data/genesis/osmosis-1/genesis.json" ]; then + wget -O /mnt/data/genesis/osmosis-1/genesis.json ${{ env.GENESIS_URL }} + fi + + # Copy genesis to config folder + cp /mnt/data/genesis/osmosis-1/genesis.json $HOME/.osmosisd/config/genesis.json + - + name: ⏬ Download last pre-epoch snapshot + run: | + REPO_MAJOR_VERSION=$(echo $(git describe --tags) | cut -f 1 -d '.') # with v prefix + + # Find current major version via rpc.osmosis.zone/abci_info + RPC_ABCI_INFO=$(curl -s --retry 5 --retry-delay 5 --connect-timeout 30 -H "Accept: application/json" ${{ env.RPC_ENDPOINT }}/abci_info) + CHAIN_MAJOR_VERSION=$(echo $RPC_ABCI_INFO | dasel --plain -r json 'result.response.version' | cut -f 1 -d '.') # no v prefix + + # Get correct url to fetch snapshot comparing versions + if [ $REPO_MAJOR_VERSION == v$CHAIN_MAJOR_VERSION ]; then + # I'm in the latest major + SNAPSHOT_INFO_URL=${{ env.SNAPSHOT_BUCKET }}/osmosis.json + else + SNAPSHOT_INFO_URL=${{ env.SNAPSHOT_BUCKET }}/$REPO_MAJOR_VERSION/osmosis.json + fi + + # Get the latest pre-epoch snapshot information from bucket + SNAPSHOT_INFO=$(curl -s --retry 5 --retry-delay 5 --connect-timeout 30 -H "Accept: application/json" $SNAPSHOT_INFO_URL) + SNAPSHOT_URL=$(echo $SNAPSHOT_INFO | dasel --plain -r json '(file=osmosis-1-pre-epoch).url') + SNAPSHOT_ID=$(echo $SNAPSHOT_INFO | dasel --plain -r json '(file=osmosis-1-pre-epoch).filename' | cut -f 1 -d '.') + + # Download snapshot if not already present + mkdir -p /mnt/data/snapshots/$REPO_MAJOR_VERSION/ + if [ ! -d "/mnt/data/snapshots/$REPO_MAJOR_VERSION/$SNAPSHOT_ID" ]; then + rm -rf /mnt/data/snapshots/$REPO_MAJOR_VERSION/* + mkdir /mnt/data/snapshots/$REPO_MAJOR_VERSION/$SNAPSHOT_ID + wget -q -O - $SNAPSHOT_URL | lz4 -d | tar -C /mnt/data/snapshots/$REPO_MAJOR_VERSION/$SNAPSHOT_ID -xvf - + fi + + # Copy snapshot in Data folder + cp -R /mnt/data/snapshots/$REPO_MAJOR_VERSION/$SNAPSHOT_ID/* $HOME/.osmosisd/ + - + name: 🧪 Configure Osmosis Node + run: | + CONFIG_FOLDER=$HOME/.osmosisd/config + + # Find current major version via rpc.osmosis.zone/abci_info + RPC_ABCI_INFO=$(curl -s --retry 5 --retry-delay 5 --connect-timeout 30 -H "Accept: application/json" ${{ env.RPC_ENDPOINT }}/abci_info) + CHAIN_MAJOR_VERSION=$(echo $RPC_ABCI_INFO | dasel --plain -r json 'result.response.version' | cut -f 1 -d '.') + + # Find last epoch block comparing repo version to current chain version + REPO_MAJOR_VERSION=$(echo $(git describe --tags) | sed 's/^v//' | cut -f 1 -d '.') # without v prefix + + if [ $REPO_MAJOR_VERSION == $CHAIN_MAJOR_VERSION ]; then + # I'm in the latest major, fetch the epoch info from the lcd endpoint + LAST_EPOCH_BLOCK_HEIGHT=$(curl -s --retry 5 --retry-delay 5 --connect-timeout 30 ${{ env.LCD_ENDPOINT }}/osmosis/epochs/v1beta1/epochs | dasel --plain -r json 'epochs.(identifier=day).current_epoch_start_height') + else + # I'm in a previous major, calculate the epoch height from the snapshot height + # (Snapshot is taken 100 blocks before epoch) + + SNAPSHOT_INFO_URL=${{ env.SNAPSHOT_BUCKET }}/v$REPO_MAJOR_VERSION/osmosis.json + SNAPSHOT_INFO=$(curl -s --retry 5 --retry-delay 5 --connect-timeout 30 -H "Accept: application/json" $SNAPSHOT_INFO_URL) + SNAPSHOT_BLOCK_HEIGHT=$(echo $SNAPSHOT_INFO | dasel --plain -r json '(file=osmosis-1-pre-epoch).height') + LAST_EPOCH_BLOCK_HEIGHT=$(($SNAPSHOT_BLOCK_HEIGHT + 100)) + fi + + HALT_HEIGHT=$(($LAST_EPOCH_BLOCK_HEIGHT + ${{ env.DELTA_HALT_HEIGHT }})) + + echo "Osmosis repo version: $REPO_MAJOR_VERSION" + echo "Last Epoch Height: $LAST_EPOCH_BLOCK_HEIGHT" + echo "Halt Height: $HALT_HEIGHT" + + # Edit config.toml + dasel put string -f $CONFIG_FOLDER/config.toml '.tx_index.indexer' null + + # Edit app.toml + dasel put string -f $CONFIG_FOLDER/app.toml '.halt-height' $HALT_HEIGHT + dasel put string -f $CONFIG_FOLDER/app.toml '.pruning' everything + dasel put string -f $CONFIG_FOLDER/app.toml '.state-sync.snapshot-interval' 0 + - + name: 🧪 Start Osmosis Node + run: build/osmosisd start + - + name: 🧹 Clean up Osmosis Home + if: always() + run: rm -rf $HOME/.osmosisd/ || true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a5c412feadb..98686bd2888 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Tests & Code Coverage +name: Tests on: pull_request: @@ -29,7 +29,7 @@ jobs: name: Skipping test run: echo Should I skip tests? ${{ steps.skip_check.outputs.should_skip }} - go_test: + go: needs: should_run_go_test if: ${{ needs.should_run_test.outputs.should_skip != 'true' }} runs-on: ubuntu-latest @@ -66,7 +66,7 @@ jobs: name: Run all tests run: make test-unit - e2e_test: + e2e: runs-on: ubuntu-latest timeout-minutes: 25 steps: @@ -123,4 +123,4 @@ jobs: BASE_IMG_TAG=debug - name: Test e2e and Upgrade - run: make test-e2e + run: make test-e2e-ci diff --git a/.gitignore b/.gitignore index 1e05d8c9fa4..713ac5a1033 100644 --- a/.gitignore +++ b/.gitignore @@ -202,3 +202,31 @@ $RECYCLE.BIN/ /x/incentives/keeper/osmosis_testing/ tools-stamp /tests/localosmosis/.osmosisd/* +*.save +*.save.* + +mutation_test_result.txt +go_mutation_test_result.txt + +# Rust ignores. Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Generated by rust-optimizer +artifacts/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +# Ignores beaker state +.beaker +blocks.db +**/blocks.db* diff --git a/.gitpod.yml b/.gitpod.yml index 5d7ad67e74f..405d1239b73 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -1,4 +1,4 @@ -image: ghcr.io/faddat/cosmos +image: ghcr.io/notional-labs/cosmos ports: - port: 1317 diff --git a/.golangci.yml b/.golangci.yml index 6f13fdeebb5..19d70d9e4c6 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -13,7 +13,6 @@ linters: # - bodyclose <- needs go 1.18 support # - contextcheck <- needs go 1.18 support # - cyclop - # - deadcode <- re-enable in another pr - depguard # - dogsled <- disabled because we would like to participate in the iditerod # - dupl <- really just catches cli stub text @@ -45,9 +44,9 @@ linters: - gomodguard - goprintffuncname # - gosec <- triggers too much for this round and should be re-enabled later -# - gosimple <- later + - gosimple # specializes in simplifying code, subset of staticcheck binary. - govet - # - ifshort <- seems to be of questionable value + # - ifshort <- questionable value, unclear if globally helping readability. - importas - ineffassign # - ireturn <- disabled because we want to return interfaces @@ -68,9 +67,8 @@ linters: # - revive <- temporarily disabled while jacob figures out how to make poolId not trigger it. # - rowserrcheck <- needs go 1.18 support # - sqlclosecheck <- needs go 1.18 support -# - staticcheck <- later -# - structcheck <- later -# - stylecheck <- enable later, atriggers on underscores in variable names and on poolId + - staticcheck # set of rules from staticcheck, subset of staticcheck binary. + - stylecheck # replacement of golint, subset of staticcheck binary. # - tagliatelle <- disabled for defying cosmos idiom - tenv - testpackage @@ -79,8 +77,7 @@ linters: - typecheck - unconvert # - unparam <- looks for unused parameters (enable later) -# - unused <- looks for unused variables (enable later) -# - varcheck <- later + - unused # looks for unused variables, subset of staticcheck binary. # - varnamelen <- disabled because defies idiom # - wastedassign - whitespace @@ -95,5 +92,24 @@ issues: - path: client/docs linters: - all + - path: x/gamm/pool-models/stableswap + linters: + # Stableswap is in development. + # We should re-enable deadcode and unused linting + # across its files, once stableswap is fully complete. + - unused + - deadcode + - linters: + - staticcheck + text: "SA1024: cutset contains duplicate characters" # proved to not provide much value, only false positives. + - linters: + - staticcheck + text: "SA9004: only the first constant in this group has an explicit type" # explicitly recommended in go syntax + - linters: + - stylecheck + text: "ST1003:" # requires identifiers with "id" to be "ID". + - linters: + - stylecheck + text: "ST1005:" # punctuation in error messages max-issues-per-linter: 10000 max-same-issues: 10000 diff --git a/.markdownlint.yml b/.markdownlint.yml index 7a7a4ae914d..084cc284dba 100644 --- a/.markdownlint.yml +++ b/.markdownlint.yml @@ -1,11 +1,16 @@ # Default state for all rules default: true -MD003: +MD003: # Heading style - style: "atx" + style: 'atx' +MD004: false # Can't disable MD007 :/ -# MD007: false +MD007: false MD009: false -MD013: +MD010: code_blocks: false -MD024: false \ No newline at end of file +MD013: false +MD024: false +MD029: false +MD033: false +MD037: false # breaks on latex diff --git a/.markdownlintignore b/.markdownlintignore index 89665653f40..629386a334e 100644 --- a/.markdownlintignore +++ b/.markdownlintignore @@ -34,7 +34,6 @@ x/lockup/spec/08_params.md x/lockup/spec/09_endblocker.md x/lockup/spec/02_state.md x/incentives/spec/06_queries.md -contrib/images/rbuilder/README.md x/incentives/spec/02_state.md x/gamm/spec/01_concepts.md x/gamm/README.md diff --git a/.vscode/templates/call.tmpl b/.vscode/templates/call.tmpl new file mode 100644 index 00000000000..3c121512de8 --- /dev/null +++ b/.vscode/templates/call.tmpl @@ -0,0 +1 @@ +{{define "call"}}{{.Name}}({{range $i, $el := .Parameters}}{{if $i}}, {{end}}{{if not .IsWriter}}tc.{{end}}{{Param .}}{{end}}){{end}} \ No newline at end of file diff --git a/.vscode/templates/function.tmpl b/.vscode/templates/function.tmpl new file mode 100644 index 00000000000..6344d290906 --- /dev/null +++ b/.vscode/templates/function.tmpl @@ -0,0 +1,31 @@ +{{define "function"}} +{{- $f := .}} + +func (suite *KeeperTestSuite) Test{{.Name}}() { + + tests := map[string]struct { + {{- range .TestParameters}} + {{Param .}} {{.Type}} + {{- end}} + expectPass bool + }{ + "example test": { + }, + } + + for name, tc := range tests { + suite.Run(name, func() { + suite.SetupTest() + k := suite.App.GAMMKeeper + + err := k.{{template "call" $f}} + + if tc.expectPass { + suite.Require().NoError(err, "test: %s", name) + } else { + suite.Require().Error(err, "test: %s", name) + } + }) + } +} +{{end}} \ No newline at end of file diff --git a/.vscode/templates/header.tmpl b/.vscode/templates/header.tmpl new file mode 100644 index 00000000000..4e36657b555 --- /dev/null +++ b/.vscode/templates/header.tmpl @@ -0,0 +1,10 @@ +{{define "header"}} +{{range .Comments}}{{.}} +{{end -}} +package {{.Package}} + +import ( +{{range .Imports}}{{.Name}} {{.Path}} +{{end}} +) +{{end}} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 405f64acb73..dc5fe9eeb5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,32 +42,163 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Features + +* [#2739](https://github.com/osmosis-labs/osmosis/pull/2739) Add pool type query +* [#2803](https://github.com/osmosis-labs/osmosis/pull/2803) Fix total pool liquidity CLI query. + +## v12.0.0 + +This release includes several cosmwasm-developer and appchain-ecosystem affecting upgrades: + +* TWAP - Time weighted average prices for all AMM pools +* Cosmwasm contract developer facing features + * Enabling select queries for cosmwasm contracts + * Add message responses to gamm messages, to remove the neccessity of bindings + * Allow specifying denom metadata from tokenfactory +* Enabling Interchain accounts (for real this time) +* Upgrading IBC to v3.3.0 +* Consistently makes authz work with ledger for all messages + +The release also contains the following changes affecting Osmosis users and node operators + +* Fixing State Sync +* Enabling expedited proposals + +This upgrade also adds a number of safety and API boundary improving changes to the codebase. +While not state machine breaking, this release also includes the revamped Osmosis simulator, +which acts as a fuzz testing tool tailored for the SDK state machine. + ### Breaking Changes +* [#2477](https://github.com/osmosis-labs/osmosis/pull/2477) Tokenfactory burn msg clash with sdk + * TypeMsgBurn: from "burn" to "tf_burn" + * TypeMsgMint: from "mint" to "tf_mint" +* [#2222](https://github.com/osmosis-labs/osmosis/pull/2222) Add scaling factors to MsgCreateStableswapPool +* [#1889](https://github.com/osmosis-labs/osmosis/pull/1825) Add proto responses to gamm LP messages: + * MsgJoinPoolResponse: share_out_amount and token_in fields + * MsgExitPoolResponse: token_out field * [#1825](https://github.com/osmosis-labs/osmosis/pull/1825) Fixes Interchain Accounts (host side) by adding it to AppModuleBasics -* [#1699](https://github.com/osmosis-labs/osmosis/pull/1699) Fixes bug in sig fig rounding on spot price queries for small values +* [#1994](https://github.com/osmosis-labs/osmosis/pull/1994) Removed bech32ibc module +* [#2016](https://github.com/osmosis-labs/osmosis/pull/2016) Add fixed 10000 gas cost for each Balancer swap +* [#2193](https://github.com/osmosis-labs/osmosis/pull/2193) Add TwapKeeper to the Osmosis app +* [#2227](https://github.com/osmosis-labs/osmosis/pull/2227) Enable charging fee in base denom for `CreateGauge` and `AddToGauge`. +* [#2283](https://github.com/osmosis-labs/osmosis/pull/2283) x/incentives: refactor `CreateGauge` and `AddToGauge` fees to use txfees denom +* [#2206](https://github.com/osmosis-labs/osmosis/pull/2283) Register all Amino interfaces and concrete types on the authz Amino codec. This will allow the authz module to properly serialize and de-serializes instances using Amino. +* [#2405](https://github.com/osmosis-labs/osmosis/pull/2405) Make SpotPrice have a max value of 2^160, and no longer be able to panic +* [#2473](https://github.com/osmosis-labs/osmosis/pull/2473) x/superfluid `AddNewSuperfluidAsset` now returns error, if any occurs instead of ignoring it. +* [#2714](https://github.com/osmosis-labs/osmosis/pull/2714) Upgrade wasmd to v0.28.0. +* Remove x/Bech32IBC #### Golang API breaks -* [#1893](https://github.com/osmosis-labs/osmosis/pull/1893) Change `EpochsKeeper.SetEpochInfo` to `AddEpochInfo`, which has more safety checks with it. (Makes it suitable to be called within upgrades) -* [#1671](https://github.com/osmosis-labs/osmosis/pull/1671) Remove methods that constitute AppModuleSimulation APIs for several modules' AppModules, which implemented no-ops -* [#1671](https://github.com/osmosis-labs/osmosis/pull/1671) Add hourly epochs to `x/epochs` DefaultGenesis. -* [#1665](https://github.com/osmosis-labs/osmosis/pull/1665) Delete app/App interface, instead use simapp.App -* [#1630](https://github.com/osmosis-labs/osmosis/pull/1630) Delete the v043_temp module, now that we're on an updated SDK version. -* [#1667](https://github.com/osmosis-labs/osmosis/pull/1673) Move wasm-bindings code out of app . +* [#2160](https://github.com/osmosis-labs/osmosis/pull/2160) Clean up GAMM keeper (move `x/gamm/keeper/params.go` contents into `x/gamm/keeper/keeper.go`, replace all uses of `PoolNumber` with `PoolId`, move `SetStableSwapScalingFactors` to stableswap package, and delete marshal_bench_test.go and grpc_query_internal_test.go) +* [#1987](https://github.com/osmosis-labs/osmosis/pull/1987) Remove `GammKeeper.GetNextPoolNumberAndIncrement` in favor of the non-mutative `GammKeeper.GetNextPoolNumber`. +* [#1667](https://github.com/osmosis-labs/osmosis/pull/1673) Move wasm-bindings code out of app package into its own root level package. +* [#2013](https://github.com/osmosis-labs/osmosis/pull/2013) Make `SetParams`, `SetPool`, `SetTotalLiquidity`, and `SetDenomLiquidity` GAMM APIs private +* [#1857](https://github.com/osmosis-labs/osmosis/pull/1857) x/mint rename GetLastHalvenEpochNum to GetLastReductionEpochNum +* [#2133](https://github.com/osmosis-labs/osmosis/pull/2133) Add `JoinPoolNoSwap` and `CalcJoinPoolNoSwapShares` to GAMM pool interface and route `JoinPoolNoSwap` in pool_service.go to new method in pool interface +* [#2353](https://github.com/osmosis-labs/osmosis/pull/2353) Re-enable stargate query via whitelsit +* [#2394](https://github.com/osmosis-labs/osmosis/pull/2394) Remove unused interface methods from expected keepers of each module +* [#2390](https://github.com/osmosis-labs/osmosis/pull/2390) x/mint remove unused mintCoins parameter from AfterDistributeMintedCoin +* [#2418](https://github.com/osmosis-labs/osmosis/pull/2418) x/mint remove SetInitialSupplyOffsetDuringMigration from keeper +* [#2417](https://github.com/osmosis-labs/osmosis/pull/2417) x/mint unexport keeper `SetLastReductionEpochNum`, `getLastReductionEpochNum`, `CreateDeveloperVestingModuleAccount`, and `MintCoins` +* [#2587](https://github.com/osmosis-labs/osmosis/pull/2587) remove encoding config argument from NewOsmosisApp +x ### Features +* [#2387](https://github.com/osmosis-labs/osmosis/pull/2387) Upgrade to IBC v3.2.0, which allows for sending/receiving IBC tokens with slashes. * [#1312] Stableswap: Createpool logic * [#1230] Stableswap CFMM equations * [#1429] solver for multi-asset CFMM * [#1539] Superfluid: Combine superfluid and staking query on querying delegation by delegator +* [#2223] Tokenfactory: Add SetMetadata functionality + +### Bug Fixes + +* [#2086](https://github.com/osmosis-labs/osmosis/pull/2086) `ReplacePoolIncentivesProposal` ProposalType() returns correct value of `ProposalTypeReplacePoolIncentives` instead of `ProposalTypeUpdatePoolIncentives` +* [1930](https://github.com/osmosis-labs/osmosis/pull/1930) Ensure you can't `JoinPoolNoSwap` tokens that are not in the pool +* [2186](https://github.com/osmosis-labs/osmosis/pull/2186) Remove liquidity event that was emitted twice per message. + +### Improvements +* [#2515](https://github.com/osmosis-labs/osmosis/pull/2515) Emit events from functions implementing epoch hooks' `panicCatchingEpochHook` cacheCtx +* [#2526](https://github.com/osmosis-labs/osmosis/pull/2526) EpochHooks interface methods (and hence modules implementing the hooks) return error instead of panic + +## v11.0.1 + +#### Golang API breaks +* [#1893](https://github.com/osmosis-labs/osmosis/pull/1893) Change `EpochsKeeper.SetEpochInfo` to `AddEpochInfo`, which has more safety checks with it. (Makes it suitable to be called within upgrades) +* [#2396](https://github.com/osmosis-labs/osmosis/pull/2396) x/mint remove unused mintCoins parameter from AfterDistributeMintedCoin +* [#2399](https://github.com/osmosis-labs/osmosis/pull/2399) Remove unused interface methods from expected keepers of each module +* [#2401](https://github.com/osmosis-labs/osmosis/pull/2401) Update Go import paths to v11 + +#### Bug Fixes +* [2291](https://github.com/osmosis-labs/osmosis/pull/2291) Remove liquidity event that was emitted twice per message +* [2288](https://github.com/osmosis-labs/osmosis/pull/2288) Fix swagger docs and swagger generation + +## v11 + +#### Improvements +* [#2237](https://github.com/osmosis-labs/osmosis/pull/2237) Enable charging fee in base denom for `CreateGauge` and `AddToGauge`. + +#### SDK Upgrades +* [#2245](https://github.com/osmosis-labs/osmosis/pull/2245) Upgrade SDK for to v0.45.0x-osmo-v9.2. Major changes: + * Minimum deposit on proposer at submission time: https://github.com/osmosis-labs/cosmos-sdk/pull/302 + +## v10.1.1 + +#### Improvements +* [#2214](https://github.com/osmosis-labs/osmosis/pull/2214) Speedup epoch distribution, superfluid component + +## v10.1.0 + +#### Bug Fixes +* [2011](https://github.com/osmosis-labs/osmosis/pull/2011) Fix bug in TokenFactory initGenesis, relating to denom creation fee param. + +#### Improvements +* [#2130](https://github.com/osmosis-labs/osmosis/pull/2130) Introduce errors in mint types. +* [#2000](https://github.com/osmosis-labs/osmosis/pull/2000) Update import paths from v9 to v10. + +#### Golang API breaks +* [#1937](https://github.com/osmosis-labs/osmosis/pull/1937) Change `lockupKeeper.ExtendLock` to take in lockID instead of the direct lock struct. +* [#2030](https://github.com/osmosis-labs/osmosis/pull/2030) Rename lockup keeper `ResetAllLocks` to `InitializeAllLocks` and `ResetAllSyntheticLocks` to `InitializeAllSyntheticLocks`. + +#### SDK Upgrades +* [#2146](https://github.com/osmosis-labs/osmosis/pull/2146) Upgrade SDK for to v0.45.0x-osmo-v9.1. Major changes: + * Concurrency query client option: https://github.com/osmosis-labs/cosmos-sdk/pull/281 + * Remove redacted message fix: https://github.com/osmosis-labs/cosmos-sdk/pull/284 + * Reduce commit store logs (change to Debug): https://github.com/osmosis-labs/cosmos-sdk/pull/282 + * Bring back the cliff vesting command: https://github.com/osmosis-labs/cosmos-sdk/pull/272 + * Allow ScheduleUpgrade to come from same block: https://github.com/osmosis-labs/cosmos-sdk/pull/261 + + +## v10.0.1 + +This release contains minor CLI bug fixes. +* Restores vesting by duration command +* Fixes pagination in x/incentives module queries + +## v10.0.0 + + +## v9.0.1 + +### Breaking Changes + +* [#1699](https://github.com/osmosis-labs/osmosis/pull/1699) Fixes bug in sig fig rounding on spot price queries for small values +* [#1671](https://github.com/osmosis-labs/osmosis/pull/1671) Remove methods that constitute AppModuleSimulation APIs for several modules' AppModules, which implemented no-ops +* [#1671](https://github.com/osmosis-labs/osmosis/pull/1671) Add hourly epochs to `x/epochs` DefaultGenesis. +* [#1665](https://github.com/osmosis-labs/osmosis/pull/1665) Delete app/App interface, instead use simapp.App +* [#1630](https://github.com/osmosis-labs/osmosis/pull/1630) Delete the v043_temp module, now that we're on an updated SDK version. ### Bug Fixes + * [1700](https://github.com/osmosis-labs/osmosis/pull/1700) Upgrade sdk fork with missing snapshot manager fix. * [1716](https://github.com/osmosis-labs/osmosis/pull/1716) Fix secondary over-LP shares bug with uneven swap amounts in `CalcJoinPoolShares`. * [1759](https://github.com/osmosis-labs/osmosis/pull/1759) Fix pagination filter in incentives query. * [1698](https://github.com/osmosis-labs/osmosis/pull/1698) Register wasm snapshotter extension. +* [1931](https://github.com/osmosis-labs/osmosis/pull/1931) Add explicit check for input denoms to `CalcJoinPoolShares` ## [v9.0.0 - Nitrogen](https://github.com/osmosis-labs/osmosis/releases/tag/v9.0.0) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9c73f4537d0..e7a6ee99974 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,7 @@ Contributions come in the form of writing documentation, raising issues / PRs, a ## First steps -The first step is to find an issue you want to fix. To identify issues we think are good for first-time contributors, we add the **good first issue** label. +The first step is to find an issue you want to fix. To identify issues we think are good for first-time contributors, we add the **good first issue** label. [You can see a list of issues to contribute here](https://github.com/osmosis-labs/osmosis/contribute). We recommend setting up your IDE as per our [recommended IDE setup](https://docs.osmosis.zone/developing/osmosis-core/ide-guide.html) before proceeding. @@ -30,6 +30,7 @@ To contribute a change proposal, use the following workflow: 1. Commit your changes. Write a simple, straightforward commit message. To learn more, see [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/). 2. Push your changes to your remote fork. To add your remote, you can copy/paste the following: + ```sh #Remove origin @@ -53,11 +54,222 @@ To contribute a change proposal, use the following workflow: #e.g. git push my_awesome_new_remote_repo ``` + 3. Create a PR on the Osmosis repository. There should be a PR template to help you do so. 4. Wait for your changes to be reviewed. If you are a maintainer, you can assign your PR to one or more reviewers. If you aren't a maintainer, one of the maintainers will assign a reviewer. 5. After you receive feedback from a reviewer, make the requested changes, commit them to your branch, and push them to your remote fork again. 6. Once approval is given, feel free to squash & merge! +## Writing tests + +We use table-driven tests because they allow us to test similar logic on many different cases in a way that is easy to both implement and understand. [This article](https://dave.cheney.net/2019/05/07/prefer-table-driven-tests) does a fantastic job explaining the motivation and structure of table-driven testing. + +Making table-driven tests in an environment built on the Cosmos SDK has some quirks to it, but overall the structure should be quite similar to what is laid out in the article linked above. + +We'll lay out three examples below (one that uses our format for messages, one that applies to keeper methods, and one that applies to our GAMM module), each of which will hopefully be simple enough to copy-paste into a test file and use as a starting point for your test-writing in the Osmosis Core repo. + +### Generating unit tests using our Gotest template + +To simplify (and speed up) the process of writing unit tests that fit our standard, we have put together a Gotest template that allows you to easily generate unit tests using built-in functionality for the Vscode Go plugin (complete with parameters listed, basic error checking logic etc.). The following two sections lay out how to generate a unit test automatically using this method. + +#### 1. Setup + +Note: this section assumes you already have the Go plugin for Vscode installed. Please refer to our [IDE setup docs](https://docs.osmosis.zone/developing/osmosis-core/ide-guide.html) if you haven't done any IDE setup yet. + +Copy the `templates` folder into your `.vscode` folder from our main repo [here](https://github.com/osmosis-labs/osmosis/tree/main/.vscode). This folder has our custom templates for generating tests that fit our testing standards as accurately as possible. + +Then, go to your `settings.json` file in your `.vscode` folder and add the following to it: + +```go + "go.generateTestsFlags": [ + "-template_dir", + "[ABSOLUTE PATH TO TEMPLATES FOLDER]" + ], +``` + +where `"[ABSOLUTE PATH TO TEMPLATES FOLDER]"` should look something like: `"User/ExampleUser/osmosis/.vscode/templates"` + +#### 2. Generating a unit test + +On the function you want to generate a unit test for, right click the function name and select `Go: Generate Unit Tests For Function`. This should take you to an automatically generated template test in the corresponding test file for the file your function is in. If there isn't a corresponding test file, it should automatically generate one, define its package and imports, and generate the test there. + +### Rules of thumb for table-driven tests + +1. Each test case should test one thing +2. Each test case should be independent from one another (i.e. ideally, reordering the tests shouldn't cause them to fail) +3. Functions should not be set as fields for a test case (this usually means that the table-driven approach is being sidestepped and that the logic in the function should probably be factored out to cover multiple/all test cases) +4. Avoid verbosity by creating local variables instead of constantly referring to struct field (e.g. doing `lockupKeeper := suite.App.LockupKeeper` instead of using `suite.App.LockupKeeper` every time). + +### Example #1: [Message-Related Test] + +This type of test is mainly for functions that would be triggered by incoming messages (we interact directly with the message server since all other metadata is stripped from a message by the time it hits the msg_server): + +```go +func(suite *KeeperTestSuite) TestCreateDenom() { + testCases := map[string] struct { + subdenom string + expectError bool + } { + + "subdenom too long": { + subdenom: "assadsadsadasdasdsadsadsadsadsadsadsklkadaskkkdasdasedskhanhassyeunganassfnlksdflksafjlkasd", + valid: false, + }, + "success case": { + subdenom: "evmos", + valid: true, + }, + } + + for name, tc := range testCases { + suite.Run(name, func() { + ctx := suite.Ctx + msgServer := suite.msgServer + queryClient := suite.queryClient + + // Create a denom + res, err := msgServer.CreateDenom(sdk.WrapSDKContext(ctx), types.NewMsgCreateDenom(suite.TestAccs[0].String(), tc.subdenom)) + + if !tc.expectError { + suite.Require().NoError(err) + + // Make sure that the admin is set correctly + queryRes, err := queryClient.DenomAuthorityMetadata(ctx.Context(), & types.QueryDenomAuthorityMetadataRequest { + Denom: res.GetNewTokenDenom(), + }) + + suite.Require().NoError(err) + suite.Require().Equal(suite.TestAccs[0].String(), queryRes.AuthorityMetadata.Admin) + + } else { + suite.Require().Error(err) + } + }) + } +} +``` + +### Example #2: [Keeper-Related Test] + +This type of test is mainly for functions that would be triggered by other modules calling public keeper methods (or just to unit-test keeper methods in general): + +```go +// TestMintExportGenesis tests that genesis is exported correctly. +// It first initializes genesis to the expected value. Then, attempts +// to export it. Lastly, compares exported to the expected. +func(suite *KeeperTestSuite) TestMintExportGenesis() { + testCases := map[string] struct { + expectedGenesis *types.GenesisState + } { + "default genesis": { + expectedGenesis: types.DefaultGenesisState(), + }, + "custom genesis": { + expectedGenesis: customGenesis, + }, + } + + for name, tc := range testCases { + suite.Run(name, func() { + // Setup. + app := suite.App + ctx := suite.Ctx + + app.MintKeeper.InitGenesis(ctx, tc.expectedGenesis) + + // Test. + actualGenesis := app.MintKeeper.ExportGenesis(ctx) + + // Assertions. + suite.Require().Equal(tc.expectedGenesis, actualGenesis) + }) + } +} +``` + +### Example #3: [Gamm-Related Test] + +Since the GAMM module is core to the Osmosis repo, it might be useful to have a good example of a well-structured GAMM-specific test. This example covers a simple getter function and validates the specific error messages around the function (as opposed to merely the presence of an error): + +```go +func TestGetPoolAssetsByDenom(t *testing.T) { + testCases := map[string] struct { + poolAssets []balancer.PoolAsset + expectedPoolAssetsByDenom map[string]balancer.PoolAsset + expectedErr error + } { + + "one pool asset": { + poolAssets: []balancer.PoolAsset { + { + Token: sdk.NewInt64Coin("uosmo", 1e12), + Weight: sdk.NewInt(100), + }, + }, + expectedPoolAssetsByDenom: map[string]balancer.PoolAsset { + "uosmo": { + Token: sdk.NewInt64Coin("uosmo", 1e12), + Weight: sdk.NewInt(100), + }, + }, + }, + + "duplicate pool assets": { + poolAssets: []balancer.PoolAsset { + { + Token: sdk.NewInt64Coin("uosmo", 1e12), + Weight: sdk.NewInt(100), + }, { + Token: sdk.NewInt64Coin("uosmo", 123), + Weight: sdk.NewInt(400), + }, + }, + err: fmt.Errorf(balancer.ErrMsgFormatRepeatingPoolAssetsNotAllowed, "uosmo"), + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + actualPoolAssetsByDenom, err := balancer.GetPoolAssetsByDenom(tc.poolAssets) + + require.Equal(t, tc.expectedErr, err) + + if tc.err != nil { + return + } + + require.Equal(t, tc.expectedPoolAssetsByDenom, actualPoolAssetsByDenom) + }) + } +} +``` + +## Debug testing e2e locally + +The e2e package defines an integration testing suite used for full end-to-end testing functionality. This package is decoupled from depending on the Osmosis codebase. It initializes the chains for testing via Docker files. + +As a result, the test suite may provide the desired Osmosis version to Docker containers during the initialization. This design allows for the opportunity of testing chain upgrades in the future by providing an older Osmosis version to the container, performing the chain upgrade, and running the latest test suite. + +The file `e2e_setup_test.go` defines the testing suite and contains the core bootstrapping logic that creates a testing environment via Docker containers. A testing network is created dynamically by providing the desirable number of validator configurations. + +The file `e2e_test.go` contains the actual end-to-end integration tests that utilize the testing suite. + +Additionally, there is an ability to disable certain components of the e2e suite. This can be done by setting the environment variables. See the [E2E test docs](https://github.com/osmosis-labs/osmosis/blob/main/tests/e2e/README.md) or more details. + +To get started: + +- Run `make test-e2e-debug` for the full e2e test suite. +- Run `make test-e2e-short` for the short e2e test suite that excludes upgrade, IBC and state-sync tests. +- Inspect the logs of the docker containers and see if something is there. +- `docker ps -a #` to list all docker containers +- Note the container id of the one you want to see the logs +- And then run `docker logs ` to debug via container logs + +Please note that if the tests are stopped mid-way, the e2e framework might fail to start again due to duplicated containers. Make sure that +containers are removed before running the tests again: `docker containers rm -f $(docker containers ls -a -q)`. + +Additionally, Docker networks do not get auto-removed. Therefore, you can manually remove them by running `docker network prune`. + ## Working with the SDK ### Updating dependencies for builds @@ -115,21 +327,251 @@ You can also feel free to do `make format` if you're getting errors related to ` There are several steps that go into a major release -* Run the [existing binary creation tool](https://github.com/osmosis-labs/osmosis/blob/main/.github/workflows/release.yml). Running `make -f contrib/images/osmobuilder/Makefile release` on the root of the repo will replicate the CI that creates the release folder containing the binaries. +- The GitHub release is created via this [GitHub workflow](https://github.com/osmosis-labs/osmosis/blob/main/.github/workflows/release.yml). The workflow is manually triggered from the [osmosis-ci repository](https://github.com/osmosis-labs/osmosis-ci). The workflow uses the `make build-reproducible` command to create the `osmosisd` binaries using the default [Makefile](https://github.com/osmosis-labs/osmosis/blob/main/Makefile#L99). + +- Make a PR to main, with a cosmovisor config, generated in tandem with the binaries from tool. + - Should be its own PR, as it may get denied for Fork upgrades. + +- Make a PR to main to update the import paths and go.mod for the new major release + +- Should also make a commit into every open PR to main to do the same find/replace. (Unless this will cause conflicts) + +- Do a PR if that commit has conflicts + +- (Eventually) Make a PR that adds a version handler for the next upgrade + - [Add v10 upgrade boilerplate #1649](https://github.com/osmosis-labs/osmosis/pull/1649/files) + +- Update chain JSON schema's recommended versions in `chain.schema.json` located in the root directory. + +## Patch and Minor Releases + +### Backport Flow + +For patch and minor releases, we should already have +a release branch available in the repository. For example, +for any v11 release, we have a `v11.x` branch. + +Therefore, for any change made to the `main` and, as long as it is +**state-compatible**, we must backport it to the last major release branch e.g. +`v11.x` when the next major release is v12. + +This helps to minimize the diff of a major upgrade review process. + +Additionally, it helps to safely and incrementally test +state-compatible changes by doing smaller patch releases. Contrary +to a major release, there is always an opportunity to safely downgrade +for any minor or patch release. + +### State-compatibility + +It is critical for the patch and minor releases to be state-machine compatible with +prior releases in the same major version. For example, v11.2.1 must be +compatible with v11.1.0 and v11.0.0. + +This is to ensure **determinism** i.e. that given the same input, the nodes +will always produce the same output. + +State-incompatibility is allowed for major upgrades because all nodes in the network +perform it at the same time. Therefore, after the upgrade, the nodes continue +functioning in a deterministic way. + +#### Scope + +The state-machine scope includes the following areas: + +- All messages supported by the chain, including: + - Every msg's ValidateBasic method + - Every msg's MsgServer method + - Net gas usage, in all execution paths (WIP to make this not include error flows) + - Error result returned (TODO: Make the error code not merkelized) + - State changes (namely every store write) +- AnteHandlers in "DeliverTx" mode +- Whitelisted queries +- All `BeginBlock`/`EndBlock` logic + +The following are **NOT** in the state-machine scope: + +- Events +- Queries that are not whitelisted +- CLI interfaces + +#### Validating State-Compatibility + +Tendermint ensures state compatibility by validating a number +of hashes that can be found [here][2]. + +`AppHash` and `LastResultsHash` are the common sources of problems stemmnig from our work. +To avoid these problems, let's now examine how these hashes work. -* Make a PR to main, with a cosmovisor config, generated in tandem with the binaries from tool. - * Should be its own PR, as it may get denied for Fork upgrades. +##### App Hash -* Make a PR to main to update the import paths and go.mod for the new major release +An app hash is a hash of hashes of every store's Merkle root that is returned by +ABCI's `Commit()` from Cosmos-SDK to Tendermint. -* Should also make a commit into every open PR to main to do the same find/replace. (Unless this will cause conflicts) +Cosmos-SDK [takes an app hash of the application state][4], and propagates +it to Tendermint which, in turn, compares it to the app hash of the +rest of the network. -* Do a PR if that commit has conflicts +For example, at height n, [we compute][5]: +`app hash = hash(hash(root of x/epochs), hash(root of x/gamm)...)` -* (Eventually) Make a PR that adds a version handler for the next upgrade - * [Add v10 upgrade boilerplate #1649](https://github.com/osmosis-labs/osmosis/pull/1649/files) +Then, Tendermint ensures that the app hash of the local node matches the app hash +of the network. Please note that the explanation and examples are simplified. -* Update chain JSON schema's recommended versions in `chain.schema.json` located in the root directory. +##### LastResultsHash + +`LastResultsHash` is the root hash of all results from the transactions +in the block returned by the ABCI's `DeliverTx`. + +The [`LastResultsHash`][3] today contains: + +1. Tx `GasWanted` + +2. Tx `GasUsed` + +`GasUsed` being merkelized means that we cannot freely reorder methods that consume gas. +We should also be careful of modifying any validation logic since changing the +locations where we error or pass might affect transaction gas usage. + +There are plans to remove this field from being Merkelized in a subsequent Tendermint release, at which point we will have more flexibility in reordering operations / erroring. + +3. Tx response `Data` + +The `Data` field includes the proto message response. Therefore, we cannot +change these in patch releases. + +4. Tx response `Code` + +This is an error code that is returned by the transaction flow. In the case of +success, it is `0`. On a general error, it is `1`. Additionally, each module +defines its custom error codes. For example, `x/mint` currently has the +following: + + +As a result, it is important to avoid changing custom error codes or change +the semantics of what is valid logic in thransaction flows. + +Note that all of the above stem from `DeliverTx` execution path, which handles: + +- `AnteHandler`'s marked as deliver tx +- `msg.ValidateBasic` +- execution of a message from the message server + +The `DeliverTx` return back to the Tendermint is defined [here][1]. + +#### Major Sources of State-incompatibility + +##### Creating Additional State + +By erroneously creating database entries that exist in Version A but not in +Version B, we can cause the app hash to differ across nodes running +these versions in the network. Therefore, this must be avoided. + +##### Changing Proto Field Definitions + +For example, if we change a field that gets persisted to the database, +the app hash will differ across nodes running these versions in the network. + +Additionally, this affects `LastResultsHash` because it contains a `Data` field that is a marshaled proto message. + +##### Returning Different Errors Given Same Input + +Version A + +```go +func (sk Keeper) validateAmount(ctx context.Context, amount sdk.Int) error { + if amount.IsNegative() { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "amount must be positive or zero") + } + return nil +} +``` + +Version B + +```go +func (sk Keeper) validateAmount(ctx context.Context, amount sdk.Int) error { + if amount.IsNegative() || amount.IsZero() { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "amount must be positive") + } + return nil +} +``` + +Note that now an amount of 0 can be valid in "Version A". However, not in "Version B". +Therefore, if some nodes are running "Version A" and others are running "Version B", +the final app hash might not be deterministic. + +Additionally, a different error message does not matter because it +is not included in any hash. However, an error code `sdkerrors.ErrInvalidRequest` does. +It translates to the `Code` field in the `LastResultsHash` and participates in +its validation. + +##### Variability in Gas Usage + +For transaction flows (or any other flow that consumes gas), it is important +that the gas usage is deterministic. + +Currently, gas usage is being Merklized in the state. As a result, reordering functions +becomes risky. + +Suppose my gas limit is 2000 and 1600 is used up before entering +`someInternalMethod`. Consider the following: + +```go +func someInternalMethod(ctx sdk.Context) { + object1 := readOnlyFunction1(ctx) # consumes 1000 gas + object2 := readOnlyFunction2(ctx) # consumes 500 gas + doStuff(ctx, object1, object2) +} +``` + +- It will run out of gas with `gasUsed = 2600` where 2600 getting merkelized +into the tx results. + +```go +func someInternalMethod(ctx sdk.Context) { + object2 := readOnlyFunction2(ctx) # consumes 500 gas + object1 := readOnlyFunction1(ctx) # consumes 1000 gas + doStuff(ctx, object1, object2) +} +``` + +- It will run out of gas with `gasUsed = 2100` where 2100 is getting merkelized +into the tx results. + +Therefore, we introduced a state-incompatibility by merklezing diverging gas +usage. + +#### Secondary Limitations To Keep In Mind + +##### Network Requests to External Services + +It is critical to avoid performing network requests to external services +since it is common for services to be unavailable or rate-limit. + +Imagine a service that returns exchange rates when clients query its HTTP endpoint. +This service might experience downtime or be restricted in some geographical areas. + +As a result, nodes may get diverging responses where some +get successful responses while others errors, leading to state breakage. + +##### Randomness + +Randomness cannot be used in the state machine, as the state machine definitionally must be deterministic. +Any time you'd consider using it, instead seed a CSPRNG off of some seed. + +One thing to note is that in golang, iteration order over `map`s is non-deterministic, so to be deterministic you must gather the keys, and sort them all prior to iterating over all values. + +##### Parallelism and Shared State + +Threads and Goroutines might preempt differently in different hardware. Therefore, +they should be avoided for the sake of determinism. Additionally, it is hard +to predict when the multi-threaded state can be updated. + +##### Hardware Errors + +This is out of the developer's control but is mentioned for completeness. ### Pre-release auditing process @@ -137,15 +579,15 @@ For every module with notable changes, we assign someone who was not a primary a Deliverables of review are: -* PR's with in-line code comments for things they had to figure out (or questions) +- PR's with in-line code comments for things they had to figure out (or questions) -* Tests / test comments needed to convince themselves of correctness +- Tests / test comments needed to convince themselves of correctness -* Spec updates +- Spec updates -* Small refactors that helped in understanding / making code conform to consistency stds / improve code signal-to-noise ratio welcome +- Small refactors that helped in understanding / making code conform to consistency stds / improve code signal-to-noise ratio welcome -* (As with all PRs, should not be a monolithic PR that gets PR'd, even though that may be the natural way its first formed) +- (As with all PRs, should not be a monolithic PR that gets PR'd, even though that may be the natural way its first formed) At the moment, we're looking for a tool that lets us statically figure out every message that had something in its code path that changed. Until a tool is found, we must do this manually. @@ -153,3 +595,9 @@ We test in testnet & e2e testnet behaviors about every message that has changed We communicate with various integrators if they'd like release-blocking QA testing for major releases * Chainapsis has communicated wanting a series of osmosis-frontend functionalities to be checked for correctness on a testnet as a release blocking item + +[1]:https://github.com/cosmos/cosmos-sdk/blob/d11196aad04e57812dbc5ac6248d35375e6603af/baseapp/abci.go#L293-L303 +[2]:https://github.com/tendermint/tendermint/blob/9f76e8da150414ce73eed2c4f248947b657c7587/proto/tendermint/types/types.proto#L70-L77 +[3]:https://github.com/tendermint/tendermint/blob/main/types/results.go#L47-L54 +[4]:https://github.com/osmosis-labs/cosmos-sdk/blob/5c9a51c277d067e0ec5cf48df30a85fae95bcd14/store/rootmulti/store.go#L430 +[5]:https://github.com/osmosis-labs/cosmos-sdk/blob/5c9a51c277d067e0ec5cf48df30a85fae95bcd14/store/types/commit_info.go#L40 diff --git a/Dockerfile b/Dockerfile index b1d1331a642..12aded4050a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,39 +1,60 @@ # syntax=docker/dockerfile:1 -ARG BASE_IMG_TAG=nonroot +ARG GO_VERSION="1.18" +ARG RUNNER_IMAGE="gcr.io/distroless/static" # -------------------------------------------------------- -# Build +# Builder # -------------------------------------------------------- -FROM golang:1.18.2-alpine3.15 as build +FROM golang:${GO_VERSION}-alpine as builder -RUN set -eux; apk add --no-cache ca-certificates build-base; -RUN apk add git -# Needed by github.com/zondax/hid -RUN apk add linux-headers +RUN set -eux; apk add --no-cache ca-certificates build-base; apk add git linux-headers +# Download go dependencies WORKDIR /osmosis -COPY . /osmosis +COPY go.mod go.sum ./ +RUN --mount=type=cache,target=/root/.cache/go-build \ + --mount=type=cache,target=/root/go/pkg/mod \ + go mod download -# CosmWasm: see https://github.com/CosmWasm/wasmvm/releases -ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.0.0/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a -ADD https://github.com/CosmWasm/wasmvm/releases/download/v1.0.0/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a -RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep 7d2239e9f25e96d0d4daba982ce92367aacf0cbd95d2facb8442268f2b1cc1fc -RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep f6282df732a13dec836cda1f399dd874b1e3163504dbd9607c6af915b2740479 +# Cosmwasm - download correct libwasmvm version +RUN WASMVM_VERSION=$(go list -m github.com/CosmWasm/wasmvm | cut -d ' ' -f 2) && \ + wget https://github.com/CosmWasm/wasmvm/releases/download/$WASMVM_VERSION/libwasmvm_muslc.$(uname -m).a \ + -O /lib/libwasmvm_muslc.a -# CosmWasm: copy the right library according to architecture. The final location will be found by the linker flag `-lwasmvm_muslc` -RUN cp /lib/libwasmvm_muslc.$(uname -m).a /lib/libwasmvm_muslc.a +# Cosmwasm - verify checksum +RUN wget https://github.com/CosmWasm/wasmvm/releases/download/v1.0.0/checksums.txt -O /tmp/checksums.txt && \ + sha256sum /lib/libwasmvm_muslc.a | grep $(cat /tmp/checksums.txt | grep $(uname -m) | cut -d ' ' -f 1) -RUN BUILD_TAGS=muslc LINK_STATICALLY=true make build +# Copy the remaining files +COPY . . + +# Build osmosisd binary +RUN --mount=type=cache,target=/root/.cache/go-build \ + --mount=type=cache,target=/root/go/pkg/mod \ + VERSION=$(echo $(git describe --tags) | sed 's/^v//') && \ + COMMIT=$(git log -1 --format='%H') && \ + go build \ + -mod=readonly \ + -tags "netgo,ledger,muslc" \ + -ldflags "-X github.com/cosmos/cosmos-sdk/version.Name="osmosis" \ + -X github.com/cosmos/cosmos-sdk/version.AppName="osmosisd" \ + -X github.com/cosmos/cosmos-sdk/version.Version=$VERSION \ + -X github.com/cosmos/cosmos-sdk/version.Commit=$COMMIT \ + -X github.com/cosmos/cosmos-sdk/version.BuildTags='netgo,ledger,muslc' \ + -w -s -linkmode=external -extldflags '-Wl,-z,muldefs -static'" \ + -trimpath \ + -o /osmosis/build/ \ + ./... # -------------------------------------------------------- # Runner # -------------------------------------------------------- -FROM gcr.io/distroless/base-debian11:${BASE_IMG_TAG} +FROM ${RUNNER_IMAGE} -COPY --from=build /osmosis/build/osmosisd /bin/osmosisd +COPY --from=builder /osmosis/build/osmosisd /bin/osmosisd ENV HOME /osmosis WORKDIR $HOME @@ -43,4 +64,3 @@ EXPOSE 26657 EXPOSE 1317 ENTRYPOINT ["osmosisd"] -CMD [ "start" ] diff --git a/Makefile b/Makefile index 1210ead7ae2..37ba47910ec 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,12 @@ #!/usr/bin/make -f -PACKAGES_SIMTEST=$(shell go list ./... | grep '/simulation') VERSION := $(shell echo $(shell git describe --tags) | sed 's/^v//') COMMIT := $(shell git log -1 --format='%H') LEDGER_ENABLED ?= true SDK_PACK := $(shell go list -m github.com/cosmos/cosmos-sdk | sed 's/ /\@/g') DOCKER := $(shell which docker) BUILDDIR ?= $(CURDIR)/build +E2E_UPGRADE_VERSION := "v12" export GO111MODULE = on @@ -77,9 +77,6 @@ ifeq (,$(findstring nostrip,$(OSMOSIS_BUILD_OPTIONS))) BUILD_FLAGS += -trimpath endif -# The below include contains the tools target. -include contrib/devtools/Makefile - ############################################################################### ### Build ### ############################################################################### @@ -96,16 +93,39 @@ $(BUILD_TARGETS): go.sum $(BUILDDIR)/ $(BUILDDIR)/: mkdir -p $(BUILDDIR)/ -build-reproducible: go.sum - $(DOCKER) rm latest-build || true - $(DOCKER) run --volume=$(CURDIR):/sources:ro \ - --env TARGET_PLATFORMS='linux/amd64' \ - --env APP=osmosisd \ - --env VERSION=$(VERSION) \ - --env COMMIT=$(COMMIT) \ - --env LEDGER_ENABLED=$(LEDGER_ENABLED) \ - --name latest-build osmolabs/rbuilder:latest - $(DOCKER) cp -a latest-build:/home/builder/artifacts/ $(CURDIR)/ +# Cross-building for arm64 from amd64 (or viceversa) takes +# a lot of time due to QEMU virtualization but it's the only way (afaik) +# to get a statically linked binary with CosmWasm + +build-reproducible: build-reproducible-amd64 build-reproducible-arm64 + +build-reproducible-amd64: go.sum $(BUILDDIR)/ + $(DOCKER) buildx create --name osmobuilder || true + $(DOCKER) buildx use osmobuilder + $(DOCKER) buildx build \ + --build-arg GO_VERSION=$(shell cat go.mod | grep -E 'go [0-9].[0-9]+' | cut -d ' ' -f 2) \ + --platform linux/amd64 \ + -t osmosis-amd64 \ + --load \ + -f Dockerfile . + $(DOCKER) rm -f osmobinary || true + $(DOCKER) create -ti --name osmobinary osmosis-amd64 + $(DOCKER) cp osmobinary:/bin/osmosisd $(BUILDDIR)/osmosisd-linux-amd64 + $(DOCKER) rm -f osmobinary + +build-reproducible-arm64: go.sum $(BUILDDIR)/ + $(DOCKER) buildx create --name osmobuilder || true + $(DOCKER) buildx use osmobuilder + $(DOCKER) buildx build \ + --build-arg GO_VERSION=$(shell cat go.mod | grep -E 'go [0-9].[0-9]+' | cut -d ' ' -f 2) \ + --platform linux/arm64 \ + -t osmosis-arm64 \ + --load \ + -f Dockerfile . + $(DOCKER) rm -f osmobinary || true + $(DOCKER) create -ti --name osmobinary osmosis-arm64 + $(DOCKER) cp osmobinary:/bin/osmosisd $(BUILDDIR)/osmosisd-linux-arm64 + $(DOCKER) rm -f osmobinary build-linux: go.sum LEDGER_ENABLED=false GOOS=linux GOARCH=amd64 $(MAKE) build @@ -167,9 +187,10 @@ docs: @echo @echo "=========== Generate Complete ============" @echo +.PHONY: docs -protoVer=v0.7 -protoImageName=tendermintdev/sdk-proto-gen:$(protoVer) +protoVer=v0.8 +protoImageName=osmolabs/osmo-proto-gen:$(protoVer) containerProtoGen=cosmos-sdk-proto-gen-$(protoVer) containerProtoFmt=cosmos-sdk-proto-fmt-$(protoVer) @@ -183,39 +204,28 @@ proto-format: @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoFmt}$$"; then docker start -a $(containerProtoFmt); else docker run --name $(containerProtoFmt) -v $(CURDIR):/workspace --workdir /workspace tendermintdev/docker-build-proto \ find ./ -not -path "./third_party/*" -name "*.proto" -exec clang-format -i {} \; ; fi -############################################################################### -### Devdoc ### -############################################################################### +proto-image-build: + @DOCKER_BUILDKIT=1 docker build -t $(protoImageName) -f ./proto/Dockerfile ./proto -build-docs: - @cd docs && \ - while read p; do \ - (git checkout $${p} && npm install && VUEPRESS_BASE="/$${p}/" npm run build) ; \ - mkdir -p ~/output/$${p} ; \ - cp -r .vuepress/dist/* ~/output/$${p}/ ; \ - cp ~/output/$${p}/index.html ~/output ; \ - done < versions ; +proto-image-push: + docker push $(protoImageName) -sync-docs: - cd ~/output && \ - echo "role_arn = ${DEPLOYMENT_ROLE_ARN}" >> /root/.aws/config ; \ - echo "CI job = ${CIRCLE_BUILD_URL}" >> version.html ; \ - aws s3 sync . s3://${WEBSITE_BUCKET} --profile terraform --delete ; \ - aws cloudfront create-invalidation --distribution-id ${CF_DISTRIBUTION_ID} --profile terraform --path "/*" ; -.PHONY: sync-docs +############################################################################### +### Querygen ### +############################################################################### +run-querygen: + @go run cmd/querygen/main.go ############################################################################### ### Tests & Simulation ### ############################################################################### -PACKAGES_UNIT=$(shell go list ./... | grep -E -v 'simapp|e2e') -PACKAGES_E2E=$(shell go list ./... | grep '/e2e') -PACKAGES_SIM=$(shell go list ./... | grep '/simapp') +PACKAGES_UNIT=$(shell go list ./... | grep -E -v 'tests/simulator|e2e') +PACKAGES_E2E=$(shell go list -tags e2e ./... | grep '/e2e') +PACKAGES_SIM=$(shell go list ./... | grep '/tests/simulator') TEST_PACKAGES=./... -include sims.mk - test: test-unit test-build test-all: check test-race test-cover @@ -229,14 +239,48 @@ test-race: test-cover: @VERSION=$(VERSION) go test -mod=readonly -timeout 30m -coverprofile=coverage.txt -tags='norace' -covermode=atomic $(PACKAGES_UNIT) -test-sim: +test-sim-suite: @VERSION=$(VERSION) go test -mod=readonly $(PACKAGES_SIM) -test-e2e: - @VERSION=$(VERSION) OSMOSIS_E2E_UPGRADE_VERSION="v11" go test -mod=readonly -timeout=25m -v $(PACKAGES_E2E) - -test-e2e-skip-upgrade: - @VERSION=$(VERSION) OSMOSIS_E2E_SKIP_UPGRADE=True go test -mod=readonly -timeout=25m -v $(PACKAGES_E2E) +test-sim-app: + @VERSION=$(VERSION) go test -mod=readonly -run ^TestFullAppSimulation -v $(PACKAGES_SIM) + +test-sim-determinism: + @VERSION=$(VERSION) go test -mod=readonly -run ^TestAppStateDeterminism -v $(PACKAGES_SIM) + +test-sim-bench: + @VERSION=$(VERSION) go test -benchmem -run ^BenchmarkFullAppSimulation -bench ^BenchmarkFullAppSimulation -cpuprofile cpu.out $(PACKAGES_SIM) + +# test-e2e runs a full e2e test suite +# deletes any pre-existing Osmosis containers before running. +# +# Attempts to delete Docker resources at the end. +# May fail to do so if stopped mid way. +# In that case, run `make e2e-remove-resources` +# manually. +# Utilizes Go cache. +test-e2e: e2e-setup test-e2e-ci + +# test-e2e-ci runs a full e2e test suite +# does not do any validation about the state of the Docker environment +# As a result, avoid using this locally. +test-e2e-ci: + @VERSION=$(VERSION) OSMOSIS_E2E_DEBUG_LOG=True OSMOSIS_E2E_UPGRADE_VERSION=$(E2E_UPGRADE_VERSION) go test -tags e2e -mod=readonly -timeout=25m -v $(PACKAGES_E2E) + +# test-e2e-debug runs a full e2e test suite but does +# not attempt to delete Docker resources at the end. +test-e2e-debug: e2e-setup + @VERSION=$(VERSION) OSMOSIS_E2E_DEBUG_LOG=True OSMOSIS_E2E_UPGRADE_VERSION=$(E2E_UPGRADE_VERSION) OSMOSIS_E2E_SKIP_CLEANUP=True go test -tags e2e -mod=readonly -timeout=25m -v $(PACKAGES_E2E) -count=1 + +# test-e2e-short runs the e2e test with only short tests. +# Does not delete any of the containers after running. +# Deletes any existing containers before running. +# Does not use Go cache. +test-e2e-short: e2e-setup + @VERSION=$(VERSION) OSMOSIS_E2E_DEBUG_LOG=True OSMOSIS_E2E_SKIP_UPGRADE=True OSMOSIS_E2E_SKIP_IBC=True OSMOSIS_E2E_SKIP_STATE_SYNC=True OSMOSIS_E2E_SKIP_CLEANUP=True go test -tags e2e -mod=readonly -timeout=25m -v $(PACKAGES_E2E) -count=1 + +test-mutation: + @bash scripts/mutation-test.sh $(MODULES) benchmark: @go test -mod=readonly -bench=. $(PACKAGES_UNIT) @@ -246,10 +290,25 @@ build-e2e-script: go build -mod=readonly $(BUILD_FLAGS) -o $(BUILDDIR)/ ./tests/e2e/initialization/$(E2E_SCRIPT_NAME) docker-build-debug: - @docker build -t osmosis:debug --build-arg BASE_IMG_TAG=debug -f Dockerfile . + @DOCKER_BUILDKIT=1 docker build -t osmosis:${COMMIT} --build-arg BASE_IMG_TAG=debug -f Dockerfile . + @DOCKER_BUILDKIT=1 docker tag osmosis:${COMMIT} osmosis:debug docker-build-e2e-init-chain: - @docker build -t osmosis-e2e-init-chain:debug --build-arg E2E_SCRIPT_NAME=chain -f tests/e2e/initialization/init.Dockerfile . + @DOCKER_BUILDKIT=1 docker build -t osmosis-e2e-init-chain:debug --build-arg E2E_SCRIPT_NAME=chain -f tests/e2e/initialization/init.Dockerfile . + +docker-build-e2e-init-node: + @DOCKER_BUILDKIT=1 docker build -t osmosis-e2e-init-node:debug --build-arg E2E_SCRIPT_NAME=node -f tests/e2e/initialization/init.Dockerfile . + +e2e-setup: e2e-check-image-sha e2e-remove-resources + @echo Finished e2e environment setup, ready to start the test + +e2e-check-image-sha: + tests/e2e/scripts/run/check_image_sha.sh + +e2e-remove-resources: + tests/e2e/scripts/run/remove_stale_resources.sh + +.PHONY: test-mutation ############################################################################### ### Linting ### @@ -258,39 +317,62 @@ docker-build-e2e-init-chain: lint: @echo "--> Running linter" @go run github.com/golangci/golangci-lint/cmd/golangci-lint run --timeout=10m + @docker run -v $(PWD):/workdir ghcr.io/igorshubovych/markdownlint-cli:latest "**/*.md" format: @go run github.com/golangci/golangci-lint/cmd/golangci-lint run ./... --fix @go run mvdan.cc/gofumpt -l -w x/ app/ ante/ tests/ + @docker run -v $(PWD):/workdir ghcr.io/igorshubovych/markdownlint-cli:latest "**/*.md" --fix + +mdlint: + @echo "--> Running markdown linter" + @docker run -v $(PWD):/workdir ghcr.io/igorshubovych/markdownlint-cli:latest "**/*.md" + +markdown: + @docker run -v $(PWD):/workdir ghcr.io/igorshubovych/markdownlint-cli:latest "**/*.md" --fix ############################################################################### ### Localnet ### ############################################################################### localnet-keys: - . tests/localosmosis/keys.sh + . tests/localosmosis/scripts/add_keys.sh localnet-build: - @docker build -t local:osmosis -f tests/localosmosis/Dockerfile . - -localnet-build-state-export: - @docker build -t local:osmosis-se --build-arg ID=$(ID) -f tests/localosmosis/mainnet_state/Dockerfile-stateExport . + @DOCKER_BUILDKIT=1 docker-compose -f tests/localosmosis/docker-compose.yml build localnet-start: - @docker-compose -f tests/localosmosis/docker-compose.yml up + @STATE="" docker-compose -f tests/localosmosis/docker-compose.yml up -localnet-start-state-export: - @docker-compose -f tests/localosmosis/mainnet_state/docker-compose-state-export.yml up +localnet-start-with-state: + @STATE=-s docker-compose -f tests/localosmosis/docker-compose.yml up + +localnet-startd: + @STATE="" docker-compose -f tests/localosmosis/docker-compose.yml up -d + +localnet-startd-with-state: + @STATE=-s docker-compose -f tests/localosmosis/docker-compose.yml up -d localnet-stop: - @docker-compose -f tests/localosmosis/docker-compose.yml down + @STATE="" docker-compose -f tests/localosmosis/docker-compose.yml down localnet-remove: localnet-stop - PWD=$(shell pwd) - @docker run --user root -v ${PWD}/tests/localosmosis/.osmosisd:/root/osmosis ubuntu /bin/sh -c "rm -rf /root/osmosis/*" + rm -rf $(PWD)/tests/localosmosis/.osmosisd + +localnet-build-state-export: + @DOCKER_BUILDKIT=1 docker-compose -f tests/localosmosis/state_export/docker-compose.yml build + +localnet-start-state-export: + @docker-compose -f tests/localosmosis/state_export/docker-compose.yml up + +localnet-startd-state-export: + @docker-compose -f tests/localosmosis/state_export/docker-compose.yml up -d + +localnet-stop-state-export: + @docker-compose -f tests/localosmosis/docker-compose.yml down localnet-remove-state-export: - @docker-compose -f tests/localosmosis/mainnet_state/docker-compose-state-export.yml down + rm -rf $(PWD)/tests/localosmosis/state_export/.osmosisd .PHONY: all build-linux install format lint \ go-mod-cache draw-deps clean build build-contract-tests-hooks \ diff --git a/README.md b/README.md index 8d3e40db88f..d62dea0aeb8 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ [![Project Status: Active -- The project has reached a stable, usable state and is being actively developed.](https://img.shields.io/badge/repo%20status-Active-green.svg?style=flat-square)](https://www.repostatus.org/#active) -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue?style=flat-square&logo=go)](https://godoc.org/github.com/osmosis-labs/osmosis) +[![GoDoc](https://img.shields.io/badge/godoc-reference-blue?style=flat-square&logo=go)](https://pkg.go.dev/github.com/osmosis-labs/osmosis/v11) [![Go Report -Card](https://goreportcard.com/badge/github.com/osmosis-labs/osmosis?style=flat-square)](https://goreportcard.com/report/github.com/osmosis-labs/osmosis) +Card](https://goreportcard.com/badge/github.com/osmosis-labs/osmosis?style=flat-square)](https://goreportcard.com/report/github.com/osmosis-labs/osmosis/v11) [![Version](https://img.shields.io/github/tag/osmosis-labs/osmosis.svg?style=flat-square)](https://github.com/osmosis-labs/osmosis/releases/latest) [![License: Apache-2.0](https://img.shields.io/github/license/osmosis-labs/osmosis.svg?style=flat-square)](https://github.com/osmosis-labs/osmosis/blob/main/LICENSE) @@ -78,6 +78,3 @@ running an Osmosis node! The contributing guide for Osmosis explains the branching structure, how to use the SDK fork, and how to make / test updates to SDK branches. - -For more information, please see [the contributing -guide](https://docs.osmosis.zone/developing/get_started/contributing.html). diff --git a/ante/sendblock.go b/ante/sendblock.go index c34faba4d38..9c01049423e 100644 --- a/ante/sendblock.go +++ b/ante/sendblock.go @@ -14,12 +14,14 @@ type SendBlockOptions struct { PermittedOnlySendTo map[string]string } +// NewSendBlockOptions returns options for sending new blocks. func NewSendBlockOptions(appOpts servertypes.AppOptions) SendBlockOptions { return SendBlockOptions{ PermittedOnlySendTo: parsePermittedOnlySendTo(appOpts), } } +// parsePermittedOnlySendTo parses the mapping PermittedOnlySendTo. func parsePermittedOnlySendTo(opts servertypes.AppOptions) map[string]string { valueInterface := opts.Get("permitted-only-send-to") if valueInterface == nil { @@ -32,12 +34,14 @@ type SendBlockDecorator struct { Options SendBlockOptions } +// NewSendBlockDecorator are a part of auth module AnteDecorators that are recursively chained together into a single AntiHandler. func NewSendBlockDecorator(options SendBlockOptions) *SendBlockDecorator { return &SendBlockDecorator{ Options: options, // TODO: hydrate from configuration } } +// AnteHandle is used for performing basic validity checks on a transaction such that it can be thrown out of the mempool. func (decorator *SendBlockDecorator) AnteHandle( ctx sdk.Context, tx sdk.Tx, diff --git a/app/ante.go b/app/ante.go index ba999fc802a..4769ec79aaa 100644 --- a/app/ante.go +++ b/app/ante.go @@ -11,11 +11,11 @@ import ( ante "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/cosmos-sdk/x/auth/signing" - osmoante "github.com/osmosis-labs/osmosis/v7/ante" - v9 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v9" + osmoante "github.com/osmosis-labs/osmosis/v12/ante" + v9 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v9" - txfeeskeeper "github.com/osmosis-labs/osmosis/v7/x/txfees/keeper" - txfeestypes "github.com/osmosis-labs/osmosis/v7/x/txfees/types" + txfeeskeeper "github.com/osmosis-labs/osmosis/v12/x/txfees/keeper" + txfeestypes "github.com/osmosis-labs/osmosis/v12/x/txfees/types" ) // Link to default ante handler used by cosmos sdk: diff --git a/app/app.go b/app/app.go index bdf85a0d5b8..002ed3816bf 100644 --- a/app/app.go +++ b/app/app.go @@ -29,7 +29,6 @@ import ( "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" - sdksimapp "github.com/cosmos/cosmos-sdk/simapp" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" @@ -40,19 +39,20 @@ import ( "github.com/cosmos/cosmos-sdk/x/crisis" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - "github.com/osmosis-labs/osmosis/v7/app/keepers" - appparams "github.com/osmosis-labs/osmosis/v7/app/params" - "github.com/osmosis-labs/osmosis/v7/app/upgrades" - v10 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v10" - v11 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v11" - v3 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v3" - v4 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v4" - v5 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v5" - v6 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v6" - v7 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v7" - v8 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v8" - v9 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v9" - _ "github.com/osmosis-labs/osmosis/v7/client/docs/statik" + "github.com/osmosis-labs/osmosis/v12/app/keepers" + "github.com/osmosis-labs/osmosis/v12/app/upgrades" + v10 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v10" + v11 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v11" + v12 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v12" + v3 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v3" + v4 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v4" + v5 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v5" + v6 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v6" + v7 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v7" + v8 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v8" + v9 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v9" + _ "github.com/osmosis-labs/osmosis/v12/client/docs/statik" + "github.com/osmosis-labs/osmosis/v12/simulation/simtypes" ) const appName = "OsmosisApp" @@ -87,9 +87,9 @@ var ( // EmptyWasmOpts defines a type alias for a list of wasm options. EmptyWasmOpts []wasm.Option - _ sdksimapp.App = (*OsmosisApp)(nil) + // _ sdksimapp.App = (*OsmosisApp)(nil) - Upgrades = []upgrades.Upgrade{v4.Upgrade, v5.Upgrade, v7.Upgrade, v9.Upgrade, v11.Upgrade} + Upgrades = []upgrades.Upgrade{v4.Upgrade, v5.Upgrade, v7.Upgrade, v9.Upgrade, v11.Upgrade, v12.Upgrade} Forks = []upgrades.Fork{v3.Fork, v6.Fork, v8.Fork, v10.Fork} ) @@ -128,10 +128,11 @@ type OsmosisApp struct { invCheckPeriod uint mm *module.Manager - sm *module.SimulationManager + sm *simtypes.Manager configurator module.Configurator } +// init sets DefaultNodeHome to default osmosisd install location. func init() { userHomeDir, err := os.UserHomeDir() if err != nil { @@ -150,12 +151,12 @@ func NewOsmosisApp( skipUpgradeHeights map[int64]bool, homePath string, invCheckPeriod uint, - encodingConfig appparams.EncodingConfig, appOpts servertypes.AppOptions, wasmEnabledProposals []wasm.ProposalType, wasmOpts []wasm.Option, baseAppOptions ...func(*baseapp.BaseApp), ) *OsmosisApp { + encodingConfig := MakeEncodingConfig() appCodec := encodingConfig.Marshaler cdc := encodingConfig.Amino interfaceRegistry := encodingConfig.InterfaceRegistry @@ -226,16 +227,11 @@ func NewOsmosisApp( // NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC) // Tell the app's module manager how to set the order of BeginBlockers, which are run at the beginning of every block. - app.mm.SetOrderBeginBlockers(orderBeginBlockers()...) + app.mm.SetOrderBeginBlockers(orderBeginBlockers(app.mm.ModuleNames())...) // Tell the app's module manager how to set the order of EndBlockers, which are run at the end of every block. app.mm.SetOrderEndBlockers(OrderEndBlockers(app.mm.ModuleNames())...) - // NOTE: The genutils moodule must occur after staking so that pools are - // properly initialized with tokens from genesis accounts. - // NOTE: Capability module must occur first so that it can initialize any capabilities - // so that other modules that want to create or claim capabilities afterwards in InitChain - // can do so safely. app.mm.SetOrderInitGenesis(OrderInitGenesis(app.mm.ModuleNames())...) app.mm.RegisterInvariants(app.CrisisKeeper) @@ -246,12 +242,9 @@ func NewOsmosisApp( app.setupUpgradeHandlers() // create the simulation manager and define the order of the modules for deterministic simulations - // - // NOTE: this is not required apps that don't use the simulator for fuzz testing - // transactions - app.sm = module.NewSimulationManager(simulationModules(app, encodingConfig, skipGenesisInvariants)...) + app.sm = createSimulationManager(app, encodingConfig, skipGenesisInvariants) - app.sm.RegisterStoreDecoders() + // app.sm.RegisterStoreDecoders() // add test gRPC service for testing gRPC queries in isolation testdata.RegisterQueryServer(app.GRPCQueryRouter(), testdata.QueryImpl{}) @@ -312,6 +305,10 @@ func MakeCodecs() (codec.Codec, *codec.LegacyAmino) { return config.Marshaler, config.Amino } +func (app *OsmosisApp) GetBaseApp() *baseapp.BaseApp { + return app.BaseApp +} + // Name returns the name of the App. func (app *OsmosisApp) Name() string { return app.BaseApp.Name() } @@ -365,7 +362,7 @@ func (app *OsmosisApp) InterfaceRegistry() types.InterfaceRegistry { } // SimulationManager implements the SimulationApp interface. -func (app *OsmosisApp) SimulationManager() *module.SimulationManager { +func (app *OsmosisApp) SimulationManager() *simtypes.Manager { return app.sm } diff --git a/app/apptesting/bench_test.go b/app/apptesting/bench_test.go new file mode 100644 index 00000000000..5a731014810 --- /dev/null +++ b/app/apptesting/bench_test.go @@ -0,0 +1,10 @@ +package apptesting + +import "testing" + +func BenchmarkSetup(b *testing.B) { + for i := 0; i < b.N; i++ { + s := new(KeeperTestHelper) + s.Setup() + } +} diff --git a/app/apptesting/events.go b/app/apptesting/events.go new file mode 100644 index 00000000000..7d0a4d4dfdd --- /dev/null +++ b/app/apptesting/events.go @@ -0,0 +1,33 @@ +package apptesting + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "golang.org/x/exp/slices" +) + +// AssertEventEmitted asserts that ctx's event manager has emitted the given number of events +// of the given type. +func (s *KeeperTestHelper) AssertEventEmitted(ctx sdk.Context, eventTypeExpected string, numEventsExpected int) { + allEvents := ctx.EventManager().Events() + // filter out other events + actualEvents := make([]sdk.Event, 0) + for _, event := range allEvents { + if event.Type == eventTypeExpected { + actualEvents = append(actualEvents, event) + } + } + s.Equal(numEventsExpected, len(actualEvents)) +} + +func (s *KeeperTestHelper) FindEvent(events []sdk.Event, name string) sdk.Event { + index := slices.IndexFunc(events, func(e sdk.Event) bool { return e.Type == name }) + return events[index] +} + +func (s *KeeperTestHelper) ExtractAttributes(event sdk.Event) map[string]string { + attrs := make(map[string]string) + for _, a := range event.Attributes { + attrs[string(a.Key)] = string(a.Value) + } + return attrs +} diff --git a/app/apptesting/gamm.go b/app/apptesting/gamm.go index d431e70399d..37f683f5539 100644 --- a/app/apptesting/gamm.go +++ b/app/apptesting/gamm.go @@ -3,8 +3,8 @@ package apptesting import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/osmosis-labs/osmosis/v7/x/gamm/pool-models/balancer" - gammtypes "github.com/osmosis-labs/osmosis/v7/x/gamm/types" + "github.com/osmosis-labs/osmosis/v12/x/gamm/pool-models/balancer" + gammtypes "github.com/osmosis-labs/osmosis/v12/x/gamm/types" ) var DefaultAcctFunds sdk.Coins = sdk.NewCoins( @@ -14,46 +14,58 @@ var DefaultAcctFunds sdk.Coins = sdk.NewCoins( sdk.NewCoin("baz", sdk.NewInt(10000000)), ) -// Returns a Univ2 pool with the initial liquidity being the provided balances -func (suite *KeeperTestHelper) PrepareUni2PoolWithAssets(asset1, asset2 sdk.Coin) uint64 { - return suite.PrepareBalancerPoolWithPoolAsset( - []balancer.PoolAsset{ - { - Weight: sdk.NewInt(1), - Token: asset1, - }, - { - Weight: sdk.NewInt(1), - Token: asset2, - }, - }, - ) +// PrepareBalancerPoolWithCoins returns a balancer pool +// consisted of given coins with equal weight. +func (s *KeeperTestHelper) PrepareBalancerPoolWithCoins(coins ...sdk.Coin) uint64 { + weights := make([]int64, len(coins)) + for i := 0; i < len(coins); i++ { + weights[i] = 1 + } + return s.PrepareBalancerPoolWithCoinsAndWeights(coins, weights) +} + +// PrepareBalancerPoolWithCoins returns a balancer pool +// PrepareBalancerPoolWithCoinsAndWeights returns a balancer pool +// consisted of given coins with the specified weights. +func (s *KeeperTestHelper) PrepareBalancerPoolWithCoinsAndWeights(coins sdk.Coins, weights []int64) uint64 { + var poolAssets []balancer.PoolAsset + for i, coin := range coins { + poolAsset := balancer.PoolAsset{ + Weight: sdk.NewInt(weights[i]), + Token: coin, + } + poolAssets = append(poolAssets, poolAsset) + } + + return s.PrepareBalancerPoolWithPoolAsset(poolAssets) } -func (suite *KeeperTestHelper) PrepareBalancerPool() uint64 { - poolId := suite.PrepareBalancerPoolWithPoolParams(balancer.PoolParams{ +// PrepareBalancerPool returns a Balancer pool's pool-ID with pool params set in PrepareBalancerPoolWithPoolParams. +func (s *KeeperTestHelper) PrepareBalancerPool() uint64 { + poolId := s.PrepareBalancerPoolWithPoolParams(balancer.PoolParams{ SwapFee: sdk.NewDec(0), ExitFee: sdk.NewDec(0), }) - spotPrice, err := suite.App.GAMMKeeper.CalculateSpotPrice(suite.Ctx, poolId, "foo", "bar") - suite.NoError(err) - suite.Equal(sdk.NewDec(2).String(), spotPrice.String()) - spotPrice, err = suite.App.GAMMKeeper.CalculateSpotPrice(suite.Ctx, poolId, "bar", "baz") - suite.NoError(err) - suite.Equal(sdk.NewDecWithPrec(15, 1).String(), spotPrice.String()) - spotPrice, err = suite.App.GAMMKeeper.CalculateSpotPrice(suite.Ctx, poolId, "baz", "foo") - suite.NoError(err) - s := sdk.NewDec(1).Quo(sdk.NewDec(3)) - sp := s.MulInt(gammtypes.SigFigs).RoundInt().ToDec().QuoInt(gammtypes.SigFigs) - suite.Equal(sp.String(), spotPrice.String()) + spotPrice, err := s.App.GAMMKeeper.CalculateSpotPrice(s.Ctx, poolId, "foo", "bar") + s.NoError(err) + s.Equal(sdk.NewDec(2).String(), spotPrice.String()) + spotPrice, err = s.App.GAMMKeeper.CalculateSpotPrice(s.Ctx, poolId, "bar", "baz") + s.NoError(err) + s.Equal(sdk.NewDecWithPrec(15, 1).String(), spotPrice.String()) + spotPrice, err = s.App.GAMMKeeper.CalculateSpotPrice(s.Ctx, poolId, "baz", "foo") + s.NoError(err) + oneThird := sdk.NewDec(1).Quo(sdk.NewDec(3)) + sp := oneThird.MulInt(gammtypes.SpotPriceSigFigs).RoundInt().ToDec().QuoInt(gammtypes.SpotPriceSigFigs) + s.Equal(sp.String(), spotPrice.String()) return poolId } -func (suite *KeeperTestHelper) PrepareBalancerPoolWithPoolParams(poolParams balancer.PoolParams) uint64 { +// PrepareBalancerPoolWithPoolParams sets up a Balancer pool with poolParams. +func (s *KeeperTestHelper) PrepareBalancerPoolWithPoolParams(poolParams balancer.PoolParams) uint64 { // Mint some assets to the account. - suite.FundAcc(suite.TestAccs[0], DefaultAcctFunds) + s.FundAcc(s.TestAccs[0], DefaultAcctFunds) poolAssets := []balancer.PoolAsset{ { @@ -68,28 +80,80 @@ func (suite *KeeperTestHelper) PrepareBalancerPoolWithPoolParams(poolParams bala Weight: sdk.NewInt(300), Token: sdk.NewCoin("baz", sdk.NewInt(5000000)), }, + { + Weight: sdk.NewInt(400), + Token: sdk.NewCoin("uosmo", sdk.NewInt(5000000)), + }, } - msg := balancer.NewMsgCreateBalancerPool(suite.TestAccs[0], poolParams, poolAssets, "") - poolId, err := suite.App.GAMMKeeper.CreatePool(suite.Ctx, msg) - suite.NoError(err) + msg := balancer.NewMsgCreateBalancerPool(s.TestAccs[0], poolParams, poolAssets, "") + poolId, err := s.App.GAMMKeeper.CreatePool(s.Ctx, msg) + s.NoError(err) return poolId } -func (suite *KeeperTestHelper) PrepareBalancerPoolWithPoolAsset(assets []balancer.PoolAsset) uint64 { - suite.Require().Len(assets, 2) - +// PrepareBalancerPoolWithPoolAsset sets up a Balancer pool with an array of assets. +func (s *KeeperTestHelper) PrepareBalancerPoolWithPoolAsset(assets []balancer.PoolAsset) uint64 { // Add coins for pool creation fee + coins needed to mint balances fundCoins := sdk.Coins{sdk.NewCoin("uosmo", sdk.NewInt(10000000000))} for _, a := range assets { fundCoins = fundCoins.Add(a.Token) } - suite.FundAcc(suite.TestAccs[0], fundCoins) + s.FundAcc(s.TestAccs[0], fundCoins) - msg := balancer.NewMsgCreateBalancerPool(suite.TestAccs[0], balancer.PoolParams{ + msg := balancer.NewMsgCreateBalancerPool(s.TestAccs[0], balancer.PoolParams{ SwapFee: sdk.ZeroDec(), ExitFee: sdk.ZeroDec(), }, assets, "") - poolId, err := suite.App.GAMMKeeper.CreatePool(suite.Ctx, msg) - suite.NoError(err) + poolId, err := s.App.GAMMKeeper.CreatePool(s.Ctx, msg) + s.NoError(err) return poolId } + +func (s *KeeperTestHelper) RunBasicSwap(poolId uint64) { + denoms, err := s.App.GAMMKeeper.GetPoolDenoms(s.Ctx, poolId) + s.Require().NoError(err) + + swapIn := sdk.NewCoins(sdk.NewCoin(denoms[0], sdk.NewInt(1000))) + s.FundAcc(s.TestAccs[0], swapIn) + + msg := gammtypes.MsgSwapExactAmountIn{ + Sender: string(s.TestAccs[0]), + Routes: []gammtypes.SwapAmountInRoute{{PoolId: poolId, TokenOutDenom: denoms[1]}}, + TokenIn: swapIn[0], + TokenOutMinAmount: sdk.ZeroInt(), + } + // TODO: switch to message + _, err = s.App.GAMMKeeper.SwapExactAmountIn(s.Ctx, s.TestAccs[0], poolId, msg.TokenIn, denoms[1], msg.TokenOutMinAmount) + s.Require().NoError(err) +} + +func (s *KeeperTestHelper) RunBasicExit(poolId uint64) { + shareInAmount := sdk.NewInt(100) + tokenOutMins := sdk.NewCoins() + _, err := s.App.GAMMKeeper.ExitPool(s.Ctx, s.TestAccs[0], poolId, shareInAmount, tokenOutMins) + s.Require().NoError(err) +} + +func (s *KeeperTestHelper) RunBasicJoin(poolId uint64) { + pool, _ := s.App.GAMMKeeper.GetPoolAndPoke(s.Ctx, poolId) + denoms, err := s.App.GAMMKeeper.GetPoolDenoms(s.Ctx, poolId) + s.Require().NoError(err) + + tokenIn := sdk.NewCoins() + for _, denom := range denoms { + tokenIn = tokenIn.Add(sdk.NewCoin(denom, sdk.NewInt(10000000))) + } + + s.FundAcc(s.TestAccs[0], sdk.NewCoins(tokenIn...)) + + totalPoolShare := pool.GetTotalShares() + msg := gammtypes.MsgJoinPool{ + Sender: string(s.TestAccs[0]), + PoolId: poolId, + ShareOutAmount: totalPoolShare.Quo(sdk.NewInt(100000)), + TokenInMaxs: tokenIn, + } + // TODO: switch to message + _, _, err = s.App.GAMMKeeper.JoinPoolNoSwap(s.Ctx, s.TestAccs[0], poolId, msg.ShareOutAmount, msg.TokenInMaxs) + s.Require().NoError(err) +} diff --git a/app/apptesting/osmoassert/assertions.go b/app/apptesting/osmoassert/assertions.go new file mode 100644 index 00000000000..aad23e9915b --- /dev/null +++ b/app/apptesting/osmoassert/assertions.go @@ -0,0 +1,60 @@ +package osmoassert + +import ( + "fmt" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" +) + +// ConditionalPanic checks if expectPanic is true, asserts that sut (system under test) +// panics. If expectPanic is false, asserts that sut does not panic. +// returns true if sut panics and false it it does not +func ConditionalPanic(t *testing.T, expectPanic bool, sut func()) { + if expectPanic { + require.Panics(t, sut) + return + } + require.NotPanics(t, sut) +} + +// ConditionalError checks if expectError is true, asserts that err is an error +// If expectError is false, asserts that err is nil +func ConditionalError(t *testing.T, expectError bool, err error) { + if expectError { + require.Error(t, err) + return + } + require.NoError(t, err) +} + +// DecApproxEq is a helper function to compare two decimals. +// It validates the two decimal are within a certain tolerance. +// If not, it fails with a message. +func DecApproxEq(t *testing.T, d1 sdk.Dec, d2 sdk.Dec, tol sdk.Dec, msgAndArgs ...interface{}) { + diff := d1.Sub(d2).Abs() + msg := messageFromMsgAndArgs(msgAndArgs...) + require.True(t, diff.LTE(tol), "expected |d1 - d2| <:\t%s\ngot |d1 - d2| = \t\t%s\nd1: %s, d2: %s\n%s", tol, diff, d1, d2, msg) +} + +func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { + if len(msgAndArgs) == 0 || msgAndArgs == nil { + return "" + } + if len(msgAndArgs) == 1 { + msg := msgAndArgs[0] + if msgAsStr, ok := msg.(string); ok { + return msgAsStr + } + return fmt.Sprintf("%+v", msg) + } + if len(msgAndArgs) > 1 { + msgFormat, ok := msgAndArgs[0].(string) + if !ok { + return "error formatting additional arguments for DecApproxEq, please disregard." + } + return fmt.Sprintf(msgFormat, msgAndArgs[1:]...) + } + return "" +} diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index 8ed0543459d..71446fecf82 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -1,30 +1,40 @@ package apptesting import ( + "encoding/json" "fmt" + "testing" "time" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/store/rootmulti" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/tx/signing" authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + "github.com/cosmos/cosmos-sdk/x/authz" + authzcodec "github.com/cosmos/cosmos-sdk/x/authz/codec" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" - "github.com/cosmos/cosmos-sdk/x/staking/teststaking" + "github.com/cosmos/cosmos-sdk/x/staking" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/ed25519" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - - "github.com/osmosis-labs/osmosis/v7/app" - "github.com/osmosis-labs/osmosis/v7/x/gamm/pool-models/balancer" - gammtypes "github.com/osmosis-labs/osmosis/v7/x/gamm/types" - lockupkeeper "github.com/osmosis-labs/osmosis/v7/x/lockup/keeper" - lockuptypes "github.com/osmosis-labs/osmosis/v7/x/lockup/types" + "github.com/tendermint/tendermint/libs/log" + tmtypes "github.com/tendermint/tendermint/proto/tendermint/types" + dbm "github.com/tendermint/tm-db" + + "github.com/osmosis-labs/osmosis/v12/app" + "github.com/osmosis-labs/osmosis/v12/x/gamm/pool-models/balancer" + gammtypes "github.com/osmosis-labs/osmosis/v12/x/gamm/types" + lockupkeeper "github.com/osmosis-labs/osmosis/v12/x/lockup/keeper" + lockuptypes "github.com/osmosis-labs/osmosis/v12/x/lockup/types" + minttypes "github.com/osmosis-labs/osmosis/v12/x/mint/types" ) type KeeperTestHelper struct { @@ -36,22 +46,87 @@ type KeeperTestHelper struct { TestAccs []sdk.AccAddress } +var ( + SecondaryDenom = "uion" + SecondaryAmount = sdk.NewInt(100000000) +) + +// Setup sets up basic environment for suite (App, Ctx, and test accounts) func (s *KeeperTestHelper) Setup() { s.App = app.Setup(false) - s.Ctx = s.App.BaseApp.NewContext(false, tmproto.Header{Height: 1, ChainID: "osmosis-1", Time: time.Now().UTC()}) + s.Ctx = s.App.BaseApp.NewContext(false, tmtypes.Header{Height: 1, ChainID: "osmosis-1", Time: time.Now().UTC()}) s.QueryHelper = &baseapp.QueryServiceTestHelper{ GRPCQueryRouter: s.App.GRPCQueryRouter(), Ctx: s.Ctx, } + s.SetEpochStartTime() s.TestAccs = CreateRandomAccounts(3) } +func (s *KeeperTestHelper) SetupTestForInitGenesis() { + // Setting to True, leads to init genesis not running + s.App = app.Setup(true) + s.Ctx = s.App.BaseApp.NewContext(true, tmtypes.Header{}) +} + +func (s *KeeperTestHelper) SetEpochStartTime() { + epochsKeeper := s.App.EpochsKeeper + + for _, epoch := range epochsKeeper.AllEpochInfos(s.Ctx) { + epoch.StartTime = s.Ctx.BlockTime() + epochsKeeper.DeleteEpochInfo(s.Ctx, epoch.Identifier) + err := epochsKeeper.AddEpochInfo(s.Ctx, epoch) + if err != nil { + panic(err) + } + } +} + +// CreateTestContext creates a test context. +func (s *KeeperTestHelper) CreateTestContext() sdk.Context { + ctx, _ := s.CreateTestContextWithMultiStore() + return ctx +} + +// CreateTestContextWithMultiStore creates a test context and returns it together with multi store. +func (s *KeeperTestHelper) CreateTestContextWithMultiStore() (sdk.Context, sdk.CommitMultiStore) { + db := dbm.NewMemDB() + logger := log.NewNopLogger() + + ms := rootmulti.NewStore(db, logger) + + return sdk.NewContext(ms, tmtypes.Header{}, false, logger), ms +} + +// CreateTestContext creates a test context. +func (s *KeeperTestHelper) Commit() { + oldHeight := s.Ctx.BlockHeight() + oldHeader := s.Ctx.BlockHeader() + s.App.Commit() + newHeader := tmtypes.Header{Height: oldHeight + 1, ChainID: oldHeader.ChainID, Time: oldHeader.Time.Add(time.Second)} + s.App.BeginBlock(abci.RequestBeginBlock{Header: newHeader}) + s.Ctx = s.App.GetBaseApp().NewContext(false, newHeader) +} + +// FundAcc funds target address with specified amount. func (s *KeeperTestHelper) FundAcc(acc sdk.AccAddress, amounts sdk.Coins) { err := simapp.FundAccount(s.App.BankKeeper, s.Ctx, acc, amounts) s.Require().NoError(err) } +// FundModuleAcc funds target modules with specified amount. +func (s *KeeperTestHelper) FundModuleAcc(moduleName string, amounts sdk.Coins) { + err := simapp.FundModuleAccount(s.App.BankKeeper, s.Ctx, moduleName, amounts) + s.Require().NoError(err) +} + +func (s *KeeperTestHelper) MintCoins(coins sdk.Coins) { + err := s.App.BankKeeper.MintCoins(s.Ctx, minttypes.ModuleName, coins) + s.Require().NoError(err) +} + +// SetupValidator sets up a validator and returns the ValAddress. func (s *KeeperTestHelper) SetupValidator(bondStatus stakingtypes.BondStatus) sdk.ValAddress { valPub := secp256k1.GenPrivKey().PubKey() valAddr := sdk.ValAddress(valPub.Address()) @@ -60,9 +135,14 @@ func (s *KeeperTestHelper) SetupValidator(bondStatus stakingtypes.BondStatus) sd s.FundAcc(sdk.AccAddress(valAddr), selfBond) - sh := teststaking.NewHelper(s.Suite.T(), s.Ctx, *s.App.StakingKeeper) - msg := sh.CreateValidatorMsg(valAddr, valPub, selfBond[0].Amount) - sh.Handle(msg, true) + stakingHandler := staking.NewHandler(*s.App.StakingKeeper) + stakingCoin := sdk.NewCoin(sdk.DefaultBondDenom, selfBond[0].Amount) + ZeroCommission := stakingtypes.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()) + msg, err := stakingtypes.NewMsgCreateValidator(valAddr, valPub, stakingCoin, stakingtypes.Description{}, ZeroCommission, sdk.OneInt()) + s.Require().NoError(err) + res, err := stakingHandler(s.Ctx, msg) + s.Require().NoError(err) + s.Require().NotNil(res) val, found := s.App.StakingKeeper.GetValidator(s.Ctx, valAddr) s.Require().True(found) @@ -86,10 +166,7 @@ func (s *KeeperTestHelper) SetupValidator(bondStatus stakingtypes.BondStatus) sd return valAddr } -func (s *KeeperTestHelper) SetupTokenFactory() { - s.App.TokenFactoryKeeper.CreateModuleAccount(s.Ctx) -} - +// BeginNewBlock starts a new block. func (s *KeeperTestHelper) BeginNewBlock(executeNextEpoch bool) { var valAddr []byte @@ -108,6 +185,7 @@ func (s *KeeperTestHelper) BeginNewBlock(executeNextEpoch bool) { s.BeginNewBlockWithProposer(executeNextEpoch, valAddr) } +// BeginNewBlockWithProposer begins a new block with a proposer. func (s *KeeperTestHelper) BeginNewBlockWithProposer(executeNextEpoch bool, proposer sdk.ValAddress) { validator, found := s.App.StakingKeeper.GetValidator(s.Ctx, proposer) s.Assert().True(found) @@ -121,11 +199,10 @@ func (s *KeeperTestHelper) BeginNewBlockWithProposer(executeNextEpoch bool, prop epoch := s.App.EpochsKeeper.GetEpochInfo(s.Ctx, epochIdentifier) newBlockTime := s.Ctx.BlockTime().Add(5 * time.Second) if executeNextEpoch { - endEpochTime := epoch.CurrentEpochStartTime.Add(epoch.Duration) - newBlockTime = endEpochTime.Add(time.Second) + newBlockTime = s.Ctx.BlockTime().Add(epoch.Duration).Add(time.Second) } - header := tmproto.Header{Height: s.Ctx.BlockHeight() + 1, Time: newBlockTime} + header := tmtypes.Header{Height: s.Ctx.BlockHeight() + 1, Time: newBlockTime} newCtx := s.Ctx.WithBlockTime(newBlockTime).WithBlockHeight(s.Ctx.BlockHeight() + 1) s.Ctx = newCtx lastCommitInfo := abci.LastCommitInfo{ @@ -138,13 +215,16 @@ func (s *KeeperTestHelper) BeginNewBlockWithProposer(executeNextEpoch bool, prop fmt.Println("beginning block ", s.Ctx.BlockHeight()) s.App.BeginBlocker(s.Ctx, reqBeginBlock) + s.Ctx = s.App.NewContext(false, reqBeginBlock.Header) } +// EndBlock ends the block, and runs commit func (s *KeeperTestHelper) EndBlock() { reqEndBlock := abci.RequestEndBlock{Height: s.Ctx.BlockHeight()} s.App.EndBlocker(s.Ctx, reqEndBlock) } +// AllocateRewardsToValidator allocates reward tokens to a distribution module then allocates rewards to the validator address. func (s *KeeperTestHelper) AllocateRewardsToValidator(valAddr sdk.ValAddress, rewardAmt sdk.Int) { validator, found := s.App.StakingKeeper.GetValidator(s.Ctx, valAddr) s.Require().True(found) @@ -162,16 +242,11 @@ func (s *KeeperTestHelper) AllocateRewardsToValidator(valAddr sdk.ValAddress, re // SetupGammPoolsWithBondDenomMultiplier uses given multipliers to set initial pool supply of bond denom. func (s *KeeperTestHelper) SetupGammPoolsWithBondDenomMultiplier(multipliers []sdk.Dec) []gammtypes.PoolI { - s.App.GAMMKeeper.SetParams(s.Ctx, gammtypes.Params{ - PoolCreationFee: sdk.Coins{}, - }) - bondDenom := s.App.StakingKeeper.BondDenom(s.Ctx) // TODO: use sdk crypto instead of tendermint to generate address acc1 := sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address().Bytes()) - poolCreationFee := s.App.GAMMKeeper.GetParams(s.Ctx) - s.FundAcc(acc1, poolCreationFee.PoolCreationFee) + params := s.App.GAMMKeeper.GetParams(s.Ctx) pools := []gammtypes.PoolI{} for index, multiplier := range multipliers { @@ -181,22 +256,22 @@ func (s *KeeperTestHelper) SetupGammPoolsWithBondDenomMultiplier(multipliers []s s.FundAcc(acc1, sdk.NewCoins( sdk.NewCoin(bondDenom, uosmoAmount.Mul(sdk.NewInt(10))), sdk.NewInt64Coin(token, 100000), - )) + ).Add(params.PoolCreationFee...)) var ( defaultFutureGovernor = "" // pool assets - defaultFooAsset balancer.PoolAsset = balancer.PoolAsset{ + defaultFooAsset = balancer.PoolAsset{ Weight: sdk.NewInt(100), Token: sdk.NewCoin(bondDenom, uosmoAmount), } - defaultBarAsset balancer.PoolAsset = balancer.PoolAsset{ + defaultBarAsset = balancer.PoolAsset{ Weight: sdk.NewInt(100), Token: sdk.NewCoin(token, sdk.NewInt(10000)), } - poolAssets []balancer.PoolAsset = []balancer.PoolAsset{defaultFooAsset, defaultBarAsset} + poolAssets = []balancer.PoolAsset{defaultFooAsset, defaultBarAsset} ) poolParams := balancer.PoolParams{ @@ -243,6 +318,7 @@ func (s *KeeperTestHelper) SwapAndSetSpotPrice(poolId uint64, fromAsset sdk.Coin return spotPrice } +// LockTokens funds an account, locks tokens and returns a lockID. func (s *KeeperTestHelper) LockTokens(addr sdk.AccAddress, coins sdk.Coins, duration time.Duration) (lockID uint64) { msgServer := lockupkeeper.NewMsgServerImpl(s.App.LockupKeeper) s.FundAcc(addr, coins) @@ -253,6 +329,7 @@ func (s *KeeperTestHelper) LockTokens(addr sdk.AccAddress, coins sdk.Coins, dura return msgResponse.ID } +// BuildTx builds a transaction. func (s *KeeperTestHelper) BuildTx( txBuilder client.TxBuilder, msgs []sdk.Msg, @@ -283,3 +360,49 @@ func CreateRandomAccounts(numAccts int) []sdk.AccAddress { return testAddrs } + +func TestMessageAuthzSerialization(t *testing.T, msg sdk.Msg) { + someDate := time.Date(1, 1, 1, 1, 1, 1, 1, time.UTC) + const ( + mockGranter string = "cosmos1abc" + mockGrantee string = "cosmos1xyz" + ) + + var ( + mockMsgGrant authz.MsgGrant + mockMsgRevoke authz.MsgRevoke + mockMsgExec authz.MsgExec + ) + + // Authz: Grant Msg + typeURL := sdk.MsgTypeURL(msg) + grant, err := authz.NewGrant(someDate, authz.NewGenericAuthorization(typeURL), someDate.Add(time.Hour)) + require.NoError(t, err) + + msgGrant := authz.MsgGrant{Granter: mockGranter, Grantee: mockGrantee, Grant: grant} + msgGrantBytes := json.RawMessage(sdk.MustSortJSON(authzcodec.ModuleCdc.MustMarshalJSON(&msgGrant))) + err = authzcodec.ModuleCdc.UnmarshalJSON(msgGrantBytes, &mockMsgGrant) + require.NoError(t, err) + + // Authz: Revoke Msg + msgRevoke := authz.MsgRevoke{Granter: mockGranter, Grantee: mockGrantee, MsgTypeUrl: typeURL} + msgRevokeByte := json.RawMessage(sdk.MustSortJSON(authzcodec.ModuleCdc.MustMarshalJSON(&msgRevoke))) + err = authzcodec.ModuleCdc.UnmarshalJSON(msgRevokeByte, &mockMsgRevoke) + require.NoError(t, err) + + // Authz: Exec Msg + msgAny, err := cdctypes.NewAnyWithValue(msg) + require.NoError(t, err) + msgExec := authz.MsgExec{Grantee: mockGrantee, Msgs: []*cdctypes.Any{msgAny}} + execMsgByte := json.RawMessage(sdk.MustSortJSON(authzcodec.ModuleCdc.MustMarshalJSON(&msgExec))) + err = authzcodec.ModuleCdc.UnmarshalJSON(execMsgByte, &mockMsgExec) + require.NoError(t, err) + require.Equal(t, msgExec.Msgs[0].Value, mockMsgExec.Msgs[0].Value) +} + +func GenerateTestAddrs() (string, string) { + pk1 := ed25519.GenPrivKey().PubKey() + validAddr := sdk.AccAddress(pk1.Address()).String() + invalidAddr := sdk.AccAddress("invalid").String() + return validAddr, invalidAddr +} diff --git a/app/config.go b/app/config.go index 72e8975ef0d..6d271c9b836 100644 --- a/app/config.go +++ b/app/config.go @@ -4,7 +4,6 @@ import ( "fmt" "time" - "github.com/osmosis-labs/osmosis/v7/app/params" dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/baseapp" @@ -30,7 +29,7 @@ func DefaultConfig() network.Config { LegacyAmino: encCfg.Amino, InterfaceRegistry: encCfg.InterfaceRegistry, AccountRetriever: authtypes.AccountRetriever{}, - AppConstructor: NewAppConstructor(encCfg), + AppConstructor: NewAppConstructor(), GenesisState: ModuleBasics.DefaultGenesis(encCfg.Marshaler), TimeoutCommit: 1 * time.Second / 2, ChainID: "osmosis-code-test", @@ -47,11 +46,11 @@ func DefaultConfig() network.Config { } } -func NewAppConstructor(encodingCfg params.EncodingConfig) network.AppConstructor { +// NewAppConstructor returns a new Osmosis app given encoding type configs. +func NewAppConstructor() network.AppConstructor { return func(val network.Validator) servertypes.Application { return NewOsmosisApp( val.Ctx.Logger, dbm.NewMemDB(), nil, true, make(map[int64]bool), val.Ctx.Config.RootDir, 0, - encodingCfg, simapp.EmptyAppOptions{}, GetWasmEnabledProposals(), EmptyWasmOpts, diff --git a/app/encoding.go b/app/encoding.go index 809483a93d4..dafe7e3e200 100644 --- a/app/encoding.go +++ b/app/encoding.go @@ -1,12 +1,12 @@ package app import ( - "github.com/osmosis-labs/osmosis/v7/app/params" + "github.com/osmosis-labs/osmosis/v12/app/params" "github.com/cosmos/cosmos-sdk/std" ) -// MakeEncodingConfig creates an EncodingConfig for testing. +// MakeEncodingConfig creates an EncodingConfig. func MakeEncodingConfig() params.EncodingConfig { encodingConfig := params.MakeEncodingConfig() std.RegisterLegacyAminoCodec(encodingConfig.Amino) diff --git a/app/export.go b/app/export.go index 183f2efb856..ed37266f304 100644 --- a/app/export.go +++ b/app/export.go @@ -46,7 +46,8 @@ func (app *OsmosisApp) ExportAppStateAndValidators( // prepare for fresh start at zero height // NOTE zero height genesis is a temporary feature which will be deprecated -// in favour of export at a block height +// +// in favour of export at a block height func (app *OsmosisApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) { applyAllowedAddrs := false diff --git a/app/forks.go b/app/forks.go index d8268170f0a..e3ca6b4b842 100644 --- a/app/forks.go +++ b/app/forks.go @@ -4,7 +4,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// BeginBlockForks is intended to be ran in. +// BeginBlockForks is intended to be ran in a chain upgrade. func BeginBlockForks(ctx sdk.Context, app *OsmosisApp) { for _, fork := range Forks { if ctx.BlockHeight() == fork.UpgradeHeight { diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index f563ae5ec6c..c359895e914 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -36,6 +36,9 @@ import ( icahost "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host" icahostkeeper "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host/keeper" icahosttypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host/types" + "github.com/cosmos/ibc-go/v3/modules/apps/icq" + icqkeeper "github.com/cosmos/ibc-go/v3/modules/apps/icq/keeper" + icqtypes "github.com/cosmos/ibc-go/v3/modules/apps/icq/types" ibctransferkeeper "github.com/cosmos/ibc-go/v3/modules/apps/transfer/keeper" ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" ibcclient "github.com/cosmos/ibc-go/v3/modules/core/02-client" @@ -46,34 +49,32 @@ import ( // IBC Transfer: Defines the "transfer" IBC port transfer "github.com/cosmos/ibc-go/v3/modules/apps/transfer" - "github.com/osmosis-labs/bech32-ibc/x/bech32ibc" - bech32ibckeeper "github.com/osmosis-labs/bech32-ibc/x/bech32ibc/keeper" - bech32ibctypes "github.com/osmosis-labs/bech32-ibc/x/bech32ibc/types" - bech32ics20keeper "github.com/osmosis-labs/bech32-ibc/x/bech32ics20/keeper" - - _ "github.com/osmosis-labs/osmosis/v7/client/docs/statik" - owasm "github.com/osmosis-labs/osmosis/v7/wasmbinding" - epochskeeper "github.com/osmosis-labs/osmosis/v7/x/epochs/keeper" - epochstypes "github.com/osmosis-labs/osmosis/v7/x/epochs/types" - gammkeeper "github.com/osmosis-labs/osmosis/v7/x/gamm/keeper" - gammtypes "github.com/osmosis-labs/osmosis/v7/x/gamm/types" - incentiveskeeper "github.com/osmosis-labs/osmosis/v7/x/incentives/keeper" - incentivestypes "github.com/osmosis-labs/osmosis/v7/x/incentives/types" - lockupkeeper "github.com/osmosis-labs/osmosis/v7/x/lockup/keeper" - lockuptypes "github.com/osmosis-labs/osmosis/v7/x/lockup/types" - mintkeeper "github.com/osmosis-labs/osmosis/v7/x/mint/keeper" - minttypes "github.com/osmosis-labs/osmosis/v7/x/mint/types" - poolincentives "github.com/osmosis-labs/osmosis/v7/x/pool-incentives" - poolincentiveskeeper "github.com/osmosis-labs/osmosis/v7/x/pool-incentives/keeper" - poolincentivestypes "github.com/osmosis-labs/osmosis/v7/x/pool-incentives/types" - "github.com/osmosis-labs/osmosis/v7/x/superfluid" - superfluidkeeper "github.com/osmosis-labs/osmosis/v7/x/superfluid/keeper" - superfluidtypes "github.com/osmosis-labs/osmosis/v7/x/superfluid/types" - tokenfactorykeeper "github.com/osmosis-labs/osmosis/v7/x/tokenfactory/keeper" - tokenfactorytypes "github.com/osmosis-labs/osmosis/v7/x/tokenfactory/types" - "github.com/osmosis-labs/osmosis/v7/x/txfees" - txfeeskeeper "github.com/osmosis-labs/osmosis/v7/x/txfees/keeper" - txfeestypes "github.com/osmosis-labs/osmosis/v7/x/txfees/types" + + _ "github.com/osmosis-labs/osmosis/v12/client/docs/statik" + owasm "github.com/osmosis-labs/osmosis/v12/wasmbinding" + epochskeeper "github.com/osmosis-labs/osmosis/v12/x/epochs/keeper" + epochstypes "github.com/osmosis-labs/osmosis/v12/x/epochs/types" + gammkeeper "github.com/osmosis-labs/osmosis/v12/x/gamm/keeper" + gammtypes "github.com/osmosis-labs/osmosis/v12/x/gamm/types" + incentiveskeeper "github.com/osmosis-labs/osmosis/v12/x/incentives/keeper" + incentivestypes "github.com/osmosis-labs/osmosis/v12/x/incentives/types" + lockupkeeper "github.com/osmosis-labs/osmosis/v12/x/lockup/keeper" + lockuptypes "github.com/osmosis-labs/osmosis/v12/x/lockup/types" + mintkeeper "github.com/osmosis-labs/osmosis/v12/x/mint/keeper" + minttypes "github.com/osmosis-labs/osmosis/v12/x/mint/types" + poolincentives "github.com/osmosis-labs/osmosis/v12/x/pool-incentives" + poolincentiveskeeper "github.com/osmosis-labs/osmosis/v12/x/pool-incentives/keeper" + poolincentivestypes "github.com/osmosis-labs/osmosis/v12/x/pool-incentives/types" + "github.com/osmosis-labs/osmosis/v12/x/superfluid" + superfluidkeeper "github.com/osmosis-labs/osmosis/v12/x/superfluid/keeper" + superfluidtypes "github.com/osmosis-labs/osmosis/v12/x/superfluid/types" + tokenfactorykeeper "github.com/osmosis-labs/osmosis/v12/x/tokenfactory/keeper" + tokenfactorytypes "github.com/osmosis-labs/osmosis/v12/x/tokenfactory/types" + "github.com/osmosis-labs/osmosis/v12/x/twap" + twaptypes "github.com/osmosis-labs/osmosis/v12/x/twap/types" + "github.com/osmosis-labs/osmosis/v12/x/txfees" + txfeeskeeper "github.com/osmosis-labs/osmosis/v12/x/txfees/keeper" + txfeestypes "github.com/osmosis-labs/osmosis/v12/x/txfees/types" ) type AppKeepers struct { @@ -87,6 +88,7 @@ type AppKeepers struct { // make scoped keepers public for test purposes ScopedIBCKeeper capabilitykeeper.ScopedKeeper ScopedICAHostKeeper capabilitykeeper.ScopedKeeper + ScopedICQKeeper capabilitykeeper.ScopedKeeper ScopedTransferKeeper capabilitykeeper.ScopedKeeper ScopedWasmKeeper capabilitykeeper.ScopedKeeper @@ -99,11 +101,11 @@ type AppKeepers struct { SlashingKeeper *slashingkeeper.Keeper IBCKeeper *ibckeeper.Keeper ICAHostKeeper *icahostkeeper.Keeper + ICQKeeper *icqkeeper.Keeper TransferKeeper *ibctransferkeeper.Keeper - Bech32IBCKeeper *bech32ibckeeper.Keeper - Bech32ICS20Keeper *bech32ics20keeper.Keeper EvidenceKeeper *evidencekeeper.Keeper GAMMKeeper *gammkeeper.Keeper + TwapKeeper *twap.Keeper LockupKeeper *lockupkeeper.Keeper EpochsKeeper *epochskeeper.Keeper IncentivesKeeper *incentiveskeeper.Keeper @@ -124,6 +126,7 @@ type AppKeepers struct { memKeys map[string]*sdk.MemoryStoreKey } +// InitNormalKeepers initializes all 'normal' keepers (account, app, bank, auth, staking, distribution, slashing, transfer, gamm, IBC router, pool incentives, governance, mint, txfees keepers). func (appKeepers *AppKeepers) InitNormalKeepers( appCodec codec.Codec, bApp *baseapp.BaseApp, @@ -223,30 +226,26 @@ func (appKeepers *AppKeepers) InitNormalKeepers( bApp.MsgServiceRouter(), ) appKeepers.ICAHostKeeper = &icaHostKeeper + icqKeeper := icqkeeper.NewKeeper( + appCodec, appKeepers.keys[icqtypes.StoreKey], + appKeepers.GetSubspace(icqtypes.ModuleName), + appKeepers.IBCKeeper.ChannelKeeper, + appKeepers.IBCKeeper.ChannelKeeper, + &appKeepers.IBCKeeper.PortKeeper, + appKeepers.ScopedICQKeeper, + bApp, + ) + appKeepers.ICQKeeper = &icqKeeper + icqIBCModule := icq.NewIBCModule(*appKeepers.ICQKeeper) icaHostIBCModule := icahost.NewIBCModule(*appKeepers.ICAHostKeeper) // Create static IBC router, add transfer route, then set and seal it ibcRouter := porttypes.NewRouter() ibcRouter.AddRoute(icahosttypes.SubModuleName, icaHostIBCModule). + AddRoute(icqtypes.ModuleName, icqIBCModule). AddRoute(ibctransfertypes.ModuleName, transferIBCModule) // Note: the sealing is done after creating wasmd and wiring that up - appKeepers.Bech32IBCKeeper = bech32ibckeeper.NewKeeper( - appKeepers.IBCKeeper.ChannelKeeper, appCodec, appKeepers.keys[bech32ibctypes.StoreKey], - appKeepers.TransferKeeper, - ) - - // TODO: Should we be passing this instead of bank in many places? - // Where do we want send coins to be cross-chain? - appKeepers.Bech32ICS20Keeper = bech32ics20keeper.NewKeeper( - appKeepers.IBCKeeper.ChannelKeeper, - appKeepers.BankKeeper, - appKeepers.TransferKeeper, - appKeepers.Bech32IBCKeeper, - appKeepers.TransferKeeper, - appCodec, - ) - // create evidence keeper with router // If evidence needs to be handled for the app, set routes in router here and seal appKeepers.EvidenceKeeper = evidencekeeper.NewKeeper( @@ -262,6 +261,12 @@ func (appKeepers *AppKeepers) InitNormalKeepers( appKeepers.AccountKeeper, appKeepers.BankKeeper, appKeepers.DistrKeeper) appKeepers.GAMMKeeper = &gammKeeper + appKeepers.TwapKeeper = twap.NewKeeper( + appKeepers.keys[twaptypes.StoreKey], + appKeepers.tkeys[twaptypes.TransientStoreKey], + appKeepers.GetSubspace(twaptypes.ModuleName), + appKeepers.GAMMKeeper) + appKeepers.LockupKeeper = lockupkeeper.NewKeeper( appCodec, appKeepers.keys[lockuptypes.StoreKey], @@ -272,6 +277,18 @@ func (appKeepers *AppKeepers) InitNormalKeepers( appKeepers.EpochsKeeper = epochskeeper.NewKeeper(appCodec, appKeepers.keys[epochstypes.StoreKey]) + txFeesKeeper := txfeeskeeper.NewKeeper( + appCodec, + appKeepers.AccountKeeper, + appKeepers.BankKeeper, + appKeepers.keys[txfeestypes.StoreKey], + appKeepers.GAMMKeeper, + appKeepers.GAMMKeeper, + txfeestypes.FeeCollectorName, + txfeestypes.NonNativeFeeCollectorName, + ) + appKeepers.TxFeesKeeper = &txFeesKeeper + appKeepers.IncentivesKeeper = incentiveskeeper.NewKeeper( appCodec, appKeepers.keys[incentivestypes.StoreKey], @@ -279,6 +296,8 @@ func (appKeepers *AppKeepers) InitNormalKeepers( appKeepers.BankKeeper, appKeepers.LockupKeeper, appKeepers.EpochsKeeper, + appKeepers.DistrKeeper, + appKeepers.TxFeesKeeper, ) appKeepers.SuperfluidKeeper = superfluidkeeper.NewKeeper( @@ -306,26 +325,11 @@ func (appKeepers *AppKeepers) InitNormalKeepers( appKeepers.BankKeeper, appKeepers.IncentivesKeeper, appKeepers.DistrKeeper, - distrtypes.ModuleName, - authtypes.FeeCollectorName, - ) - appKeepers.PoolIncentivesKeeper = &poolIncentivesKeeper - - txFeesKeeper := txfeeskeeper.NewKeeper( - appCodec, - appKeepers.AccountKeeper, - appKeepers.BankKeeper, - appKeepers.EpochsKeeper, - appKeepers.keys[txfeestypes.StoreKey], - appKeepers.GAMMKeeper, appKeepers.GAMMKeeper, - txfeestypes.FeeCollectorName, - txfeestypes.NonNativeFeeCollectorName, ) - appKeepers.TxFeesKeeper = &txFeesKeeper + appKeepers.PoolIncentivesKeeper = &poolIncentivesKeeper tokenFactoryKeeper := tokenfactorykeeper.NewKeeper( - appCodec, appKeepers.keys[tokenfactorytypes.StoreKey], appKeepers.GetSubspace(tokenfactorytypes.ModuleName), appKeepers.AccountKeeper, @@ -338,7 +342,8 @@ func (appKeepers *AppKeepers) InitNormalKeepers( // if we want to allow any custom callbacks supportedFeatures := "iterator,staking,stargate,osmosis" - wasmOpts = append(owasm.RegisterCustomPlugins(appKeepers.GAMMKeeper, appKeepers.BankKeeper, appKeepers.TokenFactoryKeeper), wasmOpts...) + wasmOpts = append(owasm.RegisterCustomPlugins(appKeepers.GAMMKeeper, appKeepers.BankKeeper, appKeepers.TwapKeeper, appKeepers.TokenFactoryKeeper), wasmOpts...) + wasmOpts = append(owasm.RegisterStargateQueries(*bApp.GRPCQueryRouter(), appCodec), wasmOpts...) wasmKeeper := wasm.NewKeeper( appCodec, @@ -374,7 +379,6 @@ func (appKeepers *AppKeepers) InitNormalKeepers( AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(*appKeepers.UpgradeKeeper)). AddRoute(ibchost.RouterKey, ibcclient.NewClientProposalHandler(appKeepers.IBCKeeper.ClientKeeper)). AddRoute(poolincentivestypes.RouterKey, poolincentives.NewPoolIncentivesProposalHandler(*appKeepers.PoolIncentivesKeeper)). - AddRoute(bech32ibctypes.RouterKey, bech32ibc.NewBech32IBCProposalHandler(*appKeepers.Bech32IBCKeeper)). AddRoute(txfeestypes.RouterKey, txfees.NewUpdateFeeTokenProposalHandler(*appKeepers.TxFeesKeeper)). AddRoute(superfluidtypes.RouterKey, superfluid.NewSuperfluidProposalHandler(*appKeepers.SuperfluidKeeper, *appKeepers.EpochsKeeper)) @@ -390,6 +394,7 @@ func (appKeepers *AppKeepers) InitNormalKeepers( appKeepers.GovKeeper = &govKeeper } +// InitSpecialKeepers initiates special keepers (crisis appkeeper, upgradekeeper, params keeper) func (appKeepers *AppKeepers) InitSpecialKeepers( appCodec codec.Codec, bApp *baseapp.BaseApp, @@ -410,6 +415,7 @@ func (appKeepers *AppKeepers) InitSpecialKeepers( appKeepers.CapabilityKeeper = capabilitykeeper.NewKeeper(appCodec, appKeepers.keys[capabilitytypes.StoreKey], appKeepers.memKeys[capabilitytypes.MemStoreKey]) appKeepers.ScopedIBCKeeper = appKeepers.CapabilityKeeper.ScopeToModule(ibchost.ModuleName) appKeepers.ScopedICAHostKeeper = appKeepers.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName) + appKeepers.ScopedICQKeeper = appKeepers.CapabilityKeeper.ScopeToModule(icqtypes.ModuleName) appKeepers.ScopedTransferKeeper = appKeepers.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) appKeepers.ScopedWasmKeeper = appKeepers.CapabilityKeeper.ScopeToModule(wasm.ModuleName) appKeepers.CapabilityKeeper.Seal() @@ -446,16 +452,19 @@ func (appKeepers *AppKeepers) initParamsKeeper(appCodec codec.BinaryCodec, legac paramsKeeper.Subspace(ibctransfertypes.ModuleName) paramsKeeper.Subspace(ibchost.ModuleName) paramsKeeper.Subspace(icahosttypes.SubModuleName) + paramsKeeper.Subspace(icqtypes.ModuleName) paramsKeeper.Subspace(incentivestypes.ModuleName) paramsKeeper.Subspace(poolincentivestypes.ModuleName) paramsKeeper.Subspace(superfluidtypes.ModuleName) paramsKeeper.Subspace(gammtypes.ModuleName) paramsKeeper.Subspace(wasm.ModuleName) paramsKeeper.Subspace(tokenfactorytypes.ModuleName) + paramsKeeper.Subspace(twaptypes.ModuleName) return paramsKeeper } +// SetupHooks sets up hooks for modules. func (appKeepers *AppKeepers) SetupHooks() { // For every module that has hooks set on it, // you must check InitNormalKeepers to ensure that its not passed by de-reference @@ -474,6 +483,7 @@ func (appKeepers *AppKeepers) SetupHooks() { gammtypes.NewMultiGammHooks( // insert gamm hooks receivers here appKeepers.PoolIncentivesKeeper.Hooks(), + appKeepers.TwapKeeper.GammHooks(), ), ) @@ -501,6 +511,7 @@ func (appKeepers *AppKeepers) SetupHooks() { epochstypes.NewMultiEpochHooks( // insert epoch hooks receivers here appKeepers.TxFeesKeeper.Hooks(), + appKeepers.TwapKeeper.EpochHooks(), appKeepers.SuperfluidKeeper.Hooks(), appKeepers.IncentivesKeeper.Hooks(), appKeepers.MintKeeper.Hooks(), @@ -527,11 +538,13 @@ func KVStoreKeys() []string { paramstypes.StoreKey, ibchost.StoreKey, icahosttypes.StoreKey, + icqtypes.StoreKey, upgradetypes.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, gammtypes.StoreKey, + twaptypes.StoreKey, lockuptypes.StoreKey, incentivestypes.StoreKey, epochstypes.StoreKey, @@ -539,7 +552,6 @@ func KVStoreKeys() []string { authzkeeper.StoreKey, txfeestypes.StoreKey, superfluidtypes.StoreKey, - bech32ibctypes.StoreKey, wasm.StoreKey, tokenfactorytypes.StoreKey, } diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 556a0314280..0dd748966ec 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -4,33 +4,40 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + + twaptypes "github.com/osmosis-labs/osmosis/v12/x/twap/types" ) +// GenerateKeys generates new keys (KV Store, Transient store, and memory store). func (appKeepers *AppKeepers) GenerateKeys() { // Define what keys will be used in the cosmos-sdk key/value store. // Cosmos-SDK modules each have a "key" that allows the application to reference what they've stored on the chain. appKeepers.keys = sdk.NewKVStoreKeys(KVStoreKeys()...) // Define transient store keys - appKeepers.tkeys = sdk.NewTransientStoreKeys(paramstypes.TStoreKey) + appKeepers.tkeys = sdk.NewTransientStoreKeys(paramstypes.TStoreKey, twaptypes.TransientStoreKey) // MemKeys are for information that is stored only in RAM. appKeepers.memKeys = sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) } +// GetSubspace gets existing substore from keeper. func (appKeepers *AppKeepers) GetSubspace(moduleName string) paramstypes.Subspace { subspace, _ := appKeepers.ParamsKeeper.GetSubspace(moduleName) return subspace } +// GetKVStoreKey gets KV Store keys. func (appKeepers *AppKeepers) GetKVStoreKey() map[string]*sdk.KVStoreKey { return appKeepers.keys } +// GetTransientStoreKey gets Transient Store keys. func (appKeepers *AppKeepers) GetTransientStoreKey() map[string]*sdk.TransientStoreKey { return appKeepers.tkeys } +// GetMemoryStoreKey get memory Store keys. func (appKeepers *AppKeepers) GetMemoryStoreKey() map[string]*sdk.MemoryStoreKey { return appKeepers.memKeys } diff --git a/app/keepers/modules.go b/app/keepers/modules.go index b0766bf1b6b..8de0f56d599 100644 --- a/app/keepers/modules.go +++ b/app/keepers/modules.go @@ -3,10 +3,10 @@ package keepers import ( "github.com/CosmWasm/wasmd/x/wasm" wasmclient "github.com/CosmWasm/wasmd/x/wasm/client" + "github.com/cosmos/ibc-go/v3/modules/apps/icq" transfer "github.com/cosmos/ibc-go/v3/modules/apps/transfer" ibc "github.com/cosmos/ibc-go/v3/modules/core" ibcclientclient "github.com/cosmos/ibc-go/v3/modules/core/02-client/client" - "github.com/osmosis-labs/bech32-ibc/x/bech32ibc" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/auth" @@ -28,18 +28,19 @@ import ( upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" ica "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts" - _ "github.com/osmosis-labs/osmosis/v7/client/docs/statik" - "github.com/osmosis-labs/osmosis/v7/x/epochs" - "github.com/osmosis-labs/osmosis/v7/x/gamm" - "github.com/osmosis-labs/osmosis/v7/x/incentives" - "github.com/osmosis-labs/osmosis/v7/x/lockup" - "github.com/osmosis-labs/osmosis/v7/x/mint" - poolincentives "github.com/osmosis-labs/osmosis/v7/x/pool-incentives" - poolincentivesclient "github.com/osmosis-labs/osmosis/v7/x/pool-incentives/client" - superfluid "github.com/osmosis-labs/osmosis/v7/x/superfluid" - superfluidclient "github.com/osmosis-labs/osmosis/v7/x/superfluid/client" - "github.com/osmosis-labs/osmosis/v7/x/tokenfactory" - "github.com/osmosis-labs/osmosis/v7/x/txfees" + _ "github.com/osmosis-labs/osmosis/v12/client/docs/statik" + "github.com/osmosis-labs/osmosis/v12/x/epochs" + "github.com/osmosis-labs/osmosis/v12/x/gamm" + "github.com/osmosis-labs/osmosis/v12/x/incentives" + "github.com/osmosis-labs/osmosis/v12/x/lockup" + "github.com/osmosis-labs/osmosis/v12/x/mint" + poolincentives "github.com/osmosis-labs/osmosis/v12/x/pool-incentives" + poolincentivesclient "github.com/osmosis-labs/osmosis/v12/x/pool-incentives/client" + superfluid "github.com/osmosis-labs/osmosis/v12/x/superfluid" + superfluidclient "github.com/osmosis-labs/osmosis/v12/x/superfluid/client" + "github.com/osmosis-labs/osmosis/v12/x/tokenfactory" + "github.com/osmosis-labs/osmosis/v12/x/twap/twapmodule" + "github.com/osmosis-labs/osmosis/v12/x/txfees" ) // AppModuleBasics returns ModuleBasics for the module BasicManager. @@ -59,6 +60,7 @@ var AppModuleBasics = []module.AppModuleBasic{ upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler, poolincentivesclient.UpdatePoolIncentivesHandler, + poolincentivesclient.ReplacePoolIncentivesHandler, ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler, superfluidclient.SetSuperfluidAssetsProposalHandler, @@ -75,6 +77,7 @@ var AppModuleBasics = []module.AppModuleBasic{ transfer.AppModuleBasic{}, vesting.AppModuleBasic{}, gamm.AppModuleBasic{}, + twapmodule.AppModuleBasic{}, txfees.AppModuleBasic{}, incentives.AppModuleBasic{}, lockup.AppModuleBasic{}, @@ -82,7 +85,7 @@ var AppModuleBasics = []module.AppModuleBasic{ epochs.AppModuleBasic{}, superfluid.AppModuleBasic{}, tokenfactory.AppModuleBasic{}, - bech32ibc.AppModuleBasic{}, wasm.AppModuleBasic{}, ica.AppModuleBasic{}, + icq.AppModuleBasic{}, } diff --git a/app/modules.go b/app/modules.go index add97dcd9cf..b0e12a61ba3 100644 --- a/app/modules.go +++ b/app/modules.go @@ -8,9 +8,8 @@ import ( ica "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts" icatypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types" - "github.com/osmosis-labs/bech32-ibc/x/bech32ibc" - bech32ibctypes "github.com/osmosis-labs/bech32-ibc/x/bech32ibc/types" - "github.com/osmosis-labs/bech32-ibc/x/bech32ics20" + icq "github.com/cosmos/ibc-go/v3/modules/apps/icq" + icqtypes "github.com/cosmos/ibc-go/v3/modules/apps/icq/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/auth" @@ -20,6 +19,7 @@ import ( vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" "github.com/cosmos/cosmos-sdk/x/authz" authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module" + "github.com/cosmos/cosmos-sdk/x/bank" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/capability" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" @@ -42,27 +42,30 @@ import ( "github.com/cosmos/cosmos-sdk/x/upgrade" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - appparams "github.com/osmosis-labs/osmosis/v7/app/params" - _ "github.com/osmosis-labs/osmosis/v7/client/docs/statik" - "github.com/osmosis-labs/osmosis/v7/osmoutils/partialord" - "github.com/osmosis-labs/osmosis/v7/x/epochs" - epochstypes "github.com/osmosis-labs/osmosis/v7/x/epochs/types" - "github.com/osmosis-labs/osmosis/v7/x/gamm" - gammtypes "github.com/osmosis-labs/osmosis/v7/x/gamm/types" - "github.com/osmosis-labs/osmosis/v7/x/incentives" - incentivestypes "github.com/osmosis-labs/osmosis/v7/x/incentives/types" - "github.com/osmosis-labs/osmosis/v7/x/lockup" - lockuptypes "github.com/osmosis-labs/osmosis/v7/x/lockup/types" - "github.com/osmosis-labs/osmosis/v7/x/mint" - minttypes "github.com/osmosis-labs/osmosis/v7/x/mint/types" - poolincentives "github.com/osmosis-labs/osmosis/v7/x/pool-incentives" - poolincentivestypes "github.com/osmosis-labs/osmosis/v7/x/pool-incentives/types" - superfluid "github.com/osmosis-labs/osmosis/v7/x/superfluid" - superfluidtypes "github.com/osmosis-labs/osmosis/v7/x/superfluid/types" - "github.com/osmosis-labs/osmosis/v7/x/tokenfactory" - tokenfactorytypes "github.com/osmosis-labs/osmosis/v7/x/tokenfactory/types" - "github.com/osmosis-labs/osmosis/v7/x/txfees" - txfeestypes "github.com/osmosis-labs/osmosis/v7/x/txfees/types" + appparams "github.com/osmosis-labs/osmosis/v12/app/params" + _ "github.com/osmosis-labs/osmosis/v12/client/docs/statik" + "github.com/osmosis-labs/osmosis/v12/osmoutils/partialord" + "github.com/osmosis-labs/osmosis/v12/simulation/simtypes" + "github.com/osmosis-labs/osmosis/v12/x/epochs" + epochstypes "github.com/osmosis-labs/osmosis/v12/x/epochs/types" + "github.com/osmosis-labs/osmosis/v12/x/gamm" + gammtypes "github.com/osmosis-labs/osmosis/v12/x/gamm/types" + "github.com/osmosis-labs/osmosis/v12/x/incentives" + incentivestypes "github.com/osmosis-labs/osmosis/v12/x/incentives/types" + "github.com/osmosis-labs/osmosis/v12/x/lockup" + lockuptypes "github.com/osmosis-labs/osmosis/v12/x/lockup/types" + "github.com/osmosis-labs/osmosis/v12/x/mint" + minttypes "github.com/osmosis-labs/osmosis/v12/x/mint/types" + poolincentives "github.com/osmosis-labs/osmosis/v12/x/pool-incentives" + poolincentivestypes "github.com/osmosis-labs/osmosis/v12/x/pool-incentives/types" + superfluid "github.com/osmosis-labs/osmosis/v12/x/superfluid" + superfluidtypes "github.com/osmosis-labs/osmosis/v12/x/superfluid/types" + "github.com/osmosis-labs/osmosis/v12/x/tokenfactory" + tokenfactorytypes "github.com/osmosis-labs/osmosis/v12/x/tokenfactory/types" + "github.com/osmosis-labs/osmosis/v12/x/twap/twapmodule" + twaptypes "github.com/osmosis-labs/osmosis/v12/x/twap/types" + "github.com/osmosis-labs/osmosis/v12/x/txfees" + txfeestypes "github.com/osmosis-labs/osmosis/v12/x/txfees/types" ) // moduleAccountPermissions defines module account permissions @@ -105,7 +108,7 @@ func appModules( ), auth.NewAppModule(appCodec, *app.AccountKeeper, nil), vesting.NewAppModule(*app.AccountKeeper, app.BankKeeper), - bech32ics20.NewAppModule(appCodec, *app.Bech32ICS20Keeper), + bank.NewAppModule(appCodec, *app.BankKeeper, app.AccountKeeper), capability.NewAppModule(appCodec, *app.CapabilityKeeper), crisis.NewAppModule(app.CrisisKeeper, skipGenesisInvariants), gov.NewAppModule(appCodec, *app.GovKeeper, app.AccountKeeper, app.BankKeeper), @@ -119,16 +122,17 @@ func appModules( authzmodule.NewAppModule(appCodec, *app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), ibc.NewAppModule(app.IBCKeeper), ica.NewAppModule(nil, app.ICAHostKeeper), + icq.NewAppModule(*app.ICQKeeper), params.NewAppModule(*app.ParamsKeeper), app.TransferModule, gamm.NewAppModule(appCodec, *app.GAMMKeeper, app.AccountKeeper, app.BankKeeper), - txfees.NewAppModule(appCodec, *app.TxFeesKeeper), - incentives.NewAppModule(appCodec, *app.IncentivesKeeper, app.AccountKeeper, app.BankKeeper, app.EpochsKeeper), - lockup.NewAppModule(appCodec, *app.LockupKeeper, app.AccountKeeper, app.BankKeeper), - poolincentives.NewAppModule(appCodec, *app.PoolIncentivesKeeper), - epochs.NewAppModule(appCodec, *app.EpochsKeeper), + twapmodule.NewAppModule(*app.TwapKeeper), + txfees.NewAppModule(*app.TxFeesKeeper), + incentives.NewAppModule(*app.IncentivesKeeper, app.AccountKeeper, app.BankKeeper, app.EpochsKeeper), + lockup.NewAppModule(*app.LockupKeeper, app.AccountKeeper, app.BankKeeper), + poolincentives.NewAppModule(*app.PoolIncentivesKeeper), + epochs.NewAppModule(*app.EpochsKeeper), superfluid.NewAppModule( - appCodec, *app.SuperfluidKeeper, app.AccountKeeper, app.BankKeeper, @@ -137,64 +141,47 @@ func appModules( app.GAMMKeeper, app.EpochsKeeper, ), - tokenfactory.NewAppModule(appCodec, *app.TokenFactoryKeeper, app.AccountKeeper, app.BankKeeper), - bech32ibc.NewAppModule(appCodec, *app.Bech32IBCKeeper), + tokenfactory.NewAppModule(*app.TokenFactoryKeeper, app.AccountKeeper, app.BankKeeper), } } -// orderBeginBlockers Tell the app's module manager how to set the order of -// BeginBlockers, which are run at the beginning of every block. -func orderBeginBlockers() []string { - return []string{ - // Upgrades should be run VERY first - upgradetypes.ModuleName, - // Note: epochs' begin should be "real" start of epochs, we keep epochs beginblock at the beginning - epochstypes.ModuleName, - capabilitytypes.ModuleName, - minttypes.ModuleName, - poolincentivestypes.ModuleName, - distrtypes.ModuleName, - slashingtypes.ModuleName, - evidencetypes.ModuleName, - stakingtypes.ModuleName, - ibchost.ModuleName, - ibctransfertypes.ModuleName, - icatypes.ModuleName, - authtypes.ModuleName, - banktypes.ModuleName, - govtypes.ModuleName, - crisistypes.ModuleName, - genutiltypes.ModuleName, - authz.ModuleName, - paramstypes.ModuleName, - vestingtypes.ModuleName, - gammtypes.ModuleName, - incentivestypes.ModuleName, - lockuptypes.ModuleName, - poolincentivestypes.ModuleName, - tokenfactorytypes.ModuleName, - // superfluid must come after distribution and epochs - superfluidtypes.ModuleName, - bech32ibctypes.ModuleName, - txfeestypes.ModuleName, - wasm.ModuleName, - } +// orderBeginBlockers returns the order of BeginBlockers, by module name. +func orderBeginBlockers(allModuleNames []string) []string { + ord := partialord.NewPartialOrdering(allModuleNames) + // Upgrades should be run VERY first + // Epochs is set to be next right now, this in principle could change to come later / be at the end. + // But would have to be a holistic change with other pipelines taken into account. + ord.FirstElements(upgradetypes.ModuleName, epochstypes.ModuleName, capabilitytypes.ModuleName) + + // Staking ordering + // TODO: Perhaps this can be relaxed, left to future work to analyze. + ord.Sequence(distrtypes.ModuleName, slashingtypes.ModuleName, evidencetypes.ModuleName, stakingtypes.ModuleName) + // superfluid must come after distribution & epochs. + // TODO: we actually set it to come after staking, since thats what happened before, and want to minimize chance of break. + ord.After(superfluidtypes.ModuleName, stakingtypes.ModuleName) + // TODO: This can almost certainly be un-constrained, but we keep the constraint to match prior functionality. + // IBChost came after staking, before superfluid. + // TODO: Come back and delete this line after testing the base change. + ord.Sequence(stakingtypes.ModuleName, ibchost.ModuleName, superfluidtypes.ModuleName) + // every remaining module's begin block is a no-op. + return ord.TotalOrdering() } +// OrderEndBlockers returns EndBlockers (crisis, govtypes, staking) with no relative order. func OrderEndBlockers(allModuleNames []string) []string { ord := partialord.NewPartialOrdering(allModuleNames) - // Epochs must run after all other end blocks - ord.LastElements(epochstypes.ModuleName) - // txfees auto-swap code should occur before any potential gamm end block code. - ord.Before(txfeestypes.ModuleName, gammtypes.ModuleName) - // only remaining modules that aren;t no-ops are: crisis & govtypes + // only Osmosis modules with endblock code are: twap, crisis, govtypes, staking // we don't care about the relative ordering between them. - return ord.TotalOrdering() } // OrderInitGenesis returns module names in order for init genesis calls. func OrderInitGenesis(allModuleNames []string) []string { + // NOTE: The genutils moodule must occur after staking so that pools are + // properly initialized with tokens from genesis accounts. + // NOTE: Capability module must occur first so that it can initialize any capabilities + // so that other modules that want to create or claim capabilities afterwards in InitChain + // can do so safely. return []string{ capabilitytypes.ModuleName, authtypes.ModuleName, @@ -207,7 +194,9 @@ func OrderInitGenesis(allModuleNames []string) []string { crisistypes.ModuleName, ibchost.ModuleName, icatypes.ModuleName, + icqtypes.ModuleName, gammtypes.ModuleName, + twaptypes.ModuleName, txfeestypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, @@ -215,7 +204,6 @@ func OrderInitGenesis(allModuleNames []string) []string { upgradetypes.ModuleName, vestingtypes.ModuleName, ibctransfertypes.ModuleName, - bech32ibctypes.ModuleName, // comes after ibctransfertypes poolincentivestypes.ModuleName, superfluidtypes.ModuleName, tokenfactorytypes.ModuleName, @@ -228,38 +216,24 @@ func OrderInitGenesis(allModuleNames []string) []string { } } -// simulationModules returns modules for simulation manager -func simulationModules( +// createSimulationManager returns a simulation manager +// must be ran after modulemanager.SetInitGenesisOrder +func createSimulationManager( app *OsmosisApp, encodingConfig appparams.EncodingConfig, skipGenesisInvariants bool, -) []module.AppModuleSimulation { +) *simtypes.Manager { appCodec := encodingConfig.Marshaler - // recreate list of modules, to ensure no issues with overriding prior module structs. - modules := appModules(app, encodingConfig, skipGenesisInvariants) overrideModules := map[string]module.AppModuleSimulation{ authtypes.ModuleName: auth.NewAppModule(appCodec, *app.AccountKeeper, authsims.RandomGenesisAccounts), } - - simModules := []module.AppModuleSimulation{} - for _, appModule := range modules { - // For every module, see if we override it. If so, use override. - // Else, if we can cast the app module into a simulation module add it. - // otherwise no simulation module. - if simModule, ok := overrideModules[appModule.Name()]; ok { - simModules = append(simModules, simModule) - } else { - if simModule, ok := appModule.(module.AppModuleSimulation); ok { - simModules = append(simModules, simModule) - } - } - } - return simModules + simulationManager := simtypes.NewSimulationManager(*app.mm, overrideModules) + return &simulationManager } // ModuleAccountAddrs returns all the app's module account addresses. -func (app *OsmosisApp) ModuleAccountAddrs() map[string]bool { +func ModuleAccountAddrs() map[string]bool { modAccAddrs := make(map[string]bool) for acc := range maccPerms { modAccAddrs[authtypes.NewModuleAddress(acc).String()] = true @@ -267,3 +241,11 @@ func (app *OsmosisApp) ModuleAccountAddrs() map[string]bool { return modAccAddrs } + +func (app *OsmosisApp) GetAccountKeeper() simtypes.AccountKeeper { + return app.AppKeepers.AccountKeeper +} + +func (app *OsmosisApp) GetBankKeeper() simtypes.BankKeeper { + return app.AppKeepers.BankKeeper +} diff --git a/app/params/config.go b/app/params/config.go index 8b952c2849a..3da0e06560a 100644 --- a/app/params/config.go +++ b/app/params/config.go @@ -36,6 +36,7 @@ func init() { RegisterDenoms() } +// RegisterDenoms registers token denoms. func RegisterDenoms() { err := sdk.RegisterDenom(HumanCoinUnit, sdk.OneDec()) if err != nil { @@ -47,6 +48,7 @@ func RegisterDenoms() { } } +// SetAddressPrefixes builds the Config with Bech32 addressPrefix and publKeyPrefix for accounts, validators, and consensus nodes and verifies that addreeses have correct format. func SetAddressPrefixes() { config := sdk.GetConfig() config.SetBech32PrefixForAccount(Bech32PrefixAccAddr, Bech32PrefixAccPub) diff --git a/app/test_helpers.go b/app/test_helpers.go index 65af5804e2f..4e5ba6fb7cd 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -12,16 +12,26 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// Setup initializes a new OsmosisApp. -func Setup(isCheckTx bool) *OsmosisApp { - db := dbm.NewMemDB() - app := NewOsmosisApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, MakeEncodingConfig(), simapp.EmptyAppOptions{}, GetWasmEnabledProposals(), EmptyWasmOpts) - if !isCheckTx { +var defaultGenesisBz []byte + +func getDefaultGenesisStateBytes() []byte { + if len(defaultGenesisBz) == 0 { genesisState := NewDefaultGenesisState() stateBytes, err := json.MarshalIndent(genesisState, "", " ") if err != nil { panic(err) } + defaultGenesisBz = stateBytes + } + return defaultGenesisBz +} + +// Setup initializes a new OsmosisApp. +func Setup(isCheckTx bool) *OsmosisApp { + db := dbm.NewMemDB() + app := NewOsmosisApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, simapp.EmptyAppOptions{}, GetWasmEnabledProposals(), EmptyWasmOpts) + if !isCheckTx { + stateBytes := getDefaultGenesisStateBytes() app.InitChain( abci.RequestInitChain{ @@ -43,7 +53,7 @@ func SetupTestingAppWithLevelDb(isCheckTx bool) (app *OsmosisApp, cleanupFn func if err != nil { panic(err) } - app = NewOsmosisApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, MakeEncodingConfig(), simapp.EmptyAppOptions{}, GetWasmEnabledProposals(), EmptyWasmOpts) + app = NewOsmosisApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, simapp.EmptyAppOptions{}, GetWasmEnabledProposals(), EmptyWasmOpts) if !isCheckTx { genesisState := NewDefaultGenesisState() stateBytes, err := json.MarshalIndent(genesisState, "", " ") diff --git a/app/upgrades/types.go b/app/upgrades/types.go index 02e715e1dad..ea2110d9543 100644 --- a/app/upgrades/types.go +++ b/app/upgrades/types.go @@ -7,7 +7,7 @@ import ( upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" abci "github.com/tendermint/tendermint/abci/types" - "github.com/osmosis-labs/osmosis/v7/app/keepers" + "github.com/osmosis-labs/osmosis/v12/app/keepers" ) // BaseAppParamManager defines an interrace that BaseApp is expected to fullfil diff --git a/app/upgrades/v10/constants.go b/app/upgrades/v10/constants.go index 21c1bac4650..1a89765c0b5 100644 --- a/app/upgrades/v10/constants.go +++ b/app/upgrades/v10/constants.go @@ -1,7 +1,7 @@ package v10 import ( - "github.com/osmosis-labs/osmosis/v7/app/upgrades" + "github.com/osmosis-labs/osmosis/v12/app/upgrades" ) // Last executed block on the v9 code was 4713064. diff --git a/app/upgrades/v10/fork.go b/app/upgrades/v10/fork.go index 6e0444dce6e..048151da82d 100644 --- a/app/upgrades/v10/fork.go +++ b/app/upgrades/v10/fork.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/osmosis-labs/osmosis/v7/app/keepers" + "github.com/osmosis-labs/osmosis/v12/app/keepers" ) func RunForkLogic(ctx sdk.Context, appKeepers *keepers.AppKeepers) { diff --git a/app/upgrades/v10/upgrades_test.go b/app/upgrades/v10/upgrades_test.go index 2f072445639..dec5f1d4da1 100644 --- a/app/upgrades/v10/upgrades_test.go +++ b/app/upgrades/v10/upgrades_test.go @@ -6,8 +6,8 @@ import ( "github.com/stretchr/testify/suite" - "github.com/osmosis-labs/osmosis/v7/app/apptesting" - v10 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v10" + "github.com/osmosis-labs/osmosis/v12/app/apptesting" + v10 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v10" ) type UpgradeTestSuite struct { diff --git a/app/upgrades/v11/constants.go b/app/upgrades/v11/constants.go index 4b0e8f2aded..14f92a1303e 100644 --- a/app/upgrades/v11/constants.go +++ b/app/upgrades/v11/constants.go @@ -1,12 +1,12 @@ package v11 import ( - "github.com/osmosis-labs/osmosis/v7/app/upgrades" - store "github.com/cosmos/cosmos-sdk/store/types" + + "github.com/osmosis-labs/osmosis/v12/app/upgrades" ) -// UpgradeName defines the on-chain upgrade name for the Osmosis v9 upgrade. +// UpgradeName defines the on-chain upgrade name for the Osmosis v11 upgrade. const UpgradeName = "v11" var Upgrade = upgrades.Upgrade{ diff --git a/app/upgrades/v11/upgrades.go b/app/upgrades/v11/upgrades.go index 58bf0897984..639dca70113 100644 --- a/app/upgrades/v11/upgrades.go +++ b/app/upgrades/v11/upgrades.go @@ -5,8 +5,8 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - "github.com/osmosis-labs/osmosis/v7/app/keepers" - "github.com/osmosis-labs/osmosis/v7/app/upgrades" + "github.com/osmosis-labs/osmosis/v12/app/keepers" + "github.com/osmosis-labs/osmosis/v12/app/upgrades" ) func CreateUpgradeHandler( @@ -15,7 +15,7 @@ func CreateUpgradeHandler( bpm upgrades.BaseAppParamManager, keepers *keepers.AppKeepers, ) upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - return mm.RunMigrations(ctx, configurator, fromVM) + return func(ctx sdk.Context, plan upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { + return mm.RunMigrations(ctx, configurator, vm) } } diff --git a/app/upgrades/v12/constants.go b/app/upgrades/v12/constants.go new file mode 100644 index 00000000000..c6583ea3f84 --- /dev/null +++ b/app/upgrades/v12/constants.go @@ -0,0 +1,20 @@ +package v12 + +import ( + "github.com/osmosis-labs/osmosis/v12/app/upgrades" + twaptypes "github.com/osmosis-labs/osmosis/v12/x/twap/types" + + store "github.com/cosmos/cosmos-sdk/store/types" +) + +// UpgradeName defines the on-chain upgrade name for the Osmosis v12 upgrade. +const UpgradeName = "v12" + +var Upgrade = upgrades.Upgrade{ + UpgradeName: UpgradeName, + CreateUpgradeHandler: CreateUpgradeHandler, + StoreUpgrades: store.StoreUpgrades{ + Added: []string{twaptypes.StoreKey}, + Deleted: []string{}, // double check bech32ibc + }, +} diff --git a/app/upgrades/v12/upgrade_test.go b/app/upgrades/v12/upgrade_test.go new file mode 100644 index 00000000000..9cb3892f816 --- /dev/null +++ b/app/upgrades/v12/upgrade_test.go @@ -0,0 +1,89 @@ +package v12_test + +import ( + "fmt" + "testing" + + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/osmosis-labs/osmosis/v12/app/apptesting" +) + +type UpgradeTestSuite struct { + apptesting.KeeperTestHelper +} + +func (suite *UpgradeTestSuite) SetupTest() { + suite.Setup() +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(UpgradeTestSuite)) +} + +const dummyUpgradeHeight = 5 + +// note that this test does not perfectly test state migration, as pre_upgrade function +// which includes setting up tests by creating new pools would also create twap records +// automatically with this binary. The goal of this test is to test that the upgrade handler +// does not panic upon upgrade. +// Detailed state migration tests are placed within the twap keeper. +func (suite *UpgradeTestSuite) TestPoolMigration() { + testCases := []struct { + name string + pre_upgrade func() uint64 + upgrade func() + post_upgrade func(uint64) + }{ + { + "Test that the upgrade succeeds", + func() uint64 { + poolId := suite.PrepareBalancerPool() + poolDenoms, err := suite.App.GAMMKeeper.GetPoolDenoms(suite.Ctx, poolId) + suite.Require().NoError(err) + + _, err = suite.App.TwapKeeper.GetBeginBlockAccumulatorRecord(suite.Ctx, poolId, poolDenoms[0], poolDenoms[1]) + suite.Require().NoError(err) + return poolId + }, + func() { + suite.Ctx = suite.Ctx.WithBlockHeight(dummyUpgradeHeight - 1) + plan := upgradetypes.Plan{Name: "v12", Height: dummyUpgradeHeight} + err := suite.App.UpgradeKeeper.ScheduleUpgrade(suite.Ctx, plan) + suite.Require().NoError(err) + plan, exists := suite.App.UpgradeKeeper.GetUpgradePlan(suite.Ctx) + suite.Require().True(exists) + + suite.Ctx = suite.Ctx.WithBlockHeight(dummyUpgradeHeight) + suite.Require().NotPanics(func() { + beginBlockRequest := abci.RequestBeginBlock{} + suite.App.BeginBlocker(suite.Ctx, beginBlockRequest) + }) + }, + func(poolId uint64) { + poolDenoms, err := suite.App.GAMMKeeper.GetPoolDenoms(suite.Ctx, poolId) + suite.Require().NoError(err) + + _, err = suite.App.TwapKeeper.GetBeginBlockAccumulatorRecord(suite.Ctx, poolId, poolDenoms[0], poolDenoms[1]) + suite.Require().NoError(err) + }, + }, + } + + for _, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.name), func() { + suite.SetupTest() // reset + + // creating pools before upgrade + poolId := tc.pre_upgrade() + + // run upgrade + tc.upgrade() + + // check that pool migration has been successfully done, did not break state + tc.post_upgrade(poolId) + }) + } +} diff --git a/app/upgrades/v12/upgrades.go b/app/upgrades/v12/upgrades.go new file mode 100644 index 00000000000..975013b919c --- /dev/null +++ b/app/upgrades/v12/upgrades.go @@ -0,0 +1,89 @@ +package v12 + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + icahosttypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host/types" + ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" + + gammtypes "github.com/osmosis-labs/osmosis/v12/x/gamm/types" + superfluidtypes "github.com/osmosis-labs/osmosis/v12/x/superfluid/types" + + "github.com/osmosis-labs/osmosis/v12/app/keepers" + "github.com/osmosis-labs/osmosis/v12/app/upgrades" + twaptypes "github.com/osmosis-labs/osmosis/v12/x/twap/types" +) + +// We set the app version to pre-upgrade because it will be incremented by one +// after the upgrade is applied by the handler. +const preUpgradeAppVersion = 11 + +func CreateUpgradeHandler( + mm *module.Manager, + configurator module.Configurator, + bpm upgrades.BaseAppParamManager, + keepers *keepers.AppKeepers, +) upgradetypes.UpgradeHandler { + return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + // Although the app version was already set during the v9 upgrade, our v10 was a fork and + // v11 was decided to be limited to the "gauge creation minimum fee" change only: + // https://github.com/osmosis-labs/osmosis/pull/2202 + // + // As a result, the upgrade handler was not executed to increment the app version. + // This change helps to correctly set the app version for v12. + if err := keepers.UpgradeKeeper.SetAppVersion(ctx, preUpgradeAppVersion); err != nil { + return nil, err + } + + // Specifying the whole list instead of adding and removing. Less fragile. + hostParams := icahosttypes.Params{ + HostEnabled: true, + AllowMessages: []string{ + // Change: Added MsgTrasnsfer + sdk.MsgTypeURL(&ibctransfertypes.MsgTransfer{}), + + sdk.MsgTypeURL(&banktypes.MsgSend{}), + sdk.MsgTypeURL(&stakingtypes.MsgDelegate{}), + sdk.MsgTypeURL(&stakingtypes.MsgBeginRedelegate{}), + sdk.MsgTypeURL(&stakingtypes.MsgCreateValidator{}), + sdk.MsgTypeURL(&stakingtypes.MsgEditValidator{}), + // Change: Added MsgUndelegate + sdk.MsgTypeURL(&stakingtypes.MsgUndelegate{}), + sdk.MsgTypeURL(&distrtypes.MsgWithdrawDelegatorReward{}), + sdk.MsgTypeURL(&distrtypes.MsgSetWithdrawAddress{}), + sdk.MsgTypeURL(&distrtypes.MsgWithdrawValidatorCommission{}), + sdk.MsgTypeURL(&distrtypes.MsgFundCommunityPool{}), + sdk.MsgTypeURL(&govtypes.MsgVote{}), + // Change: Removed authz messages + sdk.MsgTypeURL(&gammtypes.MsgJoinPool{}), + sdk.MsgTypeURL(&gammtypes.MsgExitPool{}), + sdk.MsgTypeURL(&gammtypes.MsgSwapExactAmountIn{}), + sdk.MsgTypeURL(&gammtypes.MsgSwapExactAmountOut{}), + sdk.MsgTypeURL(&gammtypes.MsgJoinSwapExternAmountIn{}), + sdk.MsgTypeURL(&gammtypes.MsgJoinSwapShareAmountOut{}), + sdk.MsgTypeURL(&gammtypes.MsgExitSwapExternAmountOut{}), + sdk.MsgTypeURL(&gammtypes.MsgExitSwapShareAmountIn{}), + // Change: Added superfluid unbound + sdk.MsgTypeURL(&superfluidtypes.MsgSuperfluidUnbondLock{}), + }, + } + keepers.ICAHostKeeper.SetParams(ctx, hostParams) + + // Initialize TWAP state + latestPoolId := keepers.GAMMKeeper.GetNextPoolId(ctx) - 1 + err := keepers.TwapKeeper.MigrateExistingPools(ctx, latestPoolId) + if err != nil { + return nil, err + } + + // Set TWAP parameters to default values. + keepers.TwapKeeper.SetParams(ctx, twaptypes.DefaultParams()) + + return mm.RunMigrations(ctx, configurator, fromVM) + } +} diff --git a/app/upgrades/v3/constants.go b/app/upgrades/v3/constants.go index 6d47d6677ba..089e00c5e34 100644 --- a/app/upgrades/v3/constants.go +++ b/app/upgrades/v3/constants.go @@ -1,6 +1,6 @@ package v3 -import "github.com/osmosis-labs/osmosis/v7/app/upgrades" +import "github.com/osmosis-labs/osmosis/v12/app/upgrades" const ( // UpgradeName defines the on-chain upgrade name for the Osmosis v3 upgrade. diff --git a/app/upgrades/v3/forks.go b/app/upgrades/v3/forks.go index 28fac0d1a32..fb1b372dcb8 100644 --- a/app/upgrades/v3/forks.go +++ b/app/upgrades/v3/forks.go @@ -5,7 +5,7 @@ import ( govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" - "github.com/osmosis-labs/osmosis/v7/app/keepers" + "github.com/osmosis-labs/osmosis/v12/app/keepers" ) // RunForkLogic executes height-gated on-chain fork logic for the Osmosis v3 diff --git a/app/upgrades/v4/constants.go b/app/upgrades/v4/constants.go index 33654160b88..a2a086cbceb 100644 --- a/app/upgrades/v4/constants.go +++ b/app/upgrades/v4/constants.go @@ -1,7 +1,7 @@ package v4 import ( - "github.com/osmosis-labs/osmosis/v7/app/upgrades" + "github.com/osmosis-labs/osmosis/v12/app/upgrades" store "github.com/cosmos/cosmos-sdk/store/types" ) diff --git a/app/upgrades/v4/upgrade_test.go b/app/upgrades/v4/upgrade_test.go index 0a402b6f768..8f2e4ab4eac 100644 --- a/app/upgrades/v4/upgrade_test.go +++ b/app/upgrades/v4/upgrade_test.go @@ -7,12 +7,13 @@ import ( "testing" "time" - "github.com/osmosis-labs/osmosis/v7/app" - v4 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v4" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "github.com/osmosis-labs/osmosis/v12/app" + v4 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v4" + sdk "github.com/cosmos/cosmos-sdk/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) @@ -107,9 +108,11 @@ func (suite *UpgradeTestSuite) TestUpgradePayments() { suite.Require().Equal(feePool.GetCommunityPool(), sdk.NewDecCoins(sdk.NewInt64DecCoin("uosmo", expectedBal))) // Check that gamm Minimum Fee has been set correctly - gammParams := suite.app.GAMMKeeper.GetParams(suite.ctx) - expectedCreationFee := sdk.NewCoins(sdk.NewCoin("uosmo", sdk.OneInt())) - suite.Require().Equal(gammParams.PoolCreationFee, expectedCreationFee) + + // Kept as comments for recordkeeping. Since SetParams is now private, the changes being tested for can no longer be made: + // gammParams := suite.app.GAMMKeeper.GetParams(suite.ctx) + // expectedCreationFee := sdk.NewCoins(sdk.NewCoin("uosmo", sdk.OneInt())) + // suite.Require().Equal(gammParams.PoolCreationFee, expectedCreationFee) }, true, }, diff --git a/app/upgrades/v4/upgrades.go b/app/upgrades/v4/upgrades.go index e5b60ae3615..9f5ec691fe6 100644 --- a/app/upgrades/v4/upgrades.go +++ b/app/upgrades/v4/upgrades.go @@ -5,9 +5,8 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - "github.com/osmosis-labs/osmosis/v7/app/keepers" - "github.com/osmosis-labs/osmosis/v7/app/upgrades" - gammtypes "github.com/osmosis-labs/osmosis/v7/x/gamm/types" + "github.com/osmosis-labs/osmosis/v12/app/keepers" + "github.com/osmosis-labs/osmosis/v12/app/upgrades" ) // CreateUpgradeHandler returns an x/upgrade handler for the Osmosis v4 on-chain @@ -22,8 +21,8 @@ func CreateUpgradeHandler( keepers *keepers.AppKeepers, ) upgradetypes.UpgradeHandler { return func(ctx sdk.Context, _plan upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { - // configure upgrade for x/gamm module pool creation fee param - keepers.GAMMKeeper.SetParams(ctx, gammtypes.NewParams(sdk.Coins{sdk.NewInt64Coin("uosmo", 1)})) // 1 uOSMO + // Kept as comments for recordkeeping. SetParams is now private: + // keepers.GAMMKeeper.SetParams(ctx, gammtypes.NewParams(sdk.Coins{sdk.NewInt64Coin("uosmo", 1)})) // 1 uOSMO Prop12(ctx, keepers.BankKeeper, keepers.DistrKeeper) diff --git a/app/upgrades/v5/constants.go b/app/upgrades/v5/constants.go index 39dfb39105c..107f504935d 100644 --- a/app/upgrades/v5/constants.go +++ b/app/upgrades/v5/constants.go @@ -1,7 +1,7 @@ package v5 import ( - "github.com/osmosis-labs/osmosis/v7/app/upgrades" + "github.com/osmosis-labs/osmosis/v12/app/upgrades" store "github.com/cosmos/cosmos-sdk/store/types" ) diff --git a/app/upgrades/v5/upgrades.go b/app/upgrades/v5/upgrades.go index 851f9b0ba92..bb077f6b5f6 100644 --- a/app/upgrades/v5/upgrades.go +++ b/app/upgrades/v5/upgrades.go @@ -2,7 +2,7 @@ package v5 import ( ibcconnectiontypes "github.com/cosmos/ibc-go/v3/modules/core/03-connection/types" - bech32ibctypes "github.com/osmosis-labs/bech32-ibc/x/bech32ibc/types" + // bech32ibctypes "github.com/osmosis-labs/bech32-ibc/x/bech32ibc/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" @@ -10,9 +10,9 @@ import ( "github.com/cosmos/cosmos-sdk/x/authz" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - "github.com/osmosis-labs/osmosis/v7/app/keepers" - "github.com/osmosis-labs/osmosis/v7/app/upgrades" - txfeestypes "github.com/osmosis-labs/osmosis/v7/x/txfees/types" + "github.com/osmosis-labs/osmosis/v12/app/keepers" + "github.com/osmosis-labs/osmosis/v12/app/upgrades" + txfeestypes "github.com/osmosis-labs/osmosis/v12/x/txfees/types" ) func CreateUpgradeHandler( @@ -46,7 +46,7 @@ func CreateUpgradeHandler( // Override versions for authz & bech32ibctypes module as to not skip their // InitGenesis for txfees module, we will override txfees ourselves. delete(fromVM, authz.ModuleName) - delete(fromVM, bech32ibctypes.ModuleName) + // delete(fromVM, bech32ibctypes.ModuleName) newVM, err := mm.RunMigrations(ctx, configurator, fromVM) if err != nil { diff --git a/app/upgrades/v5/whitelist_feetokens.go b/app/upgrades/v5/whitelist_feetokens.go index 2345ea81559..e0a40202bbb 100644 --- a/app/upgrades/v5/whitelist_feetokens.go +++ b/app/upgrades/v5/whitelist_feetokens.go @@ -7,14 +7,15 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - gammkeeper "github.com/osmosis-labs/osmosis/v7/x/gamm/keeper" - "github.com/osmosis-labs/osmosis/v7/x/txfees/types" + gammkeeper "github.com/osmosis-labs/osmosis/v12/x/gamm/keeper" + "github.com/osmosis-labs/osmosis/v12/x/txfees/types" ) // Every asset with a liquid osmo pairing pool on Osmosis, as of 12/01/21 // Notably, Tick is not on this list because the osmo pool has $76 of liquidity. // Cheq'd and KRT are also not on this, due to neither having osmo pairings. // We nolint because these are strings of whitelisted ibc denoms. +// //nolint:gosec var feetoken_whitelist_data = ` ion,uion,2 diff --git a/app/upgrades/v6/constants.go b/app/upgrades/v6/constants.go index 83b26923a11..f36b6270667 100644 --- a/app/upgrades/v6/constants.go +++ b/app/upgrades/v6/constants.go @@ -1,6 +1,6 @@ package v6 -import "github.com/osmosis-labs/osmosis/v7/app/upgrades" +import "github.com/osmosis-labs/osmosis/v12/app/upgrades" const ( // UpgradeName defines the on-chain upgrade name for the Osmosis v6 upgrade. diff --git a/app/upgrades/v6/forks.go b/app/upgrades/v6/forks.go index f51eee496e4..5820eb36e70 100644 --- a/app/upgrades/v6/forks.go +++ b/app/upgrades/v6/forks.go @@ -3,7 +3,7 @@ package v6 import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/osmosis-labs/osmosis/v7/app/keepers" + "github.com/osmosis-labs/osmosis/v12/app/keepers" ) // RunForkLogic executes height-gated on-chain fork logic for the Osmosis v6 diff --git a/app/upgrades/v7/constants.go b/app/upgrades/v7/constants.go index f561859b2cc..dfa85ee3ccc 100644 --- a/app/upgrades/v7/constants.go +++ b/app/upgrades/v7/constants.go @@ -3,8 +3,8 @@ package v7 import ( "github.com/CosmWasm/wasmd/x/wasm" - "github.com/osmosis-labs/osmosis/v7/app/upgrades" - superfluidtypes "github.com/osmosis-labs/osmosis/v7/x/superfluid/types" + "github.com/osmosis-labs/osmosis/v12/app/upgrades" + superfluidtypes "github.com/osmosis-labs/osmosis/v12/x/superfluid/types" store "github.com/cosmos/cosmos-sdk/store/types" ) diff --git a/app/upgrades/v7/upgrades.go b/app/upgrades/v7/upgrades.go index 9bf662f1a02..64af22d5653 100644 --- a/app/upgrades/v7/upgrades.go +++ b/app/upgrades/v7/upgrades.go @@ -7,11 +7,10 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - "github.com/osmosis-labs/osmosis/v7/app/keepers" - "github.com/osmosis-labs/osmosis/v7/app/upgrades" - lockupkeeper "github.com/osmosis-labs/osmosis/v7/x/lockup/keeper" - mintkeeper "github.com/osmosis-labs/osmosis/v7/x/mint/keeper" - superfluidtypes "github.com/osmosis-labs/osmosis/v7/x/superfluid/types" + "github.com/osmosis-labs/osmosis/v12/app/keepers" + "github.com/osmosis-labs/osmosis/v12/app/upgrades" + lockupkeeper "github.com/osmosis-labs/osmosis/v12/x/lockup/keeper" + superfluidtypes "github.com/osmosis-labs/osmosis/v12/x/superfluid/types" ) func CreateUpgradeHandler( @@ -53,10 +52,16 @@ func CreateUpgradeHandler( Denom: "gamm/pool/1", AssetType: superfluidtypes.SuperfluidAssetTypeLPShare, } - keepers.SuperfluidKeeper.AddNewSuperfluidAsset(ctx, superfluidAsset) + if err := keepers.SuperfluidKeeper.AddNewSuperfluidAsset(ctx, superfluidAsset); err != nil { + return newVM, err + } - // Set the supply offset from the developer vesting account - mintkeeper.SetInitialSupplyOffsetDuringMigration(ctx, *keepers.MintKeeper) + // N.B.: This is left for historic reasons. + // After the v7 upgrade, there was no need for this function anymore so it was removed. + // // Set the supply offset from the developer vesting account + // if err := keepers.MintKeeper.SetInitialSupplyOffsetDuringMigration(ctx); err != nil { + // panic(err) + // } return newVM, err } diff --git a/app/upgrades/v8/README.md b/app/upgrades/v8/README.md index 1c2218b7dce..5d8c005d347 100644 --- a/app/upgrades/v8/README.md +++ b/app/upgrades/v8/README.md @@ -3,6 +3,7 @@ The v8 upgrade is an emergency upgrade coordinated according to osmosis governance proposals [225](https://www.mintscan.io/osmosis/proposals/225), [226](https://www.mintscan.io/osmosis/proposals/226). And thus by implication of 225, incentive proposals [222](https://www.mintscan.io/osmosis/proposals/222), [223](https://www.mintscan.io/osmosis/proposals/223), and [224](https://www.mintscan.io/osmosis/proposals/224). ## Adjusting Incentives for 222, 223, 224 + Like the weekly Gauge Weight updates, the implementations for these proposals simply modify the weights of gauges between pools in the Upgrade: * `ApplyProp222Change` @@ -12,6 +13,7 @@ Like the weekly Gauge Weight updates, the implementations for these proposals si The specification of Minimum and Maximum values will be applied to the spreadsheet that is shared in each Weekly update. ## UnPoolWhitelistedPool for 226 + The implementation of 226 will introduce a new method for unpooling: `UnPoolWhitelistedPool` @@ -52,12 +54,15 @@ Let's review the states a position in a pool may be to be able to understand the └─────────────────────────┘ ``` + ### Unpooling Steps + To unpool, we'll need to carefully consider each of these concepts above. For instance, a user may have already begun unbonding. We will start with the most deeply locked assets, and iteratively unroll them until we end up with individual sdk.Coin entities, some of which may be locked. In the code, the following comment block may be found: + ```sh // 0) Check if its for a whitelisted unpooling poolID // 1) Consistency check that lockID corresponds to sender, and contains correct LP shares. (Should also be validated by caller) @@ -67,4 +72,4 @@ In the code, the following comment block may be found: // 5) ExitPool with these unlocked LP shares // 6) Make 1 new lock for every asset in collateral. Many code paths need this assumption to hold // 7) Make new lock begin unlocking -``` \ No newline at end of file +``` diff --git a/app/upgrades/v8/constants.go b/app/upgrades/v8/constants.go index a0fc2128ecb..26ec5f92991 100644 --- a/app/upgrades/v8/constants.go +++ b/app/upgrades/v8/constants.go @@ -1,8 +1,8 @@ package v8 import ( - "github.com/osmosis-labs/osmosis/v7/app/upgrades" - v8constants "github.com/osmosis-labs/osmosis/v7/app/upgrades/v8/constants" + "github.com/osmosis-labs/osmosis/v12/app/upgrades" + v8constants "github.com/osmosis-labs/osmosis/v12/app/upgrades/v8/constants" ) const ( diff --git a/app/upgrades/v8/forks.go b/app/upgrades/v8/forks.go index 025ef17e77f..0ecd17bc31c 100644 --- a/app/upgrades/v8/forks.go +++ b/app/upgrades/v8/forks.go @@ -3,7 +3,7 @@ package v8 import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/osmosis-labs/osmosis/v7/app/keepers" + "github.com/osmosis-labs/osmosis/v12/app/keepers" ) // RunForkLogic executes height-gated on-chain fork logic for the Osmosis v8 diff --git a/app/upgrades/v8/incentive_props.go b/app/upgrades/v8/incentive_props.go index 07ba90d918e..723fccf337f 100644 --- a/app/upgrades/v8/incentive_props.go +++ b/app/upgrades/v8/incentive_props.go @@ -2,9 +2,9 @@ package v8 import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/osmosis-labs/osmosis/v7/osmoutils" - poolincentiveskeeper "github.com/osmosis-labs/osmosis/v7/x/pool-incentives/keeper" - poolincentivestypes "github.com/osmosis-labs/osmosis/v7/x/pool-incentives/types" + "github.com/osmosis-labs/osmosis/v12/osmoutils" + poolincentiveskeeper "github.com/osmosis-labs/osmosis/v12/x/pool-incentives/keeper" + poolincentivestypes "github.com/osmosis-labs/osmosis/v12/x/pool-incentives/types" ) // This file implements logic for accelerated incentive proposals. diff --git a/app/upgrades/v8/msg_filter_ante.go b/app/upgrades/v8/msg_filter_ante.go index 056ad4ac0bb..9ebc5ff5970 100644 --- a/app/upgrades/v8/msg_filter_ante.go +++ b/app/upgrades/v8/msg_filter_ante.go @@ -4,7 +4,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" - superfluidtypes "github.com/osmosis-labs/osmosis/v7/x/superfluid/types" + superfluidtypes "github.com/osmosis-labs/osmosis/v12/x/superfluid/types" ) // MsgFilterDecorator defines an AnteHandler decorator for the v8 upgrade that diff --git a/app/upgrades/v8/msg_filter_ante_test.go b/app/upgrades/v8/msg_filter_ante_test.go index f3082ab59d8..5cfb616ece1 100644 --- a/app/upgrades/v8/msg_filter_ante_test.go +++ b/app/upgrades/v8/msg_filter_ante_test.go @@ -7,9 +7,9 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/stretchr/testify/require" - "github.com/osmosis-labs/osmosis/v7/app" - v8 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v8" - superfluidtypes "github.com/osmosis-labs/osmosis/v7/x/superfluid/types" + "github.com/osmosis-labs/osmosis/v12/app" + v8 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v8" + superfluidtypes "github.com/osmosis-labs/osmosis/v12/x/superfluid/types" ) func noOpAnteDecorator() sdk.AnteHandler { diff --git a/app/upgrades/v8/unpool_whitelist.go b/app/upgrades/v8/unpool_whitelist.go index 7ecb1ce43f7..a74c2f61047 100644 --- a/app/upgrades/v8/unpool_whitelist.go +++ b/app/upgrades/v8/unpool_whitelist.go @@ -5,8 +5,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - gammkeeper "github.com/osmosis-labs/osmosis/v7/x/gamm/keeper" - superfluidkeeper "github.com/osmosis-labs/osmosis/v7/x/superfluid/keeper" + gammkeeper "github.com/osmosis-labs/osmosis/v12/x/gamm/keeper" + superfluidkeeper "github.com/osmosis-labs/osmosis/v12/x/superfluid/keeper" ) const ustDenom = "ibc/BE1BB42D4BE3C30D50B68D7C41DB4DFCE9678E8EF8C539F6E6A9345048894FCC" diff --git a/app/upgrades/v9/constants.go b/app/upgrades/v9/constants.go index 791e83fd329..9a7f993e4d7 100644 --- a/app/upgrades/v9/constants.go +++ b/app/upgrades/v9/constants.go @@ -1,13 +1,13 @@ package v9 import ( - "github.com/osmosis-labs/osmosis/v7/app/upgrades" + "github.com/osmosis-labs/osmosis/v12/app/upgrades" store "github.com/cosmos/cosmos-sdk/store/types" icahosttypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host/types" - tokenfactorytypes "github.com/osmosis-labs/osmosis/v7/x/tokenfactory/types" + tokenfactorytypes "github.com/osmosis-labs/osmosis/v12/x/tokenfactory/types" ) // UpgradeName defines the on-chain upgrade name for the Osmosis v9 upgrade. diff --git a/app/upgrades/v9/msg_filter_ante_test.go b/app/upgrades/v9/msg_filter_ante_test.go index 0a3d9b5fee5..4a9198dd975 100644 --- a/app/upgrades/v9/msg_filter_ante_test.go +++ b/app/upgrades/v9/msg_filter_ante_test.go @@ -9,9 +9,9 @@ import ( ibcchanneltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - "github.com/osmosis-labs/osmosis/v7/app" - v8 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v8" - v9 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v9" + "github.com/osmosis-labs/osmosis/v12/app" + v8 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v8" + v9 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v9" ) func noOpAnteDecorator() sdk.AnteHandler { diff --git a/app/upgrades/v9/prop214.go b/app/upgrades/v9/prop214.go index 769b2cc7710..aee4de78f44 100644 --- a/app/upgrades/v9/prop214.go +++ b/app/upgrades/v9/prop214.go @@ -3,8 +3,8 @@ package v9 import ( sdk "github.com/cosmos/cosmos-sdk/types" - gammkeeper "github.com/osmosis-labs/osmosis/v7/x/gamm/keeper" - "github.com/osmosis-labs/osmosis/v7/x/gamm/pool-models/balancer" + gammkeeper "github.com/osmosis-labs/osmosis/v12/x/gamm/keeper" + "github.com/osmosis-labs/osmosis/v12/x/gamm/pool-models/balancer" ) // Executes prop214, https://www.mintscan.io/osmosis/proposals/214 @@ -25,8 +25,9 @@ func ExecuteProp214(ctx sdk.Context, gamm *gammkeeper.Keeper) { balancerPool.PoolParams.SwapFee = sdk.MustNewDecFromStr("0.002") - err = gamm.SetPool(ctx, balancerPool) - if err != nil { - panic(err) - } + // Kept as comments for recordkeeping. SetPool is now private: + // err = gamm.SetPool(ctx, balancerPool) + // if err != nil { + // panic(err) + // } } diff --git a/app/upgrades/v9/prop214_test.go b/app/upgrades/v9/prop214_test.go index 4445d2791bd..e7d26a63d3c 100644 --- a/app/upgrades/v9/prop214_test.go +++ b/app/upgrades/v9/prop214_test.go @@ -3,11 +3,10 @@ package v9_test import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" - "github.com/osmosis-labs/osmosis/v7/app/apptesting" - v9 "github.com/osmosis-labs/osmosis/v7/app/upgrades/v9" + "github.com/osmosis-labs/osmosis/v12/app/apptesting" + v9 "github.com/osmosis-labs/osmosis/v12/app/upgrades/v9" ) type UpgradeTestSuite struct { @@ -26,11 +25,12 @@ func (suite *UpgradeTestSuite) TestProp214() { poolId := suite.PrepareBalancerPool() v9.ExecuteProp214(suite.Ctx, suite.App.GAMMKeeper) - pool, err := suite.App.GAMMKeeper.GetPoolAndPoke(suite.Ctx, poolId) + _, err := suite.App.GAMMKeeper.GetPoolAndPoke(suite.Ctx, poolId) suite.Require().NoError(err) - swapFee := pool.GetSwapFee(suite.Ctx) - expectedSwapFee := sdk.MustNewDecFromStr("0.002") - - suite.Require().Equal(expectedSwapFee, swapFee) + // Kept as comments for recordkeeping. Since SetPool is now private, the changes being tested for can no longer be made: + // swapFee := pool.GetSwapFee(suite.Ctx) + // expectedSwapFee := sdk.MustNewDecFromStr("0.002") + // + // suite.Require().Equal(expectedSwapFee, swapFee) } diff --git a/app/upgrades/v9/upgrades.go b/app/upgrades/v9/upgrades.go index dfe54bde5aa..aa896f3292b 100644 --- a/app/upgrades/v9/upgrades.go +++ b/app/upgrades/v9/upgrades.go @@ -10,15 +10,15 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - gammtypes "github.com/osmosis-labs/osmosis/v7/x/gamm/types" + gammtypes "github.com/osmosis-labs/osmosis/v12/x/gamm/types" ica "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts" icacontrollertypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/controller/types" icahosttypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/host/types" icatypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types" - "github.com/osmosis-labs/osmosis/v7/app/keepers" - "github.com/osmosis-labs/osmosis/v7/app/upgrades" + "github.com/osmosis-labs/osmosis/v12/app/keepers" + "github.com/osmosis-labs/osmosis/v12/app/upgrades" ) const preUpgradeAppVersion = 8 diff --git a/chain.schema.json b/chain.schema.json index 2cd48336f3f..8949cd7e314 100644 --- a/chain.schema.json +++ b/chain.schema.json @@ -2,11 +2,56 @@ "$schema": "http://json-schema.org/draft-07/schema#", "codebase":{ "git_repo": "https://github.com/osmosis-labs/osmosis", - "recommended_version": "v10.0.1", - "compatible_versions": ["v10.0.0", "v10.0.1"], + "recommended_version": "11.0.0", + "compatible_versions": ["11.0.0"], "binaries": { - "linux/amd64": "https://github.com/osmosis-labs/osmosis/releases/download/v10.0.0/osmosis-10.0.0-linux-amd64", - "linux/arm64": "https://github.com/osmosis-labs/osmosis/releases/download/v10.0.0/osmosis-10.0.0-linux-arm64" - } + "linux/amd64": "https://github.com/osmosis-labs/osmosis/releases/download/v11.0.0/osmosisd-11.0.0-linux-amd64?checksum=sha256:d01423cf847b7f95a94ade8811bbf6dd9ec5938d46af0a14bc62caaaa7b7143e", + "linux/arm64": "https://github.com/osmosis-labs/osmosis/releases/download/v11.0.0/osmosisd-11.0.0-linux-arm64?checksum=sha256:375699e90e5b76fd3d7e7a9ab631b40badd97140136f361e6b3f06be3fbd863d" + }, + "cosmos_sdk_version": "0.45", + "tendermint_version": "0.34", + "cosmwasm_version": "0.27", + "cosmwasm_enabled": true, + "genesis": { + "name": "v3.1.0", + "genesis_url": "https://github.com/osmosis-labs/networks/raw/main/osmosis-1/genesis.json" + }, + "versions": [ + { + "name": "v3", + "tag" : "v3.1.0", + "height" : 0, + "next_version_name" : "v4" + }, + { + "name": "v4", + "tag" : "v4.2.0", + "height" : 1314500, + "next_version_name" : "v5" + }, + { + "name": "v5", + "tag" : "v6.4.1", + "height" : 2383300, + "next_version_name" : "v7" + }, + { + "name": "v7", + "tag" : "v8.0.0", + "height" : 3401000, + "next_version_name" : "v9" + }, + { + "name": "v9", + "tag" : "v10.0.1", + "height" : 4707300, + "next_version_name" : "v11" + }, + { + "name": "v11", + "tag" : "v11.0.0", + "height" : 5432450 + } + ] } } diff --git a/client/docs/config.json b/client/docs/config.json index 30662cb74b5..dce7013b055 100644 --- a/client/docs/config.json +++ b/client/docs/config.json @@ -7,26 +7,26 @@ }, "apis": [ { - "url": "../../tmp-swagger-gen/osmosis/gamm/v1beta1/query.swagger.json", + "url": "../../tmp-swagger-gen/osmosis/epochs/query.swagger.json", "operationIds": { "rename": { - "Params": "GAMMParams" + "Params": "EpochsParams" } } }, { - "url": "../../tmp-swagger-gen/osmosis/epochs/query.swagger.json", + "url": "../../tmp-swagger-gen/osmosis/gamm/v1beta1/query.swagger.json", "operationIds": { "rename": { - "Params": "EpochsParams" + "Params": "GAMMParams" } } }, { - "url": "../../tmp-swagger-gen/osmosis/pool-incentives/v1beta1/query.swagger.json", + "url": "../../tmp-swagger-gen/osmosis/incentives/query.swagger.json", "operationIds": { "rename": { - "Params": "PoolIncentivesParams" + "Params": "IncentivesParams" } } }, @@ -39,26 +39,44 @@ } }, { - "url": "../../tmp-swagger-gen/osmosis/incentives/query.swagger.json", + "url": "../../tmp-swagger-gen/osmosis/mint/v1beta1/query.swagger.json", "operationIds": { "rename": { - "Params": "IncentivesParams" + "Params": "MintParams" + } + } + }, + { + "url": "../../tmp-swagger-gen/osmosis/pool-incentives/v1beta1/query.swagger.json", + "operationIds": { + "rename": { + "LockableDurations": "PoolLockableDurations", + "Params": "PoolIncentivesParams" } } }, { - "url": "../../tmp-swagger-gen/osmosis/claim/v1beta1/query.swagger.json", + "url": "../../tmp-swagger-gen/osmosis/superfluid/query.swagger.json", "operationIds": { "rename": { - "Params": "ClaimParams" + "Params": "SuperfluidParams" } } }, { - "url": "../../tmp-swagger-gen/osmosis/mint/v1beta1/query.swagger.json", + "url": "../../tmp-swagger-gen/osmosis/tokenfactory/v1beta1/query.swagger.json", "operationIds": { "rename": { - "Params": "MintParams" + "Params": "TokenfactoryParams" + } + } + }, + { + "url": "../../tmp-swagger-gen/osmosis/txfees/v1beta1/query.swagger.json", + "operationIds": { + "rename": { + "Params": "TxFeesParams", + "BaseDenom": "TxFeesBaseDenom" } } }, @@ -71,100 +89,106 @@ } }, { - "url": "../../tmp-swagger-gen/cosmos/bank/v1beta1/query.swagger.json", + "url": "../../tmp-swagger-gen/cosmos/authz/v1beta1/query.swagger.json", "operationIds": { "rename": { - "Params": "BankParams" + "Params": "AuthzParams" } } }, { - "url": "../../tmp-swagger-gen/cosmos/distribution/v1beta1/query.swagger.json", + "url": "../../tmp-swagger-gen/cosmos/bank/v1beta1/query.swagger.json", "operationIds": { "rename": { - "Params": "DistributionParams" + "Params": "BankParams" } } }, { - "url": "../../tmp-swagger-gen/cosmos/evidence/v1beta1/query.swagger.json", + "url": "../../tmp-swagger-gen/cosmos/base/tendermint/v1beta1/query.swagger.json", "operationIds": { "rename": { - "Params": "EvidenceParams" + "Params": "BaseParams" } } }, { - "url": "../../tmp-swagger-gen/cosmos/gov/v1beta1/query.swagger.json", + "url": "../../tmp-swagger-gen/cosmos/distribution/v1beta1/query.swagger.json", "operationIds": { "rename": { - "Params": "GovParams" + "Params": "DistributionParams" } } }, { - "url": "../../tmp-swagger-gen/cosmos/params/v1beta1/query.swagger.json", + "url": "../../tmp-swagger-gen/cosmos/evidence/v1beta1/query.swagger.json", "operationIds": { "rename": { - "Params": "Params" + "Params": "EvidenceParams" } } }, { - "url": "../../tmp-swagger-gen/cosmos/slashing/v1beta1/query.swagger.json", + "url": "../../tmp-swagger-gen/cosmos/feegrant/v1beta1/query.swagger.json", "operationIds": { "rename": { - "Params": "SlashingParams" + "Params": "FeegrantParams" } } }, { - "url": "../../tmp-swagger-gen/cosmos/staking/v1beta1/query.swagger.json", + "url": "../../tmp-swagger-gen/cosmos/gov/v1beta1/query.swagger.json", "operationIds": { "rename": { - "Params": "StakingParams", - "Pool": "StakingPool", - "DelegatorValidators": "StakingDelegatorValidators" + "Params": "GovParams" } } }, { - "url": "../../tmp-swagger-gen/cosmos/upgrade/v1beta1/query.swagger.json", + "url": "../../tmp-swagger-gen/cosmos/mint/v1beta1/query.swagger.json", "operationIds": { "rename": { - "Params": "UpgradeParams" + "Params": "CosmosMintParams" } } }, { - "url": "../../tmp-swagger-gen/ibc/core/channel/v1/query.swagger.json", + "url": "../../tmp-swagger-gen/cosmos/params/v1beta1/query.swagger.json", "operationIds": { "rename": { - "Params": "IBCChannelParams" + "Params": "Params" } } }, { - "url": "../../tmp-swagger-gen/ibc/core/client/v1/query.swagger.json", + "url": "../../tmp-swagger-gen/cosmos/slashing/v1beta1/query.swagger.json", "operationIds": { "rename": { - "Params": "IBCClientParams" + "Params": "SlashingParams" } } }, { - "url": "../../tmp-swagger-gen/ibc/core/connection/v1/query.swagger.json", + "url": "../../tmp-swagger-gen/cosmos/staking/v1beta1/query.swagger.json", "operationIds": { "rename": { - "Params": "IBCConnectionParams" + "Params": "StakingParams", + "Pool": "StakingPool", + "DelegatorValidators": "StakingDelegatorValidators" } } }, { - "url": "../../tmp-swagger-gen/ibc/applications/transfer/v1/query.swagger.json", + "url": "../../tmp-swagger-gen/cosmos/tx/v1beta1/service.swagger.json", + "dereference": { + "circular": "ignore" + } + }, + { + "url": "../../tmp-swagger-gen/cosmos/upgrade/v1beta1/query.swagger.json", "operationIds": { "rename": { - "Params": "IBCTransferParams" + "Params": "UpgradeParams" } } } diff --git a/client/docs/package.json b/client/docs/package.json index c38bc57fabb..baf109a506a 100644 --- a/client/docs/package.json +++ b/client/docs/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "redoc-cli": "^0.9.12", - "swagger-combine": "^1.3.0", + "swagger-combine": "^1.4.0", "swagger2openapi": "^7.0.3" } } diff --git a/client/docs/static/openapi/index.html b/client/docs/static/openapi/index.html index 68c0a07abd1..368811ac057 100644 --- a/client/docs/static/openapi/index.html +++ b/client/docs/static/openapi/index.html @@ -146,6 +146,8 @@ data-styled.g9[id="sc-fujyUd"]{content:"dmdCWO,"}/*!sc*/ .kWxjDZ{font-family:Montserrat,sans-serif;font-weight:400;font-size:1.57143em;line-height:1.6em;color:black;}/*!sc*/ data-styled.g10[id="sc-pNWxx"]{content:"kWxjDZ,"}/*!sc*/ +.eCIxyj{color:#ffffff;}/*!sc*/ +data-styled.g12[id="sc-kEqYlL"]{content:"eCIxyj,"}/*!sc*/ .hAFWNc{border-bottom:1px solid rgba(38,50,56,0.3);margin:1em 0 1em 0;color:rgba(38,50,56,0.5);font-weight:normal;text-transform:uppercase;font-size:0.929em;line-height:20px;}/*!sc*/ data-styled.g13[id="sc-iqAbSa"]{content:"hAFWNc,"}/*!sc*/ .hzAFMi{cursor:pointer;margin-left:-20px;padding:0;line-height:1;width:20px;display:inline-block;outline:0;}/*!sc*/ @@ -159,7 +161,8 @@ .jlUNTT polygon{fill:#d41f1c;}/*!sc*/ .hFuYxn{height:20px;width:20px;vertical-align:middle;float:right;-webkit-transition:-webkit-transform 0.2s ease-out;-webkit-transition:transform 0.2s ease-out;transition:transform 0.2s ease-out;-webkit-transform:rotateZ(0);-ms-transform:rotateZ(0);transform:rotateZ(0);}/*!sc*/ .hFuYxn polygon{fill:white;}/*!sc*/ -data-styled.g15[id="sc-dIsAE"]{content:"hlNMKC,zIEmD,jlUNTT,hFuYxn,"}/*!sc*/ +.dWXhZG{height:18px;width:18px;vertical-align:middle;-webkit-transition:-webkit-transform 0.2s ease-out;-webkit-transition:transform 0.2s ease-out;transition:transform 0.2s ease-out;-webkit-transform:rotateZ(-90deg);-ms-transform:rotateZ(-90deg);transform:rotateZ(-90deg);}/*!sc*/ +data-styled.g15[id="sc-dIsAE"]{content:"hlNMKC,zIEmD,jlUNTT,hFuYxn,dWXhZG,"}/*!sc*/ .bfyodq{border-left:1px solid #a4a4c6;box-sizing:border-box;position:relative;padding:10px 10px 10px 0;}/*!sc*/ tr:first-of-type > .sc-hBMVcZ,tr.last > .bfyodq{border-left-width:0;background-position:top left;background-repeat:no-repeat;background-size:1px 100%;}/*!sc*/ tr:first-of-type > .sc-hBMVcZ{background-image:linear-gradient( to bottom, transparent 0%, transparent 22px, #a4a4c6 22px, #a4a4c6 100% );}/*!sc*/ @@ -182,6 +185,21 @@ .buVWLu .sc-dIvqjp,.buVWLu .sc-dIvqjp .sc-dIvqjp .sc-dIvqjp,.buVWLu .sc-dIvqjp .sc-dIvqjp .sc-dIvqjp .sc-dIvqjp .sc-dIvqjp{margin:1em;margin-right:0;background:#fafafa;}/*!sc*/ .buVWLu .sc-dIvqjp .sc-dIvqjp,.buVWLu .sc-dIvqjp .sc-dIvqjp .sc-dIvqjp .sc-dIvqjp,.buVWLu .sc-dIvqjp .sc-dIvqjp .sc-dIvqjp .sc-dIvqjp .sc-dIvqjp .sc-dIvqjp{background:#ffffff;}/*!sc*/ data-styled.g24[id="sc-hHEjAm"]{content:"buVWLu,"}/*!sc*/ +.diVOEA{margin-left:10px;text-transform:none;font-size:0.929em;color:black;}/*!sc*/ +data-styled.g43[id="sc-jcwofb"]{content:"diVOEA,"}/*!sc*/ +.ceoCql > ul{list-style:none;padding:0;margin:0;margin:0 -5px;}/*!sc*/ +.ceoCql > ul > li{padding:5px 10px;display:inline-block;background-color:#11171a;border-bottom:1px solid rgba(0,0,0,0.5);cursor:pointer;text-align:center;outline:none;color:#b3b3b3;margin:0 5px 5px 5px;border:1px solid #07090b;border-radius:5px;min-width:60px;font-size:0.9em;font-weight:bold;}/*!sc*/ +.ceoCql > ul > li.react-tabs__tab--selected{color:#333333;background:#ffffff;}/*!sc*/ +.ceoCql > ul > li.react-tabs__tab--selected:focus{outline:auto;}/*!sc*/ +.ceoCql > ul > li:only-child{-webkit-flex:none;-ms-flex:none;flex:none;min-width:100px;}/*!sc*/ +.ceoCql > ul > li.tab-success{color:#1d8127;}/*!sc*/ +.ceoCql > ul > li.tab-redirect{color:#ffa500;}/*!sc*/ +.ceoCql > ul > li.tab-info{color:#87ceeb;}/*!sc*/ +.ceoCql > ul > li.tab-error{color:#d41f1c;}/*!sc*/ +.ceoCql > .react-tabs__tab-panel{background:#11171a;}/*!sc*/ +.ceoCql > .react-tabs__tab-panel > div,.ceoCql > .react-tabs__tab-panel > pre{padding:20px;margin:0;}/*!sc*/ +.ceoCql > .react-tabs__tab-panel > div > pre{padding:0;}/*!sc*/ +data-styled.g44[id="sc-carGAA"]{content:"ceoCql,"}/*!sc*/ .cOZQxS code[class*='language-'],.cOZQxS pre[class*='language-']{text-shadow:0 -0.1em 0.2em black;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;}/*!sc*/ @media print{.cOZQxS code[class*='language-'],.cOZQxS pre[class*='language-']{text-shadow:none;}}/*!sc*/ .cOZQxS pre[class*='language-']{padding:1em;margin:0.5em 0;overflow:auto;}/*!sc*/ @@ -201,6 +219,11 @@ .cOZQxS .token.entity{cursor:help;}/*!sc*/ .cOZQxS .token.deleted{color:red;}/*!sc*/ data-styled.g46[id="sc-iBzFoy"]{content:"cOZQxS,"}/*!sc*/ +.kizJoo{opacity:0.4;-webkit-transition:opacity 0.3s ease;transition:opacity 0.3s ease;text-align:right;}/*!sc*/ +.kizJoo:focus-within{opacity:1;}/*!sc*/ +.kizJoo > button{background-color:transparent;border:0;color:inherit;padding:2px 10px;font-family:Roboto,sans-serif;font-size:14px;line-height:1.5em;cursor:pointer;outline:0;}/*!sc*/ +.kizJoo > button:hover,.kizJoo > button:focus{background:rgba(255,255,255,0.1);}/*!sc*/ +data-styled.g47[id="sc-efHXLn"]{content:"kizJoo,"}/*!sc*/ .ps{overflow:hidden !important;overflow-anchor:none;-ms-overflow-style:none;touch-action:auto;-ms-touch-action:auto;}/*!sc*/ .ps__rail-x{display:none;opacity:0;-webkit-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear;-webkit-transition:background-color .2s linear,opacity .2s linear;height:15px;bottom:0px;position:absolute;}/*!sc*/ .ps__rail-y{display:none;opacity:0;-webkit-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear;-webkit-transition:background-color .2s linear,opacity .2s linear;width:15px;right:0;position:absolute;}/*!sc*/ @@ -292,12 +315,50 @@ .gecBYU a:visited{color:#32329f;}/*!sc*/ .gecBYU a:hover{color:#6868cf;}/*!sc*/ data-styled.g54[id="sc-ArjOu"]{content:"gecBYU,"}/*!sc*/ +.eQwAZu{position:relative;}/*!sc*/ +data-styled.g55[id="sc-khIgXV"]{content:"eQwAZu,"}/*!sc*/ +.hwFewY:hover > .sc-efHXLn{opacity:1;}/*!sc*/ +data-styled.g60[id="sc-iNiQeE"]{content:"hwFewY,"}/*!sc*/ +.bFlCqe{font-family:Courier,monospace;font-size:13px;white-space:pre;contain:content;overflow-x:auto;}/*!sc*/ +.bFlCqe .redoc-json > .collapser{display:none;}/*!sc*/ +.bFlCqe .callback-function{color:gray;}/*!sc*/ +.bFlCqe .collapser:after{content:'-';cursor:pointer;}/*!sc*/ +.bFlCqe .collapsed > .collapser:after{content:'+';cursor:pointer;}/*!sc*/ +.bFlCqe .ellipsis:after{content:' … ';}/*!sc*/ +.bFlCqe .collapsible{margin-left:2em;}/*!sc*/ +.bFlCqe .hoverable{padding-top:1px;padding-bottom:1px;padding-left:2px;padding-right:2px;border-radius:2px;}/*!sc*/ +.bFlCqe .hovered{background-color:rgba(235,238,249,1);}/*!sc*/ +.bFlCqe .collapser{padding-right:6px;padding-left:6px;}/*!sc*/ +.bFlCqe ul{list-style-type:none;padding:0px;margin:0px 0px 0px 26px;}/*!sc*/ +.bFlCqe li{position:relative;display:block;}/*!sc*/ +.bFlCqe .hoverable{display:inline-block;}/*!sc*/ +.bFlCqe .selected{outline-style:solid;outline-width:1px;outline-style:dotted;}/*!sc*/ +.bFlCqe .collapsed > .collapsible{display:none;}/*!sc*/ +.bFlCqe .ellipsis{display:none;}/*!sc*/ +.bFlCqe .collapsed > .ellipsis{display:inherit;}/*!sc*/ +.bFlCqe .collapser{position:absolute;top:1px;left:-1.5em;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-user-select:none;}/*!sc*/ +data-styled.g61[id="sc-jffIyK"]{content:"bFlCqe,"}/*!sc*/ +.gasyRS{padding:0.9em;background-color:rgba(38,50,56,0.4);margin:0 0 10px 0;display:block;font-family:Montserrat,sans-serif;font-size:0.929em;line-height:1.5em;}/*!sc*/ +data-styled.g62[id="sc-eJoaVz"]{content:"gasyRS,"}/*!sc*/ +.bbKFgY{font-family:Montserrat,sans-serif;font-size:12px;position:absolute;z-index:1;top:-11px;left:12px;font-weight:600;color:rgba(255,255,255,0.4);}/*!sc*/ +data-styled.g63[id="sc-oefIU"]{content:"bbKFgY,"}/*!sc*/ +.bqSAvT{position:relative;}/*!sc*/ +data-styled.g64[id="sc-hhIhEF"]{content:"bqSAvT,"}/*!sc*/ +.fhUivV{margin-top:15px;}/*!sc*/ +data-styled.g67[id="sc-gGLyOc"]{content:"fhUivV,"}/*!sc*/ +.Hlvtr button{background-color:transparent;border:0;outline:0;font-size:13px;font-family:Courier,monospace;cursor:pointer;padding:0;color:#333333;}/*!sc*/ +.Hlvtr button:focus{font-weight:600;}/*!sc*/ +.Hlvtr .sc-dIsAE{height:1.1em;width:1.1em;}/*!sc*/ +.Hlvtr .sc-dIsAE polygon{fill:#808080;}/*!sc*/ +data-styled.g68[id="sc-ckTRkR"]{content:"Hlvtr,"}/*!sc*/ .ffLJSh{vertical-align:middle;font-size:13px;line-height:20px;}/*!sc*/ data-styled.g69[id="sc-fbIXFq"]{content:"ffLJSh,"}/*!sc*/ .lmAzvs{color:rgba(128,128,128,0.8);}/*!sc*/ data-styled.g70[id="sc-FRqcf"]{content:"lmAzvs,"}/*!sc*/ .hftVBq{color:#808080;}/*!sc*/ data-styled.g71[id="sc-fXazxj"]{content:"hftVBq,"}/*!sc*/ +.SmIsP{color:#808080;word-break:break-word;}/*!sc*/ +data-styled.g72[id="sc-dvXXZy"]{content:"SmIsP,"}/*!sc*/ .cRaJfP{vertical-align:middle;font-size:13px;line-height:20px;}/*!sc*/ data-styled.g73[id="sc-TtZHJ"]{content:"cRaJfP,"}/*!sc*/ .bfDxeF{color:#d41f1c;font-size:0.9em;font-weight:normal;margin-left:20px;line-height:1;}/*!sc*/ @@ -305,9 +366,6 @@ .dYpOEw{border-radius:2px;background-color:rgba(51,51,51,0.05);color:rgba(51,51,51,0.9);padding:0 5px;border:1px solid rgba(51,51,51,0.1);font-family:Courier,monospace;}/*!sc*/ .sc-eKYRpg + .sc-eKYRpg{margin-left:0;}/*!sc*/ data-styled.g78[id="sc-eKYRpg"]{content:"dYpOEw,"}/*!sc*/ -.hDztXq{border-radius:2px;background-color:rgba(142,142,220,0.05);color:rgba(50,50,159,0.9);margin:0 5px;padding:0 5px;border:1px solid rgba(50,50,159,0.1);font-family:Courier,monospace;}/*!sc*/ -.sc-kHWWFa + .sc-kHWWFa{margin-left:0;}/*!sc*/ -data-styled.g80[id="sc-kHWWFa"]{content:"hDztXq,"}/*!sc*/ .bCtQK{margin-top:0;margin-bottom:0.5em;}/*!sc*/ data-styled.g86[id="sc-fuIRbl"]{content:"bCtQK,"}/*!sc*/ .htVLwM{border:1px solid #32329f;color:#32329f;font-weight:normal;margin-left:0.5em;padding:4px 8px 4px;display:inline-block;-webkit-text-decoration:none;text-decoration:none;cursor:pointer;}/*!sc*/ @@ -356,7 +414,8 @@ .lbxURJ:focus{box-shadow:inset 0 2px 2px rgba(0,0,0,0.45),0 2px 0 rgba(128,128,128,0.25);}/*!sc*/ data-styled.g107[id="sc-xGAYn"]{content:"lbxURJ,"}/*!sc*/ .fDdIiv{font-size:0.929em;line-height:20px;background-color:#6bbd5b;color:#ffffff;padding:3px 10px;text-transform:uppercase;font-family:Montserrat,sans-serif;margin:0;}/*!sc*/ -data-styled.g108[id="sc-dWBSoC"]{content:"fDdIiv,"}/*!sc*/ +.gyWLOi{font-size:0.929em;line-height:20px;background-color:#248fb2;color:#ffffff;padding:3px 10px;text-transform:uppercase;font-family:Montserrat,sans-serif;margin:0;}/*!sc*/ +data-styled.g108[id="sc-dWBSoC"]{content:"fDdIiv,gyWLOi,"}/*!sc*/ .hnNwwi{position:absolute;width:100%;z-index:100;background:#fafafa;color:#263238;box-sizing:border-box;box-shadow:0px 0px 6px rgba(0,0,0,0.33);overflow:hidden;border-bottom-left-radius:4px;border-bottom-right-radius:4px;-webkit-transition:all 0.25s ease;transition:all 0.25s ease;visibility:hidden;-webkit-transform:translateY(-50%) scaleY(0);-ms-transform:translateY(-50%) scaleY(0);transform:translateY(-50%) scaleY(0);}/*!sc*/ data-styled.g109[id="sc-jHcYrh"]{content:"hnNwwi,"}/*!sc*/ .gtKCCj{padding:10px;}/*!sc*/ @@ -373,6 +432,8 @@ data-styled.g116[id="sc-ljslrt"]{content:"fcVGze,"}/*!sc*/ .bBmAHf{-webkit-backface-visibility:hidden;backface-visibility:hidden;contain:content;overflow:hidden;}/*!sc*/ data-styled.g128[id="sc-eXuzZk"]{content:"bBmAHf,"}/*!sc*/ +.eokZKJ{margin-bottom:30px;}/*!sc*/ +data-styled.g129[id="sc-iGkqGz"]{content:"eokZKJ,"}/*!sc*/ .gHivHp{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:20px;height:20px;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;color:#32329f;}/*!sc*/ data-styled.g130[id="sc-irKEWy"]{content:"gHivHp,"}/*!sc*/ .hVKzgS{width:260px;background-color:#fafafa;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-backface-visibility:hidden;backface-visibility:hidden;height:100vh;position:-webkit-sticky;position:sticky;position:-webkit-sticky;top:0;}/*!sc*/ @@ -405,32 +466,38 @@ -

Osmosis - gRPC Gateway docs (1.0.0)

Download OpenAPI specification:Download

A REST interface for state queries, legacy transactions

-

Query

NumPools

Responses

Query

CurrentEpoch provide current epoch of specified identifier

query Parameters
identifier
string

Responses

EpochInfos provide running epochInfos

Responses

NumPools

Responses

Pools

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key @@ -459,45 +530,138 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

Per Pool gRPC Endpoints

path Parameters
poolId
required
string <uint64>

Responses

Per Pool gRPC Endpoints

path Parameters
pool_id
required
string <uint64>

Responses

PoolParams

path Parameters
poolId
required
string <uint64>

Responses

PoolParams

path Parameters
pool_id
required
string <uint64>

Responses

SpotPrice

path Parameters
poolId
required
string <uint64>
query Parameters
tokenInDenom
string
tokenOutDenom
string
withSwapFee
boolean

Responses

SpotPrice defines a gRPC query handler that returns the spot price given +a base denomination and a quote denomination.

path Parameters
pool_id
required
string <uint64>
query Parameters
base_asset_denom
string
quote_asset_denom
string

Responses

PoolAssets

path Parameters
poolId
required
string <uint64>

Responses

TotalPoolLiquidity

path Parameters
pool_id
required
string <uint64>

Responses

TotalShare

path Parameters
poolId
required
string <uint64>

Responses

TotalShares

path Parameters
pool_id
required
string <uint64>

Responses

TotalLiquidity

Responses

TotalLiquidity

Responses

Estimate the swap.

path Parameters
poolId
required
string <uint64>
query Parameters
sender
string
tokenIn
string

Responses

Estimate the swap.

path Parameters
pool_id
required
string <uint64>
query Parameters
sender
string
token_in
string

Responses

EstimateSwapExactAmountOut

path Parameters
poolId
required
string <uint64>
query Parameters
sender
string
tokenOut
string

Responses

EstimateSwapExactAmountOut

path Parameters
pool_id
required
string <uint64>
query Parameters
sender
string
token_out
string

Responses

CurrentEpoch provide current epoch of specified identifier

query Parameters
identifier
string

Responses

ActiveGauges returns active gauges

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin +querying the next page most efficiently. Only one of offset or key +should be set.

+
pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. +It is less efficient than using key. Only one of offset or key should +be set.

+
pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. +If left empty it will default to a value to be set by each app.

+
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +a count of the total number of items available for pagination in UIs. +count_total is only respected when offset is used. It is ignored when key +is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

+

Responses

EpochInfos provide running epochInfos

Responses

ActiveGaugesPerDenom returns active gauges by denom

query Parameters
denom
string

Desired denom when querying active gagues.

+
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin +querying the next page most efficiently. Only one of offset or key +should be set.

+
pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. +It is less efficient than using key. Only one of offset or key should +be set.

+
pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. +If left empty it will default to a value to be set by each app.

+
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +a count of the total number of items available for pagination in UIs. +count_total is only respected when offset is used. It is ignored when key +is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

+

Responses

GaugeByID returns gauges by their respective ID

path Parameters
id
required
string <uint64>

Gague ID being queried

+

Responses

Gauges returns both upcoming and active gauges

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin +querying the next page most efficiently. Only one of offset or key +should be set.

+
pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. +It is less efficient than using key. Only one of offset or key should +be set.

+
pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. +If left empty it will default to a value to be set by each app.

+
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +a count of the total number of items available for pagination in UIs. +count_total is only respected when offset is used. It is ignored when key +is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

+

Responses

DistrInfo

Responses

LockableDurations returns lockable durations that are valid to distribute +incentives for

Responses

GaugeIds takes the pool id and returns the matching gauge ids and durations

path Parameters
pool_id
required
string <uint64>

Responses

ModuleDistributedCoins returns coins that are distributed by the module so +far

Responses

IncentivizedPools

Responses

ModuleToDistributeCoins returns coins that are going to be distributed

Responses

RewardsEst returns an estimate of the rewards from now until a specified +time in the future The querier either provides an address or a set of locks +for which they want to find the associated rewards

path Parameters
owner
required
string

Address that is being queried for future estimated rewards

+
query Parameters
lock_ids
Array of strings <uint64>

Lock IDs included in future reward estimation.

+
end_epoch
string <int64>

Upper time limit of reward estimation +Lower limit is current epoch.

+

Responses

LockableDurations

Responses

Returns scheduled gauges that have not yet occured

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin +querying the next page most efficiently. Only one of offset or key +should be set.

+
pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. +It is less efficient than using key. Only one of offset or key should +be set.

+
pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. +If left empty it will default to a value to be set by each app.

+
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +a count of the total number of items available for pagination in UIs. +count_total is only respected when offset is used. It is ignored when key +is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

+

Responses

UpcomingGaugesPerDenom returns scheduled gauges that have not yet occured +by denom

query Parameters
denom
string

Filter for upcoming gagues that match specific denom.

+
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin +querying the next page most efficiently. Only one of offset or key +should be set.

+
pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. +It is less efficient than using key. Only one of offset or key should +be set.

+
pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. +If left empty it will default to a value to be set by each app.

+
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +a count of the total number of items available for pagination in UIs. +count_total is only respected when offset is used. It is ignored when key +is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

+

Responses

PoolIncentivesParams

Responses

Return a locked coins that can't be withdrawn

path Parameters
owner
required
string

Responses

Return a locked coins that can't be withdrawn

path Parameters
owner
required
string

Responses

Returns account locked records with a specific duration

path Parameters
owner
required
string
query Parameters
duration
string

Responses

Returns account locked records with longer duration

path Parameters
owner
required
string
query Parameters
duration
string

Responses

Returns account locked records with longer duration

path Parameters
owner
required
string
query Parameters
duration
string

Responses

Returns account's locked records for a denom with longer duration

path Parameters
owner
required
string
query Parameters
duration
string
denom
string

Responses

Returns lock record by id

path Parameters
lock_id
required
string <uint64>

Responses

Return full balance of the module

Responses

Returns total locked per denom with longer past given time

query Parameters
denom
string
duration
string

Responses

Return full balance of the module

Responses

Return locked balance of the module

Responses

returns active gauges

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin +

Returns synthetic lockups by native lockup id

path Parameters
lock_id
required
string <uint64>

Responses

EpochProvisions returns the current minting epoch provisions value.

Responses

Params returns the total set of minting parameters.

Responses

DistrInfo returns the pool's matching gauge ids and weights.

Responses

ExternalIncentiveGauges returns external incentive gauges.

Responses

GaugeIds takes the pool id and returns the matching gauge ids and durations

path Parameters
pool_id
required
string <uint64>

Responses

IncentivizedPools returns currently incentivized pools

Responses

LockableDurations returns lock durations for pools.

Responses

Params returns pool incentives params.

Responses

Returns all registered superfluid assets.

Responses

Returns all superfluid intermediary accounts.

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.

pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. @@ -531,15 +717,63 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

returns Gauge by id

path Parameters
id
required
string <uint64>

Responses

Returns the total amount of osmo superfluidly staked. +Response is denominated in uosmo.

Responses

Returns the osmo equivalent multiplier used in the most recent epoch.

query Parameters
denom
string

Responses

Returns superfluid asset type, whether if it's a native asset or an lp +share.

query Parameters
denom
string

Responses

Returns intermediary account connected to a superfluid staked lock by id

path Parameters
lock_id
required
string <uint64>

Responses

Returns the amount of a specific denom delegated to a specific validator +This is labeled an estimate, because the way it calculates the amount can +lead rounding errors from the true delegated amount

query Parameters
validator_address
string
denom
string

Responses

Params returns the total set of superfluid parameters.

Responses

Returns the coins superfluid delegated for the delegator, validator, denom +triplet

query Parameters
delegator_address
string
validator_address
string
denom
string

Responses

Returns all the delegated superfluid poistions for a specific delegator.

path Parameters
delegator_address
required
string

Responses

Returns all the superfluid positions of a specific denom delegated to one +validator

query Parameters
validator_address
string
denom
string

Responses

Returns all the undelegating superfluid poistions for a specific delegator.

path Parameters
delegator_address
required
string
query Parameters
denom
string

Responses

Returns the specified delegations for a specific delegator

path Parameters
delegator_address
required
string

Responses

DenomAuthorityMetadata defines a gRPC query method for fetching +DenomAuthorityMetadata for a particular denom.

path Parameters
denom
required
string

Responses

DenomsFromCreator defines a gRPC query method for fetching all +denominations created by a specific admin/creator.

path Parameters
creator
required
string

Responses

Params defines a gRPC query method that returns the tokenfactory module's +parameters.

Responses

Returns a list of all base denom tokens and their corresponding pools.

Responses

returns gauges both upcoming and active

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin +

Returns the poolID for a specified denom input.

path Parameters
denom
required
string

Responses

FeeTokens returns a list of all the whitelisted fee tokens and their +corresponding pools. It does not include the BaseDenom, which has its own +query endpoint

Responses

DenomSpotPrice returns all spot prices by each registered token denom.

query Parameters
denom
string

Responses

Accounts returns all the existing accounts

Since: cosmos-sdk 0.43

+
query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.

pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. @@ -547,21 +781,23 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

returns coins that are distributed by module so far

Responses

Account returns account details based on address.

path Parameters
address
required
string

address defines the address to query for.

+

Responses

returns coins that is going to be distributed

Responses

ModuleAccounts returns all the existing module accounts.

Responses

RewardsEst returns an estimate of the rewards at a future specific time. -The querier either provides an address or a set of locks -for which they want to find the associated rewards.

path Parameters
owner
required
string
query Parameters
lock_ids
Array of strings <uint64>
end_epoch
string <int64>

Responses

Params queries all parameters.

Responses

returns scheduled gauges

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin +

Returns list of `Authorization`, granted to the grantee by the granter.

query Parameters
granter
string
grantee
string
msg_type_url
string

Optional, msg_type_url, when set, will query only grants matching given msg type.

+
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.

pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. @@ -569,32 +805,15 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

ClaimRecord

path Parameters
address
required
string

Responses

ClaimableForAction

path Parameters
address
required
string
action
required
string
Enum: "ActionAddLiquidity" "ActionSwap" "ActionVote" "ActionDelegateStake"

Responses

ModuleAccountBalance

Responses

ClaimParams

Responses

TotalClaimable

path Parameters
address
required
string

Responses

EpochProvisions current minting epoch provisions value.

Responses

Params returns the total set of minting parameters.

Responses

Account returns account details based on address.

path Parameters
address
required
string

address defines the address to query for.

-

Responses

Params queries all parameters.

Responses

AllBalances queries the balance of all coins for a single account.

path Parameters
address
required
string

address is the address to query balances for.

+

AllBalances queries the balance of all coins for a single account.

path Parameters
address
required
string

address is the address to query balances for.

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.

@@ -603,17 +822,22 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

Balance queries the balance of a single coin for a single account.

path Parameters
address
required
string

address is the address to query balances for.

-
denom
required
string

denom is the coin denom to query balances for.

+

Balance queries the balance of a single coin for a single account.

path Parameters
address
required
string

address is the address to query balances for.

+
query Parameters
denom
string

denom is the coin denom to query balances for.

Responses

DenomsMetadata queries the client metadata for all registered coin denominations.

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin +

BaseDenom queries for a base denomination given a denom that can either be +the base denom itself or a metadata denom unit that maps to the base denom.

query Parameters
denom
string

Responses

DenomsMetadata queries the client metadata for all registered coin denominations.

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.

pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. @@ -621,10 +845,12 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

DenomsMetadata queries the client metadata of a given coin denomination.

path Parameters
denom
required
string

denom is the coin denom to query the metadata for.

@@ -632,12 +858,45 @@

Params queries the parameters of x/bank module.

Responses

TotalSupply queries the total supply of all coins.

Responses

TotalSupply queries the total supply of all coins.

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin +querying the next page most efficiently. Only one of offset or key +should be set.

+
pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. +It is less efficient than using key. Only one of offset or key should +be set.

+
pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. +If left empty it will default to a value to be set by each app.

+
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +a count of the total number of items available for pagination in UIs. +count_total is only respected when offset is used. It is ignored when key +is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

+

Responses

SupplyOf queries the supply of a single coin.

path Parameters
denom
required
string

denom is the coin denom to query balances for.

Responses

CommunityPool queries the community pool coins.

Responses

TotalSupplyWithoutOffset queries the total supply of all coins.

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin +querying the next page most efficiently. Only one of offset or key +should be set.

+
pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. +It is less efficient than using key. Only one of offset or key should +be set.

+
pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. +If left empty it will default to a value to be set by each app.

+
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +a count of the total number of items available for pagination in UIs. +count_total is only respected when offset is used. It is ignored when key +is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

+

Responses

SupplyOf queries the supply of a single coin.

path Parameters
denom
required
string

denom is the coin denom to query balances for.

+

Responses

CommunityPool queries the community pool coins.

Responses

DelegationTotalRewards queries the total rewards accrued by a each validator.

path Parameters
delegator_address
required
string

delegator_address defines the delegator address to query for.

@@ -672,10 +931,12 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

AllEvidence queries all evidence.

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin @@ -686,16 +947,38 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

Evidence queries evidence based on evidence hash.

path Parameters
evidence_hash
required
string <byte>

evidence_hash defines the hash of the requested evidence.

Responses

Params queries all parameters of the gov module.

path Parameters
params_type
required
string

params_type defines which parameters to query for, can be one of "voting", +

Allowance returns fee granted to the grantee by the granter.

path Parameters
granter
required
string

granter is the address of the user granting an allowance of their funds.

+
grantee
required
string

grantee is the address of the user being granted an allowance of another user's funds.

+

Responses

Allowances returns all the grants for address.

path Parameters
grantee
required
string
query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin +querying the next page most efficiently. Only one of offset or key +should be set.

+
pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. +It is less efficient than using key. Only one of offset or key should +be set.

+
pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. +If left empty it will default to a value to be set by each app.

+
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +a count of the total number of items available for pagination in UIs. +count_total is only respected when offset is used. It is ignored when key +is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

+

Responses

Params queries all parameters of the gov module.

path Parameters
params_type
required
string

params_type defines which parameters to query for, can be one of "voting", "tallying" or "deposit".

Responses

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

Proposal queries proposal details based on ProposalID.

path Parameters
proposal_id
required
string <uint64>

proposal_id defines the unique id of the proposal.

@@ -741,10 +1026,12 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

Deposit queries single deposit information based proposalID, depositAddr.

path Parameters
proposal_id
required
string <uint64>

proposal_id defines the unique id of the proposal.

@@ -763,17 +1050,25 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

Vote queries voted information based on proposalID, voterAddr.

path Parameters
proposal_id
required
string <uint64>

proposal_id defines the unique id of the proposal.

voter
required
string

voter defines the oter address for the proposals.

Responses

Params queries a specific parameter of a module, given its subspace and +

AnnualProvisions current minting annual provisions value.

Responses

Inflation returns the current minting inflation value.

Responses

Params returns the total set of minting parameters.

Responses

Params queries a specific parameter of a module, given its subspace and key.

query Parameters
subspace
string

subspace defines the module to query the parameter for.

key
string

key defines the key of the parameter in the subspace.

Responses

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

SigningInfo queries the signing info of given cons address

path Parameters
cons_address
required
string

cons_address is the address to query signing info of

@@ -806,10 +1103,12 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

Redelegations queries redelegations of given address.

path Parameters
delegator_addr
required
string

delegator_addr defines the delegator address to query for.

@@ -823,10 +1122,12 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

DelegatorUnbondingDelegations queries all unbonding delegations of a given @@ -839,10 +1140,12 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

DelegatorValidators queries all validators info for given delegator @@ -855,10 +1158,12 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

DelegatorValidator queries validator info for given delegator validator @@ -882,10 +1187,12 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

Validator queries validator info for given validator address.

path Parameters
validator_addr
required
string

validator_addr defines the validator address to query for.

@@ -900,10 +1207,12 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

Delegation queries delegate info for given validator delegator pair.

path Parameters
validator_addr
required
string

validator_addr defines the validator address to query for.

@@ -924,10 +1233,12 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

AppliedPlan queries a previously applied upgrade plan by its name.

path Parameters
name
required
string

name is the name of the applied plan to query for.

@@ -935,51 +1246,30 @@

CurrentPlan queries the current upgrade plan.

Responses

UpgradedConsensusState queries the consensus state that will serve +

ModuleVersions queries the list of module versions from state.

Since: cosmos-sdk 0.43

+
query Parameters
module_name
string

module_name is a field to query a specific module +consensus version from state. Leaving this empty will +fetch the full list of module versions from state.

+

Responses

UpgradedConsensusState queries the consensus state that will serve as a trusted kernel for the next version of this chain. It will only be stored at the last height of this chain. -UpgradedConsensusState RPC not supported with legacy querier

path Parameters
last_height
required
string <int64>

last height of the current chain must be sent in request +UpgradedConsensusState RPC not supported with legacy querier +This rpc is deprecated now that IBC has its own replacement +(https://github.com/cosmos/ibc-go/blob/2c880a22e9f9cc75f62b527ca94aa75ce1106001/proto/ibc/core/client/v1/query.proto#L54)

path Parameters
last_height
required
string <int64>

last height of the current chain must be sent in request as this is the height under which next consensus state is stored

Responses

Channels queries all the IBC channels of a chain.

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin -querying the next page most efficiently. Only one of offset or key -should be set.

-
pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. -It is less efficient than using key. Only one of offset or key should -be set.

-
pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. -If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include -a count of the total number of items available for pagination in UIs. -count_total is only respected when offset is used. It is ignored when key -is set.

-

Responses

Channel queries an IBC Channel.

path Parameters
channel_id
required
string

channel unique identifier

-
port_id
required
string

port unique identifier

-

Responses

Service

GetLatestBlock returns the latest block.

Responses

ChannelClientState queries for the client state for the channel associated -with the provided channel identifiers.

path Parameters
channel_id
required
string

channel unique identifier

-
port_id
required
string

port unique identifier

-

Responses

GetBlockByHeight queries block for given height.

path Parameters
height
required
string <int64>

Responses

ChannelConsensusState queries for the consensus state for the channel -associated with the provided channel identifiers.

path Parameters
channel_id
required
string

channel unique identifier

-
port_id
required
string

port unique identifier

-
revision_number
required
string <uint64>

revision number of the consensus state

-
revision_height
required
string <uint64>

revision height of the consensus state

-

Responses

GetNodeInfo queries the current node info.

Responses

NextSequenceReceive returns the next receive sequence for a given channel.

path Parameters
channel_id
required
string

channel unique identifier

-
port_id
required
string

port unique identifier

-

Responses

GetSyncing queries node syncing.

Responses

PacketAcknowledgements returns all the packet acknowledgements associated -with a channel.

path Parameters
channel_id
required
string

channel unique identifier

-
port_id
required
string

port unique identifier

-
query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin +

GetLatestValidatorSet queries latest validator-set.

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.

pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. @@ -987,21 +1277,15 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

PacketAcknowledgement queries a stored packet acknowledgement hash.

path Parameters
channel_id
required
string

channel unique identifier

-
port_id
required
string

port unique identifier

-
sequence
required
string <uint64>

packet sequence

-

Responses

PacketCommitments returns all the packet commitments hashes associated -with a channel.

path Parameters
channel_id
required
string

channel unique identifier

-
port_id
required
string

port unique identifier

-
query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin +

GetValidatorSetByHeight queries validator-set at a given height.

path Parameters
height
required
string <int64>
query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.

pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. @@ -1009,98 +1293,21 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

Responses

UnreceivedAcks returns all the unreceived IBC acknowledgements associated with a -channel and sequences.

path Parameters
channel_id
required
string

channel unique identifier

-
port_id
required
string

port unique identifier

-
packet_ack_sequences
required
Array of strings <uint64> non-empty

list of acknowledgement sequences

-

Responses

UnreceivedPackets returns all the unreceived IBC packets associated with a -channel and sequences.

path Parameters
channel_id
required
string

channel unique identifier

-
port_id
required
string

port unique identifier

-
packet_commitment_sequences
required
Array of strings <uint64> non-empty

list of packet sequences

-

Responses

PacketCommitment queries a stored packet commitment hash.

path Parameters
channel_id
required
string

channel unique identifier

-
port_id
required
string

port unique identifier

-
sequence
required
string <uint64>

packet sequence

-

Responses

Simulate simulates executing a transaction for estimating gas usage.

Request Body schema: application/json
object (cosmos.tx.v1beta1.Tx)

Tx is the standard type used for broadcasting transactions.

+
tx_bytes
string <byte>

tx_bytes is the raw transaction.

+

Since: cosmos-sdk 0.43

+

Responses

PacketReceipt queries if a given packet sequence has been received on the queried chain

path Parameters
channel_id
required
string

channel unique identifier

-
port_id
required
string

port unique identifier

-
sequence
required
string <uint64>

packet sequence

-

Responses

ConnectionChannels queries all the channels associated with a connection -end.

path Parameters
connection
required
string

connection unique identifier

-
query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin -querying the next page most efficiently. Only one of offset or key -should be set.

-
pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. -It is less efficient than using key. Only one of offset or key should -be set.

-
pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. -If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include -a count of the total number of items available for pagination in UIs. -count_total is only respected when offset is used. It is ignored when key -is set.

-

Responses

ClientParams queries all parameters of the ibc client.

Responses

ClientStates queries all the IBC light clients of a chain.

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin -querying the next page most efficiently. Only one of offset or key -should be set.

-
pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. -It is less efficient than using key. Only one of offset or key should -be set.

-
pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. -If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include -a count of the total number of items available for pagination in UIs. -count_total is only respected when offset is used. It is ignored when key -is set.

-

Responses

ClientState queries an IBC light client.

path Parameters
client_id
required
string

client state unique identifier

-

Responses

ConsensusStates queries all the consensus state associated with a given -client.

path Parameters
client_id
required
string

client identifier

-
query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin -querying the next page most efficiently. Only one of offset or key -should be set.

-
pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. -It is less efficient than using key. Only one of offset or key should -be set.

-
pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. -If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include -a count of the total number of items available for pagination in UIs. -count_total is only respected when offset is used. It is ignored when key -is set.

-

Responses

ConsensusState queries a consensus state associated with a client state at -a given height.

path Parameters
client_id
required
string

client identifier

-
revision_number
required
string <uint64>

consensus state revision number

-
revision_height
required
string <uint64>

consensus state revision height

-
query Parameters
latest_height
boolean

latest_height overrrides the height field and queries the latest stored -ConsensusState.

-

Responses

ClientConnections queries the connection paths associated with a client -state.

path Parameters
client_id
required
string

client identifier associated with a connection

-

Responses

Connections queries all the IBC connections of a chain.

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin +

Request samples

Content type
application/json
{
  • "tx":
    {
    },
  • "tx_bytes": "string"
}

GetTxsEvent fetches txs by event.

query Parameters
events
Array of strings

events is the list of transaction event type.

+
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin querying the next page most efficiently. Only one of offset or key should be set.

pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. @@ -1108,45 +1315,38 @@ be set.

pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include +

pagination.count_total
boolean

count_total is set to true to indicate that the result set should include a count of the total number of items available for pagination in UIs. count_total is only respected when offset is used. It is ignored when key is set.

+
pagination.reverse
boolean

reverse is set to true if results are to be returned in the descending order.

+

Since: cosmos-sdk 0.43

+
order_by
string
Default: "ORDER_BY_UNSPECIFIED"
Enum: "ORDER_BY_UNSPECIFIED" "ORDER_BY_ASC" "ORDER_BY_DESC"
    +
  • ORDER_BY_UNSPECIFIED: ORDER_BY_UNSPECIFIED specifies an unknown sorting order. OrderBy defaults to ASC in this case.
  • +
  • ORDER_BY_ASC: ORDER_BY_ASC defines ascending order
  • +
  • ORDER_BY_DESC: ORDER_BY_DESC defines descending order
  • +

Responses

Connection queries an IBC connection end.

path Parameters
connection_id
required
string

connection unique identifier

-

Responses

ConnectionClientState queries the client state associated with the -connection.

path Parameters
connection_id
required
string

connection identifier

-

Responses

ConnectionConsensusState queries the consensus state associated with the -connection.

path Parameters
connection_id
required
string

connection identifier

-
revision_number
required
string <uint64>
revision_height
required
string <uint64>

Responses

DenomTraces queries all denomination traces.

query Parameters
pagination.key
string <byte>

key is a value returned in PageResponse.next_key to begin -querying the next page most efficiently. Only one of offset or key -should be set.

-
pagination.offset
string <uint64>

offset is a numeric offset that can be used when key is unavailable. -It is less efficient than using key. Only one of offset or key should -be set.

-
pagination.limit
string <uint64>

limit is the total number of results to be returned in the result page. -If left empty it will default to a value to be set by each app.

-
pagination.count_total
boolean

count_total is set to true to indicate that the result set should include -a count of the total number of items available for pagination in UIs. -count_total is only respected when offset is used. It is ignored when key -is set.

-

Responses

BroadcastTx broadcast transaction.

Request Body schema: application/json
tx_bytes
string <byte>

tx_bytes is the raw transaction.

+
mode
string
Default: "BROADCAST_MODE_UNSPECIFIED"
Enum: "BROADCAST_MODE_UNSPECIFIED" "BROADCAST_MODE_BLOCK" "BROADCAST_MODE_SYNC" "BROADCAST_MODE_ASYNC"

BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC method.

+
    +
  • BROADCAST_MODE_UNSPECIFIED: zero-value for mode ordering
  • +
  • BROADCAST_MODE_BLOCK: BROADCAST_MODE_BLOCK defines a tx broadcasting mode where the client waits for +the tx to be committed in a block.
  • +
  • BROADCAST_MODE_SYNC: BROADCAST_MODE_SYNC defines a tx broadcasting mode where the client waits for +a CheckTx execution response only.
  • +
  • BROADCAST_MODE_ASYNC: BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client returns +immediately.
  • +
+

Responses

DenomTrace queries a denomination trace information.

path Parameters
hash
required
string

hash (in hex format) of the denomination trace information.

+

Request samples

Content type
application/json
{
  • "tx_bytes": "string",
  • "mode": "BROADCAST_MODE_UNSPECIFIED"
}

GetTx fetches a tx by hash.

path Parameters
hash
required
string

hash is the tx hash to query, encoded as a hex string.

Responses

Params queries all parameters of the ibc-transfer module.

Responses

+