From c54279d0b0ec1d98226ed0447814d45be2cd957d Mon Sep 17 00:00:00 2001 From: Adam Tucker Date: Tue, 17 Oct 2023 12:26:14 -0600 Subject: [PATCH 01/25] chore: add cosmovisor binaries json (#6714) * adds cosmo binaries * fix mainnet sha --- .../upgrades/v20/mainnet/v20_binaries.json | 4 ++-- networks/osmosis-1/upgrades/v20/testnet/guide.md | 14 +++++++------- .../upgrades/v20/testnet/v20_binaries.json | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/networks/osmosis-1/upgrades/v20/mainnet/v20_binaries.json b/networks/osmosis-1/upgrades/v20/mainnet/v20_binaries.json index df2e35bd6ae..63eaf6066b5 100644 --- a/networks/osmosis-1/upgrades/v20/mainnet/v20_binaries.json +++ b/networks/osmosis-1/upgrades/v20/mainnet/v20_binaries.json @@ -1,6 +1,6 @@ { "binaries": { - "linux/amd64": "https://github.com/osmosis-labs/osmosis/releases/download/TODO/osmosisd-TODO-linux-amd64?checksum=sha256:TODO", - "linux/arm64": "https://github.com/osmosis-labs/osmosis/releases/download/TODO/osmosisd-TODO-linux-arm64?checksum=sha256:TODO" + "linux/amd64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.0.0/osmosisd-20.0.0-linux-amd64?checksum=sha256:6f0a3e5900a58f24d50c2a01c6e920a57698907a099cabe4845e0b7b682a2936", + "linux/arm64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.0.0/osmosisd-20.0.0-linux-arm64?checksum=sha256:f24dd72646fd8a554ee2538f8b5e8d62c442954e62661d646e685cdb43495056" } } \ No newline at end of file diff --git a/networks/osmosis-1/upgrades/v20/testnet/guide.md b/networks/osmosis-1/upgrades/v20/testnet/guide.md index cf51bc91d2a..3e136006e87 100644 --- a/networks/osmosis-1/upgrades/v20/testnet/guide.md +++ b/networks/osmosis-1/upgrades/v20/testnet/guide.md @@ -2,9 +2,9 @@ ## Overview -- **v20 Proposal**: [Proposal Page](https://www.mintscan.io/osmosis/proposals/TODO) -- **v20 Upgrade Block Height**: `TODO` -- **v20 Upgrade Countdown**: [Block Countdown](https://www.mintscan.io/osmosis/blocks/TODO) +- **v20 Proposal**: [Proposal Page](https://testnet.mintscan.io/osmosis-testnet/proposals/113) +- **v20 Upgrade Block Height**: `3197200` +- **v20 Upgrade Countdown**: [Block Countdown](https://testnet.mintscan.io/osmosis-testnet/blocks/3197200) ## Hardware Requirements @@ -82,12 +82,12 @@ source ~/.profile mkdir -p ~/.osmosisd/cosmovisor/upgrades/v20/bin cd $HOME/osmosis git pull -git checkout v20.0.0-rc0 +git checkout v20.0.0-rc1-testnet make build cp build/osmosisd ~/.osmosisd/cosmovisor/upgrades/v20/bin ``` -At the designated block height, Cosmovisor will automatically upgrade to version v20.0.0-rc0. +At the designated block height, Cosmovisor will automatically upgrade to version v20.0.0-rc1-testnet. --- @@ -95,14 +95,14 @@ At the designated block height, Cosmovisor will automatically upgrade to version Follow these steps if you opt for a manual upgrade: -1. Monitor Osmosis until it reaches the specified upgrade block height: TODO. +1. Monitor Osmosis until it reaches the specified upgrade block height: 3197200. 2. Observe for a panic message followed by continuous peer logs, then halt the daemon. 3. Perform these steps: ```sh cd $HOME/osmosis git pull -git checkout v20.0.0-rc0 +git checkout v20.0.0-rc1-testnet make install ``` diff --git a/networks/osmosis-1/upgrades/v20/testnet/v20_binaries.json b/networks/osmosis-1/upgrades/v20/testnet/v20_binaries.json index a0f62d3f493..4f65aa58501 100644 --- a/networks/osmosis-1/upgrades/v20/testnet/v20_binaries.json +++ b/networks/osmosis-1/upgrades/v20/testnet/v20_binaries.json @@ -1,6 +1,6 @@ { "binaries": { - "linux/amd64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.0.0-rc0/osmosisd-20.0.0-rc0-linux-amd64?checksum=sha256:f162c97b560a953f57ff6df7daee35a9c2f1d5efd0c6a210f3657f2a83411709", - "linux/arm64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.0.0-rc0/osmosisd-20.0.0-rc0-linux-arm64?checksum=sha256:60d9a22943b1fa69b2ab44c94867c31714f716872a38f59d1f79a178db170bd1" + "linux/amd64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.0.0-rc1-testnet/osmosisd-20.0.0-rc1-testnet-linux-amd64?checksum=sha256:3da66af3ab42ca13e9ace779981ebed4ba82966018309a304f2dd0d63f392ab2", + "linux/arm64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.0.0-rc1-testnet/osmosisd-20.0.0-rc1-testnet-linux-arm64?checksum=sha256:b1f621e8270d61919b3f6a52d2d889a4593e07d0b688552eb48b859d40a1ef10" } } \ No newline at end of file From a9bcb69b403e14361f3ca91fd875c897704475f8 Mon Sep 17 00:00:00 2001 From: Adam Tucker Date: Tue, 17 Oct 2023 15:29:09 -0600 Subject: [PATCH 02/25] compare branches (#6698) --- .vscode/settings.json | 6 ++++- scripts/compare_git.py | 54 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 scripts/compare_git.py diff --git a/.vscode/settings.json b/.vscode/settings.json index 07146910074..b503f0f012c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -26,5 +26,9 @@ "[proto3]": { "editor.defaultFormatter": "xaver.clang-format" }, - "clang-format.style": "{BasedOnStyle: Google, IndentWidth: 2, ColumnLimit: 120, AlignConsecutiveAssignments: true, AlignConsecutiveDeclarations: true, SpacesInSquareBrackets: true}" + "clang-format.style": "{BasedOnStyle: Google, IndentWidth: 2, ColumnLimit: 120, AlignConsecutiveAssignments: true, AlignConsecutiveDeclarations: true, SpacesInSquareBrackets: true}", + "[python]": { + "editor.defaultFormatter": "ms-python.autopep8" + }, + "python.formatting.provider": "none" } \ No newline at end of file diff --git a/scripts/compare_git.py b/scripts/compare_git.py new file mode 100644 index 00000000000..50745350766 --- /dev/null +++ b/scripts/compare_git.py @@ -0,0 +1,54 @@ +import subprocess +import re + + +def get_commits(branch): + try: + # Get the list of commits in the specified branch + commit_hashes = subprocess.check_output( + ['git', 'log', '--oneline', 'origin/' + branch]).decode().splitlines() + return commit_hashes + except subprocess.CalledProcessError as e: + print(f"Error: {e}") + return [] + + +def get_pr_number(commit_message): + # Extract PR number from commit message + pr_number = re.search(r'#\d+', commit_message) + return pr_number.group(0) if pr_number else None + + +def main(): + release_branch = input("Enter the release branch name: ") + main_branch = input("Enter the main branch name (default: main): ") + + if not main_branch: + main_branch = "main" + + # Fetch the latest branches + subprocess.call(['git', 'fetch'], stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + + main_commits = get_commits(main_branch) + release_commits = get_commits(release_branch) + + main_pr_numbers = {get_pr_number(commit) for commit in main_commits} + release_pr_numbers = {get_pr_number(commit) for commit in release_commits} + + # Find commits in main branch that are not backported to release branch + missing_commits = [commit for commit in main_commits if get_pr_number( + commit) not in release_pr_numbers] + + if not missing_commits: + print( + f"All commits from {main_branch} are present in {release_branch}.") + else: + print( + f"\nCommits present in {main_branch} but missing in {release_branch}:") + for commit in missing_commits: + print(commit) + + +if __name__ == '__main__': + main() From 4a86caf3833691415407e66ffe718b99db90d553 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 16:31:49 -0500 Subject: [PATCH 03/25] chore(deps): bump urllib3 in /scripts/release/create_binaries_json (#6716) Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.0.6 to 2.0.7. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.0.6...2.0.7) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- scripts/release/create_binaries_json/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/release/create_binaries_json/requirements.txt b/scripts/release/create_binaries_json/requirements.txt index c100b62981e..310cf521ff6 100644 --- a/scripts/release/create_binaries_json/requirements.txt +++ b/scripts/release/create_binaries_json/requirements.txt @@ -2,4 +2,4 @@ certifi==2023.7.22 charset-normalizer==3.2.0 idna==3.4 requests==2.31.0 -urllib3==2.0.6 +urllib3==2.0.7 From 60958dd8ad85d3550ed8754834a10757094bd5ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 16:37:45 -0500 Subject: [PATCH 04/25] chore(deps): bump urllib3 in /scripts/release/update_chain_registry (#6717) Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.0.6 to 2.0.7. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.0.6...2.0.7) --- updated-dependencies: - dependency-name: urllib3 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- scripts/release/update_chain_registry/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/release/update_chain_registry/requirements.txt b/scripts/release/update_chain_registry/requirements.txt index c100b62981e..310cf521ff6 100644 --- a/scripts/release/update_chain_registry/requirements.txt +++ b/scripts/release/update_chain_registry/requirements.txt @@ -2,4 +2,4 @@ certifi==2023.7.22 charset-normalizer==3.2.0 idna==3.4 requests==2.31.0 -urllib3==2.0.6 +urllib3==2.0.7 From 85e026e98d8e8aff094f08d9bb352fb1dc0d9a85 Mon Sep 17 00:00:00 2001 From: "Matt, Park" <45252226+mattverse@users.noreply.github.com> Date: Wed, 18 Oct 2023 06:47:25 +0900 Subject: [PATCH 05/25] Make Makefile usable (#6704) --- Makefile | 63 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/Makefile b/Makefile index b644b46fb19..030c9624939 100644 --- a/Makefile +++ b/Makefile @@ -287,16 +287,43 @@ tidy-workspace: ### Proto ### ############################################################################### +proto-help: + @echo "proto subcommands" + @echo "" + @echo "Usage:" + @echo " make proto-[command]" + @echo "" + @echo "Available Commands:" + @echo " all Run proto-format and proto-gen" + @echo " gen Generate Protobuf files" + @echo " format Format Protobuf files" + @echo " image-build Build the protobuf Docker image" + @echo " image-push Push the protobuf Docker image" + +proto: proto-help proto-all: proto-format proto-gen -proto: - @echo - @echo "=========== Generate Message ============" - @echo - ./scripts/protocgen.sh - @echo - @echo "=========== Generate Complete ============" - @echo +protoVer=v0.9 +protoImageName=osmolabs/osmo-proto-gen:$(protoVer) +containerProtoGen=cosmos-sdk-proto-gen-$(protoVer) +containerProtoFmt=cosmos-sdk-proto-fmt-$(protoVer) + +proto-gen: + @echo "Generating Protobuf files" + @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoGen}$$"; then docker start -a $(containerProtoGen); else docker run --name $(containerProtoGen) -v $(CURDIR):/workspace --workdir /workspace $(protoImageName) \ + sh ./scripts/protocgen.sh; fi + +proto-format: + @echo "Formatting Protobuf files" + @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoFmt}$$"; then docker start -a $(containerProtoFmt); else docker run --name $(containerProtoFmt) -v $(CURDIR):/workspace --workdir /workspace tendermintdev/docker-build-proto \ + find ./ -not -path "./third_party/*" -name "*.proto" -exec clang-format -i {} \; ; fi + +proto-image-build: + @DOCKER_BUILDKIT=1 docker build -t $(protoImageName) -f ./proto/Dockerfile ./proto + +proto-image-push: + docker push $(protoImageName) + test: @go test -v ./x/... @@ -319,26 +346,6 @@ docs: @echo .PHONY: docs -protoVer=v0.9 -protoImageName=osmolabs/osmo-proto-gen:$(protoVer) -containerProtoGen=cosmos-sdk-proto-gen-$(protoVer) -containerProtoFmt=cosmos-sdk-proto-fmt-$(protoVer) - -proto-gen: - @echo "Generating Protobuf files" - @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoGen}$$"; then docker start -a $(containerProtoGen); else docker run --name $(containerProtoGen) -v $(CURDIR):/workspace --workdir /workspace $(protoImageName) \ - sh ./scripts/protocgen.sh; fi - -proto-format: - @echo "Formatting Protobuf files" - @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoFmt}$$"; then docker start -a $(containerProtoFmt); else docker run --name $(containerProtoFmt) -v $(CURDIR):/workspace --workdir /workspace tendermintdev/docker-build-proto \ - find ./ -not -path "./third_party/*" -name "*.proto" -exec clang-format -i {} \; ; fi - -proto-image-build: - @DOCKER_BUILDKIT=1 docker build -t $(protoImageName) -f ./proto/Dockerfile ./proto - -proto-image-push: - docker push $(protoImageName) ############################################################################### ### Querygen ### From 0587abf51d75aad8f0fc6194c4aa7fb80ef847cc Mon Sep 17 00:00:00 2001 From: Adam Tucker Date: Tue, 17 Oct 2023 23:53:22 -0600 Subject: [PATCH 06/25] fix: replace remaining v19 import paths (#6713) * fix remaining v19 import paths * update go mod * remove v19 references --- tests/cl-genesis-positions/convert.go | 14 ++--- .../edit_localosmosis_genesis.go | 10 ++-- tests/cl-genesis-positions/go.mod | 27 ++++----- tests/cl-genesis-positions/go.sum | 56 +++++++++---------- tests/cl-go-client/go.mod | 15 +++-- tests/cl-go-client/go.sum | 33 ++++++----- tests/cl-go-client/main.go | 14 ++--- 7 files changed, 81 insertions(+), 88 deletions(-) diff --git a/tests/cl-genesis-positions/convert.go b/tests/cl-genesis-positions/convert.go index 024c34f6a0c..10813adcaf3 100644 --- a/tests/cl-genesis-positions/convert.go +++ b/tests/cl-genesis-positions/convert.go @@ -13,13 +13,13 @@ import ( "github.com/osmosis-labs/osmosis/osmomath" "github.com/osmosis-labs/osmosis/osmoutils/accum" - "github.com/osmosis-labs/osmosis/v19/app" - "github.com/osmosis-labs/osmosis/v19/app/apptesting" - cl "github.com/osmosis-labs/osmosis/v19/x/concentrated-liquidity" - "github.com/osmosis-labs/osmosis/v19/x/concentrated-liquidity/math" - "github.com/osmosis-labs/osmosis/v19/x/concentrated-liquidity/model" - cltypes "github.com/osmosis-labs/osmosis/v19/x/concentrated-liquidity/types" - clgenesis "github.com/osmosis-labs/osmosis/v19/x/concentrated-liquidity/types/genesis" + "github.com/osmosis-labs/osmosis/v20/app" + "github.com/osmosis-labs/osmosis/v20/app/apptesting" + cl "github.com/osmosis-labs/osmosis/v20/x/concentrated-liquidity" + "github.com/osmosis-labs/osmosis/v20/x/concentrated-liquidity/math" + "github.com/osmosis-labs/osmosis/v20/x/concentrated-liquidity/model" + cltypes "github.com/osmosis-labs/osmosis/v20/x/concentrated-liquidity/types" + clgenesis "github.com/osmosis-labs/osmosis/v20/x/concentrated-liquidity/types/genesis" ) type BigBangPositions struct { diff --git a/tests/cl-genesis-positions/edit_localosmosis_genesis.go b/tests/cl-genesis-positions/edit_localosmosis_genesis.go index 2f1f2c921ee..3b6c69e4722 100644 --- a/tests/cl-genesis-positions/edit_localosmosis_genesis.go +++ b/tests/cl-genesis-positions/edit_localosmosis_genesis.go @@ -16,12 +16,12 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - osmosisApp "github.com/osmosis-labs/osmosis/v19/app" - "github.com/osmosis-labs/osmosis/v19/x/concentrated-liquidity/model" + osmosisApp "github.com/osmosis-labs/osmosis/v20/app" + "github.com/osmosis-labs/osmosis/v20/x/concentrated-liquidity/model" - cltypes "github.com/osmosis-labs/osmosis/v19/x/concentrated-liquidity/types" - clgenesis "github.com/osmosis-labs/osmosis/v19/x/concentrated-liquidity/types/genesis" - poolmanagertypes "github.com/osmosis-labs/osmosis/v19/x/poolmanager/types" + cltypes "github.com/osmosis-labs/osmosis/v20/x/concentrated-liquidity/types" + clgenesis "github.com/osmosis-labs/osmosis/v20/x/concentrated-liquidity/types/genesis" + poolmanagertypes "github.com/osmosis-labs/osmosis/v20/x/poolmanager/types" ) func EditLocalOsmosisGenesis(updatedCLGenesis *clgenesis.GenesisState, updatedBankGenesis *banktypes.GenesisState) { diff --git a/tests/cl-genesis-positions/go.mod b/tests/cl-genesis-positions/go.mod index cc56ad32c06..f6677fa86e7 100644 --- a/tests/cl-genesis-positions/go.mod +++ b/tests/cl-genesis-positions/go.mod @@ -5,9 +5,9 @@ go 1.20 require ( github.com/cosmos/cosmos-sdk v0.47.5 github.com/ignite/cli v0.23.0 - github.com/osmosis-labs/osmosis/osmomath v0.0.7 - github.com/osmosis-labs/osmosis/osmoutils v0.0.7 - github.com/osmosis-labs/osmosis/v19 v19.1.0 + github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20231014001935-1946419d44eb + github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20231011004221-fd24b80f8366 + github.com/osmosis-labs/osmosis/v20 v20.0.0 github.com/tendermint/tendermint v0.37.0-rc1 ) @@ -30,7 +30,6 @@ require ( github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/chenzhuoyu/iasm v0.9.0 // indirect github.com/coinbase/rosetta-sdk-go v0.7.9 // indirect github.com/confio/ics23/go v0.9.1 // indirect github.com/cosmos/btcutil v1.0.5 // indirect @@ -48,17 +47,17 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgraph-io/badger/v3 v3.2103.2 // indirect - github.com/dgraph-io/ristretto v0.1.0 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac // indirect + github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect - github.com/go-logfmt/logfmt v0.5.1 // indirect - github.com/go-playground/validator/v10 v10.14.0 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/gateway v1.1.0 // indirect github.com/gogo/protobuf v1.3.3 // indirect @@ -80,7 +79,6 @@ require ( github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect @@ -99,10 +97,9 @@ require ( github.com/minio/highwayhash v1.0.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mtibben/percent v0.2.1 // indirect - github.com/onsi/gomega v1.27.10 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/osmosis-labs/osmosis/x/epochs v0.0.2 // indirect - github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.8 // indirect + github.com/osmosis-labs/osmosis/x/epochs v0.0.3-0.20231011004221-fd24b80f8366 // indirect + github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.9-0.20231014001935-1946419d44eb // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -114,8 +111,8 @@ require ( github.com/rakyll/statik v0.1.7 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/regen-network/cosmos-proto v0.3.1 // indirect - github.com/rs/cors v1.8.2 // indirect - github.com/rs/zerolog v1.27.0 // indirect + github.com/rs/cors v1.8.3 // indirect + github.com/rs/zerolog v1.29.0 // indirect github.com/sagikazarmark/locafero v0.3.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect @@ -133,8 +130,6 @@ require ( github.com/tendermint/go-amino v0.16.0 // indirect github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b // indirect github.com/tidwall/btree v1.6.0 // indirect - github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect github.com/zondax/hid v0.9.1 // indirect github.com/zondax/ledger-go v0.14.1 // indirect go.etcd.io/bbolt v1.3.6 // indirect diff --git a/tests/cl-genesis-positions/go.sum b/tests/cl-genesis-positions/go.sum index 78349df4fb7..c572c877da6 100644 --- a/tests/cl-genesis-positions/go.sum +++ b/tests/cl-genesis-positions/go.sum @@ -54,7 +54,7 @@ github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwR github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= @@ -165,7 +165,6 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo= -github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -179,6 +178,7 @@ github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE github.com/coinbase/kryptology v1.8.0/go.mod h1:RYXOAPdzOGUe3qlSFkMGn58i3xUA8hmxYHksuq+8ciI= github.com/coinbase/rosetta-sdk-go v0.7.9 h1:lqllBjMnazTjIqYrOGv8h8jxjg9+hJazIGZr9ZvoCcA= github.com/coinbase/rosetta-sdk-go v0.7.9/go.mod h1:0/knutI7XGVqXmmH4OQD8OckFrbQ8yMsUZTG7FXCR2M= +github.com/cometbft/cometbft v0.38.0 h1:ogKnpiPX7gxCvqTEF4ly25/wAxUqf181t30P3vqdpdc= github.com/confio/ics23/go v0.9.1 h1:3MV46eeWwO3xCauKyAtuAdJYMyPnnchW4iLr2bTw6/U= github.com/confio/ics23/go v0.9.1/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= @@ -244,8 +244,9 @@ github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHH github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= @@ -264,8 +265,8 @@ github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRP github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac h1:opbrjaN/L8gg6Xh5D04Tem+8xVcz6ajZlGCs49mQgyg= -github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= @@ -320,19 +321,19 @@ github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBj github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= -github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= @@ -489,7 +490,6 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= -github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -572,11 +572,9 @@ github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJw github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5 h1:2U0HzY8BJ8hVwDKIzp7y4voR9CX/nvcfymLmg2UiOio= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= -github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -694,7 +692,6 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -712,16 +709,16 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= github.com/osmosis-labs/cosmos-sdk v0.45.0-rc1.0.20230922030206-734f99fba785 h1:noyO/2kXPRafPfuOQQW3z1SYIvX5R+HogBH8t+ncwZQ= github.com/osmosis-labs/cosmos-sdk v0.45.0-rc1.0.20230922030206-734f99fba785/go.mod h1:toI9Pf+e5C4TuWAFpXfkxnkpr1RVFMK2qr7QMdkFrY8= -github.com/osmosis-labs/osmosis/osmomath v0.0.7 h1:UTCGs9KF2HfmqJU9Y5u7rLqFE3of+S7FfomnH6UMRQU= -github.com/osmosis-labs/osmosis/osmomath v0.0.7/go.mod h1:oBmsOov8oxuWoI/yMQwyKGA6QfP0cBxylLt75gFbT8s= -github.com/osmosis-labs/osmosis/osmoutils v0.0.7 h1:HnOgJiOo3XH2MQ2bsUTL7b0Xj29fObN4tVacza8M13g= -github.com/osmosis-labs/osmosis/osmoutils v0.0.7/go.mod h1:ukjFgxfR9obDrMd8ZsxKcp3HWL7+boYORVL7Bt7YOZM= -github.com/osmosis-labs/osmosis/v19 v19.1.0 h1:UjtvMa/aQJmPElJ6Dgw/JCOn/jK9inrokWLLuvyWiOs= -github.com/osmosis-labs/osmosis/v19 v19.1.0/go.mod h1:814celxyvH9vTErFcjc+aTJB5zlEgyjsXGWCgvzzzDc= -github.com/osmosis-labs/osmosis/x/epochs v0.0.2 h1:aEeXHGCSJMgMtAvCucsD2RSaWZ8lISFLD5u4MyF9KPc= -github.com/osmosis-labs/osmosis/x/epochs v0.0.2/go.mod h1:8dvJFHTpu6SIxmOaSaEw0tHnQ/Z9blf5qsF/ZJnMVHo= -github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.8 h1:BUGowctYQT0vdPgULrvwraEsW+sS6DnbzndTLKLmWVY= -github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.8/go.mod h1:sR0lpev9mcm9/9RY50T1og3UC3WpZAsINh/OmgrmFlg= +github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20231014001935-1946419d44eb h1:pXsC6vqGD+pbMGt+fVBHi9XBk/KDQuRZde2fh4s/1+k= +github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20231014001935-1946419d44eb/go.mod h1:jNZ952fypVNMzOsh31LAUS27JbF9naNJGtELxId6ZCg= +github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20231011004221-fd24b80f8366 h1:EJDJ88w2Yv5LnlaJw5x53C0k/dp/fnEYOfBYOQiMsTc= +github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20231011004221-fd24b80f8366/go.mod h1:Zmyx5zMUBN2KV94booSFn2v8KQcUKeCHqyWpKZ4PRMo= +github.com/osmosis-labs/osmosis/v20 v20.0.0 h1:r38aRP+iZVD0XfhgFlK+NUP2ALeMec0uAPv2dJvFAQ8= +github.com/osmosis-labs/osmosis/v20 v20.0.0/go.mod h1:7qBmLJPdHxxG56ij+4/GURzMX8gJcT+uokdbT4ChZ3Q= +github.com/osmosis-labs/osmosis/x/epochs v0.0.3-0.20231011004221-fd24b80f8366 h1:E6H0V3MKbSNwo1iXE9Kzatd2M02MgZpS5AiJ6CKK5us= +github.com/osmosis-labs/osmosis/x/epochs v0.0.3-0.20231011004221-fd24b80f8366/go.mod h1:vU0IHK5W38dqMeux3MkSaT3MZU6whAkx7vNuxv1IzeU= +github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.9-0.20231014001935-1946419d44eb h1:6lYLEiJERdD+QK925XYyHkvNyvQTghVFufMH5VAQLpg= +github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.9-0.20231014001935-1946419d44eb/go.mod h1:3xD12hg/OzBdtrCOJHGGJrI2zRAdOXBfqFoPP33x0jQ= github.com/osmosis-labs/wasmd v0.31.0-osmo-v16 h1:X747cZYdnqc/+RV48iPVeGprpVb/fUWSaKGsZUWrdbg= github.com/osmosis-labs/wasmd v0.31.0-osmo-v16/go.mod h1:Rf8zW/GgBQyFRRB4s62VQHWA6sTlMFSjoDQQpoq64iI= github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= @@ -807,11 +804,11 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= -github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs= -github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= +github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= +github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w= +github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -913,14 +910,13 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1 github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= @@ -1187,6 +1183,7 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1418,7 +1415,6 @@ honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/tests/cl-go-client/go.mod b/tests/cl-go-client/go.mod index bd85bf64cfd..2dce7568720 100644 --- a/tests/cl-go-client/go.mod +++ b/tests/cl-go-client/go.mod @@ -5,9 +5,9 @@ go 1.20 require ( github.com/cosmos/cosmos-sdk v0.47.5 github.com/ignite/cli v0.23.0 - github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20231011004221-fd24b80f8366 + github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20231014001935-1946419d44eb github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20231011004221-fd24b80f8366 - github.com/osmosis-labs/osmosis/v19 v19.1.0 + github.com/osmosis-labs/osmosis/v20 v20.0.0 github.com/osmosis-labs/osmosis/x/epochs v0.0.3-0.20231011004221-fd24b80f8366 ) @@ -43,15 +43,15 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgraph-io/badger/v3 v3.2103.2 // indirect - github.com/dgraph-io/ristretto v0.1.0 // indirect - github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect - github.com/go-logfmt/logfmt v0.5.1 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/gateway v1.1.0 // indirect @@ -72,7 +72,6 @@ require ( github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect @@ -101,8 +100,8 @@ require ( github.com/rakyll/statik v0.1.7 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/regen-network/cosmos-proto v0.3.1 // indirect - github.com/rs/cors v1.8.2 // indirect - github.com/rs/zerolog v1.27.0 // indirect + github.com/rs/cors v1.8.3 // indirect + github.com/rs/zerolog v1.29.0 // indirect github.com/sagikazarmark/locafero v0.3.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect diff --git a/tests/cl-go-client/go.sum b/tests/cl-go-client/go.sum index f2fc9afcaf6..9738c60cf26 100644 --- a/tests/cl-go-client/go.sum +++ b/tests/cl-go-client/go.sum @@ -54,7 +54,7 @@ github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwR github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= @@ -238,8 +238,9 @@ github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHH github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= @@ -257,8 +258,8 @@ github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRP github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac h1:opbrjaN/L8gg6Xh5D04Tem+8xVcz6ajZlGCs49mQgyg= -github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= @@ -313,8 +314,8 @@ github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBj github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= @@ -480,7 +481,6 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= -github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -698,13 +698,15 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= github.com/osmosis-labs/cosmos-sdk v0.45.0-rc1.0.20230922030206-734f99fba785 h1:noyO/2kXPRafPfuOQQW3z1SYIvX5R+HogBH8t+ncwZQ= github.com/osmosis-labs/cosmos-sdk v0.45.0-rc1.0.20230922030206-734f99fba785/go.mod h1:toI9Pf+e5C4TuWAFpXfkxnkpr1RVFMK2qr7QMdkFrY8= -github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20231011004221-fd24b80f8366 h1:E/6Yk1f+8evOyi6xKHurjhPQrWKuW/KFoWJ8cfGT6I8= -github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20231011004221-fd24b80f8366/go.mod h1:YEMUPuI9gBUATC4tp2MiW0oWRlShli0K95JqgNKJh9c= +github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20231014001935-1946419d44eb h1:pXsC6vqGD+pbMGt+fVBHi9XBk/KDQuRZde2fh4s/1+k= +github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20231014001935-1946419d44eb/go.mod h1:jNZ952fypVNMzOsh31LAUS27JbF9naNJGtELxId6ZCg= github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20231011004221-fd24b80f8366 h1:EJDJ88w2Yv5LnlaJw5x53C0k/dp/fnEYOfBYOQiMsTc= github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20231011004221-fd24b80f8366/go.mod h1:Zmyx5zMUBN2KV94booSFn2v8KQcUKeCHqyWpKZ4PRMo= +github.com/osmosis-labs/osmosis/v20 v20.0.0 h1:r38aRP+iZVD0XfhgFlK+NUP2ALeMec0uAPv2dJvFAQ8= +github.com/osmosis-labs/osmosis/v20 v20.0.0/go.mod h1:7qBmLJPdHxxG56ij+4/GURzMX8gJcT+uokdbT4ChZ3Q= github.com/osmosis-labs/osmosis/x/epochs v0.0.3-0.20231011004221-fd24b80f8366 h1:E6H0V3MKbSNwo1iXE9Kzatd2M02MgZpS5AiJ6CKK5us= github.com/osmosis-labs/osmosis/x/epochs v0.0.3-0.20231011004221-fd24b80f8366/go.mod h1:vU0IHK5W38dqMeux3MkSaT3MZU6whAkx7vNuxv1IzeU= -github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.9-0.20231012010556-df85839cab74 h1:zgv48lalsD2PX/4TiFep/xJBvwXXAr8emnQOL5i6zcc= +github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.9-0.20231014001935-1946419d44eb h1:6lYLEiJERdD+QK925XYyHkvNyvQTghVFufMH5VAQLpg= github.com/osmosis-labs/wasmd v0.31.0-osmo-v16 h1:X747cZYdnqc/+RV48iPVeGprpVb/fUWSaKGsZUWrdbg= github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= github.com/p0mvn/cli v0.23.1 h1:Y4vUUNzTmrhhlaj1FIuLDCX9Go0oTqlf88m2PtaG5Zs= @@ -789,11 +791,11 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= -github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs= -github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= +github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= +github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w= +github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -1164,6 +1166,7 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/tests/cl-go-client/main.go b/tests/cl-go-client/main.go index 045e1058e29..5f9e9a6c7f6 100644 --- a/tests/cl-go-client/main.go +++ b/tests/cl-go-client/main.go @@ -19,13 +19,13 @@ import ( "github.com/osmosis-labs/osmosis/osmomath" "github.com/osmosis-labs/osmosis/osmoutils" - clqueryproto "github.com/osmosis-labs/osmosis/v19/x/concentrated-liquidity/client/queryproto" - "github.com/osmosis-labs/osmosis/v19/x/concentrated-liquidity/model" - cltypes "github.com/osmosis-labs/osmosis/v19/x/concentrated-liquidity/types" - incentivestypes "github.com/osmosis-labs/osmosis/v19/x/incentives/types" - lockuptypes "github.com/osmosis-labs/osmosis/v19/x/lockup/types" - poolmanagerqueryproto "github.com/osmosis-labs/osmosis/v19/x/poolmanager/client/queryproto" - poolmanagertypes "github.com/osmosis-labs/osmosis/v19/x/poolmanager/types" + clqueryproto "github.com/osmosis-labs/osmosis/v20/x/concentrated-liquidity/client/queryproto" + "github.com/osmosis-labs/osmosis/v20/x/concentrated-liquidity/model" + cltypes "github.com/osmosis-labs/osmosis/v20/x/concentrated-liquidity/types" + incentivestypes "github.com/osmosis-labs/osmosis/v20/x/incentives/types" + lockuptypes "github.com/osmosis-labs/osmosis/v20/x/lockup/types" + poolmanagerqueryproto "github.com/osmosis-labs/osmosis/v20/x/poolmanager/client/queryproto" + poolmanagertypes "github.com/osmosis-labs/osmosis/v20/x/poolmanager/types" epochstypes "github.com/osmosis-labs/osmosis/x/epochs/types" ) From 7697131a83d93f578430b37e53bbe269e372699d Mon Sep 17 00:00:00 2001 From: Niccolo Raspa <6024049+niccoloraspa@users.noreply.github.com> Date: Thu, 19 Oct 2023 21:58:59 +0200 Subject: [PATCH 07/25] Add cleanup step to release GitHub Action (#6725) --- .github/workflows/release.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b22fbfd1159..0f51e413c10 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,10 @@ jobs: - name: Make release run: | - sudo rm -rf dist make release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - + name: 🧹 Clean release folder + run: | + sudo rm -rf dist From 6a28004ab7bf98f21ec22ad9f5e4dcbba78dfa76 Mon Sep 17 00:00:00 2001 From: Niccolo Raspa <6024049+niccoloraspa@users.noreply.github.com> Date: Fri, 20 Oct 2023 11:39:18 +0200 Subject: [PATCH 08/25] Replace VERSION with SDK_VERSION (#6724) --- Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 030c9624939..5cf13e191bb 100644 --- a/Makefile +++ b/Makefile @@ -258,20 +258,20 @@ distclean: clean ### Dependency Updates ### ############################################################################### -VERSION := +SDK_VERSION := MODFILES := ./go.mod ./osmoutils/go.mod ./osmomath/go.mod ./x/epochs/go.mod ./x/ibc-hooks/go.mod ./tests/cl-genesis-positions/go.mod ./tests/cl-go-client/go.mod -# run with VERSION argument specified -# e.g) make update-sdk-version VERSION=v0.45.1-0.20230523200430-193959b898ec +# run with SDK_VERSION argument specified +# e.g) make update-sdk-version SDK_VERSION=v0.45.1-0.20230523200430-193959b898ec # This will change sdk dependencyu version for go.mod in root directory + all sub-modules in this repo. update-sdk-version: - @if [ -z "$(VERSION)" ]; then \ - echo "VERSION not set"; \ + @if [ -z "$(SDK_VERSION)" ]; then \ + echo "SDK_VERSION not set"; \ exit 1; \ fi - @echo "Updating version to $(VERSION)" + @echo "Updating version to $(SDK_VERSION)" @for modfile in $(MODFILES); do \ if [ -e "$$modfile" ]; then \ - sed -i '' 's|github.com/osmosis-labs/cosmos-sdk v[0-9a-z.\-]*|github.com/osmosis-labs/cosmos-sdk $(VERSION)|g' $$modfile; \ + sed -i '' 's|github.com/osmosis-labs/cosmos-sdk v[0-9a-z.\-]*|github.com/osmosis-labs/cosmos-sdk $(SDK_VERSION)|g' $$modfile; \ cd `dirname $$modfile`; \ go mod tidy; \ cd - > /dev/null; \ From 8e252bc6e44adecf5b153f5b4d629e70aeb6a8fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90=C3=B4ng=20Li=E1=BB=81u?= <93205232+DongLieu@users.noreply.github.com> Date: Sat, 21 Oct 2023 16:42:00 +0700 Subject: [PATCH 09/25] list-env CLI command (#6709) * cli for all Environment * changelog * Update cmd/osmosisd/cmd/change_environment.go Co-authored-by: Matt, Park <45252226+mattverse@users.noreply.github.com> * lint --------- Co-authored-by: Matt, Park <45252226+mattverse@users.noreply.github.com> --- CHANGELOG.md | 1 + cmd/osmosisd/cmd/change_environment.go | 47 ++++++++++++++++++++++++++ cmd/osmosisd/cmd/root.go | 1 + 3 files changed, 49 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 185abecaf7c..1ce58ff8295 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#6420](https://github.com/osmosis-labs/osmosis/pull/6420) feat[CL]: Creates a governance set whitelist of addresses that can bypass the normal pool creation restrictions on concentrated liquidity pools * [#6623](https://github.com/osmosis-labs/osmosis/pull/6420) feat: transfer cl positions to new owner * [#6632](https://github.com/osmosis-labs/osmosis/pull/6632) Taker fee bypass whitelist +* [#6709](https://github.com/osmosis-labs/osmosis/pull/6709) CLI: Add list-env, all Environment for CLI ### State Breaking diff --git a/cmd/osmosisd/cmd/change_environment.go b/cmd/osmosisd/cmd/change_environment.go index b6609dc147a..6ec7afce7f4 100644 --- a/cmd/osmosisd/cmd/change_environment.go +++ b/cmd/osmosisd/cmd/change_environment.go @@ -226,3 +226,50 @@ func customArgs(cmd *cobra.Command, args []string) error { } return nil } +func PrintAllEnvironmentCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "list-env ", + Short: "listing all available environments.", + Long: `listing all available environments. +Example: + osmosisd list-env' + Returns all EnvironmentCmd`, + RunE: func(cmd *cobra.Command, args []string) error { + // mainnet + path, err := environmentNameToPath(EnvMainnet) + if err != nil { + fmt.Printf("Error: %v \n", err) + } + + fmt.Printf("Environment name, path: %s, %s\n", EnvMainnet, path) + + // localnet + path, err = environmentNameToPath(EnvLocalnet) + if err != nil { + fmt.Printf("Error: %v \n", err) + } + + fmt.Printf("Environment name, path: %s, %s\n", EnvLocalnet, path) + + // testnet + path, err = environmentNameToPath(EnvTestnet) + if err != nil { + fmt.Printf("Error: %v \n", err) + } + + fmt.Printf("Environment name, path: %s, %s\n", EnvTestnet, path) + + // OSMOSISD_ENVIRONMENT + val := os.Getenv(EnvVariable) + path, err = environmentNameToPath(val) + if err != nil { + fmt.Printf("Error: %v \n", err) + } + + fmt.Printf("Environment name, path: %s, %s\n", EnvVariable, path) + + return nil + }, + } + return cmd +} diff --git a/cmd/osmosisd/cmd/root.go b/cmd/osmosisd/cmd/root.go index 506a83d6a4e..a68d6aab9f4 100644 --- a/cmd/osmosisd/cmd/root.go +++ b/cmd/osmosisd/cmd/root.go @@ -487,6 +487,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { ConfigCmd(), ChangeEnvironmentCmd(), PrintEnvironmentCmd(), + PrintAllEnvironmentCmd(), UpdateAssetListCmd(osmosis.DefaultNodeHome, osmosis.ModuleBasics), ) From 022630c975311ec73c7ac25285515dea3f59436e Mon Sep 17 00:00:00 2001 From: Supanat Date: Mon, 23 Oct 2023 17:49:22 +0700 Subject: [PATCH 10/25] add infinite block before send (#6733) --- .../infinite-track-beforesend/src/contract.rs | 10 +++++++--- .../infinite-track-beforesend/src/msg.rs | 5 +++++ .../testdata/infinite_track_beforesend.wasm | Bin 158057 -> 160844 bytes 3 files changed, 12 insertions(+), 3 deletions(-) mode change 100755 => 100644 x/tokenfactory/keeper/testdata/infinite_track_beforesend.wasm diff --git a/x/tokenfactory/keeper/testcontracts/contracts/infinite-track-beforesend/src/contract.rs b/x/tokenfactory/keeper/testcontracts/contracts/infinite-track-beforesend/src/contract.rs index afb65741083..19f07985207 100644 --- a/x/tokenfactory/keeper/testcontracts/contracts/infinite-track-beforesend/src/contract.rs +++ b/x/tokenfactory/keeper/testcontracts/contracts/infinite-track-beforesend/src/contract.rs @@ -45,9 +45,13 @@ pub fn query(_deps: Deps, _env: Env, _msg: ()) -> StdResult { #[cfg_attr(not(feature = "library"), entry_point)] pub fn sudo(_deps: DepsMut, _env: Env, msg: SudoMsg) -> Result { match msg { - // Hook for bank send (aka. token transfer), this is called before the token is sent if this contract is registered with MsgSetBeforeSendHook - SudoMsg::TrackBeforeSend { .. } => { - // infinite loop + SudoMsg::TrackBeforeSend { .. } => + { + #[allow(clippy::empty_loop)] + loop {} + } + SudoMsg::BlockBeforeSend { .. } => + { #[allow(clippy::empty_loop)] loop {} } diff --git a/x/tokenfactory/keeper/testcontracts/contracts/infinite-track-beforesend/src/msg.rs b/x/tokenfactory/keeper/testcontracts/contracts/infinite-track-beforesend/src/msg.rs index 8c41de93f15..409e7142429 100644 --- a/x/tokenfactory/keeper/testcontracts/contracts/infinite-track-beforesend/src/msg.rs +++ b/x/tokenfactory/keeper/testcontracts/contracts/infinite-track-beforesend/src/msg.rs @@ -11,4 +11,9 @@ pub enum SudoMsg { to: String, amount: Coin, }, + BlockBeforeSend { + from: String, + to: String, + amount: Coin, + }, } diff --git a/x/tokenfactory/keeper/testdata/infinite_track_beforesend.wasm b/x/tokenfactory/keeper/testdata/infinite_track_beforesend.wasm old mode 100755 new mode 100644 index 28edb8b0259d99dce92fee5af2ada1aeb13bfd98..58dadef047a1fa51fecd83ad52b1a71c8d418439 GIT binary patch literal 160844 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%0Aaa|=UnbMAI=-4% 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 Dp2`Fy literal 158057 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 Date: Mon, 23 Oct 2023 13:15:50 +0200 Subject: [PATCH 11/25] Fix/v20.1.0 chores (#6738) * update cosmovisor binaries * Update guide with proposal and block * Add upgrade name * Set correct block * Update chain registry --- chain.schema.json | 39 +++++++++++++++---- networks/osmosis-1/README.md | 21 +++++++++- .../osmosis-1/upgrades/v20/mainnet/guide.md | 10 ++--- .../upgrades/v20/mainnet/v20_binaries.json | 6 +-- .../upgrades/v20/testnet/v20_binaries.json | 6 +-- .../create_all_binaries_json.sh | 1 + 6 files changed, 62 insertions(+), 21 deletions(-) diff --git a/chain.schema.json b/chain.schema.json index b575b18cf35..5338aa4e6bc 100644 --- a/chain.schema.json +++ b/chain.schema.json @@ -2,24 +2,22 @@ "$schema": "http://json-schema.org/draft-07/schema#", "codebase": { "git_repo": "https://github.com/osmosis-labs/osmosis", - "recommended_version": "v19.2.0", + "recommended_version": "v20.1.0", "compatible_versions": [ - "v19.2.0", - "v19.1.0", - "v19.0.0" + "v20.1.0" ], "binaries": { - "linux/amd64": "https://github.com/osmosis-labs/osmosis/releases/download/v19.2.0/osmosisd-19.2.0-linux-amd64?checksum=sha256:723ff1c5349eb3c039c3dc5f55895bbde2e1499fe7c0a96960cc6fadeec814c4", - "linux/arm64": "https://github.com/osmosis-labs/osmosis/releases/download/v19.2.0/osmosisd-19.2.0-linux-arm64?checksum=sha256:d933b893d537422164a25bf161d7f269a59ea26d37f398cdb7dd575a9ec33ed2" + "linux/arm64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.1.0/osmosisd-20.1.0-linux-arm64?checksum=sha256:07fa5364fd239739792b55d7b3aadcfcab09563b432e83e26f1f8af112c723b4", + "linux/amd64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.1.0/osmosisd-20.1.0-linux-amd64?checksum=sha256:958fa18f4005bd3c81fc5eb023c7d229bde46d7c1e48a15fc29a68881e105787" }, - "cosmos_sdk_version": "osmosis-labs/cosmos-sdk@0.45.0-rc1.0.20230927020814-2854ac001f06", + "cosmos_sdk_version": "osmosis-labs/cosmos-sdk@0.45.0-rc1.0.20230922030206-734f99fba785", "consensus": { "type": "tendermint", "version": "informalsystems/tendermint@0.34.24" }, "cosmwasm_version": "osmosis-labs/wasmd@0.31.0-osmo-v16", "cosmwasm_enabled": true, - "ibc_go_version": "4.3.1", + "ibc_go_version": "4.5.0", "ics_enabled": [ "ics20-1" ], @@ -251,6 +249,31 @@ "binaries": { "linux/amd64": "https://github.com/osmosis-labs/osmosis/releases/download/v19.2.0/osmosisd-19.2.0-linux-amd64?checksum=sha256:723ff1c5349eb3c039c3dc5f55895bbde2e1499fe7c0a96960cc6fadeec814c4", "linux/arm64": "https://github.com/osmosis-labs/osmosis/releases/download/v19.2.0/osmosisd-19.2.0-linux-arm64?checksum=sha256:d933b893d537422164a25bf161d7f269a59ea26d37f398cdb7dd575a9ec33ed2" + }, + "next_version_name": "v20" + }, + { + "name": "v20", + "tag": "v20.1.0", + "height": 12028900, + "recommended_version": "v20.1.0", + "compatible_versions": [ + "v20.1.0" + ], + "cosmos_sdk_version": "osmosis-labs/cosmos-sdk@0.45.0-rc1.0.20230922030206-734f99fba785", + "consensus": { + "type": "tendermint", + "version": "informalsystems/tendermint@0.34.24" + }, + "cosmwasm_version": "osmosis-labs/wasmd@0.31.0-osmo-v16", + "cosmwasm_enabled": true, + "ibc_go_version": "4.5.0", + "ics_enabled": [ + "ics20-1" + ], + "binaries": { + "linux/arm64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.1.0/osmosisd-20.1.0-linux-arm64?checksum=sha256:07fa5364fd239739792b55d7b3aadcfcab09563b432e83e26f1f8af112c723b4", + "linux/amd64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.1.0/osmosisd-20.1.0-linux-amd64?checksum=sha256:958fa18f4005bd3c81fc5eb023c7d229bde46d7c1e48a15fc29a68881e105787" } } ] diff --git a/networks/osmosis-1/README.md b/networks/osmosis-1/README.md index 1f109757462..c58de2a9dcb 100644 --- a/networks/osmosis-1/README.md +++ b/networks/osmosis-1/README.md @@ -18,8 +18,10 @@ Each version is identified by a specific id, name, tag, block height and softwar | `v15` | Sodium | `v15.2.0` | 8732500 | [Release](https://github.com/osmosis-labs/osmosis/releases/tag/v15.2.0/) | [458](https://www.mintscan.io/osmosis/proposals/458) | | `v16` | Magnesium | `v16.1.1` | 10517000 | [Release](https://github.com/osmosis-labs/osmosis/releases/tag/v16.1.1/) | [556](https://www.mintscan.io/osmosis/proposals/556) | | `v17` | Aluminium | `v17.0.0` | 11126100 | [Release](https://github.com/osmosis-labs/osmosis/releases/tag/v17.0.0/) | [586](https://www.mintscan.io/osmosis/proposals/586) | -| `v18` | | `v18.0.0` | 11155350 | [Release](https://github.com/osmosis-labs/osmosis/releases/tag/v18.0.0/) | [588](https://www.mintscan.io/osmosis/proposals/588) | -| `v19` | | `v19.2.0` | 11317300 | [Release](https://github.com/osmosis-labs/osmosis/releases/tag/v19.2.0/) | [606](https://www.mintscan.io/osmosis/proposals/606) | +| `v18` | | `v18.0.0` | 11155350 | [Release](https://github.com/osmosis-labs/osmosis/releases/tag/v18.0.0/) | [588](https://www.mintscan.io/osmosis/proposals/588) | +| `v19` | | `v19.2.0` | 11317300 | [Release](https://github.com/osmosis-labs/osmosis/releases/tag/v19.2.0/) | [606](https://www.mintscan.io/osmosis/proposals/606) | +| `v20` | Silicon | `v20.1.0` | 12028900 | [Release](https://github.com/osmosis-labs/osmosis/releases/tag/v20.1.0/) | [658](https://www.mintscan.io/osmosis/proposals/658) | + ## Upgrade binaries ### v3.1.0 @@ -175,6 +177,17 @@ Each version is identified by a specific id, name, tag, block height and softwar } ``` +### v20.1.0 + +```json +{ + "binaries": { + "linux/arm64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.1.0/osmosisd-20.1.0-linux-arm64?checksum=sha256:07fa5364fd239739792b55d7b3aadcfcab09563b432e83e26f1f8af112c723b4", + "linux/amd64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.1.0/osmosisd-20.1.0-linux-amd64?checksum=sha256:958fa18f4005bd3c81fc5eb023c7d229bde46d7c1e48a15fc29a68881e105787" + } +} +``` + ## Replay from Genesis using Cosmovisor Assuming that your osmosis home it's already initialized with the desired genesis and configuration, @@ -226,6 +239,9 @@ Alternatively, you can download the appropriate binary for your platform from ou ├── v19 │ └── bin │ └── osmosisd + ├── v20 + │ └── bin + │ └── osmosisd ├── v4 │ └── bin │ └── osmosisd @@ -262,6 +278,7 @@ versions_info=( "v17:https://github.com/osmosis-labs/osmosis/releases/download/v17.0.0/osmosisd-17.0.0-linux-amd64?checksum=sha256:d7fe62ae33cf2f0b48a17eb8b02644dadd9924f15861ed622cd90cb1a038135b" "v18:https://github.com/osmosis-labs/osmosis/releases/download/v18.0.0/osmosisd-18.0.0-linux-amd64?checksum=sha256:d83b4122e3ff9c428c8d6dcfe89718f5229f80e9976dbab2deefeb68dceb0f38" "v19:https://github.com/osmosis-labs/osmosis/releases/download/v19.2.0/osmosisd-19.2.0-linux-arm64?checksum=sha256:d933b893d537422164a25bf161d7f269a59ea26d37f398cdb7dd575a9ec33ed2" + "v20:https://github.com/osmosis-labs/osmosis/releases/download/v20.1.0/osmosisd-20.1.0-linux-amd64?checksum=sha256:958fa18f4005bd3c81fc5eb023c7d229bde46d7c1e48a15fc29a68881e105787" ) # Create the cosmovisor directory diff --git a/networks/osmosis-1/upgrades/v20/mainnet/guide.md b/networks/osmosis-1/upgrades/v20/mainnet/guide.md index bbcf0e7f18a..450fab049cb 100644 --- a/networks/osmosis-1/upgrades/v20/mainnet/guide.md +++ b/networks/osmosis-1/upgrades/v20/mainnet/guide.md @@ -2,9 +2,9 @@ ## Overview -- **v20 Proposal**: [Proposal Page](https://www.mintscan.io/osmosis/proposals/TODO) -- **v20 Upgrade Block Height**: `TODO` -- **v20 Upgrade Countdown**: [Block Countdown](https://www.mintscan.io/osmosis/blocks/TODO) +- **v20 Proposal**: [Proposal Page](https://www.mintscan.io/osmosis/proposals/658) +- **v20 Upgrade Block Height**: `12028900` +- **v20 Upgrade Countdown**: [Block Countdown](https://www.mintscan.io/osmosis/blocks/12028900) ## Hardware Requirements @@ -82,7 +82,7 @@ source ~/.profile mkdir -p ~/.osmosisd/cosmovisor/upgrades/v20/bin cd $HOME/osmosis git pull -git checkout v20.0.0 +git checkout v20.1.0 make build cp build/osmosisd ~/.osmosisd/cosmovisor/upgrades/v20/bin ``` @@ -102,7 +102,7 @@ Follow these steps if you opt for a manual upgrade: ```sh cd $HOME/osmosis git pull -git checkout v20.0.0 +git checkout v20.1.0 make install ``` diff --git a/networks/osmosis-1/upgrades/v20/mainnet/v20_binaries.json b/networks/osmosis-1/upgrades/v20/mainnet/v20_binaries.json index 63eaf6066b5..24ce7e303e7 100644 --- a/networks/osmosis-1/upgrades/v20/mainnet/v20_binaries.json +++ b/networks/osmosis-1/upgrades/v20/mainnet/v20_binaries.json @@ -1,6 +1,6 @@ { "binaries": { - "linux/amd64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.0.0/osmosisd-20.0.0-linux-amd64?checksum=sha256:6f0a3e5900a58f24d50c2a01c6e920a57698907a099cabe4845e0b7b682a2936", - "linux/arm64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.0.0/osmosisd-20.0.0-linux-arm64?checksum=sha256:f24dd72646fd8a554ee2538f8b5e8d62c442954e62661d646e685cdb43495056" + "linux/arm64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.1.0/osmosisd-20.1.0-linux-arm64?checksum=sha256:07fa5364fd239739792b55d7b3aadcfcab09563b432e83e26f1f8af112c723b4", + "linux/amd64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.1.0/osmosisd-20.1.0-linux-amd64?checksum=sha256:958fa18f4005bd3c81fc5eb023c7d229bde46d7c1e48a15fc29a68881e105787" } -} \ No newline at end of file + } \ No newline at end of file diff --git a/networks/osmosis-1/upgrades/v20/testnet/v20_binaries.json b/networks/osmosis-1/upgrades/v20/testnet/v20_binaries.json index 4f65aa58501..24ce7e303e7 100644 --- a/networks/osmosis-1/upgrades/v20/testnet/v20_binaries.json +++ b/networks/osmosis-1/upgrades/v20/testnet/v20_binaries.json @@ -1,6 +1,6 @@ { "binaries": { - "linux/amd64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.0.0-rc1-testnet/osmosisd-20.0.0-rc1-testnet-linux-amd64?checksum=sha256:3da66af3ab42ca13e9ace779981ebed4ba82966018309a304f2dd0d63f392ab2", - "linux/arm64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.0.0-rc1-testnet/osmosisd-20.0.0-rc1-testnet-linux-arm64?checksum=sha256:b1f621e8270d61919b3f6a52d2d889a4593e07d0b688552eb48b859d40a1ef10" + "linux/arm64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.1.0/osmosisd-20.1.0-linux-arm64?checksum=sha256:07fa5364fd239739792b55d7b3aadcfcab09563b432e83e26f1f8af112c723b4", + "linux/amd64": "https://github.com/osmosis-labs/osmosis/releases/download/v20.1.0/osmosisd-20.1.0-linux-amd64?checksum=sha256:958fa18f4005bd3c81fc5eb023c7d229bde46d7c1e48a15fc29a68881e105787" } -} \ No newline at end of file + } \ No newline at end of file diff --git a/scripts/release/create_binaries_json/create_all_binaries_json.sh b/scripts/release/create_binaries_json/create_all_binaries_json.sh index 5d24c1019b5..1ddbcb853e4 100755 --- a/scripts/release/create_binaries_json/create_all_binaries_json.sh +++ b/scripts/release/create_binaries_json/create_all_binaries_json.sh @@ -15,6 +15,7 @@ tags=( "v17.0.0" "v18.0.0" "v19.2.0" + "v20.1.0" ) echo "## Upgrade binaries" From 21ba5354580afae5f76a62ecefa9d68f2cf4313c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Oct 2023 12:39:18 +0530 Subject: [PATCH 12/25] chore(deps): bump github.com/cosmos/ibc-go/v4 from 4.5.0 to 4.5.1 (#6731) Bumps [github.com/cosmos/ibc-go/v4](https://github.com/cosmos/ibc-go) from 4.5.0 to 4.5.1. - [Release notes](https://github.com/cosmos/ibc-go/releases) - [Changelog](https://github.com/cosmos/ibc-go/blob/v4.5.1/CHANGELOG.md) - [Commits](https://github.com/cosmos/ibc-go/compare/v4.5.0...v4.5.1) --- updated-dependencies: - dependency-name: github.com/cosmos/ibc-go/v4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6623f3ec75c..08a4d9f7061 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v4 v4.1.0 github.com/cosmos/ibc-apps/modules/async-icq/v4 v4.1.0 - github.com/cosmos/ibc-go/v4 v4.5.0 + github.com/cosmos/ibc-go/v4 v4.5.1 github.com/gogo/protobuf v1.3.3 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 diff --git a/go.sum b/go.sum index 70ac79f9179..6e09a5648e9 100644 --- a/go.sum +++ b/go.sum @@ -274,8 +274,8 @@ github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v4 v4.1.0 h1:96f github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v4 v4.1.0/go.mod h1:Mn/jr9pIYr1ofFuptLEi9N6MjcshTT0cpoOY4ln1DeA= github.com/cosmos/ibc-apps/modules/async-icq/v4 v4.1.0 h1:1iQ8/rJwkeGJe81fKyZC/ASSajoJP0jEi6IJFiKIr7Y= github.com/cosmos/ibc-apps/modules/async-icq/v4 v4.1.0/go.mod h1:X/dLZ6QxTImzno7qvD6huLhh6ZZBcRt2URn4YCLcXFY= -github.com/cosmos/ibc-go/v4 v4.5.0 h1:pjYO0/PbqbRxcRyptwjA6M4hUSnzxEoGp5G56/VVQoQ= -github.com/cosmos/ibc-go/v4 v4.5.0/go.mod h1:2EOi40Bx/j6rJrtP1ui8k8yUAMpGybmL1EjakYqYv5U= +github.com/cosmos/ibc-go/v4 v4.5.1 h1:+P73X7aIikGAXBUJ9vP9rEbvdSuekt3KGXmAWCSYets= +github.com/cosmos/ibc-go/v4 v4.5.1/go.mod h1:2EOi40Bx/j6rJrtP1ui8k8yUAMpGybmL1EjakYqYv5U= github.com/cosmos/interchain-accounts v0.2.6 h1:TV2M2g1/Rb9MCNw1YePdBKE0rcEczNj1RGHT+2iRYas= github.com/cosmos/ledger-cosmos-go v0.12.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKyF3nNqAXZA= github.com/cosmos/ledger-cosmos-go v0.12.2/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI= From ca49a1d4236ae31434bb15ae22ce404c497a53e0 Mon Sep 17 00:00:00 2001 From: Supanat Date: Wed, 25 Oct 2023 22:36:07 +0700 Subject: [PATCH 13/25] fix: `{overflow}` bug when querying cosmwasmpool spot price (#6710) * fix cosmwasm query helper gas limit * update osmoutils version * update changelog --- CHANGELOG.md | 1 + go.mod | 2 +- go.sum | 2 ++ osmoutils/cosmwasm/helpers.go | 4 ++++ x/cosmwasmpool/types/expected_keepers.go | 2 ++ 5 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ce58ff8295..fc060840be9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,6 +69,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#6666](https://github.com/osmosis-labs/osmosis/pull/6666) fix: cosmwasmpool state export bug * [#6674](https://github.com/osmosis-labs/osmosis/pull/6674) fix: remove dragonberry replace directive * [#6692](https://github.com/osmosis-labs/osmosis/pull/6692) chore: add cur sqrt price to LiquidityNetInDirection return value +* [#6710](https://github.com/osmosis-labs/osmosis/pull/6710) fix: `{overflow}` bug when querying cosmwasmpool spot price ## v19.2.0 diff --git a/go.mod b/go.mod index 08a4d9f7061..a3424397c1a 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/ory/dockertest/v3 v3.10.0 github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3 github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20231014001935-1946419d44eb - github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20231011004221-fd24b80f8366 + github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20231017074304-84e27b5e2aad github.com/osmosis-labs/osmosis/x/epochs v0.0.3-0.20231011004221-fd24b80f8366 github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.9-0.20231014001935-1946419d44eb github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index 6e09a5648e9..5b0851711ad 100644 --- a/go.sum +++ b/go.sum @@ -968,6 +968,8 @@ github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20231014001935-1946419d44eb h1 github.com/osmosis-labs/osmosis/osmomath v0.0.7-0.20231014001935-1946419d44eb/go.mod h1:jNZ952fypVNMzOsh31LAUS27JbF9naNJGtELxId6ZCg= github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20231011004221-fd24b80f8366 h1:EJDJ88w2Yv5LnlaJw5x53C0k/dp/fnEYOfBYOQiMsTc= github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20231011004221-fd24b80f8366/go.mod h1:Zmyx5zMUBN2KV94booSFn2v8KQcUKeCHqyWpKZ4PRMo= +github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20231017074304-84e27b5e2aad h1:UcQ/XLz0SqWMrA+BhgDXy9ukD4C+FlN4ULdazZmFOsE= +github.com/osmosis-labs/osmosis/osmoutils v0.0.7-0.20231017074304-84e27b5e2aad/go.mod h1:16AXMzbTLkYE5If5VLTA07fV9JNcLFwgf/VoW5sHrtU= github.com/osmosis-labs/osmosis/v19 v19.0.0 h1:gqcas/XfxtEuZXsWGTO9vNMHiY78Qs09FBQw73djIVM= github.com/osmosis-labs/osmosis/x/epochs v0.0.3-0.20231011004221-fd24b80f8366 h1:E6H0V3MKbSNwo1iXE9Kzatd2M02MgZpS5AiJ6CKK5us= github.com/osmosis-labs/osmosis/x/epochs v0.0.3-0.20231011004221-fd24b80f8366/go.mod h1:vU0IHK5W38dqMeux3MkSaT3MZU6whAkx7vNuxv1IzeU= diff --git a/osmoutils/cosmwasm/helpers.go b/osmoutils/cosmwasm/helpers.go index 21757347892..1a907f36286 100644 --- a/osmoutils/cosmwasm/helpers.go +++ b/osmoutils/cosmwasm/helpers.go @@ -2,6 +2,8 @@ package cosmwasm import ( "encoding/json" + + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -26,6 +28,7 @@ type ContractKeeper interface { // the WasmKeeper. type WasmKeeper interface { QuerySmart(ctx sdk.Context, contractAddress sdk.AccAddress, queryMsg []byte) ([]byte, error) + QueryGasLimit() storetypes.Gas } // Query is a generic function to query a CosmWasm smart contract with the given request. @@ -51,6 +54,7 @@ func Query[T any, K any](ctx sdk.Context, wasmKeeper WasmKeeper, contractAddress return response, err } + ctx = ctx.WithGasMeter(storetypes.NewGasMeter(wasmKeeper.QueryGasLimit())) responseBz, err := wasmKeeper.QuerySmart(ctx, sdk.MustAccAddressFromBech32(contractAddress), bz) if err != nil { return response, err diff --git a/x/cosmwasmpool/types/expected_keepers.go b/x/cosmwasmpool/types/expected_keepers.go index 1e4a2199a91..15324d8e308 100644 --- a/x/cosmwasmpool/types/expected_keepers.go +++ b/x/cosmwasmpool/types/expected_keepers.go @@ -1,6 +1,7 @@ package types import ( + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" @@ -52,6 +53,7 @@ type ContractKeeper interface { // the WasmKeeper. type WasmKeeper interface { QuerySmart(ctx sdk.Context, contractAddress sdk.AccAddress, queryMsg []byte) ([]byte, error) + QueryGasLimit() storetypes.Gas GetContractInfo(ctx sdk.Context, contractAddress sdk.AccAddress) *wasmtypes.ContractInfo } From 6a62e7f8d0b97513828909ad56a816dbf251f4aa Mon Sep 17 00:00:00 2001 From: xiaolou86 <20718693+xiaolou86@users.noreply.github.com> Date: Thu, 26 Oct 2023 12:46:40 +0800 Subject: [PATCH 14/25] fix typos across README and comments (#6765) --- app/upgrades/v20/upgrades_test.go | 4 ++-- app/upgrades/v8/README.md | 2 +- networks/genesis-validators.md | 2 +- networks/osmosis-1/upgrades/v10/guide.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/upgrades/v20/upgrades_test.go b/app/upgrades/v20/upgrades_test.go index ac0f89e4c23..027b27b6962 100644 --- a/app/upgrades/v20/upgrades_test.go +++ b/app/upgrades/v20/upgrades_test.go @@ -202,8 +202,8 @@ func (s *UpgradeTestSuite) TestCreateGroupsForIncentivePairs() { // 2 concentrated pools linked to 2 balancer pools - converted to group // linked balancer pools are not incentivized individually - // separete individual balancer pool - no-op - // 2 separete individual stableswap pools - no-op + // seperate individual balancer pool - no-op + // 2 seperate individual stableswap pools - no-op // concentrated pool that does not have migration link - no-op s.Run("valid multi distr record test", func() { diff --git a/app/upgrades/v8/README.md b/app/upgrades/v8/README.md index 5d8c005d347..10ed41a213f 100644 --- a/app/upgrades/v8/README.md +++ b/app/upgrades/v8/README.md @@ -18,7 +18,7 @@ The implementation of 226 will introduce a new method for unpooling: `UnPoolWhitelistedPool` -Let's review the states a position in a pool may be to be able to understand the unpooling process better. Coins are pooled together to form shares of a GAMM. These may be locked for a period of time, to receive addtional incentives. Finally, locked tokens may enter into Superfluid Delegations. +Let's review the states a position in a pool may be to be able to understand the unpooling process better. Coins are pooled together to form shares of a GAMM. These may be locked for a period of time, to receive additional incentives. Finally, locked tokens may enter into Superfluid Delegations. ```sh ┌─────────────────────────┐ ┌─────────────────────────┐ diff --git a/networks/genesis-validators.md b/networks/genesis-validators.md index 0ef95945a6c..c2db4c1102d 100644 --- a/networks/genesis-validators.md +++ b/networks/genesis-validators.md @@ -33,7 +33,7 @@ Some important notes on joining as a genesis validator: 4. To be a genesis validator, you must have OSMO at genesis via the fairdrop. Every address that had ATOMs during the Stargate upgrade of the Cosmos Hub from `cosmoshub-3` to `cosmoshub-4` will have - recieve fairdrop OSMO. You can verify that a Cosmos address has + receive fairdrop OSMO. You can verify that a Cosmos address has received coins in the fairdrop by inputting an address here: . - **Note: The airdrop URL has been deprecated.** diff --git a/networks/osmosis-1/upgrades/v10/guide.md b/networks/osmosis-1/upgrades/v10/guide.md index 49e23c495f4..3c77e639810 100644 --- a/networks/osmosis-1/upgrades/v10/guide.md +++ b/networks/osmosis-1/upgrades/v10/guide.md @@ -6,7 +6,7 @@ All validator nodes should upgrade to v10 prior to the network restarting. The v * At exactly 4:00PM UTC on June 12th, 2022, all validators start their nodes at the same time * Once 67% or more of the voting power gets online, block 4713065 will be reached, along with the upgrade at this height. Prior to 67 percent of validator power getting online, you will only see p2p logs. This is also an epoch block, so it will take some time to process * After block 4713065, three more epochs will happen back to back, one per block. -* If the June 12th epoch time has not occured yet, blocks will be produced until the epoch time. If the epoch time has occured, the June 12th epoch will occur in conjunction with the four other epochs above. +* If the June 12th epoch time has not occurred yet, blocks will be produced until the epoch time. If the epoch time has occurred, the June 12th epoch will occur in conjunction with the four other epochs above. The coordination of restart will happen over Discord. In the event Discord is down, validators should form a Telegram group to further coordinate the network restart. From 0d36c62ce2dd3ddb577e337d9e99166e765f705d Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Fri, 27 Oct 2023 17:52:29 +0200 Subject: [PATCH 15/25] Add forgotten redelegation codec (#6758) * Add forgotten redelegation codec * add changelog * Restore changelog --- CHANGELOG.md | 6 ++++++ x/valset-pref/types/codec.go | 2 ++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc060840be9..db9cf5d3994 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### State Breaks + +* [#6758](https://github.com/osmosis-labs/osmosis/pull/6758) Add codec for MsgUndelegateFromRebalancedValidatorSet + +## v20.0.0 + ### Features * [#6468](https://github.com/osmosis-labs/osmosis/pull/6468) feat: remove osmo multihop discount diff --git a/x/valset-pref/types/codec.go b/x/valset-pref/types/codec.go index b4e19e67d64..88dcb497be0 100644 --- a/x/valset-pref/types/codec.go +++ b/x/valset-pref/types/codec.go @@ -13,6 +13,7 @@ func RegisterCodec(cdc *codec.LegacyAmino) { cdc.RegisterConcrete(&MsgSetValidatorSetPreference{}, "osmosis/MsgSetValidatorSetPreference", nil) cdc.RegisterConcrete(&MsgDelegateToValidatorSet{}, "osmosis/MsgDelegateToValidatorSet", nil) cdc.RegisterConcrete(&MsgUndelegateFromValidatorSet{}, "osmosis/MsgUndelegateFromValidatorSet", nil) + cdc.RegisterConcrete(&MsgUndelegateFromRebalancedValidatorSet{}, "osmosis/MsgUndelegateFromRebalValset", nil) cdc.RegisterConcrete(&MsgWithdrawDelegationRewards{}, "osmosis/MsgWithdrawDelegationRewards", nil) cdc.RegisterConcrete(&MsgRedelegateValidatorSet{}, "osmosis/MsgRedelegateValidatorSet", nil) } @@ -23,6 +24,7 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { &MsgSetValidatorSetPreference{}, &MsgDelegateToValidatorSet{}, &MsgUndelegateFromValidatorSet{}, + &MsgUndelegateFromRebalancedValidatorSet{}, &MsgWithdrawDelegationRewards{}, &MsgRedelegateValidatorSet{}, ) From 3abc40e5bfdda882f15203567997468b60d33755 Mon Sep 17 00:00:00 2001 From: Osmosis <105710778+osmo-bot@users.noreply.github.com> Date: Fri, 27 Oct 2023 13:16:41 -0500 Subject: [PATCH 16/25] auto: code-gen upgrade handler v21 (#6776) * [create-pull-request] automated change * Update config.go --------- Co-authored-by: czarcas7ic Co-authored-by: Adam Tucker --- Makefile | 2 +- app/app.go | 3 ++- app/upgrades/v21/constants.go | 19 +++++++++++++++++++ app/upgrades/v21/upgrades.go | 28 ++++++++++++++++++++++++++++ tests/e2e/containers/config.go | 4 ++-- 5 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 app/upgrades/v21/constants.go create mode 100644 app/upgrades/v21/upgrades.go diff --git a/Makefile b/Makefile index 5cf13e191bb..36b7fcbb089 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ LEDGER_ENABLED ?= true SDK_PACK := $(shell go list -m github.com/cosmos/cosmos-sdk | sed 's/ /\@/g') BUILDDIR ?= $(CURDIR)/build DOCKER := $(shell which docker) -E2E_UPGRADE_VERSION := "v20" +E2E_UPGRADE_VERSION := "v21" #SHELL := /bin/bash # Go version to be used in docker images diff --git a/app/app.go b/app/app.go index 9e5480e85da..08c29fc5508 100644 --- a/app/app.go +++ b/app/app.go @@ -61,6 +61,7 @@ import ( v18 "github.com/osmosis-labs/osmosis/v20/app/upgrades/v18" v19 "github.com/osmosis-labs/osmosis/v20/app/upgrades/v19" v20 "github.com/osmosis-labs/osmosis/v20/app/upgrades/v20" + v21 "github.com/osmosis-labs/osmosis/v20/app/upgrades/v21" v3 "github.com/osmosis-labs/osmosis/v20/app/upgrades/v3" v4 "github.com/osmosis-labs/osmosis/v20/app/upgrades/v4" v5 "github.com/osmosis-labs/osmosis/v20/app/upgrades/v5" @@ -106,7 +107,7 @@ var ( // _ sdksimapp.App = (*OsmosisApp)(nil) - Upgrades = []upgrades.Upgrade{v4.Upgrade, v5.Upgrade, v7.Upgrade, v9.Upgrade, v11.Upgrade, v12.Upgrade, v13.Upgrade, v14.Upgrade, v15.Upgrade, v16.Upgrade, v17.Upgrade, v18.Upgrade, v19.Upgrade, v20.Upgrade} + Upgrades = []upgrades.Upgrade{v4.Upgrade, v5.Upgrade, v7.Upgrade, v9.Upgrade, v11.Upgrade, v12.Upgrade, v13.Upgrade, v14.Upgrade, v15.Upgrade, v16.Upgrade, v17.Upgrade, v18.Upgrade, v19.Upgrade, v20.Upgrade, v21.Upgrade} Forks = []upgrades.Fork{v3.Fork, v6.Fork, v8.Fork, v10.Fork} ) diff --git a/app/upgrades/v21/constants.go b/app/upgrades/v21/constants.go new file mode 100644 index 00000000000..e8b9039cb3e --- /dev/null +++ b/app/upgrades/v21/constants.go @@ -0,0 +1,19 @@ +package v21 + +import ( + "github.com/osmosis-labs/osmosis/v20/app/upgrades" + + store "github.com/cosmos/cosmos-sdk/store/types" +) + +// UpgradeName defines the on-chain upgrade name for the Osmosis v21 upgrade. +const UpgradeName = "v21" + +var Upgrade = upgrades.Upgrade{ + UpgradeName: UpgradeName, + CreateUpgradeHandler: CreateUpgradeHandler, + StoreUpgrades: store.StoreUpgrades{ + Added: []string{}, + Deleted: []string{}, + }, +} diff --git a/app/upgrades/v21/upgrades.go b/app/upgrades/v21/upgrades.go new file mode 100644 index 00000000000..1ccfa242734 --- /dev/null +++ b/app/upgrades/v21/upgrades.go @@ -0,0 +1,28 @@ +package v21 + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + + "github.com/osmosis-labs/osmosis/v20/app/keepers" + "github.com/osmosis-labs/osmosis/v20/app/upgrades" +) + +func CreateUpgradeHandler( + mm *module.Manager, + configurator module.Configurator, + bpm upgrades.BaseAppParamManager, + keepers *keepers.AppKeepers, +) upgradetypes.UpgradeHandler { + return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + // Run migrations before applying any other state changes. + // NOTE: DO NOT PUT ANY STATE CHANGES BEFORE RunMigrations(). + migrations, err := mm.RunMigrations(ctx, configurator, fromVM) + if err != nil { + return nil, err + } + + return migrations, nil + } +} diff --git a/tests/e2e/containers/config.go b/tests/e2e/containers/config.go index c540d432792..ed1ea094bc2 100644 --- a/tests/e2e/containers/config.go +++ b/tests/e2e/containers/config.go @@ -24,10 +24,10 @@ const ( // It should be uploaded to Docker Hub. OSMOSIS_E2E_SKIP_UPGRADE should be unset // for this functionality to be used. previousVersionOsmoRepository = "osmolabs/osmosis" - previousVersionOsmoTag = "19.0.0-alpine" + previousVersionOsmoTag = "20.1.0-alpine" // Pre-upgrade repo/tag for osmosis initialization (this should be one version below upgradeVersion) previousVersionInitRepository = "osmolabs/osmosis-e2e-init-chain" - previousVersionInitTag = "19.0.0" + previousVersionInitTag = "20.1.0" // Hermes repo/version for relayer relayerRepository = "informalsystems/hermes" relayerTag = "1.5.1" From 294ee63dbf4267244fb1436e6c0230ff0917e420 Mon Sep 17 00:00:00 2001 From: "Matt, Park" <45252226+mattverse@users.noreply.github.com> Date: Mon, 30 Oct 2023 13:35:28 +0900 Subject: [PATCH 17/25] Refactor: Change Makefile with better accessibility (#6727) * WIP * Finish * Separate out make files * Cleanup duplicated command * Make lint ci happy --- .github/workflows/lint.yml | 4 +- Makefile | 567 ++--------------------- scripts/makefiles/build.mk | 139 ++++++ scripts/makefiles/deps.mk | 62 +++ scripts/makefiles/docker.mk | 50 ++ scripts/makefiles/e2e.mk | 43 ++ scripts/makefiles/lint.mk | 32 ++ scripts/makefiles/localnet.mk | 154 ++++++ scripts/makefiles/proto.mk | 59 +++ scripts/makefiles/release.mk | 41 ++ scripts/makefiles/tests.mk | 91 ++++ tests/e2e/README.md | 2 +- tests/e2e/containers/config.go | 2 +- tests/e2e/initialization/README.md | 4 +- tests/e2e/initialization/init.Dockerfile | 2 +- tests/e2e/scripts/run/check_image_sha.sh | 4 +- 16 files changed, 715 insertions(+), 541 deletions(-) create mode 100644 scripts/makefiles/build.mk create mode 100644 scripts/makefiles/deps.mk create mode 100644 scripts/makefiles/docker.mk create mode 100644 scripts/makefiles/e2e.mk create mode 100644 scripts/makefiles/lint.mk create mode 100644 scripts/makefiles/localnet.mk create mode 100644 scripts/makefiles/proto.mk create mode 100644 scripts/makefiles/release.mk create mode 100644 scripts/makefiles/tests.mk diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 2c87042b846..ef48f91efaa 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -35,7 +35,7 @@ jobs: - name: Run golangci-lint if: env.GIT_DIFF - run: make lint + run: make lint-all documentation-linter: name: Run super-linter @@ -60,4 +60,4 @@ jobs: - name: Run documentation linter if: env.GIT_DIFF - run: make mdlint + run: make lint-mdlint diff --git a/Makefile b/Makefile index 36b7fcbb089..68287a7236c 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,38 @@ #!/usr/bin/make -f +# the subcommands are located in the specific makefiles +include scripts/makefiles/build.mk +include scripts/makefiles/deps.mk +include scripts/makefiles/docker.mk +include scripts/makefiles/e2e.mk +include scripts/makefiles/lint.mk +include scripts/makefiles/localnet.mk +include scripts/makefiles/proto.mk +include scripts/makefiles/release.mk +include scripts/makefiles/tests.mk + +.DEFAULT_GOAL := help +help: + @echo "Available top-level commands:" + @echo "" + @echo "Usage:" + @echo " make [command]" + @echo "" + @echo " make build Build osmosisd binary" + @echo " make install Install osmosisd binary" + @echo " make deps Show available deps commands" + @echo " make proto Show available proto commands" + @echo " make release Show available release commands" + @echo " make e2e Show available e2e commands" + @echo " make docker Show available docker commands" + @echo " make lint Show available lint commands" + @echo " make test Show available test commands" + @echo " make test Show available test commands" + @echo " make localnet Show available localnet commands" + @echo " make release-help Show available release commands" + @echo "" + @echo "Run 'make [subcommand]' to see the available commands for each subcommand." + VERSION := $(shell echo $(shell git describe --tags) | sed 's/^v//') COMMIT := $(shell git log -1 --format='%H') @@ -103,527 +136,24 @@ else # In WSL SKIP_WASM_WSL_TESTS := "true" endif - ############################################################################### -### Build ### +### Build & Install ### ############################################################################### -check_version: - @echo "Go version: $(GO_MAJOR_VERSION).$(GO_MINOR_VERSION)" - @if [ $(GO_MAJOR_VERSION) -gt $(GO_MINIMUM_MAJOR_VERSION) ]; then \ - echo "Go version is sufficient"; \ - exit 0; \ - elif [ $(GO_MAJOR_VERSION) -lt $(GO_MINIMUM_MAJOR_VERSION) ]; then \ - echo '$(GO_VERSION_ERR_MSG)'; \ - exit 1; \ - elif [ $(GO_MINOR_VERSION) -lt $(GO_MINIMUM_MINOR_VERSION) ]; then \ - echo '$(GO_VERSION_ERR_MSG)'; \ - exit 1; \ - fi - -all: install lint test - build: check_version go.sum mkdir -p $(BUILDDIR)/ GOWORK=off go build -mod=readonly $(BUILD_FLAGS) -o $(BUILDDIR)/ $(GO_MODULE)/cmd/osmosisd -build-all: check_version go.sum - mkdir -p $(BUILDDIR)/ - GOWORK=off go build -mod=readonly $(BUILD_FLAGS) -o $(BUILDDIR)/ ./... - install: check_version go.sum GOWORK=off go install -mod=readonly $(BUILD_FLAGS) $(GO_MODULE)/cmd/osmosisd -# disables optimization, inlining and symbol removal -GC_FLAGS := -gcflags="all=-N -l" -REMOVE_STRING := -w -s -DEBUG_BUILD_FLAGS:= $(subst $(REMOVE_STRING),,$(BUILD_FLAGS)) -DEBUG_LDFLAGS = $(subst $(REMOVE_STRING),,$(ldflags)) - -dev-install: go.sum - GOWORK=off go install $(DEBUG_BUILD_FLAGS) $(GC_FLAGS) $(GO_MODULE)/cmd/osmosisd - -dev-build: - mkdir -p $(BUILDDIR)/ - GOWORK=off go build $(GC_FLAGS) -mod=readonly -ldflags '$(DEBUG_LDFLAGS)' -trimpath -o $(BUILDDIR) ./...; - -install-with-autocomplete: check_version go.sum - GOWORK=off go install -mod=readonly $(BUILD_FLAGS) $(GO_MODULE)/cmd/osmosisd - @PARENT_SHELL=$$(ps -o ppid= -p $$PPID | xargs ps -o comm= -p); \ - if echo "$$PARENT_SHELL" | grep -q "zsh"; then \ - if ! grep -q ". <(osmosisd enable-cli-autocomplete zsh)" ~/.zshrc; then \ - echo ". <(osmosisd enable-cli-autocomplete zsh)" >> ~/.zshrc; \ - echo; \ - echo "Autocomplete enabled. Run 'source ~/.zshrc' to complete installation."; \ - else \ - echo; \ - echo "Autocomplete already enabled in ~/.zshrc"; \ - fi \ - elif echo "$$PARENT_SHELL" | grep -q "bash" && [ "$$(uname)" = "Darwin" ]; then \ - if ! grep -q -e "\. <(osmosisd enable-cli-autocomplete bash)" -e '\[\[ -r "/opt/homebrew/etc/profile.d/bash_completion.sh" \]\] && \. "/opt/homebrew/etc/profile.d/bash_completion.sh"' ~/.bash_profile; then \ - brew install bash-completion; \ - echo '[ -r "/opt/homebrew/etc/profile.d/bash_completion.sh" ] && . "/opt/homebrew/etc/profile.d/bash_completion.sh"' >> ~/.bash_profile; \ - echo ". <(osmosisd enable-cli-autocomplete bash)" >> ~/.bash_profile; \ - echo; \ - echo; \ - echo "Autocomplete enabled. Run 'source ~/.bash_profile' to complete installation."; \ - else \ - echo "Autocomplete already enabled in ~/.bash_profile"; \ - fi \ - elif echo "$$PARENT_SHELL" | grep -q "bash" && [ "$$(uname)" = "Linux" ]; then \ - if ! grep -q ". <(osmosisd enable-cli-autocomplete bash)" ~/.bash_profile; then \ - sudo apt-get install -y bash-completion; \ - echo '[ -r "/etc/bash_completion" ] && . "/etc/bash_completion"' >> ~/.bash_profile; \ - echo ". <(osmosisd enable-cli-autocomplete bash)" >> ~/.bash_profile; \ - echo; \ - echo "Autocomplete enabled. Run 'source ~/.bash_profile' to complete installation."; \ - else \ - echo; \ - echo "Autocomplete already enabled in ~/.bash_profile"; \ - fi \ - else \ - echo "Shell or OS not recognized. Skipping autocomplete setup."; \ - fi - - -# Cross-building for arm64 from amd64 (or viceversa) takes -# a lot of time due to QEMU virtualization but it's the only way (afaik) -# to get a statically linked binary with CosmWasm - -build-reproducible: build-reproducible-amd64 build-reproducible-arm64 - -build-reproducible-amd64: go.sum - mkdir -p $(BUILDDIR) - $(DOCKER) buildx create --name osmobuilder || true - $(DOCKER) buildx use osmobuilder - $(DOCKER) buildx build \ - --build-arg GO_VERSION=$(GO_VERSION) \ - --build-arg GIT_VERSION=$(VERSION) \ - --build-arg GIT_COMMIT=$(COMMIT) \ - --build-arg RUNNER_IMAGE=alpine:3.17 \ - --platform linux/amd64 \ - -t osmosis:local-amd64 \ - --load \ - -f Dockerfile . - $(DOCKER) rm -f osmobinary || true - $(DOCKER) create -ti --name osmobinary osmosis:local-amd64 - $(DOCKER) cp osmobinary:/bin/osmosisd $(BUILDDIR)/osmosisd-linux-amd64 - $(DOCKER) rm -f osmobinary - -build-reproducible-arm64: go.sum - mkdir -p $(BUILDDIR) - $(DOCKER) buildx create --name osmobuilder || true - $(DOCKER) buildx use osmobuilder - $(DOCKER) buildx build \ - --build-arg GO_VERSION=$(GO_VERSION) \ - --build-arg GIT_VERSION=$(VERSION) \ - --build-arg GIT_COMMIT=$(COMMIT) \ - --build-arg RUNNER_IMAGE=alpine:3.17 \ - --platform linux/arm64 \ - -t osmosis:local-arm64 \ - --load \ - -f Dockerfile . - $(DOCKER) rm -f osmobinary || true - $(DOCKER) create -ti --name osmobinary osmosis:local-arm64 - $(DOCKER) cp osmobinary:/bin/osmosisd $(BUILDDIR)/osmosisd-linux-arm64 - $(DOCKER) rm -f osmobinary - -build-linux: go.sum - LEDGER_ENABLED=false GOOS=linux GOARCH=amd64 $(MAKE) build - -build-contract-tests-hooks: - mkdir -p $(BUILDDIR) - go build -mod=readonly $(BUILD_FLAGS) -o $(BUILDDIR)/ ./cmd/contract_tests - -go-mod-cache: go.sum - @echo "--> Download go modules to local cache" - @go mod download - -go.sum: go.mod - @echo "--> Ensure dependencies have not been modified" - @GOWORK=off go mod verify - -draw-deps: - @# requires brew install graphviz or apt-get install graphviz - go get github.com/RobotsAndPencils/goviz - @goviz -i ./cmd/osmosisd -d 2 | dot -Tpng -o dependency-graph.png - -clean: - rm -rf $(CURDIR)/artifacts/ - -distclean: clean - rm -rf vendor/ - ############################################################################### -### Dependency Updates ### -############################################################################### - -SDK_VERSION := -MODFILES := ./go.mod ./osmoutils/go.mod ./osmomath/go.mod ./x/epochs/go.mod ./x/ibc-hooks/go.mod ./tests/cl-genesis-positions/go.mod ./tests/cl-go-client/go.mod -# run with SDK_VERSION argument specified -# e.g) make update-sdk-version SDK_VERSION=v0.45.1-0.20230523200430-193959b898ec -# This will change sdk dependencyu version for go.mod in root directory + all sub-modules in this repo. -update-sdk-version: - @if [ -z "$(SDK_VERSION)" ]; then \ - echo "SDK_VERSION not set"; \ - exit 1; \ - fi - @echo "Updating version to $(SDK_VERSION)" - @for modfile in $(MODFILES); do \ - if [ -e "$$modfile" ]; then \ - sed -i '' 's|github.com/osmosis-labs/cosmos-sdk v[0-9a-z.\-]*|github.com/osmosis-labs/cosmos-sdk $(SDK_VERSION)|g' $$modfile; \ - cd `dirname $$modfile`; \ - go mod tidy; \ - cd - > /dev/null; \ - else \ - echo "File $$modfile does not exist"; \ - fi; \ - done - -tidy-workspace: - @./scripts/tidy_workspace.sh - -############################################################################### -### Proto ### -############################################################################### - -proto-help: - @echo "proto subcommands" - @echo "" - @echo "Usage:" - @echo " make proto-[command]" - @echo "" - @echo "Available Commands:" - @echo " all Run proto-format and proto-gen" - @echo " gen Generate Protobuf files" - @echo " format Format Protobuf files" - @echo " image-build Build the protobuf Docker image" - @echo " image-push Push the protobuf Docker image" - -proto: proto-help -proto-all: proto-format proto-gen - -protoVer=v0.9 -protoImageName=osmolabs/osmo-proto-gen:$(protoVer) -containerProtoGen=cosmos-sdk-proto-gen-$(protoVer) -containerProtoFmt=cosmos-sdk-proto-fmt-$(protoVer) - -proto-gen: - @echo "Generating Protobuf files" - @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoGen}$$"; then docker start -a $(containerProtoGen); else docker run --name $(containerProtoGen) -v $(CURDIR):/workspace --workdir /workspace $(protoImageName) \ - sh ./scripts/protocgen.sh; fi - -proto-format: - @echo "Formatting Protobuf files" - @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoFmt}$$"; then docker start -a $(containerProtoFmt); else docker run --name $(containerProtoFmt) -v $(CURDIR):/workspace --workdir /workspace tendermintdev/docker-build-proto \ - find ./ -not -path "./third_party/*" -name "*.proto" -exec clang-format -i {} \; ; fi - -proto-image-build: - @DOCKER_BUILDKIT=1 docker build -t $(protoImageName) -f ./proto/Dockerfile ./proto - -proto-image-push: - docker push $(protoImageName) - - -test: - @go test -v ./x/... - -docs: - @echo - @echo "=========== Generate Message ============" - @echo - ./scripts/generate-docs.sh - - statik -src=client/docs/static -dest=client/docs -f -m - @if [ -n "$(git status --porcelain)" ]; then \ - echo "\033[91mSwagger docs are out of sync!!!\033[0m";\ - exit 1;\ - else \ - echo "\033[92mSwagger docs are in sync\033[0m";\ - fi - @echo - @echo "=========== Generate Complete ============" - @echo -.PHONY: docs - - -############################################################################### -### Querygen ### +### Gen ### ############################################################################### run-querygen: @go run cmd/querygen/main.go -############################################################################### -### Tests & Simulation ### -############################################################################### - -PACKAGES_UNIT=$(shell go list ./... ./osmomath/... ./osmoutils/... ./x/ibc-hooks/... ./x/epochs | grep -E -v 'tests/simulator|e2e') -PACKAGES_E2E := $(shell go list ./... | grep '/e2e' | awk -F'/e2e' '{print $$1 "/e2e"}' | uniq) -PACKAGES_SIM=$(shell go list ./... | grep '/tests/simulator') -TEST_PACKAGES=./... - -test: test-unit test-build - -test-all: test-race test-cover - -test-unit: - @VERSION=$(VERSION) SKIP_WASM_WSL_TESTS=$(SKIP_WASM_WSL_TESTS) go test -mod=readonly -tags='ledger test_ledger_mock norace' $(PACKAGES_UNIT) - -test-race: - @VERSION=$(VERSION) go test -mod=readonly -race -tags='ledger test_ledger_mock' $(PACKAGES_UNIT) - -test-cover: - @VERSION=$(VERSION) go test -mod=readonly -timeout 30m -coverprofile=coverage.txt -tags='norace' -covermode=atomic $(PACKAGES_UNIT) - -test-sim-suite: - @VERSION=$(VERSION) go test -mod=readonly $(PACKAGES_SIM) - -test-sim-app: - @VERSION=$(VERSION) go test -mod=readonly -run ^TestFullAppSimulation -v $(PACKAGES_SIM) - -test-sim-determinism: - @VERSION=$(VERSION) go test -mod=readonly -run ^TestAppStateDeterminism -v $(PACKAGES_SIM) - -test-sim-bench: - @VERSION=$(VERSION) go test -benchmem -run ^BenchmarkFullAppSimulation -bench ^BenchmarkFullAppSimulation -cpuprofile cpu.out $(PACKAGES_SIM) - -# test-e2e runs a full e2e test suite -# deletes any pre-existing Osmosis containers before running. -# -# Deletes Docker resources at the end. -# Utilizes Go cache. -test-e2e: e2e-setup test-e2e-ci e2e-remove-resources - -# test-e2e-ci runs a majority of e2e tests, only skipping the ones that are marked as scheduled tests -# does not do any validation about the state of the Docker environment -# As a result, avoid using this locally. -test-e2e-ci: - @VERSION=$(VERSION) OSMOSIS_E2E=True OSMOSIS_E2E_DEBUG_LOG=False OSMOSIS_E2E_UPGRADE_VERSION=$(E2E_UPGRADE_VERSION) go test -mod=readonly -timeout=25m -v $(PACKAGES_E2E) -p 4 - -# test-e2e-ci-scheduled runs every e2e test available, and is only run on a scheduled basis -test-e2e-ci-scheduled: - @VERSION=$(VERSION) OSMOSIS_E2E_SCHEDULED=True OSMOSIS_E2E=True OSMOSIS_E2E_DEBUG_LOG=False OSMOSIS_E2E_UPGRADE_VERSION=$(E2E_UPGRADE_VERSION) go test -mod=readonly -timeout=25m -v $(PACKAGES_E2E) -p 4 - -# test-e2e-debug runs a full e2e test suite but does -# not attempt to delete Docker resources at the end. -test-e2e-debug: e2e-setup - @VERSION=$(VERSION) OSMOSIS_E2E=True OSMOSIS_E2E_DEBUG_LOG=True OSMOSIS_E2E_UPGRADE_VERSION=$(E2E_UPGRADE_VERSION) OSMOSIS_E2E_SKIP_CLEANUP=True go test -mod=readonly -timeout=25m -v $(PACKAGES_E2E) -count=1 - -# test-e2e-short runs the e2e test with only short tests. -# Does not delete any of the containers after running. -# Deletes any existing containers before running. -# Does not use Go cache. -test-e2e-short: e2e-setup - @VERSION=$(VERSION) OSMOSIS_E2E=True OSMOSIS_E2E_DEBUG_LOG=True OSMOSIS_E2E_SKIP_UPGRADE=True OSMOSIS_E2E_SKIP_IBC=True OSMOSIS_E2E_SKIP_STATE_SYNC=True OSMOSIS_E2E_SKIP_CLEANUP=True go test -mod=readonly -timeout=25m -v $(PACKAGES_E2E) -count=1 - -test-mutation: - @bash scripts/mutation-test.sh $(MODULES) - -benchmark: - @go test -mod=readonly -bench=. $(PACKAGES_UNIT) - -build-e2e-script: - mkdir -p $(BUILDDIR) - go build -mod=readonly $(BUILD_FLAGS) -o $(BUILDDIR)/ ./tests/e2e/initialization/$(E2E_SCRIPT_NAME) - -docker-build-debug: - @DOCKER_BUILDKIT=1 docker build -t osmosis:${COMMIT} --build-arg BASE_IMG_TAG=debug --build-arg RUNNER_IMAGE=$(RUNNER_BASE_IMAGE_ALPINE) -f Dockerfile . - @DOCKER_BUILDKIT=1 docker tag osmosis:${COMMIT} osmosis:debug - -docker-build-e2e-init-chain: - @DOCKER_BUILDKIT=1 docker build -t osmolabs/osmosis-e2e-init-chain:debug --build-arg E2E_SCRIPT_NAME=chain --platform=linux/x86_64 -f tests/e2e/initialization/init.Dockerfile . - -docker-build-e2e-init-node: - @DOCKER_BUILDKIT=1 docker build -t osmosis-e2e-init-node:debug --build-arg E2E_SCRIPT_NAME=node --platform=linux/x86_64 -f tests/e2e/initialization/init.Dockerfile . - -e2e-setup: e2e-check-image-sha e2e-remove-resources - @echo Finished e2e environment setup, ready to start the test - -e2e-check-image-sha: - tests/e2e/scripts/run/check_image_sha.sh - -e2e-remove-resources: - tests/e2e/scripts/run/remove_stale_resources.sh - -.PHONY: test-mutation - -############################################################################### -### Docker ### -############################################################################### - -RUNNER_BASE_IMAGE_DISTROLESS := gcr.io/distroless/static-debian11 -RUNNER_BASE_IMAGE_ALPINE := alpine:3.17 -RUNNER_BASE_IMAGE_NONROOT := gcr.io/distroless/static-debian11:nonroot - -docker-build: - @DOCKER_BUILDKIT=1 docker build \ - -t osmosis:local \ - -t osmosis:local-distroless \ - --build-arg GO_VERSION=$(GO_VERSION) \ - --build-arg RUNNER_IMAGE=$(RUNNER_BASE_IMAGE_DISTROLESS) \ - --build-arg GIT_VERSION=$(VERSION) \ - --build-arg GIT_COMMIT=$(COMMIT) \ - -f Dockerfile . - -docker-build-distroless: docker-build - -docker-build-alpine: - @DOCKER_BUILDKIT=1 docker build \ - -t osmosis:local-alpine \ - --build-arg GO_VERSION=$(GO_VERSION) \ - --build-arg RUNNER_IMAGE=$(RUNNER_BASE_IMAGE_ALPINE) \ - --build-arg GIT_VERSION=$(VERSION) \ - --build-arg GIT_COMMIT=$(COMMIT) \ - -f Dockerfile . - -docker-build-nonroot: - @DOCKER_BUILDKIT=1 docker build \ - -t osmosis:local-nonroot \ - --build-arg GO_VERSION=$(GO_VERSION) \ - --build-arg RUNNER_IMAGE=$(RUNNER_BASE_IMAGE_NONROOT) \ - --build-arg GIT_VERSION=$(VERSION) \ - --build-arg GIT_COMMIT=$(COMMIT) \ - -f Dockerfile . - -############################################################################### -### Linting ### -############################################################################### - -lint: - @echo "--> Running linter" - @go run github.com/golangci/golangci-lint/cmd/golangci-lint run --timeout=10m - @docker run -v $(PWD):/workdir ghcr.io/igorshubovych/markdownlint-cli:latest "**/*.md" - -format: - @go run github.com/golangci/golangci-lint/cmd/golangci-lint run ./... --fix - @go run mvdan.cc/gofumpt -l -w x/ app/ ante/ tests/ - @docker run -v $(PWD):/workdir ghcr.io/igorshubovych/markdownlint-cli:latest "**/*.md" --fix - -mdlint: - @echo "--> Running markdown linter" - @docker run -v $(PWD):/workdir ghcr.io/igorshubovych/markdownlint-cli:latest "**/*.md" - -markdown: - @docker run -v $(PWD):/workdir ghcr.io/igorshubovych/markdownlint-cli:latest "**/*.md" --fix - -############################################################################### -### Localnet ### -############################################################################### -# -# Please refer to https://github.com/osmosis-labs/osmosis/blob/main/tests/localosmosis/README.md for detailed -# usage of localnet. - -localnet-keys: - . tests/localosmosis/scripts/add_keys.sh - -localnet-init: localnet-clean localnet-build - -localnet-build: - @DOCKER_BUILDKIT=1 COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f tests/localosmosis/docker-compose.yml build - -localnet-start: - @STATE="" docker-compose -f tests/localosmosis/docker-compose.yml up - -localnet-start-with-state: - @STATE=-s docker-compose -f tests/localosmosis/docker-compose.yml up - -localnet-startd: - @STATE="" docker-compose -f tests/localosmosis/docker-compose.yml up -d - -localnet-startd-with-state: - @STATE=-s docker-compose -f tests/localosmosis/docker-compose.yml up -d - -localnet-stop: - @STATE="" docker-compose -f tests/localosmosis/docker-compose.yml down - -localnet-clean: - @rm -rfI $(HOME)/.osmosisd-local/ - -localnet-state-export-init: localnet-state-export-clean localnet-state-export-build - -localnet-state-export-build: - @DOCKER_BUILDKIT=1 COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f tests/localosmosis/state_export/docker-compose.yml build - -localnet-state-export-start: - @docker-compose -f tests/localosmosis/state_export/docker-compose.yml up - -localnet-state-export-startd: - @docker-compose -f tests/localosmosis/state_export/docker-compose.yml up -d - -localnet-state-export-stop: - @docker-compose -f tests/localosmosis/docker-compose.yml down - -localnet-state-export-clean: localnet-clean - -# create 100 concentrated-liquidity positions in localosmosis at pool id 1 -localnet-cl-create-positions: - go run tests/cl-go-client/main.go --operation 0 - -# does 100 small randomized swaps in localosmosis at pool id 1 -localnet-cl-small-swap: - go run tests/cl-go-client/main.go --operation 1 - -# does 100 large swaps where the output of the previous swap is swapped back at the -# next swap. localosmosis at pool id 1 -localnet-cl-large-swap: - go run tests/cl-go-client/main.go --operation 2 - -# creates a gauge and waits for one epoch so that the gauge -# is converted into an incentive record for pool id 1. -localnet-cl-external-incentive: - go run tests/cl-go-client/main.go --operation 3 - -# attempts to create a CL pool at id 1. -# if pool already exists, this is a no-op. -# if pool with different id is desired, tweak expectedPoolId -# in the script. -localnet-cl-create-pool: - go run tests/cl-go-client/main.go --operation 4 - -# claims spread rewards for a random account for a random -# subset of positions. -localnet-cl-claim-spread-rewards: - go run tests/cl-go-client/main.go --operation 5 - -# claims incentives for a random account for a random -# subset of positions. -localnet-cl-claim-incentives: - go run tests/cl-go-client/main.go --operation 6 - -localnet-cl-add-to-positions: - go run tests/cl-go-client/main.go --operation 7 - -localnet-cl-withdraw-positions: - go run tests/cl-go-client/main.go --operation 8 - - -# does both of localnet-cl-create-positions and localnet-cl-small-swap -localnet-cl-positions-small-swaps: localnet-cl-create-positions localnet-cl-small-swap - -# does both of localnet-cl-create-positions and localnet-cl-large-swap -localnet-cl-positions-large-swaps: localnet-cl-create-positions localnet-cl-large-swap - -# This script retrieves Uniswap v3 Ethereum position data -# from subgraph. It uses WETH / USDC pool. This is helpful -# for setting up somewhat realistic positions for testing -# in localosmosis. It writes the file under -# tests/cl-genesis-positions/subgraph_positions.json -cl-refresh-subgraph-positions: - go run ./tests/cl-genesis-positions --operation 0 - -# This script converts the positions data created by the -# cl-refresh-subgraph-positions makefile step into an Osmosis -# genesis. It writes the file under tests/cl-genesis-positions/genesis.json -cl-refresh-subgraph-genesis: - go run ./tests/cl-genesis-positions --operation 1 - -# This script converts the positions data created by the -# cl-refresh-subgraph-positions makefile step into a Big Bang -# configuration file for spinning up testnets. -# It writes the file under tests/cl-genesis-positions/bigbang_positions.json -cl-create-bigbang-config: - go run ./tests/cl-genesis-positions --operation 1 --big-bang ############################################################################### ### Go Mock ### @@ -638,7 +168,6 @@ go-mock-update: ############################################################################### ### Release ### ############################################################################### - GORELEASER_IMAGE := ghcr.io/goreleaser/goreleaser-cross:v$(GO_VERSION) COSMWASM_VERSION := $(shell go list -m github.com/CosmWasm/wasmvm | sed 's/.* //') @@ -659,32 +188,6 @@ release: @echo "Error: GITHUB_TOKEN is not defined. Please define it before running 'make release'." endif -release-dry-run: - docker run \ - --rm \ - -e COSMWASM_VERSION=$(COSMWASM_VERSION) \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v `pwd`:/go/src/osmosisd \ - -w /go/src/osmosisd \ - $(GORELEASER_IMAGE) \ - release \ - --clean \ - --skip-publish - -release-snapshot: - docker run \ - --rm \ - -e COSMWASM_VERSION=$(COSMWASM_VERSION) \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v `pwd`:/go/src/osmosisd \ - -w /go/src/osmosisd \ - $(GORELEASER_IMAGE) \ - release \ - --clean \ - --snapshot \ - --skip-validate \ - --skip-publish - .PHONY: all build-linux install format lint \ go-mod-cache draw-deps clean build build-contract-tests-hooks \ test test-all test-build test-cover test-unit test-race benchmark \ diff --git a/scripts/makefiles/build.mk b/scripts/makefiles/build.mk new file mode 100644 index 00000000000..dc7d836c306 --- /dev/null +++ b/scripts/makefiles/build.mk @@ -0,0 +1,139 @@ +############################################################################### +### Build ### +############################################################################### + +build-help: + @echo "build subcommands" + @echo "" + @echo "Usage:" + @echo " make build-[command]" + @echo "" + @echo "Available Commands:" + @echo " all Build all targets" + @echo " check-version Check Go version" + @echo " dev-install Install development build" + @echo " dev-build Build development version" + @echo " install-with-autocomplete Install with autocomplete support" + @echo " reproducible Build reproducible binaries" + @echo " reproducible-amd64 Build reproducible amd64 binary" + @echo " reproducible-arm64 Build reproducible arm64 binary" + @echo " linux Build for Linux" + @echo " contract-tests-hooks Build contract tests hooks" + +build-check-version: + @echo "Go version: $(GO_MAJOR_VERSION).$(GO_MINOR_VERSION)" + @if [ $(GO_MAJOR_VERSION) -gt $(GO_MINIMUM_MAJOR_VERSION) ]; then \ + echo "Go version is sufficient"; \ + exit 0; \ + elif [ $(GO_MAJOR_VERSION) -lt $(GO_MINIMUM_MAJOR_VERSION) ]; then \ + echo '$(GO_VERSION_ERR_MSG)'; \ + exit 1; \ + elif [ $(GO_MINOR_VERSION) -lt $(GO_MINIMUM_MINOR_VERSION) ]; then \ + echo '$(GO_VERSION_ERR_MSG)'; \ + exit 1; \ + fi + +build-all: check_version go.sum + mkdir -p $(BUILDDIR)/ + GOWORK=off go build -mod=readonly $(BUILD_FLAGS) -o $(BUILDDIR)/ ./... + +# disables optimization, inlining and symbol removal +GC_FLAGS := -gcflags="all=-N -l" +REMOVE_STRING := -w -s +DEBUG_BUILD_FLAGS:= $(subst $(REMOVE_STRING),,$(BUILD_FLAGS)) +DEBUG_LDFLAGS = $(subst $(REMOVE_STRING),,$(ldflags)) + +build-dev-install: go.sum + GOWORK=off go install $(DEBUG_BUILD_FLAGS) $(GC_FLAGS) $(GO_MODULE)/cmd/osmosisd + +build-dev-build: + mkdir -p $(BUILDDIR)/ + GOWORK=off go build $(GC_FLAGS) -mod=readonly -ldflags '$(DEBUG_LDFLAGS)' -trimpath -o $(BUILDDIR) ./...; + +build-install-with-autocomplete: check_version go.sum + GOWORK=off go install -mod=readonly $(BUILD_FLAGS) $(GO_MODULE)/cmd/osmosisd + @PARENT_SHELL=$$(ps -o ppid= -p $$PPID | xargs ps -o comm= -p); \ + if echo "$$PARENT_SHELL" | grep -q "zsh"; then \ + if ! grep -q ". <(osmosisd enable-cli-autocomplete zsh)" ~/.zshrc; then \ + echo ". <(osmosisd enable-cli-autocomplete zsh)" >> ~/.zshrc; \ + echo; \ + echo "Autocomplete enabled. Run 'source ~/.zshrc' to complete installation."; \ + else \ + echo; \ + echo "Autocomplete already enabled in ~/.zshrc"; \ + fi \ + elif echo "$$PARENT_SHELL" | grep -q "bash" && [ "$$(uname)" = "Darwin" ]; then \ + if ! grep -q -e "\. <(osmosisd enable-cli-autocomplete bash)" -e '\[\[ -r "/opt/homebrew/etc/profile.d/bash_completion.sh" \]\] && \. "/opt/homebrew/etc/profile.d/bash_completion.sh"' ~/.bash_profile; then \ + brew install bash-completion; \ + echo '[ -r "/opt/homebrew/etc/profile.d/bash_completion.sh" ] && . "/opt/homebrew/etc/profile.d/bash_completion.sh"' >> ~/.bash_profile; \ + echo ". <(osmosisd enable-cli-autocomplete bash)" >> ~/.bash_profile; \ + echo; \ + echo; \ + echo "Autocomplete enabled. Run 'source ~/.bash_profile' to complete installation."; \ + else \ + echo "Autocomplete already enabled in ~/.bash_profile"; \ + fi \ + elif echo "$$PARENT_SHELL" | grep -q "bash" && [ "$$(uname)" = "Linux" ]; then \ + if ! grep -q ". <(osmosisd enable-cli-autocomplete bash)" ~/.bash_profile; then \ + sudo apt-get install -y bash-completion; \ + echo '[ -r "/etc/bash_completion" ] && . "/etc/bash_completion"' >> ~/.bash_profile; \ + echo ". <(osmosisd enable-cli-autocomplete bash)" >> ~/.bash_profile; \ + echo; \ + echo "Autocomplete enabled. Run 'source ~/.bash_profile' to complete installation."; \ + else \ + echo; \ + echo "Autocomplete already enabled in ~/.bash_profile"; \ + fi \ + else \ + echo "Shell or OS not recognized. Skipping autocomplete setup."; \ + fi + + +# Cross-building for arm64 from amd64 (or viceversa) takes +# a lot of time due to QEMU virtualization but it's the only way (afaik) +# to get a statically linked binary with CosmWasm + +build-reproducible: build-reproducible-amd64 build-reproducible-arm64 + +build-reproducible-amd64: go.sum + mkdir -p $(BUILDDIR) + $(DOCKER) buildx create --name osmobuilder || true + $(DOCKER) buildx use osmobuilder + $(DOCKER) buildx build \ + --build-arg GO_VERSION=$(GO_VERSION) \ + --build-arg GIT_VERSION=$(VERSION) \ + --build-arg GIT_COMMIT=$(COMMIT) \ + --build-arg RUNNER_IMAGE=alpine:3.17 \ + --platform linux/amd64 \ + -t osmosis:local-amd64 \ + --load \ + -f Dockerfile . + $(DOCKER) rm -f osmobinary || true + $(DOCKER) create -ti --name osmobinary osmosis:local-amd64 + $(DOCKER) cp osmobinary:/bin/osmosisd $(BUILDDIR)/osmosisd-linux-amd64 + $(DOCKER) rm -f osmobinary + +build-reproducible-arm64: go.sum + mkdir -p $(BUILDDIR) + $(DOCKER) buildx create --name osmobuilder || true + $(DOCKER) buildx use osmobuilder + $(DOCKER) buildx build \ + --build-arg GO_VERSION=$(GO_VERSION) \ + --build-arg GIT_VERSION=$(VERSION) \ + --build-arg GIT_COMMIT=$(COMMIT) \ + --build-arg RUNNER_IMAGE=alpine:3.17 \ + --platform linux/arm64 \ + -t osmosis:local-arm64 \ + --load \ + -f Dockerfile . + $(DOCKER) rm -f osmobinary || true + $(DOCKER) create -ti --name osmobinary osmosis:local-arm64 + $(DOCKER) cp osmobinary:/bin/osmosisd $(BUILDDIR)/osmosisd-linux-arm64 + $(DOCKER) rm -f osmobinary + +build-linux: go.sum + LEDGER_ENABLED=false GOOS=linux GOARCH=amd64 $(MAKE) build + +build-contract-tests-hooks: + mkdir -p $(BUILDDIR) + go build -mod=readonly $(BUILD_FLAGS) -o $(BUILDDIR)/ ./cmd/contract_tests \ No newline at end of file diff --git a/scripts/makefiles/deps.mk b/scripts/makefiles/deps.mk new file mode 100644 index 00000000000..97b25a98a7d --- /dev/null +++ b/scripts/makefiles/deps.mk @@ -0,0 +1,62 @@ +############################################################################### +### Dependency Updates ### +############################################################################### +deps-help: + @echo "Dependency Update subcommands" + @echo "" + @echo "Usage:" + @echo " make deps-[command]" + @echo "" + @echo "Available Commands:" + @echo " go-mod-cache Download go modules to local cache" + @echo " go.sum Ensure dependencies have not been modified" + @echo " draw Create a dependency graph" + @echo " clean Remove artifacts" + @echo " distclean Remove vendor directory" + @echo " update-sdk-version Update SDK version" + @echo " tidy-workspace Tidy workspace" +deps: deps-help + +deps-go-mod-cache: go.sum + @echo "--> Download go modules to local cache" + @go mod download + +deps-go.sum: go.mod + @echo "--> Ensure dependencies have not been modified" + @GOWORK=off go mod verify + +deps-draw: + @# requires brew install graphviz or apt-get install graphviz + go get github.com/RobotsAndPencils/goviz + @goviz -i ./cmd/osmosisd -d 2 | dot -Tpng -o dependency-graph.png + +dpes-clean: + rm -rf $(CURDIR)/artifacts/ + +deps-distclean: clean + rm -rf vendor/ + +VERSION := +MODFILES := ./go.mod ./osmoutils/go.mod ./osmomath/go.mod ./x/epochs/go.mod ./x/ibc-hooks/go.mod ./tests/cl-genesis-positions/go.mod ./tests/cl-go-client/go.mod +# run with VERSION argument specified +# e.g) make update-sdk-version VERSION=v0.45.1-0.20230523200430-193959b898ec +# This will change sdk dependencyu version for go.mod in root directory + all sub-modules in this repo. +deps-update-sdk-version: + @if [ -z "$(VERSION)" ]; then \ + echo "VERSION not set"; \ + exit 1; \ + fi + @echo "Updating version to $(VERSION)" + @for modfile in $(MODFILES); do \ + if [ -e "$$modfile" ]; then \ + sed -i '' 's|github.com/osmosis-labs/cosmos-sdk v[0-9a-z.\-]*|github.com/osmosis-labs/cosmos-sdk $(VERSION)|g' $$modfile; \ + cd `dirname $$modfile`; \ + go mod tidy; \ + cd - > /dev/null; \ + else \ + echo "File $$modfile does not exist"; \ + fi; \ + done + +deps-tidy-workspace: + @./scripts/tidy_workspace.sh diff --git a/scripts/makefiles/docker.mk b/scripts/makefiles/docker.mk new file mode 100644 index 00000000000..2b4181c0c36 --- /dev/null +++ b/scripts/makefiles/docker.mk @@ -0,0 +1,50 @@ +############################################################################### +### Docker ### +############################################################################### + +RUNNER_BASE_IMAGE_DISTROLESS := gcr.io/distroless/static-debian11 +RUNNER_BASE_IMAGE_ALPINE := alpine:3.17 +RUNNER_BASE_IMAGE_NONROOT := gcr.io/distroless/static-debian11:nonroot + +docker-help: + @echo "docker subcommands" + @echo "" + @echo "Usage:" + @echo " make docker-[command]" + @echo "" + @echo "Available Commands:" + @echo " build Build Docker image" + @echo " build-distroless Build distroless Docker image" + @echo " build-alpine Build alpine Docker image" + @echo " build-nonroot Build nonroot Docker image" +docker: docker-help + +docker-build: + @DOCKER_BUILDKIT=1 docker build \ + -t osmosis:local \ + -t osmosis:local-distroless \ + --build-arg GO_VERSION=$(GO_VERSION) \ + --build-arg RUNNER_IMAGE=$(RUNNER_BASE_IMAGE_DISTROLESS) \ + --build-arg GIT_VERSION=$(VERSION) \ + --build-arg GIT_COMMIT=$(COMMIT) \ + -f Dockerfile . + +docker-build-distroless: docker-build + +docker-build-alpine: + @DOCKER_BUILDKIT=1 docker build \ + -t osmosis:local-alpine \ + --build-arg GO_VERSION=$(GO_VERSION) \ + --build-arg RUNNER_IMAGE=$(RUNNER_BASE_IMAGE_ALPINE) \ + --build-arg GIT_VERSION=$(VERSION) \ + --build-arg GIT_COMMIT=$(COMMIT) \ + -f Dockerfile . + +docker-build-nonroot: + @DOCKER_BUILDKIT=1 docker build \ + -t osmosis:local-nonroot \ + --build-arg GO_VERSION=$(GO_VERSION) \ + --build-arg RUNNER_IMAGE=$(RUNNER_BASE_IMAGE_NONROOT) \ + --build-arg GIT_VERSION=$(VERSION) \ + --build-arg GIT_COMMIT=$(COMMIT) \ + -f Dockerfile . diff --git a/scripts/makefiles/e2e.mk b/scripts/makefiles/e2e.mk new file mode 100644 index 00000000000..ccad78bdef6 --- /dev/null +++ b/scripts/makefiles/e2e.mk @@ -0,0 +1,43 @@ +############################################################################### +### E2E ### +############################################################################### +e2e-help: + @echo "e2e subcommands" + @echo "" + @echo "Usage:" + @echo " make e2e-[command]" + @echo "" + @echo "Available Commands:" + @echo " build-script Build e2e script" + @echo " docker-build-debug Build e2e debug Docker image" + @echo " docker-build-e2e-init-chain Build e2e init chain Docker image" + @echo " docker-build-e2e-init-node Build e2e init node Docker image" + @echo " setup Set up e2e environment" + @echo " check-image-sha Check e2e image SHA" + @echo " remove-resources Remove e2e resources" +e2e: e2e-help + +e2e-build-script: + mkdir -p $(BUILDDIR) + go build -mod=readonly $(BUILD_FLAGS) -o $(BUILDDIR)/ ./tests/e2e/initialization/$(E2E_SCRIPT_NAME) + +e2e-docker-build-debug: + @DOCKER_BUILDKIT=1 docker build -t osmosis:${COMMIT} --build-arg BASE_IMG_TAG=debug --build-arg RUNNER_IMAGE=$(RUNNER_BASE_IMAGE_ALPINE) -f Dockerfile . + @DOCKER_BUILDKIT=1 docker tag osmosis:${COMMIT} osmosis:debug + +e2e-docker-build-e2e-init-chain: + @DOCKER_BUILDKIT=1 docker build -t osmolabs/osmosis-e2e-init-chain:debug --build-arg E2E_SCRIPT_NAME=chain --platform=linux/x86_64 -f tests/e2e/initialization/init.Dockerfile . + +e2e-docker-build-e2e-init-node: + @DOCKER_BUILDKIT=1 docker build -t osmosis-e2e-init-node:debug --build-arg E2E_SCRIPT_NAME=node --platform=linux/x86_64 -f tests/e2e/initialization/init.Dockerfile . + +e2e-setup: e2e-check-image-sha e2e-remove-resources + @echo Finished e2e environment setup, ready to start the test + +e2e-check-image-sha: + tests/e2e/scripts/run/check_image_sha.sh + +e2e-remove-resources: + tests/e2e/scripts/run/remove_stale_resources.sh + +.PHONY: test-mutation \ No newline at end of file diff --git a/scripts/makefiles/lint.mk b/scripts/makefiles/lint.mk new file mode 100644 index 00000000000..91ccf2102cb --- /dev/null +++ b/scripts/makefiles/lint.mk @@ -0,0 +1,32 @@ +############################################################################### +### Linting ### +############################################################################### +lint-help: + @echo "lint subcommands" + @echo "" + @echo "Usage:" + @echo " make lint-[command]" + @echo "" + @echo "Available Commands:" + @echo " all Run all linters" + @echo " format Run linters with auto-fix" + @echo " mdlint Run markdown linter" + @echo " markdown Run markdown linter with auto-fix" +lint: lint-help + +lint-all: + @echo "--> Running linter" + @go run github.com/golangci/golangci-lint/cmd/golangci-lint run --timeout=10m + @docker run -v $(PWD):/workdir ghcr.io/igorshubovych/markdownlint-cli:latest "**/*.md" + +lint-format: + @go run github.com/golangci/golangci-lint/cmd/golangci-lint run ./... --fix + @go run mvdan.cc/gofumpt -l -w x/ app/ ante/ tests/ + @docker run -v $(PWD):/workdir ghcr.io/igorshubovych/markdownlint-cli:latest "**/*.md" --fix + +lint-mdlint: + @echo "--> Running markdown linter" + @docker run -v $(PWD):/workdir ghcr.io/igorshubovych/markdownlint-cli:latest "**/*.md" + +lint-markdown: + @docker run -v $(PWD):/workdir ghcr.io/igorshubovych/markdownlint-cli:latest "**/*.md" --fix diff --git a/scripts/makefiles/localnet.mk b/scripts/makefiles/localnet.mk new file mode 100644 index 00000000000..2b507f45a55 --- /dev/null +++ b/scripts/makefiles/localnet.mk @@ -0,0 +1,154 @@ +############################################################################### +### Localnet ### +############################################################################### +# +# Please refer to https://github.com/osmosis-labs/osmosis/blob/main/tests/localosmosis/README.md for detailed +# usage of localnet. + +localnet-help: + @echo "localnet subcommands" + @echo "" + @echo "Usage:" + @echo " make localnet-[command]" + @echo "" + @echo "Available Commands:" + @echo " keys Add keys for localnet" + @echo " init Initialize localnet" + @echo " build Build localnet" + @echo " start Start localnet" + @echo " start-with-state Start localnet with state" + @echo " startd Start localnet in detached mode" + @echo " startd-with-state Start localnet in detached mode with state" + @echo " stop Stop localnet" + @echo " clean Clean localnet" + @echo " state-export-init Initialize localnet state export" + @echo " state-export-build Build localnet state export" + @echo " state-export-start Start localnet state export" + @echo " state-export-startd Start localnet state export in detached mode" + @echo " state-export-stop Stop localnet state export" + @echo " state-export-clean Clean localnet state export" + @echo " cl-create-positions Create concentrated liquidity positions" + @echo " cl-small-swap Perform small randomized swaps" + @echo " cl-large-swap Perform large swaps" + @echo " cl-external-incentive Create external incentive" + @echo " cl-create-pool Create concentrated liquidity pool" + @echo " cl-claim-spread-rewards Claim spread rewards" + @echo " cl-claim-incentives Claim incentives" + @echo " cl-add-to-positions Add to positions" + @echo " cl-withdraw-positions Withdraw positions" + @echo " cl-positions-small-swaps Create positions and perform small swaps" + @echo " cl-positions-large-swaps Create positions and perform large swaps" + @echo " cl-refresh-subgraph-positions Refresh subgraph positions" + @echo " cl-refresh-subgraph-genesis Refresh subgraph genesis" + @echo " cl-create-bigbang-config Create Big Bang configuration" +localnet: localnet-help + +localnet-keys: + . tests/localosmosis/scripts/add_keys.sh + +localnet-init: localnet-clean localnet-build + +localnet-build: + @DOCKER_BUILDKIT=1 COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f tests/localosmosis/docker-compose.yml build + +localnet-start: + @STATE="" docker-compose -f tests/localosmosis/docker-compose.yml up + +localnet-start-with-state: + @STATE=-s docker-compose -f tests/localosmosis/docker-compose.yml up + +localnet-startd: + @STATE="" docker-compose -f tests/localosmosis/docker-compose.yml up -d + +localnet-startd-with-state: + @STATE=-s docker-compose -f tests/localosmosis/docker-compose.yml up -d + +localnet-stop: + @STATE="" docker-compose -f tests/localosmosis/docker-compose.yml down + +localnet-clean: + @rm -rfI $(HOME)/.osmosisd-local/ + +localnet-state-export-init: localnet-state-export-clean localnet-state-export-build + +localnet-state-export-build: + @DOCKER_BUILDKIT=1 COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f tests/localosmosis/state_export/docker-compose.yml build + +localnet-state-export-start: + @docker-compose -f tests/localosmosis/state_export/docker-compose.yml up + +localnet-state-export-startd: + @docker-compose -f tests/localosmosis/state_export/docker-compose.yml up -d + +localnet-state-export-stop: + @docker-compose -f tests/localosmosis/docker-compose.yml down + +localnet-state-export-clean: localnet-clean + +# create 100 concentrated-liquidity positions in localosmosis at pool id 1 +localnet-cl-create-positions: + go run tests/cl-go-client/main.go --operation 0 + +# does 100 small randomized swaps in localosmosis at pool id 1 +localnet-cl-small-swap: + go run tests/cl-go-client/main.go --operation 1 + +# does 100 large swaps where the output of the previous swap is swapped back at the +# next swap. localosmosis at pool id 1 +localnet-cl-large-swap: + go run tests/cl-go-client/main.go --operation 2 + +# creates a gauge and waits for one epoch so that the gauge +# is converted into an incentive record for pool id 1. +localnet-cl-external-incentive: + go run tests/cl-go-client/main.go --operation 3 + +# attempts to create a CL pool at id 1. +# if pool already exists, this is a no-op. +# if pool with different id is desired, tweak expectedPoolId +# in the script. +localnet-cl-create-pool: + go run tests/cl-go-client/main.go --operation 4 + +# claims spread rewards for a random account for a random +# subset of positions. +localnet-cl-claim-spread-rewards: + go run tests/cl-go-client/main.go --operation 5 + +# claims incentives for a random account for a random +# subset of positions. +localnet-cl-claim-incentives: + go run tests/cl-go-client/main.go --operation 6 + +localnet-cl-add-to-positions: + go run tests/cl-go-client/main.go --operation 7 + +localnet-cl-withdraw-positions: + go run tests/cl-go-client/main.go --operation 8 + +# does both of localnet-cl-create-positions and localnet-cl-small-swap +localnet-cl-positions-small-swaps: localnet-cl-create-positions localnet-cl-small-swap + +# does both of localnet-cl-create-positions and localnet-cl-large-swap +localnet-cl-positions-large-swaps: localnet-cl-create-positions localnet-cl-large-swap + +# This script retrieves Uniswap v3 Ethereum position data +# from subgraph. It uses WETH / USDC pool. This is helpful +# for setting up somewhat realistic positions for testing +# in localosmosis. It writes the file under +# tests/cl-genesis-positions/subgraph_positions.json +localnet-cl-refresh-subgraph-positions: + go run ./tests/cl-genesis-positions --operation 0 + +# This script converts the positions data created by the +# cl-refresh-subgraph-positions makefile step into an Osmosis +# genesis. It writes the file under tests/cl-genesis-positions/genesis.json +localnet-cl-refresh-subgraph-genesis: + go run ./tests/cl-genesis-positions --operation 1 + +# This script converts the positions data created by the +# cl-refresh-subgraph-positions makefile step into a Big Bang +# configuration file for spinning up testnets. +# It writes the file under tests/cl-genesis-positions/bigbang_positions.json +localnet-cl-create-bigbang-config: + go run ./tests/cl-genesis-positions --operation 1 --big-bang diff --git a/scripts/makefiles/proto.mk b/scripts/makefiles/proto.mk new file mode 100644 index 00000000000..8514edb3281 --- /dev/null +++ b/scripts/makefiles/proto.mk @@ -0,0 +1,59 @@ +############################################################################### +### Proto ### +############################################################################### + +proto-help: + @echo "proto subcommands" + @echo "" + @echo "Usage:" + @echo " make proto-[command]" + @echo "" + @echo "Available Commands:" + @echo " all Run proto-format and proto-gen" + @echo " gen Generate Protobuf files" + @echo " format Format Protobuf files" + @echo " image-build Build the protobuf Docker image" + @echo " image-push Push the protobuf Docker image" + +proto: proto-help +proto-all: proto-format proto-gen + +protoVer=v0.9 +protoImageName=osmolabs/osmo-proto-gen:$(protoVer) +containerProtoGen=cosmos-sdk-proto-gen-$(protoVer) +containerProtoFmt=cosmos-sdk-proto-fmt-$(protoVer) + +proto-gen: + @echo "Generating Protobuf files" + @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoGen}$$"; then docker start -a $(containerProtoGen); else docker run --name $(containerProtoGen) -v $(CURDIR):/workspace --workdir /workspace $(protoImageName) \ + sh ./scripts/protocgen.sh; fi + +proto-format: + @echo "Formatting Protobuf files" + @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerProtoFmt}$$"; then docker start -a $(containerProtoFmt); else docker run --name $(containerProtoFmt) -v $(CURDIR):/workspace --workdir /workspace tendermintdev/docker-build-proto \ + find ./ -not -path "./third_party/*" -name "*.proto" -exec clang-format -i {} \; ; fi + +proto-image-build: + @DOCKER_BUILDKIT=1 docker build -t $(protoImageName) -f ./proto/Dockerfile ./proto + +proto-image-push: + docker push $(protoImageName) + + +docs: + @echo + @echo "=========== Generate Message ============" + @echo + ./scripts/generate-docs.sh + + statik -src=client/docs/static -dest=client/docs -f -m + @if [ -n "$(git status --porcelain)" ]; then \ + echo "\033[91mSwagger docs are out of sync!!!\033[0m";\ + exit 1;\ + else \ + echo "\033[92mSwagger docs are in sync\033[0m";\ + fi + @echo + @echo "=========== Generate Complete ============" + @echo +.PHONY: docs \ No newline at end of file diff --git a/scripts/makefiles/release.mk b/scripts/makefiles/release.mk new file mode 100644 index 00000000000..7f6004449d2 --- /dev/null +++ b/scripts/makefiles/release.mk @@ -0,0 +1,41 @@ +############################################################################### +### Release ### +############################################################################### +release-help: + @echo "release subcommands" + @echo "" + @echo "Usage:" + @echo " make release-[command]" + @echo "" + @echo "Available Commands:" + @echo " dry-run Perform a dry run release" + @echo " snapshot Create a snapshot release" + +GORELEASER_IMAGE := ghcr.io/goreleaser/goreleaser-cross:v$(GO_VERSION) +COSMWASM_VERSION := $(shell go list -m github.com/CosmWasm/wasmvm | sed 's/.* //') + +release-dry-run: + docker run \ + --rm \ + -e COSMWASM_VERSION=$(COSMWASM_VERSION) \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v `pwd`:/go/src/osmosisd \ + -w /go/src/osmosisd \ + $(GORELEASER_IMAGE) \ + release \ + --clean \ + --skip-publish + +release-snapshot: + docker run \ + --rm \ + -e COSMWASM_VERSION=$(COSMWASM_VERSION) \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v `pwd`:/go/src/osmosisd \ + -w /go/src/osmosisd \ + $(GORELEASER_IMAGE) \ + release \ + --clean \ + --snapshot \ + --skip-validate \ + --skip-publish \ No newline at end of file diff --git a/scripts/makefiles/tests.mk b/scripts/makefiles/tests.mk new file mode 100644 index 00000000000..6ce6afb9d05 --- /dev/null +++ b/scripts/makefiles/tests.mk @@ -0,0 +1,91 @@ +############################################################################### +### Tests ### +############################################################################### + +PACKAGES_UNIT=$(shell go list ./... ./osmomath/... ./osmoutils/... ./x/ibc-hooks/... ./x/epochs | grep -E -v 'tests/simulator|e2e') +PACKAGES_E2E := $(shell go list ./... | grep '/e2e' | awk -F'/e2e' '{print $$1 "/e2e"}' | uniq) +PACKAGES_SIM=$(shell go list ./... | grep '/tests/simulator') +TEST_PACKAGES=./... + +test-help: + @echo "test subcommands" + @echo "" + @echo "Usage:" + @echo " make test-[command]" + @echo "" + @echo "Available Commands:" + @echo " all Run all tests" + @echo " unit Run unit tests" + @echo " race Run race tests" + @echo " cover Run coverage tests" + @echo " sim-suite Run sim suite tests" + @echo " sim-app Run sim app tests" + @echo " sim-determinism Run sim determinism tests" + @echo " sim-bench Run sim benchmark tests" + @echo " e2e Run e2e tests" + @echo " e2e-ci Run e2e CI tests" + @echo " e2e-ci-scheduled Run e2e CI scheduled tests" + @echo " e2e-debug Run e2e debug tests" + @echo " e2e-short Run e2e short tests" + @echo " mutation Run mutation tests" + @echo " benchmark Run benchmark tests" + +test: test-help + +test-all: test-race test-covertest-unit test-build + +test-unit: + @VERSION=$(VERSION) SKIP_WASM_WSL_TESTS=$(SKIP_WASM_WSL_TESTS) go test -mod=readonly -tags='ledger test_ledger_mock norace' $(PACKAGES_UNIT) + +test-race: + @VERSION=$(VERSION) go test -mod=readonly -race -tags='ledger test_ledger_mock' $(PACKAGES_UNIT) + +test-cover: + @VERSION=$(VERSION) go test -mod=readonly -timeout 30m -coverprofile=coverage.txt -tags='norace' -covermode=atomic $(PACKAGES_UNIT) + +test-sim-suite: + @VERSION=$(VERSION) go test -mod=readonly $(PACKAGES_SIM) + +test-sim-app: + @VERSION=$(VERSION) go test -mod=readonly -run ^TestFullAppSimulation -v $(PACKAGES_SIM) + +test-sim-determinism: + @VERSION=$(VERSION) go test -mod=readonly -run ^TestAppStateDeterminism -v $(PACKAGES_SIM) + +test-sim-bench: + @VERSION=$(VERSION) go test -benchmem -run ^BenchmarkFullAppSimulation -bench ^BenchmarkFullAppSimulation -cpuprofile cpu.out $(PACKAGES_SIM) + +# test-e2e runs a full e2e test suite +# deletes any pre-existing Osmosis containers before running. +# +# Deletes Docker resources at the end. +# Utilizes Go cache. +test-e2e: e2e-setup test-e2e-ci e2e-remove-resources + +# test-e2e-ci runs a majority of e2e tests, only skipping the ones that are marked as scheduled tests +# does not do any validation about the state of the Docker environment +# As a result, avoid using this locally. +test-e2e-ci: + @VERSION=$(VERSION) OSMOSIS_E2E=True OSMOSIS_E2E_DEBUG_LOG=False OSMOSIS_E2E_UPGRADE_VERSION=$(E2E_UPGRADE_VERSION) go test -mod=readonly -timeout=25m -v $(PACKAGES_E2E) -p 4 + +# test-e2e-ci-scheduled runs every e2e test available, and is only run on a scheduled basis +test-e2e-ci-scheduled: + @VERSION=$(VERSION) OSMOSIS_E2E_SCHEDULED=True OSMOSIS_E2E=True OSMOSIS_E2E_DEBUG_LOG=False OSMOSIS_E2E_UPGRADE_VERSION=$(E2E_UPGRADE_VERSION) go test -mod=readonly -timeout=25m -v $(PACKAGES_E2E) -p 4 + +# test-e2e-debug runs a full e2e test suite but does +# not attempt to delete Docker resources at the end. +test-e2e-debug: e2e-setup + @VERSION=$(VERSION) OSMOSIS_E2E=True OSMOSIS_E2E_DEBUG_LOG=True OSMOSIS_E2E_UPGRADE_VERSION=$(E2E_UPGRADE_VERSION) OSMOSIS_E2E_SKIP_CLEANUP=True go test -mod=readonly -timeout=25m -v $(PACKAGES_E2E) -count=1 + +# test-e2e-short runs the e2e test with only short tests. +# Does not delete any of the containers after running. +# Deletes any existing containers before running. +# Does not use Go cache. +test-e2e-short: e2e-setup + @VERSION=$(VERSION) OSMOSIS_E2E=True OSMOSIS_E2E_DEBUG_LOG=True OSMOSIS_E2E_SKIP_UPGRADE=True OSMOSIS_E2E_SKIP_IBC=True OSMOSIS_E2E_SKIP_STATE_SYNC=True OSMOSIS_E2E_SKIP_CLEANUP=True go test -mod=readonly -timeout=25m -v $(PACKAGES_E2E) -count=1 + +test-mutation: + @bash scripts/mutation-test.sh $(MODULES) + +test-benchmark: + @go test -mod=readonly -bench=. $(PACKAGES_UNIT) diff --git a/tests/e2e/README.md b/tests/e2e/README.md index 08fd4615170..4d313b5650f 100644 --- a/tests/e2e/README.md +++ b/tests/e2e/README.md @@ -145,7 +145,7 @@ Please refer to `tests/e2e/initialization/README.md` ### To build the debug Osmosis image ```sh - make docker-build-debug + make e2e-docker-build-debug ``` ### Environment variables diff --git a/tests/e2e/containers/config.go b/tests/e2e/containers/config.go index ed1ea094bc2..f524283e13b 100644 --- a/tests/e2e/containers/config.go +++ b/tests/e2e/containers/config.go @@ -17,7 +17,7 @@ type ImageConfig struct { const ( // Current Git branch osmosis repo/version. It is meant to be built locally. // It is used when skipping upgrade by setting OSMOSIS_E2E_SKIP_UPGRADE to true). - // This image should be pre-built with `make docker-build-debug` either in CI or locally. + // This image should be pre-built with `make e2e-docker-build-debug` either in CI or locally. CurrentBranchOsmoRepository = "osmosis" CurrentBranchOsmoTag = "debug" // Pre-upgrade osmosis repo/tag to pull. diff --git a/tests/e2e/initialization/README.md b/tests/e2e/initialization/README.md index 5a94bdfcb67..f61f204cbf8 100644 --- a/tests/e2e/initialization/README.md +++ b/tests/e2e/initialization/README.md @@ -35,7 +35,7 @@ any of these local scripts From root folder: ```sh -make docker-build-e2e-init-chain +make e2e-docker-build-e2e-init-chain ``` This script will build a Docker image that runs a script in the `chain` package @@ -124,7 +124,7 @@ defined in `tests/e2e/initialization/chain.go` ### Initializing a Node (`node`) ```sh -make docker-build-e2e-init-node +make e2e-docker-build-e2e-init-node ``` This script will build a Docker image that runs a script in the `node` package diff --git a/tests/e2e/initialization/init.Dockerfile b/tests/e2e/initialization/init.Dockerfile index 16d7b7e4711..96b4fa96b61 100644 --- a/tests/e2e/initialization/init.Dockerfile +++ b/tests/e2e/initialization/init.Dockerfile @@ -24,7 +24,7 @@ RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep a00700aa19f5bfe0f46290ddf69bf # CosmWasm: copy the right library according to architecture. The final location will be found by the linker flag `-lwasmvm_muslc` RUN cp /lib/libwasmvm_muslc.$(uname -m).a /lib/libwasmvm_muslc.a -RUN BUILD_TAGS=muslc LINK_STATICALLY=true E2E_SCRIPT_NAME=${E2E_SCRIPT_NAME} make build-e2e-script +RUN BUILD_TAGS=muslc LINK_STATICALLY=true E2E_SCRIPT_NAME=${E2E_SCRIPT_NAME} make e2e-build-script ## Deploy image FROM ubuntu diff --git a/tests/e2e/scripts/run/check_image_sha.sh b/tests/e2e/scripts/run/check_image_sha.sh index a88e284e893..9fc309c9833 100755 --- a/tests/e2e/scripts/run/check_image_sha.sh +++ b/tests/e2e/scripts/run/check_image_sha.sh @@ -13,7 +13,7 @@ check_if_exists() { # check_if_exists returns 1 if an "osmosis" image is built from the same commit SHA # as the current commit, 0 otherwise. # It assummes that the "osmosis" image was specifically tagged with Git SHA at build -# time. Please see "docker-build-debug" Makefile step for details. +# time. Please see "e2e-docker-build-debug" Makefile step for details. check_if_up_to_date() { sha_from_image=$LIST_DOCKER_IMAGE_HASHES local_git_sha=$(git rev-parse HEAD) @@ -47,6 +47,6 @@ else fi # Rebuild the image -make docker-build-debug +make e2e-docker-build-debug check_if_up_to_date From 8670be6b0da7957a23573701f2420c526d299aed Mon Sep 17 00:00:00 2001 From: Niccolo Raspa <6024049+niccoloraspa@users.noreply.github.com> Date: Mon, 30 Oct 2023 10:06:11 +0100 Subject: [PATCH 18/25] Add SECURITY.md (#6773) * Add SECURITY.md * Fix typo * Update SECURITY.md * Update SECURITY.md * Update SECURITY.md * Update SECURITY.md moved warnings about accidental disclosure to the top --------- Co-authored-by: Nicolas Lara --- SECURITY.md | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000000..030254904b6 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,72 @@ +# Security Policy + +## Introduction + +Security researchers are essential in identifying vulnerabilities that may impact the Osmosis ecosystem. If you have discovered a security vulnerability in the Osmosis chain or any repository managed by Osmosis, we encourage you to notify us using one of the methods outlined below. + +### Guidelines for Responsible Vulnerability Testing and Reporting + +1. **Please refrain from testing the vulnerability on our publically accessible environments**, including but not limited to: + - Osmosis mainnet `osmosis-1` + - Osmosis frontend: `app.osmosis.zone` + - Osmosis public testnets + - Osmosis testnet frontend + +2. **Avoid reporting security vulnerabilities through public channels, including GitHub issues** + +## Reporting Security Issues + +To privately report a security vulnerability, please choose one of the following options: + +### 1. Email + +Send your detailed vulnerability report to `security@osmosis.team`. + +### 2. GitHub Private Vulnerability Reporting + +Utilize [GitHub's Private Vulnerability Reporting](https://github.com/osmosis-labs/osmosis/security/advisories/new) for confidential disclosure. + +## Submit Vulnerability Report + +When reporting a vulnerability through either method, please include the following details to aid in our assessment: + +- Type of vulnerability +- Description of the vulnerability +- Steps to reproduce the issue +- Impact of the issue +- Eplanation on how an attacker could exploit it + +## Vulnerability Disclosure Process + +1. **Initial Report**: Submit the vulnerability via one of the above channels. +2. **Confirmation**: We will confirm receipt of your report within 48 hours. +3. **Assessment**: Our security team will evaluate the vulnerability and inform you of its severity and the estimated time frame for resolution. +4. **Resolution**: Once fixed, you will be contacted to verify the solution. +5. **Public Disclosure**: Details of the vulnerability may be publicly disclosed after ensuring it poses no further risk. + +During the vulnerability disclosure process, we ask security researchers to keep vulnerabilities and communications around vulnerability submissions private and confidential until a patch is developed. Should a security issue require a network upgrade, additional time may be needed to raise a governance proposal and complete the upgrade. + +During this time: + +- Avoid exploiting any vulnerabilities you discover. +- Demonstrate good faith by not disrupting or degrading Osmosis's services. + +## Severity Characterization + +| Severity | Description | +|--------------|-------------------------------------------------------------------------| +| **CRITICAL** | Immediate threat to critical systems (e.g., chain halts, funds at risk) | +| **HIGH** | Significant impact on major functionality | +| **MEDIUM** | Impacts minor features or exposes non-sensitive data | +| **LOW** | Minimal impact | + +## Bug Bounty + +Though we don't have an official bug bounty program, we generally offer rewards to security researchers who responsibly disclose vulnerabilities to us. Bounties are generally awarded for vulnerabilities classified as **high** or **critical** severity. Bounty amounts will be determined during the disclosure process, after the severity has been assessed. + +> [!WARNING] +> Targeting our production environments will disqualify you from receiving any bounty. + +## Feedback on this Policy + +For recommendations on how to improve this policy, either submit a pull request or send an email to `security@osmosis.team`. From 29529af036c5fb9646481b64b595c960f923e708 Mon Sep 17 00:00:00 2001 From: Niccolo Raspa <6024049+niccoloraspa@users.noreply.github.com> Date: Mon, 30 Oct 2023 10:13:35 +0100 Subject: [PATCH 19/25] [typo] Update SECURITY.md (#6782) * Update SECURITY.md * Update SECURITY.md --- SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index 030254904b6..054e11bfd60 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -6,7 +6,7 @@ Security researchers are essential in identifying vulnerabilities that may impac ### Guidelines for Responsible Vulnerability Testing and Reporting -1. **Please refrain from testing the vulnerability on our publically accessible environments**, including but not limited to: +1. **Refrain from testing vulnerabilities on our publicly accessible environments**, including but not limited to: - Osmosis mainnet `osmosis-1` - Osmosis frontend: `app.osmosis.zone` - Osmosis public testnets From e7517c2ce4da2eb1f1932beed52d4c6e5be4043d Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 31 Oct 2023 12:31:56 -0400 Subject: [PATCH 20/25] fix: improve error message for slippage bound when LPing (#6788) * fix: improve error message for slippage bound when LPing * updates * changelog --- CHANGELOG.md | 4 ++++ x/concentrated-liquidity/types/errors.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db9cf5d3994..08acd78a1cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#6758](https://github.com/osmosis-labs/osmosis/pull/6758) Add codec for MsgUndelegateFromRebalancedValidatorSet +### Misc Improvements + +* [#6788](https://github.com/osmosis-labs/osmosis/pull/6788) Improve error message when CL LP fails due to slippage bound hit. + ## v20.0.0 ### Features diff --git a/x/concentrated-liquidity/types/errors.go b/x/concentrated-liquidity/types/errors.go index 440c73beff4..4828d40ccd0 100644 --- a/x/concentrated-liquidity/types/errors.go +++ b/x/concentrated-liquidity/types/errors.go @@ -136,7 +136,7 @@ func (e InsufficientLiquidityCreatedError) Error() string { if !e.IsTokenZero { tokenNum = 1 } - return fmt.Sprintf("insufficient amount of token %d created. Actual: (%s). Minimum (%s)", tokenNum, e.Actual, e.Minimum) + return fmt.Sprintf("slippage bound: insufficient amount of token %d created. Actual: (%s). Minimum estimated: (%s)", tokenNum, e.Actual, e.Minimum) } type NegativeLiquidityError struct { From c99369289deb6cc9bd8da81277164f95b1cd43c1 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Tue, 31 Oct 2023 18:20:07 +0100 Subject: [PATCH 21/25] Fix arb tx filter (#6791) * Fix arb tx filter * Didn't undo stash --- x/gamm/types/msg_swap.go | 8 ++--- x/poolmanager/types/msg_swap.go | 48 +++++++++++++++++++++++++ x/txfees/keeper/txfee_filters/arb_tx.go | 3 +- 3 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 x/poolmanager/types/msg_swap.go diff --git a/x/gamm/types/msg_swap.go b/x/gamm/types/msg_swap.go index 38d2090740a..a82fbd52df0 100644 --- a/x/gamm/types/msg_swap.go +++ b/x/gamm/types/msg_swap.go @@ -1,11 +1,9 @@ package types +import poolmanagertypes "github.com/osmosis-labs/osmosis/v20/x/poolmanager/types" + // SwapMsg defines a simple interface for getting the token denoms on a swap message route. -type SwapMsgRoute interface { - TokenInDenom() string - TokenOutDenom() string - TokenDenomsOnPath() []string -} +type SwapMsgRoute = poolmanagertypes.SwapMsgRoute var ( _ SwapMsgRoute = MsgSwapExactAmountOut{} diff --git a/x/poolmanager/types/msg_swap.go b/x/poolmanager/types/msg_swap.go new file mode 100644 index 00000000000..38d2090740a --- /dev/null +++ b/x/poolmanager/types/msg_swap.go @@ -0,0 +1,48 @@ +package types + +// SwapMsg defines a simple interface for getting the token denoms on a swap message route. +type SwapMsgRoute interface { + TokenInDenom() string + TokenOutDenom() string + TokenDenomsOnPath() []string +} + +var ( + _ SwapMsgRoute = MsgSwapExactAmountOut{} + _ SwapMsgRoute = MsgSwapExactAmountIn{} +) + +func (msg MsgSwapExactAmountOut) TokenInDenom() string { + return msg.Routes[0].GetTokenInDenom() +} + +func (msg MsgSwapExactAmountOut) TokenOutDenom() string { + return msg.TokenOut.Denom +} + +func (msg MsgSwapExactAmountOut) TokenDenomsOnPath() []string { + denoms := make([]string, 0, len(msg.Routes)+1) + for i := 0; i < len(msg.Routes); i++ { + denoms = append(denoms, msg.Routes[i].TokenInDenom) + } + denoms = append(denoms, msg.TokenOutDenom()) + return denoms +} + +func (msg MsgSwapExactAmountIn) TokenInDenom() string { + return msg.TokenIn.Denom +} + +func (msg MsgSwapExactAmountIn) TokenOutDenom() string { + lastRouteIndex := len(msg.Routes) - 1 + return msg.Routes[lastRouteIndex].GetTokenOutDenom() +} + +func (msg MsgSwapExactAmountIn) TokenDenomsOnPath() []string { + denoms := make([]string, 0, len(msg.Routes)+1) + denoms = append(denoms, msg.TokenInDenom()) + for i := 0; i < len(msg.Routes); i++ { + denoms = append(denoms, msg.Routes[i].TokenOutDenom) + } + return denoms +} diff --git a/x/txfees/keeper/txfee_filters/arb_tx.go b/x/txfees/keeper/txfee_filters/arb_tx.go index f02856542bc..1d1c8e7e17a 100644 --- a/x/txfees/keeper/txfee_filters/arb_tx.go +++ b/x/txfees/keeper/txfee_filters/arb_tx.go @@ -2,6 +2,7 @@ package txfee_filters import ( gammtypes "github.com/osmosis-labs/osmosis/v20/x/gamm/types" + poolmanagertypes "github.com/osmosis-labs/osmosis/v20/x/poolmanager/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -33,7 +34,7 @@ func IsArbTxLoose(tx sdk.Tx) bool { } } - swapMsg, isSwapMsg := m.(gammtypes.SwapMsgRoute) + swapMsg, isSwapMsg := m.(poolmanagertypes.SwapMsgRoute) if !isSwapMsg { continue } From c22964d5c107c4c69282a1f6abcba19da3bdcfe2 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 31 Oct 2023 16:17:17 -0400 Subject: [PATCH 22/25] fix: LP error message improvements when zero liquidity (#6794) Closes: #XXX ## What is the purpose of the change Smarter error message when LP ranges get out of range near bounds due to significant price movements. Prompted by the TIA launch --- x/concentrated-liquidity/lp.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/x/concentrated-liquidity/lp.go b/x/concentrated-liquidity/lp.go index 5284fdfed41..42525f3e823 100644 --- a/x/concentrated-liquidity/lp.go +++ b/x/concentrated-liquidity/lp.go @@ -2,6 +2,7 @@ package concentrated_liquidity import ( "errors" + "fmt" "strconv" "time" @@ -107,7 +108,23 @@ func (k Keeper) CreatePosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddr // Calculate the amount of liquidity that will be added to the pool when this position is created. liquidityDelta := math.GetLiquidityFromAmounts(pool.GetCurrentSqrtPrice(), sqrtPriceLowerTick, sqrtPriceUpperTick, amount0Desired, amount1Desired) if liquidityDelta.IsZero() { - return CreatePositionData{}, errors.New("liquidityDelta calculated equals zero") + // Note that it is impossible to reach the case with both tokens being zero because that case is handled above. + + if !amount0Desired.IsZero() && !amount1Desired.IsZero() { + return CreatePositionData{}, fmt.Errorf(`failed to translate amount0 (%d) and amount1 (%d) to positive liquidity. Possible reasons could be: + Not providing enough liquidity in both tokens + The desired tick range becoming inactive. If range becomes inactive before getting on chain, more of one token will be required as opposed to two tokens of the original amount`, amount0Desired, amount1Desired) + } else if amount0Desired.IsZero() { + return CreatePositionData{}, fmt.Errorf(`failed to translate amount1 (%d) to positive liquidity. Possible reasons could be: + Not providing enough liquidity in token 1. + The given tick range becoming activated after being inactive. If the given range becomes activated, two tokens will be needed as opposed to one.`, amount1Desired) + } + + // amount1Desired is zero + + return CreatePositionData{}, fmt.Errorf(`failed to translate amount0 (%d) to positive liquidity. Possible reasons could be: + Not providing enough liquidity in token 0. + The given tick range becoming activated after being inactive. If the given range becomes activated, two tokens will be needed as opposed to one.`, amount0Desired) } // Initialize / update the position in the pool based on the provided tick range and liquidity delta. From 18a495f9ba87a31a3c62fd6d69977dee307192b5 Mon Sep 17 00:00:00 2001 From: Adam Tucker Date: Tue, 31 Oct 2023 16:28:13 -0600 Subject: [PATCH 23/25] add taker fee docs (#6796) --- x/poolmanager/README.md | 76 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/x/poolmanager/README.md b/x/poolmanager/README.md index b48777b489c..20e99ead568 100644 --- a/x/poolmanager/README.md +++ b/x/poolmanager/README.md @@ -463,3 +463,79 @@ Here is the following process for the `estimateTradeBasedOnPriceImpactConcentrat 9. If a viable trade amount is found, the function performs a final estimation of `tokenOut` considering the swap fee and returns the estimated trade. +## Take Fee + +Taker fee distribution is defined in the poolmanager module’s param store: + +```proto +type TakerFeeParams struct { + DefaultTakerFee cosmossdk_io_math.LegacyDec `protobuf:"bytes,1,opt,name=default_taker_fee,json=defaultTakerFee,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"default_taker_fee"` + + OsmoTakerFeeDistribution TakerFeeDistributionPercentage `protobuf:"bytes,2,opt,name=osmo_taker_fee_distribution,json=osmoTakerFeeDistribution,proto3" json:"osmo_taker_fee_distribution"` + + NonOsmoTakerFeeDistribution TakerFeeDistributionPercentage `protobuf:"bytes,3,opt,name=non_osmo_taker_fee_distribution,json=nonOsmoTakerFeeDistribution,proto3" json:"non_osmo_taker_fee_distribution"` + + CommunityPoolDenomToSwapNonWhitelistedAssetsTo string `protobuf:"bytes,5,opt,name=community_pool_denom_to_swap_non_whitelisted_assets_to,json=communityPoolDenomToSwapNonWhitelistedAssetsTo,proto3" json:"community_pool_denom_to_swap_non_whitelisted_assets_to,omitempty" yaml:"community_pool_denom_to_swap_non_whitelisted_assets_to"` +} +``` + +Not shown here is a separate KVStore, which holds overrides for the defaultTakerFee. + +There are also two module accounts involved: + +```proto +non_native_fee_collector: osmo1g7ajkk295vactngp74shkfrprvjrdwn662dg26 +non_native_fee_collector_community_pool: osmo1f3xhl0gqmyhnu49c8k3j7fkdv75ug0xjtaqu09 +``` + +Lets go through the lifecycle to better understand how taker fee works in a variety of situations, and how each of these parameters and module accounts are used. + +### Example 1: Non OSMO taker fee + +A user makes a swap of USDC to OSMO. First, the protocol checks the KVStore to determine if the the denom pair has a taker fee override. If the pair exists in the KVStore, the taker fee override is used. If the pair does not exist, the defaultTakerFee is used. + +In this example, defaultTakerFee is 0.02%. A USDC<>OSMO KVStore exists with an override of 0.01%. Therefore, 0.01% is used. + +Now, imagine the amount in is 1000 USDC. This means that the amount of takerFee utilized is 0.01% of 1000, which is 1 USDC. + +In the takerFee params, there are two distribution categories: +1. Taker fees generated in OSMO +2. Taker fees generated in non-OSMO + +Since USDC is non-OSMO, we look at category 2. In both categories, the fees are distributed to a combo of staking rewards and community pool: + +```proto +type TakerFeeDistributionPercentage struct { + StakingRewards cosmossdk_io_math.LegacyDec `protobuf:"bytes,1,opt,name=staking_rewards,json=stakingRewards,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"staking_rewards" yaml:"staking_rewards"` + CommunityPool cosmossdk_io_math.LegacyDec `protobuf:"bytes,2,opt,name=community_pool,json=communityPool,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"community_pool" yaml:"community_pool"` +} +``` + +For simplicity sake, let’s say staking rewards is 40% and community pool is 60%. This means that out of the 1 USDC taken, 0.4 USDC is meant for staking rewards and 0.6 USDC is meant for community pool. + +Starting with the community pool funds, the protocol checks if the fee is a whitelisted fee token. If it is, it is sent directly to the community pool. If it is not, it is sent to the `non_native_fee_collector_community_pool` module address. At epoch, the funds in this account are swapped to the `CommunityPoolDenomToSwapNonWhitelistedAssetsTo` defined in the `poolmanger` params above, and then sent all at once to the community pool at that time. + +Next, for staking rewards, since this is a non-OSMO token, it is sent directly to the `non_native_fee_collector`. At epoch, all funds in this module account are swapped to OSMO and distributed directly to OSMO stakers. + +### Example 2: OSMO taker fee + +This example does not differ much from the previous example. In this example, a user is swapping 1000 OSMO for USDC. + +Just as before, we search for a KVStore taker fee override before utilizing the default taker fee. Just as before (order does not matter), a KVStore entry for OSMO<>USDC exists, so we utilize a 0.01% taker fee instead of the 0.02% default taker fee. 0.01% of 1000 OSMO is 1 OSMO. + +We now check the `OsmoTakerFeeDistribution`. In this example, let’s say its 20% to community pool and 80% to stakers. This means that 0.2 OSMO is set for community pool and 0.8 is set for stakers. + +For community pool, this is just a direct send to community pool. + +For staking, we actually ALSO send this to the `non_native_fee_collector`. At epoch time, this OSMO is just skipped over, while everything else is swapped to OSMO. At the very end, it takes the OSMO directly sent to the `non_native_fee_collector` along with the non native tokens that were just swapped to OSMO and distributes it to stakers. + +### Important Note: How to extract the data + +If one were to take the total amount of tokens in the two module accounts (`non_native_fee_collector` and `non_native_fee_collector_community_pool`), this would be slightly over exaggerating the amount that is generated from taker fees. This is because, when a user uses a non-native token as a FEE TOKEN, this is also sent to the `non_native_fee_collector`. So there are two options here to extract the info: + +1. Track the delta of the module accounts 1 block after epoch X and 1 block before epoch X+1. Also, track the total non osmo txfees generated in this period. Subtract the total non osmo txfees generated in this period from the delta of the `non_native_fee_collector`. Add this to the delta of `non_native_fee_collector_community_pool` values. This is the taker fees generated +2. This is the less better way, but you can track the `SendCoinsFromAccountToModule` events from each block. The problem with this is, imagine I swap USDC to OSMO and use USDC as txfee. This would generate three `SendCoinsFromAccountToModule` events: + 1. Txfee gets sent to `non_native_fee_collector` + 2. Part of taker fee gets sent to `non_native_fee_collector` + 3. Other part of taker fee gets sent to `non_native_fee_collector_community_pool` + You could make an assumption here that the txfee is going to be the smaller of the two that gets sent to the `non_native_fee_collector`, or better the order of operations is going to always be the same, so you can figure out if the first or second send to `non_native_fee_collector` is the txfee and not track that value \ No newline at end of file From 0c6c4db25ddb8b9f2e401c1d4fdac727df85c793 Mon Sep 17 00:00:00 2001 From: Zijing Zhang <50045289+pluveto@users.noreply.github.com> Date: Wed, 1 Nov 2023 18:46:29 +0800 Subject: [PATCH 24/25] ci: fix missing target `check_version` and add eof blank line (#6797) * ci: fix missing target `check_version` * fix: incorrect name --- Makefile | 4 ++-- scripts/makefiles/build.mk | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 68287a7236c..e44e245777f 100644 --- a/Makefile +++ b/Makefile @@ -140,11 +140,11 @@ endif ### Build & Install ### ############################################################################### -build: check_version go.sum +build: build-check-version go.sum mkdir -p $(BUILDDIR)/ GOWORK=off go build -mod=readonly $(BUILD_FLAGS) -o $(BUILDDIR)/ $(GO_MODULE)/cmd/osmosisd -install: check_version go.sum +install: build-check-version go.sum GOWORK=off go install -mod=readonly $(BUILD_FLAGS) $(GO_MODULE)/cmd/osmosisd ############################################################################### diff --git a/scripts/makefiles/build.mk b/scripts/makefiles/build.mk index dc7d836c306..386201b1a64 100644 --- a/scripts/makefiles/build.mk +++ b/scripts/makefiles/build.mk @@ -33,7 +33,7 @@ build-check-version: exit 1; \ fi -build-all: check_version go.sum +build-all: build-check-version go.sum mkdir -p $(BUILDDIR)/ GOWORK=off go build -mod=readonly $(BUILD_FLAGS) -o $(BUILDDIR)/ ./... @@ -50,7 +50,7 @@ build-dev-build: mkdir -p $(BUILDDIR)/ GOWORK=off go build $(GC_FLAGS) -mod=readonly -ldflags '$(DEBUG_LDFLAGS)' -trimpath -o $(BUILDDIR) ./...; -build-install-with-autocomplete: check_version go.sum +build-install-with-autocomplete: build-check-version go.sum GOWORK=off go install -mod=readonly $(BUILD_FLAGS) $(GO_MODULE)/cmd/osmosisd @PARENT_SHELL=$$(ps -o ppid= -p $$PPID | xargs ps -o comm= -p); \ if echo "$$PARENT_SHELL" | grep -q "zsh"; then \ @@ -136,4 +136,4 @@ build-linux: go.sum build-contract-tests-hooks: mkdir -p $(BUILDDIR) - go build -mod=readonly $(BUILD_FLAGS) -o $(BUILDDIR)/ ./cmd/contract_tests \ No newline at end of file + go build -mod=readonly $(BUILD_FLAGS) -o $(BUILDDIR)/ ./cmd/contract_tests From cdf8679bab3b0c9f35c66a5ff9fdee8561014273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90=C3=B4ng=20Li=E1=BB=81u?= <93205232+DongLieu@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:51:07 +0700 Subject: [PATCH 25/25] Delete unnecessary fields in 'estimate-trade-based-on-price-impact' cli usage (#6774) --- x/poolmanager/client/cli/query.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/poolmanager/client/cli/query.go b/x/poolmanager/client/cli/query.go index 47232192c45..81c1a584313 100644 --- a/x/poolmanager/client/cli/query.go +++ b/x/poolmanager/client/cli/query.go @@ -195,7 +195,7 @@ func GetCmdEstimateTradeBasedOnPriceImpact() ( *osmocli.QueryDescriptor, *queryproto.EstimateTradeBasedOnPriceImpactRequest, ) { return &osmocli.QueryDescriptor{ - Use: "estimate-trade-based-on-price-impact ", + Use: "estimate-trade-based-on-price-impact", Short: "Query estimate-trade-based-on-price-impact", Long: `{{.Short}} {{.CommandPrefix}} estimate-trade-based-on-price-impact 100uosmo stosmo 833 0.001 1.00`,