chore: remove simapp v1 (#23009)

This commit is contained in:
Julien Robert 2024-12-19 19:51:59 +01:00 committed by GitHub
parent 150f2d6b3a
commit 4a073fa4a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
55 changed files with 195 additions and 6120 deletions

View File

@ -18,7 +18,6 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
# go-arch: ["amd64", "arm", "arm64"]
go-arch: ["amd64", "arm64"] # drop 32 bit support for now (and maybe forever)
steps:
- uses: actions/checkout@v4
@ -48,19 +47,17 @@ jobs:
###################
#### Build App ####
###################
- name: Build
run: GOARCH=${{ matrix.go-arch }} make build
- name: Build v2
run: GOARCH=${{ matrix.go-arch }} COSMOS_BUILD_OPTIONS=v2 make build
- name: Build with rocksdb backend
if: matrix.go-arch == 'amd64'
run: GOARCH=${{ matrix.go-arch }} COSMOS_BUILD_OPTIONS="rocksdb" make build
run: GOARCH=${{ matrix.go-arch }} COSMOS_BUILD_OPTIONS=v2,rocksdb make build
- name: Build with BLS12381
if: matrix.go-arch == 'amd64'
run: GOARCH=${{ matrix.go-arch }} COSMOS_BUILD_OPTIONS="bls12381" make build
run: GOARCH=${{ matrix.go-arch }} COSMOS_BUILD_OPTIONS=v2,bls12381 make build
- name: Build with Secp_cgo
if: matrix.go-arch == 'amd64'
run: GOARCH=${{ matrix.go-arch }} COSMOS_BUILD_OPTIONS="secp" make build
run: GOARCH=${{ matrix.go-arch }} COSMOS_BUILD_OPTIONS=v2,secp make build
###################
## Build Tooling ##
###################

View File

@ -1,145 +0,0 @@
name: Sims release/0.47.x
# Sims workflow runs multiple types of simulations (nondeterminism, import-export, after-import, multi-seed-short)
# This workflow will run on all Pull Requests, if a .go, .mod or .sum file have been changed
on:
schedule:
- cron: "0 0,12 * * *"
release:
types: [published]
concurrency:
group: ci-${{ github.ref }}-sims-047
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, 'skip-sims')"
steps:
- uses: actions/checkout@v4
with:
ref: "release/v0.47.x"
- uses: actions/setup-go@v5
with:
go-version: "1.23"
check-latest: true
- run: make build
install-runsim:
permissions:
contents: none
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/setup-go@v5
with:
go-version: "1.23"
check-latest: true
- name: Install runsim
run: go install github.com/cosmos/tools/cmd/runsim@v1.0.0
- uses: actions/cache@v4
with:
path: ~/go/bin
key: ${{ runner.os }}-go-runsim-binary
test-sim-import-export:
runs-on: ubuntu-latest
needs: [build, install-runsim]
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
with:
ref: "release/v0.47.x"
- uses: actions/setup-go@v5
with:
go-version: "1.23"
check-latest: true
- uses: actions/cache@v4
with:
path: ~/go/bin
key: ${{ runner.os }}-go-runsim-binary
- name: test-sim-import-export
run: |
make test-sim-import-export
test-sim-after-import:
runs-on: ubuntu-latest
needs: [build, install-runsim]
steps:
- uses: actions/checkout@v4
with:
ref: "release/v0.47.x"
- uses: actions/setup-go@v5
with:
go-version: "1.23"
check-latest: true
- uses: actions/cache@v4
with:
path: ~/go/bin
key: ${{ runner.os }}-go-runsim-binary
- name: test-sim-after-import
run: |
make test-sim-after-import
test-sim-multi-seed-short:
runs-on: ubuntu-latest
needs: [build, install-runsim]
steps:
- uses: actions/checkout@v4
with:
ref: "release/v0.47.x"
- uses: actions/setup-go@v5
with:
go-version: "1.23"
check-latest: true
- uses: actions/cache@v4
with:
path: ~/go/bin
key: ${{ runner.os }}-go-runsim-binary
- name: test-sim-multi-seed-short
run: |
make test-sim-multi-seed-short
sims-notify-success:
needs:
[test-sim-multi-seed-short, test-sim-after-import, test-sim-import-export]
runs-on: ubuntu-latest
if: ${{ success() }}
steps:
- uses: actions/checkout@v4
- name: Get previous workflow status
uses: ./.github/actions/last-workflow-status
id: last_status
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Notify Slack on success
if: ${{ steps.last_status.outputs.last_status == 'failure' }}
uses: rtCamp/action-slack-notify@v2.3.2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_CHANNEL: sdk-sims
SLACK_USERNAME: Sim Tests release/0.47.x
SLACK_ICON_EMOJI: ":white_check_mark:"
SLACK_COLOR: good
SLACK_MESSAGE: 0.47.x Sims are passing
SLACK_FOOTER: ""
sims-notify-failure:
permissions:
contents: none
needs:
[test-sim-multi-seed-short, test-sim-after-import, test-sim-import-export]
runs-on: ubuntu-latest
if: ${{ failure() }}
steps:
- name: Notify Slack on failure
uses: rtCamp/action-slack-notify@v2.3.2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_CHANNEL: sdk-sims
SLACK_USERNAME: Sim Tests release/0.47.x
SLACK_ICON_EMOJI: ":skull:"
SLACK_COLOR: danger
SLACK_MESSAGE: 0.47.x Sims are failing
SLACK_FOOTER: ""

View File

@ -114,46 +114,6 @@ jobs:
name: "${{ github.sha }}-integration-coverage"
path: ./tests/integration-profile.out
test-system: # v2 system tests are in v2-test.yml
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-tags: true
- uses: actions/setup-go@v5
with:
go-version: "1.23"
check-latest: true
cache: true
cache-dependency-path: |
simapp/go.sum
systemtest/go.sum
- uses: technote-space/get-diff-action@v6.1.2
id: git_diff
with:
PATTERNS: |
**/*.go
go.mod
go.sum
**/go.mod
**/go.sum
**/Makefile
Makefile
- name: Install musl lib for simd (docker) binary
if: env.GIT_DIFF
run: |
sudo apt-get install -y musl
- name: system tests v1
if: env.GIT_DIFF
run: |
make test-system
- uses: actions/upload-artifact@v4
if: failure()
with:
name: "testnet-setup"
path: ./systemtests/testnet/
retention-days: 3
repo-analysis:
runs-on: ubuntu-latest
needs: [tests, test-integration]
@ -504,29 +464,6 @@ jobs:
with:
projectBaseDir: indexer/postgres/
test-simapp:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.23"
check-latest: true
cache: true
cache-dependency-path: simapp/go.sum
- uses: technote-space/get-diff-action@v6.1.2
id: git_diff
with:
PATTERNS: |
**/*.go
simapp/go.mod
simapp/go.sum
- name: tests simapp
if: env.GIT_DIFF
run: |
cd simapp
go test -mod=readonly -timeout 30m -tags='norace ledger test_ledger_mock' ./...
test-simapp-v2:
runs-on: ubuntu-latest
steps:

View File

@ -50,4 +50,3 @@ For more information on SDK tooling, see the [Tooling](https://docs.cosmos.netwo
## Example
* [SimApp v2](https://pkg.go.dev/cosmossdk.io/simapp/v2) - SimApp/v2 is **the** sample Cosmos SDK v2 chain. This package should not be imported in your application.
* [SimApp](https://pkg.go.dev/cosmossdk.io/simapp) - SimApp is **the** sample Cosmos SDK chain. This package should not be imported in your application.

View File

@ -14,7 +14,7 @@ use (
./log
./math
./orm
./simapp
./simapp/v2
./tests
./tests/systemtests
./schema

View File

@ -12,6 +12,7 @@ MOCKS_DIR = $(CURDIR)/tests/mocks
HTTPS_GIT := https://github.com/cosmos/cosmos-sdk.git
DOCKER := $(shell which docker)
PROJECT_NAME = $(shell git remote get-url origin | xargs basename -s .git)
COSMOS_BUILD_OPTIONS := v2
rocksdb_version=v9.6.1

View File

@ -1,9 +1,10 @@
# TODO: This should be ported to work with SimApp v2.
#? test-sim-nondeterminism: Run non-determinism test for simapp
test-sim-nondeterminism:
@echo "Running non-determinism test..."
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout=30m -tags='sims' -run TestAppStateDeterminism \
-NumBlocks=100 -BlockSize=200 -Period=0
# @echo "Running non-determinism test..."
# @cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout=30m -tags='sims' -run TestAppStateDeterminism \
# -NumBlocks=100 -BlockSize=200 -Period=0
# Requires an exported plugin. See store/streaming/README.md for documentation.
#
@ -15,49 +16,47 @@ test-sim-nondeterminism:
# export COSMOS_SDK_ABCI_V1=<path-to-sdk>/store/streaming/abci/examples/file/file
# make test-sim-nondeterminism-streaming
test-sim-nondeterminism-streaming:
@echo "Running non-determinism-streaming test..."
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout=30m -tags='sims' -run TestAppStateDeterminism \
-NumBlocks=100 -BlockSize=200 -Period=0 -EnableStreaming=true
# @echo "Running non-determinism-streaming test..."
# @cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout=30m -tags='sims' -run TestAppStateDeterminism \
# -NumBlocks=100 -BlockSize=200 -Period=0 -EnableStreaming=true
test-sim-custom-genesis-fast:
@echo "Running custom genesis simulation..."
@echo "By default, ${HOME}/.simapp/config/genesis.json will be used."
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout=30m -tags='sims' -run TestFullAppSimulation -Genesis=${HOME}/.simapp/config/genesis.json \
-NumBlocks=100 -BlockSize=200 -Seed=99 -Period=5 -SigverifyTx=false
# @echo "Running custom genesis simulation..."
# @echo "By default, ${HOME}/.simapp/config/genesis.json will be used."
# @cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout=30m -tags='sims' -run TestFullAppSimulation -Genesis=${HOME}/.simapp/config/genesis.json \
# -NumBlocks=100 -BlockSize=200 -Seed=99 -Period=5 -SigverifyTx=false
test-sim-import-export:
@echo "Running application import/export simulation. This may take several minutes..."
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout 20m -tags='sims' -run TestAppImportExport \
-NumBlocks=50 -Period=5
# @echo "Running application import/export simulation. This may take several minutes..."
# @cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout 20m -tags='sims' -run TestAppImportExport \
# -NumBlocks=50 -Period=5
test-sim-after-import:
@echo "Running application simulation-after-import. This may take several minutes..."
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout 30m -tags='sims' -run TestAppSimulationAfterImport \
-NumBlocks=50 -Period=5
# @echo "Running application simulation-after-import. This may take several minutes..."
# @cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout 30m -tags='sims' -run TestAppSimulationAfterImport \
# -NumBlocks=50 -Period=5
test-sim-custom-genesis-multi-seed:
@echo "Running multi-seed custom genesis simulation..."
@echo "By default, ${HOME}/.simapp/config/genesis.json will be used."
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout 30m -tags='sims' -run TestFullAppSimulation -Genesis=${HOME}/.simapp/config/genesis.json \
-NumBlocks=400 -Period=5
# @echo "Running multi-seed custom genesis simulation..."
# @echo "By default, ${HOME}/.simapp/config/genesis.json will be used."
# @cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout 30m -tags='sims' -run TestFullAppSimulation -Genesis=${HOME}/.simapp/config/genesis.json \
# -NumBlocks=400 -Period=5
test-sim-multi-seed-long:
@echo "Running long multi-seed application simulation. This may take awhile!"
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout=2h -tags='sims' -run TestFullAppSimulation \
-NumBlocks=150 -Period=50
# @echo "Running long multi-seed application simulation. This may take awhile!"
# @cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout=2h -tags='sims' -run TestFullAppSimulation \
# -NumBlocks=150 -Period=50
test-sim-multi-seed-short:
@echo "Running short multi-seed application simulation. This may take awhile!"
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout 30m -tags='sims' -run TestFullAppSimulation \
-NumBlocks=50 -Period=10 -FauxMerkle=true
# @echo "Running short multi-seed application simulation. This may take awhile!"
# @cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -timeout 30m -tags='sims' -run TestFullAppSimulation \
# -NumBlocks=50 -Period=10 -FauxMerkle=true
test-sim-benchmark-invariants:
@echo "Running simulation invariant benchmarks..."
cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -benchmem -bench=BenchmarkInvariants -tags='sims' -run=^$ \
-Enabled=true -NumBlocks=1000 -BlockSize=200 \
-Period=1 -Commit=true -Seed=57 -v -timeout 24h
# @echo "Running simulation invariant benchmarks..."
# cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -benchmem -bench=BenchmarkInvariants -tags='sims' -run=^$ \
# -Enabled=true -NumBlocks=1000 -BlockSize=200 \
# -Period=1 -Commit=true -Seed=57 -v -timeout 24h
.PHONY: \
test-sim-nondeterminism \

View File

@ -1,22 +0,0 @@
#!/usr/bin/env bash
SIMD_BIN=${SIMD_BIN:=$(which simd 2>/dev/null)}
if [ -z "$SIMD_BIN" ]; then echo "SIMD_BIN is not set. Make sure to run 'make install' before"; exit 1; fi
SIMD_HOME=$($SIMD_BIN config home)
if [ -d "$SIMD_HOME" ]; then rm -rv $SIMD_HOME; fi
$SIMD_BIN config set client chain-id demo
$SIMD_BIN config set client keyring-backend test
$SIMD_BIN config set client keyring-default-keyname alice
$SIMD_BIN config set app api.enable true
$SIMD_BIN keys add alice --indiscreet
$SIMD_BIN keys add bob --indiscreet
$SIMD_BIN init test --chain-id demo
# to change the voting_period
jq '.app_state.gov.params.voting_period = "600s"' $SIMD_HOME/config/genesis.json > temp.json && mv temp.json $SIMD_HOME/config/genesis.json
jq '.app_state.gov.params.expedited_voting_period = "300s"' $SIMD_HOME/config/genesis.json > temp.json && mv temp.json $SIMD_HOME/config/genesis.json
jq '.app_state.mint.minter.inflation = "0.300000000000000000"' $SIMD_HOME/config/genesis.json > temp.json && mv temp.json $SIMD_HOME/config/genesis.json # to change the inflation
$SIMD_BIN genesis add-genesis-account alice 5000000000stake --keyring-backend test
$SIMD_BIN genesis add-genesis-account bob 5000000000stake --keyring-backend test
$SIMD_BIN genesis gentx alice 1000000stake --chain-id demo
$SIMD_BIN genesis collect-gentxs

View File

@ -15,7 +15,6 @@ import (
cmtproto "github.com/cometbft/cometbft/api/cometbft/types/v1"
cryptoenc "github.com/cometbft/cometbft/crypto/encoding"
protoio "github.com/cosmos/gogoproto/io"
"github.com/cosmos/gogoproto/proto"
gogoproto "github.com/cosmos/gogoproto/proto"
gogoany "github.com/cosmos/gogoproto/types/any"
"google.golang.org/grpc/codes"
@ -516,7 +515,7 @@ func ValidateVoteExtensions[T transaction.Tx](
return nil
}
marshalDelimitedFn := func(msg proto.Message) ([]byte, error) {
marshalDelimitedFn := func(msg gogoproto.Message) ([]byte, error) {
var buf bytes.Buffer
if err := protoio.NewDelimitedWriter(&buf).WriteMsg(msg); err != nil {
return nil, err

View File

@ -1,63 +0,0 @@
<!--
Guiding Principles:
Changelogs are for humans, not machines.
There should be an entry for every single version.
The same types of changes should be grouped.
Versions and sections should be linkable.
The latest version comes first.
The release date of each version is displayed.
Mention whether you follow Semantic Versioning.
Usage:
Change log entries are to be added to the Unreleased section under the
appropriate stanza (see below). Each entry should ideally include a tag and
the Github issue reference in the following format:
* (<tag>) [#<issue-number>] Changelog message.
Types of changes (Stanzas):
"Features" for new features.
"Improvements" for changes in existing functionality.
"Deprecated" for soon-to-be removed features.
"Bug Fixes" for any bug fixes.
"API Breaking" for breaking exported APIs used by developers building on SDK.
Ref: https://keepachangelog.com/en/1.0.0/
-->
# Changelog
`SimApp` is an application built using the Cosmos SDK for testing and educational purposes.
It won't be tagged or intended to be imported in an application.
This changelog is aimed to help developers understand the wiring changes between SDK versions.
It is an exautive list of changes that completes the SimApp section in the [UPGRADING.md](https://github.com/cosmos/cosmos-sdk/blob/main/UPGRADING.md#simapp)
## v0.50 to v0.52
Always refer to the [UPGRADING.md](https://github.com/cosmos/cosmos-sdk/blob/main/UPGRADING.md) to understand the changes.
* Update module path to new vanity url.
* Wire new SDK modules (`epochs`, `accounts`, `protocolpool`).
* Remove the crisis module from simapp.
* Update `export` function to make use of the new module collections API.
* Add example of how to define a custom mint function in `simapp/mint_fn.go`.
* Add address codec in client context and signing context.
* Update testnet command to match new module APIs.
* [#20409](https://github.com/cosmos/cosmos-sdk/pull/20409) Add `tx` as `SkipStoreKeys` in `app_config.go`.
* [#20485](https://github.com/cosmos/cosmos-sdk/pull/20485) The signature of `x/upgrade/types.UpgradeHandler` has changed to accept `appmodule.VersionMap` from `module.VersionMap`. These types are interchangeable, but usages of `UpradeKeeper.SetUpgradeHandler` may need to adjust their usages to match the new signature.
* [#20740](https://github.com/cosmos/cosmos-sdk/pull/20740) Update `genutilcli.Commands` to use the genutil modules from the module manager.
* [#20771](https://github.com/cosmos/cosmos-sdk/pull/20771) Use client/v2 `GetNodeHomeDirectory` helper in `app.go` and use the `DefaultNodeHome` constant everywhere in the app.
* [#20490](https://github.com/cosmos/cosmos-sdk/pull/20490) Refactor simulations to make use of `testutil/sims` instead of `runsims`.
* [#19726](https://github.com/cosmos/cosmos-sdk/pull/19726) Update APIs to match CometBFT v1.
* [#21466](https://github.com/cosmos/cosmos-sdk/pull/21466) Allow chains to plug in their own public key types in `base.Account`
* [#21508](https://github.com/cosmos/cosmos-sdk/pull/21508) Abstract the way we update the version of the app state in `app.go` using the interface `VersionModifier`.
<!-- TODO: move changelog.md elements to here -->
## v0.47 to v0.50
No changelog is provided for this migration. Please refer to the [UPGRADING.md](https://github.com/cosmos/cosmos-sdk/blob/main/UPGRADING.md#v050x)
## v0.46 to v0.47
No changelog is provided for this migration. Please refer to the [UPGRADING.md](https://github.com/cosmos/cosmos-sdk/blob/main/UPGRADING.md#v047x)
## v0.45 to v0.46
No changelog is provided for this migration. Please refer to the [UPGRADING.md](https://github.com/cosmos/cosmos-sdk/blob/main/UPGRADING.md#v046x)

View File

@ -1,122 +0,0 @@
---
sidebar_position: 1
---
# `SimApp`
`SimApp` is a CLI application built using the Cosmos SDK for testing and educational purposes.
## Running testnets with `simd`
Except stated otherwise, all participants in the testnet must follow through with each step.
### 1. Download and Setup
Download the Cosmos SDK and unzip it. You can do this manually (via the GitHub UI) or with the git clone command.
```sh
git clone github.com/cosmos/cosmos-sdk.git
```
Next, run this command to build the `simd` binary in the `build` directory.
```sh
make build
```
Use the following command and skip all the next steps to configure your SimApp node:
```sh
make init-simapp
```
If youve run `simd` in the past, you may need to reset your database before starting up a new testnet. You can do that with this command:
```sh
# you need to provide the moniker and chain ID
$ ./simd init [moniker] --chain-id [chain-id]
```
The command should initialize a new working directory at the `~simapp` location.
The `moniker` and `chain-id` can be anything but you need to use the same `chain-id` subsequently.
### 2. Create a New Key
Execute this command to create a new key.
```sh
./simd keys add [key_name]
```
The command will create a new key with your chosen name.
⚠️ Save the output somewhere safe; youll need the address later.
### 3. Add Genesis Account
Add a genesis account to your testnet blockchain.
```sh
$ ./simd genesis add-genesis-account [key_name] [amount]
```
Where `key_name` is the same key name as before, and the `amount` is something like `10000000000000000000000000stake`.
### 4. Add the Genesis Transaction
This creates the genesis transaction for your testnet chain.
```sh
$ ./simd genesis gentx [key_name] [amount] --chain-id [chain-id]
```
The amount should be at least `1000000000stake`. When you start your node, providing too much or too little may result in errors.
### 5. Create the Genesis File
A participant must create the genesis file `genesis.json` with every participant's transaction.
You can do this by gathering all the Genesis transactions under `config/gentx` and then executing this command.
```sh
$ ./simd genesis collect-gentxs
```
The command will create a new `genesis.json` file that includes data from all the validators. The command will create a new `genesis.json` file, including data from all the validators
Once you've received the super genesis file, overwrite your original `genesis.json` file with
the new super `genesis.json`.
Modify your `config/config.toml` (in the simapp working directory) to include the other participants as
persistent peers:
```
# Comma-separated list of nodes to keep persistent connections to
persistent_peers = "[validator_address]@[ip_address]:[port],[validator_address]@[ip_address]:[port]"
```
You can find `validator_address` by executing:
```sh
$ ./simd comet show-node-id
```
The output will be the hex-encoded `validator_address`. The default `port` is 26656.
### 6. Start the Nodes
Finally, execute this command to start your nodes.
```sh
$ ./simd start
```
Now you have a small testnet that you can use to try out changes to the Cosmos SDK or CometBFT!
> ⚠️ NOTE: Sometimes, creating the network through the `collect-gents` will fail, and validators will start in a funny state (and then panic).
>
If this happens, you can try to create and start the network first
with a single validator and then add additional validators using a `create-validator` transaction.

View File

@ -1,84 +0,0 @@
package simapp
import (
"bytes"
"crypto/rand"
"encoding/json"
"fmt"
abci "github.com/cometbft/cometbft/api/cometbft/abci/v1"
"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
)
type (
// VoteExtensionHandler defines a dummy vote extension handler for SimApp.
//
// NOTE: This implementation is solely used for testing purposes. DO NOT use
// in a production application!
VoteExtensionHandler struct{}
// VoteExtension defines the structure used to create a dummy vote extension.
VoteExtension struct {
Hash []byte
Height int64
Data []byte
}
)
func NewVoteExtensionHandler() *VoteExtensionHandler {
return &VoteExtensionHandler{}
}
func (h *VoteExtensionHandler) SetHandlers(bApp *baseapp.BaseApp) {
bApp.SetExtendVoteHandler(h.ExtendVote())
bApp.SetVerifyVoteExtensionHandler(h.VerifyVoteExtension())
}
func (h *VoteExtensionHandler) ExtendVote() sdk.ExtendVoteHandler {
return func(_ sdk.Context, req *abci.ExtendVoteRequest) (*abci.ExtendVoteResponse, error) {
buf := make([]byte, 1024)
_, err := rand.Read(buf)
if err != nil {
return nil, fmt.Errorf("failed to generate random vote extension data: %w", err)
}
ve := VoteExtension{
Hash: req.Hash,
Height: req.Height,
Data: buf,
}
bz, err := json.Marshal(ve)
if err != nil {
return nil, fmt.Errorf("failed to encode vote extension: %w", err)
}
return &abci.ExtendVoteResponse{VoteExtension: bz}, nil
}
}
func (h *VoteExtensionHandler) VerifyVoteExtension() sdk.VerifyVoteExtensionHandler {
return func(ctx sdk.Context, req *abci.VerifyVoteExtensionRequest) (*abci.VerifyVoteExtensionResponse, error) {
var ve VoteExtension
if err := json.Unmarshal(req.VoteExtension, &ve); err != nil {
return &abci.VerifyVoteExtensionResponse{Status: abci.VERIFY_VOTE_EXTENSION_STATUS_REJECT}, nil
}
switch {
case req.Height != ve.Height:
return &abci.VerifyVoteExtensionResponse{Status: abci.VERIFY_VOTE_EXTENSION_STATUS_REJECT}, nil
case !bytes.Equal(req.Hash, ve.Hash):
return &abci.VerifyVoteExtensionResponse{Status: abci.VERIFY_VOTE_EXTENSION_STATUS_REJECT}, nil
case len(ve.Data) != 1024:
return &abci.VerifyVoteExtensionResponse{Status: abci.VERIFY_VOTE_EXTENSION_STATUS_REJECT}, nil
}
return &abci.VerifyVoteExtensionResponse{Status: abci.VERIFY_VOTE_EXTENSION_STATUS_ACCEPT}, nil
}
}

View File

@ -1,50 +0,0 @@
package simapp
import (
"errors"
circuitante "cosmossdk.io/x/circuit/ante"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/cosmos/cosmos-sdk/x/auth/ante/unorderedtx"
)
// HandlerOptions are the options required for constructing a default SDK AnteHandler.
type HandlerOptions struct {
ante.HandlerOptions
CircuitKeeper circuitante.CircuitBreaker
}
// NewAnteHandler returns an AnteHandler that checks and increments sequence
// numbers, checks signatures & account numbers, and deducts fees from the first
// signer.
func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
if options.AccountKeeper == nil {
return nil, errors.New("account keeper is required for ante builder")
}
if options.BankKeeper == nil {
return nil, errors.New("bank keeper is required for ante builder")
}
if options.SignModeHandler == nil {
return nil, errors.New("sign mode handler is required for ante builder")
}
anteDecorators := []sdk.AnteDecorator{
ante.NewSetUpContextDecorator(options.Environment, options.ConsensusKeeper), // outermost AnteDecorator. SetUpContext must be called first
circuitante.NewCircuitBreakerDecorator(options.CircuitKeeper),
ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker),
ante.NewValidateBasicDecorator(options.Environment),
ante.NewTxTimeoutHeightDecorator(options.Environment),
ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, options.UnorderedTxManager, options.Environment, ante.DefaultSha256Cost),
ante.NewValidateMemoDecorator(options.AccountKeeper),
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker),
ante.NewValidateSigCountDecorator(options.AccountKeeper),
ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler, options.SigGasConsumer, options.AccountAbstractionKeeper),
}
return sdk.ChainAnteDecorators(anteDecorators...), nil
}

View File

@ -1,403 +0,0 @@
package simapp
import (
_ "embed"
"fmt"
"io"
_ "github.com/jackc/pgx/v5/stdlib" // Import and register pgx driver
clienthelpers "cosmossdk.io/client/v2/helpers"
"cosmossdk.io/core/address"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/registry"
corestore "cosmossdk.io/core/store"
"cosmossdk.io/depinject"
"cosmossdk.io/depinject/appconfig"
_ "cosmossdk.io/indexer/postgres" // register the postgres indexer
"cosmossdk.io/log"
"cosmossdk.io/x/accounts"
basedepinject "cosmossdk.io/x/accounts/defaults/base/depinject"
lockupdepinject "cosmossdk.io/x/accounts/defaults/lockup/depinject"
multisigdepinject "cosmossdk.io/x/accounts/defaults/multisig/depinject"
"cosmossdk.io/x/accounts/testing/account_abstraction"
"cosmossdk.io/x/accounts/testing/counter"
bankkeeper "cosmossdk.io/x/bank/keeper"
circuitkeeper "cosmossdk.io/x/circuit/keeper"
consensuskeeper "cosmossdk.io/x/consensus/keeper"
distrkeeper "cosmossdk.io/x/distribution/keeper"
feegrantkeeper "cosmossdk.io/x/feegrant/keeper"
_ "cosmossdk.io/x/protocolpool"
slashingkeeper "cosmossdk.io/x/slashing/keeper"
stakingkeeper "cosmossdk.io/x/staking/keeper"
upgradekeeper "cosmossdk.io/x/upgrade/keeper"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/server/api"
"github.com/cosmos/cosmos-sdk/server/config"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
testdata_pulsar "github.com/cosmos/cosmos-sdk/testutil/testdata/testpb"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/cosmos/cosmos-sdk/x/auth/ante/unorderedtx"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
// DefaultNodeHome default home directories for the application daemon
var DefaultNodeHome string
var (
_ runtime.AppI = (*SimApp)(nil)
_ servertypes.Application = (*SimApp)(nil)
)
// SimApp extends an ABCI application, but with most of its parameters exported.
// They are exported for convenience in creating helper functions, as object
// capabilities aren't needed for testing.
type SimApp struct {
*runtime.App
legacyAmino registry.AminoRegistrar
appCodec codec.Codec
txConfig client.TxConfig
interfaceRegistry codectypes.InterfaceRegistry
// required keepers during wiring
// others keepers are all in the app
AccountsKeeper accounts.Keeper
AuthKeeper authkeeper.AccountKeeper
BankKeeper bankkeeper.Keeper
StakingKeeper *stakingkeeper.Keeper
SlashingKeeper slashingkeeper.Keeper
DistrKeeper distrkeeper.Keeper
UpgradeKeeper *upgradekeeper.Keeper
FeeGrantKeeper feegrantkeeper.Keeper
ConsensusParamsKeeper consensuskeeper.Keeper
CircuitBreakerKeeper circuitkeeper.Keeper
// simulation manager
sm *module.SimulationManager
}
func init() {
var err error
DefaultNodeHome, err = clienthelpers.GetNodeHomeDirectory(".simapp")
if err != nil {
panic(err)
}
}
// AppConfig returns the default app config.
func AppConfig() depinject.Config {
return depinject.Configs(
appconfig.Compose(appConfig), // Alternatively use appconfig.LoadYAML(AppConfigYAML)
depinject.Provide(
ProvideExampleMintFn, // optional: override the mint module's mint function with epoched minting
),
)
}
// NewSimApp returns a reference to an initialized SimApp.
func NewSimApp(
logger log.Logger,
db corestore.KVStoreWithBatch,
traceStore io.Writer,
loadLatest bool,
appOpts servertypes.AppOptions,
baseAppOptions ...func(*baseapp.BaseApp),
) *SimApp {
var (
app = &SimApp{}
appBuilder *runtime.AppBuilder
// merge the AppConfig and other configuration in one config
appConfig = depinject.Configs(
AppConfig(),
depinject.Supply(
// supply the application options
appOpts,
// supply the logger
logger,
// ADVANCED CONFIGURATION
//
// AUTH
//
// For providing a custom function required in auth to generate custom account types
// add it below. By default the auth module uses simulation.RandomGenesisAccounts.
//
// authtypes.RandomGenesisAccountsFn(simulation.RandomGenesisAccounts),
//
// For providing a custom a base account type add it below.
// By default the auth module uses authtypes.ProtoBaseAccount().
//
// func() sdk.AccountI { return authtypes.ProtoBaseAccount() },
//
// For providing a different address codec, add it below.
// By default the auth module uses a Bech32 address codec,
// with the prefix defined in the auth module configuration.
//
// func() address.Codec { return <- custom address codec type -> }
//
// STAKING
//
// For provinding a different validator and consensus address codec, add it below.
// By default the staking module uses the bech32 prefix provided in the auth config,
// and appends "valoper" and "valcons" for validator and consensus addresses respectively.
// When providing a custom address codec in auth, custom address codecs must be provided here as well.
//
// func() runtime.ValidatorAddressCodec { return <- custom validator address codec type -> }
// func() runtime.ConsensusAddressCodec { return <- custom consensus address codec type -> }
//
// MINT
//
// For providing a custom inflation function for x/mint add here your
// custom function that implements the minttypes.MintFn interface.
),
depinject.Provide(
// inject desired account types:
multisigdepinject.ProvideAccount,
basedepinject.ProvideAccount,
lockupdepinject.ProvideAllLockupAccounts,
// provide base account options
basedepinject.ProvideSecp256K1PubKey,
// if you want to provide a custom public key you
// can do it from here.
// Example:
// basedepinject.ProvideCustomPubkey[Ed25519PublicKey]()
//
// You can also provide a custom public key with a custom validation function:
//
// basedepinject.ProvideCustomPubKeyAndValidationFunc(func(pub Ed25519PublicKey) error {
// if len(pub.Key) != 64 {
// return fmt.Errorf("invalid pub key size")
// }
// })
// TESTING: do not add below account types
counter.ProvideAccount,
account_abstraction.ProvideAccount,
),
)
)
var appModules map[string]appmodule.AppModule
if err := depinject.Inject(appConfig,
&appBuilder,
&appModules,
&app.appCodec,
&app.legacyAmino,
&app.txConfig,
&app.interfaceRegistry,
&app.AuthKeeper,
&app.AccountsKeeper,
&app.BankKeeper,
&app.StakingKeeper,
&app.SlashingKeeper,
&app.DistrKeeper,
&app.UpgradeKeeper,
&app.FeeGrantKeeper,
&app.ConsensusParamsKeeper,
&app.CircuitBreakerKeeper,
); err != nil {
panic(err)
}
// Below we could construct and set an application specific mempool and
// ABCI 1.0 PrepareProposal and ProcessProposal handlers. These defaults are
// already set in the SDK's BaseApp, this shows an example of how to override
// them.
//
// Example:
//
// app.App = appBuilder.Build(...)
// nonceMempool := mempool.NewSenderNonceMempool()
// abciPropHandler := NewDefaultProposalHandler(nonceMempool, app.App.BaseApp)
//
// app.App.BaseApp.SetMempool(nonceMempool)
// app.App.BaseApp.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())
// app.App.BaseApp.SetProcessProposal(abciPropHandler.ProcessProposalHandler())
//
// Alternatively, you can construct BaseApp options, append those to
// baseAppOptions and pass them to the appBuilder.
//
// Example:
//
// prepareOpt = func(app *baseapp.BaseApp) {
// abciPropHandler := baseapp.NewDefaultProposalHandler(nonceMempool, app)
// app.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())
// }
// baseAppOptions = append(baseAppOptions, prepareOpt)
// create and set dummy vote extension handler
voteExtOp := func(bApp *baseapp.BaseApp) {
voteExtHandler := NewVoteExtensionHandler()
voteExtHandler.SetHandlers(bApp)
}
baseAppOptions = append(baseAppOptions, voteExtOp, baseapp.SetOptimisticExecution())
app.App = appBuilder.Build(db, traceStore, baseAppOptions...)
/**** Module Options ****/
// RegisterUpgradeHandlers is used for registering any on-chain upgrades.
app.RegisterUpgradeHandlers()
// add test gRPC service for testing gRPC queries in isolation
testdata_pulsar.RegisterQueryServer(app.GRPCQueryRouter(), testdata_pulsar.QueryImpl{})
// 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
overrideModules := map[string]module.AppModuleSimulation{
authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AuthKeeper, &app.AccountsKeeper, authsims.RandomGenesisAccounts, nil),
}
app.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, overrideModules)
app.sm.RegisterStoreDecoders()
// A custom InitChainer can be set if extra pre-init-genesis logic is required.
// By default, when using app wiring enabled module, this is not required.
// For instance, the upgrade module will set automatically the module version map in its init genesis thanks to app wiring.
// However, when registering a module manually (i.e. that does not support app wiring), the module version map
// must be set manually as follow. The upgrade module will de-duplicate the module version map.
//
// app.SetInitChainer(func(ctx sdk.Context, req *abci.InitChainRequest) (*abci.InitChainResponse, error) {
// app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap())
// return app.App.InitChainer(ctx, req)
// })
// register custom snapshot extensions (if any)
if manager := app.SnapshotManager(); manager != nil {
if err := manager.RegisterExtensions(
unorderedtx.NewSnapshotter(app.UnorderedTxManager),
); err != nil {
panic(fmt.Errorf("failed to register snapshot extension: %w", err))
}
}
// set custom ante handlers
app.setCustomAnteHandler()
if err := app.Load(loadLatest); err != nil {
panic(err)
}
return app
}
// setCustomAnteHandler overwrites default ante handlers with custom ante handlers
// set SkipAnteHandler to true in app config and set custom ante handler on baseapp
func (app *SimApp) setCustomAnteHandler() {
anteHandler, err := NewAnteHandler(
HandlerOptions{
ante.HandlerOptions{
AccountKeeper: app.AuthKeeper,
BankKeeper: app.BankKeeper,
ConsensusKeeper: app.ConsensusParamsKeeper,
SignModeHandler: app.txConfig.SignModeHandler(),
FeegrantKeeper: app.FeeGrantKeeper,
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
UnorderedTxManager: app.UnorderedTxManager,
Environment: app.AuthKeeper.Environment,
AccountAbstractionKeeper: app.AccountsKeeper,
},
&app.CircuitBreakerKeeper,
},
)
if err != nil {
panic(err)
}
// Set the AnteHandler for the app
app.SetAnteHandler(anteHandler)
}
// LegacyAmino returns SimApp's amino codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.
func (app *SimApp) LegacyAmino() *codec.LegacyAmino {
switch cdc := app.legacyAmino.(type) {
case *codec.LegacyAmino:
return cdc
default:
panic("unexpected codec type")
}
}
// AppCodec returns SimApp's app codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.
func (app *SimApp) AppCodec() codec.Codec {
return app.appCodec
}
// InterfaceRegistry returns SimApp's InterfaceRegistry.
func (app *SimApp) InterfaceRegistry() codectypes.InterfaceRegistry {
return app.interfaceRegistry
}
// TxConfig returns SimApp's TxConfig
func (app *SimApp) TxConfig() client.TxConfig {
return app.txConfig
}
// SimulationManager implements the SimulationApp interface
func (app *SimApp) SimulationManager() *module.SimulationManager {
return app.sm
}
// RegisterAPIRoutes registers all application module routes with the provided
// API server.
func (app *SimApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
app.App.RegisterAPIRoutes(apiSvr, apiConfig)
// register swagger API in app.go so that other applications can override easily
if err := server.RegisterSwaggerAPI(apiSvr.ClientCtx, apiSvr.Router, apiConfig.Swagger); err != nil {
panic(err)
}
}
// GetMaccPerms returns a copy of the module account permissions
//
// NOTE: This is solely to be used for testing purposes.
func GetMaccPerms() map[string][]string {
dup := make(map[string][]string)
for _, perms := range moduleAccPerms {
dup[perms.Account] = perms.Permissions
}
return dup
}
// BlockedAddresses returns all the app's blocked account addresses.
// This function takes an address.Codec parameter to maintain compatibility
// with the signature of the same function in appV1.
func BlockedAddresses(_ address.Codec) (map[string]bool, error) {
result := make(map[string]bool)
if len(blockAccAddrs) > 0 {
for _, addr := range blockAccAddrs {
result[addr] = true
}
} else {
for addr := range GetMaccPerms() {
result[addr] = true
}
}
return result, nil
}

View File

@ -1,301 +0,0 @@
//nolint:unused,nolintlint // ignore unused code linting
package simapp
import (
"time"
"google.golang.org/protobuf/types/known/durationpb"
accountsmodulev1 "cosmossdk.io/api/cosmos/accounts/module/v1"
runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1"
authzmodulev1 "cosmossdk.io/api/cosmos/authz/module/v1"
bankmodulev1 "cosmossdk.io/api/cosmos/bank/module/v1"
circuitmodulev1 "cosmossdk.io/api/cosmos/circuit/module/v1"
consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1"
epochsmodulev1 "cosmossdk.io/api/cosmos/epochs/module/v1"
evidencemodulev1 "cosmossdk.io/api/cosmos/evidence/module/v1"
feegrantmodulev1 "cosmossdk.io/api/cosmos/feegrant/module/v1"
genutilmodulev1 "cosmossdk.io/api/cosmos/genutil/module/v1"
govmodulev1 "cosmossdk.io/api/cosmos/gov/module/v1"
groupmodulev1 "cosmossdk.io/api/cosmos/group/module/v1"
mintmodulev1 "cosmossdk.io/api/cosmos/mint/module/v1"
nftmodulev1 "cosmossdk.io/api/cosmos/nft/module/v1"
poolmodulev1 "cosmossdk.io/api/cosmos/protocolpool/module/v1"
slashingmodulev1 "cosmossdk.io/api/cosmos/slashing/module/v1"
stakingmodulev1 "cosmossdk.io/api/cosmos/staking/module/v1"
txconfigv1 "cosmossdk.io/api/cosmos/tx/config/v1"
upgrademodulev1 "cosmossdk.io/api/cosmos/upgrade/module/v1"
validatemodulev1 "cosmossdk.io/api/cosmos/validate/module/v1"
vestingmodulev1 "cosmossdk.io/api/cosmos/vesting/module/v1"
"cosmossdk.io/depinject/appconfig"
"cosmossdk.io/x/accounts"
"cosmossdk.io/x/authz"
_ "cosmossdk.io/x/authz/module" // import for side-effects
_ "cosmossdk.io/x/bank" // import for side-effects
banktypes "cosmossdk.io/x/bank/types"
_ "cosmossdk.io/x/bank/v2" // import for side-effects
bankv2types "cosmossdk.io/x/bank/v2/types"
bankmodulev2 "cosmossdk.io/x/bank/v2/types/module"
_ "cosmossdk.io/x/circuit" // import for side-effects
circuittypes "cosmossdk.io/x/circuit/types"
_ "cosmossdk.io/x/consensus" // import for side-effects
consensustypes "cosmossdk.io/x/consensus/types"
_ "cosmossdk.io/x/distribution" // import for side-effects
distrtypes "cosmossdk.io/x/distribution/types"
_ "cosmossdk.io/x/epochs" // import for side-effects
epochstypes "cosmossdk.io/x/epochs/types"
_ "cosmossdk.io/x/evidence" // import for side-effects
evidencetypes "cosmossdk.io/x/evidence/types"
"cosmossdk.io/x/feegrant"
_ "cosmossdk.io/x/feegrant/module" // import for side-effects
_ "cosmossdk.io/x/gov" // import for side-effects
govtypes "cosmossdk.io/x/gov/types"
"cosmossdk.io/x/group"
_ "cosmossdk.io/x/group/module" // import for side-effects
_ "cosmossdk.io/x/mint" // import for side-effects
minttypes "cosmossdk.io/x/mint/types"
"cosmossdk.io/x/nft"
_ "cosmossdk.io/x/nft/module" // import for side-effects
_ "cosmossdk.io/x/protocolpool" // import for side-effects
pooltypes "cosmossdk.io/x/protocolpool/types"
_ "cosmossdk.io/x/slashing" // import for side-effects
slashingtypes "cosmossdk.io/x/slashing/types"
_ "cosmossdk.io/x/staking" // import for side-effects
stakingtypes "cosmossdk.io/x/staking/types"
_ "cosmossdk.io/x/upgrade" // import for side-effects
upgradetypes "cosmossdk.io/x/upgrade/types"
"github.com/cosmos/cosmos-sdk/runtime"
_ "github.com/cosmos/cosmos-sdk/testutil/x/counter" // import for side-effects
authtxconfig "github.com/cosmos/cosmos-sdk/x/auth/tx/config"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
_ "github.com/cosmos/cosmos-sdk/x/auth/vesting" // import for side-effects
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/cosmos/cosmos-sdk/x/validate"
)
var (
// module account permissions
moduleAccPerms = []*authmodulev1.ModuleAccountPermission{
{Account: authtypes.FeeCollectorName},
{Account: distrtypes.ModuleName},
{Account: pooltypes.ModuleName},
{Account: pooltypes.StreamAccount},
{Account: pooltypes.ProtocolPoolDistrAccount},
{Account: minttypes.ModuleName, Permissions: []string{authtypes.Minter}},
{Account: stakingtypes.BondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}},
{Account: stakingtypes.NotBondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}},
{Account: govtypes.ModuleName, Permissions: []string{authtypes.Burner}},
{Account: nft.ModuleName},
}
// blocked account addresses
blockAccAddrs = []string{
authtypes.FeeCollectorName,
distrtypes.ModuleName,
minttypes.ModuleName,
stakingtypes.BondedPoolName,
stakingtypes.NotBondedPoolName,
nft.ModuleName,
// We allow the following module accounts to receive funds:
// govtypes.ModuleName
// pooltypes.ModuleName
}
// application configuration (used by depinject)
appConfig = &appv1alpha1.Config{
Modules: []*appv1alpha1.ModuleConfig{
{
Name: runtime.ModuleName,
Config: appconfig.WrapAny(&runtimev1alpha1.Module{
AppName: "SimApp",
// NOTE: upgrade module is required to be prioritized
PreBlockers: []string{
upgradetypes.ModuleName,
},
// During begin block slashing happens after distr.BeginBlocker so that
// there is nothing left over in the validator fee pool, so as to keep the
// CanWithdrawInvariant invariant.
// NOTE: staking module is required if HistoricalEntries param > 0
BeginBlockers: []string{
minttypes.ModuleName,
distrtypes.ModuleName,
pooltypes.ModuleName,
slashingtypes.ModuleName,
evidencetypes.ModuleName,
stakingtypes.ModuleName,
authz.ModuleName,
epochstypes.ModuleName,
},
EndBlockers: []string{
govtypes.ModuleName,
stakingtypes.ModuleName,
feegrant.ModuleName,
group.ModuleName,
pooltypes.ModuleName,
},
// The following is mostly only needed when ModuleName != StoreKey name.
OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{
{
ModuleName: authtypes.ModuleName,
KvStoreKey: "acc",
},
{
ModuleName: accounts.ModuleName,
KvStoreKey: accounts.StoreKey,
},
},
// NOTE: The genutils module must occur after staking so that pools are
// properly initialized with tokens from genesis accounts.
// NOTE: The genutils module must also occur after auth so that it can access the params from auth.
InitGenesis: []string{
consensustypes.ModuleName,
accounts.ModuleName,
authtypes.ModuleName,
banktypes.ModuleName,
bankv2types.ModuleName,
distrtypes.ModuleName,
stakingtypes.ModuleName,
slashingtypes.ModuleName,
govtypes.ModuleName,
minttypes.ModuleName,
genutiltypes.ModuleName,
evidencetypes.ModuleName,
authz.ModuleName,
feegrant.ModuleName,
nft.ModuleName,
group.ModuleName,
upgradetypes.ModuleName,
vestingtypes.ModuleName,
circuittypes.ModuleName,
pooltypes.ModuleName,
epochstypes.ModuleName,
},
// When ExportGenesis is not specified, the export genesis module order
// is equal to the init genesis order
// ExportGenesis: []string{},
// Uncomment if you want to set a custom migration order here.
// OrderMigrations: []string{},
// SkipStoreKeys is an optional list of store keys to skip when constructing the
// module's keeper. This is useful when a module does not have a store key.
SkipStoreKeys: []string{
authtxconfig.DepinjectModuleName,
validate.ModuleName,
},
}),
},
{
Name: authtxconfig.DepinjectModuleName, // x/auth/tx/config depinject module (not app module), use to provide tx configuration
Config: appconfig.WrapAny(&txconfigv1.Config{}),
},
{
Name: validate.ModuleName,
Config: appconfig.WrapAny(&validatemodulev1.Module{}),
},
{
Name: authtypes.ModuleName,
Config: appconfig.WrapAny(&authmodulev1.Module{
Bech32Prefix: "cosmos",
ModuleAccountPermissions: moduleAccPerms,
// By default modules authority is the governance module. This is configurable with the following:
// Authority: "group", // A custom module authority can be set using a module name
// Authority: "cosmos1cwwv22j5ca08ggdv9c2uky355k908694z577tv", // or a specific address
}),
},
{
Name: vestingtypes.ModuleName,
Config: appconfig.WrapAny(&vestingmodulev1.Module{}),
},
{
Name: banktypes.ModuleName,
Config: appconfig.WrapAny(&bankmodulev1.Module{
BlockedModuleAccountsOverride: blockAccAddrs,
}),
},
{
Name: stakingtypes.ModuleName,
Config: appconfig.WrapAny(&stakingmodulev1.Module{
// NOTE: specifying a prefix is only necessary when using bech32 addresses
// If not specified, the auth Bech32Prefix appended with "valoper" and "valcons" is used by default
Bech32PrefixValidator: "cosmosvaloper",
Bech32PrefixConsensus: "cosmosvalcons",
}),
},
{
Name: slashingtypes.ModuleName,
Config: appconfig.WrapAny(&slashingmodulev1.Module{}),
},
{
Name: genutiltypes.ModuleName,
Config: appconfig.WrapAny(&genutilmodulev1.Module{}),
},
{
Name: authz.ModuleName,
Config: appconfig.WrapAny(&authzmodulev1.Module{}),
},
{
Name: upgradetypes.ModuleName,
Config: appconfig.WrapAny(&upgrademodulev1.Module{}),
},
{
Name: distrtypes.ModuleName,
Config: appconfig.WrapAny(&distrmodulev1.Module{}),
},
{
Name: evidencetypes.ModuleName,
Config: appconfig.WrapAny(&evidencemodulev1.Module{}),
},
{
Name: minttypes.ModuleName,
Config: appconfig.WrapAny(&mintmodulev1.Module{}),
},
{
Name: group.ModuleName,
Config: appconfig.WrapAny(&groupmodulev1.Module{
MaxExecutionPeriod: durationpb.New(time.Second * 1209600),
MaxMetadataLen: 255,
}),
},
{
Name: nft.ModuleName,
Config: appconfig.WrapAny(&nftmodulev1.Module{}),
},
{
Name: feegrant.ModuleName,
Config: appconfig.WrapAny(&feegrantmodulev1.Module{}),
},
{
Name: govtypes.ModuleName,
Config: appconfig.WrapAny(&govmodulev1.Module{}),
},
{
Name: consensustypes.ModuleName,
Config: appconfig.WrapAny(&consensusmodulev1.Module{}),
},
{
Name: circuittypes.ModuleName,
Config: appconfig.WrapAny(&circuitmodulev1.Module{}),
},
{
Name: pooltypes.ModuleName,
Config: appconfig.WrapAny(&poolmodulev1.Module{}),
},
{
Name: accounts.ModuleName,
Config: appconfig.WrapAny(&accountsmodulev1.Module{}),
},
{
Name: epochstypes.ModuleName,
Config: appconfig.WrapAny(&epochsmodulev1.Module{}),
},
{
Name: bankv2types.ModuleName,
Config: appconfig.WrapAny(&bankmodulev2.Module{}),
},
},
}
)

View File

@ -1,315 +0,0 @@
package simapp
import (
"encoding/json"
"fmt"
"testing"
abci "github.com/cometbft/cometbft/api/cometbft/abci/v1"
cmtproto "github.com/cometbft/cometbft/api/cometbft/types/v1"
"github.com/cosmos/gogoproto/proto"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
"google.golang.org/grpc"
"cosmossdk.io/core/appmodule"
coretesting "cosmossdk.io/core/testing"
"cosmossdk.io/log"
"cosmossdk.io/x/accounts"
authzmodule "cosmossdk.io/x/authz/module"
"cosmossdk.io/x/bank"
banktypes "cosmossdk.io/x/bank/types"
bankv2 "cosmossdk.io/x/bank/v2"
"cosmossdk.io/x/distribution"
"cosmossdk.io/x/epochs"
"cosmossdk.io/x/evidence"
feegrantmodule "cosmossdk.io/x/feegrant/module"
"cosmossdk.io/x/gov"
group "cosmossdk.io/x/group/module"
"cosmossdk.io/x/mint"
"cosmossdk.io/x/protocolpool"
"cosmossdk.io/x/slashing"
"cosmossdk.io/x/staking"
"cosmossdk.io/x/upgrade"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/testutil/mock"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/types/msgservice"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
"github.com/cosmos/cosmos-sdk/x/genutil"
)
func TestSimAppExportAndBlockedAddrs(t *testing.T) {
db := coretesting.NewMemDB()
logger := log.NewTestLogger(t)
app := NewSimappWithCustomOptions(t, false, SetupOptions{
Logger: logger.With("instance", "first"),
DB: db,
AppOpts: simtestutil.NewAppOptionsWithFlagHome(t.TempDir()),
})
// BlockedAddresses returns a map of addresses in app v1 and a map of modules names in app di.
blockedAddrs, err := BlockedAddresses(app.interfaceRegistry.SigningContext().AddressCodec())
require.NoError(t, err)
for acc := range blockedAddrs {
var addr sdk.AccAddress
if modAddr, err := app.InterfaceRegistry().SigningContext().AddressCodec().StringToBytes(acc); err == nil {
addr = modAddr
} else {
addr = app.AuthKeeper.GetModuleAddress(acc)
}
require.True(
t,
app.BankKeeper.BlockedAddr(addr),
fmt.Sprintf("ensure that blocked addresses are properly set in bank keeper: %s should be blocked", acc),
)
}
// finalize block so we have CheckTx state set
_, err = app.FinalizeBlock(&abci.FinalizeBlockRequest{
Height: 1,
})
require.NoError(t, err)
_, err = app.Commit()
require.NoError(t, err)
// Making a new app object with the db, so that initchain hasn't been called
app2 := NewSimApp(logger.With("instance", "second"), db, nil, true, simtestutil.NewAppOptionsWithFlagHome(t.TempDir()))
_, err = app2.ExportAppStateAndValidators(false, []string{}, []string{})
require.NoError(t, err, "ExportAppStateAndValidators should not have an error")
}
func TestRunMigrations(t *testing.T) {
db := coretesting.NewMemDB()
logger := log.NewTestLogger(t)
app := NewSimApp(logger.With("instance", "simapp"), db, nil, true, simtestutil.NewAppOptionsWithFlagHome(t.TempDir()))
// Create a new baseapp and configurator for the purpose of this test.
bApp := baseapp.NewBaseApp(app.Name(), logger.With("instance", "baseapp"), db, app.TxConfig().TxDecoder())
bApp.SetCommitMultiStoreTracer(nil)
bApp.SetInterfaceRegistry(app.InterfaceRegistry())
app.BaseApp = bApp
configurator := module.NewConfigurator(app.appCodec, bApp.MsgServiceRouter(), app.GRPCQueryRouter())
// We register all modules on the Configurator, except x/bank. x/bank will
// serve as the test subject on which we run the migration tests.
//
// The loop below is the same as calling `RegisterServices` on
// ModuleManager, except that we skip x/bank.
for name, mod := range app.ModuleManager.Modules {
if name == banktypes.ModuleName {
continue
}
if mod, ok := mod.(module.HasServices); ok {
mod.RegisterServices(configurator)
}
if mod, ok := mod.(interface {
RegisterServices(grpc.ServiceRegistrar) error
}); ok {
err := mod.RegisterServices(configurator)
require.NoError(t, err)
}
require.NoError(t, configurator.Error())
}
// Initialize the chain
_, err := app.InitChain(&abci.InitChainRequest{})
require.NoError(t, err)
_, err = app.Commit()
require.NoError(t, err)
testCases := []struct {
name string
moduleName string
fromVersion uint64
toVersion uint64
expRegErr bool // errors while registering migration
expRegErrMsg string
expRunErr bool // errors while running migration
expRunErrMsg string
expCalled int
}{
{
"cannot register migration for version 0",
"bank", 0, 1,
true, "module migration versions should start at 1: invalid version", false, "", 0,
},
{
"throws error on RunMigrations if no migration registered for bank",
"", 1, 2,
false, "", true, "no migrations found for module bank: not found", 0,
},
{
"can register 1->2 migration handler for x/bank, cannot run migration",
"bank", 1, 2,
false, "", true, "no migration found for module bank from version 2 to version 3: not found", 0,
},
{
"can register 2->3 migration handler for x/bank, can run migration",
"bank", 2, bank.AppModule{}.ConsensusVersion(),
false, "", false, "", int(bank.AppModule{}.ConsensusVersion() - 2), // minus 2 because 1-2 is run in the previous test case.
},
{
"cannot register migration handler for same module & fromVersion",
"bank", 1, 2,
true, "another migration for module bank and version 1 already exists: internal logic error", false, "", 0,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(tt *testing.T) {
var err error
// Since it's very hard to test actual in-place store migrations in
// tests (due to the difficulty of maintaining multiple versions of a
// module), we're just testing here that the migration logic is
// called.
called := 0
if tc.moduleName != "" {
for i := tc.fromVersion; i < tc.toVersion; i++ {
// Register migration for module from version `fromVersion` to `fromVersion+1`.
tt.Logf("Registering migration for %q v%d", tc.moduleName, i)
err = configurator.RegisterMigration(tc.moduleName, i, func(sdk.Context) error {
called++
return nil
})
if tc.expRegErr {
require.EqualError(tt, err, tc.expRegErrMsg)
return
}
require.NoError(tt, err, "registering migration")
}
}
orderMigrations := module.DefaultMigrationsOrder(app.ModuleManager.ModuleNames())
// Filter out benchmark module from migrations list
filteredMigrations := make([]string, 0, len(app.ModuleManager.OrderMigrations))
for _, name := range orderMigrations {
if name != "benchmark" {
filteredMigrations = append(filteredMigrations, name)
}
}
app.ModuleManager.OrderMigrations = filteredMigrations
// Run migrations only for bank. That's why we put the initial
// version for bank as 1, and for all other modules, we put as
// their latest ConsensusVersion.
_, err = app.ModuleManager.RunMigrations(
app.NewContextLegacy(true, cmtproto.Header{Height: app.LastBlockHeight()}), configurator,
appmodule.VersionMap{
"accounts": accounts.AppModule{}.ConsensusVersion(),
"bank": 1,
"bankv2": bankv2.AppModule{}.ConsensusVersion(),
"auth": auth.AppModule{}.ConsensusVersion(),
"authz": authzmodule.AppModule{}.ConsensusVersion(),
"staking": staking.AppModule{}.ConsensusVersion(),
"mint": mint.AppModule{}.ConsensusVersion(),
"distribution": distribution.AppModule{}.ConsensusVersion(),
"slashing": slashing.AppModule{}.ConsensusVersion(),
"gov": gov.AppModule{}.ConsensusVersion(),
"group": group.AppModule{}.ConsensusVersion(),
"upgrade": upgrade.AppModule{}.ConsensusVersion(),
"vesting": vesting.AppModule{}.ConsensusVersion(),
"feegrant": feegrantmodule.AppModule{}.ConsensusVersion(),
"evidence": evidence.AppModule{}.ConsensusVersion(),
"genutil": genutil.AppModule{}.ConsensusVersion(),
"protocolpool": protocolpool.AppModule{}.ConsensusVersion(),
"epochs": epochs.AppModule{}.ConsensusVersion(),
},
)
if tc.expRunErr {
require.EqualError(tt, err, tc.expRunErrMsg, "running migration")
} else {
require.NoError(tt, err, "running migration")
// Make sure bank's migration is called.
require.Equal(tt, tc.expCalled, called)
}
})
}
}
func TestInitGenesisOnMigration(t *testing.T) {
db := coretesting.NewMemDB()
app := NewSimApp(log.NewTestLogger(t), db, nil, true, simtestutil.NewAppOptionsWithFlagHome(t.TempDir()))
ctx := app.NewContextLegacy(true, cmtproto.Header{Height: app.LastBlockHeight()})
// Create a mock module. This module will serve as the new module we're
// adding during a migration.
mockCtrl := gomock.NewController(t)
t.Cleanup(mockCtrl.Finish)
mockModule := mock.NewMockAppModuleWithAllExtensions(mockCtrl)
mockDefaultGenesis := json.RawMessage(`{"key": "value"}`)
mockModule.EXPECT().DefaultGenesis().Times(1).Return(mockDefaultGenesis)
mockModule.EXPECT().InitGenesis(gomock.Eq(ctx), gomock.Eq(mockDefaultGenesis)).Times(1)
mockModule.EXPECT().ConsensusVersion().Times(1).Return(uint64(0))
app.ModuleManager.Modules["mock"] = mockModule
// Run migrations only for "mock" module. We exclude it from
// the VersionMap to simulate upgrading with a new module.
_, err := app.ModuleManager.RunMigrations(ctx, app.Configurator(),
appmodule.VersionMap{
"bank": bank.AppModule{}.ConsensusVersion(),
"auth": auth.AppModule{}.ConsensusVersion(),
"authz": authzmodule.AppModule{}.ConsensusVersion(),
"staking": staking.AppModule{}.ConsensusVersion(),
"mint": mint.AppModule{}.ConsensusVersion(),
"distribution": distribution.AppModule{}.ConsensusVersion(),
"slashing": slashing.AppModule{}.ConsensusVersion(),
"gov": gov.AppModule{}.ConsensusVersion(),
"upgrade": upgrade.AppModule{}.ConsensusVersion(),
"vesting": vesting.AppModule{}.ConsensusVersion(),
"feegrant": feegrantmodule.AppModule{}.ConsensusVersion(),
"evidence": evidence.AppModule{}.ConsensusVersion(),
"genutil": genutil.AppModule{}.ConsensusVersion(),
},
)
require.NoError(t, err)
}
func TestUpgradeStateOnGenesis(t *testing.T) {
db := coretesting.NewMemDB()
app := NewSimappWithCustomOptions(t, false, SetupOptions{
Logger: log.NewTestLogger(t),
DB: db,
AppOpts: simtestutil.NewAppOptionsWithFlagHome(t.TempDir()),
})
// make sure the upgrade keeper has version map in state
ctx := app.NewContext(false)
vm, err := app.UpgradeKeeper.GetModuleVersionMap(ctx)
require.NoError(t, err)
for v, i := range app.ModuleManager.Modules {
if i, ok := i.(appmodule.HasConsensusVersion); ok {
require.Equal(t, vm[v], i.ConsensusVersion())
}
}
}
// TestMergedRegistry tests that fetching the gogo/protov2 merged registry
// doesn't fail after loading all file descriptors.
func TestMergedRegistry(t *testing.T) {
r, err := proto.MergedRegistry()
require.NoError(t, err)
require.Greater(t, r.NumFiles(), 0)
}
func TestProtoAnnotations(t *testing.T) {
r, err := proto.MergedRegistry()
require.NoError(t, err)
err = msgservice.ValidateProtoAnnotations(r)
require.NoError(t, err)
}

View File

@ -1,39 +0,0 @@
//go:build benchmark
package simapp
import (
runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
benchmarkmodulev1 "cosmossdk.io/api/cosmos/benchmark/module/v1"
"cosmossdk.io/depinject/appconfig"
benchmark "cosmossdk.io/tools/benchmark/module"
"fmt"
)
func init() {
// WARNING!
// Enabling this module will produce 3M keys in the genesis state for the benchmark module.
// Will also enable processing of benchmark transactions which can easily overwhelm the system.
appConfig.Modules = append(appConfig.Modules, &appv1alpha1.ModuleConfig{
Name: benchmark.ModuleName,
Config: appconfig.WrapAny(&benchmarkmodulev1.Module{
GenesisParams: &benchmarkmodulev1.GeneratorParams{
Seed: 34,
BucketCount: 3,
GenesisCount: 3_000_000,
KeyMean: 64,
KeyStdDev: 12,
ValueMean: 1024,
ValueStdDev: 256,
},
}),
})
runtimeConfig := &runtimev1alpha1.Module{}
err := appConfig.Modules[0].Config.UnmarshalTo(runtimeConfig)
if err != nil {
panic(fmt.Errorf("benchmark init: failed to unmarshal runtime module config: %w", err))
}
runtimeConfig.InitGenesis = append(runtimeConfig.InitGenesis, benchmark.ModuleName)
appConfig.Modules[0].Config = appconfig.WrapAny(runtimeConfig)
}

View File

@ -1,266 +0,0 @@
package simapp
import (
"encoding/json"
"fmt"
cmtproto "github.com/cometbft/cometbft/api/cometbft/types/v1"
"cosmossdk.io/collections"
storetypes "cosmossdk.io/store/types"
slashingtypes "cosmossdk.io/x/slashing/types"
"cosmossdk.io/x/staking"
stakingtypes "cosmossdk.io/x/staking/types"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// ExportAppStateAndValidators exports the state of the application for a genesis
// file.
func (app *SimApp) ExportAppStateAndValidators(forZeroHeight bool, jailAllowedAddrs, modulesToExport []string) (servertypes.ExportedApp, error) {
// as if they could withdraw from the start of the next block
ctx := app.NewContextLegacy(true, cmtproto.Header{Height: app.LastBlockHeight()})
// We export at last height + 1, because that's the height at which
// CometBFT will start InitChain.
height := app.LastBlockHeight() + 1
if forZeroHeight {
height = 0
app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs)
}
genState, err := app.ModuleManager.ExportGenesisForModules(ctx, modulesToExport)
if err != nil {
return servertypes.ExportedApp{}, err
}
appState, err := json.MarshalIndent(genState, "", " ")
if err != nil {
return servertypes.ExportedApp{}, err
}
validators, err := staking.WriteValidators(ctx, app.StakingKeeper)
return servertypes.ExportedApp{
AppState: appState,
Validators: validators,
Height: height,
ConsensusParams: app.BaseApp.GetConsensusParams(ctx),
}, err
}
// prepForZeroHeightGenesis prepares for fresh start at zero height
// NOTE zero height genesis is a temporary feature which will be deprecated
//
// in favor of export at a block height
func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) {
applyAllowedAddrs := false
// check if there is a allowed address list
if len(jailAllowedAddrs) > 0 {
applyAllowedAddrs = true
}
allowedAddrsMap := make(map[string]bool)
for _, addr := range jailAllowedAddrs {
_, err := app.InterfaceRegistry().SigningContext().ValidatorAddressCodec().StringToBytes(addr)
if err != nil {
panic(err)
}
allowedAddrsMap[addr] = true
}
/* Handle fee distribution state. */
// withdraw all validator commission
err := app.StakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.ValidatorI) (stop bool) {
valBz, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator())
if err != nil {
panic(err)
}
_, _ = app.DistrKeeper.WithdrawValidatorCommission(ctx, valBz)
return false
})
if err != nil {
panic(err)
}
// withdraw all delegator rewards
dels, err := app.StakingKeeper.GetAllDelegations(ctx)
if err != nil {
panic(err)
}
for _, delegation := range dels {
valAddr, err := app.InterfaceRegistry().SigningContext().ValidatorAddressCodec().StringToBytes(delegation.ValidatorAddress)
if err != nil {
panic(err)
}
delAddr, err := app.InterfaceRegistry().SigningContext().AddressCodec().StringToBytes(delegation.DelegatorAddress)
if err != nil {
panic(err)
}
_, _ = app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr)
}
// clear validator slash events
err = app.DistrKeeper.ValidatorSlashEvents.Clear(ctx, nil)
if err != nil {
panic(err)
}
// clear validator historical rewards
err = app.DistrKeeper.ValidatorHistoricalRewards.Clear(ctx, nil)
if err != nil {
panic(err)
}
// set context height to zero
height := ctx.BlockHeight()
ctx = ctx.WithBlockHeight(0)
// reinitialize all validators
err = app.StakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.ValidatorI) (stop bool) {
valBz, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator())
if err != nil {
panic(err)
}
// donate any unwithdrawn outstanding reward tokens to the community pool
rewards, err := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, valBz)
if err != nil {
panic(err)
}
feePool, err := app.DistrKeeper.FeePool.Get(ctx)
if err != nil {
panic(err)
}
feePool.DecimalPool = feePool.DecimalPool.Add(rewards...) // distribution will allocate this to the protocolpool eventually
if err := app.DistrKeeper.FeePool.Set(ctx, feePool); err != nil {
panic(err)
}
if err := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, valBz); err != nil {
panic(err)
}
return false
})
if err != nil {
panic(err)
}
// reinitialize all delegations
for _, del := range dels {
valAddr, err := app.InterfaceRegistry().SigningContext().ValidatorAddressCodec().StringToBytes(del.ValidatorAddress)
if err != nil {
panic(err)
}
delAddr, err := app.InterfaceRegistry().SigningContext().AddressCodec().StringToBytes(del.DelegatorAddress)
if err != nil {
panic(err)
}
if err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil {
// never called as BeforeDelegationCreated always returns nil
panic(fmt.Errorf("error while incrementing period: %w", err))
}
if err := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); err != nil {
// never called as AfterDelegationModified always returns nil
panic(fmt.Errorf("error while creating a new delegation period record: %w", err))
}
}
// reset context height
ctx = ctx.WithBlockHeight(height)
/* Handle staking state. */
// iterate through redelegations, reset creation height
err = app.StakingKeeper.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) {
for i := range red.Entries {
red.Entries[i].CreationHeight = 0
}
err = app.StakingKeeper.SetRedelegation(ctx, red)
if err != nil {
panic(err)
}
return false
})
if err != nil {
panic(err)
}
// iterate through unbonding delegations, reset creation height
err = app.StakingKeeper.UnbondingDelegations.Walk(
ctx,
nil,
func(_ collections.Pair[[]byte, []byte], ubd stakingtypes.UnbondingDelegation) (stop bool, err error) {
for i := range ubd.Entries {
ubd.Entries[i].CreationHeight = 0
}
err = app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
if err != nil {
return true, err
}
return false, err
},
)
if err != nil {
panic(err)
}
// Iterate through validators by power descending, reset bond heights, and
// update bond intra-tx counters.
store := ctx.KVStore(app.GetKey(stakingtypes.StoreKey))
iter := storetypes.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey)
for ; iter.Valid(); iter.Next() {
addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key()))
validator, err := app.StakingKeeper.GetValidator(ctx, addr)
if err != nil {
panic("expected validator, not found")
}
valAddr, err := app.StakingKeeper.ValidatorAddressCodec().BytesToString(addr)
if err != nil {
panic(err)
}
validator.UnbondingHeight = 0
if applyAllowedAddrs && !allowedAddrsMap[valAddr] {
validator.Jailed = true
}
if err = app.StakingKeeper.SetValidator(ctx, validator); err != nil {
panic(err)
}
}
if err := iter.Close(); err != nil {
app.Logger().Error("error while closing the key-value store reverse prefix iterator: ", err)
return
}
_, err = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
if err != nil {
panic(err)
}
/* Handle slashing state. */
// reset start height on signing infos
err = app.SlashingKeeper.ValidatorSigningInfo.Walk(ctx, nil, func(addr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool, err error) {
info.StartHeight = 0
err = app.SlashingKeeper.ValidatorSigningInfo.Set(ctx, addr, info)
if err != nil {
return true, err
}
return false, nil
})
if err != nil {
panic(err)
}
}

View File

@ -1,14 +0,0 @@
package simapp
import (
"encoding/json"
)
// GenesisState of the blockchain is represented here as a map of raw json
// messages key'd by a identifier string.
// The identifier is used to determine which module genesis information belongs
// to so it may be appropriately routed during init chain.
// Within this application default genesis information is retrieved from
// the module manager which populates json from each module
// object provided to it during init.
type GenesisState map[string]json.RawMessage

View File

@ -1,47 +0,0 @@
package simapp
import (
"errors"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
var _ authtypes.GenesisAccount = (*SimGenesisAccount)(nil)
// SimGenesisAccount defines a type that implements the GenesisAccount interface
// to be used for simulation accounts in the genesis state.
type SimGenesisAccount struct {
*authtypes.BaseAccount
// vesting account fields
OriginalVesting sdk.Coins `json:"original_vesting" yaml:"original_vesting"` // total vesting coins upon initialization
DelegatedFree sdk.Coins `json:"delegated_free" yaml:"delegated_free"` // delegated vested coins at time of delegation
DelegatedVesting sdk.Coins `json:"delegated_vesting" yaml:"delegated_vesting"` // delegated vesting coins at time of delegation
StartTime int64 `json:"start_time" yaml:"start_time"` // vesting start time (UNIX Epoch time)
EndTime int64 `json:"end_time" yaml:"end_time"` // vesting end time (UNIX Epoch time)
// module account fields
ModuleName string `json:"module_name" yaml:"module_name"` // name of the module account
ModulePermissions []string `json:"module_permissions" yaml:"module_permissions"` // permissions of module account
}
// Validate checks for errors on the vesting and module account parameters
func (sga SimGenesisAccount) Validate() error {
if !sga.OriginalVesting.IsZero() {
if sga.StartTime >= sga.EndTime {
return errors.New("vesting start-time cannot be after end-time")
}
}
if sga.ModuleName != "" {
ma := authtypes.ModuleAccount{
BaseAccount: sga.BaseAccount, Name: sga.ModuleName, Permissions: sga.ModulePermissions,
}
if err := ma.Validate(); err != nil {
return err
}
}
return sga.BaseAccount.Validate()
}

View File

@ -1,88 +0,0 @@
package simapp_test
import (
"testing"
"time"
"github.com/cometbft/cometbft/crypto"
"github.com/stretchr/testify/require"
"cosmossdk.io/simapp"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
func TestSimGenesisAccountValidate(t *testing.T) {
pubkey := secp256k1.GenPrivKey().PubKey()
addr := sdk.AccAddress(pubkey.Address())
vestingStart := time.Now().UTC()
coins := sdk.NewCoins(sdk.NewInt64Coin("test", 1000))
baseAcc := authtypes.NewBaseAccount(addr, pubkey, 0, 0)
testCases := []struct {
name string
sga simapp.SimGenesisAccount
wantErr bool
}{
{
"valid basic account",
simapp.SimGenesisAccount{
BaseAccount: baseAcc,
},
false,
},
{
"invalid basic account with mismatching address/pubkey",
simapp.SimGenesisAccount{
BaseAccount: authtypes.NewBaseAccount(addr, secp256k1.GenPrivKey().PubKey(), 0, 0),
},
true,
},
{
"valid basic account with module name",
simapp.SimGenesisAccount{
BaseAccount: authtypes.NewBaseAccount(sdk.AccAddress(crypto.AddressHash([]byte("testmod"))), nil, 0, 0),
ModuleName: "testmod",
},
false,
},
{
"valid basic account with invalid module name/pubkey pair",
simapp.SimGenesisAccount{
BaseAccount: baseAcc,
ModuleName: "testmod",
},
true,
},
{
"valid basic account with valid vesting attributes",
simapp.SimGenesisAccount{
BaseAccount: baseAcc,
OriginalVesting: coins,
StartTime: vestingStart.Unix(),
EndTime: vestingStart.Add(1 * time.Hour).Unix(),
},
false,
},
{
"valid basic account with invalid vesting end time",
simapp.SimGenesisAccount{
BaseAccount: baseAcc,
OriginalVesting: coins,
StartTime: vestingStart.Add(2 * time.Hour).Unix(),
EndTime: vestingStart.Add(1 * time.Hour).Unix(),
},
true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
require.Equal(t, tc.wantErr, tc.sga.Validate() != nil)
})
}
}

View File

@ -1,290 +0,0 @@
module cosmossdk.io/simapp
go 1.23.3
require (
cosmossdk.io/api v0.8.0-rc.3
cosmossdk.io/client/v2 v2.0.0-beta.6
cosmossdk.io/collections v1.0.0-rc.1
cosmossdk.io/core v1.0.0-alpha.6
cosmossdk.io/core/testing v0.0.1
cosmossdk.io/depinject v1.1.0
cosmossdk.io/log v1.5.0
cosmossdk.io/math v1.4.0
cosmossdk.io/store v1.10.0-rc.1
cosmossdk.io/tools/confix v0.0.0-20230613133644-0a778132a60f
cosmossdk.io/x/accounts v0.0.0-20240913065641-0064ccbce64e
cosmossdk.io/x/accounts/defaults/base v0.0.0-00010101000000-000000000000
cosmossdk.io/x/accounts/defaults/lockup v0.0.0-20240417181816-5e7aae0db1f5
cosmossdk.io/x/accounts/defaults/multisig v0.0.0-00010101000000-000000000000
cosmossdk.io/x/authz v0.0.0-00010101000000-000000000000
cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91
cosmossdk.io/x/circuit v0.0.0-20230613133644-0a778132a60f
cosmossdk.io/x/consensus v0.0.0-00010101000000-000000000000
cosmossdk.io/x/distribution v0.0.0-20240227221813-a248d05f70f4
cosmossdk.io/x/epochs v0.0.0-20240522060652-a1ae4c3e0337
cosmossdk.io/x/evidence v0.0.0-20230613133644-0a778132a60f
cosmossdk.io/x/feegrant v0.0.0-20230613133644-0a778132a60f
cosmossdk.io/x/gov v0.0.0-20231113122742-912390d5fc4a
cosmossdk.io/x/group v0.0.0-00010101000000-000000000000
cosmossdk.io/x/mint v0.0.0-00010101000000-000000000000
cosmossdk.io/x/nft v0.0.0-20230613133644-0a778132a60f
cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190
cosmossdk.io/x/slashing v0.0.0-00010101000000-000000000000
cosmossdk.io/x/staking v0.0.0-20240226161501-23359a0b6d91
cosmossdk.io/x/tx v1.0.0-alpha.3 // indirect
cosmossdk.io/x/upgrade v0.0.0-20230613133644-0a778132a60f
github.com/cometbft/cometbft v1.0.0
github.com/cometbft/cometbft/api v1.0.0
// this version is not used as it is always replaced by the latest Cosmos SDK version
github.com/cosmos/cosmos-sdk v0.53.0
github.com/cosmos/gogoproto v1.7.0
github.com/spf13/cast v1.7.1 // indirect
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.10.0
go.uber.org/mock v0.5.0
google.golang.org/grpc v1.68.1
google.golang.org/protobuf v1.36.0
)
require (
cosmossdk.io/indexer/postgres v0.1.0
cosmossdk.io/tools/benchmark v0.0.0-00010101000000-000000000000
github.com/jackc/pgx/v5 v5.7.1
)
require (
buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.0-20241120201313-68e42a58b301.1 // indirect
buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.0-20240130113600-88ef6483f90f.1 // indirect
cloud.google.com/go v0.115.1 // indirect
cloud.google.com/go/auth v0.8.1 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect
cloud.google.com/go/compute/metadata v0.5.0 // indirect
cloud.google.com/go/iam v1.1.13 // indirect
cloud.google.com/go/storage v1.43.0 // indirect
cosmossdk.io/errors v1.0.1 // indirect
cosmossdk.io/schema v1.0.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/99designs/keyring v1.2.2 // indirect
github.com/DataDog/datadog-go v4.8.3+incompatible // indirect
github.com/DataDog/zstd v1.5.5 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/aws/aws-sdk-go v1.55.5 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/bgentry/speakeasy v0.2.0 // indirect
github.com/bits-and-blooms/bitset v1.10.0 // indirect
github.com/bytedance/sonic v1.12.6 // indirect
github.com/bytedance/sonic/loader v0.2.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chzyer/readline v1.5.1 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
github.com/cockroachdb/errors v1.11.3 // indirect
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/pebble v1.1.2 // indirect
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/cometbft/cometbft-db v1.0.1 // indirect
github.com/cosmos/btcutil v1.0.5 // indirect
github.com/cosmos/cosmos-db v1.1.1 // indirect
github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/gogogateway v1.2.0 // indirect
github.com/cosmos/iavl v1.3.4 // indirect
github.com/cosmos/ics23/go v0.11.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.14.0 // indirect
github.com/creachadair/atomicfile v0.3.6 // indirect
github.com/creachadair/tomledit v0.0.26 // indirect
github.com/danieljoos/wincred v1.2.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/dgraph-io/badger/v4 v4.5.0 // indirect
github.com/dgraph-io/ristretto/v2 v2.0.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/dvsekhvalnov/jose2go v1.6.0 // indirect
github.com/emicklei/dot v1.6.2 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/getsentry/sentry-go v0.27.0 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/flatbuffers v24.3.25+incompatible // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/orderedcode v0.0.1 // indirect
github.com/google/s2a-go v0.1.8 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.13.0 // indirect
github.com/gorilla/handlers v1.5.2 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-getter v1.7.6 // indirect
github.com/hashicorp/go-hclog v1.6.3 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-metrics v0.5.3 // indirect
github.com/hashicorp/go-plugin v1.6.2 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/yamux v0.1.2 // indirect
github.com/hdevalence/ed25519consensus v0.2.0 // indirect
github.com/huandu/skiplist v1.2.1 // indirect
github.com/iancoleman/strcase v0.3.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/linxGnu/grocksdb v1.9.3 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/magiconair/properties v1.8.9 // indirect
github.com/manifoldco/promptui v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mdp/qrterminal/v3 v3.2.0 // indirect
github.com/minio/highwayhash v1.0.3 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mtibben/percent v0.2.1 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.20.5 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.61.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rs/cors v1.11.1 // indirect
github.com/rs/zerolog v1.33.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sasha-s/go-deadlock v0.3.5 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/supranational/blst v0.3.13 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
github.com/tendermint/go-amino v0.16.0 // indirect
github.com/tidwall/btree v1.7.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
github.com/zondax/hid v0.9.2 // indirect
github.com/zondax/ledger-go v0.14.3 // indirect
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect
go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
go.opentelemetry.io/otel v1.28.0 // indirect
go.opentelemetry.io/otel/metric v1.28.0 // indirect
go.opentelemetry.io/otel/trace v1.28.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/arch v0.12.0 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/net v0.32.0 // indirect
golang.org/x/oauth2 v0.24.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/term v0.27.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.27.0 // indirect
google.golang.org/api v0.192.0 // indirect
google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.1 // indirect
pgregory.net/rapid v1.1.0 // indirect
rsc.io/qr v0.2.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
// Here are the short-lived replace from the SimApp
// Replace here are pending PRs, or version to be tagged
// replace (
// <temporary replace>
// )
// SimApp on main always tests the latest extracted SDK modules importing the sdk
replace (
cosmossdk.io/client/v2 => ../client/v2
cosmossdk.io/tools/benchmark => ../tools/benchmark
cosmossdk.io/tools/confix => ../tools/confix
cosmossdk.io/x/accounts => ../x/accounts
cosmossdk.io/x/accounts/defaults/base => ../x/accounts/defaults/base
cosmossdk.io/x/accounts/defaults/lockup => ../x/accounts/defaults/lockup
cosmossdk.io/x/accounts/defaults/multisig => ../x/accounts/defaults/multisig
cosmossdk.io/x/authz => ../x/authz
cosmossdk.io/x/bank => ../x/bank
cosmossdk.io/x/circuit => ../x/circuit
cosmossdk.io/x/consensus => ../x/consensus
cosmossdk.io/x/distribution => ../x/distribution
cosmossdk.io/x/epochs => ../x/epochs
cosmossdk.io/x/evidence => ../x/evidence
cosmossdk.io/x/feegrant => ../x/feegrant
cosmossdk.io/x/gov => ../x/gov
cosmossdk.io/x/group => ../x/group
cosmossdk.io/x/mint => ../x/mint
cosmossdk.io/x/nft => ../x/nft
cosmossdk.io/x/params => ../x/params
cosmossdk.io/x/protocolpool => ../x/protocolpool
cosmossdk.io/x/slashing => ../x/slashing
cosmossdk.io/x/staking => ../x/staking
cosmossdk.io/x/upgrade => ../x/upgrade
)
// Below are the long-lived replace of the SimApp
replace (
// use cosmos fork of keyring
github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0
// Simapp always use the latest version of the cosmos-sdk
github.com/cosmos/cosmos-sdk => ../.
// Fix upstream GHSA-h395-qcrw-5vmq and GHSA-3vp4-m3rf-835h vulnerabilities.
// TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409
github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.9.1
// replace broken goleveldb
github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
)

File diff suppressed because it is too large Load Diff

View File

@ -1,139 +0,0 @@
package simapp
import (
"context"
"encoding/binary"
"fmt"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/event"
"cosmossdk.io/math"
banktypes "cosmossdk.io/x/bank/types"
minttypes "cosmossdk.io/x/mint/types"
stakingtypes "cosmossdk.io/x/staking/types"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
type MintBankKeeper interface {
MintCoins(ctx context.Context, moduleName string, coins sdk.Coins) error
SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt sdk.Coins) error
}
// ProvideExampleMintFn returns the function used in x/mint's endblocker to mint new tokens.
// Note that this function can not have the mint keeper as a parameter because it would create a cyclic dependency.
func ProvideExampleMintFn(bankKeeper MintBankKeeper) minttypes.MintFn {
return func(ctx context.Context, env appmodule.Environment, minter *minttypes.Minter, epochID string, epochNumber int64) error {
// in this example we ignore epochNumber as we don't care what epoch we are in, we just assume we are being called every minute.
if epochID != "minute" {
return nil
}
resp, err := env.QueryRouterService.Invoke(ctx, &stakingtypes.QueryParamsRequest{})
if err != nil {
return err
}
stakingParams, ok := resp.(*stakingtypes.QueryParamsResponse)
if !ok {
return fmt.Errorf("unexpected response type: %T", resp)
}
resp, err = env.QueryRouterService.Invoke(ctx, &banktypes.QuerySupplyOfRequest{Denom: stakingParams.Params.BondDenom})
if err != nil {
return err
}
bankSupply, ok := resp.(*banktypes.QuerySupplyOfResponse)
if !ok {
return fmt.Errorf("unexpected response type: %T", resp)
}
stakingTokenSupply := bankSupply.Amount
resp, err = env.QueryRouterService.Invoke(ctx, &minttypes.QueryParamsRequest{})
if err != nil {
return err
}
mintParams, ok := resp.(*minttypes.QueryParamsResponse)
if !ok {
return fmt.Errorf("unexpected response type: %T", resp)
}
resp, err = env.QueryRouterService.Invoke(ctx, &stakingtypes.QueryPoolRequest{})
if err != nil {
return err
}
stakingPool, ok := resp.(*stakingtypes.QueryPoolResponse)
if !ok {
return fmt.Errorf("unexpected response type: %T", resp)
}
// bondedRatio
bondedRatio := math.LegacyNewDecFromInt(stakingPool.Pool.BondedTokens).QuoInt(stakingTokenSupply.Amount)
minter.Inflation = minter.NextInflationRate(mintParams.Params, bondedRatio)
minter.AnnualProvisions = minter.NextAnnualProvisions(mintParams.Params, stakingTokenSupply.Amount)
// to get a more accurate amount of tokens minted, we get, and later store, last minting time.
// if this is the first time minting, we initialize the minter.Data with the current time - 60s
// to mint tokens at the beginning. Note: this is a custom behavior to avoid breaking tests.
if minter.Data == nil {
minter.Data = make([]byte, 8)
binary.BigEndian.PutUint64(minter.Data, (uint64)(env.HeaderService.HeaderInfo(ctx).Time.UnixMilli()-60000))
}
lastMint := binary.BigEndian.Uint64(minter.Data)
binary.BigEndian.PutUint64(minter.Data, (uint64)(env.HeaderService.HeaderInfo(ctx).Time.UnixMilli()))
// calculate the amount of tokens to mint, based on the time since the last mint.
msSinceLastMint := env.HeaderService.HeaderInfo(ctx).Time.UnixMilli() - (int64)(lastMint)
provisionAmt := minter.AnnualProvisions.QuoInt64(31536000000).MulInt64(msSinceLastMint) // 31536000000 = milliseconds in a year
mintedCoin := sdk.NewCoin(mintParams.Params.MintDenom, provisionAmt.TruncateInt())
maxSupply := mintParams.Params.MaxSupply
totalSupply := stakingTokenSupply.Amount
if !maxSupply.IsZero() {
// supply is not infinite, check the amount to mint
remainingSupply := maxSupply.Sub(totalSupply)
if remainingSupply.LTE(math.ZeroInt()) {
// max supply reached, no new tokens will be minted
// also handles the case where totalSupply > maxSupply
return nil
}
// if the amount to mint is greater than the remaining supply, mint the remaining supply
if mintedCoin.Amount.GT(remainingSupply) {
mintedCoin.Amount = remainingSupply
}
}
if mintedCoin.Amount.IsZero() {
// skip as no coins need to be minted
return nil
}
mintedCoins := sdk.NewCoins(mintedCoin)
if err := bankKeeper.MintCoins(ctx, minttypes.ModuleName, mintedCoins); err != nil {
return err
}
// Example of custom send while minting
// Send some tokens to a "team account"
// if err = bankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, ... ); err != nil {
// return err
// }
if err = bankKeeper.SendCoinsFromModuleToModule(ctx, minttypes.ModuleName, authtypes.FeeCollectorName, mintedCoins); err != nil {
return err
}
return env.EventService.EventManager(ctx).EmitKV(
minttypes.EventTypeMint,
event.NewAttribute(minttypes.AttributeKeyBondedRatio, bondedRatio.String()),
event.NewAttribute(minttypes.AttributeKeyInflation, minter.Inflation.String()),
event.NewAttribute(minttypes.AttributeKeyAnnualProvisions, minter.AnnualProvisions.String()),
event.NewAttribute(sdk.AttributeKeyAmount, mintedCoin.Amount.String()),
)
}
}

View File

@ -1,19 +0,0 @@
/*
Package params defines the simulation parameters in the simapp.
It contains the default weights used for each transaction used on the module's
simulation. These weights define the chance for a transaction to be simulated at
any given operation.
You can replace the default values for the weights by providing a params.json
file with the weights defined for each of the transaction operations:
{
"op_weight_msg_send": 60,
"op_weight_msg_delegate": 100,
}
In the example above, the `MsgSend` has 60% chance to be simulated, while the
`MsgDelegate` will always be simulated.
*/
package params

View File

@ -1,16 +0,0 @@
package params
import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
)
// EncodingConfig specifies the concrete encoding types to use for a given app.
// This is provided for compatibility between protobuf and amino implementations.
type EncodingConfig struct {
InterfaceRegistry types.InterfaceRegistry
Codec codec.Codec
TxConfig client.TxConfig
Amino *codec.LegacyAmino
}

View File

@ -1,21 +0,0 @@
//go:build sims
package simapp
import (
"github.com/cosmos/cosmos-sdk/simsx"
"testing"
simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli"
)
// Profile with:
// /usr/local/go/bin/go test -benchmem -run=^$ cosmossdk.io/simapp -bench ^BenchmarkFullAppSimulation$ -Commit=true -cpuprofile cpu.out
func BenchmarkFullAppSimulation(b *testing.B) {
b.ReportAllocs()
config := simcli.NewConfigFromFlags()
config.ChainID = simsx.SimAppChainID
simsx.RunWithSeed(b, config, NewSimApp, setupStateFactory, 1, nil)
}

View File

@ -1,286 +0,0 @@
//go:build sims
package simapp
import (
"encoding/binary"
"encoding/json"
"flag"
"io"
"math/rand"
"strings"
"sync"
"testing"
"time"
abci "github.com/cometbft/cometbft/api/cometbft/abci/v1"
cmtproto "github.com/cometbft/cometbft/api/cometbft/types/v1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
corestore "cosmossdk.io/core/store"
"cosmossdk.io/log"
"cosmossdk.io/store"
storetypes "cosmossdk.io/store/types"
authzkeeper "cosmossdk.io/x/authz/keeper"
"cosmossdk.io/x/feegrant"
slashingtypes "cosmossdk.io/x/slashing/types"
stakingtypes "cosmossdk.io/x/staking/types"
"github.com/cosmos/cosmos-sdk/baseapp"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
"github.com/cosmos/cosmos-sdk/simsx"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/cosmos/cosmos-sdk/x/simulation"
simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli"
)
// SimAppChainID hardcoded chainID for simulation
var FlagEnableStreamingValue bool
// Get flags every time the simulator is run
func init() {
simcli.GetSimulatorFlags()
flag.BoolVar(&FlagEnableStreamingValue, "EnableStreaming", false, "Enable streaming service")
}
// interBlockCacheOpt returns a BaseApp option function that sets the persistent
// inter-block write-through cache.
func interBlockCacheOpt() func(*baseapp.BaseApp) {
return baseapp.SetInterBlockCache(store.NewCommitKVStoreCacheManager())
}
func TestFullAppSimulation(t *testing.T) {
simsx.Run(t, NewSimApp, setupStateFactory)
}
func setupStateFactory(app *SimApp) simsx.SimStateFactory {
blockedAddre, _ := BlockedAddresses(app.interfaceRegistry.SigningContext().AddressCodec())
return simsx.SimStateFactory{
Codec: app.AppCodec(),
AppStateFn: simtestutil.AppStateFn(app.AppCodec(), app.AuthKeeper.AddressCodec(), app.StakingKeeper.ValidatorAddressCodec(), app.SimulationManager().Modules, app.DefaultGenesis()),
BlockedAddr: blockedAddre,
AccountSource: app.AuthKeeper,
BalanceSource: app.BankKeeper,
}
}
var (
exportAllModules []string
exportWithValidatorSet []string
)
func TestAppImportExport(t *testing.T) {
simsx.Run(t, NewSimApp, setupStateFactory, func(t testing.TB, ti simsx.TestInstance[*SimApp], _ []simtypes.Account) {
app := ti.App
t.Log("exporting genesis...\n")
exported, err := app.ExportAppStateAndValidators(false, exportWithValidatorSet, exportAllModules)
require.NoError(t, err)
t.Log("importing genesis...\n")
newTestInstance := simsx.NewSimulationAppInstance(t, ti.Cfg, NewSimApp)
newApp := newTestInstance.App
var genesisState GenesisState
require.NoError(t, json.Unmarshal(exported.AppState, &genesisState))
ctxB := newApp.NewContextLegacy(true, cmtproto.Header{Height: app.LastBlockHeight()})
_, err = newApp.ModuleManager.InitGenesis(ctxB, genesisState)
if IsEmptyValidatorSetErr(err) {
t.Skip("Skipping simulation as all validators have been unbonded")
return
}
require.NoError(t, err)
err = newApp.StoreConsensusParams(ctxB, exported.ConsensusParams)
require.NoError(t, err)
t.Log("comparing stores...")
// skip certain prefixes
skipPrefixes := map[string][][]byte{
stakingtypes.StoreKey: {
stakingtypes.UnbondingQueueKey, stakingtypes.RedelegationQueueKey, stakingtypes.ValidatorQueueKey,
},
authzkeeper.StoreKey: {authzkeeper.GrantQueuePrefix},
feegrant.StoreKey: {feegrant.FeeAllowanceQueueKeyPrefix},
slashingtypes.StoreKey: {slashingtypes.ValidatorMissedBlockBitmapKeyPrefix},
}
AssertEqualStores(t, app, newApp, app.SimulationManager().StoreDecoders, skipPrefixes)
})
}
// Scenario:
//
// Start a fresh node and run n blocks, export state
// set up a new node instance, Init chain from exported genesis
// run new instance for n blocks
func TestAppSimulationAfterImport(t *testing.T) {
simsx.Run(t, NewSimApp, setupStateFactory, func(t testing.TB, ti simsx.TestInstance[*SimApp], accs []simtypes.Account) {
app := ti.App
t.Log("exporting genesis...\n")
exported, err := app.ExportAppStateAndValidators(false, exportWithValidatorSet, exportAllModules)
require.NoError(t, err)
importGenesisStateFactory := func(app *SimApp) simsx.SimStateFactory {
return simsx.SimStateFactory{
Codec: app.AppCodec(),
AppStateFn: func(r *rand.Rand, _ []simtypes.Account, config simtypes.Config) (json.RawMessage, []simtypes.Account, string, time.Time) {
t.Log("importing genesis...\n")
genesisTimestamp := time.Unix(config.GenesisTime, 0)
_, err = app.InitChain(&abci.InitChainRequest{
AppStateBytes: exported.AppState,
ChainId: simsx.SimAppChainID,
InitialHeight: exported.Height,
Time: genesisTimestamp,
})
if IsEmptyValidatorSetErr(err) {
t.Skip("Skipping simulation as all validators have been unbonded")
return nil, nil, "", time.Time{}
}
require.NoError(t, err)
// use accounts from initial run
return exported.AppState, accs, config.ChainID, genesisTimestamp
},
BlockedAddr: must(BlockedAddresses(app.AuthKeeper.AddressCodec())),
AccountSource: app.AuthKeeper,
BalanceSource: app.BankKeeper,
}
}
ti.Cfg.InitialBlockHeight = int(exported.Height)
simsx.RunWithSeed(t, ti.Cfg, NewSimApp, importGenesisStateFactory, ti.Cfg.Seed, ti.Cfg.FuzzSeed)
})
}
func IsEmptyValidatorSetErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "validator set is empty after InitGenesis")
}
func TestAppStateDeterminism(t *testing.T) {
const numTimesToRunPerSeed = 3
var seeds []int64
if s := simcli.NewConfigFromFlags().Seed; s != simcli.DefaultSeedValue {
// We will be overriding the random seed and just run a single simulation on the provided seed value
for j := 0; j < numTimesToRunPerSeed; j++ { // multiple rounds
seeds = append(seeds, s)
}
} else {
// setup with 3 random seeds
for i := 0; i < 3; i++ {
seed := rand.Int63()
for j := 0; j < numTimesToRunPerSeed; j++ { // multiple rounds
seeds = append(seeds, seed)
}
}
}
// overwrite default app config
interBlockCachingAppFactory := func(logger log.Logger, db corestore.KVStoreWithBatch, traceStore io.Writer, loadLatest bool, appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp)) *SimApp {
if FlagEnableStreamingValue {
m := map[string]any{
"streaming.abci.keys": []string{"*"},
"streaming.abci.plugin": "abci_v1",
"streaming.abci.stop-node-on-err": true,
}
others := appOpts
appOpts = simsx.AppOptionsFn(func(k string) any {
if v, ok := m[k]; ok {
return v
}
return others.Get(k)
})
}
return NewSimApp(logger, db, nil, true, appOpts, append(baseAppOptions, interBlockCacheOpt())...)
}
var mx sync.Mutex
appHashResults := make(map[int64][][]byte)
appSimLogger := make(map[int64][]simulation.LogWriter)
captureAndCheckHash := func(t testing.TB, ti simsx.TestInstance[*SimApp], _ []simtypes.Account) {
seed, appHash := ti.Cfg.Seed, ti.App.LastCommitID().Hash
mx.Lock()
otherHashes, execWriters := appHashResults[seed], appSimLogger[seed]
if len(otherHashes) < numTimesToRunPerSeed-1 {
appHashResults[seed], appSimLogger[seed] = append(otherHashes, appHash), append(execWriters, ti.ExecLogWriter)
} else { // cleanup
delete(appHashResults, seed)
delete(appSimLogger, seed)
}
mx.Unlock()
var failNow bool
// and check that all app hashes per seed are equal for each iteration
for i := 0; i < len(otherHashes); i++ {
if !assert.Equal(t, otherHashes[i], appHash) {
execWriters[i].PrintLogs()
failNow = true
}
}
if failNow {
ti.ExecLogWriter.PrintLogs()
t.Fatalf("non-determinism in seed %d", seed)
}
}
// run simulations
simsx.RunWithSeeds(t, interBlockCachingAppFactory, setupStateFactory, seeds, []byte{}, captureAndCheckHash)
}
type ComparableStoreApp interface {
LastBlockHeight() int64
NewContextLegacy(isCheckTx bool, header cmtproto.Header) sdk.Context
GetKey(storeKey string) *storetypes.KVStoreKey
GetStoreKeys() []storetypes.StoreKey
}
func AssertEqualStores(t testing.TB, app, newApp ComparableStoreApp, storeDecoders simtypes.StoreDecoderRegistry, skipPrefixes map[string][][]byte) {
ctxA := app.NewContextLegacy(true, cmtproto.Header{Height: app.LastBlockHeight()})
ctxB := newApp.NewContextLegacy(true, cmtproto.Header{Height: app.LastBlockHeight()})
storeKeys := app.GetStoreKeys()
require.NotEmpty(t, storeKeys)
for _, appKeyA := range storeKeys {
// only compare kvstores
if _, ok := appKeyA.(*storetypes.KVStoreKey); !ok {
continue
}
keyName := appKeyA.Name()
appKeyB := newApp.GetKey(keyName)
storeA := ctxA.KVStore(appKeyA)
storeB := ctxB.KVStore(appKeyB)
failedKVAs, failedKVBs := simtestutil.DiffKVStores(storeA, storeB, skipPrefixes[keyName])
require.Equal(t, len(failedKVAs), len(failedKVBs), "unequal sets of key-values to compare %s, key stores %s and %s", keyName, appKeyA, appKeyB)
t.Logf("compared %d different key/value pairs between %s and %s\n", len(failedKVAs), appKeyA, appKeyB)
if !assert.Equal(t, 0, len(failedKVAs), simtestutil.GetSimulationLog(keyName, storeDecoders, failedKVAs, failedKVBs)) {
for _, v := range failedKVAs {
t.Logf("store mismatch: %q\n", v)
}
t.FailNow()
}
}
}
func FuzzFullAppSimulation(f *testing.F) {
f.Fuzz(func(t *testing.T, rawSeed []byte) {
if len(rawSeed) < 8 {
t.Skip()
return
}
simsx.RunWithSeeds(
t,
NewSimApp,
setupStateFactory,
[]int64{int64(binary.BigEndian.Uint64(rawSeed))},
rawSeed[8:],
)
})
}
func must[T any](r T, err error) T {
if err != nil {
panic(err)
}
return r
}

View File

@ -1,162 +0,0 @@
package cmd
import (
"errors"
"io"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"cosmossdk.io/client/v2/offchain"
corestore "cosmossdk.io/core/store"
"cosmossdk.io/log"
"cosmossdk.io/simapp"
confixcmd "cosmossdk.io/tools/confix/cmd"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/debug"
"github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/client/pruning"
"github.com/cosmos/cosmos-sdk/client/rpc"
"github.com/cosmos/cosmos-sdk/client/snapshot"
"github.com/cosmos/cosmos-sdk/server"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
)
func initRootCmd(
rootCmd *cobra.Command,
moduleManager *module.Manager,
) {
cfg := sdk.GetConfig()
cfg.Seal()
rootCmd.AddCommand(
genutilcli.InitCmd(moduleManager),
NewTestnetCmd(moduleManager),
debug.Cmd(),
confixcmd.ConfigCommand(),
pruning.Cmd(newApp),
snapshot.Cmd(newApp),
)
server.AddCommands(rootCmd, newApp, server.StartCmdOptions[servertypes.Application]{})
// add keybase, auxiliary RPC, query, genesis, and tx child commands
rootCmd.AddCommand(
server.StatusCommand(),
genesisCommand(moduleManager, appExport),
queryCommand(),
txCommand(),
keys.Commands(),
offchain.OffChain(),
)
}
// genesisCommand builds genesis-related `simd genesis` command. Users may provide application specific commands as a parameter
func genesisCommand(moduleManager *module.Manager, appExport servertypes.AppExporter, cmds ...*cobra.Command) *cobra.Command {
cmd := genutilcli.Commands(moduleManager.Modules[genutiltypes.ModuleName].(genutil.AppModule), moduleManager, appExport)
for _, subCmd := range cmds {
cmd.AddCommand(subCmd)
}
return cmd
}
func queryCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "query",
Aliases: []string{"q"},
Short: "Querying subcommands",
DisableFlagParsing: false,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}
cmd.AddCommand(
rpc.WaitTxCmd(),
server.QueryBlockCmd(),
authcmd.QueryTxsByEventsCmd(),
server.QueryBlocksCmd(),
authcmd.QueryTxCmd(),
server.QueryBlockResultsCmd(),
)
return cmd
}
func txCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "tx",
Short: "Transactions subcommands",
DisableFlagParsing: false,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}
cmd.AddCommand(
authcmd.GetSignCommand(),
authcmd.GetSignBatchCommand(),
authcmd.GetMultiSignCommand(),
authcmd.GetMultiSignBatchCmd(),
authcmd.GetValidateSignaturesCommand(),
authcmd.GetBroadcastCommand(),
authcmd.GetEncodeCommand(),
authcmd.GetDecodeCommand(),
authcmd.GetSimulateCmd(),
)
return cmd
}
// newApp creates the application
func newApp(
logger log.Logger,
db corestore.KVStoreWithBatch,
traceStore io.Writer,
appOpts servertypes.AppOptions,
) servertypes.Application {
baseappOptions := server.DefaultBaseappOptions(appOpts)
return simapp.NewSimApp(
logger, db, traceStore, true,
appOpts,
baseappOptions...,
)
}
// appExport creates a new simapp (optionally at a given height) and exports state.
func appExport(
logger log.Logger,
db corestore.KVStoreWithBatch,
traceStore io.Writer,
height int64,
forZeroHeight bool,
jailAllowedAddrs []string,
appOpts servertypes.AppOptions,
modulesToExport []string,
) (servertypes.ExportedApp, error) {
viperAppOpts, ok := appOpts.(*viper.Viper)
if !ok {
return servertypes.ExportedApp{}, errors.New("appOpts is not viper.Viper")
}
// overwrite the FlagInvCheckPeriod
viperAppOpts.Set(server.FlagInvCheckPeriod, 1)
var simApp *simapp.SimApp
if height != -1 {
simApp = simapp.NewSimApp(logger, db, traceStore, false, viperAppOpts)
if err := simApp.LoadHeight(height); err != nil {
return servertypes.ExportedApp{}, err
}
} else {
simApp = simapp.NewSimApp(logger, db, traceStore, true, viperAppOpts)
}
return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport)
}

View File

@ -1,128 +0,0 @@
package cmd
import (
"strings"
cmtcfg "github.com/cometbft/cometbft/config"
clientconfig "github.com/cosmos/cosmos-sdk/client/config"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
serverconfig "github.com/cosmos/cosmos-sdk/server/config"
)
// initCometBFTConfig helps to override default CometBFT Config values.
// return cmtcfg.DefaultConfig if no custom configuration is required for the application.
func initCometBFTConfig() *cmtcfg.Config {
cfg := cmtcfg.DefaultConfig()
// display only error logs by default except for p2p and state
cfg.LogLevel = "*:error,p2p:info,state:info"
// use previous db backend
cfg.DBBackend = "goleveldb"
// these values put a higher strain on node memory
// cfg.P2P.MaxNumInboundPeers = 100
// cfg.P2P.MaxNumOutboundPeers = 40
return cfg
}
// initClientConfig helps to override default client config template and configs.
// return "", nil if no custom configuration is required for the application.
func initClientConfig() (string, interface{}) {
type GasConfig struct {
GasAdjustment float64 `mapstructure:"gas-adjustment"`
}
type CustomClientConfig struct {
clientconfig.Config `mapstructure:",squash"`
GasConfig GasConfig `mapstructure:"gas"`
}
// Optionally allow the chain developer to overwrite the SDK's default client config.
clientCfg := clientconfig.DefaultConfig()
// The SDK's default keyring backend is set to "os".
// This is more secure than "test" and is the recommended value.
//
// In simapp, we set the default keyring backend to test, as SimApp is meant
// to be an example and testing application.
clientCfg.KeyringBackend = keyring.BackendTest
// Now we set the custom config default values.
customClientConfig := CustomClientConfig{
Config: *clientCfg,
GasConfig: GasConfig{
GasAdjustment: 1.5,
},
}
// The default SDK app template is defined in serverconfig.DefaultConfigTemplate.
// We append the custom config template to the default one.
// And we set the default config to the custom app template.
customClientConfigTemplate := clientconfig.DefaultClientConfigTemplate + strings.TrimSpace(`
# This is default the gas adjustment factor used in tx commands.
# It can be overwritten by the --gas-adjustment flag in each tx command.
gas-adjustment = {{ .GasConfig.GasAdjustment }}
`)
return customClientConfigTemplate, customClientConfig
}
// initAppConfig helps to override default appConfig template and configs.
// return "", nil if no custom configuration is required for the application.
func initAppConfig() (string, interface{}) {
// The following code snippet is just for reference.
// CustomConfig defines an arbitrary custom config to extend app.toml.
// If you don't need it, you can remove it.
// If you wish to add fields that correspond to flags that aren't in the SDK server config,
// this custom config can as well help.
type CustomConfig struct {
CustomField string `mapstructure:"custom-field"`
}
type CustomAppConfig struct {
serverconfig.Config `mapstructure:",squash"`
Custom CustomConfig `mapstructure:"custom"`
}
// Optionally allow the chain developer to overwrite the SDK's default
// server config.
srvCfg := serverconfig.DefaultConfig()
// The SDK's default minimum gas price is set to "" (empty value) inside
// app.toml. If left empty by validators, the node will halt on startup.
// However, the chain developer can set a default app.toml value for their
// validators here.
//
// In summary:
// - if you leave srvCfg.MinGasPrices = "", all validators MUST tweak their
// own app.toml config,
// - if you set srvCfg.MinGasPrices non-empty, validators CAN tweak their
// own app.toml to override, or use this default value.
//
// In simapp, we set the min gas prices to 0.
srvCfg.MinGasPrices = "0stake"
// Now we set the custom config default values.
customAppConfig := CustomAppConfig{
Config: *srvCfg,
Custom: CustomConfig{
CustomField: "anything",
},
}
// The default SDK app template is defined in serverconfig.DefaultConfigTemplate.
// We append the custom config template to the default one.
// And we set the default config to the custom app template.
customAppTemplate := serverconfig.DefaultConfigTemplate + `
[custom]
# That field will be parsed by server.InterceptConfigsPreRunHandler and held by viper.
# Do not forget to add quotes around the value if it is a string.
custom-field = "{{ .Custom.CustomField }}"`
return customAppTemplate, customAppConfig
}

View File

@ -1,154 +0,0 @@
package cmd
import (
"os"
"github.com/spf13/cobra"
authv1 "cosmossdk.io/api/cosmos/auth/module/v1"
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
stakingv1 "cosmossdk.io/api/cosmos/staking/module/v1"
"cosmossdk.io/client/v2/autocli"
"cosmossdk.io/core/address"
"cosmossdk.io/core/registry"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
"cosmossdk.io/simapp"
basedepinject "cosmossdk.io/x/accounts/defaults/base/depinject"
lockupdepinject "cosmossdk.io/x/accounts/defaults/lockup/depinject"
multisigdepinject "cosmossdk.io/x/accounts/defaults/multisig/depinject"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/config"
nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/auth/tx"
authtxconfig "github.com/cosmos/cosmos-sdk/x/auth/tx/config"
"github.com/cosmos/cosmos-sdk/x/auth/types"
)
// NewRootCmd creates a new root command for simd. It is called once in the main function.
func NewRootCmd() *cobra.Command {
var (
autoCliOpts autocli.AppOptions
moduleManager *module.Manager
clientCtx client.Context
)
if err := depinject.Inject(
depinject.Configs(simapp.AppConfig(),
depinject.Supply(log.NewNopLogger()),
depinject.Provide(
ProvideClientContext,
multisigdepinject.ProvideAccount,
basedepinject.ProvideAccount,
lockupdepinject.ProvideAllLockupAccounts,
// provide base account options
basedepinject.ProvideSecp256K1PubKey,
),
),
&autoCliOpts,
&moduleManager,
&clientCtx,
); err != nil {
panic(err)
}
rootCmd := &cobra.Command{
Use: "simd",
Short: "simulation app",
SilenceErrors: true,
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
// set the default command outputs
cmd.SetOut(cmd.OutOrStdout())
cmd.SetErr(cmd.ErrOrStderr())
clientCtx = clientCtx.WithCmdContext(cmd.Context()).WithViper("")
clientCtx, err := client.ReadPersistentCommandFlags(clientCtx, cmd.Flags())
if err != nil {
return err
}
customClientTemplate, customClientConfig := initClientConfig()
clientCtx, err = config.CreateClientConfig(clientCtx, customClientTemplate, customClientConfig)
if err != nil {
return err
}
if err := client.SetCmdClientContextHandler(clientCtx, cmd); err != nil {
return err
}
customAppTemplate, customAppConfig := initAppConfig()
customCMTConfig := initCometBFTConfig()
return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customCMTConfig)
},
}
initRootCmd(rootCmd, moduleManager)
nodeCmds := nodeservice.NewNodeCommands()
autoCliOpts.ModuleOptions = make(map[string]*autocliv1.ModuleOptions)
autoCliOpts.ModuleOptions[nodeCmds.Name()] = nodeCmds.AutoCLIOptions()
if err := autoCliOpts.EnhanceRootCommand(rootCmd); err != nil {
panic(err)
}
return rootCmd
}
func ProvideClientContext(
appCodec codec.Codec,
interfaceRegistry codectypes.InterfaceRegistry,
txConfigOpts tx.ConfigOptions,
legacyAmino registry.AminoRegistrar,
addressCodec address.Codec,
validatorAddressCodec address.ValidatorAddressCodec,
consensusAddressCodec address.ConsensusAddressCodec,
authConfig *authv1.Module,
stakingConfig *stakingv1.Module,
) client.Context {
var err error
amino, ok := legacyAmino.(*codec.LegacyAmino)
if !ok {
panic("ProvideClientContext requires a *codec.LegacyAmino instance")
}
clientCtx := client.Context{}.
WithCodec(appCodec).
WithInterfaceRegistry(interfaceRegistry).
WithLegacyAmino(amino).
WithInput(os.Stdin).
WithAccountRetriever(types.AccountRetriever{}).
WithAddressCodec(addressCodec).
WithValidatorAddressCodec(validatorAddressCodec).
WithConsensusAddressCodec(consensusAddressCodec).
WithHomeDir(simapp.DefaultNodeHome).
WithViper(""). // uses by default the binary name as prefix
WithAddressPrefix(authConfig.Bech32Prefix).
WithValidatorPrefix(stakingConfig.Bech32PrefixValidator)
// Read the config to overwrite the default values with the values from the config file
customClientTemplate, customClientConfig := initClientConfig()
clientCtx, err = config.CreateClientConfig(clientCtx, customClientTemplate, customClientConfig)
if err != nil {
panic(err)
}
// textual is enabled by default, we need to re-create the tx config grpc instead of bank keeper.
txConfigOpts.TextualCoinMetadataQueryFn = authtxconfig.NewGRPCCoinMetadataQueryFn(clientCtx)
txConfig, err := tx.NewTxConfigWithOptions(clientCtx.Codec, txConfigOpts)
if err != nil {
panic(err)
}
clientCtx = clientCtx.WithTxConfig(txConfig)
return clientCtx
}

View File

@ -1,43 +0,0 @@
package cmd_test
import (
"fmt"
"testing"
"github.com/stretchr/testify/require"
"cosmossdk.io/simapp"
"cosmossdk.io/simapp/simd/cmd"
"github.com/cosmos/cosmos-sdk/client/flags"
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
"github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
)
func TestInitCmd(t *testing.T) {
rootCmd := cmd.NewRootCmd()
rootCmd.SetArgs([]string{
"init", // Test the init cmd
"simapp-test", // Moniker
fmt.Sprintf("--%s=%s", cli.FlagOverwrite, "true"), // Overwrite genesis.json, in case it already exists
})
require.NoError(t, svrcmd.Execute(rootCmd, "", simapp.DefaultNodeHome))
}
func TestHomeFlagRegistration(t *testing.T) {
homeDir := "/tmp/foo"
rootCmd := cmd.NewRootCmd()
rootCmd.SetArgs([]string{
"query",
fmt.Sprintf("--%s", flags.FlagHome),
homeDir,
})
require.NoError(t, svrcmd.Execute(rootCmd, "", simapp.DefaultNodeHome))
result, err := rootCmd.Flags().GetString(flags.FlagHome)
require.NoError(t, err)
require.Equal(t, result, homeDir)
}

View File

@ -1,754 +0,0 @@
package cmd
import (
"bufio"
"encoding/json"
"fmt"
"io"
"net"
"net/url"
"os"
"os/exec"
"os/signal"
"path/filepath"
"strconv"
"strings"
"time"
cmtconfig "github.com/cometbft/cometbft/config"
cmttime "github.com/cometbft/cometbft/types/time"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"cosmossdk.io/math"
"cosmossdk.io/math/unsafe"
banktypes "cosmossdk.io/x/bank/types"
stakingtypes "cosmossdk.io/x/staking/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/server"
srvconfig "github.com/cosmos/cosmos-sdk/server/config"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/version"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
)
var (
flagNodeDirPrefix = "node-dir-prefix"
flagNumValidators = "validator-count"
flagOutputDir = "output-dir"
flagNodeDaemonHome = "node-daemon-home"
flagStartingIPAddress = "starting-ip-address"
flagListenIPAddress = "listen-ip-address"
flagEnableLogging = "enable-logging"
flagGRPCAddress = "grpc.address"
flagRPCAddress = "rpc.address"
flagAPIAddress = "api.address"
flagPrintMnemonic = "print-mnemonic"
flagStakingDenom = "staking-denom"
flagCommitTimeout = "commit-timeout"
flagSingleHost = "single-host"
// default values
defaultRPCPort = 26657
defaultAPIPort = 1317
defaultGRPCPort = 9090
defaultListenIPAddress = "127.0.0.1"
defaultStartingIPAddress = "192.168.0.1"
defaultNodeDirPrefix = "node"
defaultNodeDaemonHome = "simd"
)
type initArgs struct {
algo string
chainID string
keyringBackend string
minGasPrices string
nodeDaemonHome string
nodeDirPrefix string
numValidators int
outputDir string
startingIPAddress string
listenIPAddress string
singleMachine bool
bondTokenDenom string
// start command arguments
apiListenAddress string
grpcListenAddress string
rpcPort int
apiPort int
grpcPort int
enableLogging bool
printMnemonic bool
}
func addTestnetFlagsToCmd(cmd *cobra.Command) {
cmd.Flags().IntP(flagNumValidators, "n", 4, "Number of validators to initialize the testnet with")
cmd.Flags().StringP(flagOutputDir, "o", "./.testnets", "Directory to store initialization data for the testnet")
cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
cmd.Flags().String(server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom), "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)")
cmd.Flags().String(flags.FlagKeyType, string(hd.Secp256k1Type), "Key signing algorithm to generate keys for")
// support old flags name for backwards compatibility
cmd.Flags().SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName {
if name == flags.FlagKeyAlgorithm {
name = flags.FlagKeyType
}
return pflag.NormalizedName(name)
})
}
// NewTestnetCmd creates a root testnet command with subcommands to run an in-process testnet or initialize
// validator configuration files for running a multi-validator testnet in a separate process
func NewTestnetCmd(mm *module.Manager) *cobra.Command {
testnetCmd := &cobra.Command{
Use: "testnet",
Short: "subcommands for starting or configuring local testnets",
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}
testnetCmd.AddCommand(testnetStartCmd(mm))
testnetCmd.AddCommand(testnetInitFilesCmd(mm))
return testnetCmd
}
// testnetInitFilesCmd returns a cmd to initialize all files for CometBFT testnet and application
func testnetInitFilesCmd(mm *module.Manager) *cobra.Command {
cmd := &cobra.Command{
Use: "init-files",
Short: "Initialize config directories & files for a multi-validator testnet running locally via separate processes (e.g. Docker Compose or similar)",
Long: fmt.Sprintf(`init-files will setup one directory per validator and populate each with
necessary files (private validator, genesis, config, etc.) for running validator nodes.
Booting up a network with these validator folders is intended to be used with Docker Compose,
or a similar setup where each node has a manually configurable IP address.
Note, strict routability for addresses is turned off in the config file.
Example:
%s testnet init-files --validator-count 4 --output-dir ./.testnets --starting-ip-address 192.168.10.2
`, version.AppName),
RunE: func(cmd *cobra.Command, _ []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
config := client.GetConfigFromCmd(cmd)
args := initArgs{
rpcPort: defaultRPCPort,
apiPort: defaultAPIPort,
grpcPort: defaultGRPCPort,
apiListenAddress: defaultListenIPAddress,
grpcListenAddress: defaultListenIPAddress,
}
args.outputDir, _ = cmd.Flags().GetString(flagOutputDir)
args.keyringBackend, _ = cmd.Flags().GetString(flags.FlagKeyringBackend)
args.chainID, _ = cmd.Flags().GetString(flags.FlagChainID)
args.minGasPrices, _ = cmd.Flags().GetString(server.FlagMinGasPrices)
args.nodeDirPrefix, _ = cmd.Flags().GetString(flagNodeDirPrefix)
args.nodeDaemonHome, _ = cmd.Flags().GetString(flagNodeDaemonHome)
args.startingIPAddress, _ = cmd.Flags().GetString(flagStartingIPAddress)
args.listenIPAddress, _ = cmd.Flags().GetString(flagListenIPAddress)
args.numValidators, _ = cmd.Flags().GetInt(flagNumValidators)
args.algo, _ = cmd.Flags().GetString(flags.FlagKeyType)
args.bondTokenDenom, _ = cmd.Flags().GetString(flagStakingDenom)
args.singleMachine, _ = cmd.Flags().GetBool(flagSingleHost)
config.Consensus.TimeoutCommit, err = cmd.Flags().GetDuration(flagCommitTimeout)
if err != nil {
return err
}
if args.chainID == "" {
args.chainID = "chain-" + unsafe.Str(6)
}
return initTestnetFiles(clientCtx, cmd, config, mm, args)
},
}
addTestnetFlagsToCmd(cmd)
cmd.Flags().String(flagNodeDirPrefix, defaultNodeDirPrefix, "Prefix for the name of per-validator subdirectories (to be number-suffixed like node0, node1, ...)")
cmd.Flags().String(flagNodeDaemonHome, defaultNodeDaemonHome, "Home directory of the node's daemon configuration")
cmd.Flags().String(flagStartingIPAddress, defaultStartingIPAddress, "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)")
cmd.Flags().String(flagListenIPAddress, defaultListenIPAddress, "TCP or UNIX socket IP address for the RPC server to listen on")
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
cmd.Flags().Duration(flagCommitTimeout, 5*time.Second, "Time to wait after a block commit before starting on the new height")
cmd.Flags().Bool(flagSingleHost, false, "Cluster runs on a single host machine with different ports")
cmd.Flags().String(flagStakingDenom, sdk.DefaultBondDenom, "Default staking token denominator")
return cmd
}
// testnetStartCmd returns a cmd to start multi validator in-process testnet
func testnetStartCmd(mm *module.Manager) *cobra.Command {
cmd := &cobra.Command{
Use: "start",
Short: "Launch an in-process multi-validator testnet",
Long: fmt.Sprintf(`testnet will launch an in-process multi-validator testnet,
and generate a directory for each validator populated with necessary
configuration files (private validator, genesis, config, etc.).
Example:
%s testnet --validator-count4 --output-dir ./.testnets
`, version.AppName),
RunE: func(cmd *cobra.Command, _ []string) (err error) {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
config := client.GetConfigFromCmd(cmd)
args := initArgs{
singleMachine: true,
bondTokenDenom: sdk.DefaultBondDenom,
nodeDaemonHome: defaultNodeDaemonHome,
nodeDirPrefix: defaultNodeDirPrefix,
keyringBackend: keyring.BackendTest,
}
args.outputDir, _ = cmd.Flags().GetString(flagOutputDir)
args.chainID, _ = cmd.Flags().GetString(flags.FlagChainID)
args.minGasPrices, _ = cmd.Flags().GetString(server.FlagMinGasPrices)
args.numValidators, _ = cmd.Flags().GetInt(flagNumValidators)
args.algo, _ = cmd.Flags().GetString(flags.FlagKeyType)
args.enableLogging, _ = cmd.Flags().GetBool(flagEnableLogging)
rpcAddress, _ := cmd.Flags().GetString(flagRPCAddress)
args.listenIPAddress, args.rpcPort, err = parseURL(rpcAddress)
if err != nil {
return fmt.Errorf("invalid rpc address: %w", err)
}
apiAddress, _ := cmd.Flags().GetString(flagAPIAddress)
args.apiListenAddress, args.apiPort, err = parseURL(apiAddress)
if err != nil {
return fmt.Errorf("invalid api address: %w", err)
}
grpcAddress, _ := cmd.Flags().GetString(flagGRPCAddress)
// add scheme to avoid issues with parsing
if !strings.Contains(grpcAddress, "://") {
grpcAddress = "tcp://" + grpcAddress
}
args.grpcListenAddress, args.grpcPort, err = parseURL(grpcAddress)
if err != nil {
return fmt.Errorf("invalid grpc address: %w", err)
}
args.printMnemonic, _ = cmd.Flags().GetBool(flagPrintMnemonic)
if args.chainID == "" {
args.chainID = "chain-" + unsafe.Str(6)
}
return startTestnet(clientCtx, cmd, config, mm, args)
},
}
addTestnetFlagsToCmd(cmd)
cmd.Flags().Bool(flagEnableLogging, false, "Enable INFO logging of CometBFT validator nodes")
cmd.Flags().String(flagRPCAddress, "tcp://127.0.0.1:26657", "the RPC address to listen on")
cmd.Flags().String(flagAPIAddress, "tcp://127.0.0.1:1317", "the address to listen on for REST API")
cmd.Flags().String(flagGRPCAddress, "127.0.0.1:9090", "the gRPC server address to listen on")
cmd.Flags().Bool(flagPrintMnemonic, true, "print mnemonic of first validator to stdout for manual testing")
return cmd
}
func parseURL(str string) (host string, port int, err error) {
u, err := url.Parse(str)
if err != nil {
return
}
host = u.Hostname()
port, err = strconv.Atoi(u.Port())
return
}
const nodeDirPerm = 0o755
// initTestnetFiles initializes testnet files for a testnet to be run in a separate process
func initTestnetFiles(
clientCtx client.Context,
cmd *cobra.Command,
nodeConfig *cmtconfig.Config,
mm *module.Manager,
args initArgs,
) error {
nodeIDs := make([]string, args.numValidators)
valPubKeys := make([]cryptotypes.PubKey, args.numValidators)
appConfig := srvconfig.DefaultConfig()
appConfig.MinGasPrices = args.minGasPrices
appConfig.API.Enable = true
appConfig.GRPC.Enable = true
appConfig.Telemetry.Enabled = true
appConfig.Telemetry.PrometheusRetentionTime = 60
appConfig.Telemetry.EnableHostnameLabel = false
appConfig.Telemetry.GlobalLabels = [][]string{{"chain_id", args.chainID}}
var (
genAccounts []authtypes.GenesisAccount
genBalances []banktypes.Balance
genFiles []string
)
var (
rpcPort = args.rpcPort
apiPort = args.apiPort
grpcPort = args.grpcPort
)
p2pPortStart := 26656
inBuf := bufio.NewReader(cmd.InOrStdin())
// generate private keys, node IDs, and initial transactions
for i := 0; i < args.numValidators; i++ {
var portOffset int
if args.singleMachine {
portOffset = i
p2pPortStart = 16656 // use different start point to not conflict with rpc port
nodeConfig.P2P.AddrBookStrict = false
nodeConfig.P2P.PexReactor = false
nodeConfig.P2P.AllowDuplicateIP = true
appConfig.API.Address = fmt.Sprintf("tcp://%s:%d", args.apiListenAddress, apiPort+portOffset)
appConfig.GRPC.Address = fmt.Sprintf("%s:%d", args.grpcListenAddress, grpcPort+portOffset)
}
nodeDirName, nodeDir := getNodeDir(args, i)
gentxsDir := filepath.Join(args.outputDir, "gentxs")
nodeConfig.SetRoot(nodeDir)
nodeConfig.Moniker = nodeDirName
nodeConfig.RPC.ListenAddress = fmt.Sprintf("tcp://%s:%d", args.listenIPAddress, rpcPort+portOffset)
if err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm); err != nil {
_ = os.RemoveAll(args.outputDir)
return err
}
var (
err error
ip string
)
if args.singleMachine {
ip = "127.0.0.1"
} else {
ip, err = getIP(i, args.startingIPAddress)
if err != nil {
_ = os.RemoveAll(args.outputDir)
return err
}
}
nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(nodeConfig, args.algo)
if err != nil {
_ = os.RemoveAll(args.outputDir)
return err
}
memo := fmt.Sprintf("%s@%s:%d", nodeIDs[i], ip, p2pPortStart+portOffset)
genFiles = append(genFiles, nodeConfig.GenesisFile())
kb, err := keyring.New(sdk.KeyringServiceName(), args.keyringBackend, nodeDir, inBuf, clientCtx.Codec)
if err != nil {
return err
}
keyringAlgos, _ := kb.SupportedAlgorithms()
algo, err := keyring.NewSigningAlgoFromString(args.algo, keyringAlgos)
if err != nil {
return err
}
addr, secret, err := testutil.GenerateSaveCoinKey(kb, nodeDirName, "", true, algo, sdk.GetFullBIP44Path())
if err != nil {
_ = os.RemoveAll(args.outputDir)
return err
}
// if PrintMnemonic is set to true, we print the first validator node's secret to the network's logger
// for debugging and manual testing
if args.printMnemonic && i == 0 {
printMnemonic(secret)
}
info := map[string]string{"secret": secret}
cliPrint, err := json.Marshal(info)
if err != nil {
return err
}
// save private key seed words
if err := writeFile(fmt.Sprintf("%v.json", "key_seed"), nodeDir, cliPrint); err != nil {
return err
}
accTokens := sdk.TokensFromConsensusPower(1000, sdk.DefaultPowerReduction)
accStakingTokens := sdk.TokensFromConsensusPower(500, sdk.DefaultPowerReduction)
coins := sdk.Coins{
sdk.NewCoin("testtoken", accTokens),
sdk.NewCoin(args.bondTokenDenom, accStakingTokens),
}
addrStr, err := clientCtx.AddressCodec.BytesToString(addr)
if err != nil {
return err
}
genBalances = append(genBalances, banktypes.Balance{Address: addrStr, Coins: coins.Sort()})
genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0))
valStr, err := clientCtx.ValidatorAddressCodec.BytesToString(addr)
if err != nil {
return err
}
valTokens := sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction)
createValMsg, err := stakingtypes.NewMsgCreateValidator(
valStr,
valPubKeys[i],
sdk.NewCoin(args.bondTokenDenom, valTokens),
stakingtypes.NewDescription(nodeDirName, "", "", "", "", &stakingtypes.Metadata{}),
stakingtypes.NewCommissionRates(math.LegacyOneDec(), math.LegacyOneDec(), math.LegacyOneDec()),
math.OneInt(),
)
if err != nil {
return err
}
txBuilder := clientCtx.TxConfig.NewTxBuilder()
if err := txBuilder.SetMsgs(createValMsg); err != nil {
return err
}
txBuilder.SetMemo(memo)
txFactory := tx.Factory{}
txFactory = txFactory.
WithChainID(args.chainID).
WithMemo(memo).
WithKeybase(kb).
WithTxConfig(clientCtx.TxConfig)
if err := tx.Sign(clientCtx, txFactory, nodeDirName, txBuilder, true); err != nil {
return err
}
txBz, err := clientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx())
if err != nil {
return err
}
if err := writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBz); err != nil {
return err
}
if err := srvconfig.SetConfigTemplate(srvconfig.DefaultConfigTemplate); err != nil {
return err
}
if err := srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config", "app.toml"), appConfig); err != nil {
return err
}
}
if err := initGenFiles(clientCtx, mm, args.chainID, genAccounts, genBalances, genFiles, args.numValidators); err != nil {
return err
}
err := collectGenFiles(
clientCtx, nodeConfig, args.chainID, nodeIDs, valPubKeys, args.numValidators,
args.outputDir, args.nodeDirPrefix, args.nodeDaemonHome,
rpcPort, p2pPortStart, args.singleMachine,
)
if err != nil {
return err
}
// Update viper root since root dir become rootdir/node/simd
client.GetViperFromCmd(cmd).Set(flags.FlagHome, nodeConfig.RootDir)
cmd.PrintErrf("Successfully initialized %d node directories\n", args.numValidators)
return nil
}
func initGenFiles(
clientCtx client.Context, mm *module.Manager, chainID string,
genAccounts []authtypes.GenesisAccount, genBalances []banktypes.Balance,
genFiles []string, numValidators int,
) error {
appGenState := mm.DefaultGenesis()
// set the accounts in the genesis state
var authGenState authtypes.GenesisState
clientCtx.Codec.MustUnmarshalJSON(appGenState[authtypes.ModuleName], &authGenState)
accounts, err := authtypes.PackAccounts(genAccounts)
if err != nil {
return err
}
authGenState.Accounts = accounts
appGenState[authtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&authGenState)
// set the balances in the genesis state
var bankGenState banktypes.GenesisState
clientCtx.Codec.MustUnmarshalJSON(appGenState[banktypes.ModuleName], &bankGenState)
bankGenState.Balances, err = banktypes.SanitizeGenesisBalances(genBalances, clientCtx.AddressCodec)
if err != nil {
return err
}
for _, bal := range bankGenState.Balances {
bankGenState.Supply = bankGenState.Supply.Add(bal.Coins...)
}
appGenState[banktypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&bankGenState)
appGenStateJSON, err := json.MarshalIndent(appGenState, "", " ")
if err != nil {
return err
}
appGenesis := genutiltypes.NewAppGenesisWithVersion(chainID, appGenStateJSON)
// generate empty genesis files for each validator and save
for i := 0; i < numValidators; i++ {
if err := appGenesis.SaveAs(genFiles[i]); err != nil {
return err
}
}
return nil
}
func collectGenFiles(
clientCtx client.Context, nodeConfig *cmtconfig.Config, chainID string,
nodeIDs []string, valPubKeys []cryptotypes.PubKey, numValidators int,
outputDir, nodeDirPrefix, nodeDaemonHome string,
rpcPortStart, p2pPortStart int,
singleMachine bool,
) error {
var appState json.RawMessage
genTime := cmttime.Now()
for i := 0; i < numValidators; i++ {
if singleMachine {
portOffset := i
nodeConfig.RPC.ListenAddress = fmt.Sprintf("tcp://127.0.0.1:%d", rpcPortStart+portOffset)
nodeConfig.P2P.ListenAddress = fmt.Sprintf("tcp://127.0.0.1:%d", p2pPortStart+portOffset)
}
nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)
nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome)
gentxsDir := filepath.Join(outputDir, "gentxs")
nodeConfig.Moniker = nodeDirName
nodeConfig.SetRoot(nodeDir)
nodeID, valPubKey := nodeIDs[i], valPubKeys[i]
initCfg := genutiltypes.NewInitConfig(chainID, gentxsDir, nodeID, valPubKey)
appGenesis, err := genutiltypes.AppGenesisFromFile(nodeConfig.GenesisFile())
if err != nil {
return err
}
nodeAppState, err := genutil.GenAppStateFromConfig(clientCtx.Codec, clientCtx.TxConfig, nodeConfig, initCfg, appGenesis, genutiltypes.DefaultMessageValidator,
clientCtx.ValidatorAddressCodec, clientCtx.AddressCodec)
if err != nil {
return err
}
if appState == nil {
// set the canonical application state (they should not differ)
appState = nodeAppState
}
genFile := nodeConfig.GenesisFile()
// overwrite each validator's genesis file to have a canonical genesis time
if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil {
return err
}
}
return nil
}
func getIP(i int, startingIPAddr string) (ip string, err error) {
if len(startingIPAddr) == 0 {
ip, err = server.ExternalIP()
if err != nil {
return "", err
}
return ip, nil
}
return calculateIP(startingIPAddr, i)
}
func calculateIP(ip string, i int) (string, error) {
ipv4 := net.ParseIP(ip).To4()
if ipv4 == nil {
return "", fmt.Errorf("%v: non ipv4 address", ip)
}
for j := 0; j < i; j++ {
ipv4[3]++
}
return ipv4.String(), nil
}
func writeFile(name, dir string, contents []byte) error {
file := filepath.Join(dir, name)
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("could not create directory %q: %w", dir, err)
}
return os.WriteFile(file, contents, 0o600)
}
// printMnemonic prints a provided mnemonic seed phrase on a network logger
// for debugging and manual testing
func printMnemonic(secret string) {
lines := []string{
"THIS MNEMONIC IS FOR TESTING PURPOSES ONLY",
"DO NOT USE IN PRODUCTION",
"",
strings.Join(strings.Fields(secret)[0:8], " "),
strings.Join(strings.Fields(secret)[8:16], " "),
strings.Join(strings.Fields(secret)[16:24], " "),
}
lineLengths := make([]int, len(lines))
for i, line := range lines {
lineLengths[i] = len(line)
}
maxLineLength := 0
for _, lineLen := range lineLengths {
if lineLen > maxLineLength {
maxLineLength = lineLen
}
}
fmt.Printf("\n\n")
fmt.Println(strings.Repeat("+", maxLineLength+8))
for _, line := range lines {
fmt.Printf("++ %s ++\n", centerText(line, maxLineLength))
}
fmt.Println(strings.Repeat("+", maxLineLength+8))
fmt.Printf("\n\n")
}
// centerText centers text across a fixed width, filling either side with whitespace buffers
func centerText(text string, width int) string {
textLen := len(text)
leftBuffer := strings.Repeat(" ", (width-textLen)/2)
rightBuffer := strings.Repeat(" ", (width-textLen)/2+(width-textLen)%2)
return fmt.Sprintf("%s%s%s", leftBuffer, text, rightBuffer)
}
func getNodeDir(args initArgs, nodeID int) (nodeDirName, nodeDir string) {
nodeDirName = fmt.Sprintf("%s%d", args.nodeDirPrefix, nodeID)
nodeDir = filepath.Join(args.outputDir, nodeDirName, args.nodeDaemonHome)
return
}
// startTestnet starts an in-process testnet
func startTestnet(
clientCtx client.Context,
cmd *cobra.Command,
nodeConfig *cmtconfig.Config,
mm *module.Manager,
args initArgs,
) error {
fmt.Printf(`Preparing test network with chain-id "%s"`, args.chainID)
args.outputDir = fmt.Sprintf("%s/%s", args.outputDir, args.chainID)
err := initTestnetFiles(clientCtx, cmd, nodeConfig, mm, args)
if err != nil {
return err
}
// slice to keep track of validator processes
var processes []*exec.Cmd
// channel to signal shutdown
shutdownCh := make(chan struct{})
fmt.Println("Starting test network...")
// Start each validator in a separate process
for i := 0; i < args.numValidators; i++ {
_, nodeDir := getNodeDir(args, i)
// run start command
binName := cmd.Root().Use
cmdArgs := []string{"start", fmt.Sprintf("--%s=%s", flags.FlagHome, nodeDir)}
runCmd := exec.Command(binName, cmdArgs...) // spawn new process
// Set stdout and stderr based on enableLogging flag
if args.enableLogging {
runCmd.Stdout = os.Stdout
runCmd.Stderr = os.Stderr
} else {
runCmd.Stdout = io.Discard // discard output when logging is disabled
runCmd.Stderr = io.Discard
}
if err := runCmd.Start(); err != nil {
return fmt.Errorf("failed to start validator %d: %w", i, err)
}
fmt.Printf("Started Validator %d\n", i+1)
processes = append(processes, runCmd) // add to processes slice
}
// goroutine to listen for Enter key press
go func() {
fmt.Println("Press the Enter Key to terminate all validator processes")
if _, err := fmt.Scanln(); err == nil {
close(shutdownCh) // Signal shutdown
}
}()
// goroutine to listen for Ctrl+C (SIGINT)
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt)
go func() {
<-sigCh // Wait for Ctrl+C
fmt.Println("\nCtrl+C detected, terminating validator processes...")
close(shutdownCh) // Signal shutdown
}()
// block until shutdown signal is received
<-shutdownCh
// terminate all validator processes
fmt.Println("Shutting down validator processes...")
for i, p := range processes {
if err := p.Process.Kill(); err != nil {
fmt.Printf("Failed to terminate validator %d process: %v\n", i+1, err)
} else {
fmt.Printf("Validator %d terminated\n", i+1)
}
}
_ = os.RemoveAll(args.outputDir) // Clean up the output directory
fmt.Println("Finished cleaning up test network")
return nil
}

View File

@ -1,88 +0,0 @@
package cmd
import (
"context"
"fmt"
"testing"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
corectx "cosmossdk.io/core/context"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
banktypes "cosmossdk.io/x/bank/types"
"cosmossdk.io/x/staking"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil"
"github.com/cosmos/cosmos-sdk/testutil/configurator"
genutiltest "github.com/cosmos/cosmos-sdk/testutil/x/genutil"
"github.com/cosmos/cosmos-sdk/types/module"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
"github.com/cosmos/cosmos-sdk/x/auth"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
)
func Test_TestnetCmd(t *testing.T) {
config := configurator.NewAppConfig(
configurator.AccountsModule(),
configurator.AuthModule(),
configurator.BankModule(),
configurator.GenutilModule(),
configurator.StakingModule(),
configurator.ConsensusModule(),
configurator.TxModule(),
configurator.ValidateModule(),
configurator.MintModule(),
)
var moduleManager *module.Manager
err := depinject.Inject(
depinject.Configs(config,
depinject.Supply(log.NewNopLogger()),
),
&moduleManager,
)
require.NoError(t, err)
require.NotNil(t, moduleManager)
require.Len(t, moduleManager.Modules, 9) // the registered above + runtime
home := t.TempDir()
cdcOpts := codectestutil.CodecOptions{}
encodingConfig := moduletestutil.MakeTestEncodingConfig(cdcOpts, auth.AppModule{}, staking.AppModule{})
logger := log.NewNopLogger()
viper := viper.New()
cfg, err := genutiltest.CreateDefaultCometConfig(home)
require.NoError(t, err)
err = genutiltest.ExecInitCmd(moduleManager, home, encodingConfig.Codec)
require.NoError(t, err)
err = genutiltest.WriteAndTrackCometConfig(viper, home, cfg)
require.NoError(t, err)
clientCtx := client.Context{}.
WithCodec(encodingConfig.Codec).
WithHomeDir(home).
WithTxConfig(encodingConfig.TxConfig).
WithAddressCodec(cdcOpts.GetAddressCodec()).
WithValidatorAddressCodec(cdcOpts.GetValidatorCodec())
ctx := context.Background()
ctx = context.WithValue(ctx, corectx.ViperContextKey, viper)
ctx = context.WithValue(ctx, corectx.LoggerContextKey, logger)
ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx)
cmd := testnetInitFilesCmd(moduleManager)
cmd.SetArgs(
[]string{fmt.Sprintf("--%s=test", flags.FlagKeyringBackend), fmt.Sprintf("--output-dir=%s", home)},
)
err = cmd.ExecuteContext(ctx)
require.NoError(t, err)
genFile := client.GetConfigFromCmd(cmd).GenesisFile()
appState, _, err := genutiltypes.GenesisStateFromGenFile(genFile)
require.NoError(t, err)
bankGenState := banktypes.GetGenesisStateFromAppState(encodingConfig.Codec, appState)
require.NotEmpty(t, bankGenState.Supply.String())
}

View File

@ -1,20 +0,0 @@
package main
import (
"fmt"
"os"
clientv2helpers "cosmossdk.io/client/v2/helpers"
"cosmossdk.io/simapp"
"cosmossdk.io/simapp/simd/cmd"
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
)
func main() {
rootCmd := cmd.NewRootCmd()
if err := svrcmd.Execute(rootCmd, clientv2helpers.EnvPrefix, simapp.DefaultNodeHome); err != nil {
fmt.Fprintln(rootCmd.OutOrStderr(), err)
os.Exit(1)
}
}

View File

@ -1,221 +0,0 @@
package simapp
import (
"encoding/json"
"testing"
abci "github.com/cometbft/cometbft/api/cometbft/abci/v1"
cmtjson "github.com/cometbft/cometbft/libs/json"
cmttypes "github.com/cometbft/cometbft/types"
"github.com/stretchr/testify/require"
corestore "cosmossdk.io/core/store"
coretesting "cosmossdk.io/core/testing"
"cosmossdk.io/log"
sdkmath "cosmossdk.io/math"
banktypes "cosmossdk.io/x/bank/types"
minttypes "cosmossdk.io/x/mint/types"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/server"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
"github.com/cosmos/cosmos-sdk/testutil/mock"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
// SetupOptions defines arguments that are passed into `Simapp` constructor.
type SetupOptions struct {
Logger log.Logger
DB corestore.KVStoreWithBatch
AppOpts servertypes.AppOptions
}
func setup(withGenesis bool, invCheckPeriod uint) (*SimApp, GenesisState) {
db := coretesting.NewMemDB()
appOptions := make(simtestutil.AppOptionsMap, 0)
appOptions[flags.FlagHome] = DefaultNodeHome
appOptions[server.FlagInvCheckPeriod] = invCheckPeriod
app := NewSimApp(log.NewNopLogger(), db, nil, true, appOptions)
if withGenesis {
return app, app.DefaultGenesis()
}
return app, GenesisState{}
}
// NewSimappWithCustomOptions initializes a new SimApp with custom options.
func NewSimappWithCustomOptions(t *testing.T, isCheckTx bool, options SetupOptions) *SimApp {
t.Helper()
privVal := mock.NewPV()
pubKey, err := privVal.GetPubKey()
require.NoError(t, err)
// create validator set with single validator
validator := cmttypes.NewValidator(pubKey, 1)
valSet := cmttypes.NewValidatorSet([]*cmttypes.Validator{validator})
app := NewSimApp(options.Logger, options.DB, nil, true, options.AppOpts)
// generate genesis account
senderPrivKey := secp256k1.GenPrivKey()
acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0)
accAddr, err := app.InterfaceRegistry().SigningContext().AddressCodec().BytesToString(acc.GetAddress())
require.NoError(t, err)
balance := banktypes.Balance{
Address: accAddr,
Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(100000000000000))),
}
genesisState := app.DefaultGenesis()
genesisState, err = simtestutil.GenesisStateWithValSet(app.AppCodec(), genesisState, valSet, []authtypes.GenesisAccount{acc}, balance)
require.NoError(t, err)
if !isCheckTx {
// init chain must be called to stop deliverState from being nil
stateBytes, err := cmtjson.MarshalIndent(genesisState, "", " ")
require.NoError(t, err)
// Initialize the chain
_, err = app.InitChain(&abci.InitChainRequest{
Validators: []abci.ValidatorUpdate{},
ConsensusParams: simtestutil.DefaultConsensusParams,
AppStateBytes: stateBytes,
})
require.NoError(t, err)
}
return app
}
// Setup initializes a new SimApp. A Nop logger is set in SimApp.
func Setup(t *testing.T, isCheckTx bool) *SimApp {
t.Helper()
privVal := mock.NewPV()
pubKey, err := privVal.GetPubKey()
require.NoError(t, err)
// create validator set with single validator
validator := cmttypes.NewValidator(pubKey, 1)
valSet := cmttypes.NewValidatorSet([]*cmttypes.Validator{validator})
sApp, _ := setup(true, 0)
// generate genesis account
senderPrivKey := secp256k1.GenPrivKey()
acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0)
accAddr, err := sApp.interfaceRegistry.SigningContext().AddressCodec().BytesToString(acc.GetAddress())
require.NoError(t, err)
balance := banktypes.Balance{
Address: accAddr,
Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(100000000000000))),
}
app := SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, balance)
return app
}
// SetupWithGenesisValSet initializes a new SimApp with a validator set and genesis accounts
// that also act as delegators. For simplicity, each validator is bonded with a delegation
// of one consensus engine unit in the default token of the simapp from first genesis
// account. A Nop logger is set in SimApp.
func SetupWithGenesisValSet(t *testing.T, valSet *cmttypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *SimApp {
t.Helper()
app, genesisState := setup(true, 5)
genesisState, err := simtestutil.GenesisStateWithValSet(app.AppCodec(), genesisState, valSet, genAccs, balances...)
require.NoError(t, err)
stateBytes, err := json.MarshalIndent(genesisState, "", " ")
require.NoError(t, err)
// init chain will set the validator set and initialize the genesis accounts
_, err = app.InitChain(&abci.InitChainRequest{
Validators: []abci.ValidatorUpdate{},
ConsensusParams: simtestutil.DefaultConsensusParams,
AppStateBytes: stateBytes,
},
)
require.NoError(t, err)
require.NoError(t, err)
_, err = app.FinalizeBlock(&abci.FinalizeBlockRequest{
Height: app.LastBlockHeight() + 1,
Hash: app.LastCommitID().Hash,
NextValidatorsHash: valSet.Hash(),
})
require.NoError(t, err)
return app
}
// GenesisStateWithSingleValidator initializes GenesisState with a single validator and genesis accounts
// that also act as delegators.
func GenesisStateWithSingleValidator(t *testing.T, app *SimApp) GenesisState {
t.Helper()
privVal := mock.NewPV()
pubKey, err := privVal.GetPubKey()
require.NoError(t, err)
// create validator set with single validator
validator := cmttypes.NewValidator(pubKey, 1)
valSet := cmttypes.NewValidatorSet([]*cmttypes.Validator{validator})
// generate genesis account
senderPrivKey := secp256k1.GenPrivKey()
acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0)
accAddr, err := app.interfaceRegistry.SigningContext().AddressCodec().BytesToString(acc.GetAddress())
require.NoError(t, err)
balances := []banktypes.Balance{
{
Address: accAddr,
Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(100000000000000))),
},
}
genesisState := app.DefaultGenesis()
genesisState, err = simtestutil.GenesisStateWithValSet(app.AppCodec(), genesisState, valSet, []authtypes.GenesisAccount{acc}, balances...)
require.NoError(t, err)
return genesisState
}
// AddTestAddrsIncremental constructs and returns accNum amount of accounts with an
// initial balance of accAmt in random order
func AddTestAddrsIncremental(app *SimApp, ctx sdk.Context, accNum int, accAmt sdkmath.Int) []sdk.AccAddress {
return addTestAddrs(app, ctx, accNum, accAmt, simtestutil.CreateIncrementalAccounts)
}
func addTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdkmath.Int, strategy simtestutil.GenerateAccountStrategy) []sdk.AccAddress {
testAddrs := strategy(accNum)
bondDenom, err := app.StakingKeeper.BondDenom(ctx)
if err != nil {
panic(err)
}
initCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, accAmt))
for _, addr := range testAddrs {
initAccountWithCoins(app, ctx, addr, initCoins)
}
return testAddrs
}
func initAccountWithCoins(app *SimApp, ctx sdk.Context, addr sdk.AccAddress, coins sdk.Coins) {
err := app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, coins)
if err != nil {
panic(err)
}
err = app.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, addr, coins)
if err != nil {
panic(err)
}
}

View File

@ -1,42 +0,0 @@
package simapp
import (
"context"
"cosmossdk.io/core/appmodule"
corestore "cosmossdk.io/core/store"
bankv2types "cosmossdk.io/x/bank/v2/types"
upgradetypes "cosmossdk.io/x/upgrade/types"
)
// UpgradeName defines the on-chain upgrade name for the sample SimApp upgrade
// from v0.52.x to v0.54.x
//
// NOTE: This upgrade defines a reference implementation of what an upgrade
// could look like when an application is migrating from Cosmos SDK version
// v0.52.x to v0.54.x.
const UpgradeName = "v052-to-v054"
func (app SimApp) RegisterUpgradeHandlers() {
app.UpgradeKeeper.SetUpgradeHandler(
UpgradeName,
func(ctx context.Context, _ upgradetypes.Plan, fromVM appmodule.VersionMap) (appmodule.VersionMap, error) {
return app.ModuleManager.RunMigrations(ctx, app.Configurator(), fromVM)
},
)
upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
if err != nil {
panic(err)
}
if upgradeInfo.Name == UpgradeName && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
storeUpgrades := corestore.StoreUpgrades{
Added: []string{bankv2types.StoreKey},
Deleted: []string{},
}
// configure store loader that checks if version == upgradeHeight and applies store upgrades
app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades))
}
}

View File

@ -1,55 +0,0 @@
package simapp
import (
"testing"
cmtproto "github.com/cometbft/cometbft/api/cometbft/types/v1"
"github.com/stretchr/testify/require"
"cosmossdk.io/collections"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
// TestSyncAccountNumber tests if accounts module account number is set correctly with the value get from auth.
// Also check if the store entry for auth GlobalAccountNumberKey is successfully deleted.
func TestSyncAccountNumber(t *testing.T) {
app := Setup(t, true)
ctx := app.NewUncachedContext(true, cmtproto.Header{})
bytesKey := authtypes.GlobalAccountNumberKey
store := app.AuthKeeper.KVStoreService.OpenKVStore(ctx)
// initially there is no value set yet
v, err := store.Get(bytesKey)
require.NoError(t, err)
require.Nil(t, v)
// set value for legacy account number
v, err = collections.Uint64Value.Encode(10)
require.NoError(t, err)
err = store.Set(bytesKey, v)
require.NoError(t, err)
// make sure value are updated
v, err = store.Get(bytesKey)
require.NoError(t, err)
require.NotEmpty(t, v)
num, err := collections.Uint64Value.Decode(v)
require.NoError(t, err)
require.Equal(t, uint64(10), num)
err = authkeeper.MigrateAccountNumberUnsafe(ctx, &app.AuthKeeper)
require.NoError(t, err)
// make sure the DB entry for this key is deleted
v, err = store.Get(bytesKey)
require.NoError(t, err)
require.Nil(t, v)
// check if accounts's account number is updated
currentNum, err := app.AccountsKeeper.AccountNumber.Peek(ctx)
require.NoError(t, err)
require.Equal(t, uint64(10), currentNum)
}

View File

@ -6,3 +6,117 @@ sidebar_position: 1
SimApp is an application built using the Cosmos SDK for testing and educational purposes.
`SimApp/v2` demonstrate a runtime/v2, server/v2 and store/v2 wiring.
## Running testnets with `simdv2`
Except stated otherwise, all participants in the testnet must follow through with each step.
### 1. Download and Setup
Download the Cosmos SDK and unzip it. You can do this manually (via the GitHub UI) or with the git clone command.
```sh
git clone github.com/cosmos/cosmos-sdk.git
```
Next, run this command to build the `simdv2` binary in the `build` directory.
```sh
make build
```
Use the following command and skip all the next steps to configure your SimApp node:
```sh
make init-simapp-v2
```
If youve run `simd` in the past, you may need to reset your database before starting up a new testnet. You can do that with this command:
```sh
# you need to provide the moniker and chain ID
$ ./simdv2 init [moniker] --chain-id [chain-id]
```
The command should initialize a new working directory at the `~simappv2` location.
The `moniker` and `chain-id` can be anything but you need to use the same `chain-id` subsequently.
### 2. Create a New Key
Execute this command to create a new key.
```sh
./simdv2 keys add [key_name]
```
The command will create a new key with your chosen name.
⚠️ Save the output somewhere safe; youll need the address later.
### 3. Add Genesis Account
Add a genesis account to your testnet blockchain.
```sh
./simdv2 genesis add-genesis-account [key_name] [amount]
```
Where `key_name` is the same key name as before, and the `amount` is something like `10000000000000000000000000stake`.
### 4. Add the Genesis Transaction
This creates the genesis transaction for your testnet chain.
```sh
./simdv2 genesis gentx [key_name] [amount] --chain-id [chain-id]
```
The amount should be at least `1000000000stake`. When you start your node, providing too much or too little may result in errors.
### 5. Create the Genesis File
A participant must create the genesis file `genesis.json` with every participant's transaction.
You can do this by gathering all the Genesis transactions under `config/gentx` and then executing this command.
```sh
./simdv2 genesis collect-gentxs
```
The command will create a new `genesis.json` file that includes data from all the validators. The command will create a new `genesis.json` file, including data from all the validators
Once you've received the super genesis file, overwrite your original `genesis.json` file with
the new super `genesis.json`.
Modify your `config/config.toml` (in the simapp working directory) to include the other participants as
persistent peers:
```toml
# Comma-separated list of nodes to keep persistent connections to
persistent_peers = "[validator_address]@[ip_address]:[port],[validator_address]@[ip_address]:[port]"
```
You can find `validator_address` by executing:
```sh
./simdv2 comet show-node-id
```
The output will be the hex-encoded `validator_address`. The default `port` is 26656.
### 6. Start the Nodes
Finally, execute this command to start your nodes.
```sh
./simdv2 start
```
Now you have a small testnet that you can use to try out changes to the Cosmos SDK or CometBFT!
> ⚠️ NOTE: Sometimes, creating the network through the `collect-gents` will fail, and validators will start in a funny state (and then panic).
If this happens, you can try to create and start the network first
with a single validator and then add additional validators using a `create-validator` transaction.

View File

@ -9,11 +9,9 @@ require (
cosmossdk.io/depinject v1.1.0
cosmossdk.io/log v1.5.0
cosmossdk.io/math v1.4.0
cosmossdk.io/simapp v0.0.0-20230309163709-87da587416ba
cosmossdk.io/store v1.10.0-rc.1
cosmossdk.io/x/evidence v0.0.0-20230613133644-0a778132a60f
cosmossdk.io/x/feegrant v0.0.0-20230613133644-0a778132a60f
cosmossdk.io/x/nft v0.0.0-20230613133644-0a778132a60f // indirect
cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190
cosmossdk.io/x/tx v1.0.0-alpha.3
cosmossdk.io/x/upgrade v0.0.0-20230613133644-0a778132a60f
@ -71,11 +69,8 @@ require (
cosmossdk.io/client/v2 v2.0.0-beta.6 // indirect
cosmossdk.io/errors v1.0.1 // indirect
cosmossdk.io/errors/v2 v2.0.0 // indirect
cosmossdk.io/indexer/postgres v0.1.0 // indirect
cosmossdk.io/schema v1.0.0 // indirect
cosmossdk.io/server/v2/appmanager v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/tools/benchmark v0.0.0-00010101000000-000000000000 // indirect
cosmossdk.io/x/circuit v0.0.0-20230613133644-0a778132a60f // indirect
cosmossdk.io/x/epochs v0.0.0-20240522060652-a1ae4c3e0337 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
@ -159,10 +154,6 @@ require (
github.com/huandu/skiplist v1.2.1 // indirect
github.com/iancoleman/strcase v0.3.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.7.1 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/klauspost/compress v1.17.11 // indirect
@ -281,8 +272,6 @@ replace (
// Below are the long-lived replace for tests.
replace (
// We always want to test against the latest version of the simapp.
cosmossdk.io/simapp => ../simapp
github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0
// We always want to test against the latest version of the SDK.
github.com/cosmos/cosmos-sdk => ../.

View File

@ -606,14 +606,6 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=
github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=

View File

@ -1,85 +0,0 @@
package rootmulti_test
import (
"fmt"
"testing"
abci "github.com/cometbft/cometbft/api/cometbft/abci/v1"
cmtproto "github.com/cometbft/cometbft/api/cometbft/types/v1"
"gotest.tools/v3/assert"
coretesting "cosmossdk.io/core/testing"
"cosmossdk.io/log"
"cosmossdk.io/simapp"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
)
func TestRollback(t *testing.T) {
db := coretesting.NewMemDB()
options := simapp.SetupOptions{
Logger: log.NewNopLogger(),
DB: db,
AppOpts: simtestutil.NewAppOptionsWithFlagHome(t.TempDir()),
}
app := simapp.NewSimappWithCustomOptions(t, false, options)
ver0 := app.LastBlockHeight()
// commit 10 blocks
for i := int64(1); i <= 10; i++ {
header := cmtproto.Header{
Height: ver0 + i,
AppHash: app.LastCommitID().Hash,
}
_, err := app.FinalizeBlock(&abci.FinalizeBlockRequest{
Height: header.Height,
})
assert.NilError(t, err)
ctx := app.NewContextLegacy(false, header)
store := ctx.KVStore(app.GetKey("bank"))
store.Set([]byte("key"), []byte(fmt.Sprintf("value%d", i)))
_, err = app.FinalizeBlock(&abci.FinalizeBlockRequest{
Height: header.Height,
})
assert.NilError(t, err)
_, err = app.Commit()
assert.NilError(t, err)
}
assert.Equal(t, ver0+10, app.LastBlockHeight())
store := app.NewContext(true).KVStore(app.GetKey("bank"))
assert.DeepEqual(t, []byte("value10"), store.Get([]byte("key")))
// rollback 5 blocks
target := ver0 + 5
assert.NilError(t, app.CommitMultiStore().RollbackToVersion(target))
assert.Equal(t, target, app.LastBlockHeight())
// recreate app to have clean check state
app = simapp.NewSimApp(options.Logger, options.DB, nil, true, simtestutil.NewAppOptionsWithFlagHome(t.TempDir()))
store = app.NewContext(true).KVStore(app.GetKey("bank"))
assert.DeepEqual(t, []byte("value5"), store.Get([]byte("key")))
// commit another 5 blocks with different values
for i := int64(6); i <= 10; i++ {
header := cmtproto.Header{
Height: ver0 + i,
AppHash: app.LastCommitID().Hash,
}
_, err := app.FinalizeBlock(&abci.FinalizeBlockRequest{Height: header.Height})
assert.NilError(t, err)
ctx := app.NewContextLegacy(false, header)
store := ctx.KVStore(app.GetKey("bank"))
store.Set([]byte("key"), []byte(fmt.Sprintf("VALUE%d", i)))
_, err = app.FinalizeBlock(&abci.FinalizeBlockRequest{
Height: header.Height,
})
assert.NilError(t, err)
_, err = app.Commit()
assert.NilError(t, err)
}
assert.Equal(t, ver0+10, app.LastBlockHeight())
store = app.NewContext(true).KVStore(app.GetKey("bank"))
assert.DeepEqual(t, []byte("VALUE10"), store.Get([]byte("key")))
}

View File

@ -247,7 +247,7 @@ func (s *IntegrationTestSuite) setupStakingParams(ctx context.Context, sk *staki
require.NoError(s.T(), err)
// update unbonding time
params.UnbondingTime = time.Duration(time.Second * 10)
params.UnbondingTime = time.Second * 10
err = sk.Params.Set(ctx, params)
require.NoError(s.T(), err)
}

View File

@ -104,8 +104,8 @@ type StartupConfig struct {
GasService gas.Service
}
func DefaultStartUpConfig(t testing.TB) StartupConfig {
t.Helper()
func DefaultStartUpConfig(tb testing.TB) StartupConfig {
tb.Helper()
priv := secp256k1.GenPrivKey()
ba := authtypes.NewBaseAccount(
@ -120,8 +120,8 @@ func DefaultStartUpConfig(t testing.TB) StartupConfig {
sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(100000000000000)),
),
}
homedir := t.TempDir()
t.Logf("generated integration test app config; HomeDir=%s", homedir)
homedir := tb.TempDir()
tb.Logf("generated integration test app config; HomeDir=%s", homedir)
return StartupConfig{
ValidatorSet: CreateRandomValidatorSet,
GenesisBehavior: Genesis_COMMIT,

View File

@ -10,7 +10,6 @@ import (
"cosmossdk.io/depinject"
"cosmossdk.io/log"
"cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
_ "cosmossdk.io/x/accounts" // import as blank for app wiring
_ "cosmossdk.io/x/bank" // import as blank for app wiring
bankkeeper "cosmossdk.io/x/bank/keeper"
@ -45,9 +44,8 @@ var (
type fixture struct {
app *integration.App
ctx context.Context
cdc codec.Codec
keys map[string]*storetypes.KVStoreKey
ctx context.Context
cdc codec.Codec
queryClient stakingkeeper.Querier

View File

@ -4,7 +4,7 @@ go 1.23
require (
cosmossdk.io/math v1.4.0
cosmossdk.io/systemtests v1.0.0-rc.4.0.20241219115822-5bebfb028815
cosmossdk.io/systemtests v1.0.0
github.com/cosmos/cosmos-sdk v0.50.11
)

View File

@ -16,8 +16,8 @@ cosmossdk.io/math v1.4.0 h1:XbgExXFnXmF/CccPPEto40gOO7FpWu9yWNAZPN3nkNQ=
cosmossdk.io/math v1.4.0/go.mod h1:O5PkD4apz2jZs4zqFdTr16e1dcaQCc5z6lkEnrrppuk=
cosmossdk.io/store v1.1.1 h1:NA3PioJtWDVU7cHHeyvdva5J/ggyLDkyH0hGHl2804Y=
cosmossdk.io/store v1.1.1/go.mod h1:8DwVTz83/2PSI366FERGbWSH7hL6sB7HbYp8bqksNwM=
cosmossdk.io/systemtests v1.0.0-rc.4.0.20241219115822-5bebfb028815 h1:ilHcBaGJrYhEKC2gO+DVBmWOPNt1VUWNQz3g7/9X4Ow=
cosmossdk.io/systemtests v1.0.0-rc.4.0.20241219115822-5bebfb028815/go.mod h1:tTDdBl9wnIyP4L1Gi1/GXD1onPfaAOsscWCw7JUuJ/A=
cosmossdk.io/systemtests v1.0.0 h1:VuEj4aA//v1icbMoA6UMuWOwO6ejb6uK7PzSBT+Y460=
cosmossdk.io/systemtests v1.0.0/go.mod h1:6kl2MKa7tLoW8vgKx4ZgwAqWVD1T7eAiL5mc/9R7XGY=
cosmossdk.io/x/tx v1.0.0-alpha.3 h1:+55/JFH5QRqnFhOI2heH3DKsaNL0RpXcJOQNzUvHiaQ=
cosmossdk.io/x/tx v1.0.0-alpha.3/go.mod h1:h4pQ/j6Gfu8goB1R3Jbl4qY4RjYVNAsoylcleTXdSRg=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=

View File

@ -6,7 +6,7 @@ import (
"io"
"testing"
"github.com/gogo/protobuf/types"
"github.com/cosmos/gogoproto/types"
"github.com/stretchr/testify/suite"
"cosmossdk.io/math"

View File

@ -16,6 +16,8 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
const valAddress = "val_address"
func setupContinuousAccount(t *testing.T, ctx context.Context, ss store.KVStoreService) *ContinuousLockingAccount {
t.Helper()
deps := makeMockDependencies(ss)
@ -42,7 +44,7 @@ func TestContinuousAccountDelegate(t *testing.T) {
acc := setupContinuousAccount(t, sdkCtx, ss)
_, err := acc.Delegate(sdkCtx, &lockuptypes.MsgDelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(1)),
})
require.NoError(t, err)
@ -61,7 +63,7 @@ func TestContinuousAccountDelegate(t *testing.T) {
_, err = acc.Delegate(sdkCtx, &lockuptypes.MsgDelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(5)),
})
require.NoError(t, err)
@ -85,7 +87,7 @@ func TestContinuousAccountUndelegate(t *testing.T) {
// Delegate first
_, err := acc.Delegate(sdkCtx, &lockuptypes.MsgDelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(1)),
})
require.NoError(t, err)
@ -97,21 +99,21 @@ func TestContinuousAccountUndelegate(t *testing.T) {
// Undelegate
_, err = acc.Undelegate(sdkCtx, &lockuptypes.MsgUndelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(1)),
})
require.NoError(t, err)
entries, err := acc.UnbondEntries.Get(sdkCtx, "val_address")
entries, err := acc.UnbondEntries.Get(sdkCtx, valAddress)
require.NoError(t, err)
require.Len(t, entries.Entries, 1)
require.True(t, entries.Entries[0].Amount.Amount.Equal(math.NewInt(1)))
require.True(t, entries.Entries[0].ValidatorAddress == "val_address")
require.True(t, entries.Entries[0].ValidatorAddress == valAddress)
err = acc.checkUnbondingEntriesMature(sdkCtx)
require.NoError(t, err)
_, err = acc.UnbondEntries.Get(sdkCtx, "val_address")
_, err = acc.UnbondEntries.Get(sdkCtx, valAddress)
require.Error(t, err)
delLocking, err = acc.DelegatedLocking.Get(ctx, "test")

View File

@ -41,7 +41,7 @@ func TestDelayedAccountDelegate(t *testing.T) {
acc := setupDelayedAccount(t, sdkCtx, ss)
_, err := acc.Delegate(sdkCtx, &lockuptypes.MsgDelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(1)),
})
require.NoError(t, err)
@ -60,7 +60,7 @@ func TestDelayedAccountDelegate(t *testing.T) {
_, err = acc.Delegate(sdkCtx, &lockuptypes.MsgDelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(5)),
})
require.NoError(t, err)
@ -84,7 +84,7 @@ func TestDelayedAccountUndelegate(t *testing.T) {
// Delegate first
_, err := acc.Delegate(sdkCtx, &lockuptypes.MsgDelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(1)),
})
require.NoError(t, err)
@ -96,21 +96,21 @@ func TestDelayedAccountUndelegate(t *testing.T) {
// Undelegate
_, err = acc.Undelegate(sdkCtx, &lockuptypes.MsgUndelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(1)),
})
require.NoError(t, err)
entries, err := acc.UnbondEntries.Get(sdkCtx, "val_address")
entries, err := acc.UnbondEntries.Get(sdkCtx, valAddress)
require.NoError(t, err)
require.Len(t, entries.Entries, 1)
require.True(t, entries.Entries[0].Amount.Amount.Equal(math.NewInt(1)))
require.True(t, entries.Entries[0].ValidatorAddress == "val_address")
require.True(t, entries.Entries[0].ValidatorAddress == valAddress)
err = acc.checkUnbondingEntriesMature(sdkCtx)
require.NoError(t, err)
_, err = acc.UnbondEntries.Get(sdkCtx, "val_address")
_, err = acc.UnbondEntries.Get(sdkCtx, valAddress)
require.Error(t, err)
delLocking, err = acc.DelegatedLocking.Get(ctx, "test")

View File

@ -386,7 +386,7 @@ func (bva *BaseLockup) checkUnbondingEntriesMature(ctx context.Context) error {
found := false
// check if the entry is still exist in the unbonding entries
for _, e := range stakingUnbonding {
if e.CompletionTime.Equal(entry.EndTime) && entry.CreationHeight == entry.CreationHeight {
if e.CompletionTime.Equal(entry.EndTime) && e.CreationHeight == entry.CreationHeight {
found = true
break
}

View File

@ -55,7 +55,7 @@ func TestPeriodicAccountDelegate(t *testing.T) {
acc := setupPeriodicAccount(t, sdkCtx, ss)
_, err := acc.Delegate(sdkCtx, &lockuptypes.MsgDelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(1)),
})
require.NoError(t, err)
@ -74,7 +74,7 @@ func TestPeriodicAccountDelegate(t *testing.T) {
_, err = acc.Delegate(sdkCtx, &lockuptypes.MsgDelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(5)),
})
require.NoError(t, err)
@ -94,7 +94,7 @@ func TestPeriodicAccountDelegate(t *testing.T) {
_, err = acc.Delegate(sdkCtx, &lockuptypes.MsgDelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(4)),
})
require.NoError(t, err)
@ -118,7 +118,7 @@ func TestPeriodicAccountUndelegate(t *testing.T) {
// Delegate first
_, err := acc.Delegate(sdkCtx, &lockuptypes.MsgDelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(1)),
})
require.NoError(t, err)
@ -130,22 +130,22 @@ func TestPeriodicAccountUndelegate(t *testing.T) {
// Undelegate
_, err = acc.Undelegate(sdkCtx, &lockuptypes.MsgUndelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(1)),
})
require.NoError(t, err)
// sequence should be the previous one
entries, err := acc.UnbondEntries.Get(sdkCtx, "val_address")
entries, err := acc.UnbondEntries.Get(sdkCtx, valAddress)
require.NoError(t, err)
require.Len(t, entries.Entries, 1)
require.True(t, entries.Entries[0].Amount.Amount.Equal(math.NewInt(1)))
require.True(t, entries.Entries[0].ValidatorAddress == "val_address")
require.True(t, entries.Entries[0].ValidatorAddress == valAddress)
err = acc.checkUnbondingEntriesMature(sdkCtx)
require.NoError(t, err)
_, err = acc.UnbondEntries.Get(sdkCtx, "val_address")
_, err = acc.UnbondEntries.Get(sdkCtx, valAddress)
require.Error(t, err)
delLocking, err = acc.DelegatedLocking.Get(ctx, "test")

View File

@ -40,7 +40,7 @@ func TestPermanentAccountDelegate(t *testing.T) {
acc := setupPermanentAccount(t, sdkCtx, ss)
_, err := acc.Delegate(sdkCtx, &lockuptypes.MsgDelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(1)),
})
require.NoError(t, err)
@ -60,7 +60,7 @@ func TestPermanentAccountUndelegate(t *testing.T) {
// Delegate first
_, err := acc.Delegate(sdkCtx, &lockuptypes.MsgDelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(1)),
})
require.NoError(t, err)
@ -72,22 +72,22 @@ func TestPermanentAccountUndelegate(t *testing.T) {
// Undelegate
_, err = acc.Undelegate(sdkCtx, &lockuptypes.MsgUndelegate{
Sender: "owner",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Amount: sdk.NewCoin("test", math.NewInt(1)),
})
require.NoError(t, err)
// sequence should be the previous one
entries, err := acc.UnbondEntries.Get(sdkCtx, "val_address")
entries, err := acc.UnbondEntries.Get(sdkCtx, valAddress)
require.NoError(t, err)
require.Len(t, entries.Entries, 1)
require.True(t, entries.Entries[0].Amount.Amount.Equal(math.NewInt(1)))
require.True(t, entries.Entries[0].ValidatorAddress == "val_address")
require.True(t, entries.Entries[0].ValidatorAddress == valAddress)
err = acc.checkUnbondingEntriesMature(sdkCtx)
require.NoError(t, err)
_, err = acc.UnbondEntries.Get(sdkCtx, "val_address")
_, err = acc.UnbondEntries.Get(sdkCtx, valAddress)
require.Error(t, err)
delLocking, err = acc.DelegatedLocking.Get(ctx, "test")

View File

@ -100,7 +100,7 @@ func newMockContext(t *testing.T) (context.Context, store.KVStoreService) {
return &stakingtypes.QueryUnbondingDelegationResponse{
Unbond: stakingtypes.UnbondingDelegation{
DelegatorAddress: "sender",
ValidatorAddress: "val_address",
ValidatorAddress: valAddress,
Entries: []stakingtypes.UnbondingDelegationEntry{
{
CreationHeight: 1,

View File

@ -80,7 +80,7 @@ require (
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/gogo/protobuf v1.3.2
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect