From 24ef87f27ac0ff3482f5a0d50508b2ea2b991dcf Mon Sep 17 00:00:00 2001 From: Artur Troian Date: Sat, 25 Oct 2025 20:54:19 -0500 Subject: [PATCH] feat!: cosmos-sdk v0.53.x Signed-off-by: Artur Troian --- .env | 1 + .envrc | 84 +- .github/.repo | 1 + .github/actions/setup-ubuntu/action.yaml | 38 + .github/workflows/concommits.yaml | 2 +- .github/workflows/release.yaml | 44 +- .github/workflows/tests.yaml | 188 +- .golangci.yaml | 56 +- .goreleaser-docker.yaml | 4 +- .goreleaser-test-bins.yaml | 2 +- .goreleaser.yaml | 32 +- .mockery.yaml | 19 +- CHANGELOG.md | 2 +- Makefile | 6 +- README.md | 2 +- _build/single-node.sh | 6 +- _docs/adr/adr-001-network-upgrades.md | 6 +- app/ante.go | 36 +- app/app.go | 749 ++-- app/app_configure.go | 329 +- app/app_test.go | 42 - app/config.go | 128 +- app/decorators/gov_filter.go | 92 - app/decorators/min_commision.go | 107 - app/export.go | 238 +- app/genesis.go | 140 +- app/mac.go | 13 +- app/modules.go | 325 ++ app/option.go | 52 + app/params/proto.go | 23 - app/sim/sim_config.go | 76 + app/sim/sim_utils.go | 110 + app/sim_test.go | 404 ++- app/testnet.go | 226 +- app/types/app.go | 547 ++- app/types/app_test.go | 2 +- app/upgrades.go | 39 +- client/client.go | 71 - client/utils.go | 9 +- cmd/akash/cmd/app_creator.go | 145 +- cmd/akash/cmd/auth.go | 4 +- cmd/akash/cmd/bech32.go | 2 +- cmd/akash/cmd/flag_test.go | 202 -- cmd/akash/cmd/genaccounts.go | 25 +- cmd/akash/cmd/genesis.go | 274 ++ cmd/akash/cmd/root.go | 253 +- cmd/akash/cmd/testnet.go | 412 +++ cmd/akash/cmd/testnetify/cmt_abci.go | 73 + cmd/akash/cmd/testnetify/config.go | 15 +- cmd/akash/cmd/testnetify/testnetify.go | 204 +- cmd/akash/cmd/testnetify/utils.go | 25 +- cmd/akash/main.go | 13 +- cmd/common/flags.go | 97 - cmd/common/signal.go | 42 - cmd/common/util.go | 28 - cmd/common/util_test.go | 34 - docgen/main.go | 2 +- events/cmd/root.go | 88 - events/publish.go | 183 - events/publish_test.go | 50 - events/query.go | 23 - go.mod | 359 +- go.sum | 3167 +++++++++++++---- install.sh | 5 - make/codegen.mk | 3 + make/init.mk | 44 +- make/lint.mk | 32 +- make/mod.mk | 6 + make/releasing.mk | 26 +- make/setup-cache.mk | 8 +- make/test-integration.mk | 14 +- make/test-simulation.mk | 8 +- make/test-upgrade.mk | 47 +- meta.json | 5 + pubsub/bus_test.go | 4 +- script/shellcheck.sh | 0 script/tools.sh | 252 +- script/upgrades.sh | 435 ++- sdl/_testdata/deployment-svc-mismatch.yaml | 45 - sdl/_testdata/private_service.yaml | 64 - sdl/_testdata/profile-svc-name-mismatch.yaml | 38 - sdl/_testdata/service-mix.yaml | 80 - sdl/_testdata/service-mix2.yaml | 69 - sdl/_testdata/simple-double-ram.yaml | 45 - sdl/_testdata/simple-gpu.yaml | 52 - sdl/_testdata/simple-with-ip.yaml | 50 - sdl/_testdata/simple.yaml | 45 - sdl/_testdata/simple2.yaml | 64 - sdl/_testdata/simple3.yaml | 45 - sdl/_testdata/simple4.yaml | 90 - sdl/_testdata/storageClass1.yaml | 52 - sdl/_testdata/storageClass2.yaml | 53 - sdl/_testdata/storageClass3.yaml | 52 - sdl/_testdata/storageClass4.yaml | 59 - sdl/_testdata/storageClass5.yaml | 51 - sdl/_testdata/storageClass6.yaml | 53 - sdl/_testdata/v2.1-credentials-error.yaml | 48 - sdl/_testdata/v2.1-credentials.yaml | 49 - .../v2.1-deployment-svc-mismatch.yaml | 45 - sdl/_testdata/v2.1-private_service.yaml | 64 - .../v2.1-profile-svc-name-mismatch.yaml | 38 - sdl/_testdata/v2.1-service-mix.yaml | 80 - sdl/_testdata/v2.1-service-mix2.yaml | 69 - sdl/_testdata/v2.1-simple-gpu.yaml | 52 - sdl/_testdata/v2.1-simple-with-ip.yaml | 50 - sdl/_testdata/v2.1-simple.yaml | 45 - sdl/_testdata/v2.1-simple2.yaml | 64 - sdl/_testdata/v2.1-simple3.yaml | 45 - sdl/_testdata/v2.1-simple4.yaml | 90 - sdl/coin.go | 53 - sdl/coin_test.go | 43 - sdl/cpu.go | 47 - sdl/cpu_test.go | 24 - sdl/expose.go | 114 - sdl/full_test.go | 66 - sdl/gpu.go | 131 - sdl/gpu_test.go | 190 - sdl/groupBuilder_v2.go | 149 - sdl/groupBuilder_v2_1.go | 160 - sdl/memory.go | 42 - sdl/placement.go | 37 - sdl/pricing.go | 4 - sdl/resources.go | 59 - sdl/sdl.go | 159 - sdl/sdl_test.go | 59 - sdl/storage.go | 251 -- sdl/storage_test.go | 229 -- sdl/units.go | 154 - sdl/units_test.go | 99 - sdl/util/util.go | 31 - sdl/util/util_test.go | 31 - sdl/utils.go | 17 - sdl/v2.go | 582 --- sdl/v2_1.go | 364 -- sdl/v2_1_ip_test.go | 279 -- sdl/v2_1_test.go | 760 ---- sdl/v2_ip_test.go | 297 -- sdl/v2_test.go | 940 ----- tests/e2e/certs_cli_test.go | 257 ++ tests/e2e/certs_grpc_test.go | 114 + tests/e2e/cli_test.go | 33 + tests/e2e/deployment_cli_test.go | 542 +++ tests/e2e/deployment_grpc_test.go | 286 ++ tests/e2e/grpc_test.go | 30 + tests/e2e/market_cli_test.go | 502 +++ tests/e2e/market_grpc_test.go | 632 ++++ tests/e2e/provider_cli_test.go | 107 + tests/e2e/provider_grpc_test.go | 163 + tests/upgrade/config.json | 36 + tests/upgrade/test-cases.json | 166 +- tests/upgrade/test-config-gha.json | 10 + tests/upgrade/test-config.json | 3 +- tests/upgrade/testnet.json | 53 +- tests/upgrade/types/types.go | 2 +- tests/upgrade/upgrade_test.go | 84 +- tests/upgrade/v0.26.0/postupgrade.go | 176 - tests/upgrade/v0.32.0/postupgrade.go | 118 - tests/upgrade/v0.34.0/postupgrade.go | 346 -- tests/upgrade/v0.36.0/postupgrade.go | 239 -- tests/upgrade/workers_test.go | 142 +- testutil/audit.go | 22 - testutil/base.go | 119 - testutil/cert.go | 213 -- testutil/channel_wait.go | 71 - testutil/cli/cmd.go | 67 - testutil/cosmos/keepers.go | 28 +- testutil/cosmos/mocks/AuthzKeeper_mock.go | 372 ++ testutil/cosmos/mocks/BankKeeper_mock.go | 368 ++ .../{take_keeper.go => TakeKeeper_mock.go} | 80 +- testutil/cosmos/mocks/authz_keeper.go | 200 -- testutil/cosmos/mocks/bank_keeper.go | 182 - testutil/cosmos/mocks/distr_keeper.go | 118 - testutil/deployment.go | 61 - testutil/event.go | 60 - testutil/ids.go | 102 - testutil/log.go | 27 - testutil/network/network.go | 345 +- testutil/network/option.go | 22 + testutil/network/util.go | 157 +- testutil/network_suite.go | 176 +- testutil/provider.go | 21 - testutil/rand.go | 12 - testutil/sdk.go | 43 - testutil/sims/address_helpers.go | 170 + testutil/sims/app_helpers.go | 306 ++ testutil/sims/expected_keepers.go | 19 + testutil/sims/simulation_helpers.go | 246 ++ testutil/sims/simulation_helpers_test.go | 124 + testutil/sims/state_helpers.go | 292 ++ testutil/sims/tx_helpers.go | 157 + testutil/state/suite.go | 132 +- testutil/types.go | 197 +- tools/upgrade-info/main.go | 2 +- types/config.go | 5 - upgrades/CHANGELOG.md | 27 +- upgrades/software/v0.15.0/audit.go | 34 - upgrades/software/v0.15.0/cert.go | 34 - upgrades/software/v0.15.0/deployment.go | 48 - upgrades/software/v0.15.0/escrow.go | 84 - upgrades/software/v0.15.0/helpers.go | 41 - upgrades/software/v0.15.0/init.go | 25 - upgrades/software/v0.15.0/market.go | 183 - .../v0.15.0/proto_compatibility_test.go | 290 -- upgrades/software/v0.15.0/provider.go | 46 - upgrades/software/v0.15.0/upgrade.go | 93 - upgrades/software/v0.18.0/init.go | 11 - upgrades/software/v0.18.0/upgrade.go | 79 - upgrades/software/v0.20.0/init.go | 11 - upgrades/software/v0.20.0/upgrade.go | 58 - upgrades/software/v0.24.0/deployment.go | 48 - upgrades/software/v0.24.0/init.go | 17 - upgrades/software/v0.24.0/market.go | 59 - upgrades/software/v0.24.0/upgrade.go | 220 -- upgrades/software/v0.26.0/init.go | 11 - upgrades/software/v0.26.0/upgrade.go | 206 -- upgrades/software/v0.28.0/init.go | 14 - upgrades/software/v0.28.0/market.go | 48 - upgrades/software/v0.28.0/upgrade.go | 47 - upgrades/software/v0.30.0/init.go | 11 - upgrades/software/v0.30.0/upgrade.go | 47 - upgrades/software/v0.32.0/init.go | 14 - upgrades/software/v0.32.0/market.go | 39 - upgrades/software/v0.32.0/upgrade.go | 47 - upgrades/software/v0.34.0/init.go | 11 - upgrades/software/v0.34.0/upgrade.go | 47 - upgrades/software/v0.36.0/init.go | 11 - upgrades/software/v0.36.0/upgrade.go | 47 - upgrades/software/v0.38.0/authz.go | 42 - upgrades/software/v0.38.0/cert.go | 68 - upgrades/software/v0.38.0/deployment.go | 130 - upgrades/software/v0.38.0/init.go | 21 - upgrades/software/v0.38.0/upgrade.go | 47 - upgrades/software/v1.0.0/audit.go | 56 + upgrades/software/v1.0.0/cert.go | 54 + upgrades/software/v1.0.0/deployment.go | 123 + upgrades/software/v1.0.0/escrow.go | 120 + upgrades/software/v1.0.0/init.go | 27 + .../software/{v0.38.0 => v1.0.0}/market.go | 110 +- upgrades/software/v1.0.0/provider.go | 65 + upgrades/software/v1.0.0/take.go | 27 + upgrades/software/v1.0.0/upgrade.go | 346 ++ upgrades/types/helpers.go | 18 +- upgrades/types/types.go | 35 +- upgrades/upgrades.go | 2 +- upgrades/upgrades_test.go | 2 +- util/cli/configs.go | 217 +- util/cli/upgrade_info.go | 12 +- util/metrics/metrics.go | 2 +- util/partialord/internal/dag/dag.go | 316 ++ util/partialord/internal/dag/dag_test.go | 158 + util/partialord/internal/dag/module.go | 9 + util/partialord/module.go | 2 + util/partialord/partialord.go | 97 + util/partialord/partialord_test.go | 74 + util/query/pagination.go | 8 +- util/server/server.go | 126 +- util/server/utils.go | 38 + util/wsutil/wsutil.go | 3 +- util/wsutil/wsutil_test.go | 5 +- x/audit/alias.go | 4 +- x/audit/client/cli/cli_test.go | 1 - x/audit/client/cli/query.go | 129 - x/audit/client/cli/tx.go | 252 -- x/audit/client/rest/rest.go | 87 - x/audit/genesis.go | 50 +- x/audit/handler/handler.go | 15 +- x/audit/handler/handler_test.go | 42 +- x/audit/handler/msg_server.go | 4 +- x/audit/keeper/grpc_query.go | 21 +- x/audit/keeper/grpc_query_test.go | 19 +- x/audit/keeper/keeper.go | 155 +- x/audit/keeper/keeper_test.go | 44 +- x/audit/keeper/key.go | 39 +- x/audit/module.go | 129 +- x/audit/query/rawclient.go | 2 +- x/cert/alias.go | 4 +- x/cert/client/cli/errors.go | 9 - x/cert/client/cli/grpc_rest_test.go | 138 - x/cert/client/cli/query.go | 111 - x/cert/client/cli/test_helpers.go | 89 - x/cert/client/cli/tx.go | 250 -- x/cert/client/cli/tx_cmd.go | 255 -- x/cert/client/cli/tx_test.go | 135 - x/cert/genesis.go | 9 +- x/cert/handler/handler.go | 13 +- x/cert/handler/handler_test.go | 81 +- x/cert/handler/msg_server.go | 4 +- x/cert/keeper/grpc_query.go | 16 +- x/cert/keeper/grpc_query_test.go | 26 +- x/cert/keeper/keeper.go | 31 +- x/cert/keeper/keeper_test.go | 45 +- x/cert/keeper/key.go | 52 +- x/cert/keeper/key_test.go | 14 +- x/cert/module.go | 135 +- x/cert/simulation/genesis.go | 2 +- x/cert/utils/constants.go | 2 + x/cert/utils/key_pair_manager.go | 12 +- x/cert/utils/utils.go | 4 +- x/deployment/alias.go | 4 +- x/deployment/client/cli/cli_test.go | 463 --- x/deployment/client/cli/flags.go | 212 -- x/deployment/client/cli/grpc_rest_test.go | 301 -- x/deployment/client/cli/query.go | 174 - x/deployment/client/cli/test_helpers.go | 136 - x/deployment/client/cli/tx.go | 678 ---- x/deployment/client/cli/util.go | 20 - x/deployment/client/rest/params.go | 95 - x/deployment/client/rest/rest.go | 80 - x/deployment/genesis.go | 52 +- x/deployment/handler/handler.go | 31 +- x/deployment/handler/handler_test.go | 493 +-- x/deployment/handler/keepers.go | 35 +- x/deployment/handler/mocks/authz_keeper.go | 200 -- x/deployment/handler/server.go | 200 +- x/deployment/keeper/external.go | 5 +- x/deployment/keeper/grpc_query.go | 58 +- x/deployment/keeper/grpc_query_test.go | 206 +- x/deployment/keeper/keeper.go | 262 +- x/deployment/keeper/keeper_test.go | 78 +- x/deployment/keeper/key.go | 58 +- x/deployment/module.go | 176 +- x/deployment/query/client.go | 2 +- x/deployment/query/path.go | 2 +- x/deployment/query/rawclient.go | 2 +- x/deployment/query/types.go | 22 +- x/deployment/simulation/genesis.go | 25 +- x/deployment/simulation/operations.go | 200 +- x/deployment/simulation/proposals.go | 57 + x/escrow/alias.go | 6 +- x/escrow/client/cli/query.go | 142 - x/escrow/client/cli/tx.go | 7 - x/escrow/client/rest/rest.go | 2 +- x/escrow/client/util/util.go | 8 +- x/escrow/genesis.go | 59 +- x/escrow/handler/handler.go | 25 + x/escrow/handler/keepers.go | 21 + x/escrow/handler/server.go | 43 + x/escrow/keeper/external.go | 24 +- x/escrow/keeper/grpc_query.go | 264 ++ x/escrow/keeper/grpc_query_test.go | 299 ++ x/escrow/keeper/keeper.go | 1116 +++--- x/escrow/keeper/keeper_settle_test.go | 224 +- x/escrow/keeper/keeper_test.go | 191 +- x/escrow/keeper/key.go | 183 +- x/escrow/keeper/querier.go | 4 +- x/escrow/module.go | 185 +- x/escrow/query/querier.go | 20 +- x/gov/alias.go | 24 - x/gov/genesis.go | 54 - x/gov/keeper/keeper.go | 60 - x/gov/module.go | 195 - x/gov/simulation/genesis.go | 14 - x/gov/simulation/operations.go | 42 - x/inflation/alias.go | 24 - x/inflation/genesis.go | 53 - x/inflation/keeper/keeper.go | 57 - x/inflation/module.go | 191 - x/inflation/simulation/genesis.go | 21 - x/market/alias.go | 8 +- x/market/client/cli/bid.go | 99 - x/market/client/cli/cli_test.go | 411 --- x/market/client/cli/flags.go | 210 -- x/market/client/cli/grpc_rest_test.go | 627 ---- x/market/client/cli/lease.go | 99 - x/market/client/cli/order.go | 98 - x/market/client/cli/query.go | 75 - x/market/client/cli/test_helpers.go | 139 - x/market/client/cli/tx.go | 339 -- x/market/client/rest/params.go | 215 +- x/market/client/rest/rest.go | 185 +- x/market/genesis.go | 65 +- x/market/handler/handler.go | 20 +- x/market/handler/handler_test.go | 193 +- x/market/handler/keepers.go | 54 +- x/market/handler/server.go | 202 +- x/market/hooks/external.go | 26 +- x/market/hooks/hooks.go | 41 +- x/market/keeper/external.go | 12 +- x/market/keeper/grpc_query.go | 68 +- x/market/keeper/grpc_query_test.go | 226 +- x/market/keeper/keeper.go | 381 +- x/market/keeper/keeper_test.go | 188 +- x/market/keeper/keys/{v1beta4 => }/key.go | 109 +- x/market/keeper/keys/v1beta1/key.go | 92 - x/market/keeper/keys/v1beta2/key.go | 164 - x/market/keeper/keys/v1beta2/key_test.go | 34 - x/market/keeper/keys/v1beta3/key.go | 164 - x/market/keeper/keys/v1beta3/key_test.go | 34 - x/market/keeper/keys/v1beta4/key_test.go | 35 - x/market/module.go | 165 +- x/market/query/client.go | 8 +- x/market/query/path.go | 39 +- x/market/query/rawclient.go | 15 +- x/market/query/types.go | 33 +- x/market/simulation/genesis.go | 7 +- x/market/simulation/operations.go | 184 +- x/market/simulation/proposals.go | 44 + x/market/simulation/utils.go | 13 +- x/provider/alias.go | 4 +- x/provider/client/cli/cli_test.go | 114 - x/provider/client/cli/grpc_rest_test.go | 170 - x/provider/client/cli/query.go | 108 - x/provider/client/cli/test_helpers.go | 53 - x/provider/client/cli/tx.go | 139 - x/provider/client/rest/rest.go | 49 +- x/provider/config/config.go | 15 +- x/provider/genesis.go | 13 +- x/provider/handler/handler.go | 17 +- x/provider/handler/handler_test.go | 53 +- x/provider/handler/server.go | 23 +- x/provider/keeper/grpc_query.go | 4 +- x/provider/keeper/grpc_query_test.go | 14 +- x/provider/keeper/keeper.go | 41 +- x/provider/keeper/keeper_test.go | 8 +- x/provider/keeper/key.go | 8 +- x/provider/module.go | 162 +- x/provider/query/types.go | 2 +- x/provider/simulation/genesis.go | 2 +- x/provider/simulation/operations.go | 140 +- x/staking/alias.go | 24 - x/staking/genesis.go | 39 - x/staking/keeper/keeper.go | 65 - x/staking/module.go | 194 - x/staking/simulation/genesis.go | 14 - x/staking/simulation/operations.go | 42 - x/take/alias.go | 2 +- x/take/genesis.go | 14 +- x/take/handler/server.go | 39 + x/take/keeper/grpc_query.go | 29 + x/take/keeper/keeper.go | 79 +- x/take/module.go | 151 +- x/take/simulation/decoder.go | 17 + x/take/simulation/genesis.go | 3 +- x/take/simulation/proposals.go | 65 + 434 files changed, 20067 insertions(+), 28187 deletions(-) create mode 100644 .github/.repo create mode 100644 .github/actions/setup-ubuntu/action.yaml delete mode 100644 app/app_test.go delete mode 100644 app/decorators/gov_filter.go delete mode 100644 app/decorators/min_commision.go create mode 100644 app/modules.go create mode 100644 app/option.go delete mode 100644 app/params/proto.go create mode 100644 app/sim/sim_config.go create mode 100644 app/sim/sim_utils.go delete mode 100644 client/client.go delete mode 100644 cmd/akash/cmd/flag_test.go create mode 100644 cmd/akash/cmd/genesis.go create mode 100644 cmd/akash/cmd/testnet.go create mode 100644 cmd/akash/cmd/testnetify/cmt_abci.go delete mode 100644 cmd/common/flags.go delete mode 100644 cmd/common/signal.go delete mode 100644 cmd/common/util.go delete mode 100644 cmd/common/util_test.go delete mode 100644 events/cmd/root.go delete mode 100644 events/publish.go delete mode 100644 events/publish_test.go delete mode 100644 events/query.go mode change 100644 => 100755 script/shellcheck.sh delete mode 100644 sdl/_testdata/deployment-svc-mismatch.yaml delete mode 100644 sdl/_testdata/private_service.yaml delete mode 100644 sdl/_testdata/profile-svc-name-mismatch.yaml delete mode 100644 sdl/_testdata/service-mix.yaml delete mode 100644 sdl/_testdata/service-mix2.yaml delete mode 100644 sdl/_testdata/simple-double-ram.yaml delete mode 100644 sdl/_testdata/simple-gpu.yaml delete mode 100644 sdl/_testdata/simple-with-ip.yaml delete mode 100644 sdl/_testdata/simple.yaml delete mode 100644 sdl/_testdata/simple2.yaml delete mode 100644 sdl/_testdata/simple3.yaml delete mode 100644 sdl/_testdata/simple4.yaml delete mode 100644 sdl/_testdata/storageClass1.yaml delete mode 100644 sdl/_testdata/storageClass2.yaml delete mode 100644 sdl/_testdata/storageClass3.yaml delete mode 100644 sdl/_testdata/storageClass4.yaml delete mode 100644 sdl/_testdata/storageClass5.yaml delete mode 100644 sdl/_testdata/storageClass6.yaml delete mode 100644 sdl/_testdata/v2.1-credentials-error.yaml delete mode 100644 sdl/_testdata/v2.1-credentials.yaml delete mode 100644 sdl/_testdata/v2.1-deployment-svc-mismatch.yaml delete mode 100644 sdl/_testdata/v2.1-private_service.yaml delete mode 100644 sdl/_testdata/v2.1-profile-svc-name-mismatch.yaml delete mode 100644 sdl/_testdata/v2.1-service-mix.yaml delete mode 100644 sdl/_testdata/v2.1-service-mix2.yaml delete mode 100644 sdl/_testdata/v2.1-simple-gpu.yaml delete mode 100644 sdl/_testdata/v2.1-simple-with-ip.yaml delete mode 100644 sdl/_testdata/v2.1-simple.yaml delete mode 100644 sdl/_testdata/v2.1-simple2.yaml delete mode 100644 sdl/_testdata/v2.1-simple3.yaml delete mode 100644 sdl/_testdata/v2.1-simple4.yaml delete mode 100644 sdl/coin.go delete mode 100644 sdl/coin_test.go delete mode 100644 sdl/cpu.go delete mode 100644 sdl/cpu_test.go delete mode 100644 sdl/expose.go delete mode 100644 sdl/full_test.go delete mode 100644 sdl/gpu.go delete mode 100644 sdl/gpu_test.go delete mode 100644 sdl/groupBuilder_v2.go delete mode 100644 sdl/groupBuilder_v2_1.go delete mode 100644 sdl/memory.go delete mode 100644 sdl/placement.go delete mode 100644 sdl/pricing.go delete mode 100644 sdl/resources.go delete mode 100644 sdl/sdl.go delete mode 100644 sdl/sdl_test.go delete mode 100644 sdl/storage.go delete mode 100644 sdl/storage_test.go delete mode 100644 sdl/units.go delete mode 100644 sdl/units_test.go delete mode 100644 sdl/util/util.go delete mode 100644 sdl/util/util_test.go delete mode 100644 sdl/utils.go delete mode 100644 sdl/v2.go delete mode 100644 sdl/v2_1.go delete mode 100644 sdl/v2_1_ip_test.go delete mode 100644 sdl/v2_1_test.go delete mode 100644 sdl/v2_ip_test.go delete mode 100644 sdl/v2_test.go create mode 100644 tests/e2e/certs_cli_test.go create mode 100644 tests/e2e/certs_grpc_test.go create mode 100644 tests/e2e/cli_test.go create mode 100644 tests/e2e/deployment_cli_test.go create mode 100644 tests/e2e/deployment_grpc_test.go create mode 100644 tests/e2e/grpc_test.go create mode 100644 tests/e2e/market_cli_test.go create mode 100644 tests/e2e/market_grpc_test.go create mode 100644 tests/e2e/provider_cli_test.go create mode 100644 tests/e2e/provider_grpc_test.go create mode 100644 tests/upgrade/test-config-gha.json delete mode 100644 tests/upgrade/v0.26.0/postupgrade.go delete mode 100644 tests/upgrade/v0.32.0/postupgrade.go delete mode 100644 tests/upgrade/v0.34.0/postupgrade.go delete mode 100644 tests/upgrade/v0.36.0/postupgrade.go delete mode 100644 testutil/audit.go delete mode 100644 testutil/base.go delete mode 100644 testutil/cert.go delete mode 100644 testutil/channel_wait.go delete mode 100644 testutil/cli/cmd.go create mode 100644 testutil/cosmos/mocks/AuthzKeeper_mock.go create mode 100644 testutil/cosmos/mocks/BankKeeper_mock.go rename testutil/cosmos/mocks/{take_keeper.go => TakeKeeper_mock.go} (56%) delete mode 100644 testutil/cosmos/mocks/authz_keeper.go delete mode 100644 testutil/cosmos/mocks/bank_keeper.go delete mode 100644 testutil/cosmos/mocks/distr_keeper.go delete mode 100644 testutil/deployment.go delete mode 100644 testutil/event.go delete mode 100644 testutil/ids.go delete mode 100644 testutil/log.go create mode 100644 testutil/network/option.go delete mode 100644 testutil/provider.go delete mode 100644 testutil/rand.go delete mode 100644 testutil/sdk.go create mode 100644 testutil/sims/address_helpers.go create mode 100644 testutil/sims/app_helpers.go create mode 100644 testutil/sims/expected_keepers.go create mode 100644 testutil/sims/simulation_helpers.go create mode 100644 testutil/sims/simulation_helpers_test.go create mode 100644 testutil/sims/state_helpers.go create mode 100644 testutil/sims/tx_helpers.go delete mode 100644 types/config.go delete mode 100644 upgrades/software/v0.15.0/audit.go delete mode 100644 upgrades/software/v0.15.0/cert.go delete mode 100644 upgrades/software/v0.15.0/deployment.go delete mode 100644 upgrades/software/v0.15.0/escrow.go delete mode 100644 upgrades/software/v0.15.0/helpers.go delete mode 100644 upgrades/software/v0.15.0/init.go delete mode 100644 upgrades/software/v0.15.0/market.go delete mode 100644 upgrades/software/v0.15.0/proto_compatibility_test.go delete mode 100644 upgrades/software/v0.15.0/provider.go delete mode 100644 upgrades/software/v0.15.0/upgrade.go delete mode 100644 upgrades/software/v0.18.0/init.go delete mode 100644 upgrades/software/v0.18.0/upgrade.go delete mode 100644 upgrades/software/v0.20.0/init.go delete mode 100644 upgrades/software/v0.20.0/upgrade.go delete mode 100644 upgrades/software/v0.24.0/deployment.go delete mode 100644 upgrades/software/v0.24.0/init.go delete mode 100644 upgrades/software/v0.24.0/market.go delete mode 100644 upgrades/software/v0.24.0/upgrade.go delete mode 100644 upgrades/software/v0.26.0/init.go delete mode 100644 upgrades/software/v0.26.0/upgrade.go delete mode 100644 upgrades/software/v0.28.0/init.go delete mode 100644 upgrades/software/v0.28.0/market.go delete mode 100644 upgrades/software/v0.28.0/upgrade.go delete mode 100644 upgrades/software/v0.30.0/init.go delete mode 100644 upgrades/software/v0.30.0/upgrade.go delete mode 100644 upgrades/software/v0.32.0/init.go delete mode 100644 upgrades/software/v0.32.0/market.go delete mode 100644 upgrades/software/v0.32.0/upgrade.go delete mode 100644 upgrades/software/v0.34.0/init.go delete mode 100644 upgrades/software/v0.34.0/upgrade.go delete mode 100644 upgrades/software/v0.36.0/init.go delete mode 100644 upgrades/software/v0.36.0/upgrade.go delete mode 100644 upgrades/software/v0.38.0/authz.go delete mode 100644 upgrades/software/v0.38.0/cert.go delete mode 100644 upgrades/software/v0.38.0/deployment.go delete mode 100644 upgrades/software/v0.38.0/init.go delete mode 100644 upgrades/software/v0.38.0/upgrade.go create mode 100644 upgrades/software/v1.0.0/audit.go create mode 100644 upgrades/software/v1.0.0/cert.go create mode 100644 upgrades/software/v1.0.0/deployment.go create mode 100644 upgrades/software/v1.0.0/escrow.go create mode 100644 upgrades/software/v1.0.0/init.go rename upgrades/software/{v0.38.0 => v1.0.0}/market.go (53%) create mode 100644 upgrades/software/v1.0.0/provider.go create mode 100644 upgrades/software/v1.0.0/take.go create mode 100644 upgrades/software/v1.0.0/upgrade.go create mode 100644 util/partialord/internal/dag/dag.go create mode 100644 util/partialord/internal/dag/dag_test.go create mode 100644 util/partialord/internal/dag/module.go create mode 100644 util/partialord/module.go create mode 100644 util/partialord/partialord.go create mode 100644 util/partialord/partialord_test.go create mode 100644 util/server/utils.go delete mode 100644 x/audit/client/cli/cli_test.go delete mode 100644 x/audit/client/cli/query.go delete mode 100644 x/audit/client/cli/tx.go delete mode 100644 x/audit/client/rest/rest.go delete mode 100644 x/cert/client/cli/errors.go delete mode 100644 x/cert/client/cli/grpc_rest_test.go delete mode 100644 x/cert/client/cli/query.go delete mode 100644 x/cert/client/cli/test_helpers.go delete mode 100644 x/cert/client/cli/tx.go delete mode 100644 x/cert/client/cli/tx_cmd.go delete mode 100644 x/cert/client/cli/tx_test.go delete mode 100644 x/deployment/client/cli/cli_test.go delete mode 100644 x/deployment/client/cli/flags.go delete mode 100644 x/deployment/client/cli/grpc_rest_test.go delete mode 100644 x/deployment/client/cli/query.go delete mode 100644 x/deployment/client/cli/test_helpers.go delete mode 100644 x/deployment/client/cli/tx.go delete mode 100644 x/deployment/client/cli/util.go delete mode 100644 x/deployment/client/rest/params.go delete mode 100644 x/deployment/client/rest/rest.go delete mode 100644 x/deployment/handler/mocks/authz_keeper.go create mode 100644 x/deployment/simulation/proposals.go delete mode 100644 x/escrow/client/cli/query.go delete mode 100644 x/escrow/client/cli/tx.go create mode 100644 x/escrow/handler/handler.go create mode 100644 x/escrow/handler/keepers.go create mode 100644 x/escrow/handler/server.go create mode 100644 x/escrow/keeper/grpc_query.go create mode 100644 x/escrow/keeper/grpc_query_test.go delete mode 100644 x/gov/alias.go delete mode 100644 x/gov/genesis.go delete mode 100644 x/gov/keeper/keeper.go delete mode 100644 x/gov/module.go delete mode 100644 x/gov/simulation/genesis.go delete mode 100644 x/gov/simulation/operations.go delete mode 100644 x/inflation/alias.go delete mode 100644 x/inflation/genesis.go delete mode 100644 x/inflation/keeper/keeper.go delete mode 100644 x/inflation/module.go delete mode 100644 x/inflation/simulation/genesis.go delete mode 100644 x/market/client/cli/bid.go delete mode 100644 x/market/client/cli/cli_test.go delete mode 100644 x/market/client/cli/flags.go delete mode 100644 x/market/client/cli/grpc_rest_test.go delete mode 100644 x/market/client/cli/lease.go delete mode 100644 x/market/client/cli/order.go delete mode 100644 x/market/client/cli/query.go delete mode 100644 x/market/client/cli/test_helpers.go delete mode 100644 x/market/client/cli/tx.go rename x/market/keeper/keys/{v1beta4 => }/key.go (84%) delete mode 100644 x/market/keeper/keys/v1beta1/key.go delete mode 100644 x/market/keeper/keys/v1beta2/key.go delete mode 100644 x/market/keeper/keys/v1beta2/key_test.go delete mode 100644 x/market/keeper/keys/v1beta3/key.go delete mode 100644 x/market/keeper/keys/v1beta3/key_test.go delete mode 100644 x/market/keeper/keys/v1beta4/key_test.go create mode 100644 x/market/simulation/proposals.go delete mode 100644 x/provider/client/cli/cli_test.go delete mode 100644 x/provider/client/cli/grpc_rest_test.go delete mode 100644 x/provider/client/cli/query.go delete mode 100644 x/provider/client/cli/test_helpers.go delete mode 100644 x/provider/client/cli/tx.go delete mode 100644 x/staking/alias.go delete mode 100644 x/staking/genesis.go delete mode 100644 x/staking/keeper/keeper.go delete mode 100644 x/staking/module.go delete mode 100644 x/staking/simulation/genesis.go delete mode 100644 x/staking/simulation/operations.go create mode 100644 x/take/handler/server.go create mode 100644 x/take/keeper/grpc_query.go create mode 100644 x/take/simulation/decoder.go create mode 100644 x/take/simulation/proposals.go diff --git a/.env b/.env index 8235e23c8e..da7aa6deaf 100644 --- a/.env +++ b/.env @@ -11,3 +11,4 @@ AKASH_DEVCACHE_VERSIONS=${AKASH_DEVCACHE}/versions AKASH_DEVCACHE_NODE_MODULES=${AKASH_DEVCACHE} AKASH_DEVCACHE_NODE_BIN=${AKASH_DEVCACHE_NODE_MODULES}/node_modules/.bin AKASH_RUN=${AKASH_DEVCACHE}/run +AKASH_RUN_BIN=${AKASH_RUN}/bin diff --git a/.envrc b/.envrc index 57cf4c4159..9ea99da26f 100644 --- a/.envrc +++ b/.envrc @@ -2,55 +2,71 @@ direnv_version_major=$(direnv version | cut -d "." -f1 | tr -d '\n') direnv_version_minor=$(direnv version | cut -d "." -f2 | tr -d '\n') if [[ $direnv_version_major -lt 2 ]] || [[ $direnv_version_major -eq 2 ]] && [[ $direnv_version_minor -lt 32 ]]; then - echo -e "\033[31munsupported direnv version $(direnv version) < 2.32.x" - exit 1 + echo -e "\033[31munsupported direnv version $(direnv version) < 2.32.x" + exit 1 fi -if [[ "$SHELL" == "bash" ]]; then - if [ "${BASH_VERSINFO:-0}" -lt 4 ]; then - echo -e "\033[31mthe environment needs BASH 4 or above" >&2 - exit 1 - fi +if [[ "$(ps -p "$$" -o 'comm=')" =~ "bash" ]]; then + if [ "${BASH_VERSINFO:-0}" -lt 4 ]; then + echo -e "\033[31mthe environment needs BASH 4 or above" >&2 + exit 1 + fi fi -if ! has make ; then - echo "make is not installed"; exit 1 +if ! has make; then + echo "make is not installed" + exit 1 fi -if ! has unzip ; then - echo "unzip is not installed"; exit 1 +if ! has unzip; then + echo "unzip is not installed" + exit 1 fi -if ! has wget ; then - echo "wget is not installed"; exit 1 +if ! has wget; then + echo "wget is not installed" + exit 1 fi -if ! has curl ; then - echo "curl is not installed"; exit 1 +if ! has curl; then + echo "curl is not installed" + exit 1 fi -if ! has npm ; then - echo "npm is not installed"; exit 1 +if ! has npm; then + echo "npm is not installed" + exit 1 fi -if ! has jq ; then - echo "jq is not installed"; exit 1 +if ! has jq; then + echo "jq is not installed" + exit 1 fi -if ! has readlink ; then - echo "readlink is not installed"; exit 1 +if ! has readlink; then + echo "readlink is not installed" + exit 1 +fi + +if ! has pv; then + echo "pv is not installed" + exit 1 +fi + +if ! has lz4; then + echo "lz4 is not installed" + exit 1 fi if [ -z "$GOPATH" ]; then - GOPATH=$(go env GOPATH) - export GOPATH + GOPATH=$(go env GOPATH) + export GOPATH fi AKASH_ROOT=$(pwd) export AKASH_ROOT dotenv -dotenv_if_exists dev.env TOOLS=${AKASH_ROOT}/script/tools.sh SEMVER=${AKASH_ROOT}/script/semver.sh @@ -58,16 +74,30 @@ SEMVER=${AKASH_ROOT}/script/semver.sh GOTOOLCHAIN=$(${TOOLS} gotoolchain) GOTOOLCHAIN_SEMVER=$(echo "${GOTOOLCHAIN}" | sed 's/go*/v/' | tr -d '\n') +dotenv_if_exists dev.env + +if [[ ${GOWORK} != "off" ]] && [[ -f go.work ]]; then + GOWORK=${AKASH_ROOT}/go.work +else + GOWORK=off +fi + if [[ "$OSTYPE" == "darwin"* ]]; then - # on MacOS disable deprecation warnings security framework - CGO_CFLAGS=-Wno-deprecated-declarations + # on MacOS disable deprecation warnings security framework + CGO_CFLAGS=-Wno-deprecated-declarations + + export CGO_CFLAGS +fi - export CGO_CFLAGS +if [ -z "${GOARCH}" ]; then + GOARCH=$(go env GOARCH) + export GOARCH fi export SEMVER export GOTOOLCHAIN export GOTOOLCHAIN_SEMVER +export GOWORK PATH_add "$AKASH_DEVCACHE_NODE_BIN" PATH_add "$AKASH_DEVCACHE_BIN" diff --git a/.github/.repo b/.github/.repo new file mode 100644 index 0000000000..4638b1400b --- /dev/null +++ b/.github/.repo @@ -0,0 +1 @@ +github.com/akash-network/node diff --git a/.github/actions/setup-ubuntu/action.yaml b/.github/actions/setup-ubuntu/action.yaml new file mode 100644 index 0000000000..d55423b38c --- /dev/null +++ b/.github/actions/setup-ubuntu/action.yaml @@ -0,0 +1,38 @@ +--- +name: setup-ubuntu +runs: + using: 'composite' + steps: + - name: Fetch all tags + shell: bash + run: | + if git rev-parse --is-shallow-repository | grep -qxF true; then + git fetch --prune --unshallow + else + git fetch --prune --tags + fi + - name: Install dependencies + # Shell must explicitly specify the shell for each step. https://github.com/orgs/community/discussions/18597 + shell: bash + run: sudo apt install -y make direnv unzip lz4 wget curl npm jq pv coreutils + - name: Setup npm + uses: actions/setup-node@v4 + with: + node-version: 18 + - name: Detect required Go version + shell: bash + run: | + toolchain=$(./script/tools.sh gotoolchain | sed 's/^go//') + if [ -z "$toolchain" ]; then + echo "Error: Failed to detect Go version from script/tools.sh" >&2 + exit 1 + fi + echo "GOVERSION=${toolchain}" >> $GITHUB_ENV + - uses: actions/setup-go@v5 + with: + go-version: "${{ env.GOVERSION }}" + check-latest: true + - name: set environment + uses: HatsuneMiku3939/direnv-action@v1 + with: + masks: '' diff --git a/.github/workflows/concommits.yaml b/.github/workflows/concommits.yaml index f9e5d8dd37..3cab6d1063 100644 --- a/.github/workflows/concommits.yaml +++ b/.github/workflows/concommits.yaml @@ -14,4 +14,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: webiny/action-conventional-commits@v1.1.0 + - uses: webiny/action-conventional-commits@v1.3.0 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ef3d07713f..3755d62fcd 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -10,19 +10,16 @@ on: jobs: publish: - runs-on: ubuntu-latest + runs-on: core-e2e steps: - - uses: actions/checkout@v4 - - run: git fetch --prune --unshallow - - name: Detect required Go version + - name: Cleanup build folder run: | - toolchain=$(./script/tools.sh gotoolchain | sed 's/go*//') - echo "GOVERSION=${toolchain}" >> $GITHUB_ENV - - uses: actions/setup-go@v5 - with: - go-version: "${{ env.GOVERSION }}" - - name: set environment - uses: HatsuneMiku3939/direnv-action@v1 + sudo rm -rf ./* || true + sudo rm -rf ./.??* || true + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup environment + uses: ./.github/actions/setup-ubuntu - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx @@ -37,7 +34,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Make and publish run: | - sudo rm -rf dist + sudo rm -rf .cache/goreleaser make release env: GORELEASER_RELEASE: true @@ -45,21 +42,18 @@ jobs: # using PAT as homebrew is located in different repo GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} test-network-upgrade-on-release: - runs-on: upgrade-tester + runs-on: gh-runner-test needs: - publish steps: - - uses: actions/checkout@v4 - - run: git fetch --prune --unshallow - - name: Detect required Go version + - name: Cleanup build folder run: | - toolchain=$(./script/tools.sh gotoolchain | sed 's/go*//') - echo "GOVERSION=${toolchain}" >> $GITHUB_ENV - - uses: actions/setup-go@v5 - with: - go-version: "${{ env.GOVERSION }}" - - name: set environment - uses: HatsuneMiku3939/direnv-action@v1 + sudo rm -rf ./* || true + sudo rm -rf ./.??* || true + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup environment + uses: ./.github/actions/setup-ubuntu - name: detect release tag run: echo "RELEASE_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV - name: configure variables @@ -67,10 +61,12 @@ jobs: test_required=$(./script/upgrades.sh test-required ${{ env.RELEASE_TAG }}) echo "TEST_REQUIRED=$test_required" >> $GITHUB_ENV - name: run test + id: test if: env.TEST_REQUIRED != '' env: UPGRADE_BINARY_VERSION: ${{ env.RELEASE_TAG }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TEST_CONFIG: test-config-gha.json run: | cd tests/upgrade make test @@ -80,7 +76,7 @@ jobs: with: name: logs path: | - .cache/run/upgrade/validators/logs/*.log + .cache/run/upgrade/validators/logs/.akash*.log notify-homebrew: runs-on: ubuntu-latest diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 344311be06..0411e53f7d 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -20,8 +20,8 @@ jobs: steps: - name: Install dependencies run: | - brew install bash direnv - sudo chsh -s /usr/local/bin/bash + brew install bash direnv pv lz4 + sudo chsh -s "$(brew --prefix)/bin/bash" - name: Hook direnv to bash run: echo 'eval "$(direnv hook bash)"' >> $HOME/.bashrc - uses: actions/checkout@v4 @@ -39,94 +39,52 @@ jobs: direnv allow direnv export gha >> "$GITHUB_ENV" - run: make bins + build-bins: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - run: git fetch --prune --unshallow - - name: Detect required Go version - run: | - toolchain=$(./script/tools.sh gotoolchain | sed 's/go*//') - echo "GOVERSION=${toolchain}" >> $GITHUB_ENV - - uses: actions/setup-go@v5 - with: - go-version: "${{ env.GOVERSION }}" - check-latest: true - - name: set environment - uses: HatsuneMiku3939/direnv-action@v1 + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup environment + uses: ./.github/actions/setup-ubuntu - run: make bins - run: make docker-image tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - run: git fetch --prune --unshallow - - name: Detect required Go version - run: | - toolchain=$(./script/tools.sh gotoolchain | sed 's/go*//') - echo "GOVERSION=${toolchain}" >> $GITHUB_ENV - - uses: actions/setup-go@v5 - with: - go-version: "${{ env.GOVERSION }}" - - name: set environment - uses: HatsuneMiku3939/direnv-action@v1 + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup environment + uses: ./.github/actions/setup-ubuntu - run: make test-full coverage: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: git fetch --prune --unshallow - - name: Detect required Go version - run: | - toolchain=$(./script/tools.sh gotoolchain | sed 's/go*//') - echo "GOVERSION=${toolchain}" >> $GITHUB_ENV - - uses: actions/setup-go@v5 - with: - go-version: "${{ env.GOVERSION }}" - - name: set environment - uses: HatsuneMiku3939/direnv-action@v1 + - uses: ./.github/actions/setup-ubuntu - run: make test-coverage - uses: codecov/codecov-action@v4 - lint: + lint-go: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - run: git fetch --prune --unshallow - - name: Detect required Go version - run: | - toolchain=$(./script/tools.sh gotoolchain | sed 's/go*//') - echo "GOVERSION=${toolchain}" >> $GITHUB_ENV - - uses: actions/setup-go@v5 - with: - go-version: "${{ env.GOVERSION }}" - - name: set environment - uses: HatsuneMiku3939/direnv-action@v1 + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup environment + uses: ./.github/actions/setup-ubuntu - run: make deps-tidy - - run: make build - - run: make test-vet - - name: lint all - run: make test-lint-all - - name: lint make-sublinters - run: make test-sublinters + - run: make lint-go - shellcheck: + lint-shell: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - run: git fetch --prune --unshallow - - name: Detect required Go version - run: | - toolchain=$(./script/tools.sh gotoolchain | sed 's/go*//') - echo "GOVERSION=${toolchain}" >> $GITHUB_ENV - - uses: actions/setup-go@v5 - with: - go-version: "${{ env.GOVERSION }}" - - name: set environment - uses: HatsuneMiku3939/direnv-action@v1 - - run: make shellcheck + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup environment + uses: ./.github/actions/setup-ubuntu + - run: make lint-shell sims: runs-on: ubuntu-latest @@ -134,16 +92,10 @@ jobs: - uses: rokroskar/workflow-run-cleanup-action@master env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - - uses: actions/checkout@v4 - - name: Detect required Go version - run: | - toolchain=$(./script/tools.sh gotoolchain | sed 's/go*//') - echo "GOVERSION=${toolchain}" >> $GITHUB_ENV - - uses: actions/setup-go@v5 - with: - go-version: "${{ env.GOVERSION }}" - - name: set environment - uses: HatsuneMiku3939/direnv-action@v1 + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup environment + uses: ./.github/actions/setup-ubuntu - name: test-sim-nondeterminism run: make test-sim-nondeterminism - name: test-sim-import-export @@ -154,19 +106,16 @@ jobs: run: make test-sim-fullapp release-dry-run: - runs-on: ubuntu-latest + runs-on: core-e2e steps: - - uses: actions/checkout@v4 - - run: git fetch --prune --unshallow - - name: Detect required Go version + - name: Cleanup build folder run: | - toolchain=$(./script/tools.sh gotoolchain | sed 's/go*//') - echo "GOVERSION=${toolchain}" >> $GITHUB_ENV - - uses: actions/setup-go@v5 - with: - go-version: "${{ env.GOVERSION }}" - - name: set environment - uses: HatsuneMiku3939/direnv-action@v1 + sudo rm -rf ./* || true + sudo rm -rf ./.??* || true + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup environment + uses: ./.github/actions/setup-ubuntu - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx @@ -177,38 +126,22 @@ jobs: - name: git tag run: git tag -a ${{ env.RELEASE_TAG }} -m ${{ env.RELEASE_TAG }} - name: release dry-run - run: make release + run: | + make release network-upgrade-names: - runs-on: upgrade-tester + runs-on: ubuntu-latest steps: - - name: Cleanup build folder - run: | - sudo rm -rf ./* || true - sudo rm -rf ./.??* || true - - uses: actions/checkout@v4 - - run: git fetch --prune --unshallow - - name: Detect required Go version - run: | - toolchain=$(./script/tools.sh gotoolchain | sed 's/go*//') - echo "GOVERSION=${toolchain}" >> $GITHUB_ENV - - name: 'Setup jq' - uses: dcarbone/install-jq-action@v3 - - name: Setup npm - uses: actions/setup-node@v4 - with: - node-version: 18 - - uses: actions/setup-go@v5 - with: - go-version: "${{ env.GOVERSION }}" + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup environment + uses: ./.github/actions/setup-ubuntu - name: Setup docker user run: | DOCKER_USER=$(id -u) DOCKER_GROUP=$(id -g) echo "DOCKER_USER=$DOCKER_USER" >> $GITHUB_ENV echo "DOCKER_GROUP=$DOCKER_GROUP" >> $GITHUB_ENV - - name: set environment - uses: HatsuneMiku3939/direnv-action@v1 - name: Ensure only directories exists in upgrades dir run: | dir=./upgrades/software @@ -224,41 +157,34 @@ jobs: done <<< $(find "$dir" ! -path "$dir" -maxdepth 1 -type d -exec basename {} \;) network-upgrade: runs-on: upgrade-tester + needs: + network-upgrade-names steps: - name: Cleanup build folder run: | sudo rm -rf ./* || true sudo rm -rf ./.??* || true - - uses: actions/checkout@v4 - - run: git fetch --prune --unshallow - - name: Detect required Go version - run: | - toolchain=$(./script/tools.sh gotoolchain | sed 's/go*//') - echo "GOVERSION=${toolchain}" >> $GITHUB_ENV - - name: 'Setup jq' - uses: dcarbone/install-jq-action@v3 - - name: Setup npm - uses: actions/setup-node@v4 - with: - node-version: 18 - - uses: actions/setup-go@v5 - with: - go-version: "${{ env.GOVERSION }}" + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup environment + uses: ./.github/actions/setup-ubuntu - name: Setup docker user run: | DOCKER_USER=$(id -u) DOCKER_GROUP=$(id -g) echo "DOCKER_USER=$DOCKER_USER" >> $GITHUB_ENV echo "DOCKER_GROUP=$DOCKER_GROUP" >> $GITHUB_ENV - - name: set environment - uses: HatsuneMiku3939/direnv-action@v1 - name: configure variables run: | test_required=$(./script/upgrades.sh test-required ${{ github.ref }}) + #snapshot_source=$(./script/upgrades.sh snapshot-source ${{ github.ref }}) echo "TEST_REQUIRED=$test_required" >> $GITHUB_ENV + #echo "SNAPSHOT_SOURCE=$snapshot_source" >> $GITHUB_ENV - name: run test id: test if: env.TEST_REQUIRED != '' + env: + TEST_CONFIG: test-config-gha.json run: | cd tests/upgrade make test @@ -267,9 +193,9 @@ jobs: uses: actions/upload-artifact@v4 with: name: validators-logs - path: | - .cache/run/upgrade/validators/logs/*.log include-hidden-files: true + path: | + .cache/run/upgrade/validators/logs/.akash*.log dispatch-release: runs-on: ubuntu-latest @@ -279,11 +205,11 @@ jobs: - build-bins - tests - coverage - - lint + - lint-go + - lint-shell - sims - release-dry-run - network-upgrade - - shellcheck steps: - uses: actions/checkout@v4 with: diff --git a/.golangci.yaml b/.golangci.yaml index 682344183f..12fe1c24c9 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -1,20 +1,46 @@ -issues: - exclude: - - comment on exported (method|function|type|const|var) - exclude-use-default: true - exclude-dirs: - - ".*/mocks" - # Skip vendor/ etc - skip-dirs-use-default: true +--- +version: "2" linters: - disable-all: true + default: none enable: - - misspell - - unused - - gofmt - - gocritic + - copyloopvar + - errcheck + - errchkjson - goconst + - gocritic + - gosec + - govet - ineffassign - - unparam - - staticcheck + - misspell - prealloc + - staticcheck + - unparam + - unused +settings: + gocritic: + disabled-checks: + - ifElseChain + - singleCaseSwitch +exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - path: (.+)\.go$ + text: comment on exported (method|function|type|const|var) + paths: + - third_party$ + - builtin$ + - examples$ +formatters: + enable: + - gofmt + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/.goreleaser-docker.yaml b/.goreleaser-docker.yaml index d9da6089a2..224fcf3c8a 100644 --- a/.goreleaser-docker.yaml +++ b/.goreleaser-docker.yaml @@ -1,6 +1,5 @@ --- version: 2 -project_name: node dist: ./.cache/goreleaser/docker env: - GO111MODULE=on @@ -77,4 +76,5 @@ dockers: - '{{ .Env.DOCKER_IMAGE }}:latest-arm64' archives: - - format: binary + - formats: + - binary diff --git a/.goreleaser-test-bins.yaml b/.goreleaser-test-bins.yaml index 66517ad157..3f484f6513 100644 --- a/.goreleaser-test-bins.yaml +++ b/.goreleaser-test-bins.yaml @@ -90,7 +90,7 @@ universal_binaries: archives: - id: wo/version - builds: + ids: - akash-darwin-universal - akash-linux-amd64 - akash-linux-arm64 diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 54d26566e5..a90e84103e 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -1,7 +1,7 @@ --- version: 2 project_name: node -dist: ./.cache/goreleaser +dist: ./.cache/goreleaser/main env: - GO111MODULE=on - CGO_ENABLED=1 @@ -89,7 +89,7 @@ universal_binaries: name_template: "akash" archives: - id: w/version - builds: + ids: - akash-darwin-universal - akash-linux-amd64 - akash-linux-arm64 @@ -100,7 +100,7 @@ archives: files: - none* - id: wo/version - builds: + ids: - akash-darwin-universal - akash-linux-amd64 - akash-linux-arm64 @@ -125,14 +125,14 @@ dockers: - --platform=linux/amd64 - --label=org.opencontainers.image.title={{ .ProjectName }} - --label=org.opencontainers.image.description={{ .ProjectName }} - - --label=org.opencontainers.image.url={{.GitURL}} - - --label=org.opencontainers.image.source={{.GitURL}} - - --label=org.opencontainers.image.version={{ .Version }} + - --label=org.opencontainers.image.url={{ .GitURL }} + - --label=org.opencontainers.image.source={{ .GitURL }} + - --label=org.opencontainers.image.version={{ replace .Version "+" "-" }} - --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }} - --label=org.opencontainers.image.revision={{ .FullCommit }} image_templates: - '{{ .Env.DOCKER_IMAGE }}:{{ .ShortCommit }}-amd64' - - '{{ .Env.DOCKER_IMAGE }}:{{ .Version }}-amd64' + - '{{ .Env.DOCKER_IMAGE }}:{{ replace .Version "+" "-" }}-amd64' - '{{ .Env.DOCKER_IMAGE }}:{{if eq .Env.STABLE "true"}}stable{{else}}latest{{end}}-amd64' - dockerfile: _build/Dockerfile.akash use: buildx @@ -142,24 +142,24 @@ dockers: - --platform=linux/arm64 - --label=org.opencontainers.image.title={{ .ProjectName }} - --label=org.opencontainers.image.description={{ .ProjectName }} - - --label=org.opencontainers.image.url={{.GitURL}} - - --label=org.opencontainers.image.source={{.GitURL}} - - --label=org.opencontainers.image.version={{ .Version }} + - --label=org.opencontainers.image.url={{ .GitURL }} + - --label=org.opencontainers.image.source={{ .GitURL }} + - --label=org.opencontainers.image.version={{ replace .Version "+" "-" }} - --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }} - --label=org.opencontainers.image.revision={{ .FullCommit }} image_templates: - '{{ .Env.DOCKER_IMAGE }}:{{ .ShortCommit }}-arm64' - - '{{ .Env.DOCKER_IMAGE }}:{{ .Version }}-arm64' + - '{{ .Env.DOCKER_IMAGE }}:{{ replace .Version "+" "-" }}-arm64' - '{{ .Env.DOCKER_IMAGE }}:{{if eq .Env.STABLE "true"}}stable{{else}}latest{{end}}-arm64' docker_manifests: - name_template: "{{ .Env.DOCKER_IMAGE }}:{{ .ShortCommit }}" image_templates: - - "{{ .Env.DOCKER_IMAGE }}:{{ .ShortCommit }}-amd64" - - "{{ .Env.DOCKER_IMAGE }}:{{ .ShortCommit }}-arm64" - - name_template: "{{ .Env.DOCKER_IMAGE }}:{{ .Version }}" + - '{{ .Env.DOCKER_IMAGE }}:{{ .ShortCommit }}-amd64' + - '{{ .Env.DOCKER_IMAGE }}:{{ .ShortCommit }}-arm64' + - name_template: '{{ .Env.DOCKER_IMAGE }}:{{ replace .Version "+" "-" }}' image_templates: - - "{{ .Env.DOCKER_IMAGE }}:{{ .Version }}-amd64" - - "{{ .Env.DOCKER_IMAGE }}:{{ .Version }}-arm64" + - '{{ .Env.DOCKER_IMAGE }}:{{ replace .Version "+" "-" }}-amd64' + - '{{ .Env.DOCKER_IMAGE }}:{{ replace .Version "+" "-" }}-arm64' - name_template: "{{ .Env.DOCKER_IMAGE }}:latest" image_templates: - "{{ .Env.DOCKER_IMAGE }}:latest-amd64" diff --git a/.mockery.yaml b/.mockery.yaml index b8a37a4358..90d8abcef8 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -1,5 +1,14 @@ -quiet: False -inpackage: False -with-expecter: True -keeptree: True -case: underscore +dir: mocks +structname: '{{.InterfaceName}}' +filename: "{{.StructName}}_mock.go" +template: testify +template-data: + unroll-variadic: true +packages: + pkg.akt.dev/node/testutil/cosmos: + config: + dir: testutil/cosmos/mocks + interfaces: + AuthzKeeper: {} + BankKeeper: {} + TakeKeeper: {} diff --git a/CHANGELOG.md b/CHANGELOG.md index d5a46927bf..d6e650ae95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,7 +38,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] -* (ibc-go) Use ibc v4.4.0 https://github.com/akash-network/node/pull/1825 +* (ibc-go) Use ibc v4.4.0 https://pkg.akt.dev/node/pull/1825 ### Improvements diff --git a/Makefile b/Makefile index 843bd28131..f8a0343741 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ include make/init.mk DOCKER_RUN := docker run --rm -v $(shell pwd):/workspace -w /workspace GOLANGCI_LINT_RUN := $(GOLANGCI_LINT) run -LINT = $(GOLANGCI_LINT_RUN) ./... --disable-all --timeout=5m --enable +LINT = $(GOLANGCI_LINT_RUN) ./... --disable-all --deadline=5m --enable GORELEASER_CONFIG ?= .goreleaser.yaml @@ -25,7 +25,7 @@ IS_MAINNET := $(shell $(ROOT_DIR)/script/mainnet-from-tag.sh "$(RELEA IS_STABLE ?= false GO_LINKMODE ?= external -GO_MOD ?= readonly +GOMOD ?= readonly BUILD_TAGS ?= osusergo,netgo,ledger GORELEASER_STRIP_FLAGS ?= @@ -61,7 +61,7 @@ endif ldflags += $(LDFLAGS) ldflags := $(strip $(ldflags)) -BUILD_FLAGS := -mod=$(GO_MOD) -tags='$(BUILD_TAGS)' -ldflags '$(ldflags)' +BUILD_FLAGS := -mod=$(GOMOD) -tags='$(BUILD_TAGS)' -ldflags '$(ldflags)' .PHONY: all all: build bins diff --git a/README.md b/README.md index 80e53256c6..795f3560fa 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ The `main` branch contains new features and is under active development; the `ma Akash Suite is the reference implementation of the [Akash Protocol](https://ipfs.io/ipfs/QmdV52bF7j4utynJ6L11RgG93FuJiUmBH1i7pRD6NjUt6B). Akash is an actively-developed prototype currently focused on the distributed marketplace functionality. -The Suite is composed of one binary, `akash`, which contains a ([tendermint](https://github.com/tendermint/tendermint)-powered) blockchain node that +The Suite is composed of one binary, `akash`, which contains a ([tendermint](https://github.com/cometbft/cometbft)-powered) blockchain node that implements the decentralized exchange as well as client functionality to access the exchange and network data in general. ## Get Started with Akash diff --git a/_build/single-node.sh b/_build/single-node.sh index c347cdde19..9295a14fe1 100755 --- a/_build/single-node.sh +++ b/_build/single-node.sh @@ -14,12 +14,12 @@ if [ -z "$2" ]; then fi # Build genesis file incl account for passed address -coins="10000000000stake,100000000000samoleans" +coins="10000000000uakt" akash init --chain-id "$CHAINID" "$CHAINID" akash keys add validator --keyring-backend="test" akash add-genesis-account "$(akash keys show validator -a --keyring-backend="test")" $coins akash add-genesis-account "$GENACCT" $coins -akash gentx validator 10000000000stake --keyring-backend="test" --chain-id "$CHAINID" +akash gentx validator 10000000000uakt --keyring-backend="test" --chain-id "$CHAINID" akash collect-gentxs # Set proper defaults and change ports @@ -29,4 +29,4 @@ sed -i 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ~/.akash/config/confi sed -i 's/index_all_keys = false/index_all_keys = true/g' ~/.akash/config/config.toml # Start the akash -akash start --pruning=nothing \ No newline at end of file +akash start --pruning=nothing diff --git a/_docs/adr/adr-001-network-upgrades.md b/_docs/adr/adr-001-network-upgrades.md index 4cc2b787ee..f94db2d4f3 100644 --- a/_docs/adr/adr-001-network-upgrades.md +++ b/_docs/adr/adr-001-network-upgrades.md @@ -40,12 +40,12 @@ Each file has steps in form of comment with `StepX` prefix. Each step must be im package v0_24_0 import ( - "github.com/tendermint/tendermint/libs/log" + "github.com/cometbft/cometbft/libs/log" - storetypes "github.com/cosmos/cosmos-sdk/store/types" + storetypes "cosmossdk.io/store" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + upgradetypes "cosmossdk.io/x/upgrade/types" apptypes "github.com/akash-network/node/app/types" utypes "github.com/akash-network/node/upgrades/types" diff --git a/app/ante.go b/app/ante.go index 2e0f63df62..b8af644b7e 100644 --- a/app/ante.go +++ b/app/ante.go @@ -6,19 +6,13 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/ante" govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" - - "github.com/akash-network/node/app/decorators" - agovkeeper "github.com/akash-network/node/x/gov/keeper" - astakingkeeper "github.com/akash-network/node/x/staking/keeper" ) // HandlerOptions extends the SDK's AnteHandler options type HandlerOptions struct { ante.HandlerOptions - CDC codec.BinaryCodec - AStakingKeeper astakingkeeper.IKeeper - GovKeeper *govkeeper.Keeper - AGovKeeper agovkeeper.IKeeper + CDC codec.BinaryCodec + GovKeeper *govkeeper.Keeper } // NewAnteHandler returns an AnteHandler that checks and increments sequence @@ -26,53 +20,41 @@ type HandlerOptions struct { // signer. func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { if options.AccountKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "account keeper is required for ante builder") + return nil, sdkerrors.ErrLogic.Wrap("account keeper is required for ante builder") } if options.BankKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "bank keeper is required for ante builder") + return nil, sdkerrors.ErrLogic.Wrap("bank keeper is required for ante builder") } if options.SignModeHandler == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") + return nil, sdkerrors.ErrLogic.Wrap("sign mode handler is required for ante builder") } if options.SigGasConsumer == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "sig gas consumer handler is required for ante builder") - } - - if options.AStakingKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "custom akash staking keeper is required for ante builder") + return nil, sdkerrors.ErrLogic.Wrap("sig gas consumer handler is required for ante builder") } if options.GovKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "akash governance keeper is required for ante builder") - } - - if options.AGovKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "custom akash governance keeper is required for ante builder") + return nil, sdkerrors.ErrLogic.Wrap("akash governance keeper is required for ante builder") } if options.FeegrantKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "akash feegrant keeper is required for ante builder") + return nil, sdkerrors.ErrLogic.Wrap("akash feegrant keeper is required for ante builder") } anteDecorators := []sdk.AnteDecorator{ ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first - ante.NewRejectExtensionOptionsDecorator(), - ante.NewMempoolFeeDecorator(), ante.NewValidateBasicDecorator(), ante.NewTxTimeoutHeightDecorator(), ante.NewValidateMemoDecorator(options.AccountKeeper), ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), - ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper), + ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, nil), ante.NewSetPubKeyDecorator(options.AccountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators ante.NewValidateSigCountDecorator(options.AccountKeeper), ante.NewSigGasConsumeDecorator(options.AccountKeeper, options.SigGasConsumer), ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), ante.NewIncrementSequenceDecorator(options.AccountKeeper), - decorators.NewMinCommissionDecorator(options.CDC, options.AStakingKeeper), - decorators.NewGovPreventSpamDecorator(options.CDC, *options.GovKeeper, options.AGovKeeper), } return sdk.ChainAnteDecorators(anteDecorators...), nil diff --git a/app/app.go b/app/app.go index ba688185d6..9d5af9848c 100644 --- a/app/app.go +++ b/app/app.go @@ -8,98 +8,70 @@ import ( "path/filepath" "time" - "github.com/cosmos/cosmos-sdk/x/authz" - "github.com/cosmos/cosmos-sdk/x/feegrant" - feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper" - feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module" "github.com/gorilla/mux" "github.com/rakyll/statik/fs" "github.com/spf13/cast" - - abci "github.com/tendermint/tendermint/abci/types" - tmjson "github.com/tendermint/tendermint/libs/json" - "github.com/tendermint/tendermint/libs/log" - tmos "github.com/tendermint/tendermint/libs/os" - tmtypes "github.com/tendermint/tendermint/types" - dbm "github.com/tendermint/tm-db" - - bam "github.com/cosmos/cosmos-sdk/baseapp" + emodule "pkg.akt.dev/go/node/escrow/module" + "pkg.akt.dev/go/sdkutil" + + abci "github.com/cometbft/cometbft/abci/types" + tmjson "github.com/cometbft/cometbft/libs/json" + cmos "github.com/cometbft/cometbft/libs/os" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + tmtypes "github.com/cometbft/cometbft/types" + + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" + "cosmossdk.io/log" + storetypes "cosmossdk.io/store/types" + evidencetypes "cosmossdk.io/x/evidence/types" + "cosmossdk.io/x/feegrant" + upgradetypes "cosmossdk.io/x/upgrade/types" + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" - "github.com/cosmos/cosmos-sdk/client/rpc" + "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" + nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/runtime" + runtimeservices "github.com/cosmos/cosmos-sdk/runtime/services" "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" - "github.com/cosmos/cosmos-sdk/simapp" - "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/version" - "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/ante" - authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" - authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" - authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/auth/vesting" - authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" - authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module" - "github.com/cosmos/cosmos-sdk/x/bank" - bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" + "github.com/cosmos/cosmos-sdk/x/authz" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/cosmos-sdk/x/capability" - capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - "github.com/cosmos/cosmos-sdk/x/crisis" - crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper" - crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" - distr "github.com/cosmos/cosmos-sdk/x/distribution" - distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - "github.com/cosmos/cosmos-sdk/x/evidence" - evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" - "github.com/cosmos/cosmos-sdk/x/genutil" - "github.com/cosmos/cosmos-sdk/x/gov" - govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - "github.com/cosmos/cosmos-sdk/x/mint" - mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" - "github.com/cosmos/cosmos-sdk/x/params" - paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" - paramproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal" - "github.com/cosmos/cosmos-sdk/x/slashing" - slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" - "github.com/cosmos/cosmos-sdk/x/staking" - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/cosmos/cosmos-sdk/x/upgrade" - upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer" - ibc "github.com/cosmos/ibc-go/v4/modules/core" - porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" - - icacontrollertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - icahosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - ibctransferkeeper "github.com/cosmos/ibc-go/v4/modules/apps/transfer/keeper" - ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - ibcclient "github.com/cosmos/ibc-go/v4/modules/core/02-client" - ibcclienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host" - ibckeeper "github.com/cosmos/ibc-go/v4/modules/core/keeper" - - apptypes "github.com/akash-network/node/app/types" - utypes "github.com/akash-network/node/upgrades/types" - + transfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" + ibchost "github.com/cosmos/ibc-go/v10/modules/core/exported" + ibctm "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" + + cflags "pkg.akt.dev/go/cli/flags" + audittypes "pkg.akt.dev/go/node/audit/v1" + certtypes "pkg.akt.dev/go/node/cert/v1" + deploymenttypes "pkg.akt.dev/go/node/deployment/v1" + markettypes "pkg.akt.dev/go/node/market/v1" + providertypes "pkg.akt.dev/go/node/provider/v1beta4" + taketypes "pkg.akt.dev/go/node/take/v1" + + apptypes "pkg.akt.dev/node/app/types" + utypes "pkg.akt.dev/node/upgrades/types" // unnamed import of statik for swagger UI support - _ "github.com/akash-network/node/client/docs/statik" + _ "pkg.akt.dev/node/client/docs/statik" ) const ( @@ -107,37 +79,28 @@ const ( ) var ( - DefaultHome = os.ExpandEnv("$HOME/.akash") - _ servertypes.Application = (*AkashApp)(nil) + DefaultHome = os.ExpandEnv("$HOME/.akash") + + _ runtime.AppI = (*AkashApp)(nil) + _ servertypes.Application = (*AkashApp)(nil) // module accounts that are allowed to receive tokens allowedReceivingModAcc = map[string]bool{} ) -type ModulesStoreKeys map[string]*sdk.KVStoreKey -type ModulesTransientKeys map[string]*sdk.TransientStoreKey -type ModulesMemoryKeys map[string]*sdk.MemoryStoreKey - // AkashApp extends ABCI application type AkashApp struct { - *bam.BaseApp - apptypes.App - cdc *codec.LegacyAmino - appCodec codec.Codec - interfaceRegistry codectypes.InterfaceRegistry + *baseapp.BaseApp + *apptypes.App - invCheckPeriod uint - - skeys ModulesStoreKeys - tkeys ModulesTransientKeys - memkeys ModulesMemoryKeys - - // simulation manager - sm *module.SimulationManager + aminoCdc *codec.LegacyAmino + cdc codec.Codec + txConfig client.TxConfig + interfaceRegistry codectypes.InterfaceRegistry + sm *module.SimulationManager + invCheckPeriod uint } -// https://github.com/cosmos/sdk-tutorials/blob/c6754a1e313eb1ed973c5c91dcc606f2fd288811/app.go#L73 - // NewApp creates and returns a new Akash App. func NewApp( logger log.Logger, @@ -146,316 +109,114 @@ func NewApp( loadLatest bool, invCheckPeriod uint, skipUpgradeHeights map[int64]bool, - homePath string, + encodingConfig sdkutil.EncodingConfig, appOpts servertypes.AppOptions, - options ...func(*bam.BaseApp), + options ...func(*baseapp.BaseApp), ) *AkashApp { - // TODO: Remove cdc in favor of appCodec once all modules are migrated. - encodingConfig := MakeEncodingConfig() - appCodec := encodingConfig.Marshaler - cdc := encodingConfig.Amino + appCodec := encodingConfig.Codec + aminoCdc := encodingConfig.Amino interfaceRegistry := encodingConfig.InterfaceRegistry + txConfig := encodingConfig.TxConfig + + bapp := baseapp.NewBaseApp(AppName, logger, db, txConfig.TxDecoder(), options...) - bapp := bam.NewBaseApp(AppName, logger, db, encodingConfig.TxConfig.TxDecoder(), options...) bapp.SetCommitMultiStoreTracer(tio) bapp.SetVersion(version.Version) bapp.SetInterfaceRegistry(interfaceRegistry) + bapp.SetTxEncoder(txConfig.TxEncoder()) - skeys := modulesStoreKeys() - tkeys := modulesTransientKeys() - memkeys := modulesMemoryKeys() + homePath := cast.ToString(appOpts.Get(cflags.FlagHome)) + if homePath == "" { + homePath = DefaultHome + } app := &AkashApp{ - BaseApp: bapp, - cdc: cdc, - appCodec: appCodec, + BaseApp: bapp, + App: &apptypes.App{ + Log: logger, + }, + aminoCdc: aminoCdc, + cdc: appCodec, + txConfig: txConfig, interfaceRegistry: interfaceRegistry, invCheckPeriod: invCheckPeriod, - skeys: skeys, - tkeys: tkeys, - memkeys: memkeys, - } - app.Configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) - - app.Keepers.Cosmos.Params = initParamsKeeper(appCodec, cdc, app.skeys[paramstypes.ModuleName], tkeys[paramstypes.ModuleName]) - - // set the BaseApp's parameter store - bapp.SetParamStore(app.Keepers.Cosmos.Params.Subspace(bam.Paramspace).WithKeyTable(paramskeeper.ConsensusParamsKeyTable())) - - // add capability keeper and ScopeToModule for ibc module - app.Keepers.Cosmos.Cap = capabilitykeeper.NewKeeper( - appCodec, - app.skeys[capabilitytypes.ModuleName], - app.memkeys[capabilitytypes.ModuleName], - ) - - scopedIBCKeeper := app.Keepers.Cosmos.Cap.ScopeToModule(ibchost.ModuleName) - scopedTransferKeeper := app.Keepers.Cosmos.Cap.ScopeToModule(ibctransfertypes.ModuleName) - - // seal the capability keeper so all persistent capabilities are loaded in-memory and prevent - // any further modules from creating scoped sub-keepers. - app.Keepers.Cosmos.Cap.Seal() - - app.Keepers.Cosmos.Acct = authkeeper.NewAccountKeeper( - appCodec, - app.skeys[authtypes.ModuleName], - app.GetSubspace(authtypes.ModuleName), - authtypes.ProtoBaseAccount, - MacPerms(), - ) - - // add authz keeper - app.Keepers.Cosmos.Authz = authzkeeper.NewKeeper(app.skeys[authz.ModuleName], appCodec, app.MsgServiceRouter()) - - app.Keepers.Cosmos.FeeGrant = feegrantkeeper.NewKeeper( - appCodec, - skeys[feegrant.ModuleName], - app.Keepers.Cosmos.Acct, - ) - - app.Keepers.Cosmos.Bank = bankkeeper.NewBaseKeeper( - appCodec, - app.skeys[banktypes.ModuleName], - app.Keepers.Cosmos.Acct, - app.GetSubspace(banktypes.ModuleName), - app.BlockedAddrs(), - ) - - // allocation of staking keeper is scoped deliberately, - // so it's being referenced by pointer within modules that need it - { - skeeper := stakingkeeper.NewKeeper( - appCodec, - app.skeys[stakingtypes.ModuleName], - app.Keepers.Cosmos.Acct, - app.Keepers.Cosmos.Bank, - app.GetSubspace(stakingtypes.ModuleName), - ) - app.Keepers.Cosmos.Staking = &skeeper } - app.Keepers.Cosmos.Mint = mintkeeper.NewKeeper( - appCodec, - app.skeys[minttypes.ModuleName], - app.GetSubspace(minttypes.ModuleName), - app.Keepers.Cosmos.Staking, - app.Keepers.Cosmos.Acct, - app.Keepers.Cosmos.Bank, - authtypes.FeeCollectorName, - ) - - app.Keepers.Cosmos.Distr = distrkeeper.NewKeeper( - appCodec, - app.skeys[distrtypes.ModuleName], - app.GetSubspace(distrtypes.ModuleName), - app.Keepers.Cosmos.Acct, - app.Keepers.Cosmos.Bank, - app.Keepers.Cosmos.Staking, - authtypes.FeeCollectorName, - app.ModuleAccountAddrs(), - ) - - app.Keepers.Cosmos.Slashing = slashingkeeper.NewKeeper( - appCodec, - app.skeys[slashingtypes.ModuleName], - app.Keepers.Cosmos.Staking, - app.GetSubspace(slashingtypes.ModuleName), - ) - - // register the staking hooks - // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks - app.Keepers.Cosmos.Staking.SetHooks( - stakingtypes.NewMultiStakingHooks( - app.Keepers.Cosmos.Distr.Hooks(), - app.Keepers.Cosmos.Slashing.Hooks(), - ), - ) - - app.Keepers.Cosmos.Crisis = crisiskeeper.NewKeeper( - app.GetSubspace(crisistypes.ModuleName), - invCheckPeriod, - app.Keepers.Cosmos.Bank, - authtypes.FeeCollectorName, - ) - - app.Keepers.Cosmos.Upgrade = upgradekeeper.NewKeeper( + app.InitSpecialKeepers( + app.cdc, + aminoCdc, + app.BaseApp, skipUpgradeHeights, - app.skeys[upgradetypes.ModuleName], - appCodec, homePath, - app.BaseApp, - ) - - // register IBC Keeper - app.Keepers.Cosmos.IBC = ibckeeper.NewKeeper( - appCodec, - app.skeys[ibchost.ModuleName], - app.GetSubspace(ibchost.ModuleName), - app.Keepers.Cosmos.Staking, - app.Keepers.Cosmos.Upgrade, - scopedIBCKeeper, - ) - - // register the proposal types - govRouter := govtypes.NewRouter() - govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler). - AddRoute( - paramproposal.RouterKey, - params.NewParamChangeProposalHandler(app.Keepers.Cosmos.Params), - ). - AddRoute( - distrtypes.RouterKey, - distr.NewCommunityPoolSpendProposalHandler(app.Keepers.Cosmos.Distr), - ). - AddRoute( - upgradetypes.RouterKey, - upgrade.NewSoftwareUpgradeProposalHandler(app.Keepers.Cosmos.Upgrade), - ). - AddRoute( - ibcclienttypes.RouterKey, - ibcclient.NewClientProposalHandler(app.Keepers.Cosmos.IBC.ClientKeeper), - ) - - app.Keepers.Cosmos.Gov = govkeeper.NewKeeper( - appCodec, - app.skeys[govtypes.ModuleName], - app.GetSubspace(govtypes.ModuleName), - app.Keepers.Cosmos.Acct, - app.Keepers.Cosmos.Bank, - app.Keepers.Cosmos.Staking, - govRouter, ) - // register Transfer Keepers - app.Keepers.Cosmos.Transfer = ibctransferkeeper.NewKeeper( - appCodec, - app.skeys[ibctransfertypes.ModuleName], - app.GetSubspace(ibctransfertypes.ModuleName), - app.Keepers.Cosmos.IBC.ChannelKeeper, - app.Keepers.Cosmos.IBC.ChannelKeeper, - &app.Keepers.Cosmos.IBC.PortKeeper, - app.Keepers.Cosmos.Acct, - app.Keepers.Cosmos.Bank, - scopedTransferKeeper, + app.InitNormalKeepers( + app.cdc, + encodingConfig, + app.BaseApp, + ModuleAccountPerms(), + app.BlockedAddrs(), + invCheckPeriod, ) - transferModule := transfer.NewAppModule(app.Keepers.Cosmos.Transfer) - transferIBCModule := transfer.NewIBCModule(app.Keepers.Cosmos.Transfer) - - // Create static IBC router, add transfer route, then set and seal it - ibcRouter := porttypes.NewRouter() - ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferIBCModule) - - app.Keepers.Cosmos.IBC.SetRouter(ibcRouter) - - // create evidence keeper with evidence router - evidenceKeeper := evidencekeeper.NewKeeper( - appCodec, - app.skeys[evidencetypes.ModuleName], - app.Keepers.Cosmos.Staking, - app.Keepers.Cosmos.Slashing, - ) - - // if evidence needs to be handled for the app, set routes in router here and seal - app.Keepers.Cosmos.Evidence = *evidenceKeeper - - app.setAkashKeepers() - - // NOTE: we may consider parsing `appOpts` inside module constructors. For the moment - // we prefer to be more strict in what arguments the modules expect. - skipGenesisInvariants := cast.ToBool(appOpts.Get(crisis.FlagSkipGenesisInvariants)) - - app.MM = module.NewManager( - append([]module.AppModule{ - genutil.NewAppModule(app.Keepers.Cosmos.Acct, app.Keepers.Cosmos.Staking, app.BaseApp.DeliverTx, encodingConfig.TxConfig), - auth.NewAppModule(appCodec, app.Keepers.Cosmos.Acct, nil), - authzmodule.NewAppModule(appCodec, app.Keepers.Cosmos.Authz, app.Keepers.Cosmos.Acct, app.Keepers.Cosmos.Bank, app.interfaceRegistry), - feegrantmodule.NewAppModule(appCodec, app.Keepers.Cosmos.Acct, app.Keepers.Cosmos.Bank, app.Keepers.Cosmos.FeeGrant, app.interfaceRegistry), - vesting.NewAppModule(app.Keepers.Cosmos.Acct, app.Keepers.Cosmos.Bank), - bank.NewAppModule(appCodec, app.Keepers.Cosmos.Bank, app.Keepers.Cosmos.Acct), - capability.NewAppModule(appCodec, *app.Keepers.Cosmos.Cap), - crisis.NewAppModule(&app.Keepers.Cosmos.Crisis, skipGenesisInvariants), - gov.NewAppModule(appCodec, app.Keepers.Cosmos.Gov, app.Keepers.Cosmos.Acct, app.Keepers.Cosmos.Bank), - mint.NewAppModule(appCodec, app.Keepers.Cosmos.Mint, app.Keepers.Cosmos.Acct), - // todo akash-network/support#4 - // mint.NewAppModule(appCodec, app.Keepers.Cosmos.Mint, app.Keepers.Cosmos.Acct, nil), - slashing.NewAppModule(appCodec, app.Keepers.Cosmos.Slashing, app.Keepers.Cosmos.Acct, app.Keepers.Cosmos.Bank, app.Keepers.Cosmos.Staking), - distr.NewAppModule(appCodec, app.Keepers.Cosmos.Distr, app.Keepers.Cosmos.Acct, app.Keepers.Cosmos.Bank, app.Keepers.Cosmos.Staking), - staking.NewAppModule(appCodec, *app.Keepers.Cosmos.Staking, app.Keepers.Cosmos.Acct, app.Keepers.Cosmos.Bank), - upgrade.NewAppModule(app.Keepers.Cosmos.Upgrade), - evidence.NewAppModule(app.Keepers.Cosmos.Evidence), - ibc.NewAppModule(app.Keepers.Cosmos.IBC), - params.NewAppModule(app.Keepers.Cosmos.Params), - transferModule, - }, app.akashAppModules()...)..., - ) + // TODO: There is a bug here, where we register the govRouter routes in InitNormalKeepers and then + // call setupHooks afterwards. Therefore, if a gov proposal needs to call a method and that method calls a + // hook, we will get a nil pointer dereference error due to the hooks in the keeper not being + // setup yet. I will refrain from creating an issue in the sdk for now until after we unfork to 0.47, + // because I believe the concept of Routes is going away. + app.SetupHooks() + + // NOTE: All module / keeper changes should happen prior to this module.NewManager line being called. + // However, in the event any changes do need to happen after this call, ensure that that keeper + // is only passed in its keeper form (not de-ref'd anywhere) + // + // Generally NewAppModule will require the keeper that module defines to be passed in as an exact struct, + // but should take in every other keeper as long as it matches a certain interface. (So no need to be de-ref'd) + // + // Any time a module requires a keeper de-ref'd that's not its native one, + // its code-smell and should probably change. We should get the staking keeper dependencies fixed. + modules := appModules(app, encodingConfig) + + app.MM = module.NewManager(modules...) // During begin block slashing happens after distr.BeginBlocker so that // there is nothing left over in the validator fee pool, to keep the // CanWithdrawInvariant invariant. // NOTE: staking module is required if HistoricalEntries param > 0 - // NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC) - // NOTE: As of v0.45.0 of cosmos SDK, all modules need to be here. - app.MM.SetOrderBeginBlockers( - app.akashBeginBlockModules()..., - ) - app.MM.SetOrderEndBlockers( - app.akashEndBlockModules()..., - ) + // NOTE: capability module's begin-blocker must come before any modules using capabilities (e.g. IBC) - // NOTE: The genutils module must occur after staking so that pools are - // properly initialized with tokens from genesis accounts. - app.MM.SetOrderInitGenesis( - app.akashInitGenesisOrder()..., + // Upgrades from v0.50.x onwards happen in pre block + app.MM.SetOrderPreBlockers( + upgradetypes.ModuleName, + authtypes.ModuleName, ) - app.MM.RegisterInvariants(&app.Keepers.Cosmos.Crisis) - app.MM.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino) - app.MM.RegisterServices(app.Configurator) + // Tell the app's module manager how to set the order of BeginBlockers, which are run at the beginning of every block. + app.MM.SetOrderBeginBlockers(orderBeginBlockers(app.MM.ModuleNames())...) + app.MM.SetOrderInitGenesis(OrderInitGenesis(app.MM.ModuleNames())...) - utypes.IterateMigrations(func(module string, version uint64, initfn utypes.NewMigrationFn) { - migrator := initfn(utypes.NewMigrator(app.appCodec, app.skeys[module])) - if err := app.Configurator.RegisterMigration(module, version, migrator.GetHandler()); err != nil { - panic(err) - } - }) - - // add test gRPC service for testing gRPC queries in isolation - testdata.RegisterQueryServer(app.GRPCQueryRouter(), testdata.QueryImpl{}) - - app.sm = module.NewSimulationManager( - append([]module.AppModuleSimulation{ - auth.NewAppModule(appCodec, app.Keepers.Cosmos.Acct, authsims.RandomGenesisAccounts), - authzmodule.NewAppModule(appCodec, app.Keepers.Cosmos.Authz, app.Keepers.Cosmos.Acct, app.Keepers.Cosmos.Bank, app.interfaceRegistry), - bank.NewAppModule(appCodec, app.Keepers.Cosmos.Bank, app.Keepers.Cosmos.Acct), - feegrantmodule.NewAppModule(appCodec, app.Keepers.Cosmos.Acct, app.Keepers.Cosmos.Bank, app.Keepers.Cosmos.FeeGrant, app.interfaceRegistry), - capability.NewAppModule(appCodec, *app.Keepers.Cosmos.Cap), - gov.NewAppModule(appCodec, app.Keepers.Cosmos.Gov, app.Keepers.Cosmos.Acct, app.Keepers.Cosmos.Bank), - mint.NewAppModule(appCodec, app.Keepers.Cosmos.Mint, app.Keepers.Cosmos.Acct), - // todo akash-network/support#4 - // mint.NewAppModule(appCodec, app.Keepers.Cosmos.Mint, app.Keepers.Cosmos.Acct, nil), - staking.NewAppModule(appCodec, *app.Keepers.Cosmos.Staking, app.Keepers.Cosmos.Acct, app.Keepers.Cosmos.Bank), - distr.NewAppModule(appCodec, app.Keepers.Cosmos.Distr, app.Keepers.Cosmos.Acct, app.Keepers.Cosmos.Bank, *app.Keepers.Cosmos.Staking), - slashing.NewAppModule(appCodec, app.Keepers.Cosmos.Slashing, app.Keepers.Cosmos.Acct, app.Keepers.Cosmos.Bank, *app.Keepers.Cosmos.Staking), - params.NewAppModule(app.Keepers.Cosmos.Params), - evidence.NewAppModule(app.Keepers.Cosmos.Evidence), - ibc.NewAppModule(app.Keepers.Cosmos.IBC), - transferModule, - }, - app.akashSimModules()..., - )..., - ) + app.Configurator = module.NewConfigurator(app.AppCodec(), app.MsgServiceRouter(), app.GRPCQueryRouter()) + err := app.MM.RegisterServices(app.Configurator) + if err != nil { + panic(err) + } + + // register the upgrade handler + if err := app.registerUpgradeHandlers(); err != nil { + panic(err) + } + app.sm = module.NewSimulationManager(appSimModules(app, encodingConfig)...) app.sm.RegisterStoreDecoders() - // initialize stores - app.MountKVStores(app.skeys.Keys()) - app.MountTransientStores(tkeys) - app.MountMemoryStores(memkeys) + autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.MM.Modules)) - // initialize BaseApp - app.SetInitChainer(app.InitChainer) - app.SetBeginBlocker(app.BeginBlocker) + reflectionSvc := getReflectionService() + reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc) + + // initialize stores + app.MountKVStores(app.GetKVStoreKey()) + app.MountTransientStores(app.GetTransientStoreKey()) anteOpts := HandlerOptions{ HandlerOptions: ante.HandlerOptions{ @@ -465,38 +226,101 @@ func NewApp( SignModeHandler: encodingConfig.TxConfig.SignModeHandler(), SigGasConsumer: ante.DefaultSigVerificationGasConsumer, }, - CDC: app.appCodec, - AStakingKeeper: app.Keepers.Akash.Staking, - GovKeeper: &app.Keepers.Cosmos.Gov, - AGovKeeper: app.Keepers.Akash.Gov, + CDC: app.cdc, + GovKeeper: app.Keepers.Cosmos.Gov, } - handler, err := NewAnteHandler(anteOpts) + anteHandler, err := NewAnteHandler(anteOpts) if err != nil { panic(err) } - app.SetAnteHandler(handler) - app.SetEndBlocker(app.EndBlocker) + app.SetPrepareProposal(baseapp.NoOpPrepareProposal()) - // register the upgrade handler - if err = app.registerUpgradeHandlers(); err != nil { - panic(err) - } + // we use a no-op ProcessProposal, this way, we accept all proposals in avoidance + // of liveness failures due to Prepare / Process inconsistency. In other words, + // this ProcessProposal always returns ACCEPT. + app.SetProcessProposal(baseapp.NoOpProcessProposal()) + + // initialize BaseApp + app.SetInitChainer(app.InitChainer) + app.SetPreBlocker(app.PreBlocker) + app.SetBeginBlocker(app.BeginBlocker) + app.SetAnteHandler(anteHandler) + app.SetEndBlocker(app.EndBlocker) + app.SetPrecommiter(app.Precommitter) + app.SetPrepareCheckStater(app.PrepareCheckStater) if loadLatest { if err := app.LoadLatestVersion(); err != nil { - tmos.Exit("app initialization:" + err.Error()) + cmos.Exit("app initialization:" + err.Error()) } } - app.Keepers.Cosmos.ScopedIBCKeeper = scopedIBCKeeper - app.Keepers.Cosmos.ScopedTransferKeeper = scopedTransferKeeper - return app } -func getGenesisTime(appOpts servertypes.AppOptions, homePath string) time.Time { // nolint: unused,deadcode +// orderBeginBlockers returns the order of BeginBlockers, by module name. +func orderBeginBlockers(_ []string) []string { + return []string{ + upgradetypes.ModuleName, + banktypes.ModuleName, + paramstypes.ModuleName, + deploymenttypes.ModuleName, + govtypes.ModuleName, + providertypes.ModuleName, + certtypes.ModuleName, + markettypes.ModuleName, + audittypes.ModuleName, + genutiltypes.ModuleName, + vestingtypes.ModuleName, + authtypes.ModuleName, + authz.ModuleName, + taketypes.ModuleName, + emodule.ModuleName, + minttypes.ModuleName, + distrtypes.ModuleName, + slashingtypes.ModuleName, + evidencetypes.ModuleName, + stakingtypes.ModuleName, + transfertypes.ModuleName, + consensusparamtypes.ModuleName, + ibctm.ModuleName, + ibchost.ModuleName, + feegrant.ModuleName, + } +} + +// OrderEndBlockers returns EndBlockers (crisis, govtypes, staking) with no relative order. +func OrderEndBlockers(_ []string) []string { + return []string{ + govtypes.ModuleName, + stakingtypes.ModuleName, + upgradetypes.ModuleName, + banktypes.ModuleName, + paramstypes.ModuleName, + deploymenttypes.ModuleName, + providertypes.ModuleName, + certtypes.ModuleName, + markettypes.ModuleName, + audittypes.ModuleName, + genutiltypes.ModuleName, + vestingtypes.ModuleName, + authtypes.ModuleName, + authz.ModuleName, + taketypes.ModuleName, + emodule.ModuleName, + minttypes.ModuleName, + distrtypes.ModuleName, + slashingtypes.ModuleName, + evidencetypes.ModuleName, + transfertypes.ModuleName, + ibchost.ModuleName, + feegrant.ModuleName, + } +} + +func getGenesisTime(appOpts servertypes.AppOptions, homePath string) time.Time { // nolint: unused if v := appOpts.Get("GenesisTime"); v != nil { // in tests, GenesisTime is supplied using appOpts genTime, ok := v.(time.Time) @@ -514,64 +338,89 @@ func getGenesisTime(appOpts servertypes.AppOptions, homePath string) time.Time { return genDoc.GenesisTime } -// MakeCodecs constructs the *std.Codec and *codec.LegacyAmino instances used by -// simapp. It is useful for tests and clients who do not want to construct the -// full simapp -func MakeCodecs() (codec.Codec, *codec.LegacyAmino) { - config := MakeEncodingConfig() - return config.Marshaler, config.Amino -} - // Name returns the name of the App func (app *AkashApp) Name() string { return app.BaseApp.Name() } // InitChainer application update at chain initialization -func (app *AkashApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { - var genesisState simapp.GenesisState +func (app *AkashApp) InitChainer(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) { + var genesisState GenesisState if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil { panic(err) } - app.Keepers.Cosmos.Upgrade.SetModuleVersionMap(ctx, app.MM.GetVersionMap()) - return app.MM.InitGenesis(ctx, app.appCodec, genesisState) + err := app.Keepers.Cosmos.Upgrade.SetModuleVersionMap(ctx, app.MM.GetVersionMap()) + if err != nil { + panic(err) + } + + return app.MM.InitGenesis(ctx, app.cdc, genesisState) +} + +// PreBlocker application updates before each begin block. +func (app *AkashApp) PreBlocker(ctx sdk.Context, _ *abci.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error) { + // Set gas meter to the free gas meter. + // This is because there is currently non-deterministic gas usage in the + // pre-blocker, e.g. due to hydration of in-memory data structures. + // + // Note that we don't need to reset the gas meter after the pre-blocker + // because Go is pass by value. + ctx = ctx.WithGasMeter(storetypes.NewInfiniteGasMeter()) + + return app.MM.PreBlock(ctx) } // BeginBlocker is a function in which application updates every begin block -func (app *AkashApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { +func (app *AkashApp) BeginBlocker(ctx sdk.Context) (sdk.BeginBlock, error) { if patch, exists := utypes.GetHeightPatchesList()[ctx.BlockHeight()]; exists { app.Logger().Info(fmt.Sprintf("found patch %s for current height %d. applying...", patch.Name(), ctx.BlockHeight())) patch.Begin(ctx, &app.Keepers) app.Logger().Info(fmt.Sprintf("patch %s applied successfully at height %d", patch.Name(), ctx.BlockHeight())) } - return app.MM.BeginBlock(ctx, req) + return app.MM.BeginBlock(ctx) } // EndBlocker is a function in which application updates every end block -func (app *AkashApp) EndBlocker( - ctx sdk.Context, req abci.RequestEndBlock, -) abci.ResponseEndBlock { - return app.MM.EndBlock(ctx, req) +func (app *AkashApp) EndBlocker(ctx sdk.Context) (sdk.EndBlock, error) { + return app.MM.EndBlock(ctx) +} + +// Precommitter application updates before the commital of a block after all transactions have been delivered. +func (app *AkashApp) Precommitter(ctx sdk.Context) { + if err := app.MM.Precommit(ctx); err != nil { + panic(err) + } +} + +func (app *AkashApp) PrepareCheckStater(ctx sdk.Context) { + if err := app.MM.PrepareCheckState(ctx); err != nil { + panic(err) + } } // LegacyAmino returns AkashApp's amino codec. func (app *AkashApp) LegacyAmino() *codec.LegacyAmino { - return app.cdc + return app.aminoCdc } // AppCodec returns AkashApp's app codec. func (app *AkashApp) AppCodec() codec.Codec { - return app.appCodec + return app.cdc +} + +// TxConfig returns SimApp's TxConfig +func (app *AkashApp) TxConfig() client.TxConfig { + return app.txConfig } // ModuleAccountAddrs returns all the app's module account addresses. func (app *AkashApp) ModuleAccountAddrs() map[string]bool { - return MacAddrs() + return ModuleAccountAddrs() } // BlockedAddrs returns all the app's module account addresses that are not // allowed to receive external tokens. func (app *AkashApp) BlockedAddrs() map[string]bool { - perms := MacPerms() + perms := ModuleAccountAddrs() blockedAddrs := make(map[string]bool) for acc := range perms { blockedAddrs[authtypes.NewModuleAddress(acc).String()] = !allowedReceivingModAcc[acc] @@ -585,16 +434,6 @@ func (app *AkashApp) InterfaceRegistry() codectypes.InterfaceRegistry { return app.interfaceRegistry } -// GetKey returns the KVStoreKey for the provided store key. -func (app *AkashApp) GetKey(module string) *sdk.KVStoreKey { - return app.skeys[module] -} - -// GetTKey returns the TransientStoreKey for the provided store key. -func (app *AkashApp) GetTKey(module string) *sdk.TransientStoreKey { - return app.tkeys[module] -} - // GetSubspace returns a param subspace for a given module name. func (app *AkashApp) GetSubspace(moduleName string) paramstypes.Subspace { subspace, _ := app.Keepers.Cosmos.Params.GetSubspace(moduleName) @@ -609,33 +448,42 @@ func (app *AkashApp) SimulationManager() *module.SimulationManager { // RegisterAPIRoutes registers all application module routes with the provided // API server. func (app *AkashApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { - clientCtx := apiSvr.ClientCtx - rpc.RegisterRoutes(clientCtx, apiSvr.Router) - // Register legacy tx routes - authrest.RegisterTxRoutes(clientCtx, apiSvr.Router) + cctx := apiSvr.ClientCtx + // Register new tx routes from grpc-gateway - authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + authtx.RegisterGRPCGatewayRoutes(cctx, apiSvr.GRPCGatewayRouter) // Register new tendermint queries routes from grpc-gateway. - tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + cmtservice.RegisterGRPCGatewayRoutes(cctx, apiSvr.GRPCGatewayRouter) // Register legacy and grpc-gateway routes for all modules. - ModuleBasics().RegisterRESTRoutes(clientCtx, apiSvr.Router) - ModuleBasics().RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + ModuleBasics().RegisterGRPCGatewayRoutes(cctx, apiSvr.GRPCGatewayRouter) + + // Register node gRPC service for grpc-gateway. + nodeservice.RegisterGRPCGatewayRoutes(cctx, apiSvr.GRPCGatewayRouter) // register swagger API from root so that other applications can override easily if apiConfig.Swagger { - RegisterSwaggerAPI(clientCtx, apiSvr.Router) + RegisterSwaggerAPI(cctx, apiSvr.Router) } } // RegisterTxService implements the Application.RegisterTxService method. func (app *AkashApp) RegisterTxService(clientCtx client.Context) { - authtx.RegisterTxService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.BaseApp.Simulate, app.interfaceRegistry) + authtx.RegisterTxService(app.GRPCQueryRouter(), clientCtx, app.Simulate, app.interfaceRegistry) } // RegisterTendermintService implements the Application.RegisterTendermintService method. -func (app *AkashApp) RegisterTendermintService(clientCtx client.Context) { - tmservice.RegisterTendermintService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.interfaceRegistry) +func (app *AkashApp) RegisterTendermintService(cctx client.Context) { + cmtservice.RegisterTendermintService( + cctx, + app.GRPCQueryRouter(), + app.interfaceRegistry, + app.Query) +} + +// RegisterNodeService registers the node gRPC Query service. +func (app *AkashApp) RegisterNodeService(cctx client.Context, cfg config.Config) { + nodeservice.RegisterNodeService(cctx, app.GRPCQueryRouter(), cfg) } // RegisterSwaggerAPI registers swagger route with API Server @@ -646,6 +494,7 @@ func RegisterSwaggerAPI(_ client.Context, rtr *mux.Router) { } staticServer := http.FileServer(statikFS) + rtr.PathPrefix("/static/").Handler(http.StripPrefix("/static/", staticServer)) rtr.PathPrefix("/swagger/").Handler(http.StripPrefix("/swagger/", staticServer)) } @@ -654,24 +503,30 @@ func (app *AkashApp) LoadHeight(height int64) error { return app.LoadVersion(height) } -// initParamsKeeper init params keeper and its subspaces -func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, - tkey sdk.StoreKey, -) paramskeeper.Keeper { - paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey) - - paramsKeeper.Subspace(authtypes.ModuleName) - paramsKeeper.Subspace(banktypes.ModuleName) - paramsKeeper.Subspace(stakingtypes.ModuleName) - paramsKeeper.Subspace(minttypes.ModuleName) - paramsKeeper.Subspace(distrtypes.ModuleName) - paramsKeeper.Subspace(slashingtypes.ModuleName) - paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govtypes.ParamKeyTable()) - paramsKeeper.Subspace(crisistypes.ModuleName) - paramsKeeper.Subspace(ibctransfertypes.ModuleName) - paramsKeeper.Subspace(ibchost.ModuleName) - paramsKeeper.Subspace(icacontrollertypes.SubModuleName) - paramsKeeper.Subspace(icahosttypes.SubModuleName) - - return akashSubspaces(paramsKeeper) +// cache the reflectionService to save us time within tests. +var cachedReflectionService *runtimeservices.ReflectionService + +func getReflectionService() *runtimeservices.ReflectionService { + if cachedReflectionService != nil { + return cachedReflectionService + } + reflectionSvc, err := runtimeservices.NewReflectionService() + if err != nil { + panic(err) + } + cachedReflectionService = reflectionSvc + return reflectionSvc +} + +// NewProposalContext returns a context with a branched version of the state +// that is safe to query during ProcessProposal. +func (app *AkashApp) NewProposalContext(header tmproto.Header) sdk.Context { + // use custom query multistore if provided + ms := app.CommitMultiStore().CacheMultiStore() + ctx := sdk.NewContext(ms, header, false, app.Logger()). + WithBlockGasMeter(storetypes.NewInfiniteGasMeter()). + WithBlockHeader(header) + ctx = ctx.WithConsensusParams(app.GetConsensusParams(ctx)) + + return ctx } diff --git a/app/app_configure.go b/app/app_configure.go index 4646c214c9..f59ebcabde 100644 --- a/app/app_configure.go +++ b/app/app_configure.go @@ -1,55 +1,36 @@ package app import ( + evidencetypes "cosmossdk.io/x/evidence/types" + "cosmossdk.io/x/feegrant" + upgradetypes "cosmossdk.io/x/upgrade/types" "github.com/cosmos/cosmos-sdk/types/module" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" "github.com/cosmos/cosmos-sdk/x/authz" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types" crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" - "github.com/cosmos/cosmos-sdk/x/feegrant" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" - paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - - transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host" - - audittypes "github.com/akash-network/akash-api/go/node/audit/v1beta3" - certtypes "github.com/akash-network/akash-api/go/node/cert/v1beta3" - deploymenttypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - escrowtypes "github.com/akash-network/akash-api/go/node/escrow/v1beta3" - inflationtypes "github.com/akash-network/akash-api/go/node/inflation/v1beta3" - markettypes "github.com/akash-network/akash-api/go/node/market/v1beta4" - providertypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" - taketypes "github.com/akash-network/akash-api/go/node/take/v1beta3" - - "github.com/akash-network/node/x/audit" - akeeper "github.com/akash-network/node/x/audit/keeper" - "github.com/akash-network/node/x/cert" - ckeeper "github.com/akash-network/node/x/cert/keeper" - "github.com/akash-network/node/x/deployment" - "github.com/akash-network/node/x/escrow" - ekeeper "github.com/akash-network/node/x/escrow/keeper" - agov "github.com/akash-network/node/x/gov" - agovkeeper "github.com/akash-network/node/x/gov/keeper" - "github.com/akash-network/node/x/inflation" - ikeeper "github.com/akash-network/node/x/inflation/keeper" - "github.com/akash-network/node/x/market" - mhooks "github.com/akash-network/node/x/market/hooks" - "github.com/akash-network/node/x/provider" - astaking "github.com/akash-network/node/x/staking" - astakingkeeper "github.com/akash-network/node/x/staking/keeper" - "github.com/akash-network/node/x/take" - tkeeper "github.com/akash-network/node/x/take/keeper" + transfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" + ibchost "github.com/cosmos/ibc-go/v10/modules/core/exported" + + audittypes "pkg.akt.dev/go/node/audit/v1" + taketypes "pkg.akt.dev/go/node/take/v1" + + "pkg.akt.dev/node/x/audit" + "pkg.akt.dev/node/x/cert" + "pkg.akt.dev/node/x/deployment" + "pkg.akt.dev/node/x/escrow" + "pkg.akt.dev/node/x/market" + "pkg.akt.dev/node/x/provider" + "pkg.akt.dev/node/x/take" ) func akashModuleBasics() []module.AppModuleBasic { @@ -61,231 +42,17 @@ func akashModuleBasics() []module.AppModuleBasic { provider.AppModuleBasic{}, audit.AppModuleBasic{}, cert.AppModuleBasic{}, - inflation.AppModuleBasic{}, - astaking.AppModuleBasic{}, - agov.AppModuleBasic{}, - } -} - -func akashSubspaces(k paramskeeper.Keeper) paramskeeper.Keeper { - k.Subspace(deployment.ModuleName) - k.Subspace(market.ModuleName) - k.Subspace(inflation.ModuleName) - k.Subspace(astaking.ModuleName) - k.Subspace(agov.ModuleName) - k.Subspace(take.ModuleName) - - return k -} - -func (app *AkashApp) setAkashKeepers() { - app.Keepers.Akash.Take = tkeeper.NewKeeper( - app.appCodec, - app.skeys[take.ModuleName], - app.GetSubspace(take.ModuleName), - ) - - app.Keepers.Akash.Escrow = ekeeper.NewKeeper( - app.appCodec, - app.skeys[escrow.ModuleName], - app.Keepers.Cosmos.Bank, - app.Keepers.Akash.Take, - app.Keepers.Cosmos.Distr, - app.Keepers.Cosmos.Authz, - ) - - app.Keepers.Akash.Deployment = deployment.NewKeeper( - app.appCodec, - app.skeys[deployment.ModuleName], - app.GetSubspace(deployment.ModuleName), - app.Keepers.Akash.Escrow, - ) - - app.Keepers.Akash.Market = market.NewKeeper( - app.appCodec, - app.skeys[market.ModuleName], - app.GetSubspace(market.ModuleName), - app.Keepers.Akash.Escrow, - ) - - hook := mhooks.New( - app.Keepers.Akash.Deployment, - app.Keepers.Akash.Market, - ) - - app.Keepers.Akash.Escrow.AddOnAccountClosedHook(hook.OnEscrowAccountClosed) - app.Keepers.Akash.Escrow.AddOnPaymentClosedHook(hook.OnEscrowPaymentClosed) - - app.Keepers.Akash.Provider = provider.NewKeeper( - app.appCodec, - app.skeys[provider.ModuleName], - ) - - app.Keepers.Akash.Audit = akeeper.NewKeeper( - app.appCodec, - app.skeys[audit.ModuleName], - ) - - app.Keepers.Akash.Cert = ckeeper.NewKeeper( - app.appCodec, - app.skeys[cert.ModuleName], - ) - - app.Keepers.Akash.Inflation = ikeeper.NewKeeper( - app.appCodec, - app.skeys[inflation.ModuleName], - app.GetSubspace(inflation.ModuleName), - ) - - app.Keepers.Akash.Staking = astakingkeeper.NewKeeper( - app.appCodec, - app.skeys[astaking.ModuleName], - app.GetSubspace(astaking.ModuleName), - ) - - app.Keepers.Akash.Gov = agovkeeper.NewKeeper( - app.appCodec, - app.skeys[agov.ModuleName], - app.GetSubspace(agov.ModuleName), - ) -} - -func (app *AkashApp) akashAppModules() []module.AppModule { - return []module.AppModule{ - take.NewAppModule( - app.appCodec, - app.Keepers.Akash.Take, - ), - - escrow.NewAppModule( - app.appCodec, - app.Keepers.Akash.Escrow, - ), - - deployment.NewAppModule( - app.appCodec, - app.Keepers.Akash.Deployment, - app.Keepers.Akash.Market, - app.Keepers.Akash.Escrow, - app.Keepers.Cosmos.Bank, - app.Keepers.Cosmos.Authz, - ), - - market.NewAppModule( - app.appCodec, - app.Keepers.Akash.Market, - app.Keepers.Akash.Escrow, - app.Keepers.Akash.Audit, - app.Keepers.Akash.Deployment, - app.Keepers.Akash.Provider, - app.Keepers.Cosmos.Bank, - ), - - provider.NewAppModule( - app.appCodec, - app.Keepers.Akash.Provider, - app.Keepers.Cosmos.Bank, - app.Keepers.Akash.Market, - ), - - audit.NewAppModule( - app.appCodec, - app.Keepers.Akash.Audit, - ), - - cert.NewAppModule( - app.appCodec, - app.Keepers.Akash.Cert, - ), - - inflation.NewAppModule( - app.appCodec, - app.Keepers.Akash.Inflation, - ), - - astaking.NewAppModule( - app.appCodec, - app.Keepers.Akash.Staking, - ), - - agov.NewAppModule( - app.appCodec, - app.Keepers.Akash.Gov, - ), } } -// akashBeginBlockModules returns all end block modules. -func (app *AkashApp) akashBeginBlockModules() []string { +// OrderInitGenesis returns module names in order for init genesis calls. +// NOTE: The genutils module must occur after staking so that pools are +// properly initialized with tokens from genesis accounts. +// NOTE: Capability module must occur first so that it can initialize any capabilities +// so that other modules that want to create or claim capabilities afterwards in InitChain +// can do so safely. +func OrderInitGenesis(_ []string) []string { return []string{ - upgradetypes.ModuleName, - capabilitytypes.ModuleName, - banktypes.ModuleName, - paramstypes.ModuleName, - deploymenttypes.ModuleName, - govtypes.ModuleName, - agov.ModuleName, - providertypes.ModuleName, - certtypes.ModuleName, - markettypes.ModuleName, - audittypes.ModuleName, - genutiltypes.ModuleName, - vestingtypes.ModuleName, - crisistypes.ModuleName, - inflationtypes.ModuleName, - authtypes.ModuleName, - authz.ModuleName, - taketypes.ModuleName, - escrowtypes.ModuleName, - minttypes.ModuleName, - distrtypes.ModuleName, - slashingtypes.ModuleName, - evidencetypes.ModuleName, - stakingtypes.ModuleName, - astaking.ModuleName, - transfertypes.ModuleName, - ibchost.ModuleName, - feegrant.ModuleName, - } -} - -// akashEndBlockModules returns all end block modules. -func (app *AkashApp) akashEndBlockModules() []string { - return []string{ - crisistypes.ModuleName, - govtypes.ModuleName, - agov.ModuleName, - stakingtypes.ModuleName, - astaking.ModuleName, - upgradetypes.ModuleName, - capabilitytypes.ModuleName, - banktypes.ModuleName, - paramstypes.ModuleName, - deploymenttypes.ModuleName, - providertypes.ModuleName, - certtypes.ModuleName, - markettypes.ModuleName, - audittypes.ModuleName, - genutiltypes.ModuleName, - vestingtypes.ModuleName, - inflationtypes.ModuleName, - authtypes.ModuleName, - authz.ModuleName, - taketypes.ModuleName, - escrowtypes.ModuleName, - minttypes.ModuleName, - distrtypes.ModuleName, - slashingtypes.ModuleName, - evidencetypes.ModuleName, - transfertypes.ModuleName, - ibchost.ModuleName, - feegrant.ModuleName, - } -} - -func (app *AkashApp) akashInitGenesisOrder() []string { - return []string{ - capabilitytypes.ModuleName, authtypes.ModuleName, authz.ModuleName, banktypes.ModuleName, @@ -302,6 +69,7 @@ func (app *AkashApp) akashInitGenesisOrder() []string { ibchost.ModuleName, evidencetypes.ModuleName, transfertypes.ModuleName, + consensustypes.ModuleName, feegrant.ModuleName, cert.ModuleName, taketypes.ModuleName, @@ -309,53 +77,6 @@ func (app *AkashApp) akashInitGenesisOrder() []string { deployment.ModuleName, provider.ModuleName, market.ModuleName, - inflation.ModuleName, - astaking.ModuleName, - agov.ModuleName, genutiltypes.ModuleName, } } - -func (app *AkashApp) akashSimModules() []module.AppModuleSimulation { - return []module.AppModuleSimulation{ - take.NewAppModuleSimulation( - app.Keepers.Akash.Take, - ), - - deployment.NewAppModuleSimulation( - app.Keepers.Akash.Deployment, - app.Keepers.Cosmos.Acct, - app.Keepers.Cosmos.Bank, - ), - - market.NewAppModuleSimulation( - app.Keepers.Akash.Market, - app.Keepers.Cosmos.Acct, - app.Keepers.Akash.Deployment, - app.Keepers.Akash.Provider, - app.Keepers.Cosmos.Bank, - ), - - provider.NewAppModuleSimulation( - app.Keepers.Akash.Provider, - app.Keepers.Cosmos.Acct, - app.Keepers.Cosmos.Bank, - ), - - cert.NewAppModuleSimulation( - app.Keepers.Akash.Cert, - ), - - inflation.NewAppModuleSimulation( - app.Keepers.Akash.Inflation, - ), - - astaking.NewAppModuleSimulation( - app.Keepers.Akash.Staking, - ), - - agov.NewAppModuleSimulation( - app.Keepers.Akash.Gov, - ), - } -} diff --git a/app/app_test.go b/app/app_test.go deleted file mode 100644 index 908e69f4a4..0000000000 --- a/app/app_test.go +++ /dev/null @@ -1,42 +0,0 @@ -package app - -import ( - "encoding/json" - "os" - "testing" - - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/libs/log" - dbm "github.com/tendermint/tm-db" - - abci "github.com/tendermint/tendermint/abci/types" -) - -func TestAppExport(t *testing.T) { - db := dbm.NewMemDB() - app1 := NewApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), - db, nil, true, 0, map[int64]bool{}, DefaultHome, OptsWithGenesisTime(0)) - - for acc := range MacPerms() { - require.Equal(t, !allowedReceivingModAcc[acc], app1.Keepers.Cosmos.Bank.BlockedAddr(app1.Keepers.Cosmos.Acct.GetModuleAddress(acc)), - "ensure that blocked addresses are properly set in bank keeper") - } - - genesisState := NewDefaultGenesisState() - stateBytes, err := json.MarshalIndent(genesisState, "", " ") - require.NoError(t, err) - - // Initialize the chain - app1.InitChain( - abci.RequestInitChain{ - Validators: []abci.ValidatorUpdate{}, - AppStateBytes: stateBytes, - }, - ) - app1.Commit() - - // Making a new app object with the db, so that initchain hasn't been called - app2 := NewApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, 0, map[int64]bool{}, DefaultHome, OptsWithGenesisTime(0)) - _, err = app2.ExportAppStateAndValidators(false, []string{}) - require.NoError(t, err, "ExportAppStateAndValidators should not have an error") -} diff --git a/app/config.go b/app/config.go index 4ead6c6641..527ff0aa96 100644 --- a/app/config.go +++ b/app/config.go @@ -1,61 +1,29 @@ package app import ( - simparams "github.com/cosmos/cosmos-sdk/simapp/params" - "github.com/cosmos/cosmos-sdk/std" - "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" + "cosmossdk.io/x/evidence" + feegrantmodule "cosmossdk.io/x/feegrant/module" + "cosmossdk.io/x/upgrade" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/auth" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/auth/vesting" - "github.com/cosmos/cosmos-sdk/x/authz" - authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module" "github.com/cosmos/cosmos-sdk/x/bank" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/cosmos-sdk/x/capability" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + "github.com/cosmos/cosmos-sdk/x/consensus" "github.com/cosmos/cosmos-sdk/x/crisis" distr "github.com/cosmos/cosmos-sdk/x/distribution" - distrclient "github.com/cosmos/cosmos-sdk/x/distribution/client" - distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - "github.com/cosmos/cosmos-sdk/x/evidence" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" - "github.com/cosmos/cosmos-sdk/x/feegrant" - feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module" "github.com/cosmos/cosmos-sdk/x/genutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/cosmos/cosmos-sdk/x/gov" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govclient "github.com/cosmos/cosmos-sdk/x/gov/client" "github.com/cosmos/cosmos-sdk/x/mint" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" "github.com/cosmos/cosmos-sdk/x/params" paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" - paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/cosmos/cosmos-sdk/x/slashing" - slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" "github.com/cosmos/cosmos-sdk/x/staking" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/cosmos/cosmos-sdk/x/upgrade" - upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer" - ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - ibc "github.com/cosmos/ibc-go/v4/modules/core" - ibcclient "github.com/cosmos/ibc-go/v4/modules/core/02-client/client" - ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host" - - appparams "github.com/akash-network/node/app/params" - "github.com/akash-network/node/x/audit" - "github.com/akash-network/node/x/cert" - "github.com/akash-network/node/x/deployment" - "github.com/akash-network/node/x/escrow" - agov "github.com/akash-network/node/x/gov" - "github.com/akash-network/node/x/inflation" - "github.com/akash-network/node/x/market" - "github.com/akash-network/node/x/provider" - astaking "github.com/akash-network/node/x/staking" - "github.com/akash-network/node/x/take" + "github.com/cosmos/ibc-go/v10/modules/apps/transfer" + ibc "github.com/cosmos/ibc-go/v10/modules/core" + ibclightclient "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" ) var mbasics = module.NewBasicManager( @@ -65,26 +33,27 @@ var mbasics = module.NewBasicManager( // authorizations authzmodule.AppModuleBasic{}, // genesis utilities - genutil.AppModuleBasic{}, + genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator), // tokens, token balance. bank.AppModuleBasic{}, - capability.AppModuleBasic{}, // validator staking staking.AppModuleBasic{}, // inflation mint.AppModuleBasic{}, - // distribution of fess and inflation + // distribution of fees and inflation distr.AppModuleBasic{}, // governance functionality (voting) gov.NewAppModuleBasic( - paramsclient.ProposalHandler, distrclient.ProposalHandler, - upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler, - ibcclient.UpdateClientProposalHandler, ibcclient.UpgradeProposalHandler, + []govclient.ProposalHandler{ + paramsclient.ProposalHandler, + }, ), // chain parameters params.AppModuleBasic{}, + consensus.AppModuleBasic{}, crisis.AppModuleBasic{}, slashing.AppModuleBasic{}, + ibclightclient.AppModuleBasic{}, ibc.AppModuleBasic{}, upgrade.AppModuleBasic{}, evidence.AppModuleBasic{}, @@ -101,68 +70,3 @@ var mbasics = module.NewBasicManager( func ModuleBasics() module.BasicManager { return mbasics } - -// MakeEncodingConfig creates an EncodingConfig for testing -func MakeEncodingConfig() simparams.EncodingConfig { - encodingConfig := appparams.MakeEncodingConfig() - - std.RegisterLegacyAminoCodec(encodingConfig.Amino) - std.RegisterInterfaces(encodingConfig.InterfaceRegistry) - mbasics.RegisterLegacyAminoCodec(encodingConfig.Amino) - mbasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) - - return encodingConfig -} - -func (m ModulesStoreKeys) Keys() map[string]*sdk.KVStoreKey { - res := make(map[string]*sdk.KVStoreKey) - - for _, key := range m { - res[key.Name()] = key - } - - return res -} - -func modulesStoreKeys() ModulesStoreKeys { - return ModulesStoreKeys{ - authtypes.ModuleName: types.NewKVStoreKey(authtypes.StoreKey), - feegrant.ModuleName: types.NewKVStoreKey(feegrant.StoreKey), - authz.ModuleName: types.NewKVStoreKey(authzkeeper.StoreKey), - banktypes.ModuleName: types.NewKVStoreKey(banktypes.StoreKey), - stakingtypes.ModuleName: types.NewKVStoreKey(stakingtypes.StoreKey), - minttypes.ModuleName: types.NewKVStoreKey(minttypes.StoreKey), - distrtypes.ModuleName: types.NewKVStoreKey(distrtypes.StoreKey), - slashingtypes.ModuleName: types.NewKVStoreKey(slashingtypes.StoreKey), - govtypes.ModuleName: types.NewKVStoreKey(govtypes.StoreKey), - paramstypes.ModuleName: types.NewKVStoreKey(paramstypes.StoreKey), - ibchost.ModuleName: types.NewKVStoreKey(ibchost.StoreKey), - upgradetypes.ModuleName: types.NewKVStoreKey(upgradetypes.StoreKey), - evidencetypes.ModuleName: types.NewKVStoreKey(evidencetypes.StoreKey), - ibctransfertypes.ModuleName: types.NewKVStoreKey(ibctransfertypes.StoreKey), - capabilitytypes.ModuleName: types.NewKVStoreKey(capabilitytypes.StoreKey), - // akash modules - take.ModuleName: types.NewKVStoreKey(take.StoreKey), - escrow.ModuleName: types.NewKVStoreKey(escrow.StoreKey), - deployment.ModuleName: types.NewKVStoreKey(deployment.StoreKey), - market.ModuleName: types.NewKVStoreKey(market.StoreKey), - provider.ModuleName: types.NewKVStoreKey(provider.StoreKey), - audit.ModuleName: types.NewKVStoreKey(audit.StoreKey), - cert.ModuleName: types.NewKVStoreKey(cert.StoreKey), - inflation.ModuleName: types.NewKVStoreKey(inflation.StoreKey), - astaking.ModuleName: types.NewKVStoreKey(astaking.StoreKey), - agov.ModuleName: types.NewKVStoreKey(agov.StoreKey), - } -} - -func modulesTransientKeys() ModulesTransientKeys { - return ModulesTransientKeys{ - paramstypes.ModuleName: sdk.NewTransientStoreKey(paramstypes.TStoreKey), - } -} - -func modulesMemoryKeys() ModulesMemoryKeys { - return ModulesMemoryKeys{ - capabilitytypes.ModuleName: types.NewMemoryStoreKey(capabilitytypes.MemStoreKey), - } -} diff --git a/app/decorators/gov_filter.go b/app/decorators/gov_filter.go deleted file mode 100644 index ed05630e15..0000000000 --- a/app/decorators/gov_filter.go +++ /dev/null @@ -1,92 +0,0 @@ -package decorators - -import ( - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/x/authz" - govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - - agovkeeper "github.com/akash-network/node/x/gov/keeper" -) - -type GovPreventSpamDecorator struct { - cdc codec.BinaryCodec - govKeeper govkeeper.Keeper - aGovKeeper agovkeeper.IKeeper -} - -func NewGovPreventSpamDecorator(cdc codec.BinaryCodec, gov govkeeper.Keeper, aGov agovkeeper.IKeeper) GovPreventSpamDecorator { - return GovPreventSpamDecorator{ - cdc: cdc, - govKeeper: gov, - aGovKeeper: aGov, - } -} - -func (gpsd GovPreventSpamDecorator) AnteHandle( - ctx sdk.Context, tx sdk.Tx, - simulate bool, next sdk.AnteHandler, -) (newCtx sdk.Context, err error) { - msgs := tx.GetMsgs() - - err = gpsd.checkSpamSubmitProposalMsg(ctx, msgs) - - if err != nil { - return ctx, err - } - - return next(ctx, tx, simulate) -} - -func (gpsd GovPreventSpamDecorator) checkSpamSubmitProposalMsg(ctx sdk.Context, msgs []sdk.Msg) error { - validMsg := func(m sdk.Msg) error { - if msg, ok := m.(*govtypes.MsgSubmitProposal); ok { - // prevent spam gov msg - depositParams := gpsd.govKeeper.GetDepositParams(ctx) - aDepositParams := gpsd.aGovKeeper.GetDepositParams(ctx) - - minimumInitialDeposit := gpsd.calcMinimumInitialDeposit(aDepositParams.MinInitialDepositRate, depositParams.MinDeposit) - if msg.InitialDeposit.IsAllLT(minimumInitialDeposit) { - return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "not enough initial deposit. required: %v", minimumInitialDeposit) - } - } - return nil - } - - // Check every msg in the tx, if it's a MsgExec, check the inner msgs. - // If it's a MsgSubmitProposal, check the initial deposit is enough. - for _, m := range msgs { - var innerMsg sdk.Msg - if msg, ok := m.(*authz.MsgExec); ok { - for _, v := range msg.Msgs { - err := gpsd.cdc.UnpackAny(v, &innerMsg) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "cannot unmarshal authz exec msgs") - } - - err = validMsg(innerMsg) - if err != nil { - return err - } - } - } else { - err := validMsg(m) - if err != nil { - return err - } - } - } - - return nil -} - -func (gpsd GovPreventSpamDecorator) calcMinimumInitialDeposit(rate sdk.Dec, minDeposit sdk.Coins) (minimumInitialDeposit sdk.Coins) { - for _, coin := range minDeposit { - minimumInitialCoin := rate.MulInt(coin.Amount).RoundInt() - minimumInitialDeposit = minimumInitialDeposit.Add(sdk.NewCoin(coin.Denom, minimumInitialCoin)) - } - - return -} diff --git a/app/decorators/min_commision.go b/app/decorators/min_commision.go deleted file mode 100644 index 9fd47dced9..0000000000 --- a/app/decorators/min_commision.go +++ /dev/null @@ -1,107 +0,0 @@ -package decorators - -import ( - "fmt" - - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/x/authz" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - - astakingkeeper "github.com/akash-network/node/x/staking/keeper" -) - -type MinCommissionDecorator struct { - cdc codec.BinaryCodec - keeper astakingkeeper.IKeeper -} - -func NewMinCommissionDecorator(cdc codec.BinaryCodec, k astakingkeeper.IKeeper) *MinCommissionDecorator { - min := &MinCommissionDecorator{ - cdc: cdc, - keeper: k, - } - - return min -} - -func (min *MinCommissionDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { - if err := min.checkMsgs(ctx, tx.GetMsgs()); err != nil { - return ctx, err - } - - return next(ctx, tx, simulate) -} - -func (min *MinCommissionDecorator) isValidMsg(ctx sdk.Context, m sdk.Msg) error { - var rate sdk.Dec - var maxRate *sdk.Dec - - switch msg := m.(type) { - case *stakingtypes.MsgCreateValidator: - maxRate = &msg.Commission.MaxRate - rate = msg.Commission.Rate - case *stakingtypes.MsgEditValidator: - // if commission rate is nil, it means only - // other fields are affected - skip - if msg.CommissionRate == nil { - return nil - } - - rate = *msg.CommissionRate - default: - // the message is not for validator, so just skip over it - return nil - } - - minRate := min.keeper.MinCommissionRate(ctx) - - // prevent new validators joining the set with - // commission set below 5% - if rate.LT(minRate) { - return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, fmt.Sprintf("commission can't be lower than %s%%", minRate)) - } - - if maxRate != nil && maxRate.LT(minRate) { - return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, fmt.Sprintf("commission max rate can't be lower than %s%%", minRate)) - } - - return nil -} - -func (min *MinCommissionDecorator) isValidAuthz(ctx sdk.Context, execMsg *authz.MsgExec) error { - for _, v := range execMsg.Msgs { - var innerMsg sdk.Msg - err := min.cdc.UnpackAny(v, &innerMsg) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "cannot unmarshal authz exec msgs") - } - - err = min.isValidMsg(ctx, innerMsg) - if err != nil { - return err - } - } - - return nil -} - -func (min *MinCommissionDecorator) checkMsgs(ctx sdk.Context, msgs []sdk.Msg) error { - for _, m := range msgs { - if msg, ok := m.(*authz.MsgExec); ok { - if err := min.isValidAuthz(ctx, msg); err != nil { - return err - } - continue - } - - // validate normal msgs - err := min.isValidMsg(ctx, m) - if err != nil { - return err - } - } - - return nil -} diff --git a/app/export.go b/app/export.go index 0a313e14bb..8cb6aa0ce5 100644 --- a/app/export.go +++ b/app/export.go @@ -2,32 +2,38 @@ package app import ( "encoding/json" - "log" "math/rand" + errorsmod "cosmossdk.io/errors" + storetypes "cosmossdk.io/store/types" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/spf13/viper" + "pkg.akt.dev/go/sdkutil" - abci "github.com/tendermint/tendermint/abci/types" - logger "github.com/tendermint/tendermint/libs/log" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - dbm "github.com/tendermint/tm-db" + abci "github.com/cometbft/cometbft/abci/types" + cmproto "github.com/cometbft/cometbft/proto/tendermint/types" + + "cosmossdk.io/log" + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/baseapp" servertypes "github.com/cosmos/cosmos-sdk/server/types" - "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/simulation" - slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" "github.com/cosmos/cosmos-sdk/x/staking" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) // ExportAppStateAndValidators exports the state of the application for a genesis // file. func (app *AkashApp) ExportAppStateAndValidators( - forZeroHeight bool, jailAllowedAddrs []string, + forZeroHeight bool, + jailAllowedAddrs []string, + modulesToExport []string, ) (servertypes.ExportedApp, error) { // as if they could withdraw from the start of the next block - ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + ctx := app.NewContextLegacy(true, cmproto.Header{Height: app.LastBlockHeight()}) // We export at last height + 1, because that's the height at which // Tendermint will start InitChain. @@ -38,59 +44,74 @@ func (app *AkashApp) ExportAppStateAndValidators( app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs) } - genState := app.MM.ExportGenesis(ctx, app.appCodec) + genState, err := app.MM.ExportGenesisForModules(ctx, app.cdc, modulesToExport) + if err != nil { + return servertypes.ExportedApp{}, err + } + appState, err := json.MarshalIndent(genState, "", " ") if err != nil { return servertypes.ExportedApp{}, err } - validators, err := staking.WriteValidators(ctx, *app.Keepers.Cosmos.Staking) + validators, err := staking.WriteValidators(ctx, app.Keepers.Cosmos.Staking) if err != nil { return servertypes.ExportedApp{}, err } + return servertypes.ExportedApp{ AppState: appState, Validators: validators, Height: height, - ConsensusParams: app.BaseApp.GetConsensusParams(ctx), + ConsensusParams: app.GetConsensusParams(ctx), }, nil } // prepForZeroHeightGenesis prepare for fresh start at zero height -// NOTE zero height genesis is a temporary feature which will be deprecated +// NOTE zero height genesis is a temporary feature that will be deprecated // // in favour of export at a block height func (app *AkashApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) { - applyAllowedAddrs := false - - // Check if there is a allowed address list - if len(jailAllowedAddrs) > 0 { - applyAllowedAddrs = true - } + // Check if there is an allowed address list + applyAllowedAddrs := len(jailAllowedAddrs) > 0 allowedAddrsMap := make(map[string]bool) for _, addr := range jailAllowedAddrs { _, err := sdk.ValAddressFromBech32(addr) if err != nil { - log.Fatal(err) + panic(err) } allowedAddrsMap[addr] = true } - /* Just to be safe, assert the invariants on current state. */ - app.Keepers.Cosmos.Crisis.AssertInvariants(ctx) - /* Handle fee distribution state. */ // withdraw all validator commission - app.Keepers.Cosmos.Staking.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { - _, _ = app.Keepers.Cosmos.Distr.WithdrawValidatorCommission(ctx, val.GetOperator()) + err := app.Keepers.Cosmos.Staking.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { + valBz, err := app.Keepers.Cosmos.Staking.ValidatorAddressCodec().StringToBytes(val.GetOperator()) + if err != nil { + panic(err) + } + + _, err = app.Keepers.Cosmos.Distr.WithdrawValidatorCommission(ctx, valBz) + if err != nil { + if !errorsmod.IsOf(err, distrtypes.ErrNoValidatorCommission) { + panic(err) + } + } return false }) + if err != nil { + panic(err) + } // withdraw all delegator rewards - dels := app.Keepers.Cosmos.Staking.GetAllDelegations(ctx) + dels, err := app.Keepers.Cosmos.Staking.GetAllDelegations(ctx) + if err != nil { + panic(err) + } + for _, delegation := range dels { valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress) if err != nil { @@ -115,15 +136,37 @@ func (app *AkashApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs ctx = ctx.WithBlockHeight(0) // reinitialize all validators - app.Keepers.Cosmos.Staking.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { + err = app.Keepers.Cosmos.Staking.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { + valBz, err := sdk.ValAddressFromBech32(val.GetOperator()) + if err != nil { + panic(err) + } + // donate any unwithdrawn outstanding reward fraction tokens to the community pool - scraps := app.Keepers.Cosmos.Distr.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator()) - feePool := app.Keepers.Cosmos.Distr.GetFeePool(ctx) + scraps, err := app.Keepers.Cosmos.Distr.GetValidatorOutstandingRewardsCoins(ctx, valBz) + if err != nil { + panic(err) + } + + feePool, err := app.Keepers.Cosmos.Distr.FeePool.Get(ctx) + if err != nil { + panic(err) + } + feePool.CommunityPool = feePool.CommunityPool.Add(scraps...) - app.Keepers.Cosmos.Distr.SetFeePool(ctx, feePool) - app.Keepers.Cosmos.Distr.Hooks().AfterValidatorCreated(ctx, val.GetOperator()) + err = app.Keepers.Cosmos.Distr.FeePool.Set(ctx, feePool) + if err != nil { + panic(err) + } + + if err := app.Keepers.Cosmos.Distr.Hooks().AfterValidatorCreated(ctx, valBz); err != nil { + panic(err) + } return false }) + if err != nil { + panic(err) + } // reinitialize all delegations for _, del := range dels { @@ -136,8 +179,15 @@ func (app *AkashApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs if err != nil { panic(err) } - app.Keepers.Cosmos.Distr.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr) - app.Keepers.Cosmos.Distr.Hooks().AfterDelegationModified(ctx, delAddr, valAddr) + err = app.Keepers.Cosmos.Distr.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr) + if err != nil { + panic(err) + } + + err = app.Keepers.Cosmos.Distr.Hooks().AfterDelegationModified(ctx, delAddr, valAddr) + if err != nil { + panic(err) + } } // reset context height @@ -146,34 +196,48 @@ func (app *AkashApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs /* Handle staking state. */ // iterate through redelegations, reset creation height - app.Keepers.Cosmos.Staking.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) { + err = app.Keepers.Cosmos.Staking.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) { for i := range red.Entries { red.Entries[i].CreationHeight = 0 } - app.Keepers.Cosmos.Staking.SetRedelegation(ctx, red) + err = app.Keepers.Cosmos.Staking.SetRedelegation(ctx, red) + if err != nil { + panic(err) + } return false }) + if err != nil { + panic(err) + } // iterate through unbonding delegations, reset creation height - app.Keepers.Cosmos.Staking.IterateUnbondingDelegations(ctx, func(_ int64, ubd stakingtypes.UnbondingDelegation) (stop bool) { + err = app.Keepers.Cosmos.Staking.IterateUnbondingDelegations(ctx, func(_ int64, ubd stakingtypes.UnbondingDelegation) (stop bool) { for i := range ubd.Entries { ubd.Entries[i].CreationHeight = 0 } - app.Keepers.Cosmos.Staking.SetUnbondingDelegation(ctx, ubd) + err = app.Keepers.Cosmos.Staking.SetUnbondingDelegation(ctx, ubd) + if err != nil { + panic(err) + } return false }) + if err != nil { + panic(err) + } // Iterate through validators by power descending, reset bond heights, and // update bond intra-tx counters. - store := ctx.KVStore(app.skeys[stakingtypes.ModuleName]) - iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey) + + store := ctx.KVStore(app.GetKey(stakingtypes.StoreKey)) + iter := storetypes.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey) + counter := int16(0) for ; iter.Valid(); iter.Next() { addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key())) - validator, found := app.Keepers.Cosmos.Staking.GetValidator(ctx, addr) - if !found { - panic("expected validator, not found") + validator, err := app.Keepers.Cosmos.Staking.GetValidator(ctx, addr) + if err != nil { + panic(err) } validator.UnbondingHeight = 0 @@ -181,13 +245,16 @@ func (app *AkashApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs validator.Jailed = true } - app.Keepers.Cosmos.Staking.SetValidator(ctx, validator) + err = app.Keepers.Cosmos.Staking.SetValidator(ctx, validator) + if err != nil { + panic(err) + } counter++ } _ = iter.Close() - _, err := app.Keepers.Cosmos.Staking.ApplyAndReturnValidatorSetUpdates(ctx) + _, err = app.Keepers.Cosmos.Staking.ApplyAndReturnValidatorSetUpdates(ctx) if err != nil { panic(err) } @@ -195,49 +262,86 @@ func (app *AkashApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs /* Handle slashing state. */ // reset start height on signing infos - app.Keepers.Cosmos.Slashing.IterateValidatorSigningInfos( + err = app.Keepers.Cosmos.Slashing.IterateValidatorSigningInfos( ctx, func(addr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool) { info.StartHeight = 0 - app.Keepers.Cosmos.Slashing.SetValidatorSigningInfo(ctx, addr, info) + err = app.Keepers.Cosmos.Slashing.SetValidatorSigningInfo(ctx, addr, info) + if err != nil { + panic(err) + } return false }, ) + if err != nil { + panic(err) + } } // Setup initializes a new AkashApp. A Nop logger is set in AkashApp. -func Setup(isCheckTx bool) *AkashApp { +func Setup(opts ...SetupAppOption) *AkashApp { + cfg := &setupAppOptions{ + encCfg: sdkutil.MakeEncodingConfig(), + home: DefaultHome, + checkTx: false, + chainID: "akash-1", + } + + ModuleBasics().RegisterInterfaces(cfg.encCfg.InterfaceRegistry) + + for _, opt := range opts { + opt(cfg) + } + db := dbm.NewMemDB() - // TODO: make this configurable via config or flag. - app := NewApp(logger.NewNopLogger(), db, nil, true, 5, map[int64]bool{}, DefaultHome, OptsWithGenesisTime(0)) - if !isCheckTx { - // init chain must be called to stop deliverState from being nil - genesisState := NewDefaultGenesisState() - stateBytes, err := json.MarshalIndent(genesisState, "", " ") + appOpts := viper.New() + + appOpts.Set("home", cfg.home) + + r := rand.New(rand.NewSource(0)) // nolint: gosec + genTime := simulation.RandTimestamp(r) + + appOpts.Set("GenesisTime", genTime) + + app := NewApp( + log.NewNopLogger(), + db, + nil, + true, + 5, + map[int64]bool{}, + cfg.encCfg, + appOpts, + baseapp.SetChainID(cfg.chainID), + ) + + if !cfg.checkTx { + var state GenesisState + if cfg.genesisFn == nil { + // init chain must be called to stop deliverState from being nil + state = NewDefaultGenesisState(app.AppCodec()) + } else { + state = cfg.genesisFn(app.cdc) + } + + stateBytes, err := json.MarshalIndent(state, "", " ") if err != nil { panic(err) } // Initialize the chain - app.InitChain( - abci.RequestInitChain{ + _, err = app.InitChain( + &abci.RequestInitChain{ Validators: []abci.ValidatorUpdate{}, AppStateBytes: stateBytes, + ChainId: cfg.chainID, }, ) + if err != nil { + panic(err) + } } return app } - -func OptsWithGenesisTime(seed int64) servertypes.AppOptions { - r := rand.New(rand.NewSource(seed)) // nolint: gosec - genTime := simulation.RandTimestamp(r) - - appOpts := viper.New() - appOpts.Set("GenesisTime", genTime) - simapp.FlagGenesisTimeValue = genTime.Unix() - - return appOpts -} diff --git a/app/genesis.go b/app/genesis.go index ce264dd20e..a3f2882309 100644 --- a/app/genesis.go +++ b/app/genesis.go @@ -1,7 +1,24 @@ package app import ( + "bytes" "encoding/json" + "strings" + "time" + + abci "github.com/cometbft/cometbft/abci/types" + "github.com/cometbft/cometbft/crypto/secp256k1" + tmtypes "github.com/cometbft/cometbft/types" + + sdkmath "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + "github.com/cosmos/cosmos-sdk/testutil/mock" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) // GenesisState of the blockchain is represented here as a map of raw json @@ -13,8 +30,125 @@ import ( // object provided to it during init. type GenesisState map[string]json.RawMessage +func genesisFilterTokens(from GenesisState) GenesisState { + genesisState := make(GenesisState) + for k, v := range from { + data, err := v.MarshalJSON() + if err != nil { + panic(err) + } + + buf := &bytes.Buffer{} + _, err = buf.Write(data) + if err != nil { + panic(err) + } + + stringData := buf.String() + stringDataAfter := strings.ReplaceAll(stringData, `"stake"`, `"uakt"`) + if stringData == stringDataAfter { + genesisState[k] = v + continue + } + + replacementV := json.RawMessage(stringDataAfter) + genesisState[k] = replacementV + } + + return genesisState +} + // NewDefaultGenesisState generates the default state for the application. -func NewDefaultGenesisState() GenesisState { - encCfg := MakeEncodingConfig() - return ModuleBasics().DefaultGenesis(encCfg.Marshaler) +func NewDefaultGenesisState(cdc codec.Codec) GenesisState { + genesis := ModuleBasics().DefaultGenesis(cdc) + return genesisFilterTokens(genesis) +} + +func GenesisStateWithValSet(cdc codec.Codec) GenesisState { + privVal := mock.NewPV() + pubKey, _ := privVal.GetPubKey() + validator := tmtypes.NewValidator(pubKey, 1) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) + + // generate a genesis account + senderPrivKey := secp256k1.GenPrivKey() + senderPrivKey.PubKey().Address() + acc := authtypes.NewBaseAccountWithAddress(senderPrivKey.PubKey().Address().Bytes()) + + var balances []banktypes.Balance + initValPowers := make([]abci.ValidatorUpdate, 0, len(valSet.Validators)) + + genesisState := NewDefaultGenesisState(cdc) + genAccs := []authtypes.GenesisAccount{acc} + authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs) + genesisState[authtypes.ModuleName] = cdc.MustMarshalJSON(authGenesis) + + validators := make([]stakingtypes.Validator, 0, len(valSet.Validators)) + delegations := make([]stakingtypes.Delegation, 0, len(valSet.Validators)) + + bondAmt := sdk.DefaultPowerReduction + + for _, val := range valSet.Validators { + pk, _ := cryptocodec.FromCmtPubKeyInterface(val.PubKey) + pkAny, _ := codectypes.NewAnyWithValue(pk) + validator := stakingtypes.Validator{ + OperatorAddress: sdk.ValAddress(val.Address).String(), + ConsensusPubkey: pkAny, + Jailed: false, + Status: stakingtypes.Bonded, + Tokens: bondAmt, + DelegatorShares: sdkmath.LegacyOneDec(), + Description: stakingtypes.Description{}, + UnbondingHeight: int64(0), + UnbondingTime: time.Unix(0, 0).UTC(), + Commission: stakingtypes.NewCommission(sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec()), + MinSelfDelegation: sdkmath.ZeroInt(), + } + validators = append(validators, validator) + delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress().String(), sdk.ValAddress(val.Address).String(), sdkmath.LegacyOneDec())) + + // add initial validator powers so consumer InitGenesis runs correctly + pub, _ := val.ToProto() + initValPowers = append(initValPowers, abci.ValidatorUpdate{ + Power: val.VotingPower, + PubKey: pub.PubKey, + }) + } + // set validators and delegations + stakingGenesis := stakingtypes.NewGenesisState(stakingtypes.DefaultParams(), validators, delegations) + genesisState[stakingtypes.ModuleName] = cdc.MustMarshalJSON(stakingGenesis) + + totalSupply := sdk.NewCoins() + for _, b := range balances { + // add genesis acc tokens to total supply + totalSupply = totalSupply.Add(b.Coins...) + } + + for range delegations { + // add delegated tokens to total supply + totalSupply = totalSupply.Add(sdk.NewCoin(sdk.DefaultBondDenom, bondAmt)) + } + + // add bonded amount to bonded pool module account + balances = append(balances, banktypes.Balance{ + Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(), + Coins: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, bondAmt)}, + }) + + // update total supply + bankGenesis := banktypes.NewGenesisState( + banktypes.DefaultGenesisState().Params, + balances, + totalSupply, + []banktypes.Metadata{}, + []banktypes.SendEnabled{}, + ) + genesisState[banktypes.ModuleName] = cdc.MustMarshalJSON(bankGenesis) + + _, err := tmtypes.PB2TM.ValidatorUpdates(initValPowers) + if err != nil { + panic("failed to get vals") + } + + return genesisState } diff --git a/app/mac.go b/app/mac.go index 5546923678..e34aff3ddc 100644 --- a/app/mac.go +++ b/app/mac.go @@ -6,15 +6,14 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - - escrowtypes "github.com/akash-network/akash-api/go/node/escrow/v1beta3" + ibctransfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" + emodule "pkg.akt.dev/go/node/escrow/module" ) -func MacPerms() map[string][]string { +func ModuleAccountPerms() map[string][]string { return map[string][]string{ authtypes.FeeCollectorName: nil, - escrowtypes.ModuleName: nil, + emodule.ModuleName: nil, distrtypes.ModuleName: nil, minttypes.ModuleName: {authtypes.Minter}, stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, @@ -24,8 +23,8 @@ func MacPerms() map[string][]string { } } -func MacAddrs() map[string]bool { - perms := MacPerms() +func ModuleAccountAddrs() map[string]bool { + perms := ModuleAccountPerms() addrs := make(map[string]bool, len(perms)) for k := range perms { addrs[authtypes.NewModuleAddress(k).String()] = true diff --git a/app/modules.go b/app/modules.go new file mode 100644 index 0000000000..a2287bf49a --- /dev/null +++ b/app/modules.go @@ -0,0 +1,325 @@ +package app + +import ( + "cosmossdk.io/x/evidence" + feegrantmodule "cosmossdk.io/x/feegrant/module" + "cosmossdk.io/x/upgrade" + addresscodec "github.com/cosmos/cosmos-sdk/codec/address" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/x/auth" + authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/auth/vesting" + authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module" + "github.com/cosmos/cosmos-sdk/x/bank" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/cosmos-sdk/x/consensus" + distr "github.com/cosmos/cosmos-sdk/x/distribution" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + "github.com/cosmos/cosmos-sdk/x/genutil" + "github.com/cosmos/cosmos-sdk/x/gov" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/cosmos/cosmos-sdk/x/mint" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + "github.com/cosmos/cosmos-sdk/x/params" + "github.com/cosmos/cosmos-sdk/x/slashing" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + "github.com/cosmos/cosmos-sdk/x/staking" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/cosmos/ibc-go/v10/modules/apps/transfer" + ibc "github.com/cosmos/ibc-go/v10/modules/core" + ibctm "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" + + "pkg.akt.dev/go/sdkutil" + + "pkg.akt.dev/node/x/audit" + "pkg.akt.dev/node/x/cert" + "pkg.akt.dev/node/x/deployment" + "pkg.akt.dev/node/x/escrow" + "pkg.akt.dev/node/x/market" + "pkg.akt.dev/node/x/provider" + "pkg.akt.dev/node/x/take" +) + +func appModules( + app *AkashApp, + encodingConfig sdkutil.EncodingConfig, +) []module.AppModule { + cdc := encodingConfig.Codec + + return []module.AppModule{ + genutil.NewAppModule( + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Staking, + app.BaseApp, + encodingConfig.TxConfig, + ), + auth.NewAppModule( + cdc, + app.Keepers.Cosmos.Acct, + nil, + app.GetSubspace(authtypes.ModuleName), + ), + vesting.NewAppModule( + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + ), + bank.NewAppModule( + cdc, + app.Keepers.Cosmos.Bank, + app.Keepers.Cosmos.Acct, + app.GetSubspace(banktypes.ModuleName), + ), + gov.NewAppModule( + cdc, + app.Keepers.Cosmos.Gov, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.GetSubspace(govtypes.ModuleName), + ), + mint.NewAppModule( + cdc, + app.Keepers.Cosmos.Mint, + app.Keepers.Cosmos.Acct, + nil, // todo akash-network/support#4 + app.GetSubspace(minttypes.ModuleName), + ), + slashing.NewAppModule( + cdc, + app.Keepers.Cosmos.Slashing, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.Keepers.Cosmos.Staking, + app.GetSubspace(slashingtypes.ModuleName), + encodingConfig.InterfaceRegistry, + ), + distr.NewAppModule( + cdc, + app.Keepers.Cosmos.Distr, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.Keepers.Cosmos.Staking, + app.GetSubspace(distrtypes.ModuleName), + ), + staking.NewAppModule( + cdc, + app.Keepers.Cosmos.Staking, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.GetSubspace(stakingtypes.ModuleName), + ), + upgrade.NewAppModule( + app.Keepers.Cosmos.Upgrade, + addresscodec.NewBech32Codec(sdkutil.Bech32PrefixAccAddr), + ), + evidence.NewAppModule( + *app.Keepers.Cosmos.Evidence, + ), + authzmodule.NewAppModule( + cdc, app.Keepers.Cosmos.Authz, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.interfaceRegistry, + ), + feegrantmodule.NewAppModule( + cdc, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.Keepers.Cosmos.FeeGrant, + app.interfaceRegistry, + ), + ibc.NewAppModule( + app.Keepers.Cosmos.IBC, + ), + transfer.NewAppModule( + app.Keepers.Cosmos.Transfer, + ), + ibctm.NewAppModule( + app.Keepers.Modules.TMLight, + ), + params.NewAppModule( //nolint: staticcheck + app.Keepers.Cosmos.Params, + ), + consensus.NewAppModule( + cdc, + *app.Keepers.Cosmos.ConsensusParams, + ), + // akash modules + take.NewAppModule( + app.cdc, + app.Keepers.Akash.Take, + ), + escrow.NewAppModule( + app.cdc, + app.Keepers.Akash.Escrow, + app.Keepers.Cosmos.Authz, + app.Keepers.Cosmos.Bank, + ), + deployment.NewAppModule( + app.cdc, + app.Keepers.Akash.Deployment, + app.Keepers.Akash.Market, + app.Keepers.Akash.Escrow, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.Keepers.Cosmos.Authz, + ), + market.NewAppModule( + app.cdc, + app.Keepers.Akash.Market, + app.Keepers.Akash.Escrow, + app.Keepers.Akash.Audit, + app.Keepers.Akash.Deployment, + app.Keepers.Akash.Provider, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Authz, + app.Keepers.Cosmos.Bank, + ), + provider.NewAppModule( + app.cdc, + app.Keepers.Akash.Provider, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.Keepers.Akash.Market, + ), + audit.NewAppModule( + app.cdc, + app.Keepers.Akash.Audit, + ), + cert.NewAppModule( + app.cdc, + app.Keepers.Akash.Cert, + ), + } +} + +func appSimModules( + app *AkashApp, + encodingConfig sdkutil.EncodingConfig, +) []module.AppModuleSimulation { + return []module.AppModuleSimulation{ + auth.NewAppModule( + app.cdc, + app.Keepers.Cosmos.Acct, + authsims.RandomGenesisAccounts, + app.GetSubspace(authtypes.ModuleName), + ), + authzmodule.NewAppModule( + app.cdc, + app.Keepers.Cosmos.Authz, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.interfaceRegistry, + ), + bank.NewAppModule( + app.cdc, + app.Keepers.Cosmos.Bank, + app.Keepers.Cosmos.Acct, + app.GetSubspace(banktypes.ModuleName), + ), + feegrantmodule.NewAppModule( + app.cdc, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.Keepers.Cosmos.FeeGrant, + app.interfaceRegistry, + ), + authzmodule.NewAppModule( + app.cdc, + app.Keepers.Cosmos.Authz, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.interfaceRegistry, + ), + gov.NewAppModule( + app.cdc, + app.Keepers.Cosmos.Gov, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.GetSubspace(govtypes.ModuleName), + ), + mint.NewAppModule( + app.cdc, + app.Keepers.Cosmos.Mint, + app.Keepers.Cosmos.Acct, + nil, // todo akash-network/support#4 + app.GetSubspace(minttypes.ModuleName), + ), + staking.NewAppModule( + app.cdc, + app.Keepers.Cosmos.Staking, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.GetSubspace(stakingtypes.ModuleName), + ), + distr.NewAppModule( + app.cdc, + app.Keepers.Cosmos.Distr, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.Keepers.Cosmos.Staking, + app.GetSubspace(distrtypes.ModuleName), + ), + slashing.NewAppModule( + app.cdc, + app.Keepers.Cosmos.Slashing, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.Keepers.Cosmos.Staking, + app.GetSubspace(slashingtypes.ModuleName), + encodingConfig.InterfaceRegistry, + ), + params.NewAppModule( //nolint: staticcheck + app.Keepers.Cosmos.Params, + ), + evidence.NewAppModule( + *app.Keepers.Cosmos.Evidence, + ), + ibc.NewAppModule( + app.Keepers.Cosmos.IBC, + ), + transfer.NewAppModule( + app.Keepers.Cosmos.Transfer, + ), + // akash sim modules + take.NewAppModule( + app.cdc, + app.Keepers.Akash.Take, + ), + + deployment.NewAppModule( + app.cdc, + app.Keepers.Akash.Deployment, + app.Keepers.Akash.Market, + app.Keepers.Akash.Escrow, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.Keepers.Cosmos.Authz, + ), + + market.NewAppModule( + app.cdc, + app.Keepers.Akash.Market, + app.Keepers.Akash.Escrow, + app.Keepers.Akash.Audit, + app.Keepers.Akash.Deployment, + app.Keepers.Akash.Provider, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Authz, + app.Keepers.Cosmos.Bank, + ), + + provider.NewAppModule( + app.cdc, + app.Keepers.Akash.Provider, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.Keepers.Akash.Market, + ), + + cert.NewAppModule( + app.cdc, + app.Keepers.Akash.Cert, + ), + } +} diff --git a/app/option.go b/app/option.go new file mode 100644 index 0000000000..35e5320b3a --- /dev/null +++ b/app/option.go @@ -0,0 +1,52 @@ +package app + +import ( + "github.com/cosmos/cosmos-sdk/codec" + + "pkg.akt.dev/go/sdkutil" +) + +type SetupGenesisFn func(cdc codec.Codec) GenesisState + +type setupAppOptions struct { + encCfg sdkutil.EncodingConfig + home string + chainID string + checkTx bool + genesisFn SetupGenesisFn +} + +type SetupAppOption func(*setupAppOptions) + +// WithHome sets home dir for app +func WithHome(val string) SetupAppOption { + return func(t *setupAppOptions) { + t.home = val + } +} + +// WithChainID sets home dir for app +func WithChainID(val string) SetupAppOption { + return func(t *setupAppOptions) { + t.chainID = val + } +} + +// WithCheckTx sets home dir for app +func WithCheckTx(val bool) SetupAppOption { + return func(t *setupAppOptions) { + t.checkTx = val + } +} + +func WithGenesis(val SetupGenesisFn) SetupAppOption { + return func(t *setupAppOptions) { + t.genesisFn = val + } +} + +func WithEncConfig(val sdkutil.EncodingConfig) SetupAppOption { + return func(t *setupAppOptions) { + t.encCfg = val + } +} diff --git a/app/params/proto.go b/app/params/proto.go deleted file mode 100644 index b71f91e67c..0000000000 --- a/app/params/proto.go +++ /dev/null @@ -1,23 +0,0 @@ -package params - -import ( - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/codec/types" - simparams "github.com/cosmos/cosmos-sdk/simapp/params" - "github.com/cosmos/cosmos-sdk/x/auth/tx" -) - -// MakeEncodingConfig creates an EncodingConfig for a proto based test configuration. -func MakeEncodingConfig() simparams.EncodingConfig { - amino := codec.NewLegacyAmino() - interfaceRegistry := types.NewInterfaceRegistry() - marshaler := codec.NewProtoCodec(interfaceRegistry) - txCfg := tx.NewTxConfig(marshaler, tx.DefaultSignModes) - - return simparams.EncodingConfig{ - InterfaceRegistry: interfaceRegistry, - Marshaler: marshaler, - TxConfig: txCfg, - Amino: amino, - } -} diff --git a/app/sim/sim_config.go b/app/sim/sim_config.go new file mode 100644 index 0000000000..e8075b14c0 --- /dev/null +++ b/app/sim/sim_config.go @@ -0,0 +1,76 @@ +package sim + +import ( + "flag" + + "github.com/cosmos/cosmos-sdk/types/simulation" +) + +// List of available flags for the simulator +var ( + FlagGenesisFileValue string + FlagParamsFileValue string + FlagExportParamsPathValue string + FlagExportParamsHeightValue int + FlagExportStatePathValue string + FlagExportStatsPathValue string + FlagSeedValue int64 + FlagInitialBlockHeightValue int + FlagNumBlocksValue int + FlagBlockSizeValue int + FlagLeanValue bool + FlagCommitValue bool + FlagOnOperationValue bool // TODO: Remove in favor of binary search for invariant violation + FlagAllInvariantsValue bool + + FlagEnabledValue bool + FlagVerboseValue bool + FlagPeriodValue uint + FlagGenesisTimeValue int64 +) + +// GetSimulatorFlags gets the values of all the available simulation flags +func GetSimulatorFlags() { + // config fields + flag.StringVar(&FlagGenesisFileValue, "Genesis", "", "custom simulation genesis file; cannot be used with params file") + flag.StringVar(&FlagParamsFileValue, "Params", "", "custom simulation params file which overrides any random params; cannot be used with genesis") + flag.StringVar(&FlagExportParamsPathValue, "ExportParamsPath", "", "custom file path to save the exported params JSON") + flag.IntVar(&FlagExportParamsHeightValue, "ExportParamsHeight", 0, "height to which export the randomly generated params") + flag.StringVar(&FlagExportStatePathValue, "ExportStatePath", "", "custom file path to save the exported app state JSON") + flag.StringVar(&FlagExportStatsPathValue, "ExportStatsPath", "", "custom file path to save the exported simulation statistics JSON") + flag.Int64Var(&FlagSeedValue, "Seed", 42, "simulation random seed") + flag.IntVar(&FlagInitialBlockHeightValue, "InitialBlockHeight", 1, "initial block to start the simulation") + flag.IntVar(&FlagNumBlocksValue, "NumBlocks", 500, "number of new blocks to simulate from the initial block height") + flag.IntVar(&FlagBlockSizeValue, "BlockSize", 200, "operations per block") + flag.BoolVar(&FlagLeanValue, "Lean", false, "lean simulation log output") + flag.BoolVar(&FlagCommitValue, "Commit", false, "have the simulation commit") + flag.BoolVar(&FlagOnOperationValue, "SimulateEveryOperation", false, "run slow invariants every operation") + flag.BoolVar(&FlagAllInvariantsValue, "PrintAllInvariants", false, "print all invariants if a broken invariant is found") + + // simulation flags + flag.BoolVar(&FlagEnabledValue, "Enabled", false, "enable the simulation") + flag.BoolVar(&FlagVerboseValue, "Verbose", false, "verbose log output") + flag.UintVar(&FlagPeriodValue, "Period", 0, "run slow invariants only once every period assertions") + flag.Int64Var(&FlagGenesisTimeValue, "GenesisTime", 0, "override genesis UNIX time instead of using a random UNIX time") +} + +// NewConfigFromFlags creates a simulation from the retrieved values of the flags. +func NewConfigFromFlags() simulation.Config { + return simulation.Config{ + GenesisFile: FlagGenesisFileValue, + ParamsFile: FlagParamsFileValue, + ExportParamsPath: FlagExportParamsPathValue, + ExportParamsHeight: FlagExportParamsHeightValue, + ExportStatePath: FlagExportStatePathValue, + ExportStatsPath: FlagExportStatsPathValue, + Seed: FlagSeedValue, + InitialBlockHeight: FlagInitialBlockHeightValue, + NumBlocks: FlagNumBlocksValue, + BlockSize: FlagBlockSizeValue, + Lean: FlagLeanValue, + Commit: FlagCommitValue, + OnOperation: FlagOnOperationValue, + AllInvariants: FlagAllInvariantsValue, + DBBackend: "goleveldb", + } +} diff --git a/app/sim/sim_utils.go b/app/sim/sim_utils.go new file mode 100644 index 0000000000..92baa1d74d --- /dev/null +++ b/app/sim/sim_utils.go @@ -0,0 +1,110 @@ +package sim + +import ( + "encoding/json" + "fmt" + "os" + "testing" + + "cosmossdk.io/log" + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/types/module" + + "github.com/cosmos/cosmos-sdk/runtime" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + + akash "pkg.akt.dev/node/app" +) + +// SetupSimulation creates the config, db (levelDB), temporary directory and logger for +// the simulation tests. If `FlagEnabledValue` is false, it skips the current test. +// Returns error on an invalid db instance or temp dir creation. +func SetupSimulation(dirPrefix, dbName string) (simtypes.Config, dbm.DB, string, log.Logger, bool, error) { + if !FlagEnabledValue { + return simtypes.Config{}, nil, "", nil, true, nil + } + + config := NewConfigFromFlags() + config.ChainID = "akash-sim" + + var logger log.Logger + if FlagVerboseValue { + logger = log.NewTestLogger(&testing.T{}) + } else { + logger = log.NewNopLogger() + } + + dir, err := os.MkdirTemp("", dirPrefix) + if err != nil { + return simtypes.Config{}, nil, "", nil, false, err + } + + db, err := dbm.NewDB(dbName, dbm.BackendType(config.DBBackend), dir) + if err != nil { + return simtypes.Config{}, nil, "", nil, false, err + } + + return config, db, dir, logger, false, nil +} + +// SimulationOperations retrieves the simulation params from the provided file path +// and returns all the modules weighted operations +func SimulationOperations(app *akash.AkashApp, cdc codec.JSONCodec, config simtypes.Config) []simtypes.WeightedOperation { + simState := module.SimulationState{ + AppParams: make(simtypes.AppParams), + Cdc: cdc, + } + + if config.ParamsFile != "" { + bz, err := os.ReadFile(config.ParamsFile) + if err != nil { + panic(err) + } + + err = json.Unmarshal(bz, &simState.AppParams) + if err != nil { + panic(err) + } + } + + simState.LegacyProposalContents = app.SimulationManager().GetProposalContents(simState) //nolint:staticcheck + simState.ProposalMsgs = app.SimulationManager().GetProposalMsgs(simState) + return app.SimulationManager().WeightedOperations(simState) +} + +// CheckExportSimulation exports the app state and simulation parameters to JSON +// if the export paths are defined. +func CheckExportSimulation(app runtime.AppI, config simtypes.Config, params simtypes.Params) error { + if config.ExportStatePath != "" { + fmt.Println("exporting app state...") + exported, err := app.ExportAppStateAndValidators(false, nil, nil) + if err != nil { + return err + } + + if err := os.WriteFile(config.ExportStatePath, []byte(exported.AppState), 0o600); err != nil { + return err + } + } + + if config.ExportParamsPath != "" { + fmt.Println("exporting simulation params...") + paramsBz, err := json.MarshalIndent(params, "", " ") + if err != nil { + return err + } + + if err := os.WriteFile(config.ExportParamsPath, paramsBz, 0o600); err != nil { + return err + } + } + return nil +} + +// PrintStats prints the corresponding statistics from the app DB. +func PrintStats(db dbm.DB) { + fmt.Println("\nLevelDB Stats") + fmt.Println(db.Stats()["leveldb.stats"]) + fmt.Println("LevelDB cached block size", db.Stats()["leveldb.cachedblock"]) +} diff --git a/app/sim_test.go b/app/sim_test.go index 34625f0f8e..b51ab4ecef 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -1,4 +1,4 @@ -package app +package app_test import ( "encoding/json" @@ -6,56 +6,71 @@ import ( "math/rand" "os" "testing" + "time" - atypes "github.com/akash-network/akash-api/go/node/audit/v1beta3" - ctypes "github.com/akash-network/akash-api/go/node/cert/v1beta3" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - mtypes "github.com/akash-network/akash-api/go/node/market/v1beta4" - ptypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" - taketypes "github.com/akash-network/akash-api/go/node/take/v1beta3" - "github.com/cosmos/cosmos-sdk/x/authz" - authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/libs/log" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - dbm "github.com/tendermint/tm-db" + abci "github.com/cometbft/cometbft/abci/types" + + "cosmossdk.io/log" + "cosmossdk.io/store" + storetypes "cosmossdk.io/store/types" + evidencetypes "cosmossdk.io/x/evidence/types" + "cosmossdk.io/x/feegrant" + upgradetypes "cosmossdk.io/x/upgrade/types" + dbm "github.com/cosmos/cosmos-db" "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/simapp" - "github.com/cosmos/cosmos-sdk/simapp/helpers" - "github.com/cosmos/cosmos-sdk/store" - sdk "github.com/cosmos/cosmos-sdk/types" - simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + sdksim "github.com/cosmos/cosmos-sdk/types/simulation" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" + authzkeys "github.com/cosmos/cosmos-sdk/x/authz/keeper/keys" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/cosmos/cosmos-sdk/x/simulation" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host" + ibctransfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" + ibchost "github.com/cosmos/ibc-go/v10/modules/core/exported" + + atypes "pkg.akt.dev/go/node/audit/v1" + ctypes "pkg.akt.dev/go/node/cert/v1" + dtypes "pkg.akt.dev/go/node/deployment/v1" + mtypes "pkg.akt.dev/go/node/market/v1" + ptypes "pkg.akt.dev/go/node/provider/v1beta4" + taketypes "pkg.akt.dev/go/node/take/v1" + "pkg.akt.dev/go/sdkutil" + + akash "pkg.akt.dev/node/app" + "pkg.akt.dev/node/app/sim" + simtestutil "pkg.akt.dev/node/testutil/sims" ) -// Get flags every time the simulator is run -var ( - _ = func() string { - simapp.GetSimulatorFlags() - return "" - }() +// AppChainID hardcoded chainID for simulation +const ( + AppChainID = "akash-sim" ) +type storeKeyGetter interface { + GetKey(string) *storetypes.KVStoreKey +} + type StoreKeysPrefixes struct { - A sdk.StoreKey - B sdk.StoreKey + Key string + A storeKeyGetter + B storeKeyGetter Prefixes [][]byte } +func init() { + sim.GetSimulatorFlags() +} + // fauxMerkleModeOpt returns a BaseApp option to use a dbStoreAdapter instead of // an IAVLStore for faster simulation speed. func fauxMerkleModeOpt(bapp *baseapp.BaseApp) { @@ -68,172 +83,307 @@ func interBlockCacheOpt() func(*baseapp.BaseApp) { return baseapp.SetInterBlockCache(store.NewCommitKVStoreCacheManager()) } -func simulateFromSeedFunc(t *testing.T, newApp *AkashApp, config simtypes.Config) (bool, simulation.Params, error) { +func simulateFromSeedFunc(t *testing.T, newApp *akash.AkashApp, config sdksim.Config) (bool, simulation.Params, error) { return simulation.SimulateFromSeed( - t, os.Stdout, newApp.BaseApp, simapp.AppStateFn(newApp.AppCodec(), newApp.SimulationManager()), - simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1 - simapp.SimulationOperations(newApp, newApp.AppCodec(), config), - newApp.ModuleAccountAddrs(), config, + t, + os.Stdout, + newApp.BaseApp, + simtestutil.AppStateFn(newApp.AppCodec(), newApp.SimulationManager(), akash.NewDefaultGenesisState(newApp.AppCodec())), + sdksim.RandomAccounts, // Replace it with own random account function if using keys other than secp256k1 + simtestutil.BuildSimulationOperations(newApp, newApp.AppCodec(), config, newApp.TxConfig()), + newApp.ModuleAccountAddrs(), + config, newApp.AppCodec(), ) } func TestFullAppSimulation(t *testing.T) { - config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation") + config, db, dir, logger, skip, err := sim.SetupSimulation("leveldb-app-sim", "Simulation") if skip { t.Skip("skipping application simulation") } require.NoError(t, err, "simulation setup failed") + encodingConfig := sdkutil.MakeEncodingConfig() + + akash.ModuleBasics().RegisterInterfaces(encodingConfig.InterfaceRegistry) + defer func() { _ = db.Close() require.NoError(t, os.RemoveAll(dir)) }() - app1 := NewApp(logger, db, nil, true, simapp.FlagPeriodValue, map[int64]bool{}, DefaultHome, OptsWithGenesisTime(config.Seed), fauxMerkleModeOpt) + appOpts := viper.New() + appOpts.Set("home", akash.DefaultHome) + + r := rand.New(rand.NewSource(config.Seed)) // nolint: gosec + genTime := sdksim.RandTimestamp(r) + + appOpts.Set("GenesisTime", genTime) + + app1 := akash.NewApp(logger, db, nil, true, sim.FlagPeriodValue, map[int64]bool{}, encodingConfig, appOpts, fauxMerkleModeOpt, baseapp.SetChainID(AppChainID)) + require.Equal(t, "akash", app1.Name()) - fmt.Printf("config-------- %v", config) + fmt.Printf("config--------\n%v", config) // run randomized simulation _, simParams, simErr := simulateFromSeedFunc(t, app1, config) // export state and simParams before the simulation error is checked - err = simapp.CheckExportSimulation(app1, config, simParams) + err = simtestutil.CheckExportSimulation(app1, config, simParams) require.NoError(t, err) require.NoError(t, simErr) if config.Commit { - simapp.PrintStats(db) + sim.PrintStats(db) } } func TestAppImportExport(t *testing.T) { - config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation") + config, db, dir, logger, skip, err := sim.SetupSimulation("leveldb-app-sim", "Simulation") if skip { t.Skip("skipping application import/export simulation") } require.NoError(t, err, "simulation setup failed") defer func() { - db.Close() + _ = db.Close() require.NoError(t, os.RemoveAll(dir)) }() - app := NewApp(logger, db, nil, true, simapp.FlagPeriodValue, map[int64]bool{}, DefaultHome, OptsWithGenesisTime(config.Seed), fauxMerkleModeOpt) - require.Equal(t, AppName, app.Name()) + encodingConfig := sdkutil.MakeEncodingConfig() + + akash.ModuleBasics().RegisterInterfaces(encodingConfig.InterfaceRegistry) + + appOpts := viper.New() + appOpts.Set("home", akash.DefaultHome) + + r := rand.New(rand.NewSource(config.Seed)) // nolint: gosec + genTime := sdksim.RandTimestamp(r) + + appOpts.Set("GenesisTime", genTime) + + appA := akash.NewApp(logger, db, nil, true, sim.FlagPeriodValue, map[int64]bool{}, encodingConfig, appOpts, fauxMerkleModeOpt, baseapp.SetChainID(AppChainID)) + require.Equal(t, akash.AppName, appA.Name()) // Run randomized simulation - _, simParams, simErr := simulateFromSeedFunc(t, app, config) + _, simParams, simErr := simulateFromSeedFunc(t, appA, config) // export state and simParams before the simulation error is checked - err = simapp.CheckExportSimulation(app, config, simParams) + err = simtestutil.CheckExportSimulation(appA, config, simParams) require.NoError(t, err) require.NoError(t, simErr) if config.Commit { - simapp.PrintStats(db) + sim.PrintStats(db) } fmt.Printf("exporting genesis...\n") - exported, err := app.ExportAppStateAndValidators(false, []string{}) + exported, err := appA.ExportAppStateAndValidators(false, []string{}, []string{}) require.NoError(t, err) fmt.Printf("importing genesis...\n") - _, newDB, newDir, _, _, err := simapp.SetupSimulation("leveldb-app-sim-2", "Simulation-2") + _, newDB, newDir, _, _, err := sim.SetupSimulation("leveldb-app-sim-2", "Simulation-2") require.NoError(t, err, "simulation setup failed") defer func() { - newDB.Close() + _ = newDB.Close() require.NoError(t, os.RemoveAll(newDir)) }() - newApp := NewApp(log.NewNopLogger(), newDB, nil, true, simapp.FlagPeriodValue, map[int64]bool{}, DefaultHome, OptsWithGenesisTime(config.Seed), fauxMerkleModeOpt) - require.Equal(t, AppName, newApp.Name()) + appB := akash.NewApp(logger, newDB, nil, true, sim.FlagPeriodValue, map[int64]bool{}, encodingConfig, appOpts, fauxMerkleModeOpt, baseapp.SetChainID(AppChainID)) + require.Equal(t, akash.AppName, appB.Name()) - var genesisState simapp.GenesisState + var genesisState akash.GenesisState err = json.Unmarshal(exported.AppState, &genesisState) require.NoError(t, err) - ctxA := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) - ctxB := newApp.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + ctxA := appA.NewContext(true) + ctxB := appB.NewContext(true) + + _, err = appB.MM.InitGenesis(ctxB, appA.AppCodec(), genesisState) + require.NoError(t, err) - newApp.MM.InitGenesis(ctxB, app.AppCodec(), genesisState) - newApp.StoreConsensusParams(ctxB, exported.ConsensusParams) + err = appB.StoreConsensusParams(ctxB, exported.ConsensusParams) + require.NoError(t, err) fmt.Printf("comparing stores...\n") storeKeysPrefixes := []StoreKeysPrefixes{ - {app.skeys[authtypes.ModuleName], newApp.skeys[authtypes.ModuleName], [][]byte{}}, { - app.skeys[stakingtypes.ModuleName], newApp.skeys[stakingtypes.ModuleName], + consensustypes.StoreKey, + appA, + appB, + [][]byte{}, + }, + { + authtypes.StoreKey, + appA, + appB, + [][]byte{}, + }, + { + feegrant.StoreKey, + appA, + appB, [][]byte{ - stakingtypes.UnbondingQueueKey, stakingtypes.RedelegationQueueKey, stakingtypes.ValidatorQueueKey, + feegrant.FeeAllowanceQueueKeyPrefix, + }, + }, + { + authzkeeper.StoreKey, + appA, + appB, + [][]byte{ + authzkeys.GrantQueuePrefix, + authzkeys.GranteeGranterKey, + authzkeys.GranteeMsgTypeUrlKey, + }, + }, + { + banktypes.StoreKey, + appA, + appB, + [][]byte{}, + }, + { + stakingtypes.StoreKey, + appA, + appB, + [][]byte{ + stakingtypes.UnbondingQueueKey, + stakingtypes.RedelegationQueueKey, + stakingtypes.ValidatorQueueKey, + stakingtypes.UnbondingIDKey, + stakingtypes.UnbondingIndexKey, + stakingtypes.UnbondingTypeKey, + stakingtypes.ValidatorUpdatesKey, stakingtypes.HistoricalInfoKey, }, - }, // ordering may change but it doesn't matter - {app.skeys[slashingtypes.ModuleName], newApp.skeys[slashingtypes.StoreKey], [][]byte{}}, - {app.skeys[minttypes.ModuleName], newApp.skeys[minttypes.ModuleName], [][]byte{}}, - {app.skeys[distrtypes.ModuleName], newApp.skeys[distrtypes.ModuleName], [][]byte{}}, - {app.skeys[banktypes.ModuleName], newApp.skeys[banktypes.ModuleName], [][]byte{banktypes.BalancesPrefix}}, - {app.skeys[paramtypes.ModuleName], newApp.skeys[paramtypes.ModuleName], [][]byte{}}, - {app.skeys[govtypes.ModuleName], newApp.skeys[govtypes.ModuleName], [][]byte{}}, - {app.skeys[evidencetypes.ModuleName], newApp.skeys[evidencetypes.ModuleName], [][]byte{}}, - {app.skeys[capabilitytypes.ModuleName], newApp.skeys[capabilitytypes.ModuleName], [][]byte{}}, - {app.skeys[ibchost.ModuleName], newApp.skeys[ibchost.ModuleName], [][]byte{}}, - {app.skeys[ibctransfertypes.ModuleName], newApp.skeys[ibctransfertypes.ModuleName], [][]byte{}}, - {app.skeys[authz.ModuleName], newApp.skeys[authz.ModuleName], [][]byte{ - authzkeeper.GranteeKey, - }}, + }, + { + minttypes.StoreKey, + appA, + appB, + [][]byte{}, + }, + { + distrtypes.StoreKey, + appA, + appB, + [][]byte{}, + }, + { + slashingtypes.StoreKey, + appA, + appB, + [][]byte{ + slashingtypes.ValidatorMissedBlockBitmapKeyPrefix, + }, + }, + { + govtypes.StoreKey, + appA, + appB, + [][]byte{}, + }, + { + paramtypes.StoreKey, + appA, + appB, + [][]byte{}, + }, + { + ibchost.StoreKey, + appA, + appB, + [][]byte{}, + }, + { + ibctransfertypes.StoreKey, + appA, + appB, + [][]byte{}, + }, + { + upgradetypes.StoreKey, + appA, + appB, + [][]byte{ + {upgradetypes.DoneByte}, + {upgradetypes.VersionMapByte}, + {upgradetypes.ProtocolVersionByte}, + }, + }, { - app.GetKey(atypes.StoreKey), - newApp.GetKey(atypes.StoreKey), + evidencetypes.StoreKey, + appA, + appB, [][]byte{}, }, { - app.GetKey(ctypes.StoreKey), - newApp.GetKey(ctypes.StoreKey), + atypes.StoreKey, + appA, + appB, [][]byte{}, }, { - app.GetKey(dtypes.StoreKey), - newApp.GetKey(dtypes.StoreKey), + ctypes.StoreKey, + appA, + appB, [][]byte{}, }, { - app.GetKey(mtypes.StoreKey), - newApp.GetKey(mtypes.StoreKey), + dtypes.StoreKey, + appA, + appB, [][]byte{}, }, { - app.GetKey(ptypes.StoreKey), - newApp.GetKey(ptypes.StoreKey), + mtypes.StoreKey, + appA, + appB, [][]byte{}, }, { - app.GetKey(taketypes.StoreKey), - newApp.GetKey(taketypes.StoreKey), + ptypes.StoreKey, + appA, + appB, + [][]byte{}, + }, + { + taketypes.StoreKey, + appA, + appB, [][]byte{}, }, } for _, skp := range storeKeysPrefixes { - storeA := ctxA.KVStore(skp.A) - storeB := ctxB.KVStore(skp.B) + storeKeyA := skp.A.GetKey(skp.Key) + storeKeyB := skp.B.GetKey(skp.Key) + + storeA := ctxA.KVStore(storeKeyA) + storeB := ctxB.KVStore(storeKeyB) - failedKVAs, failedKVBs := sdk.DiffKVStores(storeA, storeB, skp.Prefixes) - require.Equal(t, len(failedKVAs), len(failedKVBs), "unequal sets of key-values to compare") + failedKVAs, failedKVBs := simtestutil.DiffKVStores(storeA, storeB, skp.Prefixes) + require.Equal(t, len(failedKVAs), len(failedKVBs), "unequal sets of key-values to compare %s, key stores %s and %s", skp.Key, storeKeyA, storeKeyB) - fmt.Printf("compared %d key/value pairs between %s and %s\n", len(failedKVAs), skp.A, skp.B) - require.Equal(t, len(failedKVAs), 0, simapp.GetSimulationLog(skp.A.Name(), - app.SimulationManager().StoreDecoders, failedKVAs, failedKVBs)) + t.Logf("compared %d different key/value pairs between %s and %s\n", len(failedKVAs), storeKeyA, storeKeyB) + if !assert.Equal(t, 0, len(failedKVAs), simtestutil.GetSimulationLog(skp.Key, appA.SimulationManager().StoreDecoders, failedKVAs, failedKVBs)) { + for _, v := range failedKVAs { + t.Logf("store mismatch: %q\n", v) + } + t.FailNow() + } } } func TestAppSimulationAfterImport(t *testing.T) { - config, db, dir, logger, skip, err := simapp.SetupSimulation("leveldb-app-sim", "Simulation") + config, db, dir, logger, skip, err := sim.SetupSimulation("leveldb-app-sim", "Simulation") if skip { t.Skip("skipping application simulation after import") } @@ -241,23 +391,35 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, err, "simulation setup failed") defer func() { - db.Close() + _ = db.Close() require.NoError(t, os.RemoveAll(dir)) }() - app := NewApp(logger, db, nil, true, simapp.FlagPeriodValue, map[int64]bool{}, DefaultHome, OptsWithGenesisTime(config.Seed), fauxMerkleModeOpt) - require.Equal(t, AppName, app.Name()) + encodingConfig := sdkutil.MakeEncodingConfig() + akash.ModuleBasics().RegisterInterfaces(encodingConfig.InterfaceRegistry) + + appOpts := viper.New() + + appOpts.Set("home", akash.DefaultHome) + + r := rand.New(rand.NewSource(config.Seed)) // nolint: gosec + genTime := sdksim.RandTimestamp(r) + + appOpts.Set("GenesisTime", genTime) + + app := akash.NewApp(logger, db, nil, true, sim.FlagPeriodValue, map[int64]bool{}, encodingConfig, appOpts, fauxMerkleModeOpt, baseapp.SetChainID(AppChainID)) + require.Equal(t, akash.AppName, app.Name()) // Run randomized simulation stopEarly, simParams, simErr := simulateFromSeedFunc(t, app, config) // export state and simParams before the simulation error is checked - err = simapp.CheckExportSimulation(app, config, simParams) + err = simtestutil.CheckExportSimulation(app, config, simParams) require.NoError(t, err) require.NoError(t, simErr) if config.Commit { - simapp.PrintStats(db) + sim.PrintStats(db) } if stopEarly { @@ -267,44 +429,48 @@ func TestAppSimulationAfterImport(t *testing.T) { fmt.Printf("exporting genesis...\n") - exported, err := app.ExportAppStateAndValidators(true, []string{}) + exported, err := app.ExportAppStateAndValidators(true, []string{}, []string{}) require.NoError(t, err) fmt.Printf("importing genesis...\n") - _, newDB, newDir, _, val, err := simapp.SetupSimulation("leveldb-app-sim-2", "Simulation-2") + _, newDB, newDir, _, val, err := sim.SetupSimulation("leveldb-app-sim-2", "Simulation-2") require.NoError(t, err, "simulation setup failed", val) defer func() { - newDB.Close() + _ = newDB.Close() require.NoError(t, os.RemoveAll(newDir)) }() - newApp := NewApp(log.NewNopLogger(), newDB, nil, true, simapp.FlagPeriodValue, map[int64]bool{}, DefaultHome, OptsWithGenesisTime(config.Seed), fauxMerkleModeOpt) - require.Equal(t, AppName, newApp.Name()) + newApp := akash.NewApp(log.NewNopLogger(), newDB, nil, true, sim.FlagPeriodValue, map[int64]bool{}, encodingConfig, appOpts, fauxMerkleModeOpt, baseapp.SetChainID(AppChainID)) + require.Equal(t, akash.AppName, newApp.Name()) - newApp.InitChain(abci.RequestInitChain{ + _, err = newApp.InitChain(&abci.RequestInitChain{ AppStateBytes: exported.AppState, + ChainId: AppChainID, }) + require.NoError(t, err) _, _, err = simulateFromSeedFunc(t, newApp, config) require.NoError(t, err) } func TestAppStateDeterminism(t *testing.T) { - if !simapp.FlagEnabledValue { + if !sim.FlagEnabledValue { t.Skip("skipping application simulation") } - config := simapp.NewConfigFromFlags() + encodingConfig := sdkutil.MakeEncodingConfig() + akash.ModuleBasics().RegisterInterfaces(encodingConfig.InterfaceRegistry) + + config := sim.NewConfigFromFlags() config.InitialBlockHeight = 1 config.ExportParamsPath = "" - config.OnOperation = false - config.AllInvariants = false - config.ChainID = helpers.SimAppChainID + config.ChainID = AppChainID + config.GenesisTime = time.Now().UTC().Unix() numSeeds := 2 - numTimesToRunPerSeed := 2 + numTimesToRunPerSeed := 3 appHashList := make([]json.RawMessage, numTimesToRunPerSeed) for i := 0; i < numSeeds; i++ { @@ -312,15 +478,23 @@ func TestAppStateDeterminism(t *testing.T) { for j := 0; j < numTimesToRunPerSeed; j++ { var logger log.Logger - if simapp.FlagVerboseValue { - logger = log.TestingLogger() + if sim.FlagVerboseValue { + logger = log.NewTestLogger(&testing.T{}) } else { logger = log.NewNopLogger() } db := dbm.NewMemDB() - app := NewApp(logger, db, nil, true, simapp.FlagPeriodValue, map[int64]bool{}, DefaultHome, OptsWithGenesisTime(config.Seed), interBlockCacheOpt()) + appOpts := viper.New() + appOpts.Set("home", akash.DefaultHome) + + r := rand.New(rand.NewSource(config.Seed)) // nolint: gosec + genTime := sdksim.RandTimestamp(r) + + appOpts.Set("GenesisTime", genTime) + + app := akash.NewApp(logger, db, nil, true, sim.FlagPeriodValue, map[int64]bool{}, encodingConfig, appOpts, interBlockCacheOpt(), baseapp.SetChainID(AppChainID)) fmt.Printf( "running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n", @@ -331,7 +505,7 @@ func TestAppStateDeterminism(t *testing.T) { require.NoError(t, err) if config.Commit { - simapp.PrintStats(db) + sim.PrintStats(db) } appHash := app.LastCommitID().Hash diff --git a/app/testnet.go b/app/testnet.go index 6956e4c75d..c71b53b3e2 100644 --- a/app/testnet.go +++ b/app/testnet.go @@ -2,46 +2,53 @@ package app import ( "fmt" - "strings" "time" + tmos "github.com/cometbft/cometbft/libs/os" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + + "cosmossdk.io/log" + sdkmath "cosmossdk.io/math" + "cosmossdk.io/store" + storetypes "cosmossdk.io/store/types" + upgradetypes "cosmossdk.io/x/upgrade/types" + dbm "github.com/cosmos/cosmos-db" "github.com/cosmos/cosmos-sdk/codec/types" - storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/bech32" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - tmos "github.com/tendermint/tendermint/libs/os" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - utypes "github.com/akash-network/node/upgrades/types" + "pkg.akt.dev/go/sdkutil" + + utypes "pkg.akt.dev/node/upgrades/types" ) +type TestnetDelegation struct { + Address sdk.AccAddress `json:"address"` + Amount sdk.Coin `json:"amount"` +} + type TestnetValidator struct { - OperatorAddress sdk.ValAddress + OperatorAddress sdk.Address ConsensusAddress sdk.ConsAddress ConsensusPubKey *types.Any Status stakingtypes.BondStatus Moniker string Commission stakingtypes.Commission - MinSelfDelegation sdk.Int + MinSelfDelegation sdkmath.Int Delegations []TestnetDelegation } -type TestnetUpgrade struct { - Name string -} - -type TestnetVotingPeriod struct { - time.Duration +type TestnetGov struct { + VotePeriod time.Duration `json:"vote_period"` + ExpeditedVotePeriod time.Duration `json:"expedited_vote_period"` } -type TestnetGovConfig struct { - VotingParams *struct { - VotingPeriod TestnetVotingPeriod `json:"voting_period,omitempty"` - } `json:"voting_params,omitempty"` +type TestnetUpgrade struct { + Name string } type TestnetAccount struct { @@ -49,45 +56,20 @@ type TestnetAccount struct { Balances []sdk.Coin `json:"balances"` } -type TestnetDelegation struct { - Address sdk.AccAddress `json:"address"` - Amount sdk.Coin `json:"amount"` -} - type TestnetConfig struct { Accounts []TestnetAccount Validators []TestnetValidator - Gov TestnetGovConfig + Gov TestnetGov Upgrade TestnetUpgrade } -func TrimQuotes(data string) string { - data = strings.TrimPrefix(data, "\"") - return strings.TrimSuffix(data, "\"") -} - -func (t *TestnetVotingPeriod) UnmarshalJSON(data []byte) error { - val := TrimQuotes(string(data)) - - if !strings.HasSuffix(val, "s") { - return fmt.Errorf("invalid format of voting period. must contain time unit. Valid time units are ns|us(µs)|ms|s|m|h") // nolint: goerr113 - } - - var err error - t.Duration, err = time.ParseDuration(val) - if err != nil { - return err - } - - return nil -} - // InitAkashAppForTestnet is broken down into two sections: // Required Changes: Changes that, if not made, will cause the testnet to halt or panic // Optional Changes: Changes to customize the testnet to one's liking (lower vote times, fund accounts, etc) func InitAkashAppForTestnet( app *AkashApp, - tcfg *TestnetConfig, + db dbm.DB, + tcfg TestnetConfig, ) *AkashApp { // // Required Changes: @@ -101,71 +83,80 @@ func InitAkashAppForTestnet( } }() - ctx := app.BaseApp.NewUncachedContext(true, tmproto.Header{}) + ctx := app.NewUncachedContext(true, tmproto.Header{}) + + // STAKING + // // Remove all validators from power store stakingKey := app.GetKey(stakingtypes.ModuleName) stakingStore := ctx.KVStore(stakingKey) - iterator := app.Keepers.Cosmos.Staking.ValidatorsPowerStoreIterator(ctx) - + iterator, err := app.Keepers.Cosmos.Staking.ValidatorsPowerStoreIterator(ctx) + if err != nil { + panic(err.Error()) + } for ; iterator.Valid(); iterator.Next() { stakingStore.Delete(iterator.Key()) } - if err := iterator.Close(); err != nil { - panic(err) - } - - // Remove all validators from last validators store - iterator = app.Keepers.Cosmos.Staking.LastValidatorsIterator(ctx) + _ = iterator.Close() + // Remove all validators from the last validators store + iterator, err = app.Keepers.Cosmos.Staking.LastValidatorsIterator(ctx) + if err != nil { + return nil + } for ; iterator.Valid(); iterator.Next() { stakingStore.Delete(iterator.Key()) } - if err := iterator.Close(); err != nil { - panic(err) - } + _ = iterator.Close() - // Remove all validators from validator store + // Remove all validators from the validator store iterator = storetypes.KVStorePrefixIterator(stakingStore, stakingtypes.ValidatorsKey) for ; iterator.Valid(); iterator.Next() { stakingStore.Delete(iterator.Key()) } - if err := iterator.Close(); err != nil { - panic(err) - } + _ = iterator.Close() // Remove all validators from unbonding queue iterator = storetypes.KVStorePrefixIterator(stakingStore, stakingtypes.ValidatorQueueKey) for ; iterator.Valid(); iterator.Next() { stakingStore.Delete(iterator.Key()) } - if err := iterator.Close(); err != nil { - panic(err) - } + _ = iterator.Close() // BANK // + // Fund localakash accounts for _, account := range tcfg.Accounts { err := app.Keepers.Cosmos.Bank.MintCoins(ctx, minttypes.ModuleName, account.Balances) if err != nil { - panic(err) + panic(err.Error()) } err = app.Keepers.Cosmos.Bank.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, account.Address, account.Balances) if err != nil { - panic(err) + panic(err.Error()) } } for _, val := range tcfg.Validators { + _, bz, err := bech32.DecodeAndConvert(val.OperatorAddress.String()) + if err != nil { + panic(err.Error()) + } + bech32Addr, err := bech32.ConvertAndEncode("akashvaloper", bz) + if err != nil { + panic(err.Error()) + } + // Create Validator struct for our new validator. newVal := stakingtypes.Validator{ - OperatorAddress: val.OperatorAddress.String(), + OperatorAddress: bech32Addr, ConsensusPubkey: val.ConsensusPubKey, Jailed: false, - Status: val.Status, - Tokens: sdk.NewInt(0), - DelegatorShares: sdk.MustNewDecFromStr("0"), + Status: stakingtypes.Bonded, + Tokens: sdkmath.NewInt(0), + DelegatorShares: sdkmath.LegacyMustNewDecFromStr("0"), Description: stakingtypes.Description{ Moniker: val.Moniker, }, @@ -174,52 +165,74 @@ func InitAkashAppForTestnet( } // Add our validator to power and last validators store - app.Keepers.Cosmos.Staking.SetValidator(ctx, newVal) + err = app.Keepers.Cosmos.Staking.SetValidator(ctx, newVal) + if err != nil { + panic(err.Error()) + } err = app.Keepers.Cosmos.Staking.SetValidatorByConsAddr(ctx, newVal) if err != nil { + panic(err.Error()) + } + err = app.Keepers.Cosmos.Staking.SetValidatorByPowerIndex(ctx, newVal) + if err != nil { + panic(err.Error()) + } + valAddr, err := sdk.ValAddressFromBech32(newVal.GetOperator()) + if err != nil { + panic(err.Error()) + } + err = app.Keepers.Cosmos.Staking.SetLastValidatorPower(ctx, valAddr, 0) + if err != nil { + panic(err.Error()) + } + if err := app.Keepers.Cosmos.Staking.Hooks().AfterValidatorCreated(ctx, valAddr); err != nil { panic(err) } - app.Keepers.Cosmos.Staking.SetValidatorByPowerIndex(ctx, newVal) - - valAddr := newVal.GetOperator() - app.Keepers.Cosmos.Staking.SetLastValidatorPower(ctx, valAddr, 0) - - app.Keepers.Cosmos.Distr.Hooks().AfterValidatorCreated(ctx, valAddr) - app.Keepers.Cosmos.Slashing.Hooks().AfterValidatorCreated(ctx, valAddr) - // DISTRIBUTION // // Initialize records for this validator across all distribution stores - app.Keepers.Cosmos.Distr.SetValidatorHistoricalRewards(ctx, valAddr, 0, distrtypes.NewValidatorHistoricalRewards(sdk.DecCoins{}, 1)) - app.Keepers.Cosmos.Distr.SetValidatorCurrentRewards(ctx, valAddr, distrtypes.NewValidatorCurrentRewards(sdk.DecCoins{}, 1)) - app.Keepers.Cosmos.Distr.SetValidatorAccumulatedCommission(ctx, valAddr, distrtypes.InitialValidatorAccumulatedCommission()) - app.Keepers.Cosmos.Distr.SetValidatorOutstandingRewards(ctx, valAddr, distrtypes.ValidatorOutstandingRewards{Rewards: sdk.DecCoins{}}) + valAddr, err = sdk.ValAddressFromBech32(newVal.GetOperator()) + if err != nil { + panic(err.Error()) + } + err = app.Keepers.Cosmos.Distr.SetValidatorHistoricalRewards(ctx, valAddr, 0, distrtypes.NewValidatorHistoricalRewards(sdk.DecCoins{}, 1)) + if err != nil { + panic(err.Error()) + } + err = app.Keepers.Cosmos.Distr.SetValidatorCurrentRewards(ctx, valAddr, distrtypes.NewValidatorCurrentRewards(sdk.DecCoins{}, 1)) + if err != nil { + panic(err.Error()) + } + err = app.Keepers.Cosmos.Distr.SetValidatorAccumulatedCommission(ctx, valAddr, distrtypes.InitialValidatorAccumulatedCommission()) + if err != nil { + panic(err.Error()) + } + err = app.Keepers.Cosmos.Distr.SetValidatorOutstandingRewards(ctx, valAddr, distrtypes.ValidatorOutstandingRewards{Rewards: sdk.DecCoins{}}) + if err != nil { + panic(err.Error()) + } // SLASHING // newConsAddr := val.ConsensusAddress - // Set validator signing info for our new validator. newValidatorSigningInfo := slashingtypes.ValidatorSigningInfo{ Address: newConsAddr.String(), StartHeight: app.LastBlockHeight() - 1, Tombstoned: false, } - - _, err = app.Keepers.Cosmos.Staking.ApplyAndReturnValidatorSetUpdates(ctx) + err = app.Keepers.Cosmos.Slashing.SetValidatorSigningInfo(ctx, newConsAddr, newValidatorSigningInfo) if err != nil { - panic(err) + panic(err.Error()) } - app.Keepers.Cosmos.Slashing.SetValidatorSigningInfo(ctx, newConsAddr, newValidatorSigningInfo) - for _, del := range val.Delegations { - vl, found := app.Keepers.Cosmos.Staking.GetValidator(ctx, valAddr) - if !found { - panic("validator not found") + vl, err := app.Keepers.Cosmos.Staking.GetValidator(ctx, valAddr) + if err != nil { + panic(err.Error()) } _, err = app.Keepers.Cosmos.Staking.Delegate(ctx, del.Address, del.Amount.Amount, stakingtypes.Unbonded, vl, true) @@ -228,7 +241,6 @@ func InitAkashAppForTestnet( } } } - // // Optional Changes: // @@ -236,9 +248,19 @@ func InitAkashAppForTestnet( // GOV // - voteParams := app.Keepers.Cosmos.Gov.GetVotingParams(ctx) - voteParams.VotingPeriod = tcfg.Gov.VotingParams.VotingPeriod.Duration - app.Keepers.Cosmos.Gov.SetVotingParams(ctx, voteParams) + govParams, err := app.Keepers.Cosmos.Gov.Params.Get(ctx) + if err != nil { + panic(err.Error()) + } + govParams.ExpeditedVotingPeriod = &tcfg.Gov.ExpeditedVotePeriod + govParams.VotingPeriod = &tcfg.Gov.VotePeriod + govParams.MinDeposit = sdk.NewCoins(sdk.NewInt64Coin(sdkutil.DenomUakt, 100000000)) + govParams.ExpeditedMinDeposit = sdk.NewCoins(sdk.NewInt64Coin(sdkutil.DenomUakt, 150000000)) + + err = app.Keepers.Cosmos.Gov.Params.Set(ctx, govParams) + if err != nil { + panic(err.Error()) + } // UPGRADE // @@ -253,17 +275,19 @@ func InitAkashAppForTestnet( panic(err) } + version := store.NewCommitMultiStore(db, log.NewNopLogger(), nil).LatestVersion() + 1 + for name, fn := range utypes.GetUpgradesList() { - upgrade, err := fn(app.Logger(), &app.App) + upgrade, err := fn(app.Log, app.App) if err != nil { panic(err) } if tcfg.Upgrade.Name == name { - app.Logger().Info(fmt.Sprintf("configuring upgrade `%s`", name)) + app.Log.Info(fmt.Sprintf("configuring upgrade `%s`", name)) if storeUpgrades := upgrade.StoreLoader(); storeUpgrades != nil && tcfg.Upgrade.Name == name { - app.Logger().Info(fmt.Sprintf("setting up store upgrades for `%s`", name)) - app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(app.LastBlockHeight(), storeUpgrades)) + app.Log.Info(fmt.Sprintf("setting up store upgrades for `%s`", name)) + app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(version, storeUpgrades)) } } } diff --git a/app/types/app.go b/app/types/app.go index bb362c9597..b07a4739bf 100644 --- a/app/types/app.go +++ b/app/types/app.go @@ -4,59 +4,105 @@ import ( "errors" "fmt" "reflect" + "sync" + "cosmossdk.io/log" + storetypes "cosmossdk.io/store/types" + evidencekeeper "cosmossdk.io/x/evidence/keeper" + evidencetypes "cosmossdk.io/x/evidence/types" + "cosmossdk.io/x/feegrant" + feegrantkeeper "cosmossdk.io/x/feegrant/keeper" + upgradekeeper "cosmossdk.io/x/upgrade/keeper" + upgradetypes "cosmossdk.io/x/upgrade/types" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/codec" + addresscodec "github.com/cosmos/cosmos-sdk/codec/address" + "github.com/cosmos/cosmos-sdk/runtime" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" - capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" + consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper" + crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" - evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper" - feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + "github.com/cosmos/cosmos-sdk/x/params" paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + paramproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal" slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" - upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" - ibctransferkeeper "github.com/cosmos/ibc-go/v4/modules/apps/transfer/keeper" - ibckeeper "github.com/cosmos/ibc-go/v4/modules/core/keeper" - - akeeper "github.com/akash-network/node/x/audit/keeper" - ckeeper "github.com/akash-network/node/x/cert/keeper" - dkeeper "github.com/akash-network/node/x/deployment/keeper" - ekeeper "github.com/akash-network/node/x/escrow/keeper" - agovkeeper "github.com/akash-network/node/x/gov/keeper" - ikeeper "github.com/akash-network/node/x/inflation/keeper" - mkeeper "github.com/akash-network/node/x/market/keeper" - pkeeper "github.com/akash-network/node/x/provider/keeper" - astakingkeeper "github.com/akash-network/node/x/staking/keeper" - tkeeper "github.com/akash-network/node/x/take/keeper" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + icacontrollertypes "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller/types" + icahosttypes "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/host/types" + "github.com/cosmos/ibc-go/v10/modules/apps/transfer" + ibctransferkeeper "github.com/cosmos/ibc-go/v10/modules/apps/transfer/keeper" + ibctransfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" + ibcclienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" + ibcconnectiontypes "github.com/cosmos/ibc-go/v10/modules/core/03-connection/types" + porttypes "github.com/cosmos/ibc-go/v10/modules/core/05-port/types" + ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported" + ibckeeper "github.com/cosmos/ibc-go/v10/modules/core/keeper" + ibctm "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" + emodule "pkg.akt.dev/go/node/escrow/module" + + atypes "pkg.akt.dev/go/node/audit/v1" + ctypes "pkg.akt.dev/go/node/cert/v1" + dtypes "pkg.akt.dev/go/node/deployment/v1" + dv1beta "pkg.akt.dev/go/node/deployment/v1beta3" + agovtypes "pkg.akt.dev/go/node/gov/v1beta3" + mtypes "pkg.akt.dev/go/node/market/v1beta4" + ptypes "pkg.akt.dev/go/node/provider/v1beta4" + astakingtypes "pkg.akt.dev/go/node/staking/v1beta3" + ttypes "pkg.akt.dev/go/node/take/v1" + "pkg.akt.dev/go/sdkutil" + + akeeper "pkg.akt.dev/node/x/audit/keeper" + ckeeper "pkg.akt.dev/node/x/cert/keeper" + dkeeper "pkg.akt.dev/node/x/deployment/keeper" + ekeeper "pkg.akt.dev/node/x/escrow/keeper" + mhooks "pkg.akt.dev/node/x/market/hooks" + mkeeper "pkg.akt.dev/node/x/market/keeper" + pkeeper "pkg.akt.dev/node/x/provider/keeper" + tkeeper "pkg.akt.dev/node/x/take/keeper" +) + +const ( + AccountAddressPrefix = "akash" ) var ErrEmptyFieldName = errors.New("empty field name") type AppKeepers struct { Cosmos struct { - Acct authkeeper.AccountKeeper - Authz authzkeeper.Keeper - FeeGrant feegrantkeeper.Keeper - Bank bankkeeper.Keeper - Cap *capabilitykeeper.Keeper - Staking *stakingkeeper.Keeper - Slashing slashingkeeper.Keeper - Mint mintkeeper.Keeper - Distr distrkeeper.Keeper - Gov govkeeper.Keeper - Crisis crisiskeeper.Keeper - Upgrade upgradekeeper.Keeper - Params paramskeeper.Keeper - IBC *ibckeeper.Keeper - Evidence evidencekeeper.Keeper - Transfer ibctransferkeeper.Keeper - ScopedIBCKeeper capabilitykeeper.ScopedKeeper - ScopedTransferKeeper capabilitykeeper.ScopedKeeper + Acct authkeeper.AccountKeeper + Authz authzkeeper.Keeper + FeeGrant feegrantkeeper.Keeper + Bank bankkeeper.Keeper + Staking *stakingkeeper.Keeper + Slashing slashingkeeper.Keeper + Mint mintkeeper.Keeper + Distr distrkeeper.Keeper + Gov *govkeeper.Keeper + Upgrade *upgradekeeper.Keeper + Crisis *crisiskeeper.Keeper //nolint: staticcheck + Params paramskeeper.Keeper //nolint: staticcheck + ConsensusParams *consensusparamkeeper.Keeper + IBC *ibckeeper.Keeper + Evidence *evidencekeeper.Keeper + Transfer ibctransferkeeper.Keeper } Akash struct { @@ -67,9 +113,10 @@ type AppKeepers struct { Provider pkeeper.IKeeper Audit akeeper.Keeper Cert ckeeper.Keeper - Inflation ikeeper.IKeeper - Staking astakingkeeper.IKeeper - Gov agovkeeper.IKeeper + } + + Modules struct { + TMLight ibctm.LightClientModule } } @@ -77,6 +124,426 @@ type App struct { Keepers AppKeepers Configurator module.Configurator MM *module.Manager + Log log.Logger + + // keys to access the substores + kOnce sync.Once + keys map[string]*storetypes.KVStoreKey + tkeys map[string]*storetypes.TransientStoreKey + memKeys map[string]*storetypes.MemoryStoreKey +} + +func (app *App) GenerateKeys() { + // Define what keys will be used in the cosmos-sdk key/value store. + // Cosmos-SDK modules each have a "key" that allows the application to reference what they've stored on the chain. + app.kOnce.Do(func() { + app.keys = storetypes.NewKVStoreKeys(kvStoreKeys()...) + + // Define transient store keys + app.tkeys = storetypes.NewTransientStoreKeys(transientStoreKeys()...) + + // MemKeys are for information that is stored only in RAM. + app.memKeys = storetypes.NewMemoryStoreKeys(memStoreKeys()...) + }) +} + +// GetSubspace gets existing substore from keeper. +func (app *App) GetSubspace(moduleName string) paramstypes.Subspace { + subspace, found := app.Keepers.Cosmos.Params.GetSubspace(moduleName) + if !found { + panic(fmt.Sprintf("params subspace \"%s\" not found", moduleName)) + } + return subspace +} + +// GetKVStoreKey gets KV Store keys. +func (app *App) GetKVStoreKey() map[string]*storetypes.KVStoreKey { + return app.keys +} + +// GetTransientStoreKey gets Transient Store keys. +func (app *App) GetTransientStoreKey() map[string]*storetypes.TransientStoreKey { + return app.tkeys +} + +// GetMemoryStoreKey get memory Store keys. +func (app *App) GetMemoryStoreKey() map[string]*storetypes.MemoryStoreKey { + return app.memKeys +} + +// GetKey returns the KVStoreKey for the provided store key. +// +// NOTE: This is solely to be used for testing purposes. +func (app *App) GetKey(storeKey string) *storetypes.KVStoreKey { + return app.keys[storeKey] +} + +// GetTKey returns the TransientStoreKey for the provided store key. +// +// NOTE: This is solely to be used for testing purposes. +func (app *App) GetTKey(storeKey string) *storetypes.TransientStoreKey { + return app.tkeys[storeKey] +} + +// GetMemKey returns the MemStoreKey for the provided mem key. +// +// NOTE: This is solely used for testing purposes. +func (app *App) GetMemKey(storeKey string) *storetypes.MemoryStoreKey { + return app.memKeys[storeKey] +} + +// InitSpecialKeepers initiates special keepers (crisis appkeeper, upgradekeeper, params keeper) +func (app *App) InitSpecialKeepers( + cdc codec.Codec, + legacyAmino *codec.LegacyAmino, + bApp *baseapp.BaseApp, + skipUpgradeHeights map[int64]bool, + homePath string) { + + app.GenerateKeys() + + app.Keepers.Cosmos.Params = initParamsKeeper( + cdc, + legacyAmino, + app.keys[paramstypes.StoreKey], + app.tkeys[paramstypes.TStoreKey], + ) + + // set the BaseApp's parameter store + { + keeper := consensusparamkeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(app.keys[consensusparamtypes.StoreKey]), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + runtime.EventService{}, + ) + + app.Keepers.Cosmos.ConsensusParams = &keeper + } + + bApp.SetParamStore(app.Keepers.Cosmos.ConsensusParams.ParamsStore) + + app.Keepers.Cosmos.Upgrade = upgradekeeper.NewKeeper( + skipUpgradeHeights, + runtime.NewKVStoreService(app.GetKey(upgradetypes.StoreKey)), + cdc, + homePath, + bApp, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) +} + +func (app *App) InitNormalKeepers( + cdc codec.Codec, + encodingConfig sdkutil.EncodingConfig, + bApp *baseapp.BaseApp, + maccPerms map[string][]string, + blockedAddresses map[string]bool, + invCheckPeriod uint, +) { + + legacyAmino := encodingConfig.Amino + + app.Keepers.Cosmos.Acct = authkeeper.NewAccountKeeper( + cdc, + runtime.NewKVStoreService(app.keys[authtypes.StoreKey]), + authtypes.ProtoBaseAccount, + maccPerms, + addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), + AccountAddressPrefix, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.Keepers.Cosmos.Bank = bankkeeper.NewBaseKeeper( + cdc, + runtime.NewKVStoreService(app.keys[banktypes.StoreKey]), + app.Keepers.Cosmos.Acct, + blockedAddresses, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + app.Log, + ) + + app.Keepers.Cosmos.Crisis = crisiskeeper.NewKeeper( //nolint: staticcheck + cdc, runtime.NewKVStoreService(app.keys[crisistypes.StoreKey]), + invCheckPeriod, + app.Keepers.Cosmos.Bank, + authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), + ) + + // add authz keeper + app.Keepers.Cosmos.Authz = authzkeeper.NewKeeper( + runtime.NewKVStoreService(app.keys[authzkeeper.StoreKey]), + cdc, + bApp.MsgServiceRouter(), + app.Keepers.Cosmos.Acct, + ) + + app.Keepers.Cosmos.Staking = stakingkeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(app.keys[stakingtypes.StoreKey]), + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), + ) + + app.Keepers.Cosmos.Distr = distrkeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(app.keys[distrtypes.StoreKey]), + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.Keepers.Cosmos.Staking, + authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.Keepers.Cosmos.Slashing = slashingkeeper.NewKeeper( + cdc, + legacyAmino, + runtime.NewKVStoreService(app.keys[slashingtypes.StoreKey]), + app.Keepers.Cosmos.Staking, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + // register IBC Keeper + app.Keepers.Cosmos.IBC = ibckeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(app.keys[ibcexported.StoreKey]), + app.GetSubspace(ibcexported.ModuleName), + app.Keepers.Cosmos.Upgrade, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + // create evidence keeper with evidence router + app.Keepers.Cosmos.Evidence = evidencekeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(app.keys[evidencetypes.StoreKey]), + app.Keepers.Cosmos.Staking, + app.Keepers.Cosmos.Slashing, + addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), + runtime.ProvideCometInfoService(), + ) + + app.Keepers.Cosmos.Mint = mintkeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(app.keys[minttypes.StoreKey]), + app.Keepers.Cosmos.Staking, + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + // register the proposal types + govRouter := govtypesv1.NewRouter() + govRouter. + AddRoute( + govtypes.RouterKey, + govtypesv1.ProposalHandler, + ). + AddRoute( + paramproposal.RouterKey, + params.NewParamChangeProposalHandler(app.Keepers.Cosmos.Params), + ) + + govConfig := govtypes.DefaultConfig() + // Set the maximum metadata length for government-related configurations to 10,200, deviating from the default value of 256. + govConfig.MaxMetadataLen = 10200 + + app.Keepers.Cosmos.Gov = govkeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(app.keys[govtypes.StoreKey]), + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + app.Keepers.Cosmos.Staking, + app.Keepers.Cosmos.Distr, + bApp.MsgServiceRouter(), + govConfig, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.Keepers.Cosmos.Gov.SetLegacyRouter(govRouter) + + app.Keepers.Cosmos.FeeGrant = feegrantkeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(app.keys[feegrant.StoreKey]), + app.Keepers.Cosmos.Acct, + ) + + // register Transfer Keepers + app.Keepers.Cosmos.Transfer = ibctransferkeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(app.keys[ibctransfertypes.StoreKey]), + app.GetSubspace(ibctransfertypes.ModuleName), + app.Keepers.Cosmos.IBC.ChannelKeeper, + app.Keepers.Cosmos.IBC.ChannelKeeper, + bApp.MsgServiceRouter(), + app.Keepers.Cosmos.Acct, + app.Keepers.Cosmos.Bank, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + transferIBCModule := transfer.NewIBCModule(app.Keepers.Cosmos.Transfer) + + // Create static IBC router, add transfer route, then set and seal it + ibcRouter := porttypes.NewRouter() + ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferIBCModule) + + app.Keepers.Cosmos.IBC.SetRouter(ibcRouter) + + /// Light client modules + clientKeeper := app.Keepers.Cosmos.IBC.ClientKeeper + storeProvider := app.Keepers.Cosmos.IBC.ClientKeeper.GetStoreProvider() + app.Keepers.Modules.TMLight = ibctm.NewLightClientModule(cdc, storeProvider) + + clientKeeper.AddRoute(ibctm.ModuleName, &app.Keepers.Modules.TMLight) + + app.Keepers.Akash.Take = tkeeper.NewKeeper( + cdc, + app.keys[ttypes.StoreKey], + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.Keepers.Akash.Escrow = ekeeper.NewKeeper( + cdc, + app.keys[emodule.StoreKey], + app.Keepers.Cosmos.Bank, + app.Keepers.Akash.Take, + app.Keepers.Cosmos.Authz, + app.Keepers.Cosmos.Distr.FeePool, + ) + + app.Keepers.Akash.Deployment = dkeeper.NewKeeper( + cdc, + app.keys[dtypes.StoreKey], + app.Keepers.Akash.Escrow, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.Keepers.Akash.Market = mkeeper.NewKeeper( + cdc, + app.keys[mtypes.StoreKey], + app.Keepers.Akash.Escrow, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.Keepers.Akash.Provider = pkeeper.NewKeeper( + cdc, + app.keys[ptypes.StoreKey], + ) + + app.Keepers.Akash.Audit = akeeper.NewKeeper( + cdc, + app.keys[atypes.StoreKey], + ) + + app.Keepers.Akash.Cert = ckeeper.NewKeeper( + cdc, + app.keys[ctypes.StoreKey], + ) +} + +func (app *App) SetupHooks() { + // register the staking hooks + app.Keepers.Cosmos.Staking.SetHooks( + stakingtypes.NewMultiStakingHooks( + app.Keepers.Cosmos.Distr.Hooks(), + app.Keepers.Cosmos.Slashing.Hooks(), + ), + ) + + app.Keepers.Cosmos.Gov.SetHooks( + govtypes.NewMultiGovHooks( + // insert governance hooks receivers here + ), + ) + + hook := mhooks.New( + app.Keepers.Akash.Deployment, + app.Keepers.Akash.Market, + ) + + app.Keepers.Akash.Escrow.AddOnAccountClosedHook(hook.OnEscrowAccountClosed) + app.Keepers.Akash.Escrow.AddOnPaymentClosedHook(hook.OnEscrowPaymentClosed) +} + +// initParamsKeeper init params keeper and its subspaces +func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey) paramskeeper.Keeper { // nolint: staticcheck + paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey) // nolint: staticcheck + + ibctable := ibcclienttypes.ParamKeyTable() + ibctable.RegisterParamSet(&ibcconnectiontypes.Params{}) + + paramsKeeper.Subspace(authtypes.ModuleName).WithKeyTable(authtypes.ParamKeyTable()) // nolint: staticcheck + paramsKeeper.Subspace(banktypes.ModuleName).WithKeyTable(banktypes.ParamKeyTable()) // nolint: staticcheck // SA1019 + paramsKeeper.Subspace(stakingtypes.ModuleName).WithKeyTable(stakingtypes.ParamKeyTable()) // nolint: staticcheck // SA1019 + paramsKeeper.Subspace(minttypes.ModuleName).WithKeyTable(minttypes.ParamKeyTable()) // nolint: staticcheck // SA1019 + paramsKeeper.Subspace(distrtypes.ModuleName).WithKeyTable(distrtypes.ParamKeyTable()) // nolint: staticcheck // SA1019 + paramsKeeper.Subspace(slashingtypes.ModuleName).WithKeyTable(slashingtypes.ParamKeyTable()) // nolint: staticcheck // SA1019 + paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govv1.ParamKeyTable()) // nolint: staticcheck // SA1019 + paramsKeeper.Subspace(crisistypes.ModuleName).WithKeyTable(crisistypes.ParamKeyTable()) // nolint: staticcheck // SA1019 + paramsKeeper.Subspace(ibctransfertypes.ModuleName).WithKeyTable(ibctransfertypes.ParamKeyTable()) + paramsKeeper.Subspace(ibcexported.ModuleName).WithKeyTable(ibctable) + paramsKeeper.Subspace(icacontrollertypes.SubModuleName) + paramsKeeper.Subspace(icahosttypes.SubModuleName) + + // akash params subspaces + paramsKeeper.Subspace(dtypes.ModuleName).WithKeyTable(dv1beta.ParamKeyTable()) + paramsKeeper.Subspace(mtypes.ModuleName).WithKeyTable(mtypes.ParamKeyTable()) + paramsKeeper.Subspace(astakingtypes.ModuleName).WithKeyTable(astakingtypes.ParamKeyTable()) // nolint: staticcheck // SA1019 + paramsKeeper.Subspace(agovtypes.ModuleName).WithKeyTable(agovtypes.ParamKeyTable()) // nolint: staticcheck // SA1019 + paramsKeeper.Subspace(ttypes.ModuleName).WithKeyTable(ttypes.ParamKeyTable()) // nolint: staticcheck // SA1019 + + return paramsKeeper +} + +func kvStoreKeys() []string { + keys := []string{ + consensusparamtypes.StoreKey, + authtypes.StoreKey, + feegrant.StoreKey, + authzkeeper.StoreKey, + banktypes.StoreKey, + stakingtypes.StoreKey, + minttypes.StoreKey, + distrtypes.StoreKey, + slashingtypes.StoreKey, + govtypes.StoreKey, + paramstypes.StoreKey, + ibcexported.StoreKey, + upgradetypes.StoreKey, + evidencetypes.StoreKey, + ibctransfertypes.StoreKey, + } + + keys = append(keys, akashKVStoreKeys()...) + + return keys +} + +func akashKVStoreKeys() []string { + return []string{ + ttypes.StoreKey, + emodule.StoreKey, + dtypes.StoreKey, + mtypes.StoreKey, + ptypes.StoreKey, + atypes.StoreKey, + ctypes.StoreKey, + } +} + +func transientStoreKeys() []string { + return []string{ + paramstypes.TStoreKey, + } +} + +func memStoreKeys() []string { + return []string{} } // FindStructField if an interface is either a struct or a pointer to a struct @@ -96,14 +563,14 @@ func FindStructField[C any](obj interface{}, fieldName string) (C, error) { field := rValue.Elem().FieldByName(fieldName) if !field.IsValid() { - return *new(C), fmt.Errorf("interface `%s` does not have the field `%s`", // nolint: goerr113 + return *new(C), fmt.Errorf("interface `%s` does not have the field `%s`", rValue.Type(), fieldName) } res, valid := field.Interface().(C) if !valid { - return *new(C), fmt.Errorf( // nolint: goerr113 + return *new(C), fmt.Errorf( "object's `%s` expected type `%s` does not match actual `%s`", fieldName, reflect.TypeOf(*new(C)), field.Type().String()) diff --git a/app/types/app_test.go b/app/types/app_test.go index ac559d2242..a7649548c1 100644 --- a/app/types/app_test.go +++ b/app/types/app_test.go @@ -1,4 +1,4 @@ -package types +package types //nolint: revive import ( "testing" diff --git a/app/upgrades.go b/app/upgrades.go index de636c080b..4ef4974195 100644 --- a/app/upgrades.go +++ b/app/upgrades.go @@ -3,11 +3,11 @@ package app import ( "fmt" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + upgradetypes "cosmossdk.io/x/upgrade/types" - utypes "github.com/akash-network/node/upgrades/types" + utypes "pkg.akt.dev/node/upgrades/types" // nolint: revive - _ "github.com/akash-network/node/upgrades" + _ "pkg.akt.dev/node/upgrades" ) func (app *AkashApp) registerUpgradeHandlers() error { @@ -16,19 +16,42 @@ func (app *AkashApp) registerUpgradeHandlers() error { return err } + if app.Keepers.Cosmos.Upgrade.IsSkipHeight(upgradeInfo.Height) { + return nil + } + + currentHeight := app.CommitMultiStore().LastCommitID().Version + + if upgradeInfo.Height == currentHeight+1 { + app.customPreUpgradeHandler(upgradeInfo) + } + for name, fn := range utypes.GetUpgradesList() { - app.Logger().Info(fmt.Sprintf("initializing upgrade `%s`", name)) - upgrade, err := fn(app.Logger(), &app.App) + upgrade, err := fn(app.Logger(), app.App) if err != nil { return fmt.Errorf("unable to unitialize upgrade `%s`: %w", name, err) } app.Keepers.Cosmos.Upgrade.SetUpgradeHandler(name, upgrade.UpgradeHandler()) - if storeUpgrades := upgrade.StoreLoader(); storeUpgrades != nil && upgradeInfo.Name == name { - app.Logger().Info(fmt.Sprintf("applying store upgrades for `%s`", name)) - app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, storeUpgrades)) + + if upgradeInfo.Name == name { + app.Logger().Info(fmt.Sprintf("configuring upgrade `%s`", name)) + if storeUpgrades := upgrade.StoreLoader(); storeUpgrades != nil && upgradeInfo.Name == name { + app.Logger().Info(fmt.Sprintf("setting up store upgrades for `%s`", name)) + app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, storeUpgrades)) + } } } + utypes.IterateMigrations(func(module string, version uint64, initfn utypes.NewMigrationFn) { + migrator := initfn(utypes.NewMigrator(app.cdc, app.GetKey(module))) + if err := app.Configurator.RegisterMigration(module, version, migrator.GetHandler()); err != nil { + panic(err) + } + }) + return nil } + +func (app *AkashApp) customPreUpgradeHandler(_ upgradetypes.Plan) { +} diff --git a/client/client.go b/client/client.go deleted file mode 100644 index 19032bb79a..0000000000 --- a/client/client.go +++ /dev/null @@ -1,71 +0,0 @@ -package client - -import ( - "context" - "errors" - "fmt" - "reflect" - - sdkclient "github.com/cosmos/cosmos-sdk/client" - - cmtrpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types" - - aclient "github.com/akash-network/akash-api/go/node/client" - cltypes "github.com/akash-network/akash-api/go/node/client/types" - "github.com/akash-network/akash-api/go/node/client/v1beta2" -) - -var ( - ErrInvalidClient = errors.New("invalid client") -) - -func DiscoverQueryClient(ctx context.Context, cctx sdkclient.Context) (v1beta2.QueryClient, error) { - var cl v1beta2.QueryClient - err := aclient.DiscoverQueryClient(ctx, cctx, func(i interface{}) error { - var valid bool - - if cl, valid = i.(v1beta2.QueryClient); !valid { - return fmt.Errorf("%w: expected %s, actual %s", ErrInvalidClient, reflect.TypeOf(cl), reflect.TypeOf(i)) - } - - return nil - }) - - if err != nil { - return nil, err - } - - return cl, nil -} - -func DiscoverClient(ctx context.Context, cctx sdkclient.Context, opts ...cltypes.ClientOption) (v1beta2.Client, error) { - var cl v1beta2.Client - - setupFn := func(i interface{}) error { - var valid bool - - if cl, valid = i.(v1beta2.Client); !valid { - return fmt.Errorf("%w: expected %s, actual %s", ErrInvalidClient, reflect.TypeOf(cl), reflect.TypeOf(i)) - } - - return nil - } - - err := aclient.DiscoverClient(ctx, cctx, setupFn, opts...) - - if err != nil { - return nil, err - } - - return cl, nil -} - -func RPCAkash(_ *cmtrpctypes.Context) (*aclient.Akash, error) { - result := &aclient.Akash{ - ClientInfo: &aclient.ClientInfo{ - ApiVersion: "v1beta2", - }, - } - - return result, nil -} diff --git a/client/utils.go b/client/utils.go index 900570d319..e3078e1906 100644 --- a/client/utils.go +++ b/client/utils.go @@ -3,10 +3,13 @@ package client import ( b64 "encoding/base64" + "github.com/spf13/pflag" + + errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/client/flags" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/query" - "github.com/spf13/pflag" ) // ReadPageRequest reads and builds the necessary page request flags for pagination. @@ -19,7 +22,7 @@ func ReadPageRequest(flagSet *pflag.FlagSet) (*query.PageRequest, error) { reverse, _ := flagSet.GetBool(flags.FlagReverse) if page > 1 && offset > 0 { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "page and offset cannot be used together") + return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "page and offset cannot be used together") } // Clear page key if using page numbers (page and key are mutually exclusive) @@ -32,7 +35,7 @@ func ReadPageRequest(flagSet *pflag.FlagSet) (*query.PageRequest, error) { var err error pageKey, err = b64.StdEncoding.DecodeString(pageKeyStr) if err != nil { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid pagination key") + return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "invalid pagination key") } } diff --git a/cmd/akash/cmd/app_creator.go b/cmd/akash/cmd/app_creator.go index 5d86c8e8bd..4d3abcaddc 100644 --- a/cmd/akash/cmd/app_creator.go +++ b/cmd/akash/cmd/app_creator.go @@ -1,31 +1,160 @@ package cmd import ( + "errors" "io" + "path/filepath" - "github.com/tendermint/tendermint/libs/log" - dbm "github.com/tendermint/tm-db" + "cosmossdk.io/store" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + "github.com/spf13/cast" + "github.com/spf13/viper" + "cosmossdk.io/log" + "cosmossdk.io/store/snapshots" + snapshottypes "cosmossdk.io/store/snapshots/types" + storetypes "cosmossdk.io/store/types" + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/baseapp" + sdkserver "github.com/cosmos/cosmos-sdk/server" servertypes "github.com/cosmos/cosmos-sdk/server/types" - akash "github.com/akash-network/node/app" - "github.com/akash-network/node/cmd/akash/cmd/testnetify" + cflags "pkg.akt.dev/go/cli/flags" + "pkg.akt.dev/go/sdkutil" + + akash "pkg.akt.dev/node/app" ) +type appCreator struct { + encCfg sdkutil.EncodingConfig +} + +func (a appCreator) newApp( + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + appOpts servertypes.AppOptions, +) servertypes.Application { + var cache storetypes.MultiStorePersistentCache + + if cast.ToBool(appOpts.Get(cflags.FlagInterBlockCache)) { + cache = store.NewCommitKVStoreCacheManager() + } + + skipUpgradeHeights := make(map[int64]bool) + for _, h := range cast.ToIntSlice(appOpts.Get(cflags.FlagUnsafeSkipUpgrades)) { + skipUpgradeHeights[int64(h)] = true + } + + pruningOpts, err := sdkserver.GetPruningOptionsFromFlags(appOpts) + if err != nil { + panic(err) + } + + homeDir := cast.ToString(appOpts.Get(cflags.FlagHome)) + chainID := cast.ToString(appOpts.Get(cflags.FlagChainID)) + if chainID == "" { + // fallback to genesis chain-id + genDocFile := filepath.Join(homeDir, cast.ToString(appOpts.Get("genesis_file"))) + appGenesis, err := genutiltypes.AppGenesisFromFile(genDocFile) + if err != nil { + panic(err) + } + + chainID = appGenesis.ChainID + } + + snapshotDir := filepath.Join(homeDir, "data", "snapshots") + snapshotDB, err := dbm.NewDB("metadata", sdkserver.GetAppDBBackend(appOpts), snapshotDir) + if err != nil { + panic(err) + } + + snapshotStore, err := snapshots.NewStore(snapshotDB, snapshotDir) + if err != nil { + panic(err) + } + + // BaseApp Opts + snapshotOptions := snapshottypes.NewSnapshotOptions( + cast.ToUint64(appOpts.Get(cflags.FlagStateSyncSnapshotInterval)), + cast.ToUint32(appOpts.Get(cflags.FlagStateSyncSnapshotKeepRecent)), + ) + + baseAppOptions := []func(*baseapp.BaseApp){ + baseapp.SetChainID(chainID), + baseapp.SetPruning(pruningOpts), + baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(cflags.FlagMinGasPrices))), + baseapp.SetHaltHeight(cast.ToUint64(appOpts.Get(cflags.FlagHaltHeight))), + baseapp.SetHaltTime(cast.ToUint64(appOpts.Get(cflags.FlagHaltTime))), + baseapp.SetMinRetainBlocks(cast.ToUint64(appOpts.Get(cflags.FlagMinRetainBlocks))), + baseapp.SetInterBlockCache(cache), + baseapp.SetTrace(cast.ToBool(appOpts.Get(cflags.FlagTrace))), + baseapp.SetIndexEvents(cast.ToStringSlice(appOpts.Get(cflags.FlagIndexEvents))), + baseapp.SetSnapshot(snapshotStore, snapshotOptions), + baseapp.SetIAVLCacheSize(cast.ToInt(appOpts.Get(cflags.FlagIAVLCacheSize))), + } + + return akash.NewApp( + logger, db, traceStore, true, cast.ToUint(appOpts.Get(cflags.FlagInvCheckPeriod)), skipUpgradeHeights, + a.encCfg, + appOpts, + baseAppOptions..., + ) +} + +func (a appCreator) appExport( + logger log.Logger, + db dbm.DB, + tio io.Writer, + height int64, + forZeroHeight bool, + jailAllowedAddrs []string, + appOpts servertypes.AppOptions, + modulesToExport []string, +) (servertypes.ExportedApp, error) { + var akashApp *akash.AkashApp + + homePath, ok := appOpts.Get(cflags.FlagHome).(string) + if !ok || homePath == "" { + return servertypes.ExportedApp{}, errors.New("application home is not set") + } + viperAppOpts, ok := appOpts.(*viper.Viper) + if !ok { + return servertypes.ExportedApp{}, errors.New("appOpts is not viper.Viper") + } + // overwrite the FlagInvCheckPeriod + viperAppOpts.Set(cflags.FlagInvCheckPeriod, 1) + appOpts = viperAppOpts + + if height != -1 { + akashApp = akash.NewApp(logger, db, tio, false, uint(1), map[int64]bool{}, a.encCfg, appOpts) + + if err := akashApp.LoadHeight(height); err != nil { + return servertypes.ExportedApp{}, err + } + } else { + akashApp = akash.NewApp(logger, db, tio, true, uint(1), map[int64]bool{}, a.encCfg, appOpts) + } + + return akashApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport) +} + +// newTestnetApp starts by running the normal newApp method. From there, the app interface returned is modified in order // for a testnet to be created from the provided app. -func newTestnetApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application { +func (a appCreator) newTestnetApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application { // Create an app and type cast to an AkashApp - app := newApp(logger, db, traceStore, appOpts) + app := a.newApp(logger, db, traceStore, appOpts) akashApp, ok := app.(*akash.AkashApp) if !ok { panic("app created from newApp is not of type AkashApp") } - tcfg, valid := appOpts.Get(testnetify.KeyTestnetConfig).(*akash.TestnetConfig) + tcfg, valid := appOpts.Get(cflags.KeyTestnetConfig).(akash.TestnetConfig) if !valid { panic("cflags.KeyTestnetConfig is not of type akash.TestnetConfig") } // Make modifications to the normal AkashApp required to run the network locally - return akash.InitAkashAppForTestnet(akashApp, tcfg) + return akash.InitAkashAppForTestnet(akashApp, db, tcfg) } diff --git a/cmd/akash/cmd/auth.go b/cmd/akash/cmd/auth.go index dc150a26b4..ab8d4670c7 100644 --- a/cmd/akash/cmd/auth.go +++ b/cmd/akash/cmd/auth.go @@ -11,7 +11,7 @@ import ( sdkclient "github.com/cosmos/cosmos-sdk/client" - ajwt "github.com/akash-network/akash-api/go/util/jwt" + ajwt "pkg.akt.dev/go/util/jwt" ) const ( @@ -35,7 +35,7 @@ func authJWTCmd() *cobra.Command { cmd := &cobra.Command{ Use: "jwt", Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(cmd *cobra.Command, _ []string) error { cctx, err := sdkclient.GetClientTxContext(cmd) if err != nil { return err diff --git a/cmd/akash/cmd/bech32.go b/cmd/akash/cmd/bech32.go index 50aae0d92f..b33fdafeee 100644 --- a/cmd/akash/cmd/bech32.go +++ b/cmd/akash/cmd/bech32.go @@ -1,9 +1,9 @@ package cmd import ( - "github.com/akash-network/akash-api/go/sdkutil" "github.com/cosmos/cosmos-sdk/types/bech32" "github.com/spf13/cobra" + "pkg.akt.dev/go/sdkutil" ) var flagBech32Prefix = "prefix" diff --git a/cmd/akash/cmd/flag_test.go b/cmd/akash/cmd/flag_test.go deleted file mode 100644 index 220283ded1..0000000000 --- a/cmd/akash/cmd/flag_test.go +++ /dev/null @@ -1,202 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - "os" - "testing" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/spf13/cobra" - "github.com/stretchr/testify/require" - tmcli "github.com/tendermint/tendermint/libs/cli" - - "github.com/akash-network/node/app" - "github.com/akash-network/node/testutil" - testutilcli "github.com/akash-network/node/testutil/cli" -) - -// TestContextFlags tests that all the flags which are set in client.Context are parsed correctly. -// This test has been added because recently the --home flag broke with cosmos-sdk@v0.43.0 upgrade. -func TestContextFlags(t *testing.T) { - tmpDir, err := os.MkdirTemp("", "test-akash-home") - require.NoError(t, err) - - // expected flag values - expectedFlagValues := map[string]interface{}{ - tmcli.OutputFlag: "test-output", // default = "json" - flags.FlagHome: tmpDir, - flags.FlagDryRun: true, // default = false - flags.FlagKeyringDir: "/test/keyring/dir", - flags.FlagChainID: "test-chain-id", - flags.FlagNode: "http://test-host:8080", // default = "tcp://localhost:26657" - flags.FlagHeight: int64(20), // default = 0 - flags.FlagUseLedger: true, // default = false - flags.FlagGenerateOnly: true, // default = false - flags.FlagOffline: true, // default = false - flags.FlagBroadcastMode: "async", // default = "sync" - flags.FlagSkipConfirmation: true, // default = false - flags.FlagSignMode: "direct", - flags.FlagFeeAccount: testutil.AccAddress(t).String(), - flags.FlagFrom: testutil.AccAddress(t).String(), - } - - tCases := []struct { - flag string - ctxFieldGetter func(ctx client.Context) interface{} - isQueryOnly bool - isTxOnly bool - }{ - { - flag: tmcli.OutputFlag, - ctxFieldGetter: func(ctx client.Context) interface{} { - return ctx.OutputFormat - }, - }, - { - flag: flags.FlagHome, - ctxFieldGetter: func(ctx client.Context) interface{} { - return ctx.HomeDir - }, - }, - { - flag: flags.FlagDryRun, - ctxFieldGetter: func(ctx client.Context) interface{} { - return ctx.Simulate - }, - }, - { - flag: flags.FlagKeyringDir, - ctxFieldGetter: func(ctx client.Context) interface{} { - return ctx.KeyringDir - }, - }, - { - flag: flags.FlagChainID, - ctxFieldGetter: func(ctx client.Context) interface{} { - return ctx.ChainID - }, - }, - { - flag: flags.FlagNode, - ctxFieldGetter: func(ctx client.Context) interface{} { - return ctx.NodeURI - }, - }, - { - flag: flags.FlagHeight, - ctxFieldGetter: func(ctx client.Context) interface{} { - return ctx.Height - }, - isQueryOnly: true, - }, - { - flag: flags.FlagUseLedger, - ctxFieldGetter: func(ctx client.Context) interface{} { - return ctx.UseLedger - }, - isQueryOnly: true, - }, - { - flag: flags.FlagGenerateOnly, - ctxFieldGetter: func(ctx client.Context) interface{} { - return ctx.GenerateOnly - }, - isTxOnly: true, - }, - { - flag: flags.FlagOffline, - ctxFieldGetter: func(ctx client.Context) interface{} { - return ctx.Offline - }, - isTxOnly: true, - }, - { - flag: flags.FlagBroadcastMode, - ctxFieldGetter: func(ctx client.Context) interface{} { - return ctx.BroadcastMode - }, - isTxOnly: true, - }, - { - flag: flags.FlagSkipConfirmation, - ctxFieldGetter: func(ctx client.Context) interface{} { - return ctx.SkipConfirm - }, - isTxOnly: true, - }, - { - flag: flags.FlagSignMode, - ctxFieldGetter: func(ctx client.Context) interface{} { - return ctx.SignModeStr - }, - isTxOnly: true, - }, - { - flag: flags.FlagFeeAccount, - ctxFieldGetter: func(ctx client.Context) interface{} { - return ctx.FeeGranter.String() - }, - isTxOnly: true, - }, - { - flag: flags.FlagFrom, - ctxFieldGetter: func(ctx client.Context) interface{} { - require.Equal(t, ctx.From, ctx.FromAddress.String()) - return ctx.From - }, - isTxOnly: true, - }, - } - - // test command - cmd := &cobra.Command{ - Use: "test", - PersistentPreRunE: GetPersistentPreRunE(app.MakeEncodingConfig(), []string{"AKASH"}), - } - cmd.PersistentFlags().String(flags.FlagHome, app.DefaultHome, "The application home directory") - cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID") - cmd.Flags().Int64(flags.FlagHeight, 0, "Use a specific height to query state at (this can error if the node is pruning state)") - flags.AddTxFlagsToCmd(cmd) - - // test runner - for _, tCase := range tCases { - testCase := tCase - t.Run(testCase.flag, func(t *testing.T) { - // set the run func - cmd.RunE = func(cmd *cobra.Command, args []string) error { - var clientCtx client.Context - - // prepare context - switch { - case testCase.isQueryOnly: - clientCtx, err = client.GetClientQueryContext(cmd) - require.NoError(t, err) - case testCase.isTxOnly: - clientCtx, err = client.GetClientTxContext(cmd) - require.NoError(t, err) - default: - clientCtx = client.GetClientContextFromCmd(cmd) - } - - // check that we got the expected flag value in context - require.Equal(t, expectedFlagValues[testCase.flag], testCase.ctxFieldGetter(clientCtx)) - - return nil - } - - // run the test command with expected flag value - _, err = testutilcli.ExecTestCLICmd( - context.Background(), - client.Context{}, - cmd, - fmt.Sprintf("--%s=%v", testCase.flag, expectedFlagValues[testCase.flag]), - ) - require.NoError(t, err) - }) - } - - // cleanup - require.NoError(t, os.RemoveAll(tmpDir)) -} diff --git a/cmd/akash/cmd/genaccounts.go b/cmd/akash/cmd/genaccounts.go index 2ed91f7289..bbc49ae1be 100644 --- a/cmd/akash/cmd/genaccounts.go +++ b/cmd/akash/cmd/genaccounts.go @@ -7,9 +7,9 @@ import ( "fmt" "github.com/spf13/cobra" + cflags "pkg.akt.dev/go/cli/flags" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/server" sdk "github.com/cosmos/cosmos-sdk/types" @@ -34,7 +34,7 @@ var ( // AddGenesisAccountCmd returns add-genesis-account cobra Command. func AddGenesisAccountCmd(defaultNodeHome string) *cobra.Command { cmd := &cobra.Command{ - Use: "add-genesis-account [address_or_key_name] [coin][,[coin]]", + Use: "add-account [address_or_key_name] [coin][,[coin]]", Short: "Add a genesis account to genesis.json", Long: `Add a genesis account to genesis.json. The provided account must specify the account address or key name and a list of initial coins. If a key name is given, @@ -54,10 +54,10 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa addr, err := sdk.AccAddressFromBech32(args[0]) if err != nil { inBuf := bufio.NewReader(cmd.InOrStdin()) - keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend) + keyringBackend, _ := cmd.Flags().GetString(cflags.FlagKeyringBackend) // attempt to lookup address from Keybase if no address was provided - kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, clientCtx.HomeDir, inBuf) + kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, clientCtx.HomeDir, inBuf, cdc) if err != nil { return err } @@ -67,7 +67,10 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa return fmt.Errorf("failed to get address from Keybase: %v", err) } - addr = info.GetAddress() + addr, err = info.GetAddress() + if err != nil { + return err + } } coins, err := sdk.ParseCoinsNormalized(args[1]) @@ -91,8 +94,10 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa baseAccount := authtypes.NewBaseAccount(addr, nil, 0, 0) if !vestingAmt.IsZero() { - baseVestingAccount := authvesting.NewBaseVestingAccount(baseAccount, vestingAmt.Sort(), vestingEnd) - + baseVestingAccount, err := authvesting.NewBaseVestingAccount(baseAccount, vestingAmt.Sort(), vestingEnd) + if err != nil { + panic(err) + } if (balances.Coins.IsZero() && !baseVestingAccount.OriginalVesting.IsZero()) || baseVestingAccount.OriginalVesting.IsAnyGT(balances.Coins) { return ErrVestingAmountGreater @@ -178,13 +183,13 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa }, } - cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") - cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, + cmd.Flags().String(cflags.FlagHome, defaultNodeHome, "The application home directory") + cmd.Flags().String(cflags.FlagKeyringBackend, cflags.DefaultKeyringBackend, "Select keyring's backend (os|file|kwallet|pass|test)") cmd.Flags().String(flagVestingAmt, "", "amount of coins for vesting accounts") cmd.Flags().Int64(flagVestingStart, 0, "schedule start time (unix epoch) for vesting accounts") cmd.Flags().Int64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts") - flags.AddQueryFlagsToCmd(cmd) + cflags.AddQueryFlagsToCmd(cmd) return cmd } diff --git a/cmd/akash/cmd/genesis.go b/cmd/akash/cmd/genesis.go new file mode 100644 index 0000000000..76453ed654 --- /dev/null +++ b/cmd/akash/cmd/genesis.go @@ -0,0 +1,274 @@ +package cmd + +import ( + "encoding/json" + "fmt" + "time" + + sdkmath "cosmossdk.io/math" + crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + "github.com/spf13/cobra" + "pkg.akt.dev/go/sdkutil" + + tmtypes "github.com/cometbft/cometbft/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/server" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/x/genutil" + + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +// PrepareGenesisCmd returns prepare-genesis cobra Command. +// + +func PrepareGenesisCmd(defaultNodeHome string, mbm module.BasicManager) *cobra.Command { + cmd := &cobra.Command{ + Use: "prepare-genesis", + Short: "Prepare a genesis file with initial setup", + Long: `Prepare a genesis file with initial setup. +Examples include: + - Setting module initial params + - Setting denom metadata +Example: + akash prepare-genesis mainnet akash-1 + - Check input genesis: + file is at ~/.akash/config/genesis.json +`, + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + depCdc := clientCtx.Codec + cdc := depCdc + serverCtx := server.GetServerContextFromCmd(cmd) + config := serverCtx.Config + + // read genesis file + genFile := config.GenesisFile() + appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile) + if err != nil { + return fmt.Errorf("failed to unmarshal genesis state: %w", err) + } + + // get genesis params + var genesisParams GenesisParams + network := args[0] + switch network { + case "testnet": + genesisParams = TestnetGenesisParams() + case "mainnet": + genesisParams = MainnetGenesisParams() + default: + return fmt.Errorf("please choose 'mainnet' or 'testnet'") + } + + // get genesis params + chainID := args[1] + + // run Prepare Genesis + appState, genDoc, err = PrepareGenesis(clientCtx, appState, genDoc, genesisParams, chainID) + if err != nil { + return err + } + + // validate genesis state + if err = mbm.ValidateGenesis(cdc, clientCtx.TxConfig, appState); err != nil { + return fmt.Errorf("error validating genesis file: %s", err.Error()) + } + + // save genesis + appStateJSON, err := json.Marshal(appState) + if err != nil { + return fmt.Errorf("failed to marshal application genesis state: %w", err) + } + + genDoc.AppState = appStateJSON + err = genutil.ExportGenesisFile(genDoc, genFile) + + return err + }, + } + + cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +func PrepareGenesis(clientCtx client.Context, appState map[string]json.RawMessage, genDoc *genutiltypes.AppGenesis, genesisParams GenesisParams, chainID string) (map[string]json.RawMessage, *genutiltypes.AppGenesis, error) { + depCdc := clientCtx.Codec + cdc := depCdc + + // chain params genesis + genDoc.ChainID = chainID + genDoc.GenesisTime = genesisParams.GenesisTime + genDoc.Consensus.Params = genesisParams.ConsensusParams + + // --- + // staking module genesis + stakingGenState := stakingtypes.GetGenesisStateFromAppState(depCdc, appState) + stakingGenState.Params = genesisParams.StakingParams + stakingGenStateBz, err := cdc.MarshalJSON(stakingGenState) + if err != nil { + return nil, nil, fmt.Errorf("failed to marshal staking genesis state: %w", err) + } + appState[stakingtypes.ModuleName] = stakingGenStateBz + + // mint module genesis + mintGenState := minttypes.DefaultGenesisState() + mintGenState.Params = genesisParams.MintParams + mintGenStateBz, err := cdc.MarshalJSON(mintGenState) + if err != nil { + return nil, nil, fmt.Errorf("failed to marshal mint genesis state: %w", err) + } + appState[minttypes.ModuleName] = mintGenStateBz + + // distribution module genesis + distributionGenState := distributiontypes.DefaultGenesisState() + distributionGenState.Params = genesisParams.DistributionParams + // TODO Set initial community pool + distributionGenState.FeePool.CommunityPool = sdk.NewDecCoins() + distributionGenStateBz, err := cdc.MarshalJSON(distributionGenState) + if err != nil { + return nil, nil, fmt.Errorf("failed to marshal distribution genesis state: %w", err) + } + appState[distributiontypes.ModuleName] = distributionGenStateBz + + // gov module genesis + govGenState := govtypesv1.DefaultGenesisState() + govGenState.DepositParams = genesisParams.GovParams.DepositParams + govGenState.TallyParams = genesisParams.GovParams.TallyParams + govGenState.VotingParams = genesisParams.GovParams.VotingParams + govGenStateBz, err := cdc.MarshalJSON(govGenState) + if err != nil { + return nil, nil, fmt.Errorf("failed to marshal gov genesis state: %w", err) + } + appState[govtypes.ModuleName] = govGenStateBz + + // crisis module genesis + crisisGenState := crisistypes.DefaultGenesisState() + crisisGenState.ConstantFee = genesisParams.CrisisConstantFee + // TODO Set initial community pool + // distributionGenState.FeePool.CommunityPool = sdk.NewDecCoins() + crisisGenStateBz, err := cdc.MarshalJSON(crisisGenState) + if err != nil { + return nil, nil, fmt.Errorf("failed to marshal crisis genesis state: %w", err) + } + appState[crisistypes.ModuleName] = crisisGenStateBz + + // slashing module genesis + slashingGenState := slashingtypes.DefaultGenesisState() + slashingGenState.Params = genesisParams.SlashingParams + slashingGenStateBz, err := cdc.MarshalJSON(slashingGenState) + if err != nil { + return nil, nil, fmt.Errorf("failed to marshal slashing genesis state: %w", err) + } + appState[slashingtypes.ModuleName] = slashingGenStateBz + + // return appState and genDoc + return appState, genDoc, nil +} + +type GenesisParams struct { + StrategicReserveAccounts []banktypes.Balance + + ConsensusParams *tmtypes.ConsensusParams + + GenesisTime time.Time + NativeCoinMetadatas []banktypes.Metadata + + StakingParams stakingtypes.Params + MintParams minttypes.Params + DistributionParams distributiontypes.Params + GovParams govtypesv1.Params + + CrisisConstantFee sdk.Coin + + SlashingParams slashingtypes.Params +} + +func MainnetGenesisParams() GenesisParams { + genParams := GenesisParams{} + + genParams.GenesisTime = time.Date(2021, 6, 18, 17, 0, 0, 0, time.UTC) // Jun 18, 2021 - 17:00 UTC + + genParams.NativeCoinMetadatas = []banktypes.Metadata{ + { + Description: "The native token of Akash", + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: sdkutil.DenomUakt, + Exponent: 0, + Aliases: nil, + }, + { + Denom: sdkutil.DenomAkt, + Exponent: sdkutil.DenomUaktExponent, + Aliases: nil, + }, + }, + Base: sdkutil.DenomUakt, + Display: sdkutil.DenomAkt, + }, + } + + genParams.StakingParams = stakingtypes.DefaultParams() + genParams.StakingParams.UnbondingTime = time.Hour * 24 * 7 * 2 // 2 weeks + genParams.StakingParams.MaxValidators = 100 + genParams.StakingParams.BondDenom = genParams.NativeCoinMetadatas[0].Base + genParams.StakingParams.MinCommissionRate = sdkmath.LegacyMustNewDecFromStr("0.05") + + genParams.DistributionParams = distributiontypes.DefaultParams() + genParams.DistributionParams.CommunityTax = sdkmath.LegacyMustNewDecFromStr("0") + genParams.DistributionParams.WithdrawAddrEnabled = true + + genParams.GovParams = govtypesv1.DefaultParams() + genParams.GovParams.DepositParams.MaxDepositPeriod = time.Hour * 24 * 14 // 2 weeks + genParams.GovParams.DepositParams.MinDeposit = sdk.NewCoins(sdk.NewCoin( + genParams.NativeCoinMetadatas[0].Base, + sdkmath.NewInt(2_500_000_000), + )) + genParams.GovParams.TallyParams.Quorum = sdkmath.LegacyMustNewDecFromStr("0.2") // 20% + genParams.GovParams.VotingParams.VotingPeriod = time.Hour * 24 * 3 // 3 days + + genParams.CrisisConstantFee = sdk.NewCoin( + genParams.NativeCoinMetadatas[0].Base, + sdkmath.NewInt(500_000_000_000), + ) + + genParams.SlashingParams = slashingtypes.DefaultParams() + genParams.SlashingParams.SignedBlocksWindow = int64(30000) // 30000 blocks (~41 hr at 5 second blocks) + genParams.SlashingParams.MinSignedPerWindow = sdkmath.LegacyMustNewDecFromStr("0.05") // 5% minimum liveness + genParams.SlashingParams.DowntimeJailDuration = time.Minute // 1 minute jail period + genParams.SlashingParams.SlashFractionDoubleSign = sdkmath.LegacyMustNewDecFromStr("0.05") // 5% double sign slashing + genParams.SlashingParams.SlashFractionDowntime = sdkmath.LegacyZeroDec() // 0% liveness slashing + + return genParams +} + +func TestnetGenesisParams() GenesisParams { + genParams := MainnetGenesisParams() + + genParams.GenesisTime = time.Now() + + genParams.StakingParams.UnbondingTime = time.Hour * 24 * 7 * 2 // 2 weeks + + genParams.GovParams.DepositParams.MinDeposit = sdk.NewCoins(sdk.NewCoin( + genParams.NativeCoinMetadatas[0].Base, + sdkmath.NewInt(1000000), // 1 AKT + )) + genParams.GovParams.TallyParams.Quorum = sdkmath.LegacyMustNewDecFromStr("0.0000000001") // 0.00000001% + genParams.GovParams.VotingParams.VotingPeriod = time.Second * 300 // 300 seconds + + return genParams +} diff --git a/cmd/akash/cmd/root.go b/cmd/akash/cmd/root.go index 73a9b799bd..bcb9967fef 100644 --- a/cmd/akash/cmd/root.go +++ b/cmd/akash/cmd/root.go @@ -2,95 +2,49 @@ package cmd import ( "context" - "io" - "os" - "path/filepath" + "github.com/cosmos/cosmos-sdk/x/crisis" "github.com/rs/zerolog" - "github.com/spf13/cast" "github.com/spf13/cobra" - cmtcfg "github.com/tendermint/tendermint/config" - cmtcli "github.com/tendermint/tendermint/libs/cli" - cmtlog "github.com/tendermint/tendermint/libs/log" - cmtrpc "github.com/tendermint/tendermint/rpc/core" - cmtrpcsrv "github.com/tendermint/tendermint/rpc/jsonrpc/server" - dbm "github.com/tendermint/tm-db" + cmtcfg "github.com/cometbft/cometbft/config" + cmtcli "github.com/cometbft/cometbft/libs/cli" - "github.com/cosmos/cosmos-sdk/baseapp" sdkclient "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/debug" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/keys" - "github.com/cosmos/cosmos-sdk/client/rpc" + "github.com/cosmos/cosmos-sdk/client/pruning" + "github.com/cosmos/cosmos-sdk/client/snapshot" sdkserver "github.com/cosmos/cosmos-sdk/server" - servertypes "github.com/cosmos/cosmos-sdk/server/types" - "github.com/cosmos/cosmos-sdk/simapp/params" - "github.com/cosmos/cosmos-sdk/snapshots" - "github.com/cosmos/cosmos-sdk/store" - sdk "github.com/cosmos/cosmos-sdk/types" - authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - vestingcli "github.com/cosmos/cosmos-sdk/x/auth/vesting/client/cli" - bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/cosmos-sdk/x/crisis" - genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" + rosettaCmd "github.com/cosmos/rosetta/cmd" + + "pkg.akt.dev/go/cli" + cflags "pkg.akt.dev/go/cli/flags" + "pkg.akt.dev/go/sdkutil" - "github.com/akash-network/node/app" - "github.com/akash-network/node/client" - "github.com/akash-network/node/cmd/akash/cmd/testnetify" - ecmd "github.com/akash-network/node/events/cmd" - utilcli "github.com/akash-network/node/util/cli" - "github.com/akash-network/node/util/server" + "pkg.akt.dev/node/app" + "pkg.akt.dev/node/cmd/akash/cmd/testnetify" ) // NewRootCmd creates a new root command for akash. It is called once in the // main function. -func NewRootCmd() (*cobra.Command, params.EncodingConfig) { - encodingConfig := app.MakeEncodingConfig() +func NewRootCmd() (*cobra.Command, sdkutil.EncodingConfig) { + encodingConfig := sdkutil.MakeEncodingConfig() + app.ModuleBasics().RegisterInterfaces(encodingConfig.InterfaceRegistry) rootCmd := &cobra.Command{ Use: "akash", Short: "Akash Blockchain Application", Long: "Akash CLI Utility.\n\nAkash is a peer-to-peer marketplace for computing resources and \na deployment platform for heavily distributed applications. \nFind out more at https://akash.network", SilenceUsage: true, - PersistentPreRunE: GetPersistentPreRunE(encodingConfig, []string{"AKASH"}), + PersistentPreRunE: cli.GetPersistentPreRunE(encodingConfig, []string{"AKASH"}, cli.DefaultHome), } - // register akash api routes - cmtrpc.Routes["akash"] = cmtrpcsrv.NewRPCFunc(client.RPCAkash, "") - initRootCmd(rootCmd, encodingConfig) return rootCmd, encodingConfig } -// GetPersistentPreRunE persistent prerun hook for root command -func GetPersistentPreRunE(encodingConfig params.EncodingConfig, envPrefixes []string) func(*cobra.Command, []string) error { - return func(cmd *cobra.Command, _ []string) error { - if err := utilcli.InterceptConfigsPreRunHandler(cmd, envPrefixes, false, "", nil); err != nil { - return err - } - - initClientCtx := sdkclient.Context{}. - WithCodec(encodingConfig.Marshaler). - WithInterfaceRegistry(encodingConfig.InterfaceRegistry). - WithTxConfig(encodingConfig.TxConfig). - WithLegacyAmino(encodingConfig.Amino). - WithInput(os.Stdin). - WithAccountRetriever(authtypes.AccountRetriever{}). - WithBroadcastMode(flags.BroadcastBlock). - WithHomeDir(app.DefaultHome) - - if err := sdkclient.SetCmdClientContextHandler(initClientCtx, cmd); err != nil { - return err - } - - return nil - } -} - // Execute executes the root command. func Execute(rootCmd *cobra.Command, envPrefix string) error { // Create and set a client.Context on the command's Context. During the pre-run @@ -99,21 +53,11 @@ func Execute(rootCmd *cobra.Command, envPrefix string) error { // and a Tendermint RPC. This requires the use of a pointer reference when // getting and setting the client.Context. Ideally, we utilize // https://github.com/spf13/cobra/pull/1118. - srvCtx := sdkserver.NewDefaultContext() - ctx := context.Background() - ctx = context.WithValue(ctx, sdkclient.ClientContextKey, &sdkclient.Context{}) - ctx = context.WithValue(ctx, sdkserver.ServerContextKey, srvCtx) - - rootCmd.PersistentFlags().String(flags.FlagLogLevel, zerolog.InfoLevel.String(), "The logging level (trace|debug|info|warn|error|fatal|panic)") - rootCmd.PersistentFlags().String(flags.FlagLogFormat, cmtcfg.LogFormatPlain, "The logging format (json|plain)") - rootCmd.PersistentFlags().Bool(utilcli.FlagLogColor, false, "Pretty logging output. Applied only when log_format=plain") - rootCmd.PersistentFlags().String(utilcli.FlagLogTimestamp, "", "Add timestamp prefix to the logs (rfc3339|rfc3339nano|kitchen)") - executor := cmtcli.PrepareBaseCmd(rootCmd, envPrefix, app.DefaultHome) - return executor.ExecuteContext(ctx) + return ExecuteWithCtx(context.Background(), rootCmd, envPrefix) } -// Execute executes the root command. +// ExecuteWithCtx executes the root command. func ExecuteWithCtx(ctx context.Context, rootCmd *cobra.Command, envPrefix string) error { // Create and set a client.Context on the command's Context. During the pre-run // of the root command, a default initialized client.Context is provided to @@ -126,163 +70,62 @@ func ExecuteWithCtx(ctx context.Context, rootCmd *cobra.Command, envPrefix strin ctx = context.WithValue(ctx, sdkclient.ClientContextKey, &sdkclient.Context{}) ctx = context.WithValue(ctx, sdkserver.ServerContextKey, srvCtx) - rootCmd.PersistentFlags().String(flags.FlagLogLevel, zerolog.InfoLevel.String(), "The logging level (trace|debug|info|warn|error|fatal|panic)") - rootCmd.PersistentFlags().String(flags.FlagLogFormat, cmtcfg.LogFormatPlain, "The logging format (json|plain)") - rootCmd.PersistentFlags().Bool(utilcli.FlagLogColor, false, "Pretty logging output. Applied only when log_format=plain") - rootCmd.PersistentFlags().String(utilcli.FlagLogTimestamp, "", "Add timestamp prefix to the logs (rfc3339|rfc3339nano|kitchen)") + rootCmd.PersistentFlags().String(cflags.FlagLogLevel, zerolog.InfoLevel.String(), "The logging level (trace|debug|info|warn|error|fatal|panic)") + rootCmd.PersistentFlags().String(cflags.FlagLogFormat, cmtcfg.LogFormatPlain, "The logging format (json|plain)") + rootCmd.PersistentFlags().Bool(cflags.FlagLogColor, false, "Pretty logging output. Applied only when log_format=plain") + rootCmd.PersistentFlags().String(cflags.FlagLogTimestamp, "", "Add timestamp prefix to the logs (rfc3339|rfc3339nano|kitchen)") executor := cmtcli.PrepareBaseCmd(rootCmd, envPrefix, app.DefaultHome) return executor.ExecuteContext(ctx) } -func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { +func initRootCmd(rootCmd *cobra.Command, encodingConfig sdkutil.EncodingConfig) { + ac := appCreator{encodingConfig} + + home := app.DefaultHome + debugCmd := debug.Cmd() debugCmd.AddCommand(ConvertBech32Cmd()) rootCmd.AddCommand( - rpc.StatusCommand(), - ecmd.EventCmd(), - QueryCmd(), - TxCmd(), + sdkserver.StatusCommand(), AuthCmd(), - keys.Commands(app.DefaultHome), - genutilcli.InitCmd(app.ModuleBasics(), app.DefaultHome), - genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultHome), - genutilcli.MigrateGenesisCmd(), - genutilcli.GenTxCmd(app.ModuleBasics(), encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, app.DefaultHome), - genutilcli.ValidateGenesisCmd(app.ModuleBasics()), - AddGenesisAccountCmd(app.DefaultHome), + cli.EventsCmd(), + cli.QueryCmd(), + cli.TxCmd(), + cli.KeysCmds(), + genesisCommand(encodingConfig), cmtcli.NewCompletionCmd(rootCmd, true), debugCmd, - sdkserver.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Marshaler), + rosettaCmd.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Codec), + pruning.Cmd(ac.newApp, home), + snapshot.Cmd(ac.newApp), + testnetCmd(app.ModuleBasics(), banktypes.GenesisBalancesIterator{}), + PrepareGenesisCmd(app.DefaultHome, app.ModuleBasics()), + testnetify.GetCmd(ac.newTestnetApp), ) - rootCmd.AddCommand(testnetify.GetCmd(newTestnetApp)) - rootCmd.AddCommand(server.Commands(app.DefaultHome, newApp, createAppAndExport, addModuleInitFlags)...) + cli.ServerCmds(rootCmd, home, ac.newApp, ac.appExport, addModuleInitFlags) rootCmd.SetOut(rootCmd.OutOrStdout()) rootCmd.SetErr(rootCmd.ErrOrStderr()) } func addModuleInitFlags(startCmd *cobra.Command) { - crisis.AddModuleInitFlags(startCmd) + crisis.AddModuleInitFlags(startCmd) //nolint: staticcheck } -func newApp(logger cmtlog.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application { - var cache sdk.MultiStorePersistentCache +// genesisCommand builds genesis-related `simd genesis` command. Users may provide application specific commands as a parameter +func genesisCommand(encodingConfig sdkutil.EncodingConfig, cmds ...*cobra.Command) *cobra.Command { + home := app.DefaultHome - if cast.ToBool(appOpts.Get(sdkserver.FlagInterBlockCache)) { - cache = store.NewCommitKVStoreCacheManager() - } + cmd := cli.GetGenesisCmd(app.ModuleBasics(), encodingConfig.TxConfig, app.DefaultHome, encodingConfig.SigningOptions.ValidatorAddressCodec) - skipUpgradeHeights := make(map[int64]bool) - for _, h := range cast.ToIntSlice(appOpts.Get(sdkserver.FlagUnsafeSkipUpgrades)) { - skipUpgradeHeights[int64(h)] = true + for _, subCmd := range cmds { + cmd.AddCommand(subCmd) } - pruningOpts, err := sdkserver.GetPruningOptionsFromFlags(appOpts) - if err != nil { - panic(err) - } - - snapshotDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data", "snapshots") - snapshotDB, err := sdk.NewLevelDB("metadata", snapshotDir) - if err != nil { - panic(err) - } - snapshotStore, err := snapshots.NewStore(snapshotDB, snapshotDir) - if err != nil { - panic(err) - } - - return app.NewApp( - logger, db, traceStore, true, cast.ToUint(appOpts.Get(sdkserver.FlagInvCheckPeriod)), skipUpgradeHeights, - cast.ToString(appOpts.Get(flags.FlagHome)), - appOpts, - baseapp.SetPruning(pruningOpts), - baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(sdkserver.FlagMinGasPrices))), - baseapp.SetHaltHeight(cast.ToUint64(appOpts.Get(sdkserver.FlagHaltHeight))), - baseapp.SetHaltTime(cast.ToUint64(appOpts.Get(sdkserver.FlagHaltTime))), - baseapp.SetMinRetainBlocks(cast.ToUint64(appOpts.Get(sdkserver.FlagMinRetainBlocks))), - baseapp.SetInterBlockCache(cache), - baseapp.SetTrace(cast.ToBool(appOpts.Get(sdkserver.FlagTrace))), - baseapp.SetIndexEvents(cast.ToStringSlice(appOpts.Get(sdkserver.FlagIndexEvents))), - baseapp.SetSnapshotStore(snapshotStore), - baseapp.SetSnapshotInterval(cast.ToUint64(appOpts.Get(sdkserver.FlagStateSyncSnapshotInterval))), - baseapp.SetSnapshotKeepRecent(cast.ToUint32(appOpts.Get(sdkserver.FlagStateSyncSnapshotKeepRecent))), - ) -} - -func createAppAndExport( - logger cmtlog.Logger, - db dbm.DB, - tio io.Writer, - height int64, - forZeroHeight bool, - jailAllowedAddrs []string, - appOpts servertypes.AppOptions, -) (servertypes.ExportedApp, error) { - var akashApp *app.AkashApp - - if height != -1 { - akashApp = app.NewApp(logger, db, tio, false, uint(1), map[int64]bool{}, "", appOpts) - - if err := akashApp.LoadHeight(height); err != nil { - return servertypes.ExportedApp{}, err - } - } else { - akashApp = app.NewApp(logger, db, tio, true, uint(1), map[int64]bool{}, "", appOpts) - } - - return akashApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) -} - -func QueryCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "query", - Aliases: []string{"q"}, - Short: "Querying subcommands", - } - - cmd.AddCommand( - authcmd.GetAccountCmd(), - flags.LineBreak, - rpc.ValidatorCommand(), - rpc.BlockCommand(), - authcmd.QueryTxsByEventsCmd(), - authcmd.QueryTxCmd(), - flags.LineBreak, - ) - - app.ModuleBasics().AddQueryCommands(cmd) - cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID") - return cmd -} - -func TxCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "tx", - Short: "Transactions subcommands", - } - - cmd.AddCommand( - bankcmd.NewSendTxCmd(), - flags.LineBreak, - authcmd.GetSignCommand(), - authcmd.GetSignBatchCommand(), - authcmd.GetMultiSignCommand(), - authcmd.GetValidateSignaturesCommand(), - flags.LineBreak, - authcmd.GetBroadcastCommand(), - authcmd.GetEncodeCommand(), - authcmd.GetDecodeCommand(), - flags.LineBreak, - vestingcli.GetTxCmd(), - ) - - // add modules' tx commands - app.ModuleBasics().AddTxCommands(cmd) - cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID") + cmd.AddCommand(AddGenesisAccountCmd(home)) return cmd } diff --git a/cmd/akash/cmd/testnet.go b/cmd/akash/cmd/testnet.go new file mode 100644 index 0000000000..291049cb93 --- /dev/null +++ b/cmd/akash/cmd/testnet.go @@ -0,0 +1,412 @@ +package cmd + +// DONTCOVER + +import ( + "bufio" + "context" + "encoding/json" + "fmt" + "net" + "os" + "path/filepath" + + sdkmath "cosmossdk.io/math" + tmconfig "github.com/cometbft/cometbft/config" + tmos "github.com/cometbft/cometbft/libs/os" + tmrand "github.com/cometbft/cometbft/libs/rand" + "github.com/cometbft/cometbft/types" + tmtime "github.com/cometbft/cometbft/types/time" + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/server" + srvconfig "github.com/cosmos/cosmos-sdk/server/config" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/cosmos-sdk/x/genutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +var ( + flagNodeDirPrefix = "node-dir-prefix" + flagNumValidators = "v" + flagOutputDir = "output-dir" + flagNodeDaemonHome = "node-daemon-home" + flagStartingIPAddress = "starting-ip-address" + flagKeyAlgorithm = "key-algorithm" + + emptyMnemonic = "" +) + +// testnetCmd gets the cmd to initialize all files for tendermint testnet and application. +func testnetCmd(mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator) *cobra.Command { + cmd := &cobra.Command{ + Use: "testnet", + Short: "Initialize files for a simapp testnet", + Long: `testnet will create "v" number of directories and populate each with +necessary files (private validator, genesis, config, etc.). + +Note, strict routability for addresses is turned off in the config file. + +Example: + osmosisd testnet --v 4 --output-dir ./output --starting-ip-address 192.168.10.2 + `, + RunE: func(cmd *cobra.Command, _ []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + serverCtx := server.GetServerContextFromCmd(cmd) + config := serverCtx.Config + + outputDir, _ := cmd.Flags().GetString(flagOutputDir) + keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend) + chainID, _ := cmd.Flags().GetString(flags.FlagChainID) + minGasPrices, _ := cmd.Flags().GetString(server.FlagMinGasPrices) + nodeDirPrefix, _ := cmd.Flags().GetString(flagNodeDirPrefix) + nodeDaemonHome, _ := cmd.Flags().GetString(flagNodeDaemonHome) + startingIPAddress, _ := cmd.Flags().GetString(flagStartingIPAddress) + numValidators, _ := cmd.Flags().GetInt(flagNumValidators) + algo, _ := cmd.Flags().GetString(flagKeyAlgorithm) + + if chainID == "" { + chainID = "chain-" + tmrand.NewRand().Str(6) + } + + // get testnet genesis params + genesisParams := TestnetGenesisParams() + + return InitTestnet( + clientCtx, cmd, config, mbm, genBalIterator, genesisParams, chainID, outputDir, minGasPrices, + nodeDirPrefix, nodeDaemonHome, startingIPAddress, keyringBackend, algo, numValidators, + ) + }, + } + + cmd.Flags().Int(flagNumValidators, 4, "Number of validators to initialize the testnet with") + cmd.Flags().StringP(flagOutputDir, "o", "./mytestnet", "Directory to store initialization data for the testnet") + cmd.Flags().String(flagNodeDirPrefix, "node", "Prefix the directory name for each node with (node results in node0, node1, ...)") + cmd.Flags().String(flagNodeDaemonHome, "osmosisd", "Home directory of the node's daemon configuration") + cmd.Flags().String(flagStartingIPAddress, "192.168.0.1", "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)") + cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created") + cmd.Flags().String(server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", TestnetGenesisParams().NativeCoinMetadatas[0].Base), "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.001uakt)") + cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)") + cmd.Flags().String(flagKeyAlgorithm, string(hd.Secp256k1Type), "Key signing algorithm to generate keys for") + + return cmd +} + +const nodeDirPerm = 0o755 + +// InitTestnet initializes the testnet. +func InitTestnet( + clientCtx client.Context, + cmd *cobra.Command, + nodeConfig *tmconfig.Config, + mbm module.BasicManager, + genBalIterator banktypes.GenesisBalancesIterator, + genesisParams GenesisParams, + chainID string, + outputDir, + minGasPrices, + nodeDirPrefix, + nodeDaemonHome, + startingIPAddress, + keyringBackend, + algoStr string, + numValidators int, +) error { + nodeIDs := make([]string, numValidators) + valPubKeys := make([]cryptotypes.PubKey, numValidators) + + simappConfig := srvconfig.DefaultConfig() + simappConfig.MinGasPrices = minGasPrices + simappConfig.API.Enable = true + simappConfig.Telemetry.Enabled = true + simappConfig.Telemetry.PrometheusRetentionTime = 60 + simappConfig.Telemetry.EnableHostnameLabel = false + simappConfig.Telemetry.GlobalLabels = [][]string{{"chain_id", chainID}} + + var ( + genAccounts []authtypes.GenesisAccount + genBalances []banktypes.Balance + genFiles []string + ) + + inBuf := bufio.NewReader(cmd.InOrStdin()) + // generate private keys, node IDs, and initial transactions + for i := 0; i < numValidators; i++ { + nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i) + nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome) + gentxsDir := filepath.Join(outputDir, "gentxs") + + nodeConfig.SetRoot(nodeDir) + nodeConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657" + + if err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm); err != nil { + _ = os.RemoveAll(outputDir) + return err + } + + nodeConfig.Moniker = nodeDirName + + ip, err := getIP(i, startingIPAddress) + if err != nil { + _ = os.RemoveAll(outputDir) + return err + } + + nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(nodeConfig) + if err != nil { + _ = os.RemoveAll(outputDir) + return err + } + + memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip) + genFiles = append(genFiles, nodeConfig.GenesisFile()) + + kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, nodeDir, inBuf, nil) + if err != nil { + return err + } + + keyringAlgos, _ := kb.SupportedAlgorithms() + algo, err := keyring.NewSigningAlgoFromString(algoStr, keyringAlgos) + if err != nil { + return err + } + + addr, secret, err := testutil.GenerateSaveCoinKey(kb, nodeDirName, emptyMnemonic, true, algo) + if err != nil { + _ = os.RemoveAll(outputDir) + return err + } + + info := map[string]string{"secret": secret} + + cliPrint, err := json.Marshal(info) + if err != nil { + return err + } + + // save private key seed words + if err := writeFile(fmt.Sprintf("%v.json", "key_seed"), nodeDir, cliPrint); err != nil { + return err + } + + accTokens := sdk.TokensFromConsensusPower(1000, sdkmath.NewInt(1)) + accStakingTokens := sdk.TokensFromConsensusPower(500, sdkmath.NewInt(1)) + coins := sdk.Coins{ + sdk.NewCoin(fmt.Sprintf("%stoken", nodeDirName), accTokens), + sdk.NewCoin(genesisParams.NativeCoinMetadatas[0].Base, accStakingTokens), + } + + genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: coins.Sort()}) + genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0)) + + valTokens := sdk.TokensFromConsensusPower(100, sdkmath.NewInt(1)) + createValMsg, err := stakingtypes.NewMsgCreateValidator( + sdk.ValAddress(addr).String(), + valPubKeys[i], + sdk.NewCoin(genesisParams.NativeCoinMetadatas[0].Base, valTokens), + stakingtypes.NewDescription(nodeDirName, "", "", "", ""), + stakingtypes.NewCommissionRates(sdkmath.LegacyOneDec(), sdkmath.LegacyOneDec(), sdkmath.LegacyOneDec()), + sdkmath.OneInt(), + ) + if err != nil { + return err + } + + txBuilder := clientCtx.TxConfig.NewTxBuilder() + if err := txBuilder.SetMsgs(createValMsg); err != nil { + return err + } + + txBuilder.SetMemo(memo) + + txFactory := tx.Factory{} + txFactory = txFactory. + WithChainID(chainID). + WithMemo(memo). + WithKeybase(kb). + WithTxConfig(clientCtx.TxConfig) + + if err := tx.Sign(context.Background(), txFactory, nodeDirName, txBuilder, true); err != nil { + return err + } + + txBz, err := clientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx()) + if err != nil { + return err + } + + if err := writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBz); err != nil { + return err + } + + srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config/app.toml"), simappConfig) + } + + if err := initGenFiles(clientCtx, mbm, genesisParams, chainID, genAccounts, genBalances, genFiles, numValidators); err != nil { + return err + } + + err := collectGenFiles( + clientCtx, nodeConfig, chainID, nodeIDs, valPubKeys, numValidators, + outputDir, nodeDirPrefix, nodeDaemonHome, genBalIterator, + ) + if err != nil { + return err + } + + cmd.PrintErrf("Successfully initialized %d node directories\n", numValidators) + return nil +} + +// initGenFiles initializes genesis files for testnet. +func initGenFiles( + clientCtx client.Context, mbm module.BasicManager, genesisParams GenesisParams, chainID string, + genAccounts []authtypes.GenesisAccount, genBalances []banktypes.Balance, + genFiles []string, numValidators int, +) error { + appGenState := mbm.DefaultGenesis(clientCtx.Codec) + + // set the accounts in the genesis state + var authGenState authtypes.GenesisState + clientCtx.Codec.MustUnmarshalJSON(appGenState[authtypes.ModuleName], &authGenState) + + accounts, err := authtypes.PackAccounts(genAccounts) + if err != nil { + return err + } + + authGenState.Accounts = accounts + appGenState[authtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&authGenState) + + // set the balances in the genesis state + var bankGenState banktypes.GenesisState + clientCtx.Codec.MustUnmarshalJSON(appGenState[banktypes.ModuleName], &bankGenState) + + bankGenState.Balances = genBalances + appGenState[banktypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&bankGenState) + + appGenState, _, err = PrepareGenesis(clientCtx, appGenState, &genutiltypes.AppGenesis{}, genesisParams, chainID) + if err != nil { + return err + } + + appGenStateJSON, err := json.MarshalIndent(appGenState, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal application genesis state: %w", err) + } + + genDoc := types.GenesisDoc{ + ChainID: chainID, + AppState: appGenStateJSON, + Validators: nil, + } + + // generate empty genesis files for each validator and save + for i := 0; i < numValidators; i++ { + if err := genDoc.SaveAs(genFiles[i]); err != nil { + return err + } + } + return nil +} + +func collectGenFiles( + clientCtx client.Context, nodeConfig *tmconfig.Config, chainID string, + nodeIDs []string, valPubKeys []cryptotypes.PubKey, numValidators int, + outputDir, nodeDirPrefix, nodeDaemonHome string, genBalIterator banktypes.GenesisBalancesIterator, +) error { + var appState json.RawMessage + genTime := tmtime.Now() + + for i := 0; i < numValidators; i++ { + nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i) + nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome) + gentxsDir := filepath.Join(outputDir, "gentxs") + nodeConfig.Moniker = nodeDirName + + nodeConfig.SetRoot(nodeDir) + + nodeID, valPubKey := nodeIDs[i], valPubKeys[i] + initCfg := genutiltypes.NewInitConfig(chainID, gentxsDir, nodeID, valPubKey) + + _, genDoc, err := genutiltypes.GenesisStateFromGenFile(nodeConfig.GenesisFile()) + if err != nil { + return fmt.Errorf("failed to unmarshal genesis state: %w", err) + } + + nodeAppState, err := genutil.GenAppStateFromConfig(clientCtx.Codec, clientCtx.TxConfig, nodeConfig, initCfg, genDoc, genBalIterator, genutiltypes.DefaultMessageValidator, clientCtx.TxConfig.SigningContext().ValidatorAddressCodec()) + if err != nil { + return err + } + + if appState == nil { + // set the canonical application state (they should not differ) + appState = nodeAppState + } + + genFile := nodeConfig.GenesisFile() + + // overwrite each validator's genesis file to have a canonical genesis time + if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil { + return err + } + } + + return nil +} + +func getIP(i int, startingIPAddr string) (ip string, err error) { + if len(startingIPAddr) == 0 { + ip, err = server.ExternalIP() + if err != nil { + return "", err + } + return ip, nil + } + return calculateIP(startingIPAddr, i) +} + +func calculateIP(ip string, i int) (string, error) { + ipv4 := net.ParseIP(ip).To4() + if ipv4 == nil { + return "", fmt.Errorf("%v: non ipv4 address", ip) + } + + for j := 0; j < i; j++ { + ipv4[3]++ + } + + return ipv4.String(), nil +} + +func writeFile(name string, dir string, contents []byte) error { + writePath := dir + file := filepath.Join(writePath, name) + + err := tmos.EnsureDir(writePath, 0o755) + if err != nil { + return err + } + + err = tmos.WriteFile(file, contents, 0o644) + if err != nil { + return err + } + + return nil +} diff --git a/cmd/akash/cmd/testnetify/cmt_abci.go b/cmd/akash/cmd/testnetify/cmt_abci.go new file mode 100644 index 0000000000..f2ce4462ef --- /dev/null +++ b/cmd/akash/cmd/testnetify/cmt_abci.go @@ -0,0 +1,73 @@ +package testnetify + +import ( + "context" + + abci "github.com/cometbft/cometbft/abci/types" + + servertypes "github.com/cosmos/cosmos-sdk/server/types" +) + +type cometABCIWrapper struct { + app servertypes.ABCI +} + +func NewCometABCIWrapper(app servertypes.ABCI) abci.Application { + return cometABCIWrapper{app: app} +} + +func (w cometABCIWrapper) Info(_ context.Context, req *abci.RequestInfo) (*abci.ResponseInfo, error) { + return w.app.Info(req) +} + +func (w cometABCIWrapper) Query(ctx context.Context, req *abci.RequestQuery) (*abci.ResponseQuery, error) { + return w.app.Query(ctx, req) +} + +func (w cometABCIWrapper) CheckTx(_ context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { + return w.app.CheckTx(req) +} + +func (w cometABCIWrapper) InitChain(_ context.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) { + return w.app.InitChain(req) +} + +func (w cometABCIWrapper) PrepareProposal(_ context.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { + return w.app.PrepareProposal(req) +} + +func (w cometABCIWrapper) ProcessProposal(_ context.Context, req *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { + return w.app.ProcessProposal(req) +} + +func (w cometABCIWrapper) FinalizeBlock(_ context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { + return w.app.FinalizeBlock(req) +} + +func (w cometABCIWrapper) ExtendVote(ctx context.Context, req *abci.RequestExtendVote) (*abci.ResponseExtendVote, error) { + return w.app.ExtendVote(ctx, req) +} + +func (w cometABCIWrapper) VerifyVoteExtension(_ context.Context, req *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) { + return w.app.VerifyVoteExtension(req) +} + +func (w cometABCIWrapper) Commit(_ context.Context, _ *abci.RequestCommit) (*abci.ResponseCommit, error) { + return w.app.Commit() +} + +func (w cometABCIWrapper) ListSnapshots(_ context.Context, req *abci.RequestListSnapshots) (*abci.ResponseListSnapshots, error) { + return w.app.ListSnapshots(req) +} + +func (w cometABCIWrapper) OfferSnapshot(_ context.Context, req *abci.RequestOfferSnapshot) (*abci.ResponseOfferSnapshot, error) { + return w.app.OfferSnapshot(req) +} + +func (w cometABCIWrapper) LoadSnapshotChunk(_ context.Context, req *abci.RequestLoadSnapshotChunk) (*abci.ResponseLoadSnapshotChunk, error) { + return w.app.LoadSnapshotChunk(req) +} + +func (w cometABCIWrapper) ApplySnapshotChunk(_ context.Context, req *abci.RequestApplySnapshotChunk) (*abci.ResponseApplySnapshotChunk, error) { + return w.app.ApplySnapshotChunk(req) +} diff --git a/cmd/akash/cmd/testnetify/config.go b/cmd/akash/cmd/testnetify/config.go index 0f1c449277..f306a9923a 100644 --- a/cmd/akash/cmd/testnetify/config.go +++ b/cmd/akash/cmd/testnetify/config.go @@ -3,15 +3,16 @@ package testnetify import ( "strings" - "github.com/tendermint/tendermint/crypto" - cmtjson "github.com/tendermint/tendermint/libs/json" - pvm "github.com/tendermint/tendermint/privval" - "github.com/tendermint/tendermint/types" + "github.com/cometbft/cometbft/crypto" + cmtjson "github.com/cometbft/cometbft/libs/json" + pvm "github.com/cometbft/cometbft/privval" + "github.com/cometbft/cometbft/types" + sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - akash "github.com/akash-network/node/app" + akash "pkg.akt.dev/node/app" ) type PrivValidatorKey struct { @@ -45,7 +46,7 @@ type TestnetValidator struct { Operator AccAddress `json:"operator"` Status stakingtypes.BondStatus `json:"status"` Commission stakingtypes.Commission `json:"commission"` - MinSelfDelegation sdk.Int `json:"min_self_delegation"` + MinSelfDelegation sdkmath.Int `json:"min_self_delegation"` Home string `json:"home"` Delegations []akash.TestnetDelegation `json:"delegations"` @@ -61,7 +62,7 @@ type TestnetConfig struct { ChainID string `json:"chain_id"` Validators TestnetValidators `json:"validators"` Accounts []akash.TestnetAccount `json:"accounts"` - Gov akash.TestnetGovConfig `json:"gov"` + Gov akash.TestnetGov `json:"gov"` upgrade akash.TestnetUpgrade } diff --git a/cmd/akash/cmd/testnetify/testnetify.go b/cmd/akash/cmd/testnetify/testnetify.go index 62277c5f99..e335b3fe9e 100644 --- a/cmd/akash/cmd/testnetify/testnetify.go +++ b/cmd/akash/cmd/testnetify/testnetify.go @@ -2,6 +2,7 @@ package testnetify import ( "bufio" + "context" "encoding/hex" "encoding/json" "fmt" @@ -12,46 +13,46 @@ import ( "strings" "time" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/cobra" - "github.com/tendermint/tendermint/crypto/tmhash" - - "github.com/tendermint/tendermint/node" - pvm "github.com/tendermint/tendermint/privval" - cmtstate "github.com/tendermint/tendermint/proto/tendermint/state" - cmtproto "github.com/tendermint/tendermint/proto/tendermint/types" - "github.com/tendermint/tendermint/proxy" - "github.com/tendermint/tendermint/store" - cmttypes "github.com/tendermint/tendermint/types" - dbm "github.com/tendermint/tm-db" - + "golang.org/x/sync/errgroup" + + cmtcfg "github.com/cometbft/cometbft/config" + "github.com/cometbft/cometbft/crypto/tmhash" + "github.com/cometbft/cometbft/node" + pvm "github.com/cometbft/cometbft/privval" + cmtstate "github.com/cometbft/cometbft/proto/tendermint/state" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + "github.com/cometbft/cometbft/proxy" + sm "github.com/cometbft/cometbft/state" + "github.com/cometbft/cometbft/store" + cmttypes "github.com/cometbft/cometbft/types" + + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/client" codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" sdksrv "github.com/cosmos/cosmos-sdk/server" + serverconfig "github.com/cosmos/cosmos-sdk/server/config" "github.com/cosmos/cosmos-sdk/server/types" + "github.com/cosmos/cosmos-sdk/telemetry" sdktypes "github.com/cosmos/cosmos-sdk/types" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - akash "github.com/akash-network/node/app" -) - -const ( - // testnet keys - - FlagTraceStore = "trace-store" - FlagTestnetRootDir = "testnet-rootdir" - KeyTestnetRootDir = FlagTestnetRootDir + cflags "pkg.akt.dev/go/cli/flags" - KeyIsTestnet = "is-testnet" - KeyTestnetConfig = "testnet-config" - KeyTestnetTriggerUpgrade = "testnet-trigger-upgrade" + akash "pkg.akt.dev/node/app" + "pkg.akt.dev/node/util/server" ) // GetCmd uses the provided chainID and operatorAddress as well as the local private validator key to // control the network represented in the data folder. This is useful to create testnets nearly identical to your // mainnet environment. func GetCmd(testnetAppCreator types.AppCreator) *cobra.Command { + opts := sdksrv.StartCmdOptions{} + if opts.DBOpener == nil { + opts.DBOpener = openDB + } + cmd := &cobra.Command{ Use: "testnetify", Short: "Create a testnet from current local state", @@ -74,8 +75,8 @@ those stores will be registered in order to prevent panics. Therefore, you only you want to test the upgrade handler itself. `, Example: "testnetify", - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, args []string) error { + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, _ []string) error { sctx := sdksrv.GetServerContextFromCmd(cmd) cctx, err := client.GetClientQueryContext(cmd) if err != nil { @@ -87,19 +88,14 @@ you want to test the upgrade handler itself. return err } - rootDir, err := cmd.Flags().GetString(KeyTestnetRootDir) - if err != nil { - return err - } - sctx.Logger.Info("testnetifying blockchain state") cfg := TestnetConfig{} - cfgFilePath, err := cmd.Flags().GetString(KeyTestnetConfig) + cfgFilePath, err := cmd.Flags().GetString(cflags.KeyTestnetConfig) if err != nil { return err } - cfgFile, err := os.Open(cfgFilePath) + cfgFile, err := os.Open(cfgFilePath) //nolint: gosec if err != nil { return err } @@ -119,22 +115,22 @@ you want to test the upgrade handler itself. for i, acc := range cfg.Accounts { if len(acc.Balances) > 0 { - cfg.Accounts[i].Balances = sdk.NewCoins(acc.Balances...) + cfg.Accounts[i].Balances = sdktypes.NewCoins(acc.Balances...) } else { - cfg.Accounts[i].Balances = sdk.NewCoins( - sdk.NewInt64Coin("uakt", 10000000000000), - sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D84", 1000000000000), // axlUSDC + cfg.Accounts[i].Balances = sdktypes.NewCoins( + sdktypes.NewInt64Coin("uakt", 10000000000000), + sdktypes.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D84", 1000000000000), // axlUSDC ) } } sctx.Logger.Info(fmt.Sprintf("loaded config from %s", cfgFilePath)) - if name, _ := cmd.Flags().GetString(KeyTestnetTriggerUpgrade); name != "" { + if name, _ := cmd.Flags().GetString(cflags.KeyTestnetTriggerUpgrade); name != "" { cfg.upgrade.Name = name } - if skip, _ := cmd.Flags().GetBool(flags.FlagSkipConfirmation); !skip { + if skip, _ := cmd.Flags().GetBool(cflags.FlagSkipConfirmation); !skip { // Confirmation prompt to prevent accidental modification of state. reader := bufio.NewReader(os.Stdin) fmt.Println("This operation will modify state in your data folder and cannot be undone. Do you want to continue? (y/n)") @@ -146,12 +142,17 @@ you want to test the upgrade handler itself. } } + rootDir, err := cmd.Flags().GetString(cflags.FlagTestnetRootDir) + if err != nil { + return err + } + for i := range cfg.Validators { cfg.Validators[i].Home = filepath.Join(rootDir, cfg.Validators[i].Home) } home := sctx.Config.RootDir - db, err := openDB(home) + db, err := opts.DBOpener(home, server.GetAppDBBackend(sctx.Viper)) if err != nil { return err } @@ -166,24 +167,44 @@ you want to test the upgrade handler itself. return err } + srvCfg, err := serverconfig.GetConfig(sctx.Viper) + if err != nil { + return err + } + + if err := srvCfg.ValidateBasic(); err != nil { + return err + } + + metrics, err := telemetry.New(srvCfg.Telemetry) + if err != nil { + return err + } + + ctx, cancelFn := context.WithCancel(cmd.Context()) + + getCtx := func(svrCtx *sdksrv.Context, block bool) (*errgroup.Group, context.Context) { + g, ctx := errgroup.WithContext(ctx) + // listen for quit signals so the calling parent process can gracefully exit + server.ListenForQuitSignals(g, block, cancelFn, svrCtx.Logger) + return g, ctx + } + defer func() { traceCleanupFn() - - if localErr := db.Close(); localErr != nil { + if localErr := app.Close(); localErr != nil { sctx.Logger.Error(localErr.Error()) } }() go func() { defer func() { - if proc, err := os.FindProcess(os.Getpid()); err == nil { - _ = proc.Signal(os.Interrupt) - } + cancelFn() }() - ctx := cmd.Context() cctx, err := client.GetClientQueryContext(cmd) if err != nil { + sctx.Logger.Error("failed to get client context in monitor", "err", err) return } @@ -226,7 +247,9 @@ you want to test the upgrade handler itself. } }() - err = sdksrv.StartInProcess(sctx, cctx, app) + err = sdksrv.StartInProcess(sctx, srvCfg, cctx, app, metrics, sdksrv.StartCmdOptions{ + GetCtx: getCtx, + }) if err != nil && !strings.Contains(err.Error(), "130") { sctx.Logger.Error("testnetify finished with error", "err", err.Error()) return err @@ -234,19 +257,20 @@ you want to test the upgrade handler itself. sctx.Logger.Info("testnetify completed") - return nil + return err }, } - cmd.Flags().Bool(flags.FlagSkipConfirmation, false, "Skip the confirmation prompt") - cmd.Flags().String(KeyTestnetTriggerUpgrade, "", "If set (example: \"v1.0.0\"), triggers the v1.0.0 upgrade handler to run on the first block of the testnet") - cmd.Flags().StringP(KeyTestnetConfig, "c", "", "testnet config file config file") - cmd.Flags().String(KeyTestnetRootDir, "", "path to where testnet validators are located") - cmd.Flags().String(flags.FlagNode, "tcp://localhost:26657", "") - _ = cmd.MarkFlagRequired(KeyTestnetConfig) - _ = cmd.MarkFlagRequired(KeyTestnetRootDir) + cmd.Flags().Bool(cflags.FlagSkipConfirmation, false, "Skip the confirmation prompt") + cmd.Flags().String(cflags.KeyTestnetTriggerUpgrade, "", "If set (example: \"v1.0.0\"), triggers the v1.0.0 upgrade handler to run on the first block of the testnet") + cmd.Flags().StringP(cflags.KeyTestnetConfig, "c", "", "testnet config file config file") + cmd.Flags().String(cflags.KeyTestnetRootDir, "", "path to where testnet validators are located") + cmd.Flags().String(cflags.FlagNode, "tcp://localhost:26657", "") - cmd.MarkFlagsRequiredTogether(KeyTestnetConfig, KeyTestnetRootDir) + _ = cmd.MarkFlagRequired(cflags.KeyTestnetConfig) + _ = cmd.MarkFlagRequired(cflags.KeyTestnetRootDir) + + cmd.MarkFlagsRequiredTogether(cflags.KeyTestnetConfig, cflags.KeyTestnetRootDir) return cmd } @@ -254,51 +278,54 @@ you want to test the upgrade handler itself. // testnetify modifies both state and blockStore, allowing the provided operator address and local validator key to control the network // that the state in the data folder represents. The chainID of the local genesis file is modified to match the provided chainID. func testnetify(sctx *sdksrv.Context, tcfg TestnetConfig, testnetAppCreator types.AppCreator, db dbm.DB, traceWriter io.WriteCloser) (types.Application, error) { - cfg := sctx.Config + config := sctx.Config - thisVal := cfg.PrivValidatorKeyFile() - sort.Slice(tcfg.Validators, func(i, j int) bool { + thisVal := config.PrivValidatorKeyFile() + sort.Slice(tcfg.Validators, func(i, _ int) bool { return thisVal == tcfg.Validators[i].Home }) - newChainID := tcfg.ChainID - - // Modify app genesis chain ID and save to the genesis file. - genDocProvider := node.DefaultGenesisDocProviderFunc(cfg) - cGen, err := genDocProvider() + // Modify app genesis chain ID and save to a genesis file. + genFilePath := config.GenesisFile() + appGen, err := genutiltypes.AppGenesisFromFile(genFilePath) if err != nil { return nil, err } - cGen.GenesisDoc.ChainID = newChainID - err = cGen.GenesisDoc.ValidateAndComplete() - if err != nil { + newChainID := tcfg.ChainID + + appGen.ChainID = newChainID + if err := appGen.ValidateAndComplete(); err != nil { return nil, err } - - err = cGen.GenesisDoc.SaveAs(cfg.GenesisFile()) - if err != nil { + if err := appGen.SaveAs(genFilePath); err != nil { return nil, err } - blockStoreDB, err := node.DefaultDBProvider(&node.DBContext{ID: "blockstore", Config: cfg}) + // Load the comet genesis doc provider. + genDocProvider := node.DefaultGenesisDocProviderFunc(config) + + // Initialize blockStore and stateDB. + blockStoreDB, err := cmtcfg.DefaultDBProvider(&cmtcfg.DBContext{ID: "blockstore", Config: config}) if err != nil { return nil, err } blockStore := store.NewBlockStore(blockStoreDB) + defer func() { _ = blockStore.Close() }() - stateDB, err := node.DefaultDBProvider(&node.DBContext{ID: "state", Config: cfg}) + stateDB, err := cmtcfg.DefaultDBProvider(&cmtcfg.DBContext{ID: "state", Config: config}) if err != nil { return nil, err } + defer func() { _ = stateDB.Close() }() - jsonBlob, err := os.ReadFile(cfg.GenesisFile()) + jsonBlob, err := os.ReadFile(config.GenesisFile()) if err != nil { return nil, fmt.Errorf("couldn't read GenesisDoc file: %w", err) } @@ -310,7 +337,11 @@ func testnetify(sctx *sdksrv.Context, tcfg TestnetConfig, testnetAppCreator type return nil, node.ErrSaveGenesisDocHash{Err: err} } - state, stateStore, _, err := node.LoadStateFromDBOrGenesisDocProvider(stateDB, genDocProvider, hex.EncodeToString(updatedChecksum)) + stateStore := sm.NewStore(stateDB, sm.StoreOptions{ + DiscardABCIResponses: config.Storage.DiscardABCIResponses, + }) + + state, genDoc, err := node.LoadStateFromDBOrGenesisDocProvider(stateDB, genDocProvider, hex.EncodeToString(updatedChecksum)) if err != nil { return nil, err } @@ -354,13 +385,13 @@ func testnetify(sctx *sdksrv.Context, tcfg TestnetConfig, testnetAppCreator type } appConfig.Validators = append(appConfig.Validators, akash.TestnetValidator{ - OperatorAddress: val.Operator.Bytes(), + OperatorAddress: val.Operator, ConsensusAddress: pubKey.Address().Bytes(), ConsensusPubKey: consensusPubkey, + Status: val.Status, Moniker: val.Moniker, Commission: val.Commission, MinSelfDelegation: val.MinSelfDelegation, - Status: val.Status, Delegations: val.Delegations, }) @@ -370,22 +401,23 @@ func testnetify(sctx *sdksrv.Context, tcfg TestnetConfig, testnetAppCreator type tcfg.Validators[i].consAddress = pubKey.Address().Bytes() } - sctx.Viper.Set(KeyTestnetConfig, appConfig) + sctx.Viper.Set(cflags.KeyTestnetConfig, appConfig) testnetApp := testnetAppCreator(sctx.Logger, db, traceWriter, sctx.Viper) // We need to create a temporary proxyApp to get the initial state of the application. // Depending on how the node was stopped, the application height can differ from the blockStore height. // This height difference changes how we go about modifying the state. - cmtApp := testnetApp - + cmtApp := NewCometABCIWrapper(testnetApp) + _, ctx := getCtx(sctx, true) clientCreator := proxy.NewLocalClientCreator(cmtApp) - - proxyApp := proxy.NewAppConns(clientCreator) + metricsProvider := node.DefaultMetricsProvider(cmtcfg.DefaultConfig().Instrumentation) + _, _, _, _, proxyMetrics, _, _ := metricsProvider(genDoc.ChainID) + proxyApp := proxy.NewAppConns(clientCreator, proxyMetrics) if err := proxyApp.Start(); err != nil { return nil, fmt.Errorf("error starting proxy app connections: %w", err) } - res, err := proxyApp.Query().InfoSync(proxy.RequestInfo) + res, err := proxyApp.Query().Info(ctx, proxy.RequestInfo) if err != nil { return nil, fmt.Errorf("error calling Info: %w", err) } @@ -468,6 +500,7 @@ func testnetify(sctx *sdksrv.Context, tcfg TestnetConfig, testnetAppCreator type for _, del := range val.Delegations { vp += del.Amount.Amount.Quo(sdktypes.DefaultPowerReduction).Int64() } + newValidators = append(newValidators, &cmttypes.Validator{ Address: val.validatorAddress, PubKey: val.pubKey, @@ -476,7 +509,7 @@ func testnetify(sctx *sdksrv.Context, tcfg TestnetConfig, testnetAppCreator type } // Replace all valSets in state to be the valSet with just our validator. - // and set the very first validator as a proposer + // and set the very first validator as proposer newValSet := &cmttypes.ValidatorSet{ Validators: newValidators, Proposer: newValidators[0], @@ -490,6 +523,7 @@ func testnetify(sctx *sdksrv.Context, tcfg TestnetConfig, testnetAppCreator type seenCommit.BlockID = state.LastBlockID seenCommit.Round = 0 + seenCommit.Signatures = signatures err = blockStore.SaveSeenCommit(state.LastBlockHeight, seenCommit) diff --git a/cmd/akash/cmd/testnetify/utils.go b/cmd/akash/cmd/testnetify/utils.go index c2275a33fa..ca5564eaf0 100644 --- a/cmd/akash/cmd/testnetify/utils.go +++ b/cmd/akash/cmd/testnetify/utils.go @@ -1,25 +1,29 @@ package testnetify import ( + "context" "io" "os" "path/filepath" + dbm "github.com/cosmos/cosmos-db" sdksrv "github.com/cosmos/cosmos-sdk/server" - sdk "github.com/cosmos/cosmos-sdk/types" - dbm "github.com/tendermint/tm-db" + "golang.org/x/sync/errgroup" + cflags "pkg.akt.dev/go/cli/flags" + + "pkg.akt.dev/node/util/server" ) -func openDB(rootDir string) (dbm.DB, error) { +func openDB(rootDir string, backendType dbm.BackendType) (dbm.DB, error) { dataDir := filepath.Join(rootDir, "data") - return sdk.NewLevelDB("application", dataDir) + return dbm.NewDB("application", backendType, dataDir) } func setupTraceWriter(svrCtx *sdksrv.Context) (traceWriter io.WriteCloser, cleanup func(), err error) { // clean up the traceWriter when the server is shutting down cleanup = func() {} - traceWriterFile := svrCtx.Viper.GetString(FlagTraceStore) + traceWriterFile := svrCtx.Viper.GetString(cflags.FlagTraceStore) traceWriter, err = openTraceWriter(traceWriterFile) if err != nil { return traceWriter, cleanup, err @@ -41,9 +45,18 @@ func openTraceWriter(traceWriterFile string) (w io.WriteCloser, err error) { if traceWriterFile == "" { return } - return os.OpenFile( + return os.OpenFile( //nolint: gosec traceWriterFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0o666, ) } + +func getCtx(sctx *sdksrv.Context, block bool) (*errgroup.Group, context.Context) { + ctx, cancelFn := context.WithCancel(context.Background()) + g, ctx := errgroup.WithContext(ctx) + // listen for quit signals so the calling parent process can gracefully exit + server.ListenForQuitSignals(g, block, cancelFn, sctx.Logger) + + return g, ctx +} diff --git a/cmd/akash/main.go b/cmd/akash/main.go index 9945ee52a6..6e6b39237d 100644 --- a/cmd/akash/main.go +++ b/cmd/akash/main.go @@ -3,11 +3,9 @@ package main import ( "os" - "github.com/cosmos/cosmos-sdk/server" + _ "pkg.akt.dev/go/sdkutil" - _ "github.com/akash-network/akash-api/go/sdkutil" - - "github.com/akash-network/node/cmd/akash/cmd" + "pkg.akt.dev/node/cmd/akash/cmd" ) // In main we call the rootCmd @@ -15,11 +13,6 @@ func main() { rootCmd, _ := cmd.NewRootCmd() if err := cmd.Execute(rootCmd, "AKASH"); err != nil { - switch e := err.(type) { - case server.ErrorCode: - os.Exit(e.Code) - default: - os.Exit(1) - } + os.Exit(1) } } diff --git a/cmd/common/flags.go b/cmd/common/flags.go deleted file mode 100644 index ca321459f8..0000000000 --- a/cmd/common/flags.go +++ /dev/null @@ -1,97 +0,0 @@ -package common - -import ( - "context" - "encoding/json" - "errors" - "fmt" - - "github.com/akash-network/akash-api/go/node/client/v1beta2" - "github.com/cosmos/cosmos-sdk/x/params/types/proposal" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -const ( - FlagDeposit = "deposit" -) - -var ( - ErrUnknownSubspace = errors.New("unknown subspace") -) - -type paramCoin struct { - Denom string - Amount string -} - -type paramCoins []paramCoin - -func AddDepositFlags(flags *pflag.FlagSet) { - flags.String(FlagDeposit, "", "Deposit amount") -} - -func DetectDeposit(ctx context.Context, flags *pflag.FlagSet, cl v1beta2.QueryClient, subspace, paramKey string) (sdk.Coin, error) { - var deposit sdk.Coin - var depositStr string - var err error - - if !flags.Changed(FlagDeposit) { - res, err := cl.Params().Params(ctx, &proposal.QueryParamsRequest{ - Subspace: subspace, - Key: paramKey, - }) - if err != nil { - return sdk.Coin{}, err - } - - switch subspace { - case "market": - var coin paramCoin - - if err = json.Unmarshal([]byte(res.Param.Value), &coin); err != nil { - return sdk.Coin{}, err - } - - depositStr = fmt.Sprintf("%s%s", coin.Amount, coin.Denom) - case "deployment": - var coins paramCoins - - if err = json.Unmarshal([]byte(res.Param.Value), &coins); err != nil { - return sdk.Coin{}, err - } - - // always default to AKT - for _, sCoin := range coins { - if sCoin.Denom == "uakt" { - depositStr = fmt.Sprintf("%s%s", sCoin.Amount, sCoin.Denom) - break - } - } - default: - return sdk.Coin{}, ErrUnknownSubspace - } - - if depositStr == "" { - return sdk.Coin{}, fmt.Errorf("couldn't query default deposit amount for uAKT") - } - } else { - depositStr, err = flags.GetString(FlagDeposit) - if err != nil { - return sdk.Coin{}, err - } - } - - deposit, err = sdk.ParseCoinNormalized(depositStr) - if err != nil { - return sdk.Coin{}, err - } - - return deposit, nil -} - -func MarkReqDepositFlags(cmd *cobra.Command) { - _ = cmd.MarkFlagRequired(FlagDeposit) -} diff --git a/cmd/common/signal.go b/cmd/common/signal.go deleted file mode 100644 index 2c39bbc25c..0000000000 --- a/cmd/common/signal.go +++ /dev/null @@ -1,42 +0,0 @@ -package common - -import ( - "context" - "os" - "os/signal" - "syscall" -) - -func watchSignals(ctx context.Context, cancel context.CancelFunc) <-chan struct{} { - donech := make(chan struct{}) - sigch := make(chan os.Signal, 1) - signal.Notify(sigch, syscall.SIGINT, syscall.SIGHUP, syscall.SIGTERM) - go func() { - defer close(donech) - defer signal.Stop(sigch) - select { - case <-ctx.Done(): - case <-sigch: - cancel() - } - }() - return donech -} - -// RunForever runs a function in the background, forever. Returns error in case of failure. -func RunForever(fn func(ctx context.Context) error) error { - return RunForeverWithContext(context.Background(), fn) -} - -func RunForeverWithContext(ctx context.Context, fn func(ctx context.Context) error) error { - ctx, cancel := context.WithCancel(ctx) - - donech := watchSignals(ctx, cancel) - - err := fn(ctx) - - cancel() - <-donech - - return err -} diff --git a/cmd/common/util.go b/cmd/common/util.go deleted file mode 100644 index 291362daac..0000000000 --- a/cmd/common/util.go +++ /dev/null @@ -1,28 +0,0 @@ -package common - -import ( - "bytes" - "encoding/json" - "github.com/cosmos/cosmos-sdk/client" -) - -func PrintJSON(ctx client.Context, v interface{}) error { - marshaled, err := json.Marshal(v) - if err != nil { - return err - } - - buf := &bytes.Buffer{} - err = json.Indent(buf, marshaled, "", " ") - if err != nil { - return err - } - - // Add a newline, for printing in the terminal - _, err = buf.WriteRune('\n') - if err != nil { - return err - } - - return ctx.PrintString(buf.String()) -} diff --git a/cmd/common/util_test.go b/cmd/common/util_test.go deleted file mode 100644 index 83d5818ac4..0000000000 --- a/cmd/common/util_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package common - -import ( - "github.com/cosmos/cosmos-sdk/client" - "testing" -) - -func TestPrintJSONStdoutStruct(t *testing.T) { - ctx := client.Context{} - var x struct{ foo int } - x.foo = 55 - err := PrintJSON(ctx, x) - if err != nil { - t.Errorf("PrintJSON failed:[%T] %v", err, err) - } -} - -func TestPrintJSONStdoutInt(t *testing.T) { - ctx := client.Context{} - x := 123 - err := PrintJSON(ctx, x) - if err != nil { - t.Errorf("PrintJSON failed:[%T] %v", err, err) - } -} - -func TestPrintJSONStdoutNil(t *testing.T) { - ctx := client.Context{} - var x interface{} // implicitly nil - err := PrintJSON(ctx, x) - if err != nil { - t.Errorf("PrintJSON failed:[%T] %v", err, err) - } -} diff --git a/docgen/main.go b/docgen/main.go index 288b307550..c6567f060a 100644 --- a/docgen/main.go +++ b/docgen/main.go @@ -4,8 +4,8 @@ import ( "fmt" "os" - root "github.com/akash-network/node/cmd/akash/cmd" "github.com/spf13/cobra/doc" + root "pkg.akt.dev/node/cmd/akash/cmd" ) func main() { diff --git a/events/cmd/root.go b/events/cmd/root.go deleted file mode 100644 index ee541161b8..0000000000 --- a/events/cmd/root.go +++ /dev/null @@ -1,88 +0,0 @@ -package cmd - -import ( - "context" - "errors" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - - "github.com/spf13/cobra" - "github.com/spf13/viper" - "golang.org/x/sync/errgroup" - - "github.com/akash-network/node/cmd/common" - cmdcommon "github.com/akash-network/node/cmd/common" - "github.com/akash-network/node/events" - "github.com/akash-network/node/pubsub" -) - -// EventCmd prints out events in real time -func EventCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "events", - Short: "Prints out akash events in real time", - RunE: func(cmd *cobra.Command, args []string) error { - return common.RunForeverWithContext(cmd.Context(), func(ctx context.Context) error { - return getEvents(ctx, cmd, args) - }) - }, - } - - cmd.Flags().String(flags.FlagNode, "tcp://localhost:26657", "The node address") - if err := viper.BindPFlag(flags.FlagNode, cmd.Flags().Lookup(flags.FlagNode)); err != nil { - return nil - } - - return cmd -} - -func getEvents(ctx context.Context, cmd *cobra.Command, _ []string) error { - cctx := client.GetClientContextFromCmd(cmd) - - if err := cctx.Client.Start(); err != nil { - return err - } - - bus := pubsub.NewBus() - defer bus.Close() - - group, ctx := errgroup.WithContext(ctx) - - subscriber, err := bus.Subscribe() - if err != nil { - return err - } - - evtSvc, err := events.NewEvents(ctx, cctx.Client, "akash-cli", bus) - if err != nil { - return err - } - - group.Go(func() error { - <-ctx.Done() - evtSvc.Shutdown() - - return nil - }) - - group.Go(func() error { - for { - select { - case <-subscriber.Done(): - return nil - case ev := <-subscriber.Events(): - if err := cmdcommon.PrintJSON(cctx, ev); err != nil { - return err - } - } - } - }) - - err = group.Wait() - if err != nil && !errors.Is(err, context.Canceled) { - return err - } - - return nil -} diff --git a/events/publish.go b/events/publish.go deleted file mode 100644 index 87240bd0f5..0000000000 --- a/events/publish.go +++ /dev/null @@ -1,183 +0,0 @@ -package events - -import ( - "context" - - "github.com/boz/go-lifecycle" - sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" - tmclient "github.com/tendermint/tendermint/rpc/client" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - tmtmtypes "github.com/tendermint/tendermint/types" - "golang.org/x/sync/errgroup" - - atypes "github.com/akash-network/akash-api/go/node/audit/v1beta3" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - mtypes "github.com/akash-network/akash-api/go/node/market/v1beta4" - ptypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" - "github.com/akash-network/akash-api/go/sdkutil" - - "github.com/akash-network/node/pubsub" -) - -type events struct { - ctx context.Context - group *errgroup.Group - client tmclient.Client - bus pubsub.Bus - lc lifecycle.Lifecycle -} - -// Service represents an event monitoring service that subscribes to and processes blockchain events. -// It monitors block headers and various transaction events, publishing them to a message bus. -type Service interface { - // Shutdown gracefully stops the event monitoring service and cleans up resources. - // Once called, the service will unsubscribe from events and complete any pending operations. - Shutdown() -} - -// NewEvents creates and initializes a new blockchain event monitoring service. -// -// Parameters: -// - pctx: Parent context for controlling the service lifecycle -// - client: Tendermint RPC client for interacting with the blockchain -// - name: Service name used as a prefix for subscription identifiers -// - bus: Message bus for publishing processed events -// -// Returns: -// - Service: A running event monitoring service interface -// - error: Any error encountered during service initialization -// -// The service subscribes to block header events and processes them to extract and publish -// various transaction events (deployment, market, provider, audit) to the provided message bus. -// The service starts monitoring events immediately and will continue until either the context -// is canceled or Shutdown() is called. -func NewEvents(pctx context.Context, client tmclient.Client, name string, bus pubsub.Bus) (Service, error) { - group, ctx := errgroup.WithContext(pctx) - - ev := &events{ - ctx: ctx, - group: group, - client: client, - lc: lifecycle.New(), - bus: bus, - } - - const ( - queuesz = 1000 - ) - - var blkHeaderName = name + "-blk-hdr" - - tmbus := client.(tmclient.EventsClient) - - blkch, err := tmbus.Subscribe(ctx, blkHeaderName, blkHeaderQuery().String(), queuesz) - if err != nil { - return nil, err - } - - startch := make(chan struct{}, 1) - - group.Go(func() error { - ev.lc.WatchContext(ctx) - - return ev.lc.Error() - }) - - group.Go(func() error { - return ev.run(blkHeaderName, blkch, startch) - }) - - select { - case <-pctx.Done(): - return nil, pctx.Err() - case <-startch: - return ev, nil - } -} - -func (e *events) Shutdown() { - _, stopped := <-e.lc.Done() - if stopped { - return - } - - e.lc.Shutdown(nil) - - _ = e.group.Wait() -} - -func (e *events) run(subs string, ch <-chan ctypes.ResultEvent, startch chan<- struct{}) error { - tmbus := e.client.(tmclient.EventsClient) - - defer func() { - _ = tmbus.UnsubscribeAll(e.ctx, subs) - - e.lc.ShutdownCompleted() - }() - - startch <- struct{}{} - -loop: - for { - select { - case err := <-e.lc.ShutdownRequest(): - e.lc.ShutdownInitiated(err) - break loop - case ev := <-ch: - // nolint: gocritic - switch evt := ev.Data.(type) { - case tmtmtypes.EventDataNewBlockHeader: - e.processBlock(evt.Header.Height) - } - } - } - - return e.ctx.Err() -} - -func (e *events) processBlock(height int64) { - blkResults, err := e.client.BlockResults(e.ctx, &height) - if err != nil { - return - } - - for _, tx := range blkResults.TxsResults { - if tx == nil { - continue - } - - for _, ev := range tx.Events { - if mev, ok := processEvent(ev); ok { - if err := e.bus.Publish(mev); err != nil { - return - } - } - } - } -} - -func processEvent(bev abci.Event) (interface{}, bool) { - ev, err := sdkutil.ParseEvent(sdk.StringifyEvent(bev)) - if err != nil { - return nil, false - } - - if mev, err := dtypes.ParseEvent(ev); err == nil { - return mev, true - } - - if mev, err := mtypes.ParseEvent(ev); err == nil { - return mev, true - } - - if mev, err := ptypes.ParseEvent(ev); err == nil { - return mev, true - } - - if mev, err := atypes.ParseEvent(ev); err == nil { - return mev, true - } - - return nil, false -} diff --git a/events/publish_test.go b/events/publish_test.go deleted file mode 100644 index 8b480b1d9b..0000000000 --- a/events/publish_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package events - -import ( - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/assert" - - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - mtypes "github.com/akash-network/akash-api/go/node/market/v1beta4" - ptypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" - "github.com/akash-network/akash-api/go/sdkutil" - - "github.com/akash-network/node/testutil" -) - -func Test_processEvent(t *testing.T) { - tests := []sdkutil.ModuleEvent{ - // x/deployment events - dtypes.NewEventDeploymentCreated(testutil.DeploymentID(t), testutil.DeploymentVersion(t)), - dtypes.NewEventDeploymentUpdated(testutil.DeploymentID(t), testutil.DeploymentVersion(t)), - dtypes.NewEventDeploymentClosed(testutil.DeploymentID(t)), - dtypes.NewEventGroupClosed(testutil.GroupID(t)), - - // x/market events - mtypes.NewEventOrderCreated(testutil.OrderID(t)), - mtypes.NewEventOrderClosed(testutil.OrderID(t)), - mtypes.NewEventBidCreated(testutil.BidID(t), testutil.DecCoin(t)), - mtypes.NewEventBidClosed(testutil.BidID(t), testutil.DecCoin(t)), - mtypes.NewEventLeaseCreated(testutil.LeaseID(t), testutil.DecCoin(t)), - mtypes.NewEventLeaseClosed(testutil.LeaseID(t), testutil.DecCoin(t)), - - // x/provider events - ptypes.NewEventProviderCreated(testutil.AccAddress(t)), - ptypes.NewEventProviderUpdated(testutil.AccAddress(t)), - ptypes.NewEventProviderDeleted(testutil.AccAddress(t)), - } - - for _, test := range tests { - sdkevs := sdk.Events{ - test.ToSDKEvent(), - }.ToABCIEvents() - - sdkev := sdkevs[0] - - ev, ok := processEvent(sdkev) - assert.True(t, ok, test) - assert.Equal(t, test, ev, test) - } -} diff --git a/events/query.go b/events/query.go deleted file mode 100644 index 9a561870e5..0000000000 --- a/events/query.go +++ /dev/null @@ -1,23 +0,0 @@ -package events - -import ( - "fmt" - - "github.com/tendermint/tendermint/libs/pubsub" - tmquery "github.com/tendermint/tendermint/libs/pubsub/query" - tmtypes "github.com/tendermint/tendermint/types" -) - -// func txQuery() pubsub.Query { -// return tmquery.MustParse( -// fmt.Sprintf("%s='%s'", tmtypes.EventTypeKey, tmtypes.EventTx)) -// } -// -// func blkQuery() pubsub.Query { -// return tmquery.MustParse( -// fmt.Sprintf("%s='%s'", tmtypes.EventTypeKey, tmtypes.EventNewBlock)) -// } - -func blkHeaderQuery() pubsub.Query { - return tmquery.MustParse(fmt.Sprintf("%s='%s'", tmtypes.EventTypeKey, tmtypes.EventNewBlockHeader)) -} diff --git a/go.mod b/go.mod index bde7f825de..83dd5d122b 100644 --- a/go.mod +++ b/go.mod @@ -1,216 +1,287 @@ -module github.com/akash-network/node +module pkg.akt.dev/node -go 1.23.5 - -toolchain go1.23.6 +go 1.25.2 require ( - github.com/akash-network/akash-api v0.0.83 - github.com/blang/semver/v4 v4.0.0 + cosmossdk.io/api v0.9.2 + cosmossdk.io/collections v1.2.1 + cosmossdk.io/core v0.11.3 + cosmossdk.io/depinject v1.2.1 + cosmossdk.io/errors v1.0.2 + cosmossdk.io/log v1.6.0 + cosmossdk.io/math v1.5.3 + cosmossdk.io/store v1.1.2 + cosmossdk.io/x/evidence v0.2.0 + cosmossdk.io/x/feegrant v0.2.0 + cosmossdk.io/x/upgrade v0.2.0 github.com/boz/go-lifecycle v0.1.1 - github.com/cosmos/cosmos-sdk v0.45.16 - github.com/cosmos/go-bip39 v1.0.0 - github.com/cosmos/ibc-go/v4 v4.6.0 - github.com/gogo/protobuf v1.3.3 - github.com/golang-jwt/jwt/v5 v5.2.2 - github.com/google/go-github/v56 v56.0.0 + github.com/cometbft/cometbft v0.38.17 + github.com/cosmos/cosmos-db v1.1.1 + github.com/cosmos/cosmos-sdk v0.53.3 + github.com/cosmos/gogoproto v1.7.0 + github.com/cosmos/ibc-go/v10 v10.3.0 + github.com/cosmos/rosetta v0.50.12 + github.com/golang-jwt/jwt/v5 v5.2.3 + github.com/google/go-github/v62 v62.0.0 github.com/gorilla/mux v1.8.1 - github.com/gorilla/websocket v1.5.1 + github.com/gorilla/websocket v1.5.3 github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 github.com/grpc-ecosystem/grpc-gateway v1.16.0 - github.com/ianlancetaylor/cgosymbolizer v0.0.0-20240326020559-581a3f7c677f + github.com/ianlancetaylor/cgosymbolizer v0.0.0-20250410214317-b8ecc8b6bbe6 github.com/pkg/errors v0.9.1 - // don't upgrade it as current cosmos-sdk version uses some functions which were removed after v1.16.0 - github.com/prometheus/client_golang v1.23.0 + github.com/prometheus/client_golang v1.22.0 github.com/rakyll/statik v0.1.7 github.com/regen-network/cosmos-proto v0.3.1 - github.com/rs/zerolog v1.32.0 + github.com/rs/zerolog v1.34.0 github.com/spf13/cast v1.9.2 github.com/spf13/cobra v1.9.1 - github.com/spf13/pflag v1.0.6 + github.com/spf13/pflag v1.0.7 github.com/spf13/viper v1.20.1 - github.com/stretchr/testify v1.11.1 - github.com/tendermint/tendermint v0.34.27 - github.com/tendermint/tm-db v0.6.7 - go.step.sm/crypto v0.44.6 - golang.org/x/mod v0.26.0 + github.com/stretchr/testify v1.10.0 + go.step.sm/crypto v0.45.1 + golang.org/x/mod v0.25.0 golang.org/x/oauth2 v0.30.0 golang.org/x/sync v0.16.0 - google.golang.org/grpc v1.75.0 + google.golang.org/grpc v1.74.2 gopkg.in/yaml.v3 v3.0.1 -) - -retract ( - v0.36.3-rc4 - v0.34.0 - v0.28.1 - v0.28.0 - v0.26.0 - v0.22.1 -) - -replace ( - // use cosmos fork of keyring - github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 - github.com/cosmos/cosmos-sdk => github.com/akash-network/cosmos-sdk v0.45.16-akash.7 - - // use akash version of cosmos ledger api - github.com/cosmos/ledger-cosmos-go => github.com/akash-network/ledger-go/cosmos v0.15.0 - // dgrijalva/jwt-go is deprecated and doesn't receive security updates. - // TODO: remove it: https://github.com/cosmos/cosmos-sdk/issues/13134 - github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.2 - - // Fix upstream GHSA-h395-qcrw-5vmq vulnerability. - // TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 - github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.8.1 - // Use regen gogoproto fork - // To be replaced by cosmos/gogoproto in future versions - github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - // use cometBFT system fork of tendermint with akash patches - - github.com/tendermint/tendermint => github.com/akash-network/cometbft v0.34.27-akash.5 - - github.com/zondax/hid => github.com/troian/hid v0.13.2 - github.com/zondax/ledger-go => github.com/akash-network/ledger-go v0.15.1 - // latest grpc doesn't work with with cosmos-sdk modified proto compiler, so we need to enforce - // the following version across all dependencies. - google.golang.org/grpc => google.golang.org/grpc v1.33.2 + gotest.tools/v3 v3.5.2 + pkg.akt.dev/go v0.1.5 + pkg.akt.dev/go/cli v0.1.1 + pkg.akt.dev/go/sdl v0.1.1 ) require ( - cosmossdk.io/api v0.2.6 // indirect - cosmossdk.io/core v0.5.1 // indirect - cosmossdk.io/depinject v1.0.0-alpha.3 // indirect + cel.dev/expr v0.24.0 // indirect + cloud.google.com/go v0.120.0 // indirect + cloud.google.com/go/auth v0.16.0 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect + cloud.google.com/go/compute/metadata v0.7.0 // indirect + cloud.google.com/go/iam v1.5.2 // indirect + cloud.google.com/go/monitoring v1.24.2 // indirect + cloud.google.com/go/storage v1.50.0 // indirect + cosmossdk.io/schema v1.1.0 // indirect + cosmossdk.io/x/tx v0.14.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect - github.com/99designs/keyring v1.2.1 // indirect - github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect - github.com/DataDog/zstd v1.5.0 // indirect - github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect - github.com/Workiva/go-datastructures v1.0.53 // indirect - github.com/armon/go-metrics v0.4.1 // indirect + github.com/99designs/keyring v1.2.2 // indirect + github.com/DataDog/datadog-go v4.8.3+incompatible // indirect + github.com/DataDog/zstd v1.5.7 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/PuerkitoBio/purell v1.1.1 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect + github.com/aws/aws-sdk-go v1.49.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect - github.com/cespare/xxhash v1.1.0 // indirect + github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect + github.com/bgentry/speakeasy v0.2.0 // indirect + github.com/bits-and-blooms/bitset v1.22.0 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/bytedance/gopkg v0.1.3 // indirect + github.com/bytedance/sonic v1.13.2 // indirect + github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cockroachdb/errors v1.9.1 // indirect - github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect - github.com/cockroachdb/pebble v0.0.0-20220817183557-09c6e030a677 // indirect - github.com/cockroachdb/redact v1.1.3 // indirect - github.com/coinbase/rosetta-sdk-go v0.7.9 // indirect - github.com/cometbft/cometbft-db v0.7.0 // indirect - github.com/confio/ics23/go v0.9.1 // indirect - github.com/cosmos/btcutil v1.0.4 // indirect - github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.1 // indirect - github.com/cosmos/gorocksdb v1.2.0 // indirect - github.com/cosmos/iavl v0.19.5 // indirect - github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect + github.com/chzyer/readline v1.5.1 // indirect + github.com/cloudwego/base64x v0.1.6 // indirect + github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect + github.com/cockroachdb/apd/v2 v2.0.2 // indirect + github.com/cockroachdb/errors v1.12.0 // indirect + github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 // indirect + github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 // indirect + github.com/cockroachdb/pebble v1.1.5 // indirect + github.com/cockroachdb/redact v1.1.6 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect + github.com/coinbase/rosetta-sdk-go/types v1.0.0 // indirect + github.com/cometbft/cometbft-db v1.0.4 // indirect + github.com/cosmos/btcutil v1.0.5 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect + github.com/cosmos/go-bip39 v1.0.0 // indirect + github.com/cosmos/gogogateway v1.2.0 // indirect + github.com/cosmos/iavl v1.2.2 // indirect + github.com/cosmos/ics23/go v0.11.0 // indirect + github.com/cosmos/ledger-cosmos-go v0.14.0 // indirect + github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect - github.com/creachadair/taskgroup v0.3.2 // indirect - github.com/danieljoos/wincred v1.1.2 // indirect + github.com/danieljoos/wincred v1.2.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect - github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect - github.com/dgraph-io/badger/v2 v2.2007.4 // indirect - github.com/dgraph-io/ristretto v0.2.0 // indirect - github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect + github.com/desertbit/timer v1.0.1 // indirect + github.com/dgraph-io/badger/v4 v4.6.0 // indirect + github.com/dgraph-io/ristretto/v2 v2.1.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/dvsekhvalnov/jose2go v1.8.0 // indirect github.com/edwingeng/deque/v2 v2.1.1 // indirect + github.com/emicklei/dot v1.6.2 // indirect + github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect + github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect + github.com/ethereum/go-ethereum v1.15.11 // indirect + github.com/fatih/color v1.17.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/getsentry/sentry-go v0.35.0 // indirect - github.com/go-kit/kit v0.12.0 // indirect + github.com/getsentry/sentry-go v0.32.0 // indirect + github.com/go-errors/errors v1.5.1 // indirect + github.com/go-jose/go-jose/v4 v4.0.5 // indirect + github.com/go-kit/kit v0.13.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-logr/logr v1.4.3 // indirect - github.com/go-viper/mapstructure/v2 v2.3.0 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect - github.com/gogo/gateway v1.1.0 // indirect + github.com/gogo/googleapis v1.4.1 // indirect + github.com/gogo/protobuf v1.3.3 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/google/btree v1.1.2 // indirect + github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e // indirect + github.com/google/btree v1.1.3 // indirect + github.com/google/flatbuffers v25.2.10+incompatible // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect github.com/google/orderedcode v0.0.1 // indirect - github.com/gorilla/handlers v1.5.1 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/google/s2a-go v0.1.9 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect + github.com/googleapis/gax-go/v2 v2.14.1 // indirect + github.com/gorilla/handlers v1.5.2 // indirect + github.com/goware/urlx v0.3.2 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect - github.com/gtank/merlin v0.1.1 // indirect - github.com/gtank/ristretto255 v0.1.2 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-getter v1.7.8 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect - github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect - github.com/improbable-eng/grpc-web v0.14.1 // indirect + github.com/hashicorp/go-metrics v0.5.4 // indirect + github.com/hashicorp/go-plugin v1.6.3 // indirect + github.com/hashicorp/go-safetemp v1.0.0 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/golang-lru v1.0.2 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect + github.com/hashicorp/yamux v0.1.2 // indirect + github.com/hdevalence/ed25519consensus v0.2.0 // indirect + github.com/holiman/uint256 v1.3.2 // indirect + github.com/huandu/skiplist v1.2.1 // indirect + github.com/iancoleman/strcase v0.3.0 // indirect + github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.1-0.20191019112844-b572e7f4cdac // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/lib/pq v1.10.6 // indirect - github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/linxGnu/grocksdb v1.7.10 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/lib/pq v1.10.9 // indirect + github.com/linxGnu/grocksdb v1.9.8 // indirect + github.com/manifoldco/promptui v0.9.0 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect - github.com/minio/highwayhash v1.0.2 // indirect + github.com/mdp/qrterminal/v3 v3.2.1 // indirect + github.com/minio/highwayhash v1.0.3 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect + github.com/oklog/run v1.1.0 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect - github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect + github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect + github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.65.0 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.63.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect - github.com/rs/cors v1.8.2 // indirect + github.com/rs/cors v1.11.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sagikazarmark/locafero v0.9.0 // indirect - github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/sagikazarmark/locafero v0.7.0 // indirect + github.com/sasha-s/go-deadlock v0.3.5 // indirect github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/afero v1.14.0 // indirect + github.com/spf13/afero v1.12.0 // indirect + github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect - github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect - github.com/tidwall/btree v1.5.0 // indirect + github.com/tidwall/btree v1.7.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ulikunitz/xz v0.5.11 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect - github.com/zondax/golem v0.27.0 // indirect + github.com/zeebo/errs v1.4.0 // indirect github.com/zondax/hid v0.9.2 // indirect - github.com/zondax/ledger-go v0.15.0 // indirect - go.etcd.io/bbolt v1.3.6 // indirect + github.com/zondax/ledger-go v0.14.3 // indirect + go.etcd.io/bbolt v1.4.0 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/detectors/gcp v1.36.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect + go.opentelemetry.io/otel v1.36.0 // indirect + go.opentelemetry.io/otel/metric v1.36.0 // indirect + go.opentelemetry.io/otel/sdk v1.36.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect + go.opentelemetry.io/otel/trace v1.36.0 // indirect + go.uber.org/mock v0.5.2 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.41.0 // indirect - golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a // indirect - google.golang.org/protobuf v1.36.8 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + golang.org/x/arch v0.15.0 // indirect + golang.org/x/crypto v0.40.0 // indirect + golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect + golang.org/x/net v0.42.0 // indirect + golang.org/x/sys v0.34.0 // indirect + golang.org/x/term v0.33.0 // indirect + golang.org/x/text v0.27.0 // indirect + golang.org/x/time v0.11.0 // indirect + google.golang.org/api v0.229.0 // indirect + google.golang.org/genproto v0.0.0-20250728155136-f173205681a0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/api v0.32.0 // indirect - k8s.io/apimachinery v0.32.0 // indirect + k8s.io/api v0.33.3 // indirect + k8s.io/apimachinery v0.33.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect - nhooyr.io/websocket v1.8.6 // indirect + nhooyr.io/websocket v1.8.11 // indirect + pgregory.net/rapid v1.2.0 // indirect + pkg.akt.dev/specs v0.0.1 // indirect + rsc.io/qr v0.2.0 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect +) + +replace ( + // use cosmos fork of keyring + github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 + + github.com/bytedance/sonic => github.com/bytedance/sonic v1.14.1 + + // use akash fork of cometbft + github.com/cometbft/cometbft => github.com/akash-network/cometbft v0.38.19-akash.1 + // use akash fork of cosmos sdk + github.com/cosmos/cosmos-sdk => github.com/akash-network/cosmos-sdk v0.53.4-akash.7 + + github.com/cosmos/gogoproto => github.com/akash-network/gogoproto v1.7.0-akash.2 + + // Use regen gogoproto fork + // To be replaced by cosmos/gogoproto in future versions + github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 + + // as per v0.53.x migration guide goleveldb version must be pinned for the app to work correctly + github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 + + // stick with compatible version or x/exp in v0.47.x line + golang.org/x/exp => golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb + // stick with compatible version of rapid in v0.47.x line + pgregory.net/rapid => pgregory.net/rapid v0.5.5 ) diff --git a/go.sum b/go.sum index e3c5d5a0d7..6c95d33d52 100644 --- a/go.sum +++ b/go.sum @@ -1,328 +1,1530 @@ +cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= +cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= +cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= +cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw= +cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= +cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= +cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= +cloud.google.com/go v0.110.8/go.mod h1:Iz8AkXJf1qmxC3Oxoep8R1T36w8B92yU29PcBhHO5fk= +cloud.google.com/go v0.110.9/go.mod h1:rpxevX/0Lqvlbc88b7Sc1SPNdyK1riNBTUU6JXhYNpM= +cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic= +cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU= +cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= +cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA= +cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q= +cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= +cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= +cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= +cloud.google.com/go/accessapproval v1.7.1/go.mod h1:JYczztsHRMK7NTXb6Xw+dwbs/WnOJxbo/2mTI+Kgg68= +cloud.google.com/go/accessapproval v1.7.2/go.mod h1:/gShiq9/kK/h8T/eEn1BTzalDvk0mZxJlhfw0p+Xuc0= +cloud.google.com/go/accessapproval v1.7.3/go.mod h1:4l8+pwIxGTNqSf4T3ds8nLO94NQf0W/KnMNuQ9PbnP8= +cloud.google.com/go/accessapproval v1.7.4/go.mod h1:/aTEh45LzplQgFYdQdwPMR9YdX0UlhBmvB84uAmQKUc= +cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= +cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= +cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= +cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= +cloud.google.com/go/accesscontextmanager v1.8.0/go.mod h1:uI+AI/r1oyWK99NN8cQ3UK76AMelMzgZCvJfsi2c+ps= +cloud.google.com/go/accesscontextmanager v1.8.1/go.mod h1:JFJHfvuaTC+++1iL1coPiG1eu5D24db2wXCDWDjIrxo= +cloud.google.com/go/accesscontextmanager v1.8.2/go.mod h1:E6/SCRM30elQJ2PKtFMs2YhfJpZSNcJyejhuzoId4Zk= +cloud.google.com/go/accesscontextmanager v1.8.3/go.mod h1:4i/JkF2JiFbhLnnpnfoTX5vRXfhf9ukhU1ANOTALTOQ= +cloud.google.com/go/accesscontextmanager v1.8.4/go.mod h1:ParU+WbMpD34s5JFEnGAnPBYAgUHozaTmDJU7aCU9+M= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= +cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= +cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k= +cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= +cloud.google.com/go/aiplatform v1.45.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA= +cloud.google.com/go/aiplatform v1.48.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA= +cloud.google.com/go/aiplatform v1.50.0/go.mod h1:IRc2b8XAMTa9ZmfJV1BCCQbieWWvDnP1A8znyz5N7y4= +cloud.google.com/go/aiplatform v1.51.0/go.mod h1:IRc2b8XAMTa9ZmfJV1BCCQbieWWvDnP1A8znyz5N7y4= +cloud.google.com/go/aiplatform v1.51.1/go.mod h1:kY3nIMAVQOK2XDqDPHaOuD9e+FdMA6OOpfBjsvaFSOo= +cloud.google.com/go/aiplatform v1.51.2/go.mod h1:hCqVYB3mY45w99TmetEoe8eCQEwZEp9WHxeZdcv9phw= +cloud.google.com/go/aiplatform v1.52.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= +cloud.google.com/go/aiplatform v1.54.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= +cloud.google.com/go/aiplatform v1.57.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= +cloud.google.com/go/aiplatform v1.58.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M= +cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= +cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= +cloud.google.com/go/analytics v0.21.2/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo= +cloud.google.com/go/analytics v0.21.3/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo= +cloud.google.com/go/analytics v0.21.4/go.mod h1:zZgNCxLCy8b2rKKVfC1YkC2vTrpfZmeRCySM3aUbskA= +cloud.google.com/go/analytics v0.21.5/go.mod h1:BQtOBHWTlJ96axpPPnw5CvGJ6i3Ve/qX2fTxR8qWyr8= +cloud.google.com/go/analytics v0.21.6/go.mod h1:eiROFQKosh4hMaNhF85Oc9WO97Cpa7RggD40e/RBy8w= +cloud.google.com/go/analytics v0.22.0/go.mod h1:eiROFQKosh4hMaNhF85Oc9WO97Cpa7RggD40e/RBy8w= +cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= +cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= +cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= +cloud.google.com/go/apigateway v1.6.1/go.mod h1:ufAS3wpbRjqfZrzpvLC2oh0MFlpRJm2E/ts25yyqmXA= +cloud.google.com/go/apigateway v1.6.2/go.mod h1:CwMC90nnZElorCW63P2pAYm25AtQrHfuOkbRSHj0bT8= +cloud.google.com/go/apigateway v1.6.3/go.mod h1:k68PXWpEs6BVDTtnLQAyG606Q3mz8pshItwPXjgv44Y= +cloud.google.com/go/apigateway v1.6.4/go.mod h1:0EpJlVGH5HwAN4VF4Iec8TAzGN1aQgbxAWGJsnPCGGY= +cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= +cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= +cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= +cloud.google.com/go/apigeeconnect v1.6.1/go.mod h1:C4awq7x0JpLtrlQCr8AzVIzAaYgngRqWf9S5Uhg+wWs= +cloud.google.com/go/apigeeconnect v1.6.2/go.mod h1:s6O0CgXT9RgAxlq3DLXvG8riw8PYYbU/v25jqP3Dy18= +cloud.google.com/go/apigeeconnect v1.6.3/go.mod h1:peG0HFQ0si2bN15M6QSjEW/W7Gy3NYkWGz7pFz13cbo= +cloud.google.com/go/apigeeconnect v1.6.4/go.mod h1:CapQCWZ8TCjnU0d7PobxhpOdVz/OVJ2Hr/Zcuu1xFx0= +cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= +cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= +cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= +cloud.google.com/go/apigeeregistry v0.7.1/go.mod h1:1XgyjZye4Mqtw7T9TsY4NW10U7BojBvG4RMD+vRDrIw= +cloud.google.com/go/apigeeregistry v0.7.2/go.mod h1:9CA2B2+TGsPKtfi3F7/1ncCCsL62NXBRfM6iPoGSM+8= +cloud.google.com/go/apigeeregistry v0.8.1/go.mod h1:MW4ig1N4JZQsXmBSwH4rwpgDonocz7FPBSw6XPGHmYw= +cloud.google.com/go/apigeeregistry v0.8.2/go.mod h1:h4v11TDGdeXJDJvImtgK2AFVvMIgGWjSb0HRnBSjcX8= +cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= +cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= +cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= +cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= +cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= +cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= +cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A= +cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= +cloud.google.com/go/appengine v1.8.1/go.mod h1:6NJXGLVhZCN9aQ/AEDvmfzKEfoYBlfB80/BHiKVputY= +cloud.google.com/go/appengine v1.8.2/go.mod h1:WMeJV9oZ51pvclqFN2PqHoGnys7rK0rz6s3Mp6yMvDo= +cloud.google.com/go/appengine v1.8.3/go.mod h1:2oUPZ1LVZ5EXi+AF1ihNAF+S8JrzQ3till5m9VQkrsk= +cloud.google.com/go/appengine v1.8.4/go.mod h1:TZ24v+wXBujtkK77CXCpjZbnuTvsFNT41MUaZ28D6vg= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY= +cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= +cloud.google.com/go/area120 v0.8.1/go.mod h1:BVfZpGpB7KFVNxPiQBuHkX6Ed0rS51xIgmGyjrAfzsg= +cloud.google.com/go/area120 v0.8.2/go.mod h1:a5qfo+x77SRLXnCynFWPUZhnZGeSgvQ+Y0v1kSItkh4= +cloud.google.com/go/area120 v0.8.3/go.mod h1:5zj6pMzVTH+SVHljdSKC35sriR/CVvQZzG/Icdyriw0= +cloud.google.com/go/area120 v0.8.4/go.mod h1:jfawXjxf29wyBXr48+W+GyX/f8fflxp642D/bb9v68M= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= +cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= +cloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1nOucMH0pwXN1rOBZFI= +cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= +cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI= +cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= +cloud.google.com/go/artifactregistry v1.14.1/go.mod h1:nxVdG19jTaSTu7yA7+VbWL346r3rIdkZ142BSQqhn5E= +cloud.google.com/go/artifactregistry v1.14.2/go.mod h1:Xk+QbsKEb0ElmyeMfdHAey41B+qBq3q5R5f5xD4XT3U= +cloud.google.com/go/artifactregistry v1.14.3/go.mod h1:A2/E9GXnsyXl7GUvQ/2CjHA+mVRoWAXC0brg2os+kNI= +cloud.google.com/go/artifactregistry v1.14.4/go.mod h1:SJJcZTMv6ce0LDMUnihCN7WSrI+kBSFV0KIKo8S8aYU= +cloud.google.com/go/artifactregistry v1.14.6/go.mod h1:np9LSFotNWHcjnOgh8UVK0RFPCTUGbO0ve3384xyHfE= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= +cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= +cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= +cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg= +cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= +cloud.google.com/go/asset v1.14.1/go.mod h1:4bEJ3dnHCqWCDbWJ/6Vn7GVI9LerSi7Rfdi03hd+WTQ= +cloud.google.com/go/asset v1.15.0/go.mod h1:tpKafV6mEut3+vN9ScGvCHXHj7FALFVta+okxFECHcg= +cloud.google.com/go/asset v1.15.1/go.mod h1:yX/amTvFWRpp5rcFq6XbCxzKT8RJUam1UoboE179jU4= +cloud.google.com/go/asset v1.15.2/go.mod h1:B6H5tclkXvXz7PD22qCA2TDxSVQfasa3iDlM89O2NXs= +cloud.google.com/go/asset v1.15.3/go.mod h1:yYLfUD4wL4X589A9tYrv4rFrba0QlDeag0CMcM5ggXU= +cloud.google.com/go/asset v1.16.0/go.mod h1:yYLfUD4wL4X589A9tYrv4rFrba0QlDeag0CMcM5ggXU= +cloud.google.com/go/asset v1.17.0/go.mod h1:yYLfUD4wL4X589A9tYrv4rFrba0QlDeag0CMcM5ggXU= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= +cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= +cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= +cloud.google.com/go/assuredworkloads v1.11.1/go.mod h1:+F04I52Pgn5nmPG36CWFtxmav6+7Q+c5QyJoL18Lry0= +cloud.google.com/go/assuredworkloads v1.11.2/go.mod h1:O1dfr+oZJMlE6mw0Bp0P1KZSlj5SghMBvTpZqIcUAW4= +cloud.google.com/go/assuredworkloads v1.11.3/go.mod h1:vEjfTKYyRUaIeA0bsGJceFV2JKpVRgyG2op3jfa59Zs= +cloud.google.com/go/assuredworkloads v1.11.4/go.mod h1:4pwwGNwy1RP0m+y12ef3Q/8PaiWrIDQ6nD2E8kvWI9U= +cloud.google.com/go/auth v0.16.0 h1:Pd8P1s9WkcrBE2n/PhAwKsdrR35V3Sg2II9B+ndM3CU= +cloud.google.com/go/auth v0.16.0/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= +cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= +cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= +cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= +cloud.google.com/go/automl v1.13.1/go.mod h1:1aowgAHWYZU27MybSCFiukPO7xnyawv7pt3zK4bheQE= +cloud.google.com/go/automl v1.13.2/go.mod h1:gNY/fUmDEN40sP8amAX3MaXkxcqPIn7F1UIIPZpy4Mg= +cloud.google.com/go/automl v1.13.3/go.mod h1:Y8KwvyAZFOsMAPqUCfNu1AyclbC6ivCUF/MTwORymyY= +cloud.google.com/go/automl v1.13.4/go.mod h1:ULqwX/OLZ4hBVfKQaMtxMSTlPx0GqGbWN8uA/1EqCP8= +cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= +cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= +cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= +cloud.google.com/go/baremetalsolution v1.1.1/go.mod h1:D1AV6xwOksJMV4OSlWHtWuFNZZYujJknMAP4Qa27QIA= +cloud.google.com/go/baremetalsolution v1.2.0/go.mod h1:68wi9AwPYkEWIUT4SvSGS9UJwKzNpshjHsH4lzk8iOw= +cloud.google.com/go/baremetalsolution v1.2.1/go.mod h1:3qKpKIw12RPXStwQXcbhfxVj1dqQGEvcmA+SX/mUR88= +cloud.google.com/go/baremetalsolution v1.2.2/go.mod h1:O5V6Uu1vzVelYahKfwEWRMaS3AbCkeYHy3145s1FkhM= +cloud.google.com/go/baremetalsolution v1.2.3/go.mod h1:/UAQ5xG3faDdy180rCUv47e0jvpp3BFxT+Cl0PFjw5g= +cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= +cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= +cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= +cloud.google.com/go/batch v1.3.1/go.mod h1:VguXeQKXIYaeeIYbuozUmBR13AfL4SJP7IltNPS+A4A= +cloud.google.com/go/batch v1.4.1/go.mod h1:KdBmDD61K0ovcxoRHGrN6GmOBWeAOyCgKD0Mugx4Fkk= +cloud.google.com/go/batch v1.5.0/go.mod h1:KdBmDD61K0ovcxoRHGrN6GmOBWeAOyCgKD0Mugx4Fkk= +cloud.google.com/go/batch v1.5.1/go.mod h1:RpBuIYLkQu8+CWDk3dFD/t/jOCGuUpkpX+Y0n1Xccs8= +cloud.google.com/go/batch v1.6.1/go.mod h1:urdpD13zPe6YOK+6iZs/8/x2VBRofvblLpx0t57vM98= +cloud.google.com/go/batch v1.6.3/go.mod h1:J64gD4vsNSA2O5TtDB5AAux3nJ9iV8U3ilg3JDBYejU= +cloud.google.com/go/batch v1.7.0/go.mod h1:J64gD4vsNSA2O5TtDB5AAux3nJ9iV8U3ilg3JDBYejU= +cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= +cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= +cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= +cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= +cloud.google.com/go/beyondcorp v0.6.1/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4= +cloud.google.com/go/beyondcorp v1.0.0/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4= +cloud.google.com/go/beyondcorp v1.0.1/go.mod h1:zl/rWWAFVeV+kx+X2Javly7o1EIQThU4WlkynffL/lk= +cloud.google.com/go/beyondcorp v1.0.2/go.mod h1:m8cpG7caD+5su+1eZr+TSvF6r21NdLJk4f9u4SP2Ntc= +cloud.google.com/go/beyondcorp v1.0.3/go.mod h1:HcBvnEd7eYr+HGDd5ZbuVmBYX019C6CEXBonXbCVwJo= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= +cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= +cloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/ZurWFIxmF9I/E= +cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac= +cloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q= +cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= +cloud.google.com/go/bigquery v1.52.0/go.mod h1:3b/iXjRQGU4nKa87cXeg6/gogLjO8C6PmuM8i5Bi/u4= +cloud.google.com/go/bigquery v1.53.0/go.mod h1:3b/iXjRQGU4nKa87cXeg6/gogLjO8C6PmuM8i5Bi/u4= +cloud.google.com/go/bigquery v1.55.0/go.mod h1:9Y5I3PN9kQWuid6183JFhOGOW3GcirA5LpsKCUn+2ec= +cloud.google.com/go/bigquery v1.56.0/go.mod h1:KDcsploXTEY7XT3fDQzMUZlpQLHzE4itubHrnmhUrZA= +cloud.google.com/go/bigquery v1.57.1/go.mod h1:iYzC0tGVWt1jqSzBHqCr3lrRn0u13E8e+AqowBsDgug= +cloud.google.com/go/bigquery v1.58.0/go.mod h1:0eh4mWNY0KrBTjUzLjoYImapGORq9gEPT7MWjCy9lik= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= +cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= +cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= +cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= +cloud.google.com/go/billing v1.16.0/go.mod h1:y8vx09JSSJG02k5QxbycNRrN7FGZB6F3CAcgum7jvGA= +cloud.google.com/go/billing v1.17.0/go.mod h1:Z9+vZXEq+HwH7bhJkyI4OQcR6TSbeMrjlpEjO2vzY64= +cloud.google.com/go/billing v1.17.1/go.mod h1:Z9+vZXEq+HwH7bhJkyI4OQcR6TSbeMrjlpEjO2vzY64= +cloud.google.com/go/billing v1.17.2/go.mod h1:u/AdV/3wr3xoRBk5xvUzYMS1IawOAPwQMuHgHMdljDg= +cloud.google.com/go/billing v1.17.3/go.mod h1:z83AkoZ7mZwBGT3yTnt6rSGI1OOsHSIi6a5M3mJ8NaU= +cloud.google.com/go/billing v1.17.4/go.mod h1:5DOYQStCxquGprqfuid/7haD7th74kyMBHkjO/OvDtk= +cloud.google.com/go/billing v1.18.0/go.mod h1:5DOYQStCxquGprqfuid/7haD7th74kyMBHkjO/OvDtk= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= +cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= +cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= +cloud.google.com/go/binaryauthorization v1.6.1/go.mod h1:TKt4pa8xhowwffiBmbrbcxijJRZED4zrqnwZ1lKH51U= +cloud.google.com/go/binaryauthorization v1.7.0/go.mod h1:Zn+S6QqTMn6odcMU1zDZCJxPjU2tZPV1oDl45lWY154= +cloud.google.com/go/binaryauthorization v1.7.1/go.mod h1:GTAyfRWYgcbsP3NJogpV3yeunbUIjx2T9xVeYovtURE= +cloud.google.com/go/binaryauthorization v1.7.2/go.mod h1:kFK5fQtxEp97m92ziy+hbu+uKocka1qRRL8MVJIgjv0= +cloud.google.com/go/binaryauthorization v1.7.3/go.mod h1:VQ/nUGRKhrStlGr+8GMS8f6/vznYLkdK5vaKfdCIpvU= +cloud.google.com/go/binaryauthorization v1.8.0/go.mod h1:VQ/nUGRKhrStlGr+8GMS8f6/vznYLkdK5vaKfdCIpvU= +cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= +cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= +cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= +cloud.google.com/go/certificatemanager v1.7.1/go.mod h1:iW8J3nG6SaRYImIa+wXQ0g8IgoofDFRp5UMzaNk1UqI= +cloud.google.com/go/certificatemanager v1.7.2/go.mod h1:15SYTDQMd00kdoW0+XY5d9e+JbOPjp24AvF48D8BbcQ= +cloud.google.com/go/certificatemanager v1.7.3/go.mod h1:T/sZYuC30PTag0TLo28VedIRIj1KPGcOQzjWAptHa00= +cloud.google.com/go/certificatemanager v1.7.4/go.mod h1:FHAylPe/6IIKuaRmHbjbdLhGhVQ+CWHSD5Jq0k4+cCE= +cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= +cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= +cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= +cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= +cloud.google.com/go/channel v1.16.0/go.mod h1:eN/q1PFSl5gyu0dYdmxNXscY/4Fi7ABmeHCJNf/oHmc= +cloud.google.com/go/channel v1.17.0/go.mod h1:RpbhJsGi/lXWAUM1eF4IbQGbsfVlg2o8Iiy2/YLfVT0= +cloud.google.com/go/channel v1.17.1/go.mod h1:xqfzcOZAcP4b/hUDH0GkGg1Sd5to6di1HOJn/pi5uBQ= +cloud.google.com/go/channel v1.17.2/go.mod h1:aT2LhnftnyfQceFql5I/mP8mIbiiJS4lWqgXA815zMk= +cloud.google.com/go/channel v1.17.3/go.mod h1:QcEBuZLGGrUMm7kNj9IbU1ZfmJq2apotsV83hbxX7eE= +cloud.google.com/go/channel v1.17.4/go.mod h1:QcEBuZLGGrUMm7kNj9IbU1ZfmJq2apotsV83hbxX7eE= +cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= +cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= +cloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M= +cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= +cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= +cloud.google.com/go/cloudbuild v1.10.1/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= +cloud.google.com/go/cloudbuild v1.13.0/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= +cloud.google.com/go/cloudbuild v1.14.0/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= +cloud.google.com/go/cloudbuild v1.14.1/go.mod h1:K7wGc/3zfvmYWOWwYTgF/d/UVJhS4pu+HAy7PL7mCsU= +cloud.google.com/go/cloudbuild v1.14.2/go.mod h1:Bn6RO0mBYk8Vlrt+8NLrru7WXlQ9/RDWz2uo5KG1/sg= +cloud.google.com/go/cloudbuild v1.14.3/go.mod h1:eIXYWmRt3UtggLnFGx4JvXcMj4kShhVzGndL1LwleEM= +cloud.google.com/go/cloudbuild v1.15.0/go.mod h1:eIXYWmRt3UtggLnFGx4JvXcMj4kShhVzGndL1LwleEM= +cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= +cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= +cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= +cloud.google.com/go/clouddms v1.6.1/go.mod h1:Ygo1vL52Ov4TBZQquhz5fiw2CQ58gvu+PlS6PVXCpZI= +cloud.google.com/go/clouddms v1.7.0/go.mod h1:MW1dC6SOtI/tPNCciTsXtsGNEM0i0OccykPvv3hiYeM= +cloud.google.com/go/clouddms v1.7.1/go.mod h1:o4SR8U95+P7gZ/TX+YbJxehOCsM+fe6/brlrFquiszk= +cloud.google.com/go/clouddms v1.7.2/go.mod h1:Rk32TmWmHo64XqDvW7jgkFQet1tUKNVzs7oajtJT3jU= +cloud.google.com/go/clouddms v1.7.3/go.mod h1:fkN2HQQNUYInAU3NQ3vRLkV2iWs8lIdmBKOx4nrL6Hc= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= +cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= +cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= +cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= +cloud.google.com/go/cloudtasks v1.11.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM= +cloud.google.com/go/cloudtasks v1.12.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM= +cloud.google.com/go/cloudtasks v1.12.2/go.mod h1:A7nYkjNlW2gUoROg1kvJrQGhJP/38UaWwsnuBDOBVUk= +cloud.google.com/go/cloudtasks v1.12.3/go.mod h1:GPVXhIOSGEaR+3xT4Fp72ScI+HjHffSS4B8+BaBB5Ys= +cloud.google.com/go/cloudtasks v1.12.4/go.mod h1:BEPu0Gtt2dU6FxZHNqqNdGqIG86qyWKBPGnsb7udGY0= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= +cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= +cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= +cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= +cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.23.1/go.mod h1:CqB3xpmPKKt3OJpW2ndFIXnA9A4xAy/F3Xp1ixncW78= +cloud.google.com/go/compute v1.23.2/go.mod h1:JJ0atRC0J/oWYiiVBmsSsrRnh92DhZPG4hFDcR04Rns= +cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= +cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= +cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= +cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= +cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= +cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= +cloud.google.com/go/contactcenterinsights v1.9.1/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM= +cloud.google.com/go/contactcenterinsights v1.10.0/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM= +cloud.google.com/go/contactcenterinsights v1.11.0/go.mod h1:hutBdImE4XNZ1NV4vbPJKSFOnQruhC5Lj9bZqWMTKiU= +cloud.google.com/go/contactcenterinsights v1.11.1/go.mod h1:FeNP3Kg8iteKM80lMwSk3zZZKVxr+PGnAId6soKuXwE= +cloud.google.com/go/contactcenterinsights v1.11.2/go.mod h1:A9PIR5ov5cRcd28KlDbmmXE8Aay+Gccer2h4wzkYFso= +cloud.google.com/go/contactcenterinsights v1.11.3/go.mod h1:HHX5wrz5LHVAwfI2smIotQG9x8Qd6gYilaHcLLLmNis= +cloud.google.com/go/contactcenterinsights v1.12.0/go.mod h1:HHX5wrz5LHVAwfI2smIotQG9x8Qd6gYilaHcLLLmNis= +cloud.google.com/go/contactcenterinsights v1.12.1/go.mod h1:HHX5wrz5LHVAwfI2smIotQG9x8Qd6gYilaHcLLLmNis= +cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= +cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= +cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= +cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM= +cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= +cloud.google.com/go/container v1.22.1/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4= +cloud.google.com/go/container v1.24.0/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4= +cloud.google.com/go/container v1.26.0/go.mod h1:YJCmRet6+6jnYYRS000T6k0D0xUXQgBSaJ7VwI8FBj4= +cloud.google.com/go/container v1.26.1/go.mod h1:5smONjPRUxeEpDG7bMKWfDL4sauswqEtnBK1/KKpR04= +cloud.google.com/go/container v1.26.2/go.mod h1:YlO84xCt5xupVbLaMY4s3XNE79MUJ+49VmkInr6HvF4= +cloud.google.com/go/container v1.27.1/go.mod h1:b1A1gJeTBXVLQ6GGw9/9M4FG94BEGsqJ5+t4d/3N7O4= +cloud.google.com/go/container v1.28.0/go.mod h1:b1A1gJeTBXVLQ6GGw9/9M4FG94BEGsqJ5+t4d/3N7O4= +cloud.google.com/go/container v1.29.0/go.mod h1:b1A1gJeTBXVLQ6GGw9/9M4FG94BEGsqJ5+t4d/3N7O4= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= +cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= +cloud.google.com/go/containeranalysis v0.10.1/go.mod h1:Ya2jiILITMY68ZLPaogjmOMNkwsDrWBSTyBubGXO7j0= +cloud.google.com/go/containeranalysis v0.11.0/go.mod h1:4n2e99ZwpGxpNcz+YsFT1dfOHPQFGcAC8FN2M2/ne/U= +cloud.google.com/go/containeranalysis v0.11.1/go.mod h1:rYlUOM7nem1OJMKwE1SadufX0JP3wnXj844EtZAwWLY= +cloud.google.com/go/containeranalysis v0.11.2/go.mod h1:xibioGBC1MD2j4reTyV1xY1/MvKaz+fyM9ENWhmIeP8= +cloud.google.com/go/containeranalysis v0.11.3/go.mod h1:kMeST7yWFQMGjiG9K7Eov+fPNQcGhb8mXj/UcTiWw9U= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= +cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= +cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M= +cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= +cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= +cloud.google.com/go/datacatalog v1.14.0/go.mod h1:h0PrGtlihoutNMp/uvwhawLQ9+c63Kz65UFqh49Yo+E= +cloud.google.com/go/datacatalog v1.14.1/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4= +cloud.google.com/go/datacatalog v1.16.0/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4= +cloud.google.com/go/datacatalog v1.17.1/go.mod h1:nCSYFHgtxh2MiEktWIz71s/X+7ds/UT9kp0PC7waCzE= +cloud.google.com/go/datacatalog v1.18.0/go.mod h1:nCSYFHgtxh2MiEktWIz71s/X+7ds/UT9kp0PC7waCzE= +cloud.google.com/go/datacatalog v1.18.1/go.mod h1:TzAWaz+ON1tkNr4MOcak8EBHX7wIRX/gZKM+yTVsv+A= +cloud.google.com/go/datacatalog v1.18.2/go.mod h1:SPVgWW2WEMuWHA+fHodYjmxPiMqcOiWfhc9OD5msigk= +cloud.google.com/go/datacatalog v1.18.3/go.mod h1:5FR6ZIF8RZrtml0VUao22FxhdjkoG+a0866rEnObryM= +cloud.google.com/go/datacatalog v1.19.0/go.mod h1:5FR6ZIF8RZrtml0VUao22FxhdjkoG+a0866rEnObryM= +cloud.google.com/go/datacatalog v1.19.2/go.mod h1:2YbODwmhpLM4lOFe3PuEhHK9EyTzQJ5AXgIy7EDKTEE= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= +cloud.google.com/go/dataflow v0.9.1/go.mod h1:Wp7s32QjYuQDWqJPFFlnBKhkAtiFpMTdg00qGbnIHVw= +cloud.google.com/go/dataflow v0.9.2/go.mod h1:vBfdBZ/ejlTaYIGB3zB4T08UshH70vbtZeMD+urnUSo= +cloud.google.com/go/dataflow v0.9.3/go.mod h1:HI4kMVjcHGTs3jTHW/kv3501YW+eloiJSLxkJa/vqFE= +cloud.google.com/go/dataflow v0.9.4/go.mod h1:4G8vAkHYCSzU8b/kmsoR2lWyHJD85oMJPHMtan40K8w= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= +cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= +cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= +cloud.google.com/go/dataform v0.8.1/go.mod h1:3BhPSiw8xmppbgzeBbmDvmSWlwouuJkXsXsb8UBih9M= +cloud.google.com/go/dataform v0.8.2/go.mod h1:X9RIqDs6NbGPLR80tnYoPNiO1w0wenKTb8PxxlhTMKM= +cloud.google.com/go/dataform v0.8.3/go.mod h1:8nI/tvv5Fso0drO3pEjtowz58lodx8MVkdV2q0aPlqg= +cloud.google.com/go/dataform v0.9.1/go.mod h1:pWTg+zGQ7i16pyn0bS1ruqIE91SdL2FDMvEYu/8oQxs= +cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= +cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= +cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= +cloud.google.com/go/datafusion v1.7.1/go.mod h1:KpoTBbFmoToDExJUso/fcCiguGDk7MEzOWXUsJo0wsI= +cloud.google.com/go/datafusion v1.7.2/go.mod h1:62K2NEC6DRlpNmI43WHMWf9Vg/YvN6QVi8EVwifElI0= +cloud.google.com/go/datafusion v1.7.3/go.mod h1:eoLt1uFXKGBq48jy9LZ+Is8EAVLnmn50lNncLzwYokE= +cloud.google.com/go/datafusion v1.7.4/go.mod h1:BBs78WTOLYkT4GVZIXQCZT3GFpkpDN4aBY4NDX/jVlM= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= +cloud.google.com/go/datalabeling v0.8.1/go.mod h1:XS62LBSVPbYR54GfYQsPXZjTW8UxCK2fkDciSrpRFdY= +cloud.google.com/go/datalabeling v0.8.2/go.mod h1:cyDvGHuJWu9U/cLDA7d8sb9a0tWLEletStu2sTmg3BE= +cloud.google.com/go/datalabeling v0.8.3/go.mod h1:tvPhpGyS/V7lqjmb3V0TaDdGvhzgR1JoW7G2bpi2UTI= +cloud.google.com/go/datalabeling v0.8.4/go.mod h1:Z1z3E6LHtffBGrNUkKwbwbDxTiXEApLzIgmymj8A3S8= +cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= +cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= +cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= +cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= +cloud.google.com/go/dataplex v1.8.1/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= +cloud.google.com/go/dataplex v1.9.0/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= +cloud.google.com/go/dataplex v1.9.1/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= +cloud.google.com/go/dataplex v1.10.1/go.mod h1:1MzmBv8FvjYfc7vDdxhnLFNskikkB+3vl475/XdCDhs= +cloud.google.com/go/dataplex v1.10.2/go.mod h1:xdC8URdTrCrZMW6keY779ZT1cTOfV8KEPNsw+LTRT1Y= +cloud.google.com/go/dataplex v1.11.1/go.mod h1:mHJYQQ2VEJHsyoC0OdNyy988DvEbPhqFs5OOLffLX0c= +cloud.google.com/go/dataplex v1.11.2/go.mod h1:mHJYQQ2VEJHsyoC0OdNyy988DvEbPhqFs5OOLffLX0c= +cloud.google.com/go/dataplex v1.13.0/go.mod h1:mHJYQQ2VEJHsyoC0OdNyy988DvEbPhqFs5OOLffLX0c= +cloud.google.com/go/dataplex v1.14.0/go.mod h1:mHJYQQ2VEJHsyoC0OdNyy988DvEbPhqFs5OOLffLX0c= +cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= +cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= +cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= +cloud.google.com/go/dataproc/v2 v2.0.1/go.mod h1:7Ez3KRHdFGcfY7GcevBbvozX+zyWGcwLJvvAMwCaoZ4= +cloud.google.com/go/dataproc/v2 v2.2.0/go.mod h1:lZR7AQtwZPvmINx5J87DSOOpTfof9LVZju6/Qo4lmcY= +cloud.google.com/go/dataproc/v2 v2.2.1/go.mod h1:QdAJLaBjh+l4PVlVZcmrmhGccosY/omC1qwfQ61Zv/o= +cloud.google.com/go/dataproc/v2 v2.2.2/go.mod h1:aocQywVmQVF4i8CL740rNI/ZRpsaaC1Wh2++BJ7HEJ4= +cloud.google.com/go/dataproc/v2 v2.2.3/go.mod h1:G5R6GBc9r36SXv/RtZIVfB8SipI+xVn0bX5SxUzVYbY= +cloud.google.com/go/dataproc/v2 v2.3.0/go.mod h1:G5R6GBc9r36SXv/RtZIVfB8SipI+xVn0bX5SxUzVYbY= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= +cloud.google.com/go/dataqna v0.8.1/go.mod h1:zxZM0Bl6liMePWsHA8RMGAfmTG34vJMapbHAxQ5+WA8= +cloud.google.com/go/dataqna v0.8.2/go.mod h1:KNEqgx8TTmUipnQsScOoDpq/VlXVptUqVMZnt30WAPs= +cloud.google.com/go/dataqna v0.8.3/go.mod h1:wXNBW2uvc9e7Gl5k8adyAMnLush1KVV6lZUhB+rqNu4= +cloud.google.com/go/dataqna v0.8.4/go.mod h1:mySRKjKg5Lz784P6sCov3p1QD+RZQONRMRjzGNcFd0c= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= +cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= +cloud.google.com/go/datastore v1.12.0/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= +cloud.google.com/go/datastore v1.12.1/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= +cloud.google.com/go/datastore v1.13.0/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= +cloud.google.com/go/datastore v1.14.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8= +cloud.google.com/go/datastore v1.15.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8= +cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= +cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= +cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= +cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= +cloud.google.com/go/datastream v1.9.1/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q= +cloud.google.com/go/datastream v1.10.0/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q= +cloud.google.com/go/datastream v1.10.1/go.mod h1:7ngSYwnw95YFyTd5tOGBxHlOZiL+OtpjheqU7t2/s/c= +cloud.google.com/go/datastream v1.10.2/go.mod h1:W42TFgKAs/om6x/CdXX5E4oiAsKlH+e8MTGy81zdYt0= +cloud.google.com/go/datastream v1.10.3/go.mod h1:YR0USzgjhqA/Id0Ycu1VvZe8hEWwrkjuXrGbzeDOSEA= +cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= +cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= +cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= +cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= +cloud.google.com/go/deploy v1.11.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g= +cloud.google.com/go/deploy v1.13.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g= +cloud.google.com/go/deploy v1.13.1/go.mod h1:8jeadyLkH9qu9xgO3hVWw8jVr29N1mnW42gRJT8GY6g= +cloud.google.com/go/deploy v1.14.1/go.mod h1:N8S0b+aIHSEeSr5ORVoC0+/mOPUysVt8ae4QkZYolAw= +cloud.google.com/go/deploy v1.14.2/go.mod h1:e5XOUI5D+YGldyLNZ21wbp9S8otJbBE4i88PtO9x/2g= +cloud.google.com/go/deploy v1.15.0/go.mod h1:e5XOUI5D+YGldyLNZ21wbp9S8otJbBE4i88PtO9x/2g= +cloud.google.com/go/deploy v1.16.0/go.mod h1:e5XOUI5D+YGldyLNZ21wbp9S8otJbBE4i88PtO9x/2g= +cloud.google.com/go/deploy v1.17.0/go.mod h1:XBr42U5jIr64t92gcpOXxNrqL2PStQCXHuKK5GRUuYo= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= +cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= +cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= +cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= +cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= +cloud.google.com/go/dialogflow v1.38.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4= +cloud.google.com/go/dialogflow v1.40.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4= +cloud.google.com/go/dialogflow v1.43.0/go.mod h1:pDUJdi4elL0MFmt1REMvFkdsUTYSHq+rTCS8wg0S3+M= +cloud.google.com/go/dialogflow v1.44.0/go.mod h1:pDUJdi4elL0MFmt1REMvFkdsUTYSHq+rTCS8wg0S3+M= +cloud.google.com/go/dialogflow v1.44.1/go.mod h1:n/h+/N2ouKOO+rbe/ZnI186xImpqvCVj2DdsWS/0EAk= +cloud.google.com/go/dialogflow v1.44.2/go.mod h1:QzFYndeJhpVPElnFkUXxdlptx0wPnBWLCBT9BvtC3/c= +cloud.google.com/go/dialogflow v1.44.3/go.mod h1:mHly4vU7cPXVweuB5R0zsYKPMzy240aQdAu06SqBbAQ= +cloud.google.com/go/dialogflow v1.47.0/go.mod h1:mHly4vU7cPXVweuB5R0zsYKPMzy240aQdAu06SqBbAQ= +cloud.google.com/go/dialogflow v1.48.0/go.mod h1:mHly4vU7cPXVweuB5R0zsYKPMzy240aQdAu06SqBbAQ= +cloud.google.com/go/dialogflow v1.48.1/go.mod h1:C1sjs2/g9cEwjCltkKeYp3FFpz8BOzNondEaAlCpt+A= +cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= +cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= +cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= +cloud.google.com/go/dlp v1.10.1/go.mod h1:IM8BWz1iJd8njcNcG0+Kyd9OPnqnRNkDV8j42VT5KOI= +cloud.google.com/go/dlp v1.10.2/go.mod h1:ZbdKIhcnyhILgccwVDzkwqybthh7+MplGC3kZVZsIOQ= +cloud.google.com/go/dlp v1.10.3/go.mod h1:iUaTc/ln8I+QT6Ai5vmuwfw8fqTk2kaz0FvCwhLCom0= +cloud.google.com/go/dlp v1.11.1/go.mod h1:/PA2EnioBeXTL/0hInwgj0rfsQb3lpE3R8XUJxqUNKI= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= +cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= +cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= +cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= +cloud.google.com/go/documentai v1.20.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E= +cloud.google.com/go/documentai v1.22.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E= +cloud.google.com/go/documentai v1.22.1/go.mod h1:LKs22aDHbJv7ufXuPypzRO7rG3ALLJxzdCXDPutw4Qc= +cloud.google.com/go/documentai v1.23.0/go.mod h1:LKs22aDHbJv7ufXuPypzRO7rG3ALLJxzdCXDPutw4Qc= +cloud.google.com/go/documentai v1.23.2/go.mod h1:Q/wcRT+qnuXOpjAkvOV4A+IeQl04q2/ReT7SSbytLSo= +cloud.google.com/go/documentai v1.23.4/go.mod h1:4MYAaEMnADPN1LPN5xboDR5QVB6AgsaxgFdJhitlE2Y= +cloud.google.com/go/documentai v1.23.5/go.mod h1:ghzBsyVTiVdkfKaUCum/9bGBEyBjDO4GfooEcYKhN+g= +cloud.google.com/go/documentai v1.23.6/go.mod h1:ghzBsyVTiVdkfKaUCum/9bGBEyBjDO4GfooEcYKhN+g= +cloud.google.com/go/documentai v1.23.7/go.mod h1:ghzBsyVTiVdkfKaUCum/9bGBEyBjDO4GfooEcYKhN+g= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= +cloud.google.com/go/domains v0.9.1/go.mod h1:aOp1c0MbejQQ2Pjf1iJvnVyT+z6R6s8pX66KaCSDYfE= +cloud.google.com/go/domains v0.9.2/go.mod h1:3YvXGYzZG1Temjbk7EyGCuGGiXHJwVNmwIf+E/cUp5I= +cloud.google.com/go/domains v0.9.3/go.mod h1:29k66YNDLDY9LCFKpGFeh6Nj9r62ZKm5EsUJxAl84KU= +cloud.google.com/go/domains v0.9.4/go.mod h1:27jmJGShuXYdUNjyDG0SodTfT5RwLi7xmH334Gvi3fY= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= +cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= +cloud.google.com/go/edgecontainer v1.1.1/go.mod h1:O5bYcS//7MELQZs3+7mabRqoWQhXCzenBu0R8bz2rwk= +cloud.google.com/go/edgecontainer v1.1.2/go.mod h1:wQRjIzqxEs9e9wrtle4hQPSR1Y51kqN75dgF7UllZZ4= +cloud.google.com/go/edgecontainer v1.1.3/go.mod h1:Ll2DtIABzEfaxaVSbwj3QHFaOOovlDFiWVDu349jSsA= +cloud.google.com/go/edgecontainer v1.1.4/go.mod h1:AvFdVuZuVGdgaE5YvlL1faAoa1ndRR/5XhXZvPBHbsE= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= +cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= +cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= +cloud.google.com/go/essentialcontacts v1.6.2/go.mod h1:T2tB6tX+TRak7i88Fb2N9Ok3PvY3UNbUsMag9/BARh4= +cloud.google.com/go/essentialcontacts v1.6.3/go.mod h1:yiPCD7f2TkP82oJEFXFTou8Jl8L6LBRPeBEkTaO0Ggo= +cloud.google.com/go/essentialcontacts v1.6.4/go.mod h1:iju5Vy3d9tJUg0PYMd1nHhjV7xoCXaOAVabrwLaPBEM= +cloud.google.com/go/essentialcontacts v1.6.5/go.mod h1:jjYbPzw0x+yglXC890l6ECJWdYeZ5dlYACTFL0U/VuM= +cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= +cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= +cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= +cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= +cloud.google.com/go/eventarc v1.12.1/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI= +cloud.google.com/go/eventarc v1.13.0/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI= +cloud.google.com/go/eventarc v1.13.1/go.mod h1:EqBxmGHFrruIara4FUQ3RHlgfCn7yo1HYsu2Hpt/C3Y= +cloud.google.com/go/eventarc v1.13.2/go.mod h1:X9A80ShVu19fb4e5sc/OLV7mpFUKZMwfJFeeWhcIObM= +cloud.google.com/go/eventarc v1.13.3/go.mod h1:RWH10IAZIRcj1s/vClXkBgMHwh59ts7hSWcqD3kaclg= +cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= +cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= +cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= +cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= +cloud.google.com/go/filestore v1.7.1/go.mod h1:y10jsorq40JJnjR/lQ8AfFbbcGlw3g+Dp8oN7i7FjV4= +cloud.google.com/go/filestore v1.7.2/go.mod h1:TYOlyJs25f/omgj+vY7/tIG/E7BX369triSPzE4LdgE= +cloud.google.com/go/filestore v1.7.3/go.mod h1:Qp8WaEERR3cSkxToxFPHh/b8AACkSut+4qlCjAmKTV0= +cloud.google.com/go/filestore v1.7.4/go.mod h1:S5JCxIbFjeBhWMTfIYH2Jx24J6BqjwpkkPl+nBA5DlI= +cloud.google.com/go/filestore v1.8.0/go.mod h1:S5JCxIbFjeBhWMTfIYH2Jx24J6BqjwpkkPl+nBA5DlI= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/firestore v1.11.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4= +cloud.google.com/go/firestore v1.12.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4= +cloud.google.com/go/firestore v1.13.0/go.mod h1:QojqqOh8IntInDUSTAh0c8ZsPYAr68Ma8c5DWOy8xb8= +cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= +cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= +cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= +cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA= +cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= +cloud.google.com/go/functions v1.15.1/go.mod h1:P5yNWUTkyU+LvW/S9O6V+V423VZooALQlqoXdoPz5AE= +cloud.google.com/go/functions v1.15.2/go.mod h1:CHAjtcR6OU4XF2HuiVeriEdELNcnvRZSk1Q8RMqy4lE= +cloud.google.com/go/functions v1.15.3/go.mod h1:r/AMHwBheapkkySEhiZYLDBwVJCdlRwsm4ieJu35/Ug= +cloud.google.com/go/functions v1.15.4/go.mod h1:CAsTc3VlRMVvx+XqXxKqVevguqJpnVip4DdonFsX28I= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= +cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= +cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= +cloud.google.com/go/gaming v1.10.1/go.mod h1:XQQvtfP8Rb9Rxnxm5wFVpAp9zCQkJi2bLIb7iHGwB3s= +cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= +cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= +cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= +cloud.google.com/go/gkebackup v1.3.0/go.mod h1:vUDOu++N0U5qs4IhG1pcOnD1Mac79xWy6GoBFlWCWBU= +cloud.google.com/go/gkebackup v1.3.1/go.mod h1:vUDOu++N0U5qs4IhG1pcOnD1Mac79xWy6GoBFlWCWBU= +cloud.google.com/go/gkebackup v1.3.2/go.mod h1:OMZbXzEJloyXMC7gqdSB+EOEQ1AKcpGYvO3s1ec5ixk= +cloud.google.com/go/gkebackup v1.3.3/go.mod h1:eMk7/wVV5P22KBakhQnJxWSVftL1p4VBFLpv0kIft7I= +cloud.google.com/go/gkebackup v1.3.4/go.mod h1:gLVlbM8h/nHIs09ns1qx3q3eaXcGSELgNu1DWXYz1HI= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= +cloud.google.com/go/gkeconnect v0.8.1/go.mod h1:KWiK1g9sDLZqhxB2xEuPV8V9NYzrqTUmQR9shJHpOZw= +cloud.google.com/go/gkeconnect v0.8.2/go.mod h1:6nAVhwchBJYgQCXD2pHBFQNiJNyAd/wyxljpaa6ZPrY= +cloud.google.com/go/gkeconnect v0.8.3/go.mod h1:i9GDTrfzBSUZGCe98qSu1B8YB8qfapT57PenIb820Jo= +cloud.google.com/go/gkeconnect v0.8.4/go.mod h1:84hZz4UMlDCKl8ifVW8layK4WHlMAFeq8vbzjU0yJkw= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= +cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= +cloud.google.com/go/gkehub v0.14.1/go.mod h1:VEXKIJZ2avzrbd7u+zeMtW00Y8ddk/4V9511C9CQGTY= +cloud.google.com/go/gkehub v0.14.2/go.mod h1:iyjYH23XzAxSdhrbmfoQdePnlMj2EWcvnR+tHdBQsCY= +cloud.google.com/go/gkehub v0.14.3/go.mod h1:jAl6WafkHHW18qgq7kqcrXYzN08hXeK/Va3utN8VKg8= +cloud.google.com/go/gkehub v0.14.4/go.mod h1:Xispfu2MqnnFt8rV/2/3o73SK1snL8s9dYJ9G2oQMfc= +cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= +cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= +cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= +cloud.google.com/go/gkemulticloud v0.6.1/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw= +cloud.google.com/go/gkemulticloud v1.0.0/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw= +cloud.google.com/go/gkemulticloud v1.0.1/go.mod h1:AcrGoin6VLKT/fwZEYuqvVominLriQBCKmbjtnbMjG8= +cloud.google.com/go/gkemulticloud v1.0.2/go.mod h1:+ee5VXxKb3H1l4LZAcgWB/rvI16VTNTrInWxDjAGsGo= +cloud.google.com/go/gkemulticloud v1.0.3/go.mod h1:7NpJBN94U6DY1xHIbsDqB2+TFZUfjLUKLjUX8NGLor0= +cloud.google.com/go/gkemulticloud v1.1.0/go.mod h1:7NpJBN94U6DY1xHIbsDqB2+TFZUfjLUKLjUX8NGLor0= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/grafeas v0.3.0/go.mod h1:P7hgN24EyONOTMyeJH6DxG4zD7fwiYa5Q6GUgyFSOU8= +cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= +cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= +cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= +cloud.google.com/go/gsuiteaddons v1.6.1/go.mod h1:CodrdOqRZcLp5WOwejHWYBjZvfY0kOphkAKpF/3qdZY= +cloud.google.com/go/gsuiteaddons v1.6.2/go.mod h1:K65m9XSgs8hTF3X9nNTPi8IQueljSdYo9F+Mi+s4MyU= +cloud.google.com/go/gsuiteaddons v1.6.3/go.mod h1:sCFJkZoMrLZT3JTb8uJqgKPNshH2tfXeCwTFRebTq48= +cloud.google.com/go/gsuiteaddons v1.6.4/go.mod h1:rxtstw7Fx22uLOXBpsvb9DUbC+fiXs7rF4U29KHM/pE= +cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= +cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= +cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= +cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= +cloud.google.com/go/iam v1.0.1/go.mod h1:yR3tmSL8BcZB4bxByRv2jkSIahVmCtfKZwLYGBalRE8= +cloud.google.com/go/iam v1.1.0/go.mod h1:nxdHjaKfCr7fNYx/HJMM8LgiMugmveWlkatear5gVyk= +cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= +cloud.google.com/go/iam v1.1.2/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= +cloud.google.com/go/iam v1.1.3/go.mod h1:3khUlaBXfPKKe7huYgEpDn6FtgRyMEqbkvBxrQyY5SE= +cloud.google.com/go/iam v1.1.4/go.mod h1:l/rg8l1AaA+VFMho/HYx2Vv6xinPSLMF8qfhRPIZ0L8= +cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= +cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= +cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= +cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= +cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= +cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= +cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo= +cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= +cloud.google.com/go/iap v1.8.1/go.mod h1:sJCbeqg3mvWLqjZNsI6dfAtbbV1DL2Rl7e1mTyXYREQ= +cloud.google.com/go/iap v1.9.0/go.mod h1:01OFxd1R+NFrg78S+hoPV5PxEzv22HXaNqUUlmNHFuY= +cloud.google.com/go/iap v1.9.1/go.mod h1:SIAkY7cGMLohLSdBR25BuIxO+I4fXJiL06IBL7cy/5Q= +cloud.google.com/go/iap v1.9.2/go.mod h1:GwDTOs047PPSnwRD0Us5FKf4WDRcVvHg1q9WVkKBhdI= +cloud.google.com/go/iap v1.9.3/go.mod h1:DTdutSZBqkkOm2HEOTBzhZxh2mwwxshfD/h3yofAiCw= +cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= +cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= +cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= +cloud.google.com/go/ids v1.4.1/go.mod h1:np41ed8YMU8zOgv53MMMoCntLTn2lF+SUzlM+O3u/jw= +cloud.google.com/go/ids v1.4.2/go.mod h1:3vw8DX6YddRu9BncxuzMyWn0g8+ooUjI2gslJ7FH3vk= +cloud.google.com/go/ids v1.4.3/go.mod h1:9CXPqI3GedjmkjbMWCUhMZ2P2N7TUMzAkVXYEH2orYU= +cloud.google.com/go/ids v1.4.4/go.mod h1:z+WUc2eEl6S/1aZWzwtVNWoSZslgzPxAboS0lZX0HjI= +cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= +cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= +cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= +cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= +cloud.google.com/go/iot v1.7.1/go.mod h1:46Mgw7ev1k9KqK1ao0ayW9h0lI+3hxeanz+L1zmbbbk= +cloud.google.com/go/iot v1.7.2/go.mod h1:q+0P5zr1wRFpw7/MOgDXrG/HVA+l+cSwdObffkrpnSg= +cloud.google.com/go/iot v1.7.3/go.mod h1:t8itFchkol4VgNbHnIq9lXoOOtHNR3uAACQMYbN9N4I= +cloud.google.com/go/iot v1.7.4/go.mod h1:3TWqDVvsddYBG++nHSZmluoCAVGr1hAcabbWZNKEZLk= +cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= +cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= +cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= +cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg= +cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= +cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24= +cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= +cloud.google.com/go/kms v1.11.0/go.mod h1:hwdiYC0xjnWsKQQCQQmIQnS9asjYVSK6jtXm+zFqXLM= +cloud.google.com/go/kms v1.12.1/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM= +cloud.google.com/go/kms v1.15.0/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM= +cloud.google.com/go/kms v1.15.2/go.mod h1:3hopT4+7ooWRCjc2DxgnpESFxhIraaI2IpAVUEhbT/w= +cloud.google.com/go/kms v1.15.3/go.mod h1:AJdXqHxS2GlPyduM99s9iGqi2nwbviBbhV/hdmt4iOQ= +cloud.google.com/go/kms v1.15.4/go.mod h1:L3Sdj6QTHK8dfwK5D1JLsAyELsNMnd3tAIwGS4ltKpc= +cloud.google.com/go/kms v1.15.5/go.mod h1:cU2H5jnp6G2TDpUGZyqTCoy1n16fbubHZjmVXSMtwDI= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= +cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= +cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= +cloud.google.com/go/language v1.10.1/go.mod h1:CPp94nsdVNiQEt1CNjF5WkTcisLiHPyIbMhvR8H2AW0= +cloud.google.com/go/language v1.11.0/go.mod h1:uDx+pFDdAKTY8ehpWbiXyQdz8tDSYLJbQcXsCkjYyvQ= +cloud.google.com/go/language v1.11.1/go.mod h1:Xyid9MG9WOX3utvDbpX7j3tXDmmDooMyMDqgUVpH17U= +cloud.google.com/go/language v1.12.1/go.mod h1:zQhalE2QlQIxbKIZt54IASBzmZpN/aDASea5zl1l+J4= +cloud.google.com/go/language v1.12.2/go.mod h1:9idWapzr/JKXBBQ4lWqVX/hcadxB194ry20m/bTrhWc= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= +cloud.google.com/go/lifesciences v0.9.1/go.mod h1:hACAOd1fFbCGLr/+weUKRAJas82Y4vrL3O5326N//Wc= +cloud.google.com/go/lifesciences v0.9.2/go.mod h1:QHEOO4tDzcSAzeJg7s2qwnLM2ji8IRpQl4p6m5Z9yTA= +cloud.google.com/go/lifesciences v0.9.3/go.mod h1:gNGBOJV80IWZdkd+xz4GQj4mbqaz737SCLHn2aRhQKM= +cloud.google.com/go/lifesciences v0.9.4/go.mod h1:bhm64duKhMi7s9jR9WYJYvjAFJwRqNj+Nia7hF0Z7JA= +cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= +cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= +cloud.google.com/go/logging v1.8.1/go.mod h1:TJjR+SimHwuC8MZ9cjByQulAMgni+RkXeI3wwctHJEI= +cloud.google.com/go/logging v1.9.0/go.mod h1:1Io0vnZv4onoUnsVUQY3HZ3Igb1nBchky0A0y7BBBhE= +cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc= +cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA= +cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= +cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= +cloud.google.com/go/longrunning v0.4.2/go.mod h1:OHrnaYyLUV6oqwh0xiS7e5sLQhP1m0QU9R+WhGDMgIQ= +cloud.google.com/go/longrunning v0.5.0/go.mod h1:0JNuqRShmscVAhIACGtskSAWtqtOoPkwP0YF1oVEchc= +cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc= +cloud.google.com/go/longrunning v0.5.2/go.mod h1:nqo6DQbNV2pXhGDbDMoN2bWz68MjZUzqv2YttZiveCs= +cloud.google.com/go/longrunning v0.5.3/go.mod h1:y/0ga59EYu58J6SHmmQOvekvND2qODbu8ywBBW7EK7Y= +cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI= +cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= +cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= +cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= +cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= +cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= +cloud.google.com/go/managedidentities v1.6.1/go.mod h1:h/irGhTN2SkZ64F43tfGPMbHnypMbu4RB3yl8YcuEak= +cloud.google.com/go/managedidentities v1.6.2/go.mod h1:5c2VG66eCa0WIq6IylRk3TBW83l161zkFvCj28X7jn8= +cloud.google.com/go/managedidentities v1.6.3/go.mod h1:tewiat9WLyFN0Fi7q1fDD5+0N4VUoL0SCX0OTCthZq4= +cloud.google.com/go/managedidentities v1.6.4/go.mod h1:WgyaECfHmF00t/1Uk8Oun3CQ2PGUtjc3e9Alh79wyiM= +cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= +cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= +cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= +cloud.google.com/go/maps v1.3.0/go.mod h1:6mWTUv+WhnOwAgjVsSW2QPPECmW+s3PcRyOa9vgG/5s= +cloud.google.com/go/maps v1.4.0/go.mod h1:6mWTUv+WhnOwAgjVsSW2QPPECmW+s3PcRyOa9vgG/5s= +cloud.google.com/go/maps v1.4.1/go.mod h1:BxSa0BnW1g2U2gNdbq5zikLlHUuHW0GFWh7sgML2kIY= +cloud.google.com/go/maps v1.5.1/go.mod h1:NPMZw1LJwQZYCfz4y+EIw+SI+24A4bpdFJqdKVr0lt4= +cloud.google.com/go/maps v1.6.1/go.mod h1:4+buOHhYXFBp58Zj/K+Lc1rCmJssxxF4pJ5CJnhdz18= +cloud.google.com/go/maps v1.6.2/go.mod h1:4+buOHhYXFBp58Zj/K+Lc1rCmJssxxF4pJ5CJnhdz18= +cloud.google.com/go/maps v1.6.3/go.mod h1:VGAn809ADswi1ASofL5lveOHPnE6Rk/SFTTBx1yuOLw= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= +cloud.google.com/go/mediatranslation v0.8.1/go.mod h1:L/7hBdEYbYHQJhX2sldtTO5SZZ1C1vkapubj0T2aGig= +cloud.google.com/go/mediatranslation v0.8.2/go.mod h1:c9pUaDRLkgHRx3irYE5ZC8tfXGrMYwNZdmDqKMSfFp8= +cloud.google.com/go/mediatranslation v0.8.3/go.mod h1:F9OnXTy336rteOEywtY7FOqCk+J43o2RF638hkOQl4Y= +cloud.google.com/go/mediatranslation v0.8.4/go.mod h1:9WstgtNVAdN53m6TQa5GjIjLqKQPXe74hwSCxUP6nj4= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= +cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= +cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= +cloud.google.com/go/memcache v1.10.1/go.mod h1:47YRQIarv4I3QS5+hoETgKO40InqzLP6kpNLvyXuyaA= +cloud.google.com/go/memcache v1.10.2/go.mod h1:f9ZzJHLBrmd4BkguIAa/l/Vle6uTHzHokdnzSWOdQ6A= +cloud.google.com/go/memcache v1.10.3/go.mod h1:6z89A41MT2DVAW0P4iIRdu5cmRTsbsFn4cyiIx8gbwo= +cloud.google.com/go/memcache v1.10.4/go.mod h1:v/d8PuC8d1gD6Yn5+I3INzLR01IDn0N4Ym56RgikSI0= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= +cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= +cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= +cloud.google.com/go/metastore v1.11.1/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA= +cloud.google.com/go/metastore v1.12.0/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA= +cloud.google.com/go/metastore v1.13.0/go.mod h1:URDhpG6XLeh5K+Glq0NOt74OfrPKTwS62gEPZzb5SOk= +cloud.google.com/go/metastore v1.13.1/go.mod h1:IbF62JLxuZmhItCppcIfzBBfUFq0DIB9HPDoLgWrVOU= +cloud.google.com/go/metastore v1.13.2/go.mod h1:KS59dD+unBji/kFebVp8XU/quNSyo8b6N6tPGspKszA= +cloud.google.com/go/metastore v1.13.3/go.mod h1:K+wdjXdtkdk7AQg4+sXS8bRrQa9gcOr+foOMF2tqINE= +cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= +cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= +cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= +cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= +cloud.google.com/go/monitoring v1.15.1/go.mod h1:lADlSAlFdbqQuwwpaImhsJXu1QSdd3ojypXrFSMr2rM= +cloud.google.com/go/monitoring v1.16.0/go.mod h1:Ptp15HgAyM1fNICAojDMoNc/wUmn67mLHQfyqbw+poY= +cloud.google.com/go/monitoring v1.16.1/go.mod h1:6HsxddR+3y9j+o/cMJH6q/KJ/CBTvM/38L/1m7bTRJ4= +cloud.google.com/go/monitoring v1.16.2/go.mod h1:B44KGwi4ZCF8Rk/5n+FWeispDXoKSk9oss2QNlXJBgc= +cloud.google.com/go/monitoring v1.16.3/go.mod h1:KwSsX5+8PnXv5NJnICZzW2R8pWTis8ypC4zmdRD63Tw= +cloud.google.com/go/monitoring v1.17.0/go.mod h1:KwSsX5+8PnXv5NJnICZzW2R8pWTis8ypC4zmdRD63Tw= +cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM= +cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= +cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= +cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= +cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= +cloud.google.com/go/networkconnectivity v1.12.1/go.mod h1:PelxSWYM7Sh9/guf8CFhi6vIqf19Ir/sbfZRUwXh92E= +cloud.google.com/go/networkconnectivity v1.13.0/go.mod h1:SAnGPes88pl7QRLUen2HmcBSE9AowVAcdug8c0RSBFk= +cloud.google.com/go/networkconnectivity v1.14.0/go.mod h1:SAnGPes88pl7QRLUen2HmcBSE9AowVAcdug8c0RSBFk= +cloud.google.com/go/networkconnectivity v1.14.1/go.mod h1:LyGPXR742uQcDxZ/wv4EI0Vu5N6NKJ77ZYVnDe69Zug= +cloud.google.com/go/networkconnectivity v1.14.2/go.mod h1:5UFlwIisZylSkGG1AdwK/WZUaoz12PKu6wODwIbFzJo= +cloud.google.com/go/networkconnectivity v1.14.3/go.mod h1:4aoeFdrJpYEXNvrnfyD5kIzs8YtHg945Og4koAjHQek= +cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= +cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= +cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= +cloud.google.com/go/networkmanagement v1.8.0/go.mod h1:Ho/BUGmtyEqrttTgWEe7m+8vDdK74ibQc+Be0q7Fof0= +cloud.google.com/go/networkmanagement v1.9.0/go.mod h1:UTUaEU9YwbCAhhz3jEOHr+2/K/MrBk2XxOLS89LQzFw= +cloud.google.com/go/networkmanagement v1.9.1/go.mod h1:CCSYgrQQvW73EJawO2QamemYcOb57LvrDdDU51F0mcI= +cloud.google.com/go/networkmanagement v1.9.2/go.mod h1:iDGvGzAoYRghhp4j2Cji7sF899GnfGQcQRQwgVOWnDw= +cloud.google.com/go/networkmanagement v1.9.3/go.mod h1:y7WMO1bRLaP5h3Obm4tey+NquUvB93Co1oh4wpL+XcU= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= +cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= +cloud.google.com/go/networksecurity v0.9.1/go.mod h1:MCMdxOKQ30wsBI1eI659f9kEp4wuuAueoC9AJKSPWZQ= +cloud.google.com/go/networksecurity v0.9.2/go.mod h1:jG0SeAttWzPMUILEHDUvFYdQTl8L/E/KC8iZDj85lEI= +cloud.google.com/go/networksecurity v0.9.3/go.mod h1:l+C0ynM6P+KV9YjOnx+kk5IZqMSLccdBqW6GUoF4p/0= +cloud.google.com/go/networksecurity v0.9.4/go.mod h1:E9CeMZ2zDsNBkr8axKSYm8XyTqNhiCHf1JO/Vb8mD1w= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= +cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= +cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= +cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= +cloud.google.com/go/notebooks v1.9.1/go.mod h1:zqG9/gk05JrzgBt4ghLzEepPHNwE5jgPcHZRKhlC1A8= +cloud.google.com/go/notebooks v1.10.0/go.mod h1:SOPYMZnttHxqot0SGSFSkRrwE29eqnKPBJFqgWmiK2k= +cloud.google.com/go/notebooks v1.10.1/go.mod h1:5PdJc2SgAybE76kFQCWrTfJolCOUQXF97e+gteUUA6A= +cloud.google.com/go/notebooks v1.11.1/go.mod h1:V2Zkv8wX9kDCGRJqYoI+bQAaoVeE5kSiz4yYHd2yJwQ= +cloud.google.com/go/notebooks v1.11.2/go.mod h1:z0tlHI/lREXC8BS2mIsUeR3agM1AkgLiS+Isov3SS70= +cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= +cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= +cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= +cloud.google.com/go/optimization v1.4.1/go.mod h1:j64vZQP7h9bO49m2rVaTVoNM0vEBEN5eKPUPbZyXOrk= +cloud.google.com/go/optimization v1.5.0/go.mod h1:evo1OvTxeBRBu6ydPlrIRizKY/LJKo/drDMMRKqGEUU= +cloud.google.com/go/optimization v1.5.1/go.mod h1:NC0gnUD5MWVAF7XLdoYVPmYYVth93Q6BUzqAq3ZwtV8= +cloud.google.com/go/optimization v1.6.1/go.mod h1:hH2RYPTTM9e9zOiTaYPTiGPcGdNZVnBSBxjIAJzUkqo= +cloud.google.com/go/optimization v1.6.2/go.mod h1:mWNZ7B9/EyMCcwNl1frUGEuY6CPijSkz88Fz2vwKPOY= +cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= +cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= +cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= +cloud.google.com/go/orchestration v1.8.1/go.mod h1:4sluRF3wgbYVRqz7zJ1/EUNc90TTprliq9477fGobD8= +cloud.google.com/go/orchestration v1.8.2/go.mod h1:T1cP+6WyTmh6LSZzeUhvGf0uZVmJyTx7t8z7Vg87+A0= +cloud.google.com/go/orchestration v1.8.3/go.mod h1:xhgWAYqlbYjlz2ftbFghdyqENYW+JXuhBx9KsjMoGHs= +cloud.google.com/go/orchestration v1.8.4/go.mod h1:d0lywZSVYtIoSZXb0iFjv9SaL13PGyVOKDxqGxEf/qI= +cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= +cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= +cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= +cloud.google.com/go/orgpolicy v1.11.0/go.mod h1:2RK748+FtVvnfuynxBzdnyu7sygtoZa1za/0ZfpOs1M= +cloud.google.com/go/orgpolicy v1.11.1/go.mod h1:8+E3jQcpZJQliP+zaFfayC2Pg5bmhuLK755wKhIIUCE= +cloud.google.com/go/orgpolicy v1.11.2/go.mod h1:biRDpNwfyytYnmCRWZWxrKF22Nkz9eNVj9zyaBdpm1o= +cloud.google.com/go/orgpolicy v1.11.3/go.mod h1:oKAtJ/gkMjum5icv2aujkP4CxROxPXsBbYGCDbPO8MM= +cloud.google.com/go/orgpolicy v1.11.4/go.mod h1:0+aNV/nrfoTQ4Mytv+Aw+stBDBjNf4d8fYRA9herfJI= +cloud.google.com/go/orgpolicy v1.12.0/go.mod h1:0+aNV/nrfoTQ4Mytv+Aw+stBDBjNf4d8fYRA9herfJI= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= +cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= +cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= +cloud.google.com/go/osconfig v1.12.0/go.mod h1:8f/PaYzoS3JMVfdfTubkowZYGmAhUCjjwnjqWI7NVBc= +cloud.google.com/go/osconfig v1.12.1/go.mod h1:4CjBxND0gswz2gfYRCUoUzCm9zCABp91EeTtWXyz0tE= +cloud.google.com/go/osconfig v1.12.2/go.mod h1:eh9GPaMZpI6mEJEuhEjUJmaxvQ3gav+fFEJon1Y8Iw0= +cloud.google.com/go/osconfig v1.12.3/go.mod h1:L/fPS8LL6bEYUi1au832WtMnPeQNT94Zo3FwwV1/xGM= +cloud.google.com/go/osconfig v1.12.4/go.mod h1:B1qEwJ/jzqSRslvdOCI8Kdnp0gSng0xW4LOnIebQomA= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= +cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= +cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= +cloud.google.com/go/oslogin v1.10.1/go.mod h1:x692z7yAue5nE7CsSnoG0aaMbNoRJRXO4sn73R+ZqAs= +cloud.google.com/go/oslogin v1.11.0/go.mod h1:8GMTJs4X2nOAUVJiPGqIWVcDaF0eniEto3xlOxaboXE= +cloud.google.com/go/oslogin v1.11.1/go.mod h1:OhD2icArCVNUxKqtK0mcSmKL7lgr0LVlQz+v9s1ujTg= +cloud.google.com/go/oslogin v1.12.1/go.mod h1:VfwTeFJGbnakxAY236eN8fsnglLiVXndlbcNomY4iZU= +cloud.google.com/go/oslogin v1.12.2/go.mod h1:CQ3V8Jvw4Qo4WRhNPF0o+HAM4DiLuE27Ul9CX9g2QdY= +cloud.google.com/go/oslogin v1.13.0/go.mod h1:xPJqLwpTZ90LSE5IL1/svko+6c5avZLluiyylMb/sRA= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= +cloud.google.com/go/phishingprotection v0.8.1/go.mod h1:AxonW7GovcA8qdEk13NfHq9hNx5KPtfxXNeUxTDxB6I= +cloud.google.com/go/phishingprotection v0.8.2/go.mod h1:LhJ91uyVHEYKSKcMGhOa14zMMWfbEdxG032oT6ECbC8= +cloud.google.com/go/phishingprotection v0.8.3/go.mod h1:3B01yO7T2Ra/TMojifn8EoGd4G9jts/6cIO0DgDY9J8= +cloud.google.com/go/phishingprotection v0.8.4/go.mod h1:6b3kNPAc2AQ6jZfFHioZKg9MQNybDg4ixFd4RPZZ2nE= +cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= +cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= +cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= +cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= +cloud.google.com/go/policytroubleshooter v1.7.1/go.mod h1:0NaT5v3Ag1M7U5r0GfDCpUFkWd9YqpubBWsQlhanRv0= +cloud.google.com/go/policytroubleshooter v1.8.0/go.mod h1:tmn5Ir5EToWe384EuboTcVQT7nTag2+DuH3uHmKd1HU= +cloud.google.com/go/policytroubleshooter v1.9.0/go.mod h1:+E2Lga7TycpeSTj2FsH4oXxTnrbHJGRlKhVZBLGgU64= +cloud.google.com/go/policytroubleshooter v1.9.1/go.mod h1:MYI8i0bCrL8cW+VHN1PoiBTyNZTstCg2WUw2eVC4c4U= +cloud.google.com/go/policytroubleshooter v1.10.1/go.mod h1:5C0rhT3TDZVxAu8813bwmTvd57Phbl8mr9F4ipOsxEs= +cloud.google.com/go/policytroubleshooter v1.10.2/go.mod h1:m4uF3f6LseVEnMV6nknlN2vYGRb+75ylQwJdnOXfnv0= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= +cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= +cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= +cloud.google.com/go/privatecatalog v0.9.1/go.mod h1:0XlDXW2unJXdf9zFz968Hp35gl/bhF4twwpXZAW50JA= +cloud.google.com/go/privatecatalog v0.9.2/go.mod h1:RMA4ATa8IXfzvjrhhK8J6H4wwcztab+oZph3c6WmtFc= +cloud.google.com/go/privatecatalog v0.9.3/go.mod h1:K5pn2GrVmOPjXz3T26mzwXLcKivfIJ9R5N79AFCF9UE= +cloud.google.com/go/privatecatalog v0.9.4/go.mod h1:SOjm93f+5hp/U3PqMZAHTtBtluqLygrDrVO8X8tYtG0= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= +cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= +cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= +cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= +cloud.google.com/go/pubsub v1.32.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= +cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= +cloud.google.com/go/pubsub v1.34.0/go.mod h1:alj4l4rBg+N3YTFDDC+/YyFTs6JAjam2QfYsddcAW4c= +cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= +cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= +cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= +cloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= +cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= +cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= +cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= +cloud.google.com/go/recaptchaenterprise/v2 v2.7.2/go.mod h1:kR0KjsJS7Jt1YSyWFkseQ756D45kaYNTlDPPaRAvDBU= +cloud.google.com/go/recaptchaenterprise/v2 v2.8.0/go.mod h1:QuE8EdU9dEnesG8/kG3XuJyNsjEqMlMzg3v3scCJ46c= +cloud.google.com/go/recaptchaenterprise/v2 v2.8.1/go.mod h1:JZYZJOeZjgSSTGP4uz7NlQ4/d1w5hGmksVgM0lbEij0= +cloud.google.com/go/recaptchaenterprise/v2 v2.8.2/go.mod h1:kpaDBOpkwD4G0GVMzG1W6Doy1tFFC97XAV3xy+Rd/pw= +cloud.google.com/go/recaptchaenterprise/v2 v2.8.3/go.mod h1:Dak54rw6lC2gBY8FBznpOCAR58wKf+R+ZSJRoeJok4w= +cloud.google.com/go/recaptchaenterprise/v2 v2.8.4/go.mod h1:Dak54rw6lC2gBY8FBznpOCAR58wKf+R+ZSJRoeJok4w= +cloud.google.com/go/recaptchaenterprise/v2 v2.9.0/go.mod h1:Dak54rw6lC2gBY8FBznpOCAR58wKf+R+ZSJRoeJok4w= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= +cloud.google.com/go/recommendationengine v0.8.1/go.mod h1:MrZihWwtFYWDzE6Hz5nKcNz3gLizXVIDI/o3G1DLcrE= +cloud.google.com/go/recommendationengine v0.8.2/go.mod h1:QIybYHPK58qir9CV2ix/re/M//Ty10OxjnnhWdaKS1Y= +cloud.google.com/go/recommendationengine v0.8.3/go.mod h1:m3b0RZV02BnODE9FeSvGv1qibFo8g0OnmB/RMwYy4V8= +cloud.google.com/go/recommendationengine v0.8.4/go.mod h1:GEteCf1PATl5v5ZsQ60sTClUE0phbWmo3rQ1Js8louU= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= +cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= +cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= +cloud.google.com/go/recommender v1.10.1/go.mod h1:XFvrE4Suqn5Cq0Lf+mCP6oBHD/yRMA8XxP5sb7Q7gpA= +cloud.google.com/go/recommender v1.11.0/go.mod h1:kPiRQhPyTJ9kyXPCG6u/dlPLbYfFlkwHNRwdzPVAoII= +cloud.google.com/go/recommender v1.11.1/go.mod h1:sGwFFAyI57v2Hc5LbIj+lTwXipGu9NW015rkaEM5B18= +cloud.google.com/go/recommender v1.11.2/go.mod h1:AeoJuzOvFR/emIcXdVFkspVXVTYpliRCmKNYDnyBv6Y= +cloud.google.com/go/recommender v1.11.3/go.mod h1:+FJosKKJSId1MBFeJ/TTyoGQZiEelQQIZMKYYD8ruK4= +cloud.google.com/go/recommender v1.12.0/go.mod h1:+FJosKKJSId1MBFeJ/TTyoGQZiEelQQIZMKYYD8ruK4= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= +cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= +cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= +cloud.google.com/go/redis v1.13.1/go.mod h1:VP7DGLpE91M6bcsDdMuyCm2hIpB6Vp2hI090Mfd1tcg= +cloud.google.com/go/redis v1.13.2/go.mod h1:0Hg7pCMXS9uz02q+LoEVl5dNHUkIQv+C/3L76fandSA= +cloud.google.com/go/redis v1.13.3/go.mod h1:vbUpCKUAZSYzFcWKmICnYgRAhTFg9r+djWqFxDYXi4U= +cloud.google.com/go/redis v1.14.1/go.mod h1:MbmBxN8bEnQI4doZPC1BzADU4HGocHBk2de3SbgOkqs= +cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= +cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= +cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= +cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo= +cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= +cloud.google.com/go/resourcemanager v1.9.1/go.mod h1:dVCuosgrh1tINZ/RwBufr8lULmWGOkPS8gL5gqyjdT8= +cloud.google.com/go/resourcemanager v1.9.2/go.mod h1:OujkBg1UZg5lX2yIyMo5Vz9O5hf7XQOSV7WxqxxMtQE= +cloud.google.com/go/resourcemanager v1.9.3/go.mod h1:IqrY+g0ZgLsihcfcmqSe+RKp1hzjXwG904B92AwBz6U= +cloud.google.com/go/resourcemanager v1.9.4/go.mod h1:N1dhP9RFvo3lUfwtfLWVxfUWq8+KUQ+XLlHLH3BoFJ0= +cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= +cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= +cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= +cloud.google.com/go/resourcesettings v1.6.1/go.mod h1:M7mk9PIZrC5Fgsu1kZJci6mpgN8o0IUzVx3eJU3y4Jw= +cloud.google.com/go/resourcesettings v1.6.2/go.mod h1:mJIEDd9MobzunWMeniaMp6tzg4I2GvD3TTmPkc8vBXk= +cloud.google.com/go/resourcesettings v1.6.3/go.mod h1:pno5D+7oDYkMWZ5BpPsb4SO0ewg3IXcmmrUZaMJrFic= +cloud.google.com/go/resourcesettings v1.6.4/go.mod h1:pYTTkWdv2lmQcjsthbZLNBP4QW140cs7wqA3DuqErVI= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= +cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= +cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= +cloud.google.com/go/retail v1.14.1/go.mod h1:y3Wv3Vr2k54dLNIrCzenyKG8g8dhvhncT2NcNjb/6gE= +cloud.google.com/go/retail v1.14.2/go.mod h1:W7rrNRChAEChX336QF7bnMxbsjugcOCPU44i5kbLiL8= +cloud.google.com/go/retail v1.14.3/go.mod h1:Omz2akDHeSlfCq8ArPKiBxlnRpKEBjUH386JYFLUvXo= +cloud.google.com/go/retail v1.14.4/go.mod h1:l/N7cMtY78yRnJqp5JW8emy7MB1nz8E4t2yfOmklYfg= +cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= +cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= +cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= +cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= +cloud.google.com/go/run v1.2.0/go.mod h1:36V1IlDzQ0XxbQjUx6IYbw8H3TJnWvhii963WW3B/bo= +cloud.google.com/go/run v1.3.0/go.mod h1:S/osX/4jIPZGg+ssuqh6GNgg7syixKe3YnprwehzHKU= +cloud.google.com/go/run v1.3.1/go.mod h1:cymddtZOzdwLIAsmS6s+Asl4JoXIDm/K1cpZTxV4Q5s= +cloud.google.com/go/run v1.3.2/go.mod h1:SIhmqArbjdU/D9M6JoHaAqnAMKLFtXaVdNeq04NjnVE= +cloud.google.com/go/run v1.3.3/go.mod h1:WSM5pGyJ7cfYyYbONVQBN4buz42zFqwG67Q3ch07iK4= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= +cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= +cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= +cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= +cloud.google.com/go/scheduler v1.10.1/go.mod h1:R63Ldltd47Bs4gnhQkmNDse5w8gBRrhObZ54PxgR2Oo= +cloud.google.com/go/scheduler v1.10.2/go.mod h1:O3jX6HRH5eKCA3FutMw375XHZJudNIKVonSCHv7ropY= +cloud.google.com/go/scheduler v1.10.3/go.mod h1:8ANskEM33+sIbpJ+R4xRfw/jzOG+ZFE8WVLy7/yGvbc= +cloud.google.com/go/scheduler v1.10.4/go.mod h1:MTuXcrJC9tqOHhixdbHDFSIuh7xZF2IysiINDuiq6NI= +cloud.google.com/go/scheduler v1.10.5/go.mod h1:MTuXcrJC9tqOHhixdbHDFSIuh7xZF2IysiINDuiq6NI= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= +cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= +cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= +cloud.google.com/go/secretmanager v1.11.1/go.mod h1:znq9JlXgTNdBeQk9TBW/FnR/W4uChEKGeqQWAJ8SXFw= +cloud.google.com/go/secretmanager v1.11.2/go.mod h1:MQm4t3deoSub7+WNwiC4/tRYgDBHJgJPvswqQVB1Vss= +cloud.google.com/go/secretmanager v1.11.3/go.mod h1:0bA2o6FabmShrEy328i67aV+65XoUFFSmVeLBn/51jI= +cloud.google.com/go/secretmanager v1.11.4/go.mod h1:wreJlbS9Zdq21lMzWmJ0XhWW2ZxgPeahsqeV/vZoJ3w= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= +cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= +cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= +cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= +cloud.google.com/go/security v1.15.1/go.mod h1:MvTnnbsWnehoizHi09zoiZob0iCHVcL4AUBj76h9fXA= +cloud.google.com/go/security v1.15.2/go.mod h1:2GVE/v1oixIRHDaClVbHuPcZwAqFM28mXuAKCfMgYIg= +cloud.google.com/go/security v1.15.3/go.mod h1:gQ/7Q2JYUZZgOzqKtw9McShH+MjNvtDpL40J1cT+vBs= +cloud.google.com/go/security v1.15.4/go.mod h1:oN7C2uIZKhxCLiAAijKUCuHLZbIt/ghYEo8MqwD/Ty4= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= +cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= +cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= +cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= +cloud.google.com/go/securitycenter v1.23.0/go.mod h1:8pwQ4n+Y9WCWM278R8W3nF65QtY172h4S8aXyI9/hsQ= +cloud.google.com/go/securitycenter v1.23.1/go.mod h1:w2HV3Mv/yKhbXKwOCu2i8bCuLtNP1IMHuiYQn4HJq5s= +cloud.google.com/go/securitycenter v1.24.1/go.mod h1:3h9IdjjHhVMXdQnmqzVnM7b0wMn/1O/U20eWVpMpZjI= +cloud.google.com/go/securitycenter v1.24.2/go.mod h1:l1XejOngggzqwr4Fa2Cn+iWZGf+aBLTXtB/vXjy5vXM= +cloud.google.com/go/securitycenter v1.24.3/go.mod h1:l1XejOngggzqwr4Fa2Cn+iWZGf+aBLTXtB/vXjy5vXM= +cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= +cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= +cloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA= +cloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc= +cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= +cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= +cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= +cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= +cloud.google.com/go/servicedirectory v1.10.1/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ= +cloud.google.com/go/servicedirectory v1.11.0/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ= +cloud.google.com/go/servicedirectory v1.11.1/go.mod h1:tJywXimEWzNzw9FvtNjsQxxJ3/41jseeILgwU/QLrGI= +cloud.google.com/go/servicedirectory v1.11.2/go.mod h1:KD9hCLhncWRV5jJphwIpugKwM5bn1x0GyVVD4NO8mGg= +cloud.google.com/go/servicedirectory v1.11.3/go.mod h1:LV+cHkomRLr67YoQy3Xq2tUXBGOs5z5bPofdq7qtiAw= +cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= +cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= +cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= +cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4= +cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= +cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= +cloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec= +cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA= +cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= +cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= +cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= +cloud.google.com/go/shell v1.7.1/go.mod h1:u1RaM+huXFaTojTbW4g9P5emOrrmLE69KrxqQahKn4g= +cloud.google.com/go/shell v1.7.2/go.mod h1:KqRPKwBV0UyLickMn0+BY1qIyE98kKyI216sH/TuHmc= +cloud.google.com/go/shell v1.7.3/go.mod h1:cTTEz/JdaBsQAeTQ3B6HHldZudFoYBOqjteev07FbIc= +cloud.google.com/go/shell v1.7.4/go.mod h1:yLeXB8eKLxw0dpEmXQ/FjriYrBijNsONpwnWsdPqlKM= +cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= +cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk= +cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= +cloud.google.com/go/spanner v1.47.0/go.mod h1:IXsJwVW2j4UKs0eYDqodab6HgGuA1bViSqW4uH9lfUI= +cloud.google.com/go/spanner v1.49.0/go.mod h1:eGj9mQGK8+hkgSVbHNQ06pQ4oS+cyc4tXXd6Dif1KoM= +cloud.google.com/go/spanner v1.50.0/go.mod h1:eGj9mQGK8+hkgSVbHNQ06pQ4oS+cyc4tXXd6Dif1KoM= +cloud.google.com/go/spanner v1.51.0/go.mod h1:c5KNo5LQ1X5tJwma9rSQZsXNBDNvj4/n8BVc3LNahq0= +cloud.google.com/go/spanner v1.53.0/go.mod h1:liG4iCeLqm5L3fFLU5whFITqP0e0orsAW1uUSrd4rws= +cloud.google.com/go/spanner v1.53.1/go.mod h1:liG4iCeLqm5L3fFLU5whFITqP0e0orsAW1uUSrd4rws= +cloud.google.com/go/spanner v1.54.0/go.mod h1:wZvSQVBgngF0Gq86fKup6KIYmN2be7uOKjtK97X+bQU= +cloud.google.com/go/spanner v1.55.0/go.mod h1:HXEznMUVhC+PC+HDyo9YFG2Ajj5BQDkcbqB9Z2Ffxi0= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= +cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= +cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= +cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= +cloud.google.com/go/speech v1.17.1/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo= +cloud.google.com/go/speech v1.19.0/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo= +cloud.google.com/go/speech v1.19.1/go.mod h1:WcuaWz/3hOlzPFOVo9DUsblMIHwxP589y6ZMtaG+iAA= +cloud.google.com/go/speech v1.19.2/go.mod h1:2OYFfj+Ch5LWjsaSINuCZsre/789zlcCI3SY4oAi2oI= +cloud.google.com/go/speech v1.20.1/go.mod h1:wwolycgONvfz2EDU8rKuHRW3+wc9ILPsAWoikBEWavY= +cloud.google.com/go/speech v1.21.0/go.mod h1:wwolycgONvfz2EDU8rKuHRW3+wc9ILPsAWoikBEWavY= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= -cosmossdk.io/api v0.2.6 h1:AoNwaLLapcLsphhMK6+o0kZl+D6MMUaHVqSdwinASGU= -cosmossdk.io/api v0.2.6/go.mod h1:u/d+GAxil0nWpl1XnQL8nkziQDIWuBDhv8VnDm/s6dI= -cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= -cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= -cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= -cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= +cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= +cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= +cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= +cloud.google.com/go/storage v1.50.0 h1:3TbVkzTooBvnZsk7WaAQfOsNrdoM8QHusXA1cpk6QJs= +cloud.google.com/go/storage v1.50.0/go.mod h1:l7XeiD//vx5lfqE3RavfmU9yvk5Pp0Zhcv482poyafY= +cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= +cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= +cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= +cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= +cloud.google.com/go/storagetransfer v1.10.0/go.mod h1:DM4sTlSmGiNczmV6iZyceIh2dbs+7z2Ayg6YAiQlYfA= +cloud.google.com/go/storagetransfer v1.10.1/go.mod h1:rS7Sy0BtPviWYTTJVWCSV4QrbBitgPeuK4/FKa4IdLs= +cloud.google.com/go/storagetransfer v1.10.2/go.mod h1:meIhYQup5rg9juQJdyppnA/WLQCOguxtk1pr3/vBWzA= +cloud.google.com/go/storagetransfer v1.10.3/go.mod h1:Up8LY2p6X68SZ+WToswpQbQHnJpOty/ACcMafuey8gc= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= +cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= +cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= +cloud.google.com/go/talent v1.6.2/go.mod h1:CbGvmKCG61mkdjcqTcLOkb2ZN1SrQI8MDyma2l7VD24= +cloud.google.com/go/talent v1.6.3/go.mod h1:xoDO97Qd4AK43rGjJvyBHMskiEf3KulgYzcH6YWOVoo= +cloud.google.com/go/talent v1.6.4/go.mod h1:QsWvi5eKeh6gG2DlBkpMaFYZYrYUnIpo34f6/V5QykY= +cloud.google.com/go/talent v1.6.5/go.mod h1:Mf5cma696HmE+P2BWJ/ZwYqeJXEeU0UqjHFXVLadEDI= +cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= +cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= +cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= +cloud.google.com/go/texttospeech v1.7.1/go.mod h1:m7QfG5IXxeneGqTapXNxv2ItxP/FS0hCZBwXYqucgSk= +cloud.google.com/go/texttospeech v1.7.2/go.mod h1:VYPT6aTOEl3herQjFHYErTlSZJ4vB00Q2ZTmuVgluD4= +cloud.google.com/go/texttospeech v1.7.3/go.mod h1:Av/zpkcgWfXlDLRYob17lqMstGZ3GqlvJXqKMp2u8so= +cloud.google.com/go/texttospeech v1.7.4/go.mod h1:vgv0002WvR4liGuSd5BJbWy4nDn5Ozco0uJymY5+U74= +cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= +cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= +cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= +cloud.google.com/go/tpu v1.6.1/go.mod h1:sOdcHVIgDEEOKuqUoi6Fq53MKHJAtOwtz0GuKsWSH3E= +cloud.google.com/go/tpu v1.6.2/go.mod h1:NXh3NDwt71TsPZdtGWgAG5ThDfGd32X1mJ2cMaRlVgU= +cloud.google.com/go/tpu v1.6.3/go.mod h1:lxiueqfVMlSToZY1151IaZqp89ELPSrk+3HIQ5HRkbY= +cloud.google.com/go/tpu v1.6.4/go.mod h1:NAm9q3Rq2wIlGnOhpYICNI7+bpBebMJbh0yyp3aNw1Y= +cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= +cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= +cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= +cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= +cloud.google.com/go/trace v1.10.1/go.mod h1:gbtL94KE5AJLH3y+WVpfWILmqgc6dXcqgNXdOPAQTYk= +cloud.google.com/go/trace v1.10.2/go.mod h1:NPXemMi6MToRFcSxRl2uDnu/qAlAQ3oULUphcHGh1vA= +cloud.google.com/go/trace v1.10.3/go.mod h1:Ke1bgfc73RV3wUFml+uQp7EsDw4dGaETLxB7Iq/r4CY= +cloud.google.com/go/trace v1.10.4/go.mod h1:Nso99EDIK8Mj5/zmB+iGr9dosS/bzWCJ8wGmE6TXNWY= +cloud.google.com/go/trace v1.11.6 h1:2O2zjPzqPYAHrn3OKl029qlqG6W8ZdYaOWRyr8NgMT4= +cloud.google.com/go/trace v1.11.6/go.mod h1:GA855OeDEBiBMzcckLPE2kDunIpC72N+Pq8WFieFjnI= +cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= +cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= +cloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0= +cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/translate v1.8.1/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= +cloud.google.com/go/translate v1.8.2/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= +cloud.google.com/go/translate v1.9.0/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= +cloud.google.com/go/translate v1.9.1/go.mod h1:TWIgDZknq2+JD4iRcojgeDtqGEp154HN/uL6hMvylS8= +cloud.google.com/go/translate v1.9.2/go.mod h1:E3Tc6rUTsQkVrXW6avbUhKJSr7ZE3j7zNmqzXKHqRrY= +cloud.google.com/go/translate v1.9.3/go.mod h1:Kbq9RggWsbqZ9W5YpM94Q1Xv4dshw/gr/SHfsl5yCZ0= +cloud.google.com/go/translate v1.10.0/go.mod h1:Kbq9RggWsbqZ9W5YpM94Q1Xv4dshw/gr/SHfsl5yCZ0= +cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= +cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= +cloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg= +cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= +cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/video v1.17.1/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU= +cloud.google.com/go/video v1.19.0/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU= +cloud.google.com/go/video v1.20.0/go.mod h1:U3G3FTnsvAGqglq9LxgqzOiBc/Nt8zis8S+850N2DUM= +cloud.google.com/go/video v1.20.1/go.mod h1:3gJS+iDprnj8SY6pe0SwLeC5BUW80NjhwX7INWEuWGU= +cloud.google.com/go/video v1.20.2/go.mod h1:lrixr5JeKNThsgfM9gqtwb6Okuqzfo4VrY2xynaViTA= +cloud.google.com/go/video v1.20.3/go.mod h1:TnH/mNZKVHeNtpamsSPygSR0iHtvrR/cW1/GDjN5+GU= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= +cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= +cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= +cloud.google.com/go/videointelligence v1.11.1/go.mod h1:76xn/8InyQHarjTWsBR058SmlPCwQjgcvoW0aZykOvo= +cloud.google.com/go/videointelligence v1.11.2/go.mod h1:ocfIGYtIVmIcWk1DsSGOoDiXca4vaZQII1C85qtoplc= +cloud.google.com/go/videointelligence v1.11.3/go.mod h1:tf0NUaGTjU1iS2KEkGWvO5hRHeCkFK3nPo0/cOZhZAo= +cloud.google.com/go/videointelligence v1.11.4/go.mod h1:kPBMAYsTPFiQxMLmmjpcZUMklJp3nC9+ipJJtprccD8= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= +cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= +cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= +cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= +cloud.google.com/go/vision/v2 v2.7.2/go.mod h1:jKa8oSYBWhYiXarHPvP4USxYANYUEdEsQrloLjrSwJU= +cloud.google.com/go/vision/v2 v2.7.3/go.mod h1:V0IcLCY7W+hpMKXK1JYE0LV5llEqVmj+UJChjvA1WsM= +cloud.google.com/go/vision/v2 v2.7.4/go.mod h1:ynDKnsDN/0RtqkKxQZ2iatv3Dm9O+HfRb5djl7l4Vvw= +cloud.google.com/go/vision/v2 v2.7.5/go.mod h1:GcviprJLFfK9OLf0z8Gm6lQb6ZFUulvpZws+mm6yPLM= +cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= +cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= +cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= +cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= +cloud.google.com/go/vmmigration v1.7.1/go.mod h1:WD+5z7a/IpZ5bKK//YmT9E047AD+rjycCAvyMxGJbro= +cloud.google.com/go/vmmigration v1.7.2/go.mod h1:iA2hVj22sm2LLYXGPT1pB63mXHhrH1m/ruux9TwWLd8= +cloud.google.com/go/vmmigration v1.7.3/go.mod h1:ZCQC7cENwmSWlwyTrZcWivchn78YnFniEQYRWQ65tBo= +cloud.google.com/go/vmmigration v1.7.4/go.mod h1:yBXCmiLaB99hEl/G9ZooNx2GyzgsjKnw5fWcINRgD70= +cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= +cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= +cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= +cloud.google.com/go/vmwareengine v0.4.1/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0= +cloud.google.com/go/vmwareengine v1.0.0/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0= +cloud.google.com/go/vmwareengine v1.0.1/go.mod h1:aT3Xsm5sNx0QShk1Jc1B8OddrxAScYLwzVoaiXfdzzk= +cloud.google.com/go/vmwareengine v1.0.2/go.mod h1:xMSNjIk8/itYrz1JA8nV3Ajg4L4n3N+ugP8JKzk3OaA= +cloud.google.com/go/vmwareengine v1.0.3/go.mod h1:QSpdZ1stlbfKtyt6Iu19M6XRxjmXO+vb5a/R6Fvy2y4= +cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= +cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= +cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= +cloud.google.com/go/vpcaccess v1.7.1/go.mod h1:FogoD46/ZU+JUBX9D606X21EnxiszYi2tArQwLY4SXs= +cloud.google.com/go/vpcaccess v1.7.2/go.mod h1:mmg/MnRHv+3e8FJUjeSibVFvQF1cCy2MsFaFqxeY1HU= +cloud.google.com/go/vpcaccess v1.7.3/go.mod h1:YX4skyfW3NC8vI3Fk+EegJnlYFatA+dXK4o236EUCUc= +cloud.google.com/go/vpcaccess v1.7.4/go.mod h1:lA0KTvhtEOb/VOdnH/gwPuOzGgM+CWsmGu6bb4IoMKk= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= +cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= +cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= +cloud.google.com/go/webrisk v1.9.1/go.mod h1:4GCmXKcOa2BZcZPn6DCEvE7HypmEJcJkr4mtM+sqYPc= +cloud.google.com/go/webrisk v1.9.2/go.mod h1:pY9kfDgAqxUpDBOrG4w8deLfhvJmejKB0qd/5uQIPBc= +cloud.google.com/go/webrisk v1.9.3/go.mod h1:RUYXe9X/wBDXhVilss7EDLW9ZNa06aowPuinUOPCXH8= +cloud.google.com/go/webrisk v1.9.4/go.mod h1:w7m4Ib4C+OseSr2GL66m0zMBywdrVNTDKsdEsfMl7X0= +cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= +cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= +cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= +cloud.google.com/go/websecurityscanner v1.6.1/go.mod h1:Njgaw3rttgRHXzwCB8kgCYqv5/rGpFCsBOvPbYgszpg= +cloud.google.com/go/websecurityscanner v1.6.2/go.mod h1:7YgjuU5tun7Eg2kpKgGnDuEOXWIrh8x8lWrJT4zfmas= +cloud.google.com/go/websecurityscanner v1.6.3/go.mod h1:x9XANObUFR+83Cya3g/B9M/yoHVqzxPnFtgF8yYGAXw= +cloud.google.com/go/websecurityscanner v1.6.4/go.mod h1:mUiyMQ+dGpPPRkHgknIZeCzSHJ45+fY4F52nZFDHm2o= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= +cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= +cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= +cloud.google.com/go/workflows v1.11.1/go.mod h1:Z+t10G1wF7h8LgdY/EmRcQY8ptBD/nvofaL6FqlET6g= +cloud.google.com/go/workflows v1.12.0/go.mod h1:PYhSk2b6DhZ508tj8HXKaBh+OFe+xdl0dHF/tJdzPQM= +cloud.google.com/go/workflows v1.12.1/go.mod h1:5A95OhD/edtOhQd/O741NSfIMezNTbCwLM1P1tBRGHM= +cloud.google.com/go/workflows v1.12.2/go.mod h1:+OmBIgNqYJPVggnMo9nqmizW0qEXHhmnAzK/CnBqsHc= +cloud.google.com/go/workflows v1.12.3/go.mod h1:fmOUeeqEwPzIU81foMjTRQIdwQHADi/vEr1cx9R1m5g= +cosmossdk.io/api v0.9.2 h1:9i9ptOBdmoIEVEVWLtYYHjxZonlF/aOVODLFaxpmNtg= +cosmossdk.io/api v0.9.2/go.mod h1:CWt31nVohvoPMTlPv+mMNCtC0a7BqRdESjCsstHcTkU= +cosmossdk.io/collections v1.2.1 h1:mAlNMs5vJwkda4TA+k5q/43p24RVAQ/qyDrjANu3BXE= +cosmossdk.io/collections v1.2.1/go.mod h1:PSsEJ/fqny0VPsHLFT6gXDj/2C1tBOTS9eByK0+PBFU= +cosmossdk.io/core v0.11.3 h1:mei+MVDJOwIjIniaKelE3jPDqShCc/F4LkNNHh+4yfo= +cosmossdk.io/core v0.11.3/go.mod h1:9rL4RE1uDt5AJ4Tg55sYyHWXA16VmpHgbe0PbJc6N2Y= +cosmossdk.io/depinject v1.2.1 h1:eD6FxkIjlVaNZT+dXTQuwQTKZrFZ4UrfCq1RKgzyhMw= +cosmossdk.io/depinject v1.2.1/go.mod h1:lqQEycz0H2JXqvOgVwTsjEdMI0plswI7p6KX+MVqFOM= +cosmossdk.io/errors v1.0.2 h1:wcYiJz08HThbWxd/L4jObeLaLySopyyuUFB5w4AGpCo= +cosmossdk.io/errors v1.0.2/go.mod h1:0rjgiHkftRYPj//3DrD6y8hcm40HcPv/dR4R/4efr0k= +cosmossdk.io/log v1.6.0 h1:SJIOmJ059wi1piyRgNRXKXhlDXGqnB5eQwhcZKv2tOk= +cosmossdk.io/log v1.6.0/go.mod h1:5cXXBvfBkR2/BcXmosdCSLXllvgSjphrrDVdfVRmBGM= +cosmossdk.io/math v1.5.3 h1:WH6tu6Z3AUCeHbeOSHg2mt9rnoiUWVWaQ2t6Gkll96U= +cosmossdk.io/math v1.5.3/go.mod h1:uqcZv7vexnhMFJF+6zh9EWdm/+Ylyln34IvPnBauPCQ= +cosmossdk.io/schema v1.1.0 h1:mmpuz3dzouCoyjjcMcA/xHBEmMChN+EHh8EHxHRHhzE= +cosmossdk.io/schema v1.1.0/go.mod h1:Gb7pqO+tpR+jLW5qDcNOSv0KtppYs7881kfzakguhhI= +cosmossdk.io/store v1.1.2 h1:3HOZG8+CuThREKv6cn3WSohAc6yccxO3hLzwK6rBC7o= +cosmossdk.io/store v1.1.2/go.mod h1:60rAGzTHevGm592kFhiUVkNC9w7gooSEn5iUBPzHQ6A= +cosmossdk.io/x/evidence v0.2.0 h1:o72zbmgCM7U0v7z7b0XnMB+NqX0tFamqb1HHkQbhrZ0= +cosmossdk.io/x/evidence v0.2.0/go.mod h1:zx/Xqy+hnGVzkqVuVuvmP9KsO6YCl4SfbAetYi+k+sE= +cosmossdk.io/x/feegrant v0.2.0 h1:oq3WVpoJdxko/XgWmpib63V1mYy9ZQN/1qxDajwGzJ8= +cosmossdk.io/x/feegrant v0.2.0/go.mod h1:9CutZbmhulk/Yo6tQSVD5LG8Lk40ZAQ1OX4d1CODWAE= +cosmossdk.io/x/nft v0.2.0 h1:cd8QGeThxtvspOYGu0WJX0ioI9YnUG4qNwo3/Ac03GM= +cosmossdk.io/x/nft v0.2.0/go.mod h1:KsJBxkrPvcNRNLQYzlj7MHiJjSMw7MwU7p8/P9EyDwo= +cosmossdk.io/x/tx v0.14.0 h1:hB3O25kIcyDW/7kMTLMaO8Ripj3yqs5imceVd6c/heA= +cosmossdk.io/x/tx v0.14.0/go.mod h1:Tn30rSRA1PRfdGB3Yz55W4Sn6EIutr9xtMKSHij+9PM= +cosmossdk.io/x/upgrade v0.2.0 h1:ZHy0xny3wBCSLomyhE06+UmQHWO8cYlVYjfFAJxjz5g= +cosmossdk.io/x/upgrade v0.2.0/go.mod h1:DXDtkvi//TrFyHWSOaeCZGBoiGAE6Rs8/0ABt2pcDD0= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3/go.mod h1:wMEGFFFNuPos7vHmWXfszqImLppbc0wEhh6JBfJIUgw= -git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9/go.mod h1:BVJwbDfVjCjoFiKrhkei6NdGcZYpkDkdyCdg1ukytRA= +gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= +git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -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-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= 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= -github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= -github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/DataDog/zstd v1.5.0 h1:+K/VEwIAaPcHiMtQvpLD4lqW7f0Gk3xdYZmI1hD+CXo= -github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= -github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= +github.com/DataDog/datadog-go v4.8.3+incompatible h1:fNGaYSuObuQb5nzeTQqowRAd9bpDIRRV4/gUtIBjh8Q= +github.com/DataDog/datadog-go v4.8.3+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= +github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 h1:ErKg/3iS1AKcTkf3yixlZ54f9U1rljCkQyEXWUnIUxc= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0 h1:5IT7xOdq17MtcdtL/vtl6mGfzhaq4m4vpollPRmlsBQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0/go.mod h1:ZV4VOm0/eHR06JLrXWe09068dHpr3TRpY9Uo7T+anuA= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.50.0 h1:nNMpRpnkWDAaqcpxMJvxa/Ud98gjbYwayJY4/9bdjiU= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.50.0/go.mod h1:SZiPHWGOOk3bl8tkevxkoiwPgsIl6CwrWcbwjfHZpdM= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= +github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= -github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig= -github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= -github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= -github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= -github.com/adlio/schema v1.3.3/go.mod h1:1EsRssiv9/Ce2CMzq5DoL7RiMshhuigQxrR4DMV9fHg= -github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/adlio/schema v1.3.6 h1:k1/zc2jNfeiZBA5aFTRy37jlBIuCkXCm0XmvpzCKI9I= +github.com/adlio/schema v1.3.6/go.mod h1:qkxwLgPBd1FgLRHYVCmQT/rrBr3JH38J9LjmVzWNudg= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= +github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= -github.com/akash-network/akash-api v0.0.83 h1:Vz1Nuwstf2bwoQwb+75lJA2wrgoowB/H38gmAE2eiP4= -github.com/akash-network/akash-api v0.0.83/go.mod h1:Y9Bq4S3c/MMjvWj/3KuEYmDfv3leo9OeGGxo7xL0pVc= -github.com/akash-network/cometbft v0.34.27-akash.5 h1:Xhj+lCkN5XhN04sMuhfA0wUN9iWFSehynIwNjFYNVxE= -github.com/akash-network/cometbft v0.34.27-akash.5/go.mod h1:BcCbhKv7ieM0KEddnYXvQZR+pZykTKReJJYf7YC7qhw= -github.com/akash-network/cosmos-sdk v0.45.16-akash.7 h1:tCF8WqBhgYuyqhtT6hNvlcIBX96qQysy8xBf4Kjumhs= -github.com/akash-network/cosmos-sdk v0.45.16-akash.7/go.mod h1:ck9WeD1dcIu6xwHjWM4OyeKgCHChTjox2xWgHoPJhm4= -github.com/akash-network/ledger-go v0.15.1 h1:MzN/EQO+epoCKHMfrxLtAKVU3kA86hAn5Fu5aVmE69E= -github.com/akash-network/ledger-go v0.15.1/go.mod h1:bl91msJLjUsMSCkljd1TbVl2R4jb2URjeocLHiFSA4c= -github.com/akash-network/ledger-go/cosmos v0.15.0 h1:xDamTeFQcn10bzHna+8LP1xjiiYQLDS0CLXOvOPH/lI= -github.com/akash-network/ledger-go/cosmos v0.15.0/go.mod h1:Fm1bi8WlpOfocJ0TstqKNNkukUwlpsCI6j8gSgfILBU= -github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= -github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= +github.com/akash-network/cometbft v0.38.19-akash.1 h1:am45M/0vjs1FEwh1WiLv/cp92Yskj2Dls997phjnxso= +github.com/akash-network/cometbft v0.38.19-akash.1/go.mod h1:UCu8dlHqvkAsmAFmWDRWNZJPlu6ya2fTWZlDrWsivwo= +github.com/akash-network/cosmos-sdk v0.53.4-akash.7 h1:Z/hD79JXHigTPsIDzTtcQl3hGYiPqy45pqKBVOqH9nI= +github.com/akash-network/cosmos-sdk v0.53.4-akash.7/go.mod h1:IZwPUVJ6FYETzU2GIZdYzCqi9IcXT6idNx6QcrtuG3M= +github.com/akash-network/gogoproto v1.7.0-akash.2 h1:zY5seM6kBOLMBWn15t8vrY1ao4J1HjrhNaEeO/Soro0= +github.com/akash-network/gogoproto v1.7.0-akash.2/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= +github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= +github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= +github.com/apache/arrow/go/v12 v12.0.0/go.mod h1:d+tV/eHZZ7Dz7RPrFKtPK02tpr+c9/PEd/zm8mDS9Vg= +github.com/apache/arrow/go/v12 v12.0.1/go.mod h1:weuTY7JvTG/HDPtMQxEUp7pU73vkLWMLpY67QwZ/WWw= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.49.0 h1:g9BkW1fo9GqKfwg2+zCD+TW/D36Ux+vtfJ8guF4AYmY= +github.com/aws/aws-sdk-go v1.49.0/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= -github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= -github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= -github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= -github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= -github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= -github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= -github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bgentry/speakeasy v0.2.0 h1:tgObeVOf8WAvtuAX6DhJ4xks4CFNwPDZiqzGqIHE51E= +github.com/bgentry/speakeasy v0.2.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bits-and-blooms/bitset v1.22.0 h1:Tquv9S8+SGaS3EhyA+up3FXzmkhxPGjQQCkcs2uw7w4= +github.com/bits-and-blooms/bitset v1.22.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boz/go-lifecycle v0.1.1 h1:tG/wff7Zxbkf19g4D4I0G8Y4sq83iT5QjD4rzEf/zrI= github.com/boz/go-lifecycle v0.1.1/go.mod h1:zdagAUMcC2C0OmQkBlJZFV77uF4GCVaGphAexGi7oho= -github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= -github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.21.0-beta.0.20201114000516-e9c7a5ac6401/go.mod h1:Sv4JPQ3/M+teHz9Bo5jBpkNcP0x6r7rdihlNL/7tTAs= -github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= -github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= -github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= -github.com/btcsuite/btcd/btcutil v1.1.2/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= -github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= -github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= -github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/AYFd6c= +github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= +github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= +github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= +github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= +github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= +github.com/bytedance/sonic v1.14.1 h1:FBMC0zVz5XUmE4z9wF4Jey0An5FueFvOsTKKKtwIl7w= +github.com/bytedance/sonic v1.14.1/go.mod h1:gi6uhQLMbTdeP0muCnrjHLeCUPyb70ujhnNlhOylAFc= +github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= +github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= +github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= +github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= +github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= -github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= +github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= -github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230428030218-4003588d1b74/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= +github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= -github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= -github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= -github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= -github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= -github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v0.0.0-20220817183557-09c6e030a677 h1:qbb/AE938DFhOajUYh9+OXELpSF9KZw2ZivtmW6eX1Q= -github.com/cockroachdb/pebble v0.0.0-20220817183557-09c6e030a677/go.mod h1:890yq1fUb9b6dGNwssgeUO5vQV9qfXnCPxAJhBQfXw0= -github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.12.0 h1:d7oCs6vuIMUQRVbi6jWWWEJZahLCfJpnJSVobd1/sUo= +github.com/cockroachdb/errors v1.12.0/go.mod h1:SvzfYNNBshAVbZ8wzNc/UPK3w1vf0dKDUP41ucAIf7g= +github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 h1:pU88SPhIFid6/k0egdR5V6eALQYq2qbSmukrkgIh/0A= +github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 h1:ASDL+UJcILMqgNeV5jiqR4j+sTuvQNHdf2chuKj1M5k= +github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506/go.mod h1:Mw7HqKr2kdtu6aYGn3tPmAftiP3QPX63LdK/zcariIo= +github.com/cockroachdb/pebble v1.1.5 h1:5AAWCBWbat0uE0blr8qzufZP5tBjkRyy/jWe1QWLnvw= +github.com/cockroachdb/pebble v1.1.5/go.mod h1:17wO9el1YEigxkP/YtV8NtCivQDgoCyBg5c4VR/eOWo= +github.com/cockroachdb/redact v1.1.6 h1:zXJBwDZ84xJNlHl1rMyCojqyIxv+7YUpQiJLQ7n4314= +github.com/cockroachdb/redact v1.1.6/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -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-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= -github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= -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= -github.com/consensys/bavard v0.1.8-0.20210915155054-088da2f7f54a/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= -github.com/consensys/gnark-crypto v0.5.3/go.mod h1:hOdPlWQV1gDLp7faZVeg8Y0iEPFaOUnCc4XeCCk96p0= +github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= +github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= +github.com/cometbft/cometbft-db v1.0.4 h1:cezb8yx/ZWcF124wqUtAFjAuDksS1y1yXedvtprUFxs= +github.com/cometbft/cometbft-db v1.0.4/go.mod h1:M+BtHAGU2XLrpUxo3Nn1nOCcnVCiLM9yx5OuT0u5SCA= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cosmos/btcutil v1.0.4 h1:n7C2ngKXo7UC9gNyMNLbzqz7Asuf+7Qv4gnX/rOdQ44= -github.com/cosmos/btcutil v1.0.4/go.mod h1:Ffqc8Hn6TJUdDgHBwIZLtrLQC1KdJ9jGJl/TvgUaxbU= -github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 h1:zlCp9n3uwQieELltZWHRmwPmPaZ8+XoL2Sj+A2YJlr8= -github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32/go.mod h1:kwMlEC4wWvB48zAShGKVqboJL6w4zCLesaNQ3YLU2BQ= -github.com/cosmos/cosmos-proto v1.0.0-beta.1 h1:iDL5qh++NoXxG8hSy93FdYJut4XfgbShIocllGaXx/0= -github.com/cosmos/cosmos-proto v1.0.0-beta.1/go.mod h1:8k2GNZghi5sDRFw/scPL8gMSowT1vDA+5ouxL8GjaUE= -github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= +github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= +github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +github.com/cosmos/cosmos-db v1.1.1 h1:FezFSU37AlBC8S98NlSagL76oqBRWq/prTPvFcEJNCM= +github.com/cosmos/cosmos-db v1.1.1/go.mod h1:AghjcIPqdhSLP/2Z0yha5xPH3nLnskz81pBx3tcVSAw= +github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= -github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= -github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= -github.com/cosmos/iavl v0.19.5 h1:rGA3hOrgNxgRM5wYcSCxgQBap7fW82WZgY78V9po/iY= -github.com/cosmos/iavl v0.19.5/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= -github.com/cosmos/ibc-go/v4 v4.6.0 h1:G7kiD4Zf8Wrxc8BXWIKuFnzI0W4wpvRPrl5HwdfTIsA= -github.com/cosmos/ibc-go/v4 v4.6.0/go.mod h1:ksiZHUypws0NVP50E3ea0ivVFO/bfS8q8yLg8yZ2ATQ= +github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= +github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= +github.com/cosmos/iavl v1.2.2 h1:qHhKW3I70w+04g5KdsdVSHRbFLgt3yY3qTMd4Xa4rC8= +github.com/cosmos/iavl v1.2.2/go.mod h1:GiM43q0pB+uG53mLxLDzimxM9l/5N9UuSY3/D0huuVw= +github.com/cosmos/ibc-go/v10 v10.3.0 h1:w5DkHih8qn15deAeFoTk778WJU+xC1krJ5kDnicfUBc= +github.com/cosmos/ibc-go/v10 v10.3.0/go.mod h1:CthaR7n4d23PJJ7wZHegmNgbVcLXCQql7EwHrAXnMtw= +github.com/cosmos/ics23/go v0.11.0 h1:jk5skjT0TqX5e5QJbEnwXIS2yI2vnmLOgpQPeM5RtnU= +github.com/cosmos/ics23/go v0.11.0/go.mod h1:A8OjxPE67hHST4Icw94hOxxFEJMBG031xIGF/JHNIY0= github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= github.com/cosmos/keyring v1.2.0/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cosmos/ledger-cosmos-go v0.14.0 h1:WfCHricT3rPbkPSVKRH+L4fQGKYHuGOK9Edpel8TYpE= +github.com/cosmos/ledger-cosmos-go v0.14.0/go.mod h1:E07xCWSBl3mTGofZ2QnL4cIUzMbbGVyik84QYKbX3RA= +github.com/cosmos/rosetta v0.50.12 h1:Dy8B5Hc6/aH1xxuUDYAVRvI2Dx5cilPsjCwG3INp6bE= +github.com/cosmos/rosetta v0.50.12/go.mod h1:w80RJd4oW5r6t89rajdZGJbI0mucZ1CSZdi+YeSTKow= +github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= +github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= -github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= -github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg= -github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= -github.com/cucumber/common/messages/go/v17 v17.1.1/go.mod h1:bpGxb57tDE385Rb2EohgUadLkAbhoC4IyCFi89u/JQI= -github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= -github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= -github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= -github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= -github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= +github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8= github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= -github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= -github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= -github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= -github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= -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.2.0 h1:XAfl+7cmoUDWW/2Lx8TGZQjjxIQ2Ley9DSf52dru4WE= -github.com/dgraph-io/ristretto v0.2.0/go.mod h1:8uBHCU/PBV4Ag0CJrP47b9Ofby5dqWNh4FicAdoqFNU= -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= +github.com/desertbit/timer v1.0.1 h1:yRpYNn5Vaaj6QXecdLMPMJsW81JLiI1eokUft5nBmeo= +github.com/desertbit/timer v1.0.1/go.mod h1:htRrYeY5V/t4iu1xCJ5XsQvp4xve8QulXXctAzxqcwE= +github.com/dgraph-io/badger/v4 v4.6.0 h1:acOwfOOZ4p1dPRnYzvkVm7rUk2Y21TgPVepCy5dJdFQ= +github.com/dgraph-io/badger/v4 v4.6.0/go.mod h1:KSJ5VTuZNC3Sd+YhvVjk2nYua9UZnnTr/SkXvdtiPgI= +github.com/dgraph-io/ristretto/v2 v2.1.0 h1:59LjpOJLNDULHh8MC4UaegN52lC4JnO2dITsie/Pa8I= +github.com/dgraph-io/ristretto/v2 v2.1.0/go.mod h1:uejeqfYXpUomfse0+lO+13ATz4TypQYLJZzBSAemuB4= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= -github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= 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 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/dvsekhvalnov/jose2go v1.8.0 h1:LqkkVKAlHFfH9LOEl5fe4p/zL02OhWE7pCufMBG2jLA= +github.com/dvsekhvalnov/jose2go v1.8.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edwingeng/deque/v2 v2.1.1 h1:+xjC3TnaeMPLZMi7QQf9jN2K00MZmTwruApqplbL9IY= github.com/edwingeng/deque/v2 v2.1.1/go.mod h1:HukI8CQe9KDmZCcURPZRYVYjH79Zy2tIjTF9sN3Bgb0= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A= +github.com/emicklei/dot v1.6.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= +github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= +github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= +github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= +github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0= +github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= +github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA= +github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= +github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= +github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI= +github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= -github.com/ethereum/go-ethereum v1.10.17/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= +github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= +github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= +github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= +github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs= +github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= +github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= +github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= +github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/ethereum/go-ethereum v1.15.11 h1:JK73WKeu0WC0O1eyX+mdQAVHUV+UR1a9VB/domDngBU= +github.com/ethereum/go-ethereum v1.15.11/go.mod h1:mf8YiHIb0GR4x4TipcvBUPxJLw1mFdmxzoDi11sDRoI= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -335,94 +1537,84 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= -github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= -github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= -github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= -github.com/getsentry/sentry-go v0.35.0 h1:+FJNlnjJsZMG3g0/rmmP7GiKjQoUF5EXfEtBwtPtkzY= -github.com/getsentry/sentry-go v0.35.0/go.mod h1:C55omcY9ChRQIUcVcGcs+Zdy4ZpQGvNJ7JYHIoSWOtE= -github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= +github.com/getsentry/sentry-go v0.32.0 h1:YKs+//QmwE3DcYtfKRH8/KyOOF/I6Qnx7qYGNHCGmCY= +github.com/getsentry/sentry-go v0.32.0/go.mod h1:CYNcMMz73YigoHljQRG+qPF+eMq8gG72XcGN/p71BAY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= -github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= -github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= -github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= -github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= -github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= +github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= +github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= +github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= +github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= +github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= -github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= +github.com/go-kit/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU= +github.com/go-kit/kit v0.13.0/go.mod h1:phqEHMMUbyrCFCTgH48JueqrM3md2HcAZ8N3XE4FKDg= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= +github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= 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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= -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-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= +github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= -github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= -github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= -github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= -github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= -github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= 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= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk= -github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= -github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc= -github.com/gofrs/uuid v4.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0= -github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic= -github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= +github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= -github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.2.3 h1:kkGXqQOBSDDWRhWNXTFpqGSCMyh/PLnqUvMGJPDJDs0= +github.com/golang-jwt/jwt/v5 v5.2.3/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -430,6 +1622,7 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -440,104 +1633,173 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= -github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e h1:4bw4WeyTYPp0smaXiJZCNnLrvVBqirQVreixayXezGc= +github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= +github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-github/v56 v56.0.0 h1:TysL7dMa/r7wsQi44BjqlwaHvwlFlqkK8CtBWCX3gb4= -github.com/google/go-github/v56 v56.0.0/go.mod h1:D8cdcX98YWJvi7TLo7zM4/h8ZTx6u6fwGEkCdisopo0= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-github/v62 v62.0.0 h1:/6mGCaRywZz9MuHyw9gD1CwsbmBX8GWsbFkwMmHdhl4= +github.com/google/go-github/v62 v62.0.0/go.mod h1:EMxeUqGJq2xRu9DYBMwel/mr7kZrzUOfQmmpYrZn2a4= +github.com/google/go-pkcs11 v0.2.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= +github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= +github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= +github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.4/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= +github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw= +github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= +github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= -github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= +github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= -github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/goware/urlx v0.3.2 h1:gdoo4kBHlkqZNaf6XlQ12LGtQOmpKJrR04Rc3RnpJEo= +github.com/goware/urlx v0.3.2/go.mod h1:h8uwbJy68o+tQXCGZNa9D73WN8n0r9OBae5bUnLcgjw= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= -github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= -github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= -github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= -github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= -github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-getter v1.7.8 h1:mshVHx1Fto0/MydBekWan5zUipGq7jO0novchgMmSiY= +github.com/hashicorp/go-getter v1.7.8/go.mod h1:2c6CboOEb9jG6YvmC9xdD+tyAFsrUaJPedwXDGr0TM4= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-metrics v0.5.4 h1:8mmPiIJkTPPEbAiV97IxdAGNdRdaWwVap1BU6elejKY= +github.com/hashicorp/go-metrics v0.5.4/go.mod h1:CG5yz4NZ/AI/aQt9Ucm/vdBnbh7fvmv4lxZ350i+QQI= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-plugin v1.6.3 h1:xgHB+ZUSYeuJi96WtxEjzi23uh7YQpznjGh0U0UUrwg= +github.com/hashicorp/go-plugin v1.6.3/go.mod h1:MRobyh+Wc/nYy1V4KAXUiYfzxoYhs7V1mlH1Z7iY2h0= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= +github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -545,115 +1807,86 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b 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-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.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= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 h1:aSVUgRRRtOrZOC1fYmY9gV0e9z/Iu+xNVSASWjsuyGU= -github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3/go.mod h1:5PC6ZNPde8bBqU/ewGZig35+UIZtw9Ytxez8/q5ZyFE= -github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= +github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= +github.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N3iBb1Tb4rdcU= +github.com/hdevalence/ed25519consensus v0.2.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= +github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= +github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= +github.com/huandu/skiplist v1.2.1 h1:dTi93MgjwErA/8idWTzIw4Y1kZsMWx35fmI2c8Rij7w= +github.com/huandu/skiplist v1.2.1/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/huin/goupnp v1.0.3-0.20220313090229-ca81a64b4204/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= -github.com/ianlancetaylor/cgosymbolizer v0.0.0-20240326020559-581a3f7c677f h1:+GVBxNU56C6bwGEUsy2yJdXo7MwJWFAr7rhELFSNaig= -github.com/ianlancetaylor/cgosymbolizer v0.0.0-20240326020559-581a3f7c677f/go.mod h1:DvXTE/K/RtHehxU8/GtDs4vFtfw64jJ3PaCnFri8CRg= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= +github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/ianlancetaylor/cgosymbolizer v0.0.0-20250410214317-b8ecc8b6bbe6 h1:zwkqIPMmOEgI8t4aV8zmGqg+D+Zy9A1mL9t98i8h5SM= +github.com/ianlancetaylor/cgosymbolizer v0.0.0-20250410214317-b8ecc8b6bbe6/go.mod h1:DvXTE/K/RtHehxU8/GtDs4vFtfw64jJ3PaCnFri8CRg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= -github.com/improbable-eng/grpc-web v0.14.1 h1:NrN4PY71A6tAz2sKDvC5JCauENWp0ykG8Oq1H3cpFvw= -github.com/improbable-eng/grpc-web v0.14.1/go.mod h1:zEjGHa8DAlkoOXmswrNvhUGEYQA9UI7DhrGeHR1DMGU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= +github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= -github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= -github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= -github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= -github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= -github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= -github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= -github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= -github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= -github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jhump/protoreflect v1.13.1-0.20220928232736-101791cb1b4c h1:XImQJfpJLmGEEd8ll5yPVyL/aEvmgGHW4WYTyNseLOM= -github.com/jhump/protoreflect v1.13.1-0.20220928232736-101791cb1b4c/go.mod h1:JytZfP5d0r8pVNLZvai7U/MCuTWITgrI4tTg7puQFKI= +github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= +github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.1-0.20191019112844-b572e7f4cdac h1:GcJkaxD5Wy/Ucn+L0USlpbGJy9O6+7r0nBI7ftJ7Uu0= github.com/jmhodges/levigo v1.0.1-0.20191019112844-b572e7f4cdac/go.mod h1:dM7ihgFM8Do6WGIfOXWPgpJ+4bKGR/4ZkYh8HKDdFy4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= -github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= -github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -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/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= 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= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -666,77 +1899,62 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= -github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= -github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= -github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= -github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= -github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/linxGnu/grocksdb v1.7.10 h1:dz7RY7GnFUA+GJO6jodyxgkUeGMEkPp3ikt9hAcNGEw= -github.com/linxGnu/grocksdb v1.7.10/go.mod h1:0hTf+iA+GOr0jDX4CgIYyJZxqOH9XlBh6KVj8+zmF34= -github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/linxGnu/grocksdb v1.9.8 h1:vOIKv9/+HKiqJAElJIEYv3ZLcihRxyP7Suu/Mu8Dxjs= +github.com/linxGnu/grocksdb v1.9.8/go.mod h1:C3CNe9UYc9hlEM2pC82AqiGS3LRW537u9LFV4wIZuHk= +github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= +github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= +github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= +github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= -github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/mdp/qrterminal/v3 v3.2.1 h1:6+yQjiiOsSuXT5n9/m60E54vdgFsw0zhADHhHLrFet4= +github.com/mdp/qrterminal/v3 v3.2.1/go.mod h1:jOTmXvnBsMy5xqLniO0R++Jmjs2sTm9dFSuQ5kpz/SU= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= -github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= -github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= -github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= -github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= +github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= +github.com/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD6Q= +github.com/minio/highwayhash v1.0.3/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -744,9 +1962,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= -github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= -github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= @@ -755,34 +1970,30 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= -github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= -github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/neilotoole/errgroup v0.1.6/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= +github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q= +github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= -github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 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= @@ -791,14 +2002,13 @@ github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7y 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= -github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= -github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= -github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= -github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= +github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= +github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss= +github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= @@ -806,27 +2016,22 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= -github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ= -github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= -github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= -github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= -github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 h1:Dx7Ovyv/SFnMFw3fD4oEoeorXc6saIiQ23LrGLth0Gw= +github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= +github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -835,7 +2040,10 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -846,35 +2054,38 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc= -github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= +github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= -github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= -github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= +github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -882,54 +2093,42 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5X github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzywPxOvwMdxcg= github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= -github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= -github.com/regen-network/gocuke v0.6.2/go.mod h1:zYaqIHZobHyd0xOrHGPQjbhGJsuZ1oElx150u2o1xuk= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= -github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= -github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= 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.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= -github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/locafero v0.9.0 h1:GbgQGNtTrEmddYDSAH9QLRyfAHY12md+8YFTqyMTC9k= -github.com/sagikazarmark/locafero v0.9.0/go.mod h1:UBUyz37V+EdMS3hDF3QWIiVr/2dPrx49OMO0Bn0hJqk= +github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo= +github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= -github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/sasha-s/go-deadlock v0.3.5 h1:tNCOEEDG6tBqrNDOX35j/7hL5FcFViG6awUGROb2NsU= +github.com/sasha-s/go-deadlock v0.3.5/go.mod h1:bugP6EGbdGYObIlx7pUZtWqlvo8k9H6vCBBsiChJQ5U= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= -github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262 h1:unQFBIznI+VYD1/1fApl1A+9VcBk+9dcqGfnePY87LY= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262/go.mod h1:MyOHs9Po2fbM1LHej6sBUT8ozbxmMOFG+E+rx/GSGuc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -939,36 +2138,35 @@ github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJ github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA= -github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= +github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs= +github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4= github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE= github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M= +github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= -github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= +github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= +github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -976,55 +2174,33 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8= -github.com/tendermint/tm-db v0.6.7/go.mod h1:byQDzFkZV1syXr/ReXS808NxA2xvyuuVgXOJ/088L6I= -github.com/tidwall/btree v1.5.0 h1:iV0yVY/frd7r6qGBXfEYs7DH0gTDgrKTrDjS7xt/IyQ= -github.com/tidwall/btree v1.5.0/go.mod h1:LGm8L/DZjPLmeWGjv5kFrY8dL4uVhMmzmmLYmsObdKE= -github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM= -github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= -github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= -github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= +github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI= +github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/troian/hid v0.13.2 h1:O7PWZQm5YGyg0nVvknFVLVrNTPillz4ZXvxJOtoyteE= -github.com/troian/hid v0.13.2/go.mod h1:n6adloQ1876oEXZr6fFsthy4FDHxwJhh7QYQspm30Ds= -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/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/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/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= -github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= -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.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= -github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= +github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= 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= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= @@ -1034,95 +2210,141 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/zondax/golem v0.27.0 h1:IbBjGIXF3SoGOZHsILJvIM/F/ylwJzMcHAcggiqniPw= -github.com/zondax/golem v0.27.0/go.mod h1:AmorCgJPt00L8xN1VrMBe13PSifoZksnQ1Ge906bu4A= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= +github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= +github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= +github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk= +go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.step.sm/crypto v0.44.6 h1:vQg8ujce7fNXDO8EWdriSz+ZSJpYnNh22QrFtRjdyoY= -go.step.sm/crypto v0.44.6/go.mod h1:oKRO4jaf2MaCohJDN+/8ShImkvIgUKfJxxy87gqsnXs= +go.opentelemetry.io/contrib/detectors/gcp v1.36.0 h1:F7q2tNlCaHY9nMKHR6XH9/qkp8FktLnIcy6jJNyOCQw= +go.opentelemetry.io/contrib/detectors/gcp v1.36.0/go.mod h1:IbBN8uAIIx734PTonTPxAxnjc2pQTxWNkwfstZ+6H2k= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= +go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I= +go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= +go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= +go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= +go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= +go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= +go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= +go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.step.sm/crypto v0.45.1 h1:Xb8XldsbqT6pDYsg46BVPP1euASNbeNAhzrlvUP3QWo= +go.step.sm/crypto v0.45.1/go.mod h1:XtJBuMuZb11YeJpG8uP3fyBl2MerXWJ/pWQX/Au+Kt8= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko= +go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= +go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw= +golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= -golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= -golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb h1:xIApU0ow1zwMa2uL1VDNeQlNVFTWMQxZUZCMDy0Q4Us= +golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -1130,20 +2352,33 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg= -golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= -golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= +golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1153,41 +2388,116 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= +golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= +golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1196,35 +2506,43 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1232,48 +2550,123 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210909193231-528a39cd75f3/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/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-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg= +golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -1282,23 +2675,40 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1306,41 +2716,79 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= -golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= -gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= +gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= +gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1349,12 +2797,77 @@ google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEn google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= +google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= +google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= +google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= +google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= +google.golang.org/api v0.118.0/go.mod h1:76TtD3vkgmZ66zZzp72bUUklpmQmKlhh6sYtIjYK+5E= +google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= +google.golang.org/api v0.124.0/go.mod h1:xu2HQurE5gi/3t1aFCvhPD781p0a3p11sdunTJ2BlP4= +google.golang.org/api v0.125.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= +google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= +google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750= +google.golang.org/api v0.139.0/go.mod h1:CVagp6Eekz9CjGZ718Z+sloknzkDJE7Vc1Ckj9+viBk= +google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI= +google.golang.org/api v0.150.0/go.mod h1:ccy+MJ6nrYFgE3WgRx/AMXOxOmU8Q4hSa+jjibzhxcg= +google.golang.org/api v0.155.0/go.mod h1:GI5qK5f40kCpHfPn6+YzGAByIKWv8ujFnmoWm7Igduk= +google.golang.org/api v0.229.0 h1:p98ymMtqeJ5i3lIBMj5MpR9kzIIgzpHHh8vQ+vgAzx8= +google.golang.org/api v0.229.0/go.mod h1:wyDfmq5g1wYJWn29O22FDWN48P7Xcz0xz+LBpptYvB0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1362,7 +2875,6 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -1370,21 +2882,271 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= -google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a h1:tPE/Kp+x9dMSwUm/uM0JKK0IfdiJkwAbSMSeZBXXJXc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo= -google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= +google.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= +google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= +google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= +google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= +google.golang.org/genproto v0.0.0-20230629202037-9506855d4529/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= +google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y= +google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0= +google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:0ggbjUrZYpy1q+ANUS30SEoGZ53cdfwtbuG7Ptgy108= +google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= +google.golang.org/genproto v0.0.0-20230821184602-ccc8af3d0e93/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= +google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= +google.golang.org/genproto v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:CCviP9RmpZ1mxVr8MUjCnSiY09IbAXZxhLE6EhHIdPU= +google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk= +google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:EMfReVxb80Dq1hhioy0sOsY9jCE46YDgHlJ7fWVUWRE= +google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI= +google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405/go.mod h1:3WDQMjmJk36UQhjQ89emUzb1mdaHcPeeAh4SCBKznB4= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= +google.golang.org/genproto v0.0.0-20231120223509-83a465c0220f/go.mod h1:nWSwAFPb+qfNJXsoeO3Io7zf4tMSfN8EA8RlDA04GhY= +google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3/go.mod h1:5RBcpGRxr25RbDzY5w+dmaqpSEvl8Gwl1x2CICf60ic= +google.golang.org/genproto v0.0.0-20231212172506-995d672761c0/go.mod h1:l/k7rMz0vFTBPy+tFSGvXEd3z+BcoG1k7EHbqm+YBsY= +google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= +google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k= +google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= +google.golang.org/genproto v0.0.0-20250728155136-f173205681a0 h1:btBcgujH2+KIWEfz0s7Cdtt9R7hpwM4SAEXAdXf/ddw= +google.golang.org/genproto v0.0.0-20250728155136-f173205681a0/go.mod h1:Q4yZQ3kmmIyg6HsMjCGx2vQ8gzN+dntaPmFWz6Zj0fo= +google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= +google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5/go.mod h1:5DZzOUPCLYL3mNkQ0ms0F3EuUNZ7py1Bqeq6sxzI7/Q= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= +google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= +google.golang.org/genproto/googleapis/api v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:RdyHbowztCGQySiCvQPgWQWgWhGnouTdCflKoDBt32U= +google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0= +google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:SUBoKXbI1Efip18FClrQVGjWcyd0QZd8KkvdP34t7ww= +google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870= +google.golang.org/genproto/googleapis/api v0.0.0-20231030173426-d783a09b4405/go.mod h1:oT32Z4o8Zv2xPQTg0pbVaPr0MPOH6f14RgXt7zfIpwg= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= +google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f/go.mod h1:Uy9bTZJqmfrw2rIBxgGLnamc78euZULUBrLZ9XTITKI= +google.golang.org/genproto/googleapis/api v0.0.0-20231211222908-989df2bf70f3/go.mod h1:k2dtGpRrbsSyKcNPKKI5sstZkrNCZwpU/ns96JoHbGg= +google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0/go.mod h1:CAny0tYF+0/9rmDB9fahA9YLzX3+AEVl1qXbv5hhj6c= +google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0= +google.golang.org/genproto/googleapis/api v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= +google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA= +google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0 h1:0UOBWO4dC+e51ui0NFKSPbkHHiQ4TmrEfEZMLDyRmY8= +google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0/go.mod h1:8ytArBbtOy2xfht+y2fqKd5DRDJRUQhqbyEnQ4bDChs= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20230807174057-1744710a1577/go.mod h1:NjCQG/D8JandXxM57PZbAJL1DCNL6EypA0vPPwfsc7c= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405/go.mod h1:GRUCuLdzVqZte8+Dl/D4N25yLzcGqqWaYkeVOwulFqw= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20231212172506-995d672761c0/go.mod h1:guYXGPwC6jwxgWKW5Y405fKWOFNwlvUlUnzyp9i0uqo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:8mL13HKkDa+IuJ8yruA3ci0q+0vsUz4m//+ottjwS5o= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920183334-c177e329c48b/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405/go.mod h1:67X1fPuzjcrkymZzZV1vvkFeTn2Rvc6lYF9MYFGCcwE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231211222908-989df2bf70f3/go.mod h1:eJVxU6o+4G1PSczBr85xmyvSNYAKvAYgkub40YGomFM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917/go.mod h1:xtjpI3tXFPP051KaWnhvxkiubL/6dJ18vLVf7q2pTOU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0 h1:MAKi5q709QWfnkkpNQ0M12hYJ1+e8qYVDyowc4U1XZM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= +google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.60.0/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= +google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1397,31 +3159,33 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1433,41 +3197,110 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= -gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE= -k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0= -k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg= -k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8= +k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE= +k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA= +k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= +lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20= +modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0= +modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= +modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= +modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI= +modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= +modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= +modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g= +modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= +modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= +modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= +modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= +modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= +modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= +modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA= +modernc.org/libc v1.18.0/go.mod h1:vj6zehR5bfc98ipowQOM2nIDUZnVew/wNC/2tOGS+q0= +modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0= +modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI= +modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug= +modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= +modernc.org/sqlite v1.18.2/go.mod h1:kvrTLEWgxUcHa2GfHBQtanR1H9ht3hTJNtKpzH9k1u0= +modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= +modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= +modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= +modernc.org/tcl v1.13.2/go.mod h1:7CLiGIPo1M8Rv1Mitpv5akc2+8fxUd2y2UzC/MfMzy0= +modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -pgregory.net/rapid v0.5.3 h1:163N50IHFqr1phZens4FQOdPgfJscR7a562mjQqeo4M= -pgregory.net/rapid v0.5.3/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= +nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= +pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= +pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +pkg.akt.dev/go v0.1.5 h1:UdhU70YOzfJzzd1mT6dpnK7/5RWwV7N1zr1HRNmqtaw= +pkg.akt.dev/go v0.1.5/go.mod h1:67LZ0QbZMoCipadLNIR8HzMFcL4A4My7h9aMo516SGk= +pkg.akt.dev/go/cli v0.1.1 h1:P0nYpVE/mhw90ohwSoRlY0L9+rKCZj1wID+wbj9j40o= +pkg.akt.dev/go/cli v0.1.1/go.mod h1:ZLqHZcq+D/8a27WTPYhmfCm2iGbNicWV1AwOhdspJ4Y= +pkg.akt.dev/go/sdl v0.1.1 h1:3CcAqWeKouFlvUSjQMktWLDqftOjn4cBX37TRFT7BRM= +pkg.akt.dev/go/sdl v0.1.1/go.mod h1:ADsH8/kh61tWTax8nV0utelOaKWfU3qbG+OT3v9nmeY= +pkg.akt.dev/specs v0.0.1 h1:OP0zil3Fr4kcCuybFqQ8LWgSlSP2Yn7306meWpu6/S4= +pkg.akt.dev/specs v0.0.1/go.mod h1:tiFuJAqzn+lkz662lf9qaEdjdrrDr882r3YMDnWkbp4= +pkg.akt.dev/testdata v0.0.1 h1:yHfqF0Uxf7Rg7WdwSggnyBWMxACtAg5VpBUVFXU+uvM= +pkg.akt.dev/testdata v0.0.1/go.mod h1:j/GzV0/tylRpaORo5C/SwLLzRyhEUrquPDGxTa258Ew= 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/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= +rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY= +rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= -sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA= -sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= +sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= +sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/install.sh b/install.sh index 43753689de..c06bbcff61 100755 --- a/install.sh +++ b/install.sh @@ -354,11 +354,6 @@ FORMAT=zip OS=${OS:=$(uname_os)} ARCH=${ARCH:=$(uname_arch)} PREFIX="$OWNER/$REPO" - -# use in logging routines -log_prefix() { - echo "$PREFIX" -} PLATFORM="${OS}/${ARCH}" GITHUB_DOWNLOAD=https://github.com/${OWNER}/${REPO}/releases/download diff --git a/make/codegen.mk b/make/codegen.mk index 4cdc16c47a..64a1f217fa 100644 --- a/make/codegen.mk +++ b/make/codegen.mk @@ -4,3 +4,6 @@ generate: $(MOCKERY) .PHONY: codegen codegen: generate + +mocks: $(MOCKERY) + $(MOCKERY) diff --git a/make/init.mk b/make/init.mk index a72ce1ab70..52c0bf4f9c 100644 --- a/make/init.mk +++ b/make/init.mk @@ -28,18 +28,35 @@ NULL := SPACE := $(NULL) # COMMA := , -BINS := $(AKASH) +BINS := $(AKASH) -GO := GO111MODULE=$(GO111MODULE) go -GOWORK ?= on -GO_MOD ?= vendor -ifeq ($(GOWORK), on) -GO_MOD := readonly +ifeq ($(GO111MODULE),off) +else + GOMOD=readonly +endif + +ifneq ($(GOWORK),off) +# ifeq ($(shell test -e $(AKASH_ROOT)/go.work && echo -n yes),yes) +# GOWORK=${AKASH_ROOT}/go.work +# else +# GOWORK=off +# endif + + ifeq ($(GOMOD),$(filter $(GOMOD),mod "")) +$(error '-mod may only be set to readonly or vendor when in workspace mode, but it is set to ""') + endif endif -GO_BUILD := $(GO) build -mod=$(GO_MOD) -GO_TEST := $(GO) test -mod=$(GO_MOD) -GO_VET := $(GO) vet -mod=$(GO_MOD) +ifeq ($(GOMOD),vendor) + ifneq ($(wildcard ./vendor/.),) +$(error "go -mod is in vendor mode but vendor dir has not been found. consider to run go mod vendor") + endif +endif + +GO := GO111MODULE=$(GO111MODULE) go +GO_BUILD := $(GO) build -mod=$(GOMOD) +GO_TEST := $(GO) test -mod=$(GOMOD) +GO_VET := $(GO) vet -mod=$(GOMOD) GO_MOD_NAME := $(shell go list -m 2>/dev/null) ifeq ($(OS),Windows_NT) @@ -50,11 +67,11 @@ endif # ==== Build tools versions ==== # Format _VERSION -GOLANGCI_LINT_VERSION ?= v1.62.2 +GOLANGCI_LINT_VERSION ?= v2.3.0 STATIK_VERSION ?= v0.1.7 GIT_CHGLOG_VERSION ?= v0.15.1 -MOCKERY_VERSION ?= 2.42.0 -COSMOVISOR_VERSION ?= v1.5.0 +MOCKERY_VERSION ?= 3.5.0 +COSMOVISOR_VERSION ?= v1.7.1 # ==== Build tools version tracking ==== # _VERSION_FILE points to the marker file for the installed version. @@ -64,6 +81,7 @@ MOCKERY_VERSION_FILE := $(AKASH_DEVCACHE_VERSIONS)/mockery/v$(MOCKER GOLANGCI_LINT_VERSION_FILE := $(AKASH_DEVCACHE_VERSIONS)/golangci-lint/$(GOLANGCI_LINT_VERSION) STATIK_VERSION_FILE := $(AKASH_DEVCACHE_VERSIONS)/statik/$(STATIK_VERSION) COSMOVISOR_VERSION_FILE := $(AKASH_DEVCACHE_VERSIONS)/cosmovisor/$(COSMOVISOR_VERSION) +COSMOVISOR_DEBUG_VERSION_FILE := $(AKASH_DEVCACHE_VERSIONS)/cosmovisor/debug/$(COSMOVISOR_VERSION) # ==== Build tools executables ==== GIT_CHGLOG := $(AKASH_DEVCACHE_BIN)/git-chglog @@ -72,6 +90,8 @@ NPM := npm GOLANGCI_LINT := $(AKASH_DEVCACHE_BIN)/golangci-lint STATIK := $(AKASH_DEVCACHE_BIN)/statik COSMOVISOR := $(AKASH_DEVCACHE_BIN)/cosmovisor +COSMOVISOR_DEBUG := $(AKASH_RUN_BIN)/cosmovisor + RELEASE_TAG ?= $(shell git describe --tags --abbrev=0) diff --git a/make/lint.mk b/make/lint.mk index 92c83efd31..f2d46c3ead 100644 --- a/make/lint.mk +++ b/make/lint.mk @@ -6,27 +6,25 @@ SUBLINTERS = unused \ ineffassign \ unparam \ staticcheck \ - copyloopvar \ + revive \ + gosec \ + exportloopref \ prealloc # TODO: ^ gochecknoglobals -# Execute the same lint methods as configured in .github/workflows/tests.yaml -# Clear feedback from each method as it fails. -.PHONY: test-sublinters -test-sublinters: $(patsubst %, test-sublinter-%,$(SUBLINTERS)) - -.PHONY: test-lint-all -test-lint-all: $(GOLANGCI_LINT) +.PHONY: lint-go +lint-go: $(GOLANGCI_LINT) $(GOLANGCI_LINT_RUN) ./... --issues-exit-code=0 --timeout=10m -.PHONY: test-sublinter-misspell -test-sublinter-misspell: $(GOLANGCI_LINT) - $(LINT) misspell --no-config +.PHONY: lint-go-% +lint-go-%: $(GOLANGCI_LINT) + $(LINT) $* -.PHONY: test-sublinter-ineffassign -test-sublinter-ineffassign: $(GOLANGCI_LINT) - $(LINT) ineffassign --no-config +.PHONY: lint-shell +lint-shell: + docker run --rm \ + --volume ${PWD}:/shellcheck \ + --entrypoint sh \ + koalaman/shellcheck-alpine:stable \ + -x /shellcheck/script/shellcheck.sh -.PHONY: test-sublinter-% -test-sublinter-%: $(GOLANGCI_LINT) - $(LINT) $* diff --git a/make/mod.mk b/make/mod.mk index 89fa0c2e87..4eb475daa3 100644 --- a/make/mod.mk +++ b/make/mod.mk @@ -7,3 +7,9 @@ deps-install: .PHONY: deps-tidy deps-tidy: go mod tidy + +#.PHONY: mod +#mod: go.mod +# +#go.mod: +# go mod tidy diff --git a/make/releasing.mk b/make/releasing.mk index 3728b6903a..7a5f8c31c2 100644 --- a/make/releasing.mk +++ b/make/releasing.mk @@ -5,12 +5,18 @@ GORELEASER_IMAGE := ghcr.io/goreleaser/goreleaser-cross:$(GOTOOLCHAIN_SE GORELEASER_RELEASE ?= false GORELEASER_MOUNT_CONFIG ?= false GORELEASER_SKIP := $(subst $(COMMA),$(SPACE),$(GORELEASER_SKIP)) - +RELEASE_DOCKER_IMAGE ?= ghcr.io/akash-network/node #GORELEASER_MOD_MOUNT ?= $(shell git config --get remote.origin.url | sed -r 's/.*(\@|\/\/)(.*)(\:|\/)([^:\/]*)\/([^\/\.]*)\.git/\2\/\4\/\5/' | tr -d '\n') GORELEASER_MOD_MOUNT ?= $(shell cat $(ROOT_DIR)/.github/repo | tr -d '\n') RELEASE_DOCKER_IMAGE ?= ghcr.io/akash-network/node +GORELEASER_GOWORK := $(GOWORK) + +ifneq ($(GOWORK), off) + GORELEASER_GOWORK := /go/src/$(GORELEASER_MOD_MOUNT)/go.work +endif + ifneq ($(GORELEASER_RELEASE),true) ifeq (,$(findstring publish,$(GORELEASER_SKIP))) GORELEASER_SKIP += publish @@ -34,6 +40,7 @@ bins: $(BINS) build: $(GO_BUILD) -a ./... +.PHONY: $(AKASH) $(AKASH): $(GO_BUILD) -o $@ $(BUILD_FLAGS) ./cmd/akash @@ -66,6 +73,7 @@ test-bins: -e DOCKER_IMAGE=$(RELEASE_DOCKER_IMAGE) \ -e GOPATH=/go \ -e GOTOOLCHAIN="$(GOTOOLCHAIN)" \ + -e GOWORK="$(GORELEASER_GOWORK)" \ -v /var/run/docker.sock:/var/run/docker.sock \ -v $(GOPATH):/go \ -v $(AKASH_ROOT):/go/src/$(GORELEASER_MOD_MOUNT) \ @@ -82,7 +90,7 @@ docker-image: docker run \ --rm \ -e STABLE=$(IS_STABLE) \ - -e MOD="$(GO_MOD)" \ + -e MOD="$(GOMOD)" \ -e BUILD_TAGS="$(BUILD_TAGS)" \ -e BUILD_VARS="$(GORELEASER_BUILD_VARS)" \ -e STRIP_FLAGS="$(GORELEASER_STRIP_FLAGS)" \ @@ -90,10 +98,11 @@ docker-image: -e DOCKER_IMAGE=$(RELEASE_DOCKER_IMAGE) \ -e GOPATH=/go \ -e GOTOOLCHAIN="$(GOTOOLCHAIN)" \ + -e GOWORK="$(GORELEASER_GOWORK)" \ -v /var/run/docker.sock:/var/run/docker.sock \ -v $(GOPATH):/go \ - -v $(AKASH_ROOT):/go/src/$(GO_MOD_NAME) \ - -w /go/src/$(GO_MOD_NAME) \ + -v $(AKASH_ROOT):/go/src/$(GORELEASER_MOD_MOUNT) \ + -w /go/src/$(GORELEASER_MOD_MOUNT) \ $(GORELEASER_IMAGE) \ -f .goreleaser-docker.yaml \ --verbose=$(GORELEASER_VERBOSE) \ @@ -111,7 +120,7 @@ release: gen-changelog docker run \ --rm \ -e STABLE=$(IS_STABLE) \ - -e MOD="$(GO_MOD)" \ + -e MOD="$(GOMOD)" \ -e BUILD_TAGS="$(BUILD_TAGS)" \ -e BUILD_VARS="$(GORELEASER_BUILD_VARS)" \ -e STRIP_FLAGS="$(GORELEASER_STRIP_FLAGS)" \ @@ -120,15 +129,16 @@ release: gen-changelog -e GORELEASER_CURRENT_TAG="$(RELEASE_TAG)" \ -e DOCKER_IMAGE=$(RELEASE_DOCKER_IMAGE) \ -e GOTOOLCHAIN="$(GOTOOLCHAIN)" \ + -e GOWORK="$(GORELEASER_GOWORK)" \ -e GOPATH=/go \ -v /var/run/docker.sock:/var/run/docker.sock \ -v $(GOPATH):/go \ - -v $(AKASH_ROOT):/go/src/$(GO_MOD_NAME) \ - -w /go/src/$(GO_MOD_NAME) \ + -v $(AKASH_ROOT):/go/src/$(GORELEASER_MOD_MOUNT) \ + -w /go/src/$(GORELEASER_MOD_MOUNT) \ $(GORELEASER_IMAGE) \ -f "$(GORELEASER_CONFIG)" \ release \ $(GORELEASER_SKIP) \ --verbose=$(GORELEASER_VERBOSE) \ --clean \ - --release-notes=/go/src/$(GO_MOD_NAME)/.cache/changelog.md + --release-notes=/go/src/$(GORELEASER_MOD_MOUNT)/.cache/changelog.md diff --git a/make/setup-cache.mk b/make/setup-cache.mk index d354c4d4de..cfabcd2f31 100644 --- a/make/setup-cache.mk +++ b/make/setup-cache.mk @@ -5,7 +5,7 @@ $(AKASH_DEVCACHE): mkdir -p $(AKASH_DEVCACHE_INCLUDE) mkdir -p $(AKASH_DEVCACHE_VERSIONS) mkdir -p $(AKASH_DEVCACHE_NODE_MODULES) - mkdir -p $(AKASH_DEVCACHE)/run + mkdir -p $(AKASH_RUN_BIN) cache: $(AKASH_DEVCACHE) $(GIT_CHGLOG_VERSION_FILE): $(AKASH_DEVCACHE) @@ -17,19 +17,21 @@ $(GIT_CHGLOG_VERSION_FILE): $(AKASH_DEVCACHE) touch $@ $(GIT_CHGLOG): $(GIT_CHGLOG_VERSION_FILE) +MOCKERY_MAJOR=$(shell $(SEMVER) get major $(MOCKERY_VERSION)) $(MOCKERY_VERSION_FILE): $(AKASH_DEVCACHE) @echo "installing mockery $(MOCKERY_VERSION) ..." rm -f $(MOCKERY) - GOBIN=$(AKASH_DEVCACHE_BIN) go install -ldflags '-s -w -X github.com/vektra/mockery/v2/pkg/config.SemVer=$(MOCKERY_VERSION)' github.com/vektra/mockery/v2@v$(MOCKERY_VERSION) + GOBIN=$(AKASH_DEVCACHE_BIN) go install -ldflags '-s -w -X github.com/vektra/mockery/v$(MOCKERY_MAJOR)/pkg/config.SemVer=$(MOCKERY_VERSION)' github.com/vektra/mockery/v$(MOCKERY_MAJOR)@v$(MOCKERY_VERSION) rm -rf "$(dir $@)" mkdir -p "$(dir $@)" touch $@ $(MOCKERY): $(MOCKERY_VERSION_FILE) +GOLANGCI_LINT_MAJOR=$(shell $(SEMVER) get major $(GOLANGCI_LINT_VERSION)) $(GOLANGCI_LINT_VERSION_FILE): $(AKASH_DEVCACHE) @echo "installing golangci-lint $(GOLANGCI_LINT_VERSION) ..." rm -f $(GOLANGCI_LINT) - GOBIN=$(AKASH_DEVCACHE_BIN) go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) + GOBIN=$(AKASH_DEVCACHE_BIN) go install github.com/golangci/golangci-lint/v$(GOLANGCI_LINT_MAJOR)/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) rm -rf "$(dir $@)" mkdir -p "$(dir $@)" touch $@ diff --git a/make/test-integration.mk b/make/test-integration.mk index 0c4fc3b261..ee4b63bddb 100644 --- a/make/test-integration.mk +++ b/make/test-integration.mk @@ -6,17 +6,9 @@ TEST_MODULES ?= $(shell $(GO) list ./... | grep -v '/mocks') ### Misc tests ### ############################################################################### -.PHONY: shellcheck -shellcheck: - docker run --rm \ - --volume ${PWD}:/shellcheck \ - --entrypoint sh \ - koalaman/shellcheck-alpine:stable \ - -x /shellcheck/script/shellcheck.sh - .PHONY: test test: - $(GO_TEST) -v -timeout 300s $(TEST_MODULES) + $(GO_TEST) -v -timeout 600s $(TEST_MODULES) .PHONY: test-nocache test-nocache: @@ -26,6 +18,10 @@ test-nocache: test-full: $(GO_TEST) -v -tags=$(BUILD_TAGS) $(TEST_MODULES) +.PHONY: test-integration +test-integration: + $(GO_TEST) -v -tags="e2e.integration" $(TEST_MODULES) + .PHONY: test-coverage test-coverage: $(GO_TEST) -tags=$(BUILD_MAINNET) -coverprofile=coverage.txt \ diff --git a/make/test-simulation.mk b/make/test-simulation.mk index d505f5b103..94447e70f4 100644 --- a/make/test-simulation.mk +++ b/make/test-simulation.mk @@ -4,22 +4,22 @@ test-sim-fullapp: echo "Running app simulation test..." - go test -mod=readonly -tags=$(BUILD_MAINNET) ${APP_DIR} -run=TestFullAppSimulation -Enabled=true \ + go test -mod=readonly $(APP_DIR) -run=TestFullAppSimulation -Enabled=true \ -NumBlocks=50 -BlockSize=100 -Commit=true -Seed=99 -Period=5 -v -timeout 10m test-sim-nondeterminism: echo "Running non-determinism test. This may take several minutes..." - go test -mod=readonly -tags=$(BUILD_MAINNET) $(APP_DIR) -run TestAppStateDeterminism -Enabled=true \ + go test -mod=readonly $(APP_DIR) -run TestAppStateDeterminism -Enabled=true \ -NumBlocks=50 -BlockSize=100 -Commit=true -Period=0 -v -timeout 24h test-sim-import-export: echo "Running application import/export simulation..." - go test -mod=readonly -tags=$(BUILD_MAINNET) $(APP_DIR) -run=TestAppImportExport -Enabled=true \ + go test -mod=readonly $(APP_DIR) -run=TestAppImportExport -Enabled=true \ -NumBlocks=50 -BlockSize=100 -Commit=true -Seed=99 -Period=5 -v -timeout 10m test-sim-after-import: echo "Running application simulation-after-import..." - go test -mod=readonly -tags=$(BUILD_MAINNET) $(APP_DIR) -run=TestAppSimulationAfterImport -Enabled=true \ + go test -mod=readonly $(APP_DIR) -run=TestAppSimulationAfterImport -Enabled=true \ -NumBlocks=50 -BlockSize=100 -Commit=true -Seed=99 -Period=5 -v -timeout 10m test-sims: test-sim-fullapp test-sim-nondeterminism test-sim-import-export test-sim-after-import diff --git a/make/test-upgrade.mk b/make/test-upgrade.mk index cc52e5237e..29fdad29de 100644 --- a/make/test-upgrade.mk +++ b/make/test-upgrade.mk @@ -12,6 +12,7 @@ export AKASH_GAS = auto export AKASH_STATESYNC_ENABLE = false export AKASH_LOG_COLOR = true +STATE_CONFIG ?= $(ROOT_DIR)/tests/upgrade/testnet.json TEST_CONFIG ?= test-config.json KEY_OPTS := --keyring-backend=$(AKASH_KEYRING_BACKEND) KEY_NAME ?= validator @@ -20,21 +21,49 @@ UPGRADE_FROM := $(shell cat $(ROOT_DIR)/meta.json | jq -r --arg name GENESIS_BINARY_VERSION := $(shell cat $(ROOT_DIR)/meta.json | jq -r --arg name $(UPGRADE_TO) '.upgrades[$$name].from_binary' | tr -d '\n') UPGRADE_BINARY_VERSION ?= local +SNAPSHOT_SOURCE ?= sandbox1 + +ifeq ($(SNAPSHOT_SOURCE),mainnet) + SNAPSHOT_NETWORK := akashnet-2 + CHAIN_METADATA_URL := https://raw.githubusercontent.com/akash-network/net/master/mainnet/meta.json +else ifeq ($(SNAPSHOT_SOURCE),sandbox) + SNAPSHOT_NETWORK := sandbox-2 + CHAIN_METADATA_URL := https://raw.githubusercontent.com/akash-network/net/master/sandbox-2/meta.json +else ifeq ($(SNAPSHOT_SOURCE),sandbox1) + SNAPSHOT_NETWORK := sandbox-01 + CHAIN_METADATA_URL := https://raw.githubusercontent.com/akash-network/net/master/sandbox/meta.json +else +$(error "invalid snapshot source $(SNAPSHOT_SOURCE)") +endif + +SNAPSHOT_URL ?= https://snapshots.akash.network/$(SNAPSHOT_NETWORK)/latest REMOTE_TEST_WORKDIR ?= ~/go/src/github.com/akash-network/node REMOTE_TEST_HOST ?= +MAX_VALIDATORS := $(shell cat $(TEST_CONFIG) | jq -r '.validators | length' | tr -d '\n') + $(AKASH_INIT): - $(ROOT_DIR)/script/upgrades.sh --workdir=$(AP_RUN_DIR) --gbv=$(GENESIS_BINARY_VERSION) --ufrom=$(UPGRADE_FROM) --uto=$(UPGRADE_TO) --config="$(PWD)/config.json" init + $(ROOT_DIR)/script/upgrades.sh \ + --workdir=$(AP_RUN_DIR) \ + --gbv=$(GENESIS_BINARY_VERSION) \ + --ufrom=$(UPGRADE_FROM) \ + --uto=$(UPGRADE_TO) \ + --config="$(PWD)/config.json" \ + --chain-meta=$(CHAIN_METADATA_URL) \ + --state-config=$(STATE_CONFIG) \ + --snapshot-url=$(SNAPSHOT_URL) \ + --max-validators=$(MAX_VALIDATORS) \ + init touch $@ .PHONY: init -init: $(AKASH_INIT) $(COSMOVISOR) +init: $(COSMOVISOR) $(AKASH_INIT) .PHONY: genesis genesis: $(GENESIS_DEST) .PHONY: test -test: $(COSMOVISOR) init +test: init $(GO_TEST) -run "^\QTestUpgrade\E$$" -tags e2e.upgrade -timeout 180m -v -args \ -cosmovisor=$(COSMOVISOR) \ -workdir=$(AP_RUN_DIR)/validators \ @@ -45,16 +74,20 @@ test: $(COSMOVISOR) init .PHONY: test-reset test-reset: - $(ROOT_DIR)/script/upgrades.sh --workdir=$(AP_RUN_DIR) --config="$(PWD)/config.json" --uto=$(UPGRADE_TO) clean - $(ROOT_DIR)/script/upgrades.sh --workdir=$(AP_RUN_DIR) --config="$(PWD)/config.json" --uto=$(UPGRADE_TO) --gbv=$(GENESIS_BINARY_VERSION) bins - $(ROOT_DIR)/script/upgrades.sh --workdir=$(AP_RUN_DIR) --config="$(PWD)/config.json" --uto=$(UPGRADE_TO) keys + $(ROOT_DIR)/script/upgrades.sh --workdir=$(AP_RUN_DIR) --config="$(PWD)/config.json" --uto=$(UPGRADE_TO) --snapshot-url=$(SNAPSHOT_URL) --chain-meta=$(CHAIN_METADATA_URL) --max-validators=$(MAX_VALIDATORS) clean + #$(ROOT_DIR)/script/upgrades.sh --workdir=$(AP_RUN_DIR) --config="$(PWD)/config.json" --uto=$(UPGRADE_TO) --snapshot-url=$(SNAPSHOT_URL) --gbv=$(GENESIS_BINARY_VERSION) --chain-meta=$(CHAIN_METADATA_URL) bins + $(ROOT_DIR)/script/upgrades.sh --workdir=$(AP_RUN_DIR) --config="$(PWD)/config.json" --uto=$(UPGRADE_TO) --snapshot-url=$(SNAPSHOT_URL) --chain-meta=$(CHAIN_METADATA_URL) keys + $(ROOT_DIR)/script/upgrades.sh --workdir=$(AP_RUN_DIR) --config="$(PWD)/config.json" --state-config=$(STATE_CONFIG) --snapshot-url=$(SNAPSHOT_URL) --chain-meta=$(CHAIN_METADATA_URL) --max-validators=$(MAX_VALIDATORS) prepare-state +.PHONY: prepare-state +prepare-state: + $(ROOT_DIR)/script/upgrades.sh --workdir=$(AP_RUN_DIR) --config="$(PWD)/config.json" --state-config=$(STATE_CONFIG) --chain-meta=$(CHAIN_METADATA_URL) --max-validators=$(MAX_VALIDATORS) prepare-state .PHONY: bins bins: ifneq ($(findstring build,$(SKIP)),build) bins: - $(ROOT_DIR)/script/upgrades.sh --workdir=$(AP_RUN_DIR) --config="$(PWD)/config.json" --uto=$(UPGRADE_TO) bins + $(ROOT_DIR)/script/upgrades.sh --workdir=$(AP_RUN_DIR) --config="$(PWD)/config.json" --uto=$(UPGRADE_TO) --gbv=$(GENESIS_BINARY_VERSION) --chain-meta=$(CHAIN_METADATA_URL) bins endif .PHONY: clean diff --git a/meta.json b/meta.json index 90555e71dc..5dc439ee52 100644 --- a/meta.json +++ b/meta.json @@ -39,6 +39,11 @@ "skipped": false, "from_binary": "v0.36.3-rc9", "from_version": "v0.36.0" + }, + "v1.0.0": { + "skipped": false, + "from_binary": "v0.38.6-rc2", + "from_version": "v0.38.0" } } } diff --git a/pubsub/bus_test.go b/pubsub/bus_test.go index 4af2730383..747c400102 100644 --- a/pubsub/bus_test.go +++ b/pubsub/bus_test.go @@ -3,10 +3,10 @@ package pubsub_test import ( "testing" - "github.com/akash-network/node/pubsub" + "github.com/cometbft/cometbft/crypto/ed25519" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto/ed25519" + "pkg.akt.dev/node/pubsub" ) func TestBus(t *testing.T) { diff --git a/script/shellcheck.sh b/script/shellcheck.sh old mode 100644 new mode 100755 diff --git a/script/tools.sh b/script/tools.sh index e5f929669c..c8f6999549 100755 --- a/script/tools.sh +++ b/script/tools.sh @@ -5,41 +5,227 @@ SEMVER=$SCRIPT_DIR/semver.sh gomod="$SCRIPT_DIR/../go.mod" +macos_deps=( + "bash" + "direnv" + "pv" + "lz4" +) + +debian_deps=( + "make" + "build-essential" + "direnv" + "unzip" + "wget" + "curl" + "npm" + "jq" + "coreutils" +) + +is_command() { + command -v "$1" >/dev/null +} + function get_gotoolchain() { - local gotoolchain - local goversion - local local_goversion - - gotoolchain=$(grep -E '^toolchain go[0-9]{1,}.[0-9]{1,}.[0-9]{1,}$' < "$gomod" | cut -d ' ' -f 2 | tr -d '\n') - goversion=$(grep -E '^go [0-9]{1,}.[0-9]{1,}(.[0-9]{1,})?$' < "$gomod" | cut -d ' ' -f 2 | tr -d '\n') - - if [[ ${gotoolchain} == "" ]]; then - # determine go toolchain from go version in go.mod - if which go > /dev/null 2>&1 ; then - local_goversion=$(GOTOOLCHAIN=local go version | cut -d ' ' -f 3 | sed 's/go*//' | tr -d '\n') - if [[ $($SEMVER compare "v$local_goversion" v"$goversion") -ge 0 ]]; then - goversion=$local_goversion - else - local_goversion= - fi - fi - - if [[ "$local_goversion" == "" ]]; then - goversion=$(curl -s "https://go.dev/dl/?mode=json&include=all" | jq -r --arg regexp "^go$goversion" '.[] | select(.stable == true) | select(.version | match($regexp)) | .version' | head -n 1 | sed -e s/^go//) - fi - - if [[ $goversion != "" ]] && [[ $($SEMVER compare "v$goversion" v1.21.0) -ge 0 ]]; then - gotoolchain=go${goversion} - else - gotoolchain=go$(grep -E '^go [0-9]{1,}.[0-9]{1,}$' < "$gomod" | cut -d ' ' -f 2 | tr -d '\n').0 - fi - fi - - echo -n "$gotoolchain" + local gotoolchain + local goversion + local local_goversion + local toolfile + + toolfile=$gomod + + if [[ "$GOWORK" != "off" ]] && [ -f "$GOWORK" ]; then + toolfile=$GOWORK + fi + + gotoolchain=$(grep -E '^toolchain go[0-9]{1,}.[0-9]{1,}.[0-9]{1,}$' <"$toolfile" | cut -d ' ' -f 2 | tr -d '\n') + goversion=$(grep -E '^go [0-9]{1,}.[0-9]{1,}(.[0-9]{1,})?$' <"$toolfile" | cut -d ' ' -f 2 | tr -d '\n') + + if [[ ${gotoolchain} == "" ]]; then + gotoolchain=go$goversion + fi + + if [[ ${gotoolchain} == "" ]]; then + # determine go toolchain from go version in go.mod + if which go >/dev/null 2>&1; then + # shellcheck disable=SC2086 + local_goversion=$(env -i HOME="$HOME" GOTOOLCHAIN=local $SHELL -l -c "go version | cut -d ' ' -f 3 | sed 's/go*//' | tr -d '\n'") + if ! [[ $($SEMVER compare "v$local_goversion" v"$goversion") -ge 0 ]]; then + goversion=$local_goversion + else + local_goversion= + fi + fi + + if [[ "$local_goversion" == "" ]]; then + goversion=$(curl -s "https://go.dev/dl/?mode=json&include=all" | jq -r --arg regexp "^go$goversion" '.[] | select(.stable == true) | select(.version | match($regexp)) | .version' | head -n 1 | sed -e s/^go//) + fi + + if [[ $goversion != "" ]] && [[ $($SEMVER compare "v$goversion" v1.21.0) -ge 0 ]]; then + gotoolchain=go${goversion} + else + gotoolchain=go$(grep -E '^go [0-9]{1,}.[0-9]{1,}$' <"$toolfile" | cut -d ' ' -f 2 | tr -d '\n').0 + fi + fi + + echo -n "$gotoolchain" +} + +replace_paths() { + local file="${1}" + local cimport="${2}" + local nimport="${3}" + local sedcmd=sed + + if [[ "$OSTYPE" == "darwin"* ]]; then + sedcmd=gsed + fi + + $sedcmd -ri "s~$cimport~$nimport~" "${file}" +} + +function replace_import_path() { + local next_major_version=$1 + local curr_module_name + local curr_version + local new_module_name + + curr_module_name=$(go list -m) + curr_version=$(echo "$curr_module_name" | sed -n 's/.*v\([0-9]*\).*/\1/p') + new_module_name=${curr_module_name%/"v$curr_version"}/$next_major_version + + echo "current import paths are $curr_module_name, replacing with $new_module_name" + + declare -a modules_to_upgrade_manually + + modules_to_upgrade_manually+=("./go/go.mod") + + echo "preparing files to replace" + + declare -a files + + while IFS= read -r line; do + files+=("$line") + done < <(find . -type f -not \( \ + -path "./install.sh" \ + -or -path "./upgrades/*" \ + -or -path "./.cache/*" \ + -or -path "./dist/*" \ + -or -path "./.git*" \ + -or -name "*.md" \ + -or -path "./.idea/*" \)) + + echo "updating all files" + + for file in "${files[@]}"; do + if test -f "$file"; then + # skip files that need manual upgrading + for excluded_file in "${modules_to_upgrade_manually[@]}"; do + if [[ "$file" == *"$excluded_file"* ]]; then + continue 2 + fi + done + + replace_paths "$file" "\"$curr_module_name" "\"$new_module_name" + fi + done + + echo "updating go.mod" + for retract in $(go mod edit --json | jq -cr '.Retract | if . != null then .[] else empty end'); do + local low + local high + + low=$(jq -r '.Low' <<<"$retract") + high=$(jq -r '.High' <<<"$retract") + echo " dropping retract: [$low, $high]" + go mod edit -dropretract=["$low","$high"] + done + + replace_paths "./go.mod" "$curr_module_name" "$new_module_name" +} + +function install_gha_deps() { + if [[ "$OSTYPE" == "darwin"* ]]; then + echo "Detected Darwin based system" + + if ! is_command brew; then + echo "homebrew is not installed. visit https://brew.sh" + exit 1 + fi + + local tools + + if ! is_command make || [[ $(make --version | head -1 | cut -d" " -f3 | cut -d"." -f1) -lt 4 ]]; then + tools="$tools make" + fi + + # shellcheck disable=SC2068 + for dep in ${macos_deps[@]}; do + echo -n "detecting $dep ..." + status="(installed)" + if ! brew list "$dep" >/dev/null 2>&1; then + tools="$tools $dep" + status="(not installed)" + fi + + echo " $status" + done + + if [[ "$tools" != "" ]]; then + # don't put quotes around $tools! + # shellcheck disable=SC2086 + brew install $tools + else + echo "All requirements already met. Nothing to install" + fi + elif [[ "$OSTYPE" == "linux-gnu"* ]]; then + if is_command dpkg; then + echo "Detected Debian based system" + local tools + + # shellcheck disable=SC2068 + for dep in ${debian_deps[@]}; do + echo -n "detecting $dep ..." + status="(installed)" + if ! dpkg -l "$dep" >/dev/null 2>&1; then + tools="$tools $dep" + status="(not installed)" + fi + echo " $status" + done + + cmd="apt-get" + + if is_command sudo; then + cmd="sudo $cmd" + fi + + if [[ "$tools" != "" ]]; then + $cmd update + # don't put quotes around $tools! + # shellcheck disable=SC2086 + ( + set -x + $cmd install -y $tools + ) + else + echo "All requirements already met. Nothing to install" + fi + fi + else + echo "Unsupported OS $OSTYPE" + exit 1 + fi } case "$1" in -gotoolchain) - get_gotoolchain - ;; + gotoolchain) + get_gotoolchain + ;; + replace-import-path) + shift + replace_import_path "$@" + ;; esac diff --git a/script/upgrades.sh b/script/upgrades.sh index bbf48af475..1a36983ba1 100755 --- a/script/upgrades.sh +++ b/script/upgrades.sh @@ -17,13 +17,13 @@ Options: -h, --help Print this help message. Commands: test-required Determine if latest present upgrade needed test run. - Conditions to run test: - - If current reference matches last upgrade in a codebase - - If the codebase has tag matching to the upgrade name, but release is marked as revoked - - If the codebase does not have tag matching upgrade name - Exit codes: - - 0 test required - - 1 something went wrong. check stderr" + Conditions to run test: + - If current reference matches last upgrade in a codebase + - If the codebase has tag matching to the upgrade name, but release is marked as revoked + - If the codebase does not have tag matching upgrade name + Exit codes: + - 0 test required + - 1 something went wrong. check stderr" echoerr() { echo "$@" 1>&2; } @@ -33,9 +33,13 @@ WORKDIR=${UTEST_WORKDIR:=} UPGRADE_FROM=${UTEST_UPGRADE_FROM:=} UPGRADE_TO=${UTEST_UPGRADE_TO:=} CONFIG_FILE=${UTEST_CONFIG_FILE:=} +CHAIN_METADATA_URL=https://raw.githubusercontent.com/akash-network/net/master/mainnet/meta.json +SNAPSHOT_URL=https://snapshots.akash.network/akashnet-2/latest +STATE_CONFIG= +MAX_VALIDATORS=1 short_opts=h -long_opts=help/workdir:/ufrom:/uto:/gbv:/config: # those who take an arg END with : +long_opts=help/workdir:/ufrom:/uto:/gbv:/config:/chain-meta:/snapshot-url:/state-config:/max-validators: # those who take an arg END with : while getopts ":$short_opts-:" o; do case $o in @@ -96,6 +100,7 @@ while getopts ":$short_opts-:" o; do WORKDIR=$OPTARG ;; ufrom) + # shellcheck disable=SC2034 UPGRADE_FROM=$OPTARG ;; uto) @@ -107,11 +112,72 @@ while getopts ":$short_opts-:" o; do config) CONFIG_FILE=$OPTARG ;; + chain-meta) + CHAIN_METADATA_URL=$OPTARG + ;; + snapshot-url) + SNAPSHOT_URL=$OPTARG + ;; + state-config) + STATE_CONFIG=$OPTARG + ;; + max-validators) + MAX_VALIDATORS=$OPTARG + ;; esac done shift "$((OPTIND - 1))" -GENESIS_ORIG=${UTEST_GENESIS_ORIGIN:=https://github.com/akash-network/testnetify/releases/download/${UPGRADE_FROM}/genesis.json.tar.lz4} +CHAIN_METADATA=$(curl -s "${CHAIN_METADATA_URL}") +GENESIS_URL="$(echo "$CHAIN_METADATA" | jq -r '.codebase.genesis.genesis_url? // .genesis?')" + +# Stack-based trap management +trap_add() { + local sig="$1" + shift + local new_cmd="$*" + + if [ -z "$sig" ] || [ -z "$new_cmd" ]; then + echo "Usage: trap_add SIGNAL COMMAND" >&2 + return 1 + fi + + # Get existing trap command for this signal + local existing_cmd + existing_cmd=$(trap -p "$sig" 2>/dev/null | sed -n "s/^trap -- '\(.*\)' ${sig}$/\1/p") + + # Build the new trap command + if [ -n "$existing_cmd" ]; then + # Append to existing trap + # shellcheck disable=SC2064 + trap "${existing_cmd}; ${new_cmd}" "$sig" + else + # Create new trap + # shellcheck disable=SC2064 + trap "$new_cmd" "$sig" + fi +} + +# Optional: Function to show current trap stack +trap_show() { + local sig="$1" + if [ -z "$sig" ]; then + trap -p + else + trap -p "$sig" + fi +} + +function cleanup() { + jb=$(jobs -p) + + if [[ "$jb" != "" ]]; then + # shellcheck disable=SC2086 + kill $jb + fi +} + +trap_add EXIT 'cleanup' pushd() { command pushd "$@" >/dev/null @@ -121,7 +187,7 @@ popd() { command popd >/dev/null } -function content_type() { +function tar_by_content_type() { case "$1" in *.tar.cz*) tar_cmd="tar -xJ -" @@ -143,6 +209,25 @@ function content_type() { echo "$tar_cmd" } +function content_type() { + case "$1" in + *.tar.cz*) + tar_cmd="tar.cz" + ;; + *.tar.gz*) + tar_cmd="tar.gz" + ;; + *.tar.lz4*) + tar_cmd="tar.lz4" + ;; + *.tar.zst*) + tar_cmd="tar.zst" + ;; + esac + + echo "$tar_cmd" +} + function content_size() { local size_in_bytes @@ -159,7 +244,17 @@ function content_size() { } function content_name() { - name=$(wget "$1" --spider --server-response -O - 2>&1 | grep "Content-Disposition:" | tail -1 | awk -F"filename=" '{print $2}') + name=$(wget "$1" --spider --server-response -O - 2>&1 | grep -i "content-disposition" | awk -F"filename=" '{print $2}') + # shellcheck disable=SC2181 + if [[ "$name" == "" ]]; then + echo "$1" + else + echo "$name" + fi +} + +function content_location() { + name=$(wget "$1" --spider --server-response -O - 2>&1 | grep -i -m 1 "Location:" | awk '{print $2}' | tr -d '\n') # shellcheck disable=SC2181 if [[ "$name" == "" ]]; then echo "$1" @@ -213,7 +308,7 @@ function build_bins() { if [[ $GOOS == "darwin" ]]; then archive="${archive}_darwin_all" else - archive="${archive}_linux_$(uname_arch)" + archive="${archive}_linux_$GOARCH" fi unzip -o "${AKASH_DEVCACHE}/goreleaser/test-bins/${archive}.zip" -d "$upgrade_bin" @@ -236,6 +331,8 @@ function init() { mkdir -p "${WORKDIR}/validators/logs" + snapshot_file=${validators_dir}/snapshot + for val in $(jq -c '.validators[]' <<<"$config"); do local valdir local cosmovisor_dir @@ -258,83 +355,261 @@ function init() { cp "$validators_dir/.akash0/cosmovisor/upgrades/$UPGRADE_TO/bin/akash" "$upgrade_bin/akash" fi + pushd "$(pwd)" + cd "$cosmovisor_dir" + ln -snf genesis current + popd + AKASH=$genesis_bin/akash + genesis_file=${valdir}/config/genesis.json + rm -f "$genesis_file" + $AKASH init --home "$valdir" "$(jq -rc '.moniker' <<<"$val")" >/dev/null 2>&1 - if [[ $cnt -eq 0 ]]; then - pushd "$(pwd)" - cd "$valdir/config" + cat >"$valdir/.envrc" <"$valdir/validator.json" <"$valdir/config/priv_validator_key.json" + jq -r '.keys.node' <<<"$val" >"$valdir/config/node_key.json" - if [[ "${GENESIS_ORIG}" =~ ^https?:\/\/.* ]]; then - echo "Downloading genesis from $GENESIS_ORIG" + ((cnt++)) || true + done + + import_keys + prepare_state +} + +function prepare_state() { + if [[ -z "${WORKDIR}" ]]; then + echo "workdir is not set" + echo -e "$USAGE" + exit 1 + fi + + local config + config=$(cat "$CONFIG_FILE") + + local cnt=0 + local validators_dir=${WORKDIR}/validators + + mkdir -p "${WORKDIR}/validators/logs" + + snapshot_file=${validators_dir}/snapshot + + for val in $(jq -c '.validators[]' <<<"$config"); do + local valdir + local cosmovisor_dir + local genesis_bin + local upgrade_bin + + valdir=$validators_dir/.akash${cnt} + cosmovisor_dir=$valdir/cosmovisor + genesis_bin=$cosmovisor_dir/genesis/bin + + genesis_file=${valdir}/config/genesis.json + addrbook_file=${valdir}/config/genesis.json + rm -f "$genesis_file" + rm -f "$addrbook_file" + + if [[ $cnt -eq 0 ]]; then + if [[ "${GENESIS_URL}" =~ ^https?:\/\/.* ]]; then + echo "Downloading genesis from ${GENESIS_URL}" pv_args="-petrafb -i 5" - sz=$(content_size "$GENESIS_ORIG") + sz=$(content_size "${GENESIS_URL}") # shellcheck disable=SC2181 if [ $? -eq 0 ]; then if [[ -n $sz ]]; then pv_args+=" -s $sz" fi - tar_cmd=$(content_type "$(content_name "$GENESIS_ORIG")") + tar_cmd=$(content_type "$(content_name "${GENESIS_URL}")") - # shellcheck disable=SC2086 - wget -nv -O - "$GENESIS_ORIG" | pv $pv_args | eval "$tar_cmd" + if [ "$tar_cmd" != "" ]; then + # shellcheck disable=SC2086 + wget -q -O - "${GENESIS_URL}" | pv $pv_args | eval "$tar_cmd" + else + wget -q --show-progress -O "$genesis_file" "${GENESIS_URL}" + fi else echo "unable to download genesis" fi else - echo "Unpacking genesis from $GENESIS_ORIG" - tar_cmd=$(content_type "$GENESIS_ORIG") + echo "Unpacking genesis from ${GENESIS_URL}" + tar_cmd=$(content_type "${GENESIS_URL}") # shellcheck disable=SC2086 - (pv -petrafb -i 5 "$GENESIS_ORIG" | eval "$tar_cmd") 2>&1 | stdbuf -o0 tr '\r' '\n' + (pv -petrafb -i 5 "${GENESIS_URL}" | eval "$tar_cmd") 2>&1 | stdbuf -o0 tr '\r' '\n' fi - popd + if ! ls "${snapshot_file}"* 1> /dev/null 2>&1; then + file_url=$(content_location "$SNAPSHOT_URL") + content_ext=$(content_type "$file_url") - jq -c '.mnemonics[]' <<<"$config" | while read -r mnemonic; do - jq -c '.keys[]' <<<"$mnemonic" | while read -r key; do - jq -rc '.phrase' <<<"$mnemonic" | $AKASH --home="$valdir" --keyring-backend=test keys add "$(jq -rc '.name' <<<"$key")" --recover --index "$(jq -rc '.index' <<<"$key")" - done - done + sfile="${snapshot_file}.${content_ext}" - cat >"$valdir/.envrc" <&1 | stdbuf -o0 tr '\r' '\n' + + # if snapshot provides data dir then move all things up + if [[ -d data ]]; then + echo "snapshot has data dir. moving content..." + mv data/* ./ + rm -rf data + fi + rm -f upgrade-info.json + + popd else pushd "$(pwd)" + cd "${valdir}" - cd "$valdir/config" + mkdir -p "data" - ln -snf "../../.akash0/config/genesis.json" "genesis.json" + echo '{"height": "0", "round": 0, "step": 0}' > data/priv_validator_state.json popd fi - jq -r '.keys.priv' <<<"$val" >"$valdir/config/priv_validator_key.json" - jq -r '.keys.node' <<<"$val" >"$valdir/config/node_key.json" - ((cnt++)) || true done + + local rvaldir + local rpid + local akashversion + local AKASH + AKASH=$validators_dir/.akash0/cosmovisor/genesis/bin/akash + + rvaldir=$validators_dir/.akash0 + + echo "testnetifying state" + $AKASH testnetify --home="$rvaldir" --testnet-rootdir="$validators_dir" --testnet-config="${STATE_CONFIG}" --yes + + if [[ $MAX_VALIDATORS -gt 1 ]]; then + echo "starting testnet validator" + $AKASH start --home="$rvaldir" >/dev/null 2>&1 & rpid=$! + + akashversion=$($AKASH version) + + sleep 10 + + echo "adding remaining validators to the state" + cnt=0 + for val in $(jq -c '.validators[]' <<<"$config"); do + local valdir + local valjson + + valdir=$validators_dir/.akash${cnt} + + valjson=$(cat "$valdir/validator.json") + if [[ $cnt -gt 0 ]]; then + if [[ $($semver compare "$akashversion" v1.0.0-rc0) -ge 0 ]]; then + $AKASH tx staking create-validator "$valjson" --home="$rvaldir" --from="validator$cnt" --yes + else + $AKASH tx staking create-validator \ + --home="$rvaldir" \ + --moniker="$(jq -rc '.moniker' <<<"$valjson")" \ + --amount="$(jq -rc '.amount' <<<"$valjson")" \ + --min-self-delegation="$(jq -rc '."min-self-delegation"' <<<"$valjson")" \ + --commission-max-change-rate="$(jq -rc '."commission-max-change-rate"' <<<"$valjson")" \ + --commission-max-rate="$(jq -rc '."commission-max-rate"' <<<"$valjson")" \ + --commission-rate="$(jq -rc '."commission-rate"' <<<"$valjson")" \ + --pubkey="$($AKASH tendermint show-validator --home="$valdir")" \ + --from="validator$cnt" \ + --yes + fi + fi + ((cnt++)) || true + + if [[ $cnt -eq $MAX_VALIDATORS ]]; then + break + fi + done + + sleep 10 + + kill -SIGINT $rpid + wait $rpid + + echo "copying testnetified state to remaining validators" + cnt=0 + + local srcval + srcval="${validators_dir}/.akash0" + + for val in $(jq -c '.validators[]' <<<"$config"); do + local valdir + + valdir=$validators_dir/.akash${cnt} + + if [[ $cnt -gt 0 ]]; then + pushd "$(pwd)" + + cd "${valdir}" + + rm -f "config/genesis.json" + + cp -r "$srcval/config/genesis.json" "config/genesis.json" + + local state + state=$(cat data/priv_validator_state.json) + + rm -rf "data" + cp -r "$srcval/data" ./ + + echo "$state" > data/priv_validator_state.json + popd + fi + + ((cnt++)) || true + done + fi } function clean() { @@ -360,9 +635,14 @@ function clean() { rm -rf "$valdir"/data/* rm -rf "$cosmovisor_dir/current" rm -rf "$cosmovisor_dir/upgrades/${UPGRADE_TO}/upgrade-info.json" - rm -rf "$cosmovisor_dir/upgrades/${UPGRADE_TO}/bin/akash" - echo '{"height":"0","round": 0,"step": 0}' | jq > "$valdir/data/priv_validator_state.json" + pushd "$(pwd)" + + cd "$cosmovisor_dir" + + ln -snf genesis current + + popd ((cnt++)) || true done @@ -456,6 +736,10 @@ case "$1" in shift clean ;; + prepare-state) + shift + prepare_state + ;; upgrade-from-release) shift upgrades_dir=${ROOT_DIR}/upgrades/software @@ -469,7 +753,46 @@ case "$1" in else exit 1 fi + ;; + snapshot-source) + shift + + curr_ref=$1 + snapshot_source="sandbox" + + is_valid=$($semver validate "$curr_ref") + + if [[ $is_valid == "valid" ]]; then + build=$($semver get build "$curr_ref") + if [[ -n $build ]]; then + # Split the input by dots, as only dot is allowed in semver build token + IFS='.' read -ra PARTS <<< "$build" + # Process pairs (key at even index, value at odd index) + for ((i=0; i<${#PARTS[@]}; i+=2)); do + key="${PARTS[i]}" + value="${PARTS[i+1]}" + + # Skip if value is missing + if [ -z "$value" ]; then + continue + fi + + case "$key" in + network) + snapshot_source=$value + ;; + *) + ;; + esac + done + fi + elif [[ $curr_ref == "mainnet/main" || $curr_ref == "main" ]]; then + snapshot_source="mainnet" + fi + + echo -n "$snapshot_source" + exit 0 ;; test-required) shift diff --git a/sdl/_testdata/deployment-svc-mismatch.yaml b/sdl/_testdata/deployment-svc-mismatch.yaml deleted file mode 100644 index 6bb33b41c6..0000000000 --- a/sdl/_testdata/deployment-svc-mismatch.yaml +++ /dev/null @@ -1,45 +0,0 @@ ---- -version: "2.0" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - webapp: - westcoast: - profile: web - count: 2 diff --git a/sdl/_testdata/private_service.yaml b/sdl/_testdata/private_service.yaml deleted file mode 100644 index 73db7d9606..0000000000 --- a/sdl/_testdata/private_service.yaml +++ /dev/null @@ -1,64 +0,0 @@ ---- -version: "2.0" -services: - bind: - image: bind9 - expose: - - port: 53 - proto: udp - to: - - global: true - - pg: - image: postgresql - expose: - - port: 5463 - to: - - service: bind - -profiles: - compute: - bind: - resources: - cpu: - units: "50m" - memory: - size: "64Mi" - storage: - size: "16Mi" - pg: - resources: - cpu: - units: "500m" - memory: - size: "512Mi" - storage: - size: "1000Mi" - - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - pg: - denom: uakt - amount: 1000 - bind: - denom: uakt - amount: 333 -deployment: - pg: - westcoast: - profile: pg - count: 1 - bind: - westcoast: - profile: bind - count: 8 diff --git a/sdl/_testdata/profile-svc-name-mismatch.yaml b/sdl/_testdata/profile-svc-name-mismatch.yaml deleted file mode 100644 index ea88ff49ce..0000000000 --- a/sdl/_testdata/profile-svc-name-mismatch.yaml +++ /dev/null @@ -1,38 +0,0 @@ ---- -version: "2.0" - -services: - webapp: - image: ghcr.io/akash-network/demo-app - expose: - - port: 80 - as: 80 - accept: - - thehostname.com - to: - - global: true - -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "512Mi" - storage: - size: "512Mi" - placement: - san-jose: - attributes: - region: sjc - pricing: - web: - denom: uakt - amount: 25 - -deployment: - webapp: - san-jose: - profile: web - count: 1 diff --git a/sdl/_testdata/service-mix.yaml b/sdl/_testdata/service-mix.yaml deleted file mode 100644 index 51a21a01ed..0000000000 --- a/sdl/_testdata/service-mix.yaml +++ /dev/null @@ -1,80 +0,0 @@ ---- -version: "2.0" -services: - svca: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp - svcb: - image: nginx - expose: - - port: 80 - accept: - - bhostname.com - to: - - global: true - - port: 12346 - to: - - global: true - proto: udp - -profiles: - compute: - profilea: - resources: - cpu: - units: "100m" - gpu: - units: "1" - attributes: - vendor: - nvidia: - memory: - size: "128Mi" - storage: - - size: "1Gi" - profileb: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - blalbla: foo - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - profilea: - denom: uakt - amount: 50 - profileb: - denom: uakt - amount: 50 - -deployment: - svca: - westcoast: - profile: profilea - count: 1 - svcb: - westcoast: - profile: profileb - count: 1 diff --git a/sdl/_testdata/service-mix2.yaml b/sdl/_testdata/service-mix2.yaml deleted file mode 100644 index 3eb556d980..0000000000 --- a/sdl/_testdata/service-mix2.yaml +++ /dev/null @@ -1,69 +0,0 @@ ---- -version: "2.0" -services: - svca: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp - svcb: - image: nginx - expose: - - port: 80 - accept: - - bhostname.com - to: - - global: true - - port: 12346 - to: - - global: true - proto: udp - -profiles: - compute: - profilea: - resources: - cpu: - units: "100m" - gpu: - units: "1" - attributes: - vendor: - nvidia: - memory: - size: "128Mi" - storage: - - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - blalbla: foo - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - profilea: - denom: uakt - amount: 50 - -deployment: - svca: - westcoast: - profile: profilea - count: 1 - svcb: - westcoast: - profile: profilea - count: 1 diff --git a/sdl/_testdata/simple-double-ram.yaml b/sdl/_testdata/simple-double-ram.yaml deleted file mode 100644 index 6e1bdb5cb6..0000000000 --- a/sdl/_testdata/simple-double-ram.yaml +++ /dev/null @@ -1,45 +0,0 @@ ---- -version: "2.0" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "256Mi" - storage: - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 2 diff --git a/sdl/_testdata/simple-gpu.yaml b/sdl/_testdata/simple-gpu.yaml deleted file mode 100644 index 84048e6f0b..0000000000 --- a/sdl/_testdata/simple-gpu.yaml +++ /dev/null @@ -1,52 +0,0 @@ ---- -version: "2.0" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp -profiles: - compute: - web: - resources: - cpu: - units: "100m" - gpu: - units: 1 - attributes: - vendor: - nvidia: - - model: a100 - memory: - size: "128Mi" - storage: - - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - blalbla: foo - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 2 diff --git a/sdl/_testdata/simple-with-ip.yaml b/sdl/_testdata/simple-with-ip.yaml deleted file mode 100644 index 4308f095ee..0000000000 --- a/sdl/_testdata/simple-with-ip.yaml +++ /dev/null @@ -1,50 +0,0 @@ ---- -version: "2.0" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - ip: "meow" - proto: udp -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 2 - -endpoints: - meow: - kind: "ip" diff --git a/sdl/_testdata/simple.yaml b/sdl/_testdata/simple.yaml deleted file mode 100644 index d164e60e9d..0000000000 --- a/sdl/_testdata/simple.yaml +++ /dev/null @@ -1,45 +0,0 @@ ---- -version: "2.0" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 2 diff --git a/sdl/_testdata/simple2.yaml b/sdl/_testdata/simple2.yaml deleted file mode 100644 index 08dfa81c86..0000000000 --- a/sdl/_testdata/simple2.yaml +++ /dev/null @@ -1,64 +0,0 @@ ---- -version: "2.0" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp - bew: - image: nginx - expose: - - port: 8080 - accept: - - bhostname.com - to: - - global: true - - port: 12346 - to: - - global: true - proto: udp - - port: 12347 - to: - - global: true - proto: udp -profiles: - compute: - bew: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 - bew: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: bew - count: 2 diff --git a/sdl/_testdata/simple3.yaml b/sdl/_testdata/simple3.yaml deleted file mode 100644 index 9e01620896..0000000000 --- a/sdl/_testdata/simple3.yaml +++ /dev/null @@ -1,45 +0,0 @@ ---- -version: "2.0" - -services: - app: - image: ubuntu:22.04 - command: - - "sh" - - "-c" - args: - - 'sleep infinity' - expose: - - port: 80 - as: 80 - to: - - global: true - - port: 22 - as: 22 - to: - - global: true - -profiles: - compute: - app: - resources: - cpu: - units: 1 - memory: - size: 2Gi - storage: - size: 10Gi - placement: - akash: - attributes: - host: akash - pricing: - app: - denom: uakt - amount: 1000000 - -deployment: - app: - akash: - profile: app - count: 1 diff --git a/sdl/_testdata/simple4.yaml b/sdl/_testdata/simple4.yaml deleted file mode 100644 index 1f55548556..0000000000 --- a/sdl/_testdata/simple4.yaml +++ /dev/null @@ -1,90 +0,0 @@ ---- -version: '2.0' -services: - wordpress: - image: wordpress - depends_on: - - db - expose: - - port: 80 - http_options: - max_body_size: 104857600 - # accept: - # - "example.com" - to: - - global: true - env: - - WORDPRESS_DB_HOST=db - - WORDPRESS_DB_USER=wordpress - - WORDPRESS_DB_PASSWORD=testpass4you - - WORDPRESS_DB_NAME=wordpress - params: - storage: - wordpress-data: - mount: /var/www/html - readOnly: false - db: - # We use a mariadb image which supports both amd64 & arm64 architecture - image: mariadb:10.6.4 - # If you really want to use MySQL, uncomment the following line - #image: mysql:8.0.27 - expose: - - port: 3306 - to: - - service: wordpress - env: - - MYSQL_RANDOM_ROOT_PASSWORD=1 - - MYSQL_DATABASE=wordpress - - MYSQL_USER=wordpress - - MYSQL_PASSWORD=testpass4you - params: - storage: - wordpress-db: - mount: /var/lib/mysql - readOnly: false -profiles: - compute: - wordpress: - resources: - cpu: - units: 1 - memory: - size: 1Gi - storage: - - size: 1Gi - - name: wordpress-data - size: 1Gi - attributes: - persistent: true - class: beta3 - db: - resources: - cpu: - units: 1 - memory: - size: 1Gi - storage: - - size: 1Gi - - name: wordpress-db - size: 1Gi - attributes: - persistent: true - class: beta3 - placement: - akash: - pricing: - wordpress: - denom: uakt - amount: 10000 - db: - denom: uakt - amount: 10000 -deployment: - wordpress: - akash: - profile: wordpress - count: 1 - db: - akash: - profile: db - count: 1 diff --git a/sdl/_testdata/storageClass1.yaml b/sdl/_testdata/storageClass1.yaml deleted file mode 100644 index 695e0b647b..0000000000 --- a/sdl/_testdata/storageClass1.yaml +++ /dev/null @@ -1,52 +0,0 @@ ---- -version: "2.0" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp - params: - storage: - configs: -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - - size: "1Gi" - - size: 1Gi - name: configs - attributes: - persistent: true - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 1 diff --git a/sdl/_testdata/storageClass2.yaml b/sdl/_testdata/storageClass2.yaml deleted file mode 100644 index 5f907cf07f..0000000000 --- a/sdl/_testdata/storageClass2.yaml +++ /dev/null @@ -1,53 +0,0 @@ ---- -version: "2.0" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp - params: - storage: - configs: - mount: etc/nginx -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - - size: 1Gi - - size: 1Gi - name: configs - attributes: - persistent: true - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 1 diff --git a/sdl/_testdata/storageClass3.yaml b/sdl/_testdata/storageClass3.yaml deleted file mode 100644 index 1e0bae8e61..0000000000 --- a/sdl/_testdata/storageClass3.yaml +++ /dev/null @@ -1,52 +0,0 @@ ---- -version: "2.0" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp - params: - storage: - data: -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - - size: 1Gi - - size: 1Gi - name: configs - attributes: - persistent: true - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 1 diff --git a/sdl/_testdata/storageClass4.yaml b/sdl/_testdata/storageClass4.yaml deleted file mode 100644 index 5ca8af53f9..0000000000 --- a/sdl/_testdata/storageClass4.yaml +++ /dev/null @@ -1,59 +0,0 @@ ---- -version: "2.0" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp - params: - storage: - config: - mount: /etc/nginx - data: - mount: /etc/nginx -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - - size: 1Gi - - size: 1Gi - name: config - attributes: - persistent: true - - size: 1Gi - name: data - attributes: - persistent: true - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 1 diff --git a/sdl/_testdata/storageClass5.yaml b/sdl/_testdata/storageClass5.yaml deleted file mode 100644 index 5c280bb1d2..0000000000 --- a/sdl/_testdata/storageClass5.yaml +++ /dev/null @@ -1,51 +0,0 @@ ---- -version: "2.0" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp - params: - storage: -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - - size: "1Gi" - - size: 1Gi - name: configs - attributes: - persistent: true - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 1 diff --git a/sdl/_testdata/storageClass6.yaml b/sdl/_testdata/storageClass6.yaml deleted file mode 100644 index fccfb944c9..0000000000 --- a/sdl/_testdata/storageClass6.yaml +++ /dev/null @@ -1,53 +0,0 @@ ---- -version: "2.0" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp - params: - storage: - configs: - mount: /test -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - - size: "1Gi" - - size: 1Gi - name: configs - attributes: - persistent: true - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 1 diff --git a/sdl/_testdata/v2.1-credentials-error.yaml b/sdl/_testdata/v2.1-credentials-error.yaml deleted file mode 100644 index 83e3fc24df..0000000000 --- a/sdl/_testdata/v2.1-credentials-error.yaml +++ /dev/null @@ -1,48 +0,0 @@ ---- -version: "2.1" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp - credentials: - username: "foo" - password: "foo" -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 2 diff --git a/sdl/_testdata/v2.1-credentials.yaml b/sdl/_testdata/v2.1-credentials.yaml deleted file mode 100644 index 63622b0a61..0000000000 --- a/sdl/_testdata/v2.1-credentials.yaml +++ /dev/null @@ -1,49 +0,0 @@ ---- -version: "2.1" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp - credentials: - host: "https://test.com/v1" - username: "foo" - password: "foo" -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 2 diff --git a/sdl/_testdata/v2.1-deployment-svc-mismatch.yaml b/sdl/_testdata/v2.1-deployment-svc-mismatch.yaml deleted file mode 100644 index 59e98e0038..0000000000 --- a/sdl/_testdata/v2.1-deployment-svc-mismatch.yaml +++ /dev/null @@ -1,45 +0,0 @@ ---- -version: "2.1" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - webapp: - westcoast: - profile: web - count: 2 diff --git a/sdl/_testdata/v2.1-private_service.yaml b/sdl/_testdata/v2.1-private_service.yaml deleted file mode 100644 index e4945869fc..0000000000 --- a/sdl/_testdata/v2.1-private_service.yaml +++ /dev/null @@ -1,64 +0,0 @@ ---- -version: "2.1" -services: - bind: - image: bind9 - expose: - - port: 53 - proto: udp - to: - - global: true - - pg: - image: postgresql - expose: - - port: 5463 - to: - - service: bind - -profiles: - compute: - bind: - resources: - cpu: - units: "50m" - memory: - size: "64Mi" - storage: - size: "16Mi" - pg: - resources: - cpu: - units: "500m" - memory: - size: "512Mi" - storage: - size: "1000Mi" - - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - pg: - denom: uakt - amount: 1000 - bind: - denom: uakt - amount: 333 -deployment: - pg: - westcoast: - profile: pg - count: 1 - bind: - westcoast: - profile: bind - count: 8 diff --git a/sdl/_testdata/v2.1-profile-svc-name-mismatch.yaml b/sdl/_testdata/v2.1-profile-svc-name-mismatch.yaml deleted file mode 100644 index 3128102fab..0000000000 --- a/sdl/_testdata/v2.1-profile-svc-name-mismatch.yaml +++ /dev/null @@ -1,38 +0,0 @@ ---- -version: "2.1" - -services: - webapp: - image: ghcr.io/akash-network/demo-app - expose: - - port: 80 - as: 80 - accept: - - thehostname.com - to: - - global: true - -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "512Mi" - storage: - size: "512Mi" - placement: - san-jose: - attributes: - region: sjc - pricing: - web: - denom: uakt - amount: 25 - -deployment: - webapp: - san-jose: - profile: web - count: 1 diff --git a/sdl/_testdata/v2.1-service-mix.yaml b/sdl/_testdata/v2.1-service-mix.yaml deleted file mode 100644 index 82991aff6f..0000000000 --- a/sdl/_testdata/v2.1-service-mix.yaml +++ /dev/null @@ -1,80 +0,0 @@ ---- -version: "2.1" -services: - svca: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp - svcb: - image: nginx - expose: - - port: 80 - accept: - - bhostname.com - to: - - global: true - - port: 12346 - to: - - global: true - proto: udp - -profiles: - compute: - profilea: - resources: - cpu: - units: "100m" - gpu: - units: "1" - attributes: - vendor: - nvidia: - memory: - size: "128Mi" - storage: - - size: "1Gi" - profileb: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - blalbla: foo - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - profilea: - denom: uakt - amount: 50 - profileb: - denom: uakt - amount: 50 - -deployment: - svca: - westcoast: - profile: profilea - count: 1 - svcb: - westcoast: - profile: profileb - count: 1 diff --git a/sdl/_testdata/v2.1-service-mix2.yaml b/sdl/_testdata/v2.1-service-mix2.yaml deleted file mode 100644 index 7109fd466a..0000000000 --- a/sdl/_testdata/v2.1-service-mix2.yaml +++ /dev/null @@ -1,69 +0,0 @@ ---- -version: "2.1" -services: - svca: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp - svcb: - image: nginx - expose: - - port: 80 - accept: - - bhostname.com - to: - - global: true - - port: 12346 - to: - - global: true - proto: udp - -profiles: - compute: - profilea: - resources: - cpu: - units: "100m" - gpu: - units: "1" - attributes: - vendor: - nvidia: - memory: - size: "128Mi" - storage: - - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - blalbla: foo - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - profilea: - denom: uakt - amount: 50 - -deployment: - svca: - westcoast: - profile: profilea - count: 1 - svcb: - westcoast: - profile: profilea - count: 1 diff --git a/sdl/_testdata/v2.1-simple-gpu.yaml b/sdl/_testdata/v2.1-simple-gpu.yaml deleted file mode 100644 index cc50fd82bf..0000000000 --- a/sdl/_testdata/v2.1-simple-gpu.yaml +++ /dev/null @@ -1,52 +0,0 @@ ---- -version: "2.1" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp -profiles: - compute: - web: - resources: - cpu: - units: "100m" - gpu: - units: 1 - attributes: - vendor: - nvidia: - - model: a100 - memory: - size: "128Mi" - storage: - - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - blalbla: foo - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 2 diff --git a/sdl/_testdata/v2.1-simple-with-ip.yaml b/sdl/_testdata/v2.1-simple-with-ip.yaml deleted file mode 100644 index 4121c0e545..0000000000 --- a/sdl/_testdata/v2.1-simple-with-ip.yaml +++ /dev/null @@ -1,50 +0,0 @@ ---- -version: "2.1" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - ip: "meow" - proto: udp -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 2 - -endpoints: - meow: - kind: "ip" diff --git a/sdl/_testdata/v2.1-simple.yaml b/sdl/_testdata/v2.1-simple.yaml deleted file mode 100644 index dc1ac31515..0000000000 --- a/sdl/_testdata/v2.1-simple.yaml +++ /dev/null @@ -1,45 +0,0 @@ ---- -version: "2.1" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 2 diff --git a/sdl/_testdata/v2.1-simple2.yaml b/sdl/_testdata/v2.1-simple2.yaml deleted file mode 100644 index 08dfa81c86..0000000000 --- a/sdl/_testdata/v2.1-simple2.yaml +++ /dev/null @@ -1,64 +0,0 @@ ---- -version: "2.0" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp - bew: - image: nginx - expose: - - port: 8080 - accept: - - bhostname.com - to: - - global: true - - port: 12346 - to: - - global: true - proto: udp - - port: 12347 - to: - - global: true - proto: udp -profiles: - compute: - bew: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 - bew: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: bew - count: 2 diff --git a/sdl/_testdata/v2.1-simple3.yaml b/sdl/_testdata/v2.1-simple3.yaml deleted file mode 100644 index b4d8713a02..0000000000 --- a/sdl/_testdata/v2.1-simple3.yaml +++ /dev/null @@ -1,45 +0,0 @@ ---- -version: "2.1" - -services: - app: - image: ubuntu:22.04 - command: - - "sh" - - "-c" - args: - - 'sleep infinity' - expose: - - port: 80 - as: 80 - to: - - global: true - - port: 22 - as: 22 - to: - - global: true - -profiles: - compute: - app: - resources: - cpu: - units: 1 - memory: - size: 2Gi - storage: - size: 10Gi - placement: - akash: - attributes: - host: akash - pricing: - app: - denom: uakt - amount: 1000000 - -deployment: - app: - akash: - profile: app - count: 1 diff --git a/sdl/_testdata/v2.1-simple4.yaml b/sdl/_testdata/v2.1-simple4.yaml deleted file mode 100644 index 6a899a90c7..0000000000 --- a/sdl/_testdata/v2.1-simple4.yaml +++ /dev/null @@ -1,90 +0,0 @@ ---- -version: '2.1' -services: - wordpress: - image: wordpress - depends_on: - - db - expose: - - port: 80 - http_options: - max_body_size: 104857600 - # accept: - # - "example.com" - to: - - global: true - env: - - WORDPRESS_DB_HOST=db - - WORDPRESS_DB_USER=wordpress - - WORDPRESS_DB_PASSWORD=testpass4you - - WORDPRESS_DB_NAME=wordpress - params: - storage: - wordpress-data: - mount: /var/www/html - readOnly: false - db: - # We use a mariadb image which supports both amd64 & arm64 architecture - image: mariadb:10.6.4 - # If you really want to use MySQL, uncomment the following line - #image: mysql:8.0.27 - expose: - - port: 3306 - to: - - service: wordpress - env: - - MYSQL_RANDOM_ROOT_PASSWORD=1 - - MYSQL_DATABASE=wordpress - - MYSQL_USER=wordpress - - MYSQL_PASSWORD=testpass4you - params: - storage: - wordpress-db: - mount: /var/lib/mysql - readOnly: false -profiles: - compute: - wordpress: - resources: - cpu: - units: 1 - memory: - size: 1Gi - storage: - - size: 1Gi - - name: wordpress-data - size: 1Gi - attributes: - persistent: true - class: beta3 - db: - resources: - cpu: - units: 1 - memory: - size: 1Gi - storage: - - size: 1Gi - - name: wordpress-db - size: 1Gi - attributes: - persistent: true - class: beta3 - placement: - akash: - pricing: - wordpress: - denom: uakt - amount: 10000 - db: - denom: uakt - amount: 10000 -deployment: - wordpress: - akash: - profile: wordpress - count: 1 - db: - akash: - profile: db - count: 1 diff --git a/sdl/coin.go b/sdl/coin.go deleted file mode 100644 index 70d1f02b04..0000000000 --- a/sdl/coin.go +++ /dev/null @@ -1,53 +0,0 @@ -package sdl - -import ( - "errors" - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" - "gopkg.in/yaml.v3" -) - -// v2Coin is an alias sdk.Coin to allow our custom UnmarshalYAML -// for now it supports PoC when actual pricing is specified as two fields -// aka amount and denom. we let UnmarshalYAML to deal with that and put result -// into Value field. -// discussion https://github.com/akash-network/node/issues/771 -type v2Coin struct { - Value sdk.DecCoin `yaml:"-"` -} - -var errInvalidCoinAmount = errors.New("invalid coin amount") - -func (sdl *v2Coin) UnmarshalYAML(node *yaml.Node) error { - parsedCoin := struct { - Amount string `yaml:"amount"` - Denom string `yaml:"denom"` - }{} - - if err := node.Decode(&parsedCoin); err != nil { - return err - } - - amount, err := sdk.NewDecFromStr(parsedCoin.Amount) - if err != nil { - return err - } - - if amount.IsZero() { - return fmt.Errorf("%w: amount is zero", errInvalidCoinAmount) - } - - // Never pass negative amounts to cosmos SDK DecCoin - if amount.IsNegative() { - return fmt.Errorf("%w: amount %q is negative", errNegativeValue, amount.String()) - } - - coin := sdk.NewDecCoinFromDec(parsedCoin.Denom, amount) - - *sdl = v2Coin{ - Value: coin, - } - - return nil -} diff --git a/sdl/coin_test.go b/sdl/coin_test.go deleted file mode 100644 index e44dcdebd9..0000000000 --- a/sdl/coin_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package sdl - -import ( - "github.com/stretchr/testify/require" - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/assert" - "gopkg.in/yaml.v3" -) - -func TestPricing(t *testing.T) { - lessThanOne, err := sdk.NewDecFromStr("0.7") - require.NoError(t, err) - tests := []struct { - text string - value sdk.DecCoin - err bool - }{ - {"amount: 1\ndenom: uakt", sdk.NewDecCoin("uakt", sdk.NewInt(1)), false}, - {"amount: -1\ndenom: uakt", sdk.NewDecCoin("uakt", sdk.NewInt(1)), true}, - {"amount: 0.7\ndenom: uakt", sdk.NewDecCoinFromDec("uakt", lessThanOne), false}, - {"amount: -0.7\ndenom: uakt", sdk.NewDecCoin("uakt", sdk.NewInt(0)), true}, - } - - for idx, test := range tests { - buf := []byte(test.text) - obj := &v2Coin{} - - err := yaml.Unmarshal(buf, obj) - - if test.err { - assert.Error(t, err, "idx:%v text:`%v`", idx, test.text) - continue - } - - if !assert.NoError(t, err, "idx:%v text:`%v`", idx, test.text) { - continue - } - - assert.Equal(t, test.value, obj.Value, "idx:%v text:`%v`", idx, test.text) - } -} diff --git a/sdl/cpu.go b/sdl/cpu.go deleted file mode 100644 index 37560fb348..0000000000 --- a/sdl/cpu.go +++ /dev/null @@ -1,47 +0,0 @@ -package sdl - -import ( - "fmt" - "sort" - - "gopkg.in/yaml.v3" - - types "github.com/akash-network/akash-api/go/node/types/v1beta3" -) - -type v2CPUAttributes types.Attributes - -type v2ResourceCPU struct { - Units cpuQuantity `yaml:"units"` - Attributes v2CPUAttributes `yaml:"attributes,omitempty"` -} - -func (sdl *v2CPUAttributes) UnmarshalYAML(node *yaml.Node) error { - var attr v2CPUAttributes - - for i := 0; i+1 < len(node.Content); i += 2 { - var value string - switch node.Content[i].Value { - case "arch": - if err := node.Content[i+1].Decode(&value); err != nil { - return err - } - default: - return fmt.Errorf("unsupported cpu attribute \"%s\"", node.Content[i].Value) - } - - attr = append(attr, types.Attribute{ - Key: node.Content[i].Value, - Value: value, - }) - } - - // keys are unique in attributes parsed from sdl so don't need to use sort.SliceStable - sort.Slice(attr, func(i, j int) bool { - return attr[i].Key < attr[j].Key - }) - - *sdl = attr - - return nil -} diff --git a/sdl/cpu_test.go b/sdl/cpu_test.go deleted file mode 100644 index 2e896f1abd..0000000000 --- a/sdl/cpu_test.go +++ /dev/null @@ -1,24 +0,0 @@ -package sdl - -import ( - "testing" - - "github.com/stretchr/testify/require" - "gopkg.in/yaml.v3" -) - -func TestV2ResourceCPU_Valid(t *testing.T) { - var stream = ` -units: 0.1 -attributes: - arch: amd64 -` - var p v2ResourceCPU - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) - require.Equal(t, cpuQuantity(100), p.Units) - require.Equal(t, 1, len(p.Attributes)) - require.Equal(t, "arch", p.Attributes[0].Key) - require.Equal(t, "amd64", p.Attributes[0].Value) -} diff --git a/sdl/expose.go b/sdl/expose.go deleted file mode 100644 index 23e26f96c1..0000000000 --- a/sdl/expose.go +++ /dev/null @@ -1,114 +0,0 @@ -package sdl - -import ( - "net/url" - "sort" - - manifest "github.com/akash-network/akash-api/go/manifest/v2beta2" - "gopkg.in/yaml.v3" -) - -type v2Accept struct { - Items []string `yaml:"items,omitempty"` -} - -func (p *v2Accept) UnmarshalYAML(node *yaml.Node) error { - var accept []string - if err := node.Decode(&accept); err != nil { - return err - } - - for _, item := range accept { - if _, err := url.ParseRequestURI("http://" + item); err != nil { - return err - } - } - - p.Items = accept - - return nil -} - -func (sdl v2Exposes) toManifestExpose(endpointNames map[string]uint32) (manifest.ServiceExposes, error) { - exposeCount := 0 - for _, expose := range sdl { - if len(expose.To) > 0 { - exposeCount += len(expose.To) - } else { - exposeCount++ - } - } - - res := make(manifest.ServiceExposes, 0, exposeCount) - - for _, expose := range sdl { - exp, err := expose.toManifestExposes(endpointNames) - if err != nil { - return nil, err - } - - res = append(res, exp...) - } - - sort.Sort(res) - - return res, nil -} - -func (sdl v2Expose) toManifestExposes(endpointNames map[string]uint32) (manifest.ServiceExposes, error) { - exposeCount := len(sdl.To) - if exposeCount == 0 { - exposeCount = 1 - } - - res := make(manifest.ServiceExposes, 0, exposeCount) - - proto, err := manifest.ParseServiceProtocol(sdl.Proto) - if err != nil { - return nil, err - } - - httpOptions, err := sdl.HTTPOptions.asManifest() - if err != nil { - return nil, err - } - - if len(sdl.To) > 0 { - for _, to := range sdl.To { - // This value is created just so it can be passed to the utility function - expose := manifest.ServiceExpose{ - Service: to.Service, - Port: sdl.Port, - ExternalPort: sdl.As, - Proto: proto, - Global: to.Global, - Hosts: sdl.Accept.Items, - HTTPOptions: httpOptions, - IP: to.IP, - } - - // Check to see if an IP endpoint is also specified - if expose.Global && len(expose.IP) != 0 { - seqNo := endpointNames[expose.IP] - expose.EndpointSequenceNumber = seqNo - } - - res = append(res, expose) - } - } else { - expose := manifest.ServiceExpose{ - Service: "", - Port: sdl.Port, - ExternalPort: sdl.As, - Proto: proto, - Global: false, - Hosts: sdl.Accept.Items, - HTTPOptions: httpOptions, - IP: "", - } - - res = append(res, expose) - } - - return res, nil -} diff --git a/sdl/full_test.go b/sdl/full_test.go deleted file mode 100644 index 108710f330..0000000000 --- a/sdl/full_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package sdl - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestFull(t *testing.T) { - stream := ` -version: "2.0" -services: - web: - image: ghcr.io/akash-network/demo-app - expose: - - port: 80 - as: 80 - accept: - - hello.localhost - to: - - global: true - params: - storage: - data: - mount: "/var/lib/demo-app/data" -profiles: - compute: - web: - resources: - cpu: - units: 0.1 - attributes: - arch: amd64 - gpu: - units: 1 - attributes: - vendor: - nvidia: - - model: a100 - memory: - size: 16Mi - storage: - - size: 128Mi - - name: data - size: 1Gi - attributes: - persistent: true - class: default - placement: - westcoast: - attributes: - region: us-west - pricing: - web: - amount: 1 - denom: uakt -deployment: - web: - westcoast: - profile: web - count: 1 -` - - _, err := Read([]byte(stream)) - require.NoError(t, err) -} diff --git a/sdl/gpu.go b/sdl/gpu.go deleted file mode 100644 index 54833b347a..0000000000 --- a/sdl/gpu.go +++ /dev/null @@ -1,131 +0,0 @@ -package sdl - -import ( - "fmt" - "sort" - - "gopkg.in/yaml.v3" - - types "github.com/akash-network/akash-api/go/node/types/v1beta3" -) - -type gpuInterface string - -type v2GPUNvidia struct { - Model string `yaml:"model"` - RAM *memoryQuantity `yaml:"ram,omitempty"` - Interface *gpuInterface `yaml:"interface,omitempty"` -} - -func (sdl *v2GPUNvidia) String() string { - key := sdl.Model - if sdl.RAM != nil { - key = fmt.Sprintf("%s/ram/%s", key, sdl.RAM.StringWithSuffix("Gi")) - } - - if sdl.Interface != nil { - key = fmt.Sprintf("%s/interface/%s", key, *sdl.Interface) - } - - return key -} - -type v2GPUsNvidia []v2GPUNvidia - -type gpuVendor struct { - Nvidia v2GPUsNvidia `yaml:"nvidia,omitempty"` -} - -type v2GPUAttributes types.Attributes - -type v2ResourceGPU struct { - Units gpuQuantity `yaml:"units" json:"units"` - Attributes v2GPUAttributes `yaml:"attributes,omitempty" json:"attributes,omitempty"` -} - -func (sdl *v2ResourceGPU) UnmarshalYAML(node *yaml.Node) error { - res := v2ResourceGPU{} - - for i := 0; i < len(node.Content); i += 2 { - switch node.Content[i].Value { - case "units": - if err := node.Content[i+1].Decode(&res.Units); err != nil { - return err - } - case "attributes": - if err := node.Content[i+1].Decode(&res.Attributes); err != nil { - return err - } - default: - return fmt.Errorf("sdl: unsupported field (%s) for GPU resource", node.Content[i].Value) - } - } - - if res.Units > 0 && len(res.Attributes) == 0 { - return fmt.Errorf("sdl: GPU attributes must be present if units > 0") - } - - *sdl = res - - return nil -} - -func (sdl *v2GPUAttributes) UnmarshalYAML(node *yaml.Node) error { - var res types.Attributes - - var vendor *gpuVendor - - for i := 0; i < len(node.Content); i += 2 { - switch node.Content[i].Value { - case "vendor": - if err := node.Content[i+1].Decode(&vendor); err != nil { - return err - } - default: - return fmt.Errorf("sdl: unsupported attribute (%s) for GPU resource", node.Content[i].Value) - } - } - - if vendor == nil { - return fmt.Errorf("sdl: invalid GPU attributes. at least one vendor must be set") - } - - res = make(types.Attributes, 0, len(vendor.Nvidia)) - - for _, model := range vendor.Nvidia { - res = append(res, types.Attribute{ - Key: fmt.Sprintf("vendor/nvidia/model/%s", model.String()), - Value: "true", - }) - } - - if len(res) == 0 { - res = append(res, types.Attribute{ - Key: "vendor/nvidia/model/*", - Value: "true", - }) - } - - sort.Sort(res) - - if err := res.Validate(); err != nil { - return fmt.Errorf("sdl: invalid GPU attributes: %w", err) - } - - *sdl = v2GPUAttributes(res) - - return nil -} - -func (sdl *gpuInterface) UnmarshalYAML(node *yaml.Node) error { - switch node.Value { - case "pcie": - case "sxm": - default: - return fmt.Errorf("sdl: invalid GPU interface %s. expected \"pcie|sxm\"", node.Value) - } - - *sdl = gpuInterface(node.Value) - - return nil -} diff --git a/sdl/gpu_test.go b/sdl/gpu_test.go deleted file mode 100644 index 8277fbc760..0000000000 --- a/sdl/gpu_test.go +++ /dev/null @@ -1,190 +0,0 @@ -package sdl - -import ( - "testing" - - "github.com/stretchr/testify/require" - "gopkg.in/yaml.v3" -) - -func TestV2ResourceGPU_EmptyVendor(t *testing.T) { - var stream = ` -units: 1 -attributes: - vendor: -` - var p v2ResourceGPU - - err := yaml.Unmarshal([]byte(stream), &p) - require.Error(t, err) -} - -func TestV2ResourceGPU_Wildcard(t *testing.T) { - var stream = ` -units: 1 -attributes: - vendor: - nvidia: -` - var p v2ResourceGPU - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) - require.Equal(t, gpuQuantity(1), p.Units) - require.Equal(t, 1, len(p.Attributes)) - require.Equal(t, "vendor/nvidia/model/*", p.Attributes[0].Key) - require.Equal(t, "true", p.Attributes[0].Value) -} - -func TestV2ResourceGPU_SingleModel(t *testing.T) { - var stream = ` -units: 1 -attributes: - vendor: - nvidia: - - model: a100 -` - var p v2ResourceGPU - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) - require.Equal(t, gpuQuantity(1), p.Units) - require.Equal(t, 1, len(p.Attributes)) - require.Equal(t, "vendor/nvidia/model/a100", p.Attributes[0].Key) - require.Equal(t, "true", p.Attributes[0].Value) -} - -func TestV2ResourceGPU_SingleModelWithRAM(t *testing.T) { - var stream = ` -units: 1 -attributes: - vendor: - nvidia: - - model: a100 - ram: 80Gi -` - var p v2ResourceGPU - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) - require.Equal(t, gpuQuantity(1), p.Units) - require.Equal(t, 1, len(p.Attributes)) - require.Equal(t, "vendor/nvidia/model/a100/ram/80Gi", p.Attributes[0].Key) - require.Equal(t, "true", p.Attributes[0].Value) -} - -func TestV2ResourceGPU_InvalidRAMUnit(t *testing.T) { - var stream = ` -units: 1 -attributes: - vendor: - nvidia: - - model: a100 - ram: 80G -` - var p v2ResourceGPU - - err := yaml.Unmarshal([]byte(stream), &p) - require.Error(t, err) -} - -func TestV2ResourceGPU_InterfaceInvalid(t *testing.T) { - var stream = ` -units: 1 -attributes: - vendor: - nvidia: - - model: a100 - interface: pciex -` - var p v2ResourceGPU - - err := yaml.Unmarshal([]byte(stream), &p) - require.Error(t, err) -} - -func TestV2ResourceGPU_RamWithInterface(t *testing.T) { - var stream = ` -units: 1 -attributes: - vendor: - nvidia: - - model: a100 - ram: 80Gi - interface: pcie -` - var p v2ResourceGPU - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) - require.Equal(t, gpuQuantity(1), p.Units) - require.Equal(t, 1, len(p.Attributes)) - require.Equal(t, "vendor/nvidia/model/a100/ram/80Gi/interface/pcie", p.Attributes[0].Key) - require.Equal(t, "true", p.Attributes[0].Value) -} - -func TestV2ResourceGPU_MultipleModels(t *testing.T) { - var stream = ` -units: 1 -attributes: - vendor: - nvidia: - - model: a100 - ram: 80Gi - - model: a100 - ram: 40Gi -` - var p v2ResourceGPU - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) - require.Equal(t, gpuQuantity(1), p.Units) - require.Equal(t, 2, len(p.Attributes)) - require.Equal(t, "vendor/nvidia/model/a100/ram/40Gi", p.Attributes[0].Key) - require.Equal(t, "true", p.Attributes[0].Value) - require.Equal(t, "vendor/nvidia/model/a100/ram/80Gi", p.Attributes[1].Key) - require.Equal(t, "true", p.Attributes[1].Value) -} - -func TestV2ResourceGPU_MultipleModels2(t *testing.T) { - var stream = ` -units: 1 -attributes: - vendor: - nvidia: - - model: a100 - ram: 80Gi - - model: a100 -` - var p v2ResourceGPU - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) - require.Equal(t, gpuQuantity(1), p.Units) - require.Equal(t, 2, len(p.Attributes)) - require.Equal(t, "vendor/nvidia/model/a100", p.Attributes[0].Key) - require.Equal(t, "true", p.Attributes[0].Value) - require.Equal(t, "vendor/nvidia/model/a100/ram/80Gi", p.Attributes[1].Key) - require.Equal(t, "true", p.Attributes[1].Value) -} - -func TestV2ResourceGPU_MultipleModels3(t *testing.T) { - var stream = ` -units: 1 -attributes: - vendor: - nvidia: - - model: a6000 - - model: a40 -` - var p v2ResourceGPU - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) - require.Equal(t, gpuQuantity(1), p.Units) - require.Equal(t, 2, len(p.Attributes)) - require.Equal(t, "vendor/nvidia/model/a40", p.Attributes[0].Key) - require.Equal(t, "true", p.Attributes[0].Value) - require.Equal(t, "vendor/nvidia/model/a6000", p.Attributes[1].Key) - require.Equal(t, "true", p.Attributes[1].Value) -} diff --git a/sdl/groupBuilder_v2.go b/sdl/groupBuilder_v2.go deleted file mode 100644 index 3d9911ed46..0000000000 --- a/sdl/groupBuilder_v2.go +++ /dev/null @@ -1,149 +0,0 @@ -package sdl - -import ( - "sort" - - manifest "github.com/akash-network/akash-api/go/manifest/v2beta2" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/types/v1beta3" -) - -type groupsBuilderV2 struct { - dgroup *dtypes.GroupSpec - mgroup *manifest.Group - boundComputes map[string]map[string]int -} - -// buildGroups -func (sdl *v2) buildGroups() error { - endpointsNames := sdl.computeEndpointSequenceNumbers() - - groups := make(map[string]*groupsBuilderV2) - - for _, svcName := range sdl.Deployments.svcNames() { - depl := sdl.Deployments[svcName] - - for _, placementName := range depl.placementNames() { - // objects below have been ensured to exist - svcdepl := depl[placementName] - compute := sdl.Profiles.Compute[svcdepl.Profile] - svc := sdl.Services[svcName] - infra := sdl.Profiles.Placement[placementName] - price := infra.Pricing[svcdepl.Profile] - - group := groups[placementName] - - if group == nil { - group = &groupsBuilderV2{ - dgroup: &dtypes.GroupSpec{ - Name: placementName, - }, - mgroup: &manifest.Group{ - Name: placementName, - }, - boundComputes: make(map[string]map[string]int), - } - - group.dgroup.Requirements.Attributes = types.Attributes(infra.Attributes) - group.dgroup.Requirements.SignedBy = infra.SignedBy - - // keep ordering stable - sort.Sort(group.dgroup.Requirements.Attributes) - - groups[placementName] = group - } - - if _, exists := group.boundComputes[placementName]; !exists { - group.boundComputes[placementName] = make(map[string]int) - } - - expose, err := sdl.Services[svcName].Expose.toManifestExpose(endpointsNames) - if err != nil { - return err - } - - resources := compute.Resources.toResources() - resources.Endpoints = expose.GetEndpoints() - - res := compute.Resources.toResources() - res.Endpoints = expose.GetEndpoints() - - var resID int - if ln := len(group.dgroup.Resources); ln > 0 { - resID = ln + 1 - } else { - resID = 1 - } - - res.ID = uint32(resID) - resources.ID = res.ID - - group.dgroup.Resources = append(group.dgroup.Resources, dtypes.ResourceUnit{ - Resources: res, - Price: price.Value, - Count: svcdepl.Count, - }) - - group.boundComputes[placementName][svcdepl.Profile] = len(group.dgroup.Resources) - 1 - - msvc := manifest.Service{ - Name: svcName, - Image: svc.Image, - Args: svc.Args, - Env: svc.Env, - Resources: resources, - Count: svcdepl.Count, - Command: svc.Command, - Expose: expose, - } - - if svc.Params != nil { - params := &manifest.ServiceParams{} - - if len(svc.Params.Storage) > 0 { - params.Storage = make([]manifest.StorageParams, 0, len(svc.Params.Storage)) - for volName, volParams := range svc.Params.Storage { - params.Storage = append(params.Storage, manifest.StorageParams{ - Name: volName, - Mount: volParams.Mount, - ReadOnly: volParams.ReadOnly, - }) - } - } - - msvc.Params = params - } - - if svc.Credentials != nil { - msvc.Credentials = &manifest.ServiceImageCredentials{ - Host: svc.Credentials.Host, - Username: svc.Credentials.Username, - Password: svc.Credentials.Password, - } - } - - group.mgroup.Services = append(group.mgroup.Services, msvc) - } - } - - // keep ordering stable - names := make([]string, 0, len(groups)) - for name := range groups { - names = append(names, name) - } - sort.Strings(names) - - sdl.result.dgroups = make(dtypes.GroupSpecs, 0, len(names)) - sdl.result.mgroups = make(manifest.Groups, 0, len(names)) - - for _, name := range names { - mgroup := *groups[name].mgroup - // stable ordering services by name - sort.Sort(mgroup.Services) - - sdl.result.dgroups = append(sdl.result.dgroups, groups[name].dgroup) - sdl.result.mgroups = append(sdl.result.mgroups, mgroup) - } - - return nil -} diff --git a/sdl/groupBuilder_v2_1.go b/sdl/groupBuilder_v2_1.go deleted file mode 100644 index e39143449e..0000000000 --- a/sdl/groupBuilder_v2_1.go +++ /dev/null @@ -1,160 +0,0 @@ -package sdl - -import ( - "sort" - "strings" - - manifest "github.com/akash-network/akash-api/go/manifest/v2beta2" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/types/v1beta3" -) - -type groupsBuilderV2_1 struct { - dgroup *dtypes.GroupSpec - mgroup *manifest.Group - boundComputes map[string]map[string]int -} - -// buildGroups -func (sdl *v2_1) buildGroups() error { - endpointsNames := sdl.computeEndpointSequenceNumbers() - - groups := make(map[string]*groupsBuilderV2_1) - - for _, svcName := range sdl.Deployments.svcNames() { - depl := sdl.Deployments[svcName] - - for _, placementName := range depl.placementNames() { - // objects below have been ensured to exist - svcdepl := depl[placementName] - compute := sdl.Profiles.Compute[svcdepl.Profile] - svc := sdl.Services[svcName] - infra := sdl.Profiles.Placement[placementName] - price := infra.Pricing[svcdepl.Profile] - - group := groups[placementName] - - if group == nil { - group = &groupsBuilderV2_1{ - dgroup: &dtypes.GroupSpec{ - Name: placementName, - }, - mgroup: &manifest.Group{ - Name: placementName, - }, - boundComputes: make(map[string]map[string]int), - } - - group.dgroup.Requirements.Attributes = types.Attributes(infra.Attributes) - group.dgroup.Requirements.SignedBy = infra.SignedBy - - // keep ordering stable - sort.Sort(group.dgroup.Requirements.Attributes) - - groups[placementName] = group - } - - if _, exists := group.boundComputes[placementName]; !exists { - group.boundComputes[placementName] = make(map[string]int) - } - - expose, err := sdl.Services[svcName].Expose.toManifestExpose(endpointsNames) - if err != nil { - return err - } - - resources := compute.Resources.toResources() - resources.Endpoints = expose.GetEndpoints() - - if location, bound := group.boundComputes[placementName][svcdepl.Profile]; !bound { - res := compute.Resources.toResources() - res.Endpoints = expose.GetEndpoints() - - var resID int - if ln := len(group.dgroup.Resources); ln > 0 { - resID = ln + 1 - } else { - resID = 1 - } - - res.ID = uint32(resID) - resources.ID = res.ID - - group.dgroup.Resources = append(group.dgroup.Resources, dtypes.ResourceUnit{ - Resources: res, - Price: price.Value, - Count: svcdepl.Count, - }) - - group.boundComputes[placementName][svcdepl.Profile] = len(group.dgroup.Resources) - 1 - } else { - resources.ID = group.dgroup.Resources[location].ID - - group.dgroup.Resources[location].Count += svcdepl.Count - group.dgroup.Resources[location].Endpoints = append(group.dgroup.Resources[location].Endpoints, expose.GetEndpoints()...) - - sort.Sort(group.dgroup.Resources[location].Endpoints) - } - - msvc := manifest.Service{ - Name: svcName, - Image: svc.Image, - Args: svc.Args, - Env: svc.Env, - Resources: resources, - Count: svcdepl.Count, - Command: svc.Command, - Expose: expose, - } - - if svc.Params != nil { - params := &manifest.ServiceParams{} - - if len(svc.Params.Storage) > 0 { - params.Storage = make([]manifest.StorageParams, 0, len(svc.Params.Storage)) - for volName, volParams := range svc.Params.Storage { - params.Storage = append(params.Storage, manifest.StorageParams{ - Name: volName, - Mount: volParams.Mount, - ReadOnly: volParams.ReadOnly, - }) - } - } - - msvc.Params = params - } - - if svc.Credentials != nil { - msvc.Credentials = &manifest.ServiceImageCredentials{ - Host: strings.TrimSpace(svc.Credentials.Host), - Email: strings.TrimSpace(svc.Credentials.Email), - Username: strings.TrimSpace(svc.Credentials.Username), - Password: strings.TrimSpace(svc.Credentials.Password), - } - } - - group.mgroup.Services = append(group.mgroup.Services, msvc) - } - } - - // keep ordering stable - names := make([]string, 0, len(groups)) - for name := range groups { - names = append(names, name) - } - sort.Strings(names) - - sdl.result.dgroups = make(dtypes.GroupSpecs, 0, len(names)) - sdl.result.mgroups = make(manifest.Groups, 0, len(names)) - - for _, name := range names { - mgroup := *groups[name].mgroup - // stable ordering services by name - sort.Sort(mgroup.Services) - - sdl.result.dgroups = append(sdl.result.dgroups, groups[name].dgroup) - sdl.result.mgroups = append(sdl.result.mgroups, mgroup) - } - - return nil -} diff --git a/sdl/memory.go b/sdl/memory.go deleted file mode 100644 index af55ffb82f..0000000000 --- a/sdl/memory.go +++ /dev/null @@ -1,42 +0,0 @@ -package sdl - -import ( - "sort" - - "gopkg.in/yaml.v3" - - types "github.com/akash-network/akash-api/go/node/types/v1beta3" -) - -type v2MemoryAttributes types.Attributes - -type v2ResourceMemory struct { - Quantity byteQuantity `yaml:"size"` - Attributes v2MemoryAttributes `yaml:"-"` -} - -func (sdl *v2MemoryAttributes) UnmarshalYAML(node *yaml.Node) error { - var attr v2MemoryAttributes - - var res map[string]string - - if err := node.Decode(&res); err != nil { - return err - } - - for k, v := range res { - attr = append(attr, types.Attribute{ - Key: k, - Value: v, - }) - } - - // keys are unique in attributes parsed from sdl so don't need to use sort.SliceStable - sort.Slice(attr, func(i, j int) bool { - return attr[i].Key < attr[j].Key - }) - - *sdl = attr - - return nil -} diff --git a/sdl/placement.go b/sdl/placement.go deleted file mode 100644 index a935862573..0000000000 --- a/sdl/placement.go +++ /dev/null @@ -1,37 +0,0 @@ -package sdl - -import ( - "sort" - - "gopkg.in/yaml.v3" - - types "github.com/akash-network/akash-api/go/node/types/v1beta3" -) - -type v2PlacementAttributes types.Attributes - -func (sdl *v2PlacementAttributes) UnmarshalYAML(node *yaml.Node) error { - var attr v2PlacementAttributes - - var res map[string]string - - if err := node.Decode(&res); err != nil { - return err - } - - for k, v := range res { - attr = append(attr, types.Attribute{ - Key: k, - Value: v, - }) - } - - // keys are unique in attributes parsed from sdl so don't need to use sort.SliceStable - sort.Slice(attr, func(i, j int) bool { - return attr[i].Key < attr[j].Key - }) - - *sdl = attr - - return nil -} diff --git a/sdl/pricing.go b/sdl/pricing.go deleted file mode 100644 index db2f19781c..0000000000 --- a/sdl/pricing.go +++ /dev/null @@ -1,4 +0,0 @@ -package sdl - -// todo should pricing values be in form of range? -type v2PlacementPricing map[string]v2Coin diff --git a/sdl/resources.go b/sdl/resources.go deleted file mode 100644 index 2efa9f5fd2..0000000000 --- a/sdl/resources.go +++ /dev/null @@ -1,59 +0,0 @@ -package sdl - -import ( - types "github.com/akash-network/akash-api/go/node/types/v1beta3" -) - -type v2ComputeResources struct { - CPU *v2ResourceCPU `yaml:"cpu"` - GPU *v2ResourceGPU `yaml:"gpu"` - Memory *v2ResourceMemory `yaml:"memory"` - Storage v2ResourceStorageArray `yaml:"storage"` -} - -func (sdl *v2ComputeResources) toResources() types.Resources { - if sdl == nil { - return types.Resources{} - } - - units := types.Resources{ - Endpoints: types.Endpoints{}, - } - - if sdl.CPU != nil { - units.CPU = &types.CPU{ - Units: types.NewResourceValue(uint64(sdl.CPU.Units)), - Attributes: types.Attributes(sdl.CPU.Attributes), - } - } - - if sdl.GPU != nil { - units.GPU = &types.GPU{ - Units: types.NewResourceValue(uint64(sdl.GPU.Units)), - Attributes: types.Attributes(sdl.GPU.Attributes), - } - } else { - units.GPU = &types.GPU{ - Units: types.NewResourceValue(0), - } - } - - if sdl.Memory != nil { - units.Memory = &types.Memory{ - Quantity: types.NewResourceValue(uint64(sdl.Memory.Quantity)), - Attributes: types.Attributes(sdl.Memory.Attributes), - } - } - - for _, storage := range sdl.Storage { - storageEntry := types.Storage{ - Name: storage.Name, - Quantity: types.NewResourceValue(uint64(storage.Quantity)), - Attributes: types.Attributes(storage.Attributes), - } - - units.Storage = append(units.Storage, storageEntry) - } - - return units -} diff --git a/sdl/sdl.go b/sdl/sdl.go deleted file mode 100644 index bb4bf398ab..0000000000 --- a/sdl/sdl.go +++ /dev/null @@ -1,159 +0,0 @@ -package sdl - -import ( - "errors" - "fmt" - "os" - - "github.com/blang/semver/v4" - "gopkg.in/yaml.v3" - - manifest "github.com/akash-network/akash-api/go/manifest/v2beta2" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" -) - -const ( - sdlVersionField = "version" -) - -var ( - errUninitializedConfig = errors.New("sdl: uninitialized") - errSDLInvalidNoVersion = fmt.Errorf("%w: no version found", errSDLInvalid) -) - -// SDL is the interface which wraps Validate, Deployment and Manifest methods -type SDL interface { - DeploymentGroups() (dtypes.GroupSpecs, error) - Manifest() (manifest.Manifest, error) - Version() ([]byte, error) - validate() error -} - -var _ SDL = (*sdl)(nil) - -type sdl struct { - Ver semver.Version `yaml:"version,-"` - data SDL `yaml:"-"` -} - -func (s *sdl) UnmarshalYAML(node *yaml.Node) error { - var result sdl - - foundVersion := false - for idx := range node.Content { - if node.Content[idx].Value == sdlVersionField { - var err error - if result.Ver, err = semver.ParseTolerant(node.Content[idx+1].Value); err != nil { - return err - } - foundVersion = true - break - } - } - - if !foundVersion { - return errSDLInvalidNoVersion - } - - // nolint: gocritic - if result.Ver.EQ(semver.MustParse("2.0.0")) { - var decoded v2 - if err := node.Decode(&decoded); err != nil { - return err - } - - result.data = &decoded - } else if result.Ver.GE(semver.MustParse("2.1.0")) { - var decoded v2_1 - if err := node.Decode(&decoded); err != nil { - return err - } - - result.data = &decoded - } else { - return fmt.Errorf("%w: config: unsupported version %q", errSDLInvalid, result.Ver) - } - - *s = result - - return nil -} - -// ReadFile read from given path and returns SDL instance -func ReadFile(path string) (SDL, error) { - buf, err := os.ReadFile(path) - if err != nil { - return nil, err - } - return Read(buf) -} - -// Read reads buffer data and returns SDL instance -func Read(buf []byte) (SDL, error) { - obj := &sdl{} - if err := yaml.Unmarshal(buf, obj); err != nil { - return nil, err - } - - if err := obj.validate(); err != nil { - return nil, err - } - - dgroups, err := obj.DeploymentGroups() - if err != nil { - return nil, err - } - - vgroups := make([]dtypes.GroupSpec, 0, len(dgroups)) - for _, dgroup := range dgroups { - vgroups = append(vgroups, *dgroup) - } - - if err := dtypes.ValidateDeploymentGroups(vgroups); err != nil { - return nil, err - } - - m, err := obj.Manifest() - if err != nil { - return nil, err - } - - if err := m.Validate(); err != nil { - return nil, err - } - - return obj, nil -} - -// Version creates the deterministic Deployment Version hash from the SDL. -func (s *sdl) Version() ([]byte, error) { - if s.data == nil { - return nil, errUninitializedConfig - } - - return s.data.Version() -} - -func (s *sdl) DeploymentGroups() (dtypes.GroupSpecs, error) { - if s.data == nil { - return dtypes.GroupSpecs{}, errUninitializedConfig - } - - return s.data.DeploymentGroups() -} - -func (s *sdl) Manifest() (manifest.Manifest, error) { - if s.data == nil { - return manifest.Manifest{}, errUninitializedConfig - } - - return s.data.Manifest() -} - -func (s *sdl) validate() error { - if s.data == nil { - return errUninitializedConfig - } - - return s.data.validate() -} diff --git a/sdl/sdl_test.go b/sdl/sdl_test.go deleted file mode 100644 index 2cc5821b96..0000000000 --- a/sdl/sdl_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package sdl - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestSDLManifestVersion(t *testing.T) { - obj, err := ReadFile("_testdata/simple.yaml") - require.NoError(t, err) - - m, err := obj.Manifest() - require.NoError(t, err) - - version, err := m.Version() - require.NoError(t, err) - // Should return a value - require.NotEmpty(t, version) - - obj, err = ReadFile("_testdata/private_service.yaml") - require.NoError(t, err) - - m, err = obj.Manifest() - require.NoError(t, err) - - secondVersion, err := m.Version() - require.NoError(t, err) - // Should return a value - require.NotEmpty(t, secondVersion) - // Should be different from the first - require.NotEqual(t, secondVersion, version) -} - -func TestSDLManifestVersionChangesWithVersion(t *testing.T) { - obj, err := ReadFile("_testdata/simple.yaml") - require.NoError(t, err) - - m, err := obj.Manifest() - require.NoError(t, err) - - version, err := m.Version() - require.NoError(t, err) - // Should return a value - require.NotEmpty(t, version) - - obj, err = ReadFile("_testdata/simple-double-ram.yaml") - require.NoError(t, err) - - m, err = obj.Manifest() - require.NoError(t, err) - - secondVersion, err := m.Version() - require.NoError(t, err) - // Should return a value - require.NotEmpty(t, secondVersion) - // Should be different from the first - require.NotEqual(t, secondVersion, version) -} diff --git a/sdl/storage.go b/sdl/storage.go deleted file mode 100644 index a591b4b347..0000000000 --- a/sdl/storage.go +++ /dev/null @@ -1,251 +0,0 @@ -package sdl - -import ( - "errors" - "fmt" - "sort" - - "gopkg.in/yaml.v3" - - types "github.com/akash-network/akash-api/go/node/types/v1beta3" -) - -const ( - StorageEphemeral = "ephemeral" - StorageAttributePersistent = "persistent" - StorageAttributeClass = "class" - StorageAttributeMount = "mount" - StorageAttributeReadOnly = "readOnly" // we might not need it at this point of time - StorageClassDefault = "default" - StorageClassRAM = "ram" -) - -var ( - errUnsupportedStorageAttribute = errors.New("sdl: unsupported storage attribute") - errStorageDupMountPoint = errors.New("sdl: duplicated mount point") - errStorageMultipleRootEphemeral = errors.New("sdl: multiple root ephemeral storages are not allowed") - errStorageDuplicatedVolumeName = errors.New("sdl: duplicated volume name") - errStorageEphemeralClass = errors.New("sdl: ephemeral storage should not set attribute class") - errStorageRAMClass = errors.New("sdl: ram storage class cannot be persistent") -) - -type v2StorageAttributes types.Attributes - -type v2ServiceStorageParams struct { - Mount string `yaml:"mount"` - ReadOnly bool `yaml:"readOnly"` -} - -type v2ResourceStorage struct { - Name string `yaml:"name"` - Quantity byteQuantity `yaml:"size"` - Attributes v2StorageAttributes `yaml:"attributes,omitempty"` -} - -type v2ResourceStorageArray []v2ResourceStorage - -type validateAttrFn func(string, *string) error - -var allowedStorageClasses = map[string]bool{ - "default": true, - "beta1": true, - "beta2": true, - "beta3": true, - StorageClassRAM: true, -} - -var validateStorageAttributes = map[string]validateAttrFn{ - StorageAttributePersistent: validateAttributeBool, - StorageAttributeClass: validateAttributeStorageClass, -} - -func validateAttributeBool(key string, val *string) error { - if res, valid := unifyStringAsBool(*val); valid { - *val = res - - return nil - } - - return fmt.Errorf("sdl: invalid value for attribute \"%s\". expected bool", key) -} - -func validateAttributeStorageClass(_ string, val *string) error { - if _, valid := allowedStorageClasses[*val]; valid { - return nil - } - - return fmt.Errorf("sdl: invalid value for attribute class") -} - -// UnmarshalYAML unmarshal storage config -// data can be present either as single entry mapping or an array of them -// nolint: gofmt -// e.g -// single entity -// ```yaml -// storage: -// -// size: 1Gi -// attributes: -// class: ssd -// -// ``` -// -// ```yaml -// storage: -// - size: 512Mi # ephemeral storage -// - size: 1Gi -// name: cache -// attributes: -// class: ssd -// - size: 100Gi -// name: data -// attributes: -// persistent: true # this volumes survives pod restart -// class: gp # aka general purpose -// -// ``` -func (sdl *v2ResourceStorageArray) UnmarshalYAML(node *yaml.Node) error { - var nodes v2ResourceStorageArray - - switch node.Kind { - case yaml.SequenceNode: - for _, content := range node.Content { - var nd v2ResourceStorage - if err := content.Decode(&nd); err != nil { - return err - } - - // set default name to ephemeral. later in validation error thrown if multiple - if nd.Name == "" { - nd.Name = "default" - } - nodes = append(nodes, nd) - } - case yaml.MappingNode: - var nd v2ResourceStorage - if err := node.Decode(&nd); err != nil { - return err - } - - nd.Name = "default" - nodes = append(nodes, nd) - } - - // check for duplicated volume names - names := make(map[string]string) - for _, nd := range nodes { - if _, exists := names[nd.Name]; exists { - return errStorageDuplicatedVolumeName - } - - names[nd.Name] = nd.Name - } - - nodes.sort() - - *sdl = nodes - - return nil -} - -func (sdl *v2StorageAttributes) UnmarshalYAML(node *yaml.Node) error { - var attr v2StorageAttributes - - var res map[string]string - - if err := node.Decode(&res); err != nil { - return err - } - - // set default - if _, set := res[StorageAttributePersistent]; !set { - res[StorageAttributePersistent] = valueFalse - } - - persistent := res[StorageAttributePersistent] - class := res[StorageAttributeClass] - - switch class { - case "": - if persistent == valueTrue { - res[StorageAttributeClass] = StorageClassDefault - } - case StorageClassRAM: - if persistent != valueFalse { - return errStorageRAMClass - } - default: - if persistent == valueFalse { - return errStorageEphemeralClass - } - } - - for k, v := range res { - validateFn, supportedAttr := validateStorageAttributes[k] - if !supportedAttr { - return fmt.Errorf("%w: %s", errUnsupportedStorageAttribute, k) - } - - val := v - if err := validateFn(k, &val); err != nil { - return err - } - - attr = append(attr, types.Attribute{ - Key: k, - Value: val, - }) - } - - // at this point keys are unique in attributes parsed from sdl so don't need to use sort.SliceStable - sort.Slice(attr, func(i, j int) bool { - return attr[i].Key < attr[j].Key - }) - - *sdl = attr - - return nil -} - -// sort storage slice in the following order -// 1. smaller size -// 2. if sizes are equal then one without class goes up -// 3. when both class present use lexicographic order -// 4. if no class in both cases check persistent attribute. one persistent = false goes up -// 5. volume name -func (sdl v2ResourceStorageArray) sort() { - sort.SliceStable(sdl, func(i, j int) bool { - if sdl[i].Quantity < sdl[j].Quantity { - return true - } - - if sdl[i].Quantity > sdl[j].Quantity { - return false - } - - iAttr := types.Attributes(sdl[i].Attributes) - jAttr := types.Attributes(sdl[j].Attributes) - - iClass, iExists := iAttr.Find(StorageAttributePersistent).AsString() - jClass, jExists := jAttr.Find(StorageAttributePersistent).AsString() - - if (!iExists && jExists) || - (jExists && iExists && iClass < jClass) { - return true - } else if iExists && !jExists { - return false - } - - iPersistent, _ := iAttr.Find(StorageAttributePersistent).AsBool() - jPersistent, _ := jAttr.Find(StorageAttributePersistent).AsBool() - - if !iPersistent { - return true - } else if !jPersistent { - return false - } - - return sdl[i].Name < sdl[j].Name - }) -} diff --git a/sdl/storage_test.go b/sdl/storage_test.go deleted file mode 100644 index b60c35f2d9..0000000000 --- a/sdl/storage_test.go +++ /dev/null @@ -1,229 +0,0 @@ -package sdl - -import ( - "testing" - - "github.com/stretchr/testify/require" - "gopkg.in/yaml.v3" - - "github.com/akash-network/akash-api/go/node/types/unit" - types "github.com/akash-network/akash-api/go/node/types/v1beta3" -) - -func TestStorage_LegacyValid(t *testing.T) { - var stream = ` -size: 1Gi -` - var p v2ResourceStorageArray - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) - - require.Len(t, p, 1) - require.Equal(t, byteQuantity(1*unit.Gi), p[0].Quantity) - require.Len(t, p[0].Attributes, 0) -} - -func TestStorage_ArraySingleElemValid(t *testing.T) { - var stream = ` -- size: 1Gi -` - var p v2ResourceStorageArray - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) - - require.Len(t, p, 1) - require.Equal(t, byteQuantity(1*unit.Gi), p[0].Quantity) - require.Len(t, p[0].Attributes, 0) -} - -func TestStorage_AttributesPersistentValidClass(t *testing.T) { - var stream = ` -- size: 1Gi - attributes: - persistent: true - class: default -` - var p v2ResourceStorageArray - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) - - require.Len(t, p, 1) - require.Equal(t, byteQuantity(1*unit.Gi), p[0].Quantity) - require.Len(t, p[0].Attributes, 2) - - attr := types.Attributes(p[0].Attributes) - require.Equal(t, attr[0].Key, "class") - require.Equal(t, attr[0].Value, "default") -} - -func TestStorage_AttributesUnknown(t *testing.T) { - var stream = ` -- size: 1Gi - attributes: - somefield: foo -` - var p v2ResourceStorageArray - - err := yaml.Unmarshal([]byte(stream), &p) - require.ErrorIs(t, err, errUnsupportedStorageAttribute) -} - -func TestStorage_MultipleUnnamedEphemeral(t *testing.T) { - var stream = ` -- size: 1Gi -- size: 2Gi -` - var p v2ResourceStorageArray - - err := yaml.Unmarshal([]byte(stream), &p) - require.EqualError(t, err, errStorageDuplicatedVolumeName.Error()) -} - -func TestStorage_EphemeralNoClass(t *testing.T) { - var stream = ` -- size: 1Gi -` - var p v2ResourceStorageArray - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) -} - -func TestStorage_EphemeralClass(t *testing.T) { - var stream = ` -- size: 1Gi - attributes: - class: foo -` - - var p v2ResourceStorageArray - - err := yaml.Unmarshal([]byte(stream), &p) - require.EqualError(t, err, errStorageEphemeralClass.Error()) -} - -func TestStorage_PersistentDefaultClass(t *testing.T) { - var stream = ` -- size: 1Gi - attributes: - persistent: true -` - - var p v2ResourceStorageArray - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) - require.Len(t, p[0].Attributes, 2) - - require.Equal(t, p[0].Attributes[0].Key, "class") - require.Equal(t, p[0].Attributes[0].Value, "default") -} - -func TestStorage_PersistentClass(t *testing.T) { - var stream = ` -- size: 1Gi - attributes: - persistent: true - class: beta1 -` - - var p v2ResourceStorageArray - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) - require.Len(t, p[0].Attributes, 2) - - require.Equal(t, p[0].Attributes[0].Key, "class") - require.Equal(t, p[0].Attributes[0].Value, "beta1") -} - -func TestStorage_RAMClass_Valid(t *testing.T) { - var stream = ` -- size: 1Gi - attributes: - persistent: false - class: ram -` - - var p v2ResourceStorageArray - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) - require.Len(t, p[0].Attributes, 2) - - require.Equal(t, p[0].Attributes[0].Key, "class") - require.Equal(t, p[0].Attributes[0].Value, "ram") -} - -func TestStorage_RamClass_Invalid(t *testing.T) { - var stream = ` -- size: 1Gi - attributes: - persistent: true - class: ram -` - - var p v2ResourceStorageArray - - err := yaml.Unmarshal([]byte(stream), &p) - require.Error(t, err) -} - -func TestStorage_StableSort(t *testing.T) { - storage := v2ResourceStorageArray{ - { - Quantity: 2 * unit.Gi, - Attributes: v2StorageAttributes{ - types.Attribute{ - Key: "persistent", - Value: "true", - }, - }, - }, - { - Quantity: 1 * unit.Gi, - }, - { - Quantity: 10 * unit.Gi, - }, - } - - storage.sort() - - require.Equal(t, byteQuantity(1*unit.Gi), storage[0].Quantity) - require.Equal(t, byteQuantity(2*unit.Gi), storage[1].Quantity) - require.Equal(t, byteQuantity(10*unit.Gi), storage[2].Quantity) -} - -func TestStorage_Invalid_InvalidMount(t *testing.T) { - _, err := ReadFile("./_testdata/storageClass1.yaml") - require.Error(t, err) - require.Contains(t, err.Error(), "expected absolute path") -} - -func TestStorage_Invalid_MountNotAbsolute(t *testing.T) { - _, err := ReadFile("./_testdata/storageClass2.yaml") - require.Error(t, err) - require.Contains(t, err.Error(), "expected absolute path") -} - -func TestStorage_Invalid_VolumeReference(t *testing.T) { - _, err := ReadFile("./_testdata/storageClass3.yaml") - require.Error(t, err) - require.Contains(t, err.Error(), "references to no-existing compute volume") -} - -func TestStorage_Invalid_DuplicatedMount(t *testing.T) { - _, err := ReadFile("./_testdata/storageClass4.yaml") - require.Error(t, err) - require.Contains(t, err.Error(), "already in use by volume") -} - -func TestStorage_Invalid_NoMount(t *testing.T) { - _, err := ReadFile("./_testdata/storageClass5.yaml") - require.Error(t, err) - require.Contains(t, err.Error(), "to have mount") -} diff --git a/sdl/units.go b/sdl/units.go deleted file mode 100644 index d158e44214..0000000000 --- a/sdl/units.go +++ /dev/null @@ -1,154 +0,0 @@ -package sdl - -import ( - "fmt" - "strconv" - "strings" - - "gopkg.in/yaml.v3" - - "github.com/akash-network/akash-api/go/node/types/unit" -) - -var ( - errNegativeValue = fmt.Errorf("invalid: negative value not allowed") -) - -var unitSuffixes = map[string]uint64{ - "k": unit.K, - "Ki": unit.Ki, - "M": unit.M, - "Mi": unit.Mi, - "G": unit.G, - "Gi": unit.Gi, - "T": unit.T, - "Ti": unit.Ti, - "P": unit.P, - "Pi": unit.Pi, - "E": unit.E, - "Ei": unit.Ei, -} - -var memorySuffixes = map[string]uint64{ - "Ki": unit.Ki, - "Mi": unit.Mi, - "Gi": unit.Gi, - "Ti": unit.Ti, - "Pi": unit.Pi, - "Ei": unit.Ei, -} - -// CPU shares. One CPUQuantity = 1/1000 of a CPU -type cpuQuantity uint32 - -type gpuQuantity uint64 - -func (u *cpuQuantity) UnmarshalYAML(node *yaml.Node) error { - sval := node.Value - if strings.HasSuffix(sval, "m") { - sval = strings.TrimSuffix(sval, "m") - val, err := strconv.ParseUint(sval, 10, 32) - if err != nil { - return err - } - *u = cpuQuantity(val) - return nil - } - - val, err := strconv.ParseFloat(sval, 64) - if err != nil { - return err - } - - val *= 1000 - - if val < 0 { - return errNegativeValue - } - - *u = cpuQuantity(val) - - return nil -} - -func (u *gpuQuantity) UnmarshalYAML(node *yaml.Node) error { - sval := node.Value - - val, err := strconv.ParseUint(sval, 10, 64) - if err != nil { - return err - } - - *u = gpuQuantity(val) - - return nil -} - -// Memory,Storage size in bytes. -type byteQuantity uint64 -type memoryQuantity uint64 - -func (u *byteQuantity) UnmarshalYAML(node *yaml.Node) error { - val, err := parseWithSuffix(node.Value, unitSuffixes) - if err != nil { - return err - } - *u = byteQuantity(val) - return nil -} - -func (u *memoryQuantity) UnmarshalYAML(node *yaml.Node) error { - val, err := parseWithSuffix(node.Value, memorySuffixes) - if err != nil { - return err - } - *u = memoryQuantity(val) - return nil -} - -func (u *memoryQuantity) StringWithSuffix(suffix string) string { - unit, exists := memorySuffixes[suffix] - - val := uint64(*u) / unit - - res := fmt.Sprintf("%d", val) - if exists { - res += suffix - } - - return res -} - -func parseWithSuffix(sval string, units map[string]uint64) (uint64, error) { - for suffix, unit := range units { - if !strings.HasSuffix(sval, suffix) { - continue - } - - sval := strings.TrimSuffix(sval, suffix) - - val, err := strconv.ParseFloat(sval, 64) - if err != nil { - return 0, err - } - - val *= float64(unit) - - if val < 0 { - return 0, errNegativeValue - } - - return uint64(val), nil - } - - val, err := strconv.ParseFloat(sval, 64) - if err != nil { - return 0, err - } - - if val < 0 { - return 0, errNegativeValue - } - - return uint64(val), nil -} diff --git a/sdl/units_test.go b/sdl/units_test.go deleted file mode 100644 index 559bef3932..0000000000 --- a/sdl/units_test.go +++ /dev/null @@ -1,99 +0,0 @@ -package sdl - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "gopkg.in/yaml.v3" - - "github.com/akash-network/akash-api/go/node/types/unit" -) - -func TestCPUQuantity(t *testing.T) { - - type vtype struct { - Val cpuQuantity `yaml:"val"` - } - - tests := []struct { - text string - value uint32 - err bool - }{ - {`val: 1`, 1000, false}, - {`val: -1`, 1000, true}, - - {`val: 0.5`, 500, false}, - {`val: -0.5`, 500, true}, - - {`val: "100m"`, 100, false}, - {`val: "-100m"`, 100, true}, - - {`val: ""`, 0, true}, - } - - for idx, test := range tests { - buf := []byte(test.text) - obj := &vtype{} - - err := yaml.Unmarshal(buf, obj) - - if test.err { - assert.Error(t, err, "idx:%v text:`%v`", idx, test.text) - continue - } - - if !assert.NoError(t, err, "idx:%v text:`%v`", idx, test.text) { - continue - } - - assert.Equal(t, cpuQuantity(test.value), obj.Val, "idx:%v text:`%v`", idx, test.text) - } -} - -func TestByteQuantity(t *testing.T) { - type vtype struct { - Val byteQuantity `yaml:"val"` - } - - tests := []struct { - text string - value uint64 - err bool - }{ - {`val: 1`, 1, false}, - {`val: -1`, 1, true}, - - {`val: "1M"`, unit.M, false}, - {`val: "-1M"`, 0, true}, - - {`val: "0.5M"`, unit.M / 2, false}, - {`val: "-0.5M"`, 0, true}, - - {`val: "3M"`, 3 * unit.M, false}, - {`val: "3G"`, 3 * unit.G, false}, - {`val: "3T"`, 3 * unit.T, false}, - {`val: "3P"`, 3 * unit.P, false}, - {`val: "3E"`, 3 * unit.E, false}, - - {`val: ""`, 0, true}, - } - - for idx, test := range tests { - buf := []byte(test.text) - obj := &vtype{} - - err := yaml.Unmarshal(buf, obj) - - if test.err { - assert.Error(t, err, "idx:%v text:`%v`", idx, test.text) - continue - } - - if !assert.NoError(t, err, "idx:%v text:`%v`", idx, test.text) { - continue - } - - assert.Equal(t, byteQuantity(test.value), obj.Val, "idx:%v text:`%v`", idx, test.text) - } -} diff --git a/sdl/util/util.go b/sdl/util/util.go deleted file mode 100644 index 3e80557497..0000000000 --- a/sdl/util/util.go +++ /dev/null @@ -1,31 +0,0 @@ -package util - -import ( - "math" - - sdk "github.com/cosmos/cosmos-sdk/types" - - atypes "github.com/akash-network/akash-api/go/node/types/v1beta3" -) - -func ComputeCommittedResources(factor float64, rv atypes.ResourceValue) atypes.ResourceValue { - // If the value is less than 1, commit the original value. There is no concept of undercommit - if factor <= 1.0 { - return rv - } - - v := rv.Val.Uint64() - fraction := 1.0 / factor - committedValue := math.Round(float64(v) * fraction) - - // Don't return a value of zero, since this is used as a resource request - if committedValue <= 0 { - committedValue = 1 - } - - result := atypes.ResourceValue{ - Val: sdk.NewInt(int64(committedValue)), - } - - return result -} diff --git a/sdl/util/util_test.go b/sdl/util/util_test.go deleted file mode 100644 index 3b369399ba..0000000000 --- a/sdl/util/util_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package util_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - atypes "github.com/akash-network/akash-api/go/node/types/v1beta3" - - "github.com/akash-network/node/sdl/util" -) - -func TestComputeCommittedResources(t *testing.T) { - - rv := atypes.NewResourceValue(100) - // Negative factor returns original value - require.Equal(t, uint64(100), util.ComputeCommittedResources(-1.0, rv).Val.Uint64()) - - // Zero factor returns original value - require.Equal(t, uint64(100), util.ComputeCommittedResources(0.0, rv).Val.Uint64()) - - // Factor of one returns the original value - require.Equal(t, uint64(100), util.ComputeCommittedResources(1.0, rv).Val.Uint64()) - - require.Equal(t, uint64(50), util.ComputeCommittedResources(2.0, rv).Val.Uint64()) - - require.Equal(t, uint64(33), util.ComputeCommittedResources(3.0, rv).Val.Uint64()) - - // Even for huge overcommit values, zero is not returned - require.Equal(t, uint64(1), util.ComputeCommittedResources(10000.0, rv).Val.Uint64()) -} diff --git a/sdl/utils.go b/sdl/utils.go deleted file mode 100644 index 6f4ac1c50a..0000000000 --- a/sdl/utils.go +++ /dev/null @@ -1,17 +0,0 @@ -package sdl - -const ( - valueFalse = "false" - valueTrue = "true" -) - -// as per yaml following allowed as bool values -func unifyStringAsBool(val string) (string, bool) { - if val == valueTrue || val == "on" || val == "yes" { - return valueTrue, true - } else if val == valueFalse || val == "off" || val == "no" { - return valueFalse, true - } - - return "", false -} diff --git a/sdl/v2.go b/sdl/v2.go deleted file mode 100644 index f4d132cdfd..0000000000 --- a/sdl/v2.go +++ /dev/null @@ -1,582 +0,0 @@ -package sdl - -import ( - "errors" - "fmt" - "path" - "regexp" - "sort" - "strconv" - "strings" - - "gopkg.in/yaml.v3" - - manifest "github.com/akash-network/akash-api/go/manifest/v2beta2" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/types/v1beta3" -) - -const ( - nextCaseError = "error" - nextCaseTimeout = "timeout" - nextCase500 = "500" - nextCase502 = "502" - nextCase503 = "503" - nextCase504 = "504" - nextCase403 = "403" - nextCase404 = "404" - nextCase400 = "429" - nextCaseOff = "off" - defaultMaxBodySize = uint32(1048576) - upperLimitBodySize = uint32(104857600) - defaultReadTimeout = uint32(60000) - upperLimitReadTimeout = defaultReadTimeout * 30 - defaultSendTimeout = uint32(60000) - upperLimitSendTimeout = defaultSendTimeout - defaultNextTries = uint32(3) - endpointKindIP = "ip" -) - -var ( - defaultNextCases = []string{nextCaseError, nextCaseTimeout} - errCannotSpecifyOffAndOtherCases = errors.New("if 'off' is specified, no other cases may be specified") - errUnknownNextCase = errors.New("next case is unknown") - errHTTPOptionNotAllowed = errors.New("http option not allowed") - errSDLInvalid = errors.New("SDL invalid") - errCredentialNoHost = errors.New("Service Credentials missing Host") - errCredentialNoUsername = errors.New("Service Credentials missing Username") - errCredentialNoPassword = errors.New("Service Credentials missing Password") -) - -var endpointNameValidationRegex = regexp.MustCompile(`^[[:lower:]]+[[:lower:]-_\d]+$`) - -var _ SDL = (*v2)(nil) - -type v2 struct { - Include []string `yaml:",omitempty"` - Services map[string]v2Service `yaml:"services,omitempty"` - Profiles v2profiles `yaml:"profiles,omitempty"` - Deployments v2Deployments `yaml:"deployment"` - Endpoints map[string]v2Endpoint `yaml:"endpoints"` - - result struct { - dgroups dtypes.GroupSpecs - mgroups manifest.Groups - } -} - -type v2Deployments map[string]v2Deployment - -type v2Endpoint struct { - Kind string `yaml:"kind"` -} - -type v2ExposeTo struct { - Service string `yaml:"service,omitempty"` - Global bool `yaml:"global,omitempty"` - HTTPOptions v2HTTPOptions `yaml:"http_options"` - IP string `yaml:"ip"` -} - -type v2HTTPOptions struct { - MaxBodySize uint32 `yaml:"max_body_size"` - ReadTimeout uint32 `yaml:"read_timeout"` - SendTimeout uint32 `yaml:"send_timeout"` - NextTries uint32 `yaml:"next_tries"` - NextTimeout uint32 `yaml:"next_timeout"` - NextCases []string `yaml:"next_cases"` -} - -func (ho v2HTTPOptions) asManifest() (manifest.ServiceExposeHTTPOptions, error) { - maxBodySize := ho.MaxBodySize - - if maxBodySize == 0 { - maxBodySize = defaultMaxBodySize - } else if maxBodySize > upperLimitBodySize { - return manifest.ServiceExposeHTTPOptions{}, fmt.Errorf("%w: body size cannot be greater than %d bytes", errHTTPOptionNotAllowed, upperLimitBodySize) - } - - readTimeout := ho.ReadTimeout - if readTimeout == 0 { - readTimeout = defaultReadTimeout - } else if readTimeout > upperLimitReadTimeout { - return manifest.ServiceExposeHTTPOptions{}, fmt.Errorf("%w: read timeout cannot be greater than %d ms", errHTTPOptionNotAllowed, upperLimitReadTimeout) - } - - sendTimeout := ho.SendTimeout - if sendTimeout == 0 { - sendTimeout = defaultSendTimeout - } else if sendTimeout > upperLimitSendTimeout { - return manifest.ServiceExposeHTTPOptions{}, fmt.Errorf("%w: send timeout cannot be greater than %d ms", errHTTPOptionNotAllowed, upperLimitSendTimeout) - } - - nextTries := ho.NextTries - if nextTries == 0 { - nextTries = defaultNextTries - } - - nextCases := ho.NextCases - if len(nextCases) == 0 { - nextCases = defaultNextCases - } else { - for _, nextCase := range nextCases { - switch nextCase { - case nextCaseOff: - if len(nextCases) != 1 { - return manifest.ServiceExposeHTTPOptions{}, errCannotSpecifyOffAndOtherCases - } - case nextCaseError: - case nextCaseTimeout: - case nextCase500: - case nextCase502: - case nextCase503: - case nextCase504: - case nextCase403: - case nextCase404: - case nextCase400: - default: - return manifest.ServiceExposeHTTPOptions{}, fmt.Errorf("%w: %q", errUnknownNextCase, nextCase) - } - } - } - - return manifest.ServiceExposeHTTPOptions{ - MaxBodySize: maxBodySize, - ReadTimeout: readTimeout, - SendTimeout: sendTimeout, - NextTries: nextTries, - NextTimeout: ho.NextTimeout, - NextCases: nextCases, - }, nil -} - -type v2Expose struct { - Port uint32 - As uint32 - Proto string `yaml:"proto,omitempty"` - To []v2ExposeTo `yaml:"to,omitempty"` - Accept v2Accept `yaml:"accept"` - HTTPOptions v2HTTPOptions `yaml:"http_options"` -} - -type v2Exposes []v2Expose - -type v2Dependency struct { - Service string `yaml:"service"` -} - -type v2ServiceParams struct { - Storage map[string]v2ServiceStorageParams `yaml:"storage,omitempty"` -} - -type v2Service struct { - Image string - Command []string `yaml:",omitempty"` - Args []string `yaml:",omitempty"` - Env []string `yaml:",omitempty"` - Expose v2Exposes `yaml:",omitempty"` - Dependencies []v2Dependency `yaml:",omitempty"` - Params *v2ServiceParams `yaml:",omitempty"` - Credentials *v2ServiceCredentials `yaml:",omitempty"` -} - -type v2ServiceCredentials struct { - Host string `yaml:",omitempty"` - Email string `yaml:",omitempty"` - Username string `yaml:",omitempty"` - Password string `yaml:",omitempty"` -} - -func (c v2ServiceCredentials) validate() error { - if strings.TrimSpace(c.Host) == "" { - return errCredentialNoHost - } - if strings.TrimSpace(c.Username) == "" { - return errCredentialNoUsername - } - if strings.TrimSpace(c.Password) == "" { - return errCredentialNoPassword - } - return nil -} - -type v2ServiceDeployment struct { - // Compute profile name - Profile string - - // Number of instances - Count uint32 -} - -// placement-profile -> { compute-profile, count } -type v2Deployment map[string]v2ServiceDeployment - -type v2ProfileCompute struct { - Resources *v2ComputeResources `yaml:"resources,omitempty"` -} - -type v2ProfilePlacement struct { - Attributes v2PlacementAttributes `yaml:"attributes"` - SignedBy types.SignedBy `yaml:"signedBy"` - Pricing v2PlacementPricing `yaml:"pricing"` -} - -type v2profiles struct { - Compute map[string]v2ProfileCompute `yaml:"compute"` - Placement map[string]v2ProfilePlacement `yaml:"placement"` -} - -func (sdl *v2) DeploymentGroups() (dtypes.GroupSpecs, error) { - return sdl.result.dgroups, nil -} - -func (sdl *v2) Manifest() (manifest.Manifest, error) { - return manifest.Manifest(sdl.result.mgroups), nil -} - -// Version creates the deterministic Deployment Version hash from the SDL. -func (sdl *v2) Version() ([]byte, error) { - return manifest.Manifest(sdl.result.mgroups).Version() -} - -func (sdl *v2) UnmarshalYAML(node *yaml.Node) error { - result := v2{} - -loop: - for i := 0; i < len(node.Content); i += 2 { - var val interface{} - switch node.Content[i].Value { - case "include": - val = &result.Include - case "services": - val = &result.Services - case "profiles": - val = &result.Profiles - case "deployment": - val = &result.Deployments - case "endpoints": - val = &result.Endpoints - case sdlVersionField: - // version is already verified - continue loop - default: - return fmt.Errorf("sdl: unexpected field %s", node.Content[i].Value) - } - - if err := node.Content[i+1].Decode(val); err != nil { - return err - } - } - - if err := result.buildGroups(); err != nil { - return err - } - - *sdl = result - - return nil -} - -func (sdl *v2) validate() error { - for endpointName, endpoint := range sdl.Endpoints { - if !endpointNameValidationRegex.MatchString(endpointName) { - return fmt.Errorf( - "%w: endpoint named %q is not a valid name", - errSDLInvalid, - endpointName, - ) - } - - if len(endpoint.Kind) == 0 { - return fmt.Errorf("%w: endpoint named %q has no kind", errSDLInvalid, endpointName) - } - - // Validate endpoint kind, there is only one allowed value for now - if endpoint.Kind != endpointKindIP { - return fmt.Errorf( - "%w: endpoint named %q, unknown kind %q", - errSDLInvalid, - endpointName, - endpoint.Kind, - ) - } - } - - endpointsUsed := make(map[string]struct{}) - portsUsed := make(map[string]string) - for _, svcName := range sdl.Deployments.svcNames() { - depl := sdl.Deployments[svcName] - - for _, placementName := range v2DeploymentPlacementNames(depl) { - svcdepl := depl[placementName] - - compute, ok := sdl.Profiles.Compute[svcdepl.Profile] - if !ok { - return fmt.Errorf( - "%w: %v.%v: no compute profile named %v", - errSDLInvalid, - svcName, - placementName, - svcdepl.Profile, - ) - } - - infra, ok := sdl.Profiles.Placement[placementName] - if !ok { - return fmt.Errorf( - "%w: %v.%v: no placement profile named %v", - errSDLInvalid, - svcName, - placementName, - placementName, - ) - } - - if _, ok := infra.Pricing[svcdepl.Profile]; !ok { - return fmt.Errorf( - "%w: %v.%v: no pricing for profile %v", - errSDLInvalid, - svcName, - placementName, - svcdepl.Profile, - ) - } - - svc, ok := sdl.Services[svcName] - if !ok { - return fmt.Errorf( - "%w: %v.%v: no service profile named %v", - errSDLInvalid, - svcName, - placementName, - svcName, - ) - } - - if svc.Credentials != nil { - if err := svc.Credentials.validate(); err != nil { - return fmt.Errorf( - "%w: %v.%v: %v", - errSDLInvalid, - svcName, - placementName, - err, - ) - } - } - - for _, serviceExpose := range svc.Expose { - for _, to := range serviceExpose.To { - // Check to see if an IP endpoint is also specified - if len(to.IP) != 0 { - if !to.Global { - return fmt.Errorf( - "%w: error on %q if an IP is declared the directive must be declared as global", - errSDLInvalid, - svcName, - ) - } - endpoint, endpointExists := sdl.Endpoints[to.IP] - if !endpointExists { - return fmt.Errorf( - "%w: error on service %q no endpoint named %q exists", - errSDLInvalid, - svcName, - to.IP, - ) - } - - if endpoint.Kind != endpointKindIP { - return fmt.Errorf( - "%w: error on service %q endpoint %q has type %q, should be %q", - errSDLInvalid, - svcName, - to.IP, - endpoint.Kind, - endpointKindIP, - ) - } - - endpointsUsed[to.IP] = struct{}{} - - // Endpoint exists. Now check for port collisions across a single endpoint, port, & protocol - portKey := fmt.Sprintf( - "%s-%d-%s", - to.IP, - serviceExpose.As, - serviceExpose.Proto, - ) - otherServiceName, inUse := portsUsed[portKey] - if inUse { - return fmt.Errorf( - "%w: IP endpoint %q port: %d protocol: %s specified by service %q already in use by %q", - errSDLInvalid, - to.IP, - serviceExpose.Port, - serviceExpose.Proto, - svcName, - otherServiceName, - ) - } - portsUsed[portKey] = svcName - } - } - } - - // validate storage's attributes and parameters - volumes := make(map[string]v2ResourceStorage) - for _, volume := range compute.Resources.Storage { - // making deepcopy here as we gonna merge compute attributes and service parameters for validation below - attr := make(v2StorageAttributes, len(volume.Attributes)) - - copy(attr, volume.Attributes) - - volumes[volume.Name] = v2ResourceStorage{ - Name: volume.Name, - Quantity: volume.Quantity, - Attributes: attr, - } - } - - attr := make(map[string]string) - mounts := make(map[string]string) - - if svc.Params != nil { - for name, params := range svc.Params.Storage { - if _, exists := volumes[name]; !exists { - return fmt.Errorf( - "%w: service \"%s\" references to no-existing compute volume named \"%s\"", - errSDLInvalid, - svcName, - name, - ) - } - - if !path.IsAbs(params.Mount) { - return fmt.Errorf( - "%w: invalid value for \"service.%s.params.%s.mount\" parameter. expected absolute path", - errSDLInvalid, - svcName, - name, - ) - } - - attr[StorageAttributeMount] = params.Mount - attr[StorageAttributeReadOnly] = strconv.FormatBool(params.ReadOnly) - - mount := attr[StorageAttributeMount] - if vlname, exists := mounts[mount]; exists { - if mount == "" { - return errStorageMultipleRootEphemeral - } - - return fmt.Errorf( - "%w: mount %q already in use by volume %q", - errStorageDupMountPoint, - mount, - vlname, - ) - } - - mounts[mount] = name - } - } - - for name, volume := range volumes { - for _, nd := range types.Attributes(volume.Attributes) { - attr[nd.Key] = nd.Value - } - - persistent, _ := strconv.ParseBool(attr[StorageAttributePersistent]) - - if persistent && attr[StorageAttributeMount] == "" { - return fmt.Errorf( - "%w: compute.storage.%s has persistent=true which requires service.%s.params.storage.%s to have mount", - errSDLInvalid, - name, - svcName, - name, - ) - } - } - } - } - - for endpointName := range sdl.Endpoints { - _, inUse := endpointsUsed[endpointName] - if !inUse { - return fmt.Errorf( - "%w: endpoint %q declared but never used", - errSDLInvalid, - endpointName, - ) - } - } - - return nil -} - -func (sdl *v2) computeEndpointSequenceNumbers() map[string]uint32 { - var endpointNames []string - res := make(map[string]uint32) - - for _, serviceName := range sdl.Deployments.svcNames() { - for _, expose := range sdl.Services[serviceName].Expose { - for _, to := range expose.To { - if to.Global && len(to.IP) == 0 { - continue - } - - endpointNames = append(endpointNames, to.IP) - } - } - } - - if len(endpointNames) == 0 { - return res - } - - // Make the assignment stable - sort.Strings(endpointNames) - - // Start at zero, so the first assigned one is 1 - endpointSeqNumber := uint32(0) - for _, name := range endpointNames { - endpointSeqNumber++ - seqNo := endpointSeqNumber - res[name] = seqNo - } - - return res -} - -func (sdl v2Deployments) svcNames() []string { - names := make([]string, 0, len(sdl)) - for name := range sdl { - names = append(names, name) - } - sort.Strings(names) - - return names -} - -// placementNames stable ordered placement names -func (sdl v2Deployment) placementNames() []string { - names := make([]string, 0, len(sdl)) - for name := range sdl { - names = append(names, name) - } - sort.Strings(names) - - return names -} - -func v2DeploymentPlacementNames(m v2Deployment) []string { - names := make([]string, 0, len(m)) - for name := range m { - names = append(names, name) - } - sort.Strings(names) - - return names -} diff --git a/sdl/v2_1.go b/sdl/v2_1.go deleted file mode 100644 index 98fcdec844..0000000000 --- a/sdl/v2_1.go +++ /dev/null @@ -1,364 +0,0 @@ -package sdl - -import ( - "fmt" - "path" - "sort" - "strconv" - - "gopkg.in/yaml.v3" - - manifest "github.com/akash-network/akash-api/go/manifest/v2beta2" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/types/v1beta3" -) - -var _ SDL = (*v2_1)(nil) - -type v2_1 struct { - Include []string `yaml:",omitempty"` - Services map[string]v2Service `yaml:"services,omitempty"` - Profiles v2profiles `yaml:"profiles,omitempty"` - Deployments v2Deployments `yaml:"deployment"` - Endpoints map[string]v2Endpoint `yaml:"endpoints"` - - result struct { - dgroups dtypes.GroupSpecs - mgroups manifest.Groups - } -} - -func (sdl *v2_1) DeploymentGroups() (dtypes.GroupSpecs, error) { - return sdl.result.dgroups, nil -} - -func (sdl *v2_1) Manifest() (manifest.Manifest, error) { - return manifest.Manifest(sdl.result.mgroups), nil -} - -// Version creates the deterministic Deployment Version hash from the SDL. -func (sdl *v2_1) Version() ([]byte, error) { - return manifest.Manifest(sdl.result.mgroups).Version() -} - -func (sdl *v2_1) UnmarshalYAML(node *yaml.Node) error { - result := v2_1{} - -loop: - for i := 0; i < len(node.Content); i += 2 { - var val interface{} - switch node.Content[i].Value { - case "include": - val = &result.Include - case "services": - val = &result.Services - case "profiles": - val = &result.Profiles - case "deployment": - val = &result.Deployments - case "endpoints": - val = &result.Endpoints - case sdlVersionField: - // version is already verified - continue loop - default: - return fmt.Errorf("sdl: unexpected field %s", node.Content[i].Value) - } - - if err := node.Content[i+1].Decode(val); err != nil { - return err - } - } - - if err := result.buildGroups(); err != nil { - return err - } - - *sdl = result - - return nil -} - -func (sdl *v2_1) validate() error { - for endpointName, endpoint := range sdl.Endpoints { - if !endpointNameValidationRegex.MatchString(endpointName) { - return fmt.Errorf( - "%w: endpoint named %q is not a valid name", - errSDLInvalid, - endpointName, - ) - } - - if len(endpoint.Kind) == 0 { - return fmt.Errorf("%w: endpoint named %q has no kind", errSDLInvalid, endpointName) - } - - // Validate endpoint kind, there is only one allowed value for now - if endpoint.Kind != endpointKindIP { - return fmt.Errorf( - "%w: endpoint named %q, unknown kind %q", - errSDLInvalid, - endpointName, - endpoint.Kind, - ) - } - } - - endpointsUsed := make(map[string]struct{}) - portsUsed := make(map[string]string) - for _, svcName := range sdl.Deployments.svcNames() { - depl := sdl.Deployments[svcName] - - for _, placementName := range v2DeploymentPlacementNames(depl) { - svcdepl := depl[placementName] - - compute, ok := sdl.Profiles.Compute[svcdepl.Profile] - if !ok { - return fmt.Errorf( - "%w: %v.%v: no compute profile named %v", - errSDLInvalid, - svcName, - placementName, - svcdepl.Profile, - ) - } - - infra, ok := sdl.Profiles.Placement[placementName] - if !ok { - return fmt.Errorf( - "%w: %v.%v: no placement profile named %v", - errSDLInvalid, - svcName, - placementName, - placementName, - ) - } - - if _, ok := infra.Pricing[svcdepl.Profile]; !ok { - return fmt.Errorf( - "%w: %v.%v: no pricing for profile %v", - errSDLInvalid, - svcName, - placementName, - svcdepl.Profile, - ) - } - - svc, ok := sdl.Services[svcName] - if !ok { - return fmt.Errorf( - "%w: %v.%v: no service profile named %v", - errSDLInvalid, - svcName, - placementName, - svcName, - ) - } - - if svc.Credentials != nil { - if err := svc.Credentials.validate(); err != nil { - return fmt.Errorf( - "%w: %v.%v: %v", - errSDLInvalid, - svcName, - placementName, - err, - ) - } - } - - for _, serviceExpose := range svc.Expose { - for _, to := range serviceExpose.To { - // Check to see if an IP endpoint is also specified - if len(to.IP) != 0 { - if !to.Global { - return fmt.Errorf( - "%w: error on %q if an IP is declared the directive must be declared as global", - errSDLInvalid, - svcName, - ) - } - endpoint, endpointExists := sdl.Endpoints[to.IP] - if !endpointExists { - return fmt.Errorf( - "%w: error on service %q no endpoint named %q exists", - errSDLInvalid, - svcName, - to.IP, - ) - } - - if endpoint.Kind != endpointKindIP { - return fmt.Errorf( - "%w: error on service %q endpoint %q has type %q, should be %q", - errSDLInvalid, - svcName, - to.IP, - endpoint.Kind, - endpointKindIP, - ) - } - - endpointsUsed[to.IP] = struct{}{} - - // Endpoint exists. Now check for port collisions across a single endpoint, port, & protocol - portKey := fmt.Sprintf( - "%s-%d-%s", - to.IP, - serviceExpose.As, - serviceExpose.Proto, - ) - otherServiceName, inUse := portsUsed[portKey] - if inUse { - return fmt.Errorf( - "%w: IP endpoint %q port: %d protocol: %s specified by service %q already in use by %q", - errSDLInvalid, - to.IP, - serviceExpose.Port, - serviceExpose.Proto, - svcName, - otherServiceName, - ) - } - portsUsed[portKey] = svcName - } - } - } - - // validate storage's attributes and parameters - volumes := make(map[string]v2ResourceStorage) - for _, volume := range compute.Resources.Storage { - // making deepcopy here as we gonna merge compute attributes and service parameters for validation below - attr := make(v2StorageAttributes, len(volume.Attributes)) - - copy(attr, volume.Attributes) - - volumes[volume.Name] = v2ResourceStorage{ - Name: volume.Name, - Quantity: volume.Quantity, - Attributes: attr, - } - } - - if svc.Params != nil { - mounts := make(map[string]string) - - for name, params := range svc.Params.Storage { - - volume, exists := volumes[name] - - if !exists { - return fmt.Errorf( - "%w: service \"%s\" references to no-existing compute volume named \"%s\"", - errSDLInvalid, - svcName, - name, - ) - } - - if !path.IsAbs(params.Mount) { - return fmt.Errorf( - "%w: invalid value for \"service.%s.params.%s.mount\" parameter. expected absolute path", - errSDLInvalid, - svcName, - name, - ) - } - - if vlname, exists := mounts[params.Mount]; exists { - if params.Mount == "" { - return errStorageMultipleRootEphemeral - } - - return fmt.Errorf( - "%w: mount %q already in use by volume %q", - errStorageDupMountPoint, - params.Mount, - vlname, - ) - } - - mounts[params.Mount] = name - - attr := make(map[string]string) - attr[StorageAttributeMount] = params.Mount - attr[StorageAttributeReadOnly] = strconv.FormatBool(params.ReadOnly) - - for _, nd := range types.Attributes(volume.Attributes) { - attr[nd.Key] = nd.Value - } - - persistent, _ := strconv.ParseBool(attr[StorageAttributePersistent]) - class := attr[StorageAttributeClass] - - if persistent && params.Mount == "" { - return fmt.Errorf( - "%w: compute.storage.%s has persistent=true which requires service.%s.params.storage.%s to have mount", - errSDLInvalid, - name, - svcName, - name, - ) - } - - if class == StorageClassRAM && params.ReadOnly { - return fmt.Errorf( - "%w: services.%s.params.storage.%s has readOnly=true which is not allowed for storage class \"%s\"", - errSDLInvalid, - svcName, - name, - class, - ) - } - } - } - } - } - - for endpointName := range sdl.Endpoints { - _, inUse := endpointsUsed[endpointName] - if !inUse { - return fmt.Errorf( - "%w: endpoint %q declared but never used", - errSDLInvalid, - endpointName, - ) - } - } - - return nil -} - -func (sdl *v2_1) computeEndpointSequenceNumbers() map[string]uint32 { - var endpointNames []string - res := make(map[string]uint32) - - for _, serviceName := range sdl.Deployments.svcNames() { - for _, expose := range sdl.Services[serviceName].Expose { - for _, to := range expose.To { - if to.Global && len(to.IP) == 0 { - continue - } - - endpointNames = append(endpointNames, to.IP) - } - } - } - - if len(endpointNames) == 0 { - return res - } - - // Make the assignment stable - sort.Strings(endpointNames) - - // Start at zero, so the first assigned one is 1 - endpointSeqNumber := uint32(0) - for _, name := range endpointNames { - endpointSeqNumber++ - seqNo := endpointSeqNumber - res[name] = seqNo - } - - return res -} diff --git a/sdl/v2_1_ip_test.go b/sdl/v2_1_ip_test.go deleted file mode 100644 index 645719cfd9..0000000000 --- a/sdl/v2_1_ip_test.go +++ /dev/null @@ -1,279 +0,0 @@ -package sdl - -import ( - "bytes" - "fmt" - "testing" - - manifest "github.com/akash-network/akash-api/go/manifest/v2beta2" - "github.com/stretchr/testify/require" - - types "github.com/akash-network/akash-api/go/node/types/v1beta3" -) - -func TestV2_1_ParseSimpleWithIP(t *testing.T) { - sdl, err := ReadFile("./_testdata/v2.1-simple-with-ip.yaml") - require.NoError(t, err) - require.NotNil(t, sdl) - - groups, err := sdl.DeploymentGroups() - require.NoError(t, err) - require.Len(t, groups, 1) - group := groups[0] - resources := group.GetResourceUnits() - require.Len(t, resources, 1) - resource := resources[0] - - ipEndpoint := findIPEndpoint(t, resource.Resources.Endpoints, 1) - - require.Equal(t, ipEndpoint.Kind, types.Endpoint_LEASED_IP) - - mani, err := sdl.Manifest() - require.NoError(t, err) - var exposeIP manifest.ServiceExpose - for _, expose := range mani[0].Services[0].Expose { - if len(expose.IP) != 0 { - exposeIP = expose - break - } - } - require.NotEmpty(t, exposeIP.IP) - require.Equal(t, exposeIP.Proto, manifest.UDP) - require.Equal(t, exposeIP.Port, uint32(12345)) - require.True(t, exposeIP.Global) -} - -func TestV2_1_Parse_IP(t *testing.T) { - sdl1, err := ReadFile("../x/deployment/testdata/deployment-v2.1-ip-endpoint.yaml") - require.NoError(t, err) - groups, err := sdl1.DeploymentGroups() - require.NoError(t, err) - - require.Len(t, groups, 1) - group := groups[0] - - resources := group.GetResourceUnits() - require.Len(t, resources, 1) - resource := resources[0] - endpoints := resource.Resources.Endpoints - require.Len(t, endpoints, 2) - - var ipEndpoint types.Endpoint - for _, endpoint := range endpoints { - if endpoint.Kind == types.Endpoint_LEASED_IP { - ipEndpoint = endpoint - } - } - - require.Equal(t, ipEndpoint.Kind, types.Endpoint_LEASED_IP) - require.Greater(t, ipEndpoint.SequenceNumber, uint32(0)) - - mani, err := sdl1.Manifest() - require.NoError(t, err) - maniGroups := mani.GetGroups() - require.Len(t, maniGroups, 1) - maniGroup := maniGroups[0] - services := maniGroup.Services - require.Len(t, services, 1) - - service := services[0] - exposes := service.Expose - require.Len(t, exposes, 1) - - expose := exposes[0] - - require.True(t, expose.Global) - require.Equal(t, expose.IP, "meow") - require.Greater(t, expose.EndpointSequenceNumber, uint32(0)) -} - -func TestV2_1_Parse_SharedIP(t *testing.T) { - // Read a file with 1 group having 1 endpoint shared amongst containers - sdl1, err := ReadFile("../x/deployment/testdata/deployment-v2.1-shared-ip-endpoint.yaml") - require.NoError(t, err) - - groups, err := sdl1.DeploymentGroups() - require.NoError(t, err) - require.Len(t, groups, 1) - - group := groups[0] - - resources := group.GetResourceUnits() - require.Len(t, resources, 1) - - resource := resources[0] - ipEndpoint1 := findIPEndpoint(t, resource.Resources.Endpoints, 1) - require.Greater(t, ipEndpoint1.SequenceNumber, uint32(0)) - - ipEndpoint2 := findIPEndpoint(t, resource.Resources.Endpoints, 2) - require.Greater(t, ipEndpoint2.SequenceNumber, uint32(0)) - - mani, err := sdl1.Manifest() - require.NoError(t, err) - - maniGroups := mani.GetGroups() - require.Len(t, maniGroups, 1) - maniGroup := maniGroups[0] - - services := maniGroup.Services - require.Len(t, services, 2) - serviceA := services[0] - - serviceIPEndpoint := findIPEndpoint(t, serviceA.Resources.Endpoints, 1) - require.Equal(t, serviceIPEndpoint.SequenceNumber, ipEndpoint1.SequenceNumber) - - serviceB := services[1] - serviceIPEndpoint = findIPEndpoint(t, serviceB.Resources.Endpoints, 1) - require.Equal(t, serviceIPEndpoint.SequenceNumber, ipEndpoint2.SequenceNumber) -} - -func TestV2_1_Parse_MultipleIP(t *testing.T) { - // Read a file with 1 group having two endpoints - sdl1, err := ReadFile("../x/deployment/testdata/deployment-v2.1-multi-ip-endpoint.yaml") - require.NoError(t, err) - - groups, err := sdl1.DeploymentGroups() - require.NoError(t, err) - require.Len(t, groups, 1) - - group := groups[0] - - resources := group.GetResourceUnits() - require.Len(t, resources, 1) - - mani, err := sdl1.Manifest() - require.NoError(t, err) - _ = mani -} - -func TestV2_1_Parse_MultipleGroupsIP(t *testing.T) { - // Read a file with two groups, each one having an IP endpoint that is distinct - sdl1, err := ReadFile("../x/deployment/testdata/deployment-v2.1-multi-groups-ip-endpoint.yaml") - require.NoError(t, err) - - groups, err := sdl1.DeploymentGroups() - require.NoError(t, err) - require.Len(t, groups, 2) - - resources := groups[0].GetResourceUnits() - require.Len(t, resources, 1) - - resource := resources[0] - require.Len(t, resource.Resources.Endpoints, 2) - ipEndpointFirstGroup := findIPEndpoint(t, resource.Resources.Endpoints, 1) - require.Greater(t, ipEndpointFirstGroup.SequenceNumber, uint32(0)) - - resources = groups[1].GetResourceUnits() - require.Len(t, resources, 1) - - resource = resources[0] - require.Len(t, resource.Resources.Endpoints, 2) - ipEndpointSecondGroup := findIPEndpoint(t, resource.Resources.Endpoints, 1) - require.Greater(t, ipEndpointSecondGroup.SequenceNumber, uint32(0)) - require.NotEqual(t, ipEndpointFirstGroup.SequenceNumber, ipEndpointSecondGroup.SequenceNumber) - - mani, err := sdl1.Manifest() - require.NoError(t, err) - maniGroups := mani.GetGroups() - require.Len(t, maniGroups, 2) - - maniGroup := maniGroups[0] - mresources := maniGroup.GetResourceUnits() - require.Len(t, mresources, 1) - mresource := mresources[0] - require.Equal(t, findIPEndpoint(t, mresource.Endpoints, 1).SequenceNumber, ipEndpointFirstGroup.SequenceNumber) - - maniGroup = maniGroups[1] - mresources = maniGroup.GetResourceUnits() - require.Len(t, mresources, 1) - mresource = mresources[0] - require.Equal(t, findIPEndpoint(t, mresource.Endpoints, 1).SequenceNumber, ipEndpointSecondGroup.SequenceNumber) - -} - -func TestV2_1_Parse_IPEndpointNaming(t *testing.T) { - makeSDLWithEndpointName := func(name string) []byte { - const originalSDL = `--- -version: "2.1" - -services: - web: - image: ghcr.io/akash-network/demo-app - expose: - - port: 80 - to: - - global: true - ip: %q - accept: - - test.localhost - -profiles: - compute: - web: - resources: - cpu: - units: "0.01" - memory: - size: "128Mi" - storage: - size: "512Mi" - - placement: - global: - pricing: - web: - denom: uakt - amount: 10 - -deployment: - web: - global: - profile: web - count: 1 - -endpoints: - %q: - kind: ip -` - buf := &bytes.Buffer{} - _, err := fmt.Fprintf(buf, originalSDL, name, name) - require.NoError(t, err) - return buf.Bytes() - } - - _, err := Read(makeSDLWithEndpointName("meow72-memes")) - require.NoError(t, err) - - _, err = Read(makeSDLWithEndpointName("meow72-mem_es")) - require.NoError(t, err) - - _, err = Read(makeSDLWithEndpointName("!important")) - require.Error(t, err) - require.ErrorIs(t, err, errSDLInvalid) - require.Contains(t, err.Error(), "not a valid name") - - _, err = Read(makeSDLWithEndpointName("foo^bar")) - require.Error(t, err) - require.ErrorIs(t, err, errSDLInvalid) - require.Contains(t, err.Error(), "not a valid name") - - _, err = Read(makeSDLWithEndpointName("ROAR")) - require.Error(t, err) - require.ErrorIs(t, err, errSDLInvalid) - require.Contains(t, err.Error(), "not a valid name") - - _, err = Read(makeSDLWithEndpointName("996")) - require.Error(t, err) - require.ErrorIs(t, err, errSDLInvalid) - require.Contains(t, err.Error(), "not a valid name") - - _, err = Read(makeSDLWithEndpointName("_kittens")) - require.Error(t, err) - require.ErrorIs(t, err, errSDLInvalid) - require.Contains(t, err.Error(), "not a valid name") - - _, err = Read(makeSDLWithEndpointName("-kittens")) - require.Error(t, err) - require.ErrorIs(t, err, errSDLInvalid) - require.Contains(t, err.Error(), "not a valid name") -} diff --git a/sdl/v2_1_test.go b/sdl/v2_1_test.go deleted file mode 100644 index 6e67f0d05e..0000000000 --- a/sdl/v2_1_test.go +++ /dev/null @@ -1,760 +0,0 @@ -package sdl - -import ( - "testing" - - manifest "github.com/akash-network/akash-api/go/manifest/v2beta2" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - "github.com/akash-network/akash-api/go/node/types/unit" - atypes "github.com/akash-network/akash-api/go/node/types/v1beta3" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - // "github.com/akash-network/node/testutil" -) - -func TestV2_1_ParseSimpleGPU(t *testing.T) { - sdl, err := ReadFile("./_testdata/v2.1-simple-gpu.yaml") - require.NoError(t, err) - - groups, err := sdl.DeploymentGroups() - require.NoError(t, err) - assert.Len(t, groups, 1) - - group := groups[0] - assert.Len(t, group.GetResourceUnits(), 1) - assert.Len(t, group.Requirements.Attributes, 2) - - assert.Equal(t, atypes.Attribute{ - Key: "region", - Value: "us-west", - }, group.Requirements.Attributes[1]) - - assert.Len(t, group.GetResourceUnits(), 1) - - assert.Equal(t, dtypes.ResourceUnit{ - Count: 2, - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(randCPU), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(randGPU), - Attributes: atypes.Attributes{ - { - Key: "vendor/nvidia/model/a100", - Value: "true", - }, - }, - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(randMemory), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(randStorage), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Price: AkashDecCoin(t, 50), - }, group.GetResourceUnits()[0]) - - mani, err := sdl.Manifest() - require.NoError(t, err) - - assert.Len(t, mani.GetGroups(), 1) - - expectedHosts := make([]string, 1) - expectedHosts[0] = "ahostname.com" // nolint: goconst - assert.Equal(t, manifest.Group{ - Name: "westcoast", - Services: []manifest.Service{ - { - Name: "web", - Image: "nginx", - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(100), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(1), - Attributes: atypes.Attributes{ - { - Key: "vendor/nvidia/model/a100", - Value: "true", - }, - }, - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(128 * unit.Mi), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(1 * unit.Gi), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Count: 2, - Expose: []manifest.ServiceExpose{ - {Port: 80, Global: true, Proto: manifest.TCP, Hosts: expectedHosts, - HTTPOptions: manifest.ServiceExposeHTTPOptions{ - MaxBodySize: 1048576, - ReadTimeout: 60000, - SendTimeout: 60000, - NextTries: 3, - NextTimeout: 0, - NextCases: []string{"error", "timeout"}, - }}, - {Port: 12345, Global: true, Proto: manifest.UDP, - HTTPOptions: manifest.ServiceExposeHTTPOptions{ - MaxBodySize: 1048576, - ReadTimeout: 60000, - SendTimeout: 60000, - NextTries: 3, - NextTimeout: 0, - NextCases: []string{"error", "timeout"}, - }}, - }, - }, - }, - }, mani.GetGroups()[0]) -} - -func TestV2_1_Parse_Deployments(t *testing.T) { - sdl1, err := ReadFile("../x/deployment/testdata/deployment-v2.1.yaml") - require.NoError(t, err) - _, err = sdl1.DeploymentGroups() - require.NoError(t, err) - - _, err = sdl1.Manifest() - require.NoError(t, err) - - sha1, err := sdl1.Version() - require.NoError(t, err) - assert.Len(t, sha1, 32) - - sdl2, err := ReadFile("../x/deployment/testdata/deployment-v2.yaml") - require.NoError(t, err) - sha2, err := sdl2.Version() - - require.NoError(t, err) - assert.Len(t, sha2, 32) - require.NotEqual(t, sha1, sha2) -} - -func Test_V2_1_Cross_Validates(t *testing.T) { - sdl2, err := ReadFile("../x/deployment/testdata/deployment-v2.yaml") - require.NoError(t, err) - dgroups, err := sdl2.DeploymentGroups() - require.NoError(t, err) - m, err := sdl2.Manifest() - require.NoError(t, err) - - // This is a single document producing both the manifest & deployment groups - // These should always agree with each other. If this test fails at least one of the - // following is ture - // 1. Cross validation logic is wrong - // 2. The DeploymentGroups() & Manifest() code do not agree with one another - err = m.CheckAgainstGSpecs(dgroups) - require.NoError(t, err) - - // Repeat the same test with another file - sdl2, err = ReadFile("./_testdata/v2.1-simple.yaml") - require.NoError(t, err) - dgroups, err = sdl2.DeploymentGroups() - require.NoError(t, err) - m, err = sdl2.Manifest() - require.NoError(t, err) - - // This is a single document producing both the manifest & deployment groups - // These should always agree with each other - err = m.CheckAgainstGSpecs(dgroups) - require.NoError(t, err) - - // Repeat the same test with another file - sdl2, err = ReadFile("./_testdata/v2.1-simple3.yaml") - require.NoError(t, err) - dgroups, err = sdl2.DeploymentGroups() - require.NoError(t, err) - m, err = sdl2.Manifest() - require.NoError(t, err) - - // This is a single document producing both the manifest & deployment groups - // These should always agree with each other - err = m.CheckAgainstGSpecs(dgroups) - require.NoError(t, err) - - // Repeat the same test with another file - sdl2, err = ReadFile("./_testdata/v2.1-private_service.yaml") - require.NoError(t, err) - dgroups, err = sdl2.DeploymentGroups() - require.NoError(t, err) - m, err = sdl2.Manifest() - require.NoError(t, err) - - // This is a single document producing both the manifest & deployment groups - // These should always agree with each other - err = m.CheckAgainstGSpecs(dgroups) - require.NoError(t, err) - -} - -func Test_V2_1_Parse_simple(t *testing.T) { - sdl, err := ReadFile("./_testdata/v2.1-simple.yaml") - require.NoError(t, err) - - groups, err := sdl.DeploymentGroups() - require.NoError(t, err) - assert.Len(t, groups, 1) - - group := groups[0] - assert.Len(t, group.GetResourceUnits(), 1) - - assert.Equal(t, atypes.Attribute{ - Key: "region", - Value: "us-west", - }, group.Requirements.Attributes[0]) - - assert.Len(t, group.GetResourceUnits(), 1) - - assert.Equal(t, dtypes.ResourceUnit{ - Count: 2, - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(randCPU), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(0), - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(randMemory), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(randStorage), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Price: AkashDecCoin(t, 50), - }, group.GetResourceUnits()[0]) - - mani, err := sdl.Manifest() - require.NoError(t, err) - - assert.Len(t, mani.GetGroups(), 1) - - expectedHosts := make([]string, 1) - expectedHosts[0] = "ahostname.com" - assert.Equal(t, manifest.Group{ - Name: "westcoast", - Services: []manifest.Service{ - { - Name: "web", - Image: "nginx", - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(100), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(0), - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(128 * unit.Mi), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(1 * unit.Gi), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Count: 2, - Expose: []manifest.ServiceExpose{ - {Port: 80, Global: true, Proto: manifest.TCP, Hosts: expectedHosts, - HTTPOptions: manifest.ServiceExposeHTTPOptions{ - MaxBodySize: 1048576, - ReadTimeout: 60000, - SendTimeout: 60000, - NextTries: 3, - NextTimeout: 0, - NextCases: []string{"error", "timeout"}, - }}, - {Port: 12345, Global: true, Proto: manifest.UDP, - HTTPOptions: manifest.ServiceExposeHTTPOptions{ - MaxBodySize: 1048576, - ReadTimeout: 60000, - SendTimeout: 60000, - NextTries: 3, - NextTimeout: 0, - NextCases: []string{"error", "timeout"}, - }}, - }, - }, - }, - }, mani.GetGroups()[0]) - - assert.Nil(t, mani.GetGroups()[0].Services[0].Credentials) - -} - -func Test_V2_1_Parse_credentials(t *testing.T) { - sdl, err := ReadFile("./_testdata/v2.1-credentials.yaml") - require.NoError(t, err) - - mani, err := sdl.Manifest() - require.NoError(t, err) - - assert.Len(t, mani.GetGroups(), 1) - - grp := mani.GetGroups()[0] - assert.Len(t, grp.Services, 1) - - svc := grp.Services[0] - - assert.NotNil(t, svc) - - creds := svc.Credentials - assert.NotNil(t, creds) - - assert.Equal(t, "https://test.com/v1", creds.Host) - assert.Equal(t, "foo", creds.Username) - assert.Equal(t, "foo", creds.Password) -} - -func Test_V2_1_Parse_credentials_error(t *testing.T) { - _, err := ReadFile("./_testdata/v2.1-credentials-error.yaml") - require.Error(t, err) -} - -func Test_v2_1_Parse_ProfileNameNotServiceName(t *testing.T) { - sdl, err := ReadFile("./_testdata/v2.1-profile-svc-name-mismatch.yaml") - require.NoError(t, err) - - dgroups, err := sdl.DeploymentGroups() - require.NoError(t, err) - assert.Len(t, dgroups, 1) - - mani, err := sdl.Manifest() - require.NoError(t, err) - assert.Len(t, mani.GetGroups(), 1) -} - -func Test_v2_1_Parse_DeploymentNameServiceNameMismatch(t *testing.T) { - sdl, err := ReadFile("./_testdata/v2.1-deployment-svc-mismatch.yaml") - require.Error(t, err) - require.Nil(t, sdl) - require.Contains(t, err.Error(), "no service profile named") - - sdl, err = ReadFile("./_testdata/v2.1-simple2.yaml") - require.NoError(t, err) - require.NotNil(t, sdl) - - dgroups, err := sdl.DeploymentGroups() - require.NoError(t, err) - assert.Len(t, dgroups, 1) - - mani, err := sdl.Manifest() - require.NoError(t, err) - assert.Len(t, mani.GetGroups(), 1) - - require.Equal(t, dgroups[0].Name, mani.GetGroups()[0].Name) - // SDL lists 2 services, but particular deployment specifies only one - require.Len(t, mani.GetGroups()[0].Services, 1) - - // make sure deployment maps to the right service - require.Len(t, mani.GetGroups()[0].Services[0].Expose, 2) - require.Len(t, mani.GetGroups()[0].Services[0].Expose[0].Hosts, 1) - require.Equal(t, mani.GetGroups()[0].Services[0].Expose[0].Hosts[0], "ahostname.com") -} - -func TestV2_1_ParseServiceMix(t *testing.T) { - sdl, err := ReadFile("./_testdata/v2.1-service-mix.yaml") - require.NoError(t, err) - - groups, err := sdl.DeploymentGroups() - require.NoError(t, err) - assert.Len(t, groups, 1) - - group := groups[0] - assert.Len(t, group.GetResourceUnits(), 2) - assert.Len(t, group.Requirements.Attributes, 2) - - assert.Equal(t, atypes.Attribute{ - Key: "region", - Value: "us-west", - }, group.Requirements.Attributes[1]) - - assert.Equal(t, dtypes.ResourceUnits{ - { - Count: 1, - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(randCPU), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(randGPU), - Attributes: atypes.Attributes{ - { - Key: "vendor/nvidia/model/*", - Value: "true", - }, - }, - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(randMemory), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(randStorage), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Price: AkashDecCoin(t, 50), - }, - { - Count: 1, - Resources: atypes.Resources{ - ID: 2, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(randCPU), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(0), - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(randMemory), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(randStorage), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Price: AkashDecCoin(t, 50), - }, - }, group.GetResourceUnits()) - - mani, err := sdl.Manifest() - require.NoError(t, err) - - assert.Len(t, mani.GetGroups(), 1) - - assert.Equal(t, manifest.Group{ - Name: "westcoast", - Services: []manifest.Service{ - { - Name: "svca", - Image: "nginx", - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(100), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(1), - Attributes: atypes.Attributes{ - { - Key: "vendor/nvidia/model/*", - Value: "true", - }, - }, - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(128 * unit.Mi), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(1 * unit.Gi), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Count: 1, - Expose: []manifest.ServiceExpose{ - { - Port: 80, Global: true, Proto: manifest.TCP, Hosts: []string{"ahostname.com"}, - HTTPOptions: defaultHTTPOptions, - }, - { - Port: 12345, Global: true, Proto: manifest.UDP, - HTTPOptions: defaultHTTPOptions, - }, - }, - }, - { - Name: "svcb", - Image: "nginx", - Resources: atypes.Resources{ - ID: 2, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(100), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(0), - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(128 * unit.Mi), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(1 * unit.Gi), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Count: 1, - Expose: []manifest.ServiceExpose{ - { - Port: 80, Global: true, Proto: manifest.TCP, Hosts: []string{"bhostname.com"}, - HTTPOptions: defaultHTTPOptions, - }, - { - Port: 12346, Global: true, Proto: manifest.UDP, - HTTPOptions: defaultHTTPOptions, - }, - }, - }, - }, - }, mani.GetGroups()[0]) -} - -func TestV2_1_ParseServiceMix2(t *testing.T) { - sdl, err := ReadFile("./_testdata/v2.1-service-mix2.yaml") - require.NoError(t, err) - - groups, err := sdl.DeploymentGroups() - require.NoError(t, err) - assert.Len(t, groups, 1) - - group := groups[0] - assert.Len(t, group.GetResourceUnits(), 1) - assert.Len(t, group.Requirements.Attributes, 2) - - assert.Equal(t, atypes.Attribute{ - Key: "region", - Value: "us-west", - }, group.Requirements.Attributes[1]) - - assert.Equal(t, dtypes.ResourceUnits{ - { - Count: 2, - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(randCPU), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(randGPU), - Attributes: atypes.Attributes{ - { - Key: "vendor/nvidia/model/*", - Value: "true", - }, - }, - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(randMemory), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(randStorage), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Price: AkashDecCoin(t, 50), - }, - }, group.GetResourceUnits()) - - mani, err := sdl.Manifest() - require.NoError(t, err) - - assert.Len(t, mani.GetGroups(), 1) - - assert.Equal(t, manifest.Group{ - Name: "westcoast", - Services: []manifest.Service{ - { - Name: "svca", - Image: "nginx", - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(100), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(1), - Attributes: atypes.Attributes{ - { - Key: "vendor/nvidia/model/*", - Value: "true", - }, - }, - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(128 * unit.Mi), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(1 * unit.Gi), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Count: 1, - Expose: []manifest.ServiceExpose{ - { - Port: 80, Global: true, Proto: manifest.TCP, Hosts: []string{"ahostname.com"}, - HTTPOptions: defaultHTTPOptions, - }, - { - Port: 12345, Global: true, Proto: manifest.UDP, - HTTPOptions: defaultHTTPOptions, - }, - }, - }, - { - Name: "svcb", - Image: "nginx", - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(100), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(1), - Attributes: atypes.Attributes{ - { - Key: "vendor/nvidia/model/*", - Value: "true", - }, - }, - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(128 * unit.Mi), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(1 * unit.Gi), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Count: 1, - Expose: []manifest.ServiceExpose{ - { - Port: 80, Global: true, Proto: manifest.TCP, Hosts: []string{"bhostname.com"}, - HTTPOptions: defaultHTTPOptions, - }, - { - Port: 12346, Global: true, Proto: manifest.UDP, - HTTPOptions: defaultHTTPOptions, - }, - }, - }, - }, - }, mani.GetGroups()[0]) -} diff --git a/sdl/v2_ip_test.go b/sdl/v2_ip_test.go deleted file mode 100644 index 090f525107..0000000000 --- a/sdl/v2_ip_test.go +++ /dev/null @@ -1,297 +0,0 @@ -package sdl - -import ( - "bytes" - "fmt" - "testing" - - manifest "github.com/akash-network/akash-api/go/manifest/v2beta2" - "github.com/stretchr/testify/require" - - types "github.com/akash-network/akash-api/go/node/types/v1beta3" -) - -func findIPEndpoint(t *testing.T, endpoints []types.Endpoint, id int) types.Endpoint { - t.Helper() - - idx := 0 - for _, endpoint := range endpoints { - if endpoint.Kind == types.Endpoint_LEASED_IP { - idx++ - if id == idx { - return endpoint - } - } - } - - t.Fatal("did not find any IP endpoints") - return types.Endpoint{} -} - -func TestV2ParseSimpleWithIP(t *testing.T) { - sdl, err := ReadFile("./_testdata/simple-with-ip.yaml") - require.NoError(t, err) - require.NotNil(t, sdl) - - groups, err := sdl.DeploymentGroups() - require.NoError(t, err) - require.Len(t, groups, 1) - group := groups[0] - resources := group.GetResourceUnits() - require.Len(t, resources, 1) - resource := resources[0] - - ipEndpoint := findIPEndpoint(t, resource.Resources.Endpoints, 1) - - require.Equal(t, ipEndpoint.Kind, types.Endpoint_LEASED_IP) - - mani, err := sdl.Manifest() - require.NoError(t, err) - var exposeIP manifest.ServiceExpose - for _, expose := range mani[0].Services[0].Expose { - if len(expose.IP) != 0 { - exposeIP = expose - break - } - } - require.NotEmpty(t, exposeIP.IP) - require.Equal(t, exposeIP.Proto, manifest.UDP) - require.Equal(t, exposeIP.Port, uint32(12345)) - require.True(t, exposeIP.Global) -} - -func TestV2Parse_IP(t *testing.T) { - sdl1, err := ReadFile("../x/deployment/testdata/deployment-v2-ip-endpoint.yaml") - require.NoError(t, err) - groups, err := sdl1.DeploymentGroups() - require.NoError(t, err) - - require.Len(t, groups, 1) - group := groups[0] - - resources := group.GetResourceUnits() - require.Len(t, resources, 1) - resource := resources[0] - endpoints := resource.Resources.Endpoints - require.Len(t, endpoints, 2) - - var ipEndpoint types.Endpoint - for _, endpoint := range endpoints { - if endpoint.Kind == types.Endpoint_LEASED_IP { - ipEndpoint = endpoint - } - } - - require.Equal(t, ipEndpoint.Kind, types.Endpoint_LEASED_IP) - require.Greater(t, ipEndpoint.SequenceNumber, uint32(0)) - - mani, err := sdl1.Manifest() - require.NoError(t, err) - maniGroups := mani.GetGroups() - require.Len(t, maniGroups, 1) - maniGroup := maniGroups[0] - services := maniGroup.Services - require.Len(t, services, 1) - - service := services[0] - exposes := service.Expose - require.Len(t, exposes, 1) - - expose := exposes[0] - - require.True(t, expose.Global) - require.Equal(t, expose.IP, "meow") - require.Greater(t, expose.EndpointSequenceNumber, uint32(0)) -} - -func TestV2Parse_SharedIP(t *testing.T) { - // Read a file with 1 group having 1 endpoint shared amongst containers - sdl1, err := ReadFile("../x/deployment/testdata/deployment-v2-shared-ip-endpoint.yaml") - require.NoError(t, err) - - groups, err := sdl1.DeploymentGroups() - require.NoError(t, err) - require.Len(t, groups, 1) - - group := groups[0] - - resources := group.GetResourceUnits() - require.Len(t, resources, 2) - - // resource := resources[0] - ipEndpoint1 := findIPEndpoint(t, resources[0].Resources.Endpoints, 1) - require.Greater(t, ipEndpoint1.SequenceNumber, uint32(0)) - - ipEndpoint2 := findIPEndpoint(t, resources[1].Resources.Endpoints, 1) - require.Greater(t, ipEndpoint2.SequenceNumber, uint32(0)) - - mani, err := sdl1.Manifest() - require.NoError(t, err) - - maniGroups := mani.GetGroups() - require.Len(t, maniGroups, 1) - maniGroup := maniGroups[0] - - services := maniGroup.Services - require.Len(t, services, 2) - serviceA := services[0] - - serviceIPEndpoint := findIPEndpoint(t, serviceA.Resources.Endpoints, 1) - require.Equal(t, serviceIPEndpoint.SequenceNumber, ipEndpoint1.SequenceNumber) - - serviceB := services[1] - serviceIPEndpoint = findIPEndpoint(t, serviceB.Resources.Endpoints, 1) - require.Equal(t, serviceIPEndpoint.SequenceNumber, ipEndpoint2.SequenceNumber) -} - -func TestV2Parse_MultipleIP(t *testing.T) { - // Read a file with 1 group having two endpoints - sdl1, err := ReadFile("../x/deployment/testdata/deployment-v2-multi-ip-endpoint.yaml") - require.NoError(t, err) - - groups, err := sdl1.DeploymentGroups() - require.NoError(t, err) - require.Len(t, groups, 1) - - group := groups[0] - - resources := group.GetResourceUnits() - require.Len(t, resources, 2) - - mani, err := sdl1.Manifest() - require.NoError(t, err) - _ = mani -} - -func TestV2Parse_MultipleGroupsIP(t *testing.T) { - // Read a file with two groups, each one having an IP endpoint that is distinct - sdl1, err := ReadFile("../x/deployment/testdata/deployment-v2-multi-groups-ip-endpoint.yaml") - require.NoError(t, err) - - groups, err := sdl1.DeploymentGroups() - require.NoError(t, err) - require.Len(t, groups, 2) - - resources := groups[0].GetResourceUnits() - require.Len(t, resources, 1) - - resource := resources[0] - require.Len(t, resource.Resources.Endpoints, 2) - ipEndpointFirstGroup := findIPEndpoint(t, resource.Resources.Endpoints, 1) - require.Greater(t, ipEndpointFirstGroup.SequenceNumber, uint32(0)) - - resources = groups[1].GetResourceUnits() - require.Len(t, resources, 1) - - resource = resources[0] - require.Len(t, resource.Resources.Endpoints, 2) - ipEndpointSecondGroup := findIPEndpoint(t, resource.Resources.Endpoints, 1) - require.Greater(t, ipEndpointSecondGroup.SequenceNumber, uint32(0)) - require.NotEqual(t, ipEndpointFirstGroup.SequenceNumber, ipEndpointSecondGroup.SequenceNumber) - - mani, err := sdl1.Manifest() - require.NoError(t, err) - maniGroups := mani.GetGroups() - require.Len(t, maniGroups, 2) - - maniGroup := maniGroups[0] - mresources := maniGroup.GetResourceUnits() - require.Len(t, mresources, 1) - mresource := mresources[0] - require.Equal(t, findIPEndpoint(t, mresource.Endpoints, 1).SequenceNumber, ipEndpointFirstGroup.SequenceNumber) - - maniGroup = maniGroups[1] - mresources = maniGroup.GetResourceUnits() - require.Len(t, mresources, 1) - mresource = mresources[0] - require.Equal(t, findIPEndpoint(t, mresource.Endpoints, 1).SequenceNumber, ipEndpointSecondGroup.SequenceNumber) - -} - -func TestV2Parse_IPEndpointNaming(t *testing.T) { - makeSDLWithEndpointName := func(name string) []byte { - const originalSDL = `--- -version: "2.0" - -services: - web: - image: ghcr.io/akash-network/demo-app - expose: - - port: 80 - to: - - global: true - ip: %q - accept: - - test.localhost - -profiles: - compute: - web: - resources: - cpu: - units: "0.01" - memory: - size: "128Mi" - storage: - size: "512Mi" - - placement: - global: - pricing: - web: - denom: uakt - amount: 10 - -deployment: - web: - global: - profile: web - count: 1 - -endpoints: - %q: - kind: ip -` - buf := &bytes.Buffer{} - _, err := fmt.Fprintf(buf, originalSDL, name, name) - require.NoError(t, err) - return buf.Bytes() - } - - _, err := Read(makeSDLWithEndpointName("meow72-memes")) - require.NoError(t, err) - - _, err = Read(makeSDLWithEndpointName("meow72-mem_es")) - require.NoError(t, err) - - _, err = Read(makeSDLWithEndpointName("!important")) - require.Error(t, err) - require.ErrorIs(t, err, errSDLInvalid) - require.Contains(t, err.Error(), "not a valid name") - - _, err = Read(makeSDLWithEndpointName("foo^bar")) - require.Error(t, err) - require.ErrorIs(t, err, errSDLInvalid) - require.Contains(t, err.Error(), "not a valid name") - - _, err = Read(makeSDLWithEndpointName("ROAR")) - require.Error(t, err) - require.ErrorIs(t, err, errSDLInvalid) - require.Contains(t, err.Error(), "not a valid name") - - _, err = Read(makeSDLWithEndpointName("996")) - require.Error(t, err) - require.ErrorIs(t, err, errSDLInvalid) - require.Contains(t, err.Error(), "not a valid name") - - _, err = Read(makeSDLWithEndpointName("_kittens")) - require.Error(t, err) - require.ErrorIs(t, err, errSDLInvalid) - require.Contains(t, err.Error(), "not a valid name") - - _, err = Read(makeSDLWithEndpointName("-kittens")) - require.Error(t, err) - require.ErrorIs(t, err, errSDLInvalid) - require.Contains(t, err.Error(), "not a valid name") - -} diff --git a/sdl/v2_test.go b/sdl/v2_test.go deleted file mode 100644 index 859d621f4e..0000000000 --- a/sdl/v2_test.go +++ /dev/null @@ -1,940 +0,0 @@ -package sdl - -import ( - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gopkg.in/yaml.v3" - - manifest "github.com/akash-network/akash-api/go/manifest/v2beta2" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - "github.com/akash-network/akash-api/go/node/types/unit" - atypes "github.com/akash-network/akash-api/go/node/types/v1beta3" - // "github.com/akash-network/node/testutil" -) - -func TestV2Expose(t *testing.T) { - var stream = ` -- port: 80 - as: 80 - accept: - - hello.localhost - to: - - global: true -` - - var p []v2Expose - - err := yaml.Unmarshal([]byte(stream), &p) - require.NoError(t, err) -} - -func AkashDecCoin(t testing.TB, amount int64) sdk.DecCoin { - t.Helper() - amt := sdk.NewInt(amount) - return sdk.NewDecCoin("uakt", amt) -} - -const ( - randCPU uint64 = 100 - randGPU uint64 = 1 - randMemory uint64 = 128 * unit.Mi - randStorage uint64 = 1 * unit.Gi -) - -var ( - defaultHTTPOptions = manifest.ServiceExposeHTTPOptions{ - MaxBodySize: defaultMaxBodySize, - ReadTimeout: defaultReadTimeout, - SendTimeout: defaultSendTimeout, - NextTries: defaultNextTries, - NextCases: []string{"error", "timeout"}, - } -) - -func TestV2ParseSimpleGPU(t *testing.T) { - sdl, err := ReadFile("./_testdata/simple-gpu.yaml") - require.NoError(t, err) - - groups, err := sdl.DeploymentGroups() - require.NoError(t, err) - assert.Len(t, groups, 1) - - group := groups[0] - assert.Len(t, group.GetResourceUnits(), 1) - assert.Len(t, group.Requirements.Attributes, 2) - - assert.Equal(t, atypes.Attribute{ - Key: "region", - Value: "us-west", - }, group.Requirements.Attributes[1]) - - assert.Len(t, group.GetResourceUnits(), 1) - - assert.Equal(t, dtypes.ResourceUnit{ - Count: 2, - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(randCPU), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(randGPU), - Attributes: atypes.Attributes{ - { - Key: "vendor/nvidia/model/a100", - Value: "true", - }, - }, - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(randMemory), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(randStorage), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Price: AkashDecCoin(t, 50), - }, group.GetResourceUnits()[0]) - - mani, err := sdl.Manifest() - require.NoError(t, err) - - assert.Len(t, mani.GetGroups(), 1) - - expectedHosts := make([]string, 1) - expectedHosts[0] = "ahostname.com" - assert.Equal(t, manifest.Group{ - Name: "westcoast", - Services: []manifest.Service{ - { - Name: "web", - Image: "nginx", - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(100), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(1), - Attributes: atypes.Attributes{ - { - Key: "vendor/nvidia/model/a100", - Value: "true", - }, - }, - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(128 * unit.Mi), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(1 * unit.Gi), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Count: 2, - Expose: []manifest.ServiceExpose{ - {Port: 80, Global: true, Proto: manifest.TCP, Hosts: expectedHosts, - HTTPOptions: manifest.ServiceExposeHTTPOptions{ - MaxBodySize: 1048576, - ReadTimeout: 60000, - SendTimeout: 60000, - NextTries: 3, - NextTimeout: 0, - NextCases: []string{"error", "timeout"}, - }}, - {Port: 12345, Global: true, Proto: manifest.UDP, - HTTPOptions: manifest.ServiceExposeHTTPOptions{ - MaxBodySize: 1048576, - ReadTimeout: 60000, - SendTimeout: 60000, - NextTries: 3, - NextTimeout: 0, - NextCases: []string{"error", "timeout"}, - }}, - }, - }, - }, - }, mani.GetGroups()[0]) -} - -func TestV2Parse_Deployments(t *testing.T) { - sdl1, err := ReadFile("../x/deployment/testdata/deployment.yaml") - require.NoError(t, err) - _, err = sdl1.DeploymentGroups() - require.NoError(t, err) - - _, err = sdl1.Manifest() - require.NoError(t, err) - - sha1, err := sdl1.Version() - require.NoError(t, err) - assert.Len(t, sha1, 32) - - sdl2, err := ReadFile("../x/deployment/testdata/deployment-v2.yaml") - require.NoError(t, err) - sha2, err := sdl2.Version() - - require.NoError(t, err) - assert.Len(t, sha2, 32) - require.NotEqual(t, sha1, sha2) -} - -func Test_V2_Cross_Validates(t *testing.T) { - sdl2, err := ReadFile("../x/deployment/testdata/deployment-v2.yaml") - require.NoError(t, err) - dgroups, err := sdl2.DeploymentGroups() - require.NoError(t, err) - m, err := sdl2.Manifest() - require.NoError(t, err) - - // This is a single document producing both the manifest & deployment groups - // These should always agree with each other. If this test fails at least one of the - // following is ture - // 1. Cross validation logic is wrong - // 2. The DeploymentGroups() & Manifest() code do not agree with one another - err = m.CheckAgainstGSpecs(dgroups) - require.NoError(t, err) - - // Repeat the same test with another file - sdl2, err = ReadFile("./_testdata/simple.yaml") - require.NoError(t, err) - dgroups, err = sdl2.DeploymentGroups() - require.NoError(t, err) - m, err = sdl2.Manifest() - require.NoError(t, err) - - // This is a single document producing both the manifest & deployment groups - // These should always agree with each other - err = m.CheckAgainstGSpecs(dgroups) - require.NoError(t, err) - - // Repeat the same test with another file - sdl2, err = ReadFile("./_testdata/simple3.yaml") - require.NoError(t, err) - dgroups, err = sdl2.DeploymentGroups() - require.NoError(t, err) - m, err = sdl2.Manifest() - require.NoError(t, err) - - // This is a single document producing both the manifest & deployment groups - // These should always agree with each other - err = m.CheckAgainstGSpecs(dgroups) - require.NoError(t, err) - - // Repeat the same test with another file - sdl2, err = ReadFile("./_testdata/private_service.yaml") - require.NoError(t, err) - dgroups, err = sdl2.DeploymentGroups() - require.NoError(t, err) - m, err = sdl2.Manifest() - require.NoError(t, err) - - // This is a single document producing both the manifest & deployment groups - // These should always agree with each other - err = m.CheckAgainstGSpecs(dgroups) - require.NoError(t, err) - -} - -func Test_V2_Parse_simple(t *testing.T) { - sdl, err := ReadFile("./_testdata/simple.yaml") - require.NoError(t, err) - - groups, err := sdl.DeploymentGroups() - require.NoError(t, err) - assert.Len(t, groups, 1) - - group := groups[0] - assert.Len(t, group.GetResourceUnits(), 1) - - assert.Equal(t, atypes.Attribute{ - Key: "region", - Value: "us-west", - }, group.Requirements.Attributes[0]) - - assert.Len(t, group.GetResourceUnits(), 1) - - assert.Equal(t, dtypes.ResourceUnit{ - Count: 2, - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(randCPU), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(0), - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(randMemory), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(randStorage), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Price: AkashDecCoin(t, 50), - }, group.GetResourceUnits()[0]) - - mani, err := sdl.Manifest() - require.NoError(t, err) - - assert.Len(t, mani.GetGroups(), 1) - - expectedHosts := make([]string, 1) - expectedHosts[0] = "ahostname.com" - assert.Equal(t, manifest.Group{ - Name: "westcoast", - Services: []manifest.Service{ - { - Name: "web", - Image: "nginx", - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(100), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(0), - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(128 * unit.Mi), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(1 * unit.Gi), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Count: 2, - Expose: []manifest.ServiceExpose{ - {Port: 80, Global: true, Proto: manifest.TCP, Hosts: expectedHosts, - HTTPOptions: manifest.ServiceExposeHTTPOptions{ - MaxBodySize: 1048576, - ReadTimeout: 60000, - SendTimeout: 60000, - NextTries: 3, - NextTimeout: 0, - NextCases: []string{"error", "timeout"}, - }}, - {Port: 12345, Global: true, Proto: manifest.UDP, - HTTPOptions: manifest.ServiceExposeHTTPOptions{ - MaxBodySize: 1048576, - ReadTimeout: 60000, - SendTimeout: 60000, - NextTries: 3, - NextTimeout: 0, - NextCases: []string{"error", "timeout"}, - }}, - }, - }, - }, - }, mani.GetGroups()[0]) -} - -func Test_v1_Parse_ProfileNameNotServiceName(t *testing.T) { - sdl, err := ReadFile("./_testdata/profile-svc-name-mismatch.yaml") - require.NoError(t, err) - - dgroups, err := sdl.DeploymentGroups() - require.NoError(t, err) - assert.Len(t, dgroups, 1) - - mani, err := sdl.Manifest() - require.NoError(t, err) - assert.Len(t, mani.GetGroups(), 1) -} - -func Test_v2_Parse_DeploymentNameServiceNameMismatch(t *testing.T) { - sdl, err := ReadFile("./_testdata/deployment-svc-mismatch.yaml") - require.Error(t, err) - require.Nil(t, sdl) - require.Contains(t, err.Error(), "no service profile named") - - sdl, err = ReadFile("./_testdata/simple2.yaml") - require.NoError(t, err) - require.NotNil(t, sdl) - - dgroups, err := sdl.DeploymentGroups() - require.NoError(t, err) - assert.Len(t, dgroups, 1) - - mani, err := sdl.Manifest() - require.NoError(t, err) - assert.Len(t, mani.GetGroups(), 1) - - require.Equal(t, dgroups[0].Name, mani.GetGroups()[0].Name) - // SDL lists 2 services, but particular deployment specifies only one - require.Len(t, mani.GetGroups()[0].Services, 1) - - // make sure deployment maps to the right service - require.Len(t, mani.GetGroups()[0].Services[0].Expose, 2) - require.Len(t, mani.GetGroups()[0].Services[0].Expose[0].Hosts, 1) - require.Equal(t, mani.GetGroups()[0].Services[0].Expose[0].Hosts[0], "ahostname.com") -} - -func TestV2ParseServiceMix(t *testing.T) { - sdl, err := ReadFile("./_testdata/service-mix.yaml") - require.NoError(t, err) - - groups, err := sdl.DeploymentGroups() - require.NoError(t, err) - assert.Len(t, groups, 1) - - group := groups[0] - assert.Len(t, group.GetResourceUnits(), 2) - assert.Len(t, group.Requirements.Attributes, 2) - - assert.Equal(t, atypes.Attribute{ - Key: "region", - Value: "us-west", - }, group.Requirements.Attributes[1]) - - assert.Equal(t, dtypes.ResourceUnits{ - { - Count: 1, - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(randCPU), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(randGPU), - Attributes: atypes.Attributes{ - { - Key: "vendor/nvidia/model/*", - Value: "true", - }, - }, - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(randMemory), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(randStorage), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Price: AkashDecCoin(t, 50), - }, - { - Count: 1, - Resources: atypes.Resources{ - ID: 2, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(randCPU), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(0), - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(randMemory), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(randStorage), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Price: AkashDecCoin(t, 50), - }, - }, group.GetResourceUnits()) - - mani, err := sdl.Manifest() - require.NoError(t, err) - - assert.Len(t, mani.GetGroups(), 1) - - assert.Equal(t, manifest.Group{ - Name: "westcoast", - Services: []manifest.Service{ - { - Name: "svca", - Image: "nginx", - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(100), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(1), - Attributes: atypes.Attributes{ - { - Key: "vendor/nvidia/model/*", - Value: "true", - }, - }, - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(128 * unit.Mi), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(1 * unit.Gi), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Count: 1, - Expose: []manifest.ServiceExpose{ - { - Port: 80, Global: true, Proto: manifest.TCP, Hosts: []string{"ahostname.com"}, - HTTPOptions: defaultHTTPOptions, - }, - { - Port: 12345, Global: true, Proto: manifest.UDP, - HTTPOptions: defaultHTTPOptions, - }, - }, - }, - { - Name: "svcb", - Image: "nginx", - Resources: atypes.Resources{ - ID: 2, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(100), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(0), - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(128 * unit.Mi), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(1 * unit.Gi), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Count: 1, - Expose: []manifest.ServiceExpose{ - { - Port: 80, Global: true, Proto: manifest.TCP, Hosts: []string{"bhostname.com"}, - HTTPOptions: defaultHTTPOptions, - }, - { - Port: 12346, Global: true, Proto: manifest.UDP, - HTTPOptions: defaultHTTPOptions, - }, - }, - }, - }, - }, mani.GetGroups()[0]) -} - -func TestV2ParseServiceMix2(t *testing.T) { - sdl, err := ReadFile("./_testdata/service-mix2.yaml") - require.NoError(t, err) - - groups, err := sdl.DeploymentGroups() - require.NoError(t, err) - assert.Len(t, groups, 1) - - group := groups[0] - assert.Len(t, group.GetResourceUnits(), 2) - assert.Len(t, group.Requirements.Attributes, 2) - - assert.Equal(t, atypes.Attribute{ - Key: "region", - Value: "us-west", - }, group.Requirements.Attributes[1]) - - assert.Equal(t, dtypes.ResourceUnits{ - { - Count: 1, - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(randCPU), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(randGPU), - Attributes: atypes.Attributes{ - { - Key: "vendor/nvidia/model/*", - Value: "true", - }, - }, - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(randMemory), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(randStorage), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Price: AkashDecCoin(t, 50), - }, - { - Count: 1, - Resources: atypes.Resources{ - ID: 2, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(randCPU), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(randGPU), - Attributes: atypes.Attributes{ - { - Key: "vendor/nvidia/model/*", - Value: "true", - }, - }, - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(randMemory), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(randStorage), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Price: AkashDecCoin(t, 50), - }, - }, group.GetResourceUnits()) - - mani, err := sdl.Manifest() - require.NoError(t, err) - - assert.Len(t, mani.GetGroups(), 1) - - assert.Equal(t, manifest.Group{ - Name: "westcoast", - Services: []manifest.Service{ - { - Name: "svca", - Image: "nginx", - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(100), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(1), - Attributes: atypes.Attributes{ - { - Key: "vendor/nvidia/model/*", - Value: "true", - }, - }, - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(128 * unit.Mi), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(1 * unit.Gi), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Count: 1, - Expose: []manifest.ServiceExpose{ - { - Port: 80, Global: true, Proto: manifest.TCP, Hosts: []string{"ahostname.com"}, - HTTPOptions: defaultHTTPOptions, - }, - { - Port: 12345, Global: true, Proto: manifest.UDP, - HTTPOptions: defaultHTTPOptions, - }, - }, - }, - { - Name: "svcb", - Image: "nginx", - Resources: atypes.Resources{ - ID: 2, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(100), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(1), - Attributes: atypes.Attributes{ - { - Key: "vendor/nvidia/model/*", - Value: "true", - }, - }, - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(128 * unit.Mi), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(1 * unit.Gi), - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Count: 1, - Expose: []manifest.ServiceExpose{ - { - Port: 80, Global: true, Proto: manifest.TCP, Hosts: []string{"bhostname.com"}, - HTTPOptions: defaultHTTPOptions, - }, - { - Port: 12346, Global: true, Proto: manifest.UDP, - HTTPOptions: defaultHTTPOptions, - }, - }, - }, - }, - }, mani.GetGroups()[0]) -} - -func TestV2ParseStorageName(t *testing.T) { - sdl, err := ReadFile("./_testdata/storageClass6.yaml") - require.NoError(t, err) - - groups, err := sdl.DeploymentGroups() - require.NoError(t, err) - assert.Len(t, groups, 1) - - group := groups[0] - assert.Len(t, group.GetResourceUnits(), 1) - assert.Len(t, group.Requirements.Attributes, 1) - - assert.Equal(t, atypes.Attribute{ - Key: "region", - Value: "us-west", - }, group.Requirements.Attributes[0]) - - assert.Equal(t, dtypes.ResourceUnits{ - { - Count: 1, - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(randCPU), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(0), - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(randMemory), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(randStorage), - }, - { - Name: "configs", - Quantity: atypes.NewResourceValue(randStorage), - Attributes: atypes.Attributes{ - { - Key: "class", - Value: "default", - }, - { - Key: "persistent", - Value: "true", - }, - }, - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Price: AkashDecCoin(t, 50), - }, - }, group.GetResourceUnits()) - - mani, err := sdl.Manifest() - require.NoError(t, err) - - assert.Len(t, mani.GetGroups(), 1) - - assert.Equal(t, manifest.Group{ - Name: "westcoast", - Services: []manifest.Service{ - { - Name: "web", - Image: "nginx", - Resources: atypes.Resources{ - ID: 1, - CPU: &atypes.CPU{ - Units: atypes.NewResourceValue(100), - }, - GPU: &atypes.GPU{ - Units: atypes.NewResourceValue(0), - }, - Memory: &atypes.Memory{ - Quantity: atypes.NewResourceValue(128 * unit.Mi), - }, - Storage: atypes.Volumes{ - { - Name: "default", - Quantity: atypes.NewResourceValue(1 * unit.Gi), - }, - { - Name: "configs", - Quantity: atypes.NewResourceValue(1 * unit.Gi), - Attributes: atypes.Attributes{ - { - Key: "class", - Value: "default", - }, - { - Key: "persistent", - Value: "true", - }, - }, - }, - }, - Endpoints: []atypes.Endpoint{ - { - Kind: atypes.Endpoint_SHARED_HTTP, - }, - { - Kind: atypes.Endpoint_RANDOM_PORT, - }, - }, - }, - Params: &manifest.ServiceParams{ - Storage: []manifest.StorageParams{ - { - Name: "configs", - Mount: "/test", - ReadOnly: false, - }, - }, - }, - Count: 1, - Expose: []manifest.ServiceExpose{ - { - Port: 80, Global: true, Proto: manifest.TCP, Hosts: []string{"ahostname.com"}, - HTTPOptions: defaultHTTPOptions, - }, - { - Port: 12345, Global: true, Proto: manifest.UDP, - HTTPOptions: defaultHTTPOptions, - }, - }, - }, - }, - }, mani.GetGroups()[0]) -} diff --git a/tests/e2e/certs_cli_test.go b/tests/e2e/certs_cli_test.go new file mode 100644 index 0000000000..57e607159d --- /dev/null +++ b/tests/e2e/certs_cli_test.go @@ -0,0 +1,257 @@ +//go:build e2e.integration + +package e2e + +import ( + "github.com/stretchr/testify/require" + clitestutil "pkg.akt.dev/go/cli/testutil" + + "pkg.akt.dev/node/testutil" + + "pkg.akt.dev/go/cli" + utiltls "pkg.akt.dev/go/util/tls" +) + +const certTestHost = "foobar.dev" + +type certificateIntegrationTestSuite struct { + *testutil.NetworkTestSuite +} + +func (s *certificateIntegrationTestSuite) TestGeneratePublishAndRevokeServer() { + result, err := clitestutil.TxGenerateServerExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + With(certTestHost). + WithFrom(s.WalletForTest().String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + require.NoError(s.T(), err) + require.NotNil(s.T(), result) + + result, err = clitestutil.TxPublishServerExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + WithFrom(s.WalletForTest().String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + require.NoError(s.T(), err) + require.NoError(s.T(), s.Network().WaitForNextBlock()) + _ = s.ValidateTx(result.Bytes()) + + result, err = clitestutil.TxRevokeServerExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + WithFrom(s.WalletForTest().String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + + require.NoError(s.T(), err) + require.NoError(s.T(), s.Network().WaitForNextBlock()) + _ = s.ValidateTx(result.Bytes()) +} + +func (s *certificateIntegrationTestSuite) TestGenerateServerRequiresArguments() { + _, err := clitestutil.TxGenerateServerExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + With(""). + WithFrom(s.WalletForTest().String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + require.Error(s.T(), err) + require.Contains(s.T(), err.Error(), "requires at least 1 arg(s), only received 0") +} + +func (s *certificateIntegrationTestSuite) TestGenerateServerAllowsManyArguments() { + _, err := clitestutil.TxGenerateServerExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + With("a.dev", "b.dev"). + WithFrom(s.WalletForTest().String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + require.NoError(s.T(), err) +} + +func (s *certificateIntegrationTestSuite) TestGenerateClientRejectsArguments() { + _, err := clitestutil.TxGenerateClientExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + With("empty"). + WithFrom(s.WalletForTest().String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + require.Error(s.T(), err) + require.Contains(s.T(), err.Error(), "accepts 0 arg(s), received 1") +} + +func (s *certificateIntegrationTestSuite) TestGeneratePublishAndRevokeClient() { + result, err := clitestutil.TxGenerateClientExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + WithFrom(s.WalletForTest().String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + require.NoError(s.T(), err) + require.NotNil(s.T(), result) + + result, err = clitestutil.TxPublishClientExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + WithFrom(s.WalletForTest().String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + require.NoError(s.T(), err) + require.NoError(s.T(), s.Network().WaitForNextBlock()) + _ = s.ValidateTx(result.Bytes()) + + result, err = clitestutil.TxRevokeClientExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + WithFrom(s.WalletForTest().String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + + require.NoError(s.T(), err) + require.NoError(s.T(), s.Network().WaitForNextBlock()) + _ = s.ValidateTx(result.Bytes()) +} + +func (s *certificateIntegrationTestSuite) TestGenerateAndRevokeFailsServer() { + result, err := clitestutil.TxGenerateServerExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + With(certTestHost). + WithFrom(s.WalletForTest().String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + require.NoError(s.T(), err) + require.NotNil(s.T(), result) + + _, err = clitestutil.TxRevokeServerExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + WithFrom(s.WalletForTest().String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + require.ErrorIs(s.T(), err, utiltls.ErrCertificate) + require.Contains(s.T(), err.Error(), "does not exist on chain") +} + +func (s *certificateIntegrationTestSuite) TestRevokeFailsServer() { + _, err := clitestutil.TxRevokeServerExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + WithFrom(s.WalletForTest().String()). + WithSerial("1"). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + require.ErrorIs(s.T(), err, utiltls.ErrCertificate) + require.Contains(s.T(), err.Error(), "serial 1 does not exist on chain") +} + +func (s *certificateIntegrationTestSuite) TestRevokeFailsClient() { + _, err := clitestutil.TxRevokeClientExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + WithFrom(s.WalletForTest().String()). + WithSerial("1"). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + require.ErrorIs(s.T(), err, utiltls.ErrCertificate) + require.Contains(s.T(), err.Error(), "serial 1 does not exist on chain") +} + +func (s *certificateIntegrationTestSuite) TestGenerateServerNoOverwrite() { + result, err := clitestutil.TxGenerateServerExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + With(certTestHost). + WithFrom(s.WalletForTest().String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + require.NoError(s.T(), err) + require.NotNil(s.T(), result) + + _, err = clitestutil.TxGenerateServerExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + With(certTestHost). + WithFrom(s.WalletForTest().String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + require.ErrorIs(s.T(), err, utiltls.ErrCertificate) + require.Contains(s.T(), err.Error(), "cannot overwrite") +} + +func (s *certificateIntegrationTestSuite) TestGenerateClientNoOverwrite() { + result, err := clitestutil.TxGenerateClientExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + WithFrom(s.WalletForTest().String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + require.NoError(s.T(), err) + require.NotNil(s.T(), result) + + _, err = clitestutil.TxGenerateClientExec( + s.ContextForTest(), + s.ClientContextForTest(), + cli.TestFlags(). + WithFrom(s.WalletForTest().String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + require.ErrorIs(s.T(), err, utiltls.ErrCertificate) + require.Contains(s.T(), err.Error(), "cannot overwrite") +} diff --git a/tests/e2e/certs_grpc_test.go b/tests/e2e/certs_grpc_test.go new file mode 100644 index 0000000000..8140092baf --- /dev/null +++ b/tests/e2e/certs_grpc_test.go @@ -0,0 +1,114 @@ +//go:build e2e.integration + +package e2e + +import ( + "context" + "crypto/x509" + "encoding/pem" + + "pkg.akt.dev/go/cli" + clitestutil "pkg.akt.dev/go/cli/testutil" + + "github.com/stretchr/testify/require" + types "pkg.akt.dev/go/node/cert/v1" + + "pkg.akt.dev/node/testutil" +) + +type certsGRPCRestTestSuite struct { + *testutil.NetworkTestSuite + certs types.CertificatesResponse +} + +func (s *certsGRPCRestTestSuite) TestGenerateParse() { + ctx := context.Background() + cctx := s.ClientContextForTest() + + addr := s.WalletForTest() + + // Generate client certificate + _, err := clitestutil.TxGenerateClientExec( + ctx, + cctx, + cli.TestFlags(). + WithFrom(addr.String())...) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + + // Publish client certificate + _, err = clitestutil.TxPublishClientExec( + ctx, + cctx, + cli.TestFlags(). + WithFrom(addr.String()). + WithSkipConfirm(). + WithBroadcastModeBlock(). + WithGasAutoFlags()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + + // get certs + resp, err := clitestutil.QueryCertificatesExec(ctx, cctx, cli.TestFlags().WithOutputJSON()...) + s.Require().NoError(err) + + out := &types.QueryCertificatesResponse{} + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), out) + s.Require().NoError(err) + s.Require().Len(out.Certificates, 1, "Certificate Create Failed") + block, rest := pem.Decode(out.Certificates[0].Certificate.Cert) + require.NotNil(s.T(), block) + require.Len(s.T(), rest, 0) + + require.Equal(s.T(), block.Type, types.PemBlkTypeCertificate) + + cert, err := x509.ParseCertificate(block.Bytes) + s.Require().NoError(err) + s.Require().NotNil(cert) + + s.Require().Equal(addr.String(), cert.Issuer.CommonName) + + s.certs = out.Certificates +} + +// func (s *GRPCRestTestSuite) TestGetCertificates() { +// val := s.network.Validators[0] +// certs := s.certs +// +// testCases := []struct { +// name string +// url string +// expErr bool +// expResp types.CertificatesResponse +// expLen int +// }{ +// { +// "get certificates without filters", +// fmt.Sprintf("%s/akash/cert/%s/certificates/list", val.APIAddress, atypes.ProtoAPIVersion), +// false, +// certs, +// 1, +// }, +// } +// +// for _, tc := range testCases { +// tc := tc +// s.Run(tc.name, func() { +// resp, err := sdkrest.GetRequest(tc.url) +// s.Require().NoError(err) +// +// var certs types.QueryCertificatesResponse +// err = val.ClientCtx.Codec.UnmarshalJSON(resp, &certs) +// +// if tc.expErr { +// s.Require().NotNil(err) +// s.Require().Empty(certs.Certificates) +// } else { +// s.Require().NoError(err) +// s.Require().Len(certs.Certificates, tc.expLen) +// s.Require().Equal(tc.expResp, certs.Certificates) +// } +// }) +// } +// } diff --git a/tests/e2e/cli_test.go b/tests/e2e/cli_test.go new file mode 100644 index 0000000000..647769fffa --- /dev/null +++ b/tests/e2e/cli_test.go @@ -0,0 +1,33 @@ +//go:build e2e.integration + +package e2e + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/suite" + + "pkg.akt.dev/node/testutil" +) + +var DefaultDeposit = sdk.NewCoin("uakt", sdk.NewInt(5000000)) + +func TestIntegrationCLI(t *testing.T) { + di := &deploymentIntegrationTestSuite{} + di.NetworkTestSuite = testutil.NewNetworkTestSuite(nil, di) + + ci := &certificateIntegrationTestSuite{} + ci.NetworkTestSuite = testutil.NewNetworkTestSuite(nil, ci) + + mi := &marketIntegrationTestSuite{} + mi.NetworkTestSuite = testutil.NewNetworkTestSuite(nil, mi) + + pi := &providerIntegrationTestSuite{} + pi.NetworkTestSuite = testutil.NewNetworkTestSuite(nil, pi) + + suite.Run(t, di) + suite.Run(t, ci) + suite.Run(t, mi) + suite.Run(t, pi) +} diff --git a/tests/e2e/deployment_cli_test.go b/tests/e2e/deployment_cli_test.go new file mode 100644 index 0000000000..9f314a992a --- /dev/null +++ b/tests/e2e/deployment_cli_test.go @@ -0,0 +1,542 @@ +//go:build e2e.integration + +package e2e + +import ( + "context" + "path/filepath" + + sdkmath "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/client" + + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + sdktestutil "github.com/cosmos/cosmos-sdk/testutil/cli" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + + dv1 "pkg.akt.dev/go/node/deployment/v1" + dv1beta4 "pkg.akt.dev/go/node/deployment/v1beta4" + types "pkg.akt.dev/go/node/deployment/v1beta4" + + "pkg.akt.dev/go/cli" + clitestutil "pkg.akt.dev/go/cli/testutil" + + "pkg.akt.dev/node/testutil" +) + +type deploymentIntegrationTestSuite struct { + *testutil.NetworkTestSuite + + cctx client.Context + keyFunder *keyring.Record + addrFunder sdk.AccAddress + keyDeployer *keyring.Record + addrDeployer sdk.AccAddress + defaultDeposit sdk.Coin +} + +func (s *deploymentIntegrationTestSuite) SetupSuite() { + s.NetworkTestSuite.SetupSuite() + + kb := s.Network().Validators[0].ClientCtx.Keyring + _, _, err := kb.NewMnemonic("keyFunder", keyring.English, sdk.FullFundraiserPath, "", hd.Secp256k1) + s.Require().NoError(err) + + _, _, err = kb.NewMnemonic("keyDeployer", keyring.English, sdk.FullFundraiserPath, "", hd.Secp256k1) + s.Require().NoError(err) + + val := s.Network().Validators[0] + + s.cctx = val.ClientCtx + + // Initialize funder keys with coins + s.keyFunder, err = s.cctx.Keyring.Key("keyFunder") + s.Require().NoError(err) + + s.keyDeployer, err = s.cctx.Keyring.Key("keyDeployer") + s.Require().NoError(err) + + s.addrFunder, err = s.keyFunder.GetAddress() + s.Require().NoError(err) + + s.addrDeployer, err = s.keyDeployer.GetAddress() + s.Require().NoError(err) + + s.defaultDeposit, err = dv1beta4.DefaultParams().MinDepositFor(s.Config().BondDenom) + s.Require().NoError(err) + + ctx := context.Background() + + res, err := clitestutil.ExecSend( + ctx, + s.cctx, + cli.TestFlags(). + With( + val.Address.String(), + s.addrFunder.String(), + sdk.NewCoins(sdk.NewCoin(s.Config().BondDenom, s.defaultDeposit.Amount.MulRaw(4))).String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + clitestutil.ValidateTxSuccessful(ctx, s.T(), s.cctx, res.Bytes()) + + res, err = clitestutil.ExecSend( + ctx, + s.cctx, + cli.TestFlags(). + With( + val.Address.String(), + s.addrDeployer.String(), + sdk.NewCoins(sdk.NewCoin(s.Config().BondDenom, s.defaultDeposit.Amount.MulRaw(4))).String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + clitestutil.ValidateTxSuccessful(ctx, s.T(), s.cctx, res.Bytes()) + + // Create client certificate + _, err = clitestutil.TxGenerateClientExec( + ctx, + s.cctx, + cli.TestFlags(). + WithFrom(s.addrDeployer.String())..., + ) + s.Require().NoError(err) + + _, err = clitestutil.TxPublishClientExec( + ctx, + s.cctx, + cli.TestFlags(). + WithFrom(s.addrDeployer.String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) +} + +func (s *deploymentIntegrationTestSuite) TestDeployment() { + deploymentPath, err := filepath.Abs("../../x/deployment/testdata/deployment.yaml") + s.Require().NoError(err) + + deploymentPath2, err := filepath.Abs("../../x/deployment/testdata/deployment-v2.yaml") + s.Require().NoError(err) + + ctx := context.Background() + + // create deployment + _, err = clitestutil.TxCreateDeploymentExec( + ctx, + s.cctx, + deploymentPath, + cli.TestFlags(). + WithFrom(s.addrDeployer.String()). + WithDeposit(DefaultDeposit). + WithSkipConfirm(). + WithGasAutoFlags(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + + // test query deployments + resp, err := clitestutil.QueryDeploymentsExec(ctx, + s.cctx, + cli.TestFlags().WithOutputJSON()..., + ) + s.Require().NoError(err) + + out := &dv1beta4.QueryDeploymentsResponse{} + err = s.cctx.Codec.UnmarshalJSON(resp.Bytes(), out) + s.Require().NoError(err) + s.Require().Len(out.Deployments, 1, "Deployment Create Failed") + deployments := out.Deployments + s.Require().Equal(s.addrDeployer.String(), deployments[0].Deployment.ID.Owner) + + // test query deployment + createdDep := deployments[0] + resp, err = clitestutil.QueryDeploymentExec( + ctx, + s.cctx, + cli.TestFlags().WithOutputJSON(). + WithOwner(createdDep.Deployment.ID.Owner). + WithDseq(createdDep.Deployment.ID.DSeq)..., + ) + s.Require().NoError(err) + + var deployment types.QueryDeploymentResponse + err = s.cctx.Codec.UnmarshalJSON(resp.Bytes(), &deployment) + s.Require().NoError(err) + s.Require().Equal(createdDep, deployment) + + // test query deployments with filters + resp, err = clitestutil.QueryDeploymentsExec( + ctx, + s.cctx, + cli.TestFlags(). + WithOutputJSON(). + WithOwner(s.addrDeployer.String()). + WithDseq(createdDep.Deployment.ID.DSeq)..., + ) + s.Require().NoError(err, "Error when fetching deployments with owner filter") + + out = &dv1beta4.QueryDeploymentsResponse{} + err = s.cctx.Codec.UnmarshalJSON(resp.Bytes(), out) + s.Require().NoError(err) + s.Require().Len(out.Deployments, 1) + + // test updating deployment + _, err = clitestutil.TxUpdateDeploymentExec( + ctx, + s.cctx, + deploymentPath2, + cli.TestFlags(). + WithFrom(s.addrDeployer.String()). + WithDseq(createdDep.Deployment.ID.DSeq). + WithBroadcastModeBlock(). + WithGasAutoFlags()..., + ) + s.Require().NoError(err) + + s.Require().NoError(s.Network().WaitForNextBlock()) + + resp, err = clitestutil.QueryDeploymentExec( + ctx, + s.cctx, + cli.TestFlags().WithOutputJSON(). + WithOwner(createdDep.Deployment.ID.Owner). + WithDseq(createdDep.Deployment.ID.DSeq)..., + ) + s.Require().NoError(err) + + var deploymentV2 types.QueryDeploymentResponse + err = s.cctx.Codec.UnmarshalJSON(resp.Bytes(), &deploymentV2) + s.Require().NoError(err) + s.Require().NotEqual(deployment.Deployment.Hash, deploymentV2.Deployment.Hash) + + // test query deployments with wrong owner value + _, err = clitestutil.QueryDeploymentsExec( + ctx, + s.cctx, + cli.TestFlags(). + WithOutputJSON(). + WithOwner("akash102ruvpv2srmunfffxavttxnhezln6fnc3pf7tt")..., + ) + s.Require().Error(err) + + // test query deployments with wrong state value + _, err = clitestutil.QueryDeploymentsExec( + ctx, + s.cctx, + cli.TestFlags(). + WithOutputJSON(). + WithState("hello")..., + ) + s.Require().Error(err) + + // test close deployment + _, err = clitestutil.TxCloseDeploymentExec( + ctx, + s.cctx, + cli.TestFlags(). + WithFrom(s.addrDeployer.String()). + WithDseq(createdDep.Deployment.ID.DSeq). + WithBroadcastModeBlock(). + WithGasAutoFlags()..., + ) + s.Require().NoError(err) + + s.Require().NoError(s.Network().WaitForNextBlock()) + + // test query deployments with state filter closed + resp, err = clitestutil.QueryDeploymentsExec( + ctx, + s.cctx, + cli.TestFlags(). + WithOutputJSON(). + WithState("closed")..., + ) + s.Require().NoError(err) + + out = &dv1beta4.QueryDeploymentsResponse{} + err = s.cctx.Codec.UnmarshalJSON(resp.Bytes(), out) + s.Require().NoError(err) + s.Require().Len(out.Deployments, 1, "Deployment Close Failed") +} + +func (s *deploymentIntegrationTestSuite) TestGroup() { + deploymentPath, err := filepath.Abs("../../x/deployment/testdata/deployment.yaml") + s.Require().NoError(err) + + ctx := context.Background() + + // create deployment + _, err = clitestutil.TxCreateDeploymentExec( + ctx, + s.cctx, + deploymentPath, + cli.TestFlags(). + WithFrom(s.addrDeployer.String()). + WithSkipConfirm(). + WithBroadcastModeBlock(). + WithDeposit(DefaultDeposit). + WithGasAutoFlags()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + + // test query deployments + resp, err := clitestutil.QueryDeploymentsExec( + ctx, + s.cctx, + cli.TestFlags(). + WithOutputJSON(). + WithState("active")..., + ) + s.Require().NoError(err) + + out := &dv1beta4.QueryDeploymentsResponse{} + err = s.cctx.Codec.UnmarshalJSON(resp.Bytes(), out) + s.Require().NoError(err) + s.Require().Len(out.Deployments, 1, "Deployment Create Failed") + deployments := out.Deployments + s.Require().Equal(s.addrDeployer.String(), deployments[0].Deployment.ID.Owner) + + createdDep := deployments[0] + + s.Require().NotEqual(0, len(createdDep.Groups)) + + // test close group tx + _, err = clitestutil.TxCloseGroupExec( + ctx, + s.cctx, + cli.TestFlags(). + WithFrom(s.addrDeployer.String()). + WithGroupID(createdDep.Groups[0].ID). + WithSkipConfirm(). + WithBroadcastModeBlock(). + WithGasAutoFlags()..., + ) + s.Require().NoError(err) + + s.Require().NoError(s.Network().WaitForNextBlock()) + + grp := createdDep.Groups[0] + + resp, err = clitestutil.QueryGroupExec( + ctx, + s.cctx, + cli.TestFlags(). + WithOutputJSON(). + WithOwner(grp.ID.Owner). + WithDseq(grp.ID.DSeq). + WithGseq(grp.ID.GSeq)..., + ) + s.Require().NoError(err) + + var group types.Group + err = s.cctx.Codec.UnmarshalJSON(resp.Bytes(), &group) + s.Require().NoError(err) + s.Require().Equal(types.GroupClosed, group.State) +} + +func (s *deploymentIntegrationTestSuite) TestFundedDeployment() { + deploymentPath, err := filepath.Abs("../../x/deployment/testdata/deployment-v2.yaml") + s.Require().NoError(err) + + deploymentID := dv1.DeploymentID{ + Owner: s.addrDeployer.String(), + DSeq: uint64(105), + } + + prevFunderBal := s.getAccountBalance(s.addrFunder) + + ctx := context.Background() + + // Creating deployment paid by funder's account without any authorization from funder should fail + _, err = clitestutil.TxCreateDeploymentExec( + ctx, + s.cctx, + deploymentPath, + cli.TestFlags(). + WithFrom(s.addrDeployer.String()). + WithDepositor(s.addrFunder). + WithDseq(deploymentID.DSeq). + WithSkipConfirm(). + WithBroadcastModeBlock(). + WithGasAutoFlags()..., + ) + s.Require().Error(err) + + // funder's balance shouldn't be deducted + s.Require().Equal(prevFunderBal, s.getAccountBalance(s.addrFunder)) + + // Grant the tenant authorization to use funds from the funder's account + res, err := clitestutil.TxGrantAuthorizationExec( + ctx, + s.cctx, + s.addrDeployer, + cli.TestFlags(). + WithFrom(s.addrFunder.String()). + WithSkipConfirm(). + WithBroadcastModeBlock(). + WithGasAutoFlags()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + clitestutil.ValidateTxSuccessful(ctx, s.T(), s.cctx, res.Bytes()) + prevFunderBal = s.getAccountBalance(s.addrFunder) + + ownerBal := s.getAccountBalance(s.addrDeployer) + + // Creating deployment paid by funder's account should work now + res, err = clitestutil.TxCreateDeploymentExec( + ctx, + s.cctx, + deploymentPath, + cli.TestFlags(). + WithFrom(s.addrDeployer.String()). + WithDseq(deploymentID.DSeq). + WithDepositor(s.addrFunder). + WithSkipConfirm(). + WithBroadcastModeBlock(). + WithGasAutoFlags()..., + ) + + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + clitestutil.ValidateTxSuccessful(ctx, s.T(), s.cctx, res.Bytes()) + + // funder's balance should be deducted correctly + curFunderBal := s.getAccountBalance(s.addrFunder) + s.Require().Equal(prevFunderBal.Sub(s.defaultDeposit.Amount), curFunderBal) + prevFunderBal = curFunderBal + + fees := clitestutil.GetTxFees(ctx, s.T(), s.cctx, res.Bytes()) + + // owner's balance should be deducted for fees correctly + curOwnerBal := s.getAccountBalance(s.addrDeployer) + s.Require().Equal(ownerBal.SubRaw(fees.GetFee().AmountOf("uakt").Int64()), curOwnerBal) + + ownerBal = curOwnerBal + + // depositing additional funds from the owner's account should work + res, err = clitestutil.TxDepositDeploymentExec( + ctx, + s.cctx, + s.defaultDeposit, + cli.TestFlags(). + WithFrom(s.addrDeployer.String()). + WithDseq(deploymentID.DSeq). + WithSkipConfirm(). + WithBroadcastModeBlock(). + WithGasAutoFlags()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + clitestutil.ValidateTxSuccessful(ctx, s.T(), s.cctx, res.Bytes()) + + fees = clitestutil.GetTxFees(ctx, s.T(), s.cctx, res.Bytes()) + + // owner's balance should be deducted correctly + curOwnerBal = s.getAccountBalance(s.addrDeployer) + s.Require().Equal(ownerBal.Sub(s.defaultDeposit.Amount).SubRaw(fees.GetFee().AmountOf("uakt").Int64()), curOwnerBal) + ownerBal = curOwnerBal + + // depositing additional funds from the funder's account should work + res, err = clitestutil.TxDepositDeploymentExec( + ctx, + s.cctx, + s.defaultDeposit, + cli.TestFlags(). + WithFrom(s.addrDeployer.String()). + WithDseq(deploymentID.DSeq). + WithDepositor(s.addrFunder). + WithSkipConfirm(). + WithBroadcastModeBlock(). + WithGasAutoFlags()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + clitestutil.ValidateTxSuccessful(ctx, s.T(), s.cctx, res.Bytes()) + + // funder's balance should be deducted correctly + curFunderBal = s.getAccountBalance(s.addrFunder) + s.Require().Equal(prevFunderBal.Sub(s.defaultDeposit.Amount), curFunderBal) + prevFunderBal = curFunderBal + + // revoke the authorization given to the deployment owner by the funder + res, err = clitestutil.TxRevokeAuthorizationExec( + ctx, + s.cctx, + s.addrDeployer, + cli.TestFlags(). + WithFrom(s.addrFunder.String()). + WithSkipConfirm(). + WithBroadcastModeBlock(). + WithGasAutoFlags()..., + ) + + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + clitestutil.ValidateTxSuccessful(ctx, s.T(), s.cctx, res.Bytes()) + + prevFunderBal = s.getAccountBalance(s.addrFunder) + + // depositing additional funds from the funder's account should fail now + _, err = clitestutil.TxDepositDeploymentExec( + ctx, + s.cctx, + s.defaultDeposit, + cli.TestFlags(). + WithFrom(s.addrDeployer.String()). + WithDseq(deploymentID.DSeq). + WithDepositor(s.addrFunder). + WithSkipConfirm(). + WithBroadcastModeBlock(). + WithGasAutoFlags()..., + ) + s.Require().Error(err) + + // funder's balance shouldn't be deducted + s.Require().Equal(prevFunderBal, s.getAccountBalance(s.addrFunder)) + ownerBal = s.getAccountBalance(s.addrDeployer) + + // closing the deployment should return the funds and balance in escrow to the funder and + // owner's account + res, err = clitestutil.TxCloseDeploymentExec( + ctx, + s.cctx, + cli.TestFlags(). + WithFrom(s.addrDeployer.String()). + WithDseq(deploymentID.DSeq). + WithSkipConfirm(). + WithBroadcastModeBlock(). + WithGasAutoFlags()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + clitestutil.ValidateTxSuccessful(ctx, s.T(), s.cctx, res.Bytes()) + + fees = clitestutil.GetTxFees(ctx, s.T(), s.cctx, res.Bytes()) + + s.Require().Equal(prevFunderBal.Add(s.defaultDeposit.Amount.MulRaw(2)), s.getAccountBalance(s.addrFunder)) + s.Require().Equal(ownerBal.Add(s.defaultDeposit.Amount).SubRaw(fees.GetFee().AmountOf("uakt").Int64()), s.getAccountBalance(s.addrDeployer)) +} + +func (s *deploymentIntegrationTestSuite) getAccountBalance(address sdk.AccAddress) sdkmath.Int { + cctxJSON := s.Network().Validators[0].ClientCtx.WithOutputFormat("json") + res, err := sdktestutil.QueryBalancesExec(cctxJSON, address) + s.Require().NoError(err) + var balRes banktypes.QueryAllBalancesResponse + err = cctxJSON.Codec.UnmarshalJSON(res.Bytes(), &balRes) + s.Require().NoError(err) + return balRes.Balances.AmountOf(s.Config().BondDenom) +} diff --git a/tests/e2e/deployment_grpc_test.go b/tests/e2e/deployment_grpc_test.go new file mode 100644 index 0000000000..6373d1004c --- /dev/null +++ b/tests/e2e/deployment_grpc_test.go @@ -0,0 +1,286 @@ +//go:build e2e.integration + +package e2e + +import ( + "context" + "fmt" + "path/filepath" + + "github.com/cosmos/cosmos-sdk/client" + sdktestutil "github.com/cosmos/cosmos-sdk/testutil" + "pkg.akt.dev/go/cli" + clitestutil "pkg.akt.dev/go/cli/testutil" + v1 "pkg.akt.dev/go/node/deployment/v1" + "pkg.akt.dev/go/node/deployment/v1beta4" + + "pkg.akt.dev/node/testutil" +) + +type deploymentGRPCRestTestSuite struct { + *testutil.NetworkTestSuite + + cctx client.Context + deployment v1beta4.QueryDeploymentResponse +} + +func (s *deploymentGRPCRestTestSuite) SetupSuite() { + s.NetworkTestSuite.SetupSuite() + + val := s.Network().Validators[0] + + s.cctx = val.ClientCtx + + deploymentPath, err := filepath.Abs("../../x/deployment/testdata/deployment.yaml") + s.Require().NoError(err) + + ctx := context.Background() + + // Generate client certificate + _, err = clitestutil.TxGenerateClientExec( + ctx, + s.cctx, + cli.TestFlags(). + WithFrom(val.Address.String())..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + + // Publish client certificate + _, err = clitestutil.TxPublishClientExec( + ctx, + s.cctx, + cli.TestFlags(). + WithFrom(val.Address.String()). + WithSkipConfirm(). + WithBroadcastModeBlock(). + WithGasAutoFlags()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + + // create deployment + _, err = clitestutil.TxCreateDeploymentExec( + ctx, + s.cctx, + deploymentPath, + cli.TestFlags(). + WithFrom(val.Address.String()). + WithSkipConfirm(). + WithBroadcastModeBlock(). + WithDeposit(DefaultDeposit). + WithGasAutoFlags()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + + // get deployment + resp, err := clitestutil.QueryDeploymentsExec( + ctx, + s.cctx, + cli.TestFlags(). + WithOutputJSON()..., + ) + + s.Require().NoError(err) + + out := &v1beta4.QueryDeploymentsResponse{} + err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), out) + s.Require().NoError(err) + s.Require().Len(out.Deployments, 1, "Deployment Create Failed") + deployments := out.Deployments + s.Require().Equal(val.Address.String(), deployments[0].Deployment.ID.Owner) + + s.deployment = deployments[0] +} + +func (s *deploymentGRPCRestTestSuite) TestGetDeployments() { + val := s.Network().Validators[0] + deployment := s.deployment + + testCases := []struct { + name string + url string + expErr bool + expResp v1beta4.QueryDeploymentResponse + expLen int + }{ + { + "get deployments without filters", + fmt.Sprintf("%s/akash/deployment/%s/deployments/list", val.APIAddress, v1beta4.GatewayVersion), + false, + deployment, + 1, + }, + { + "get deployments with filters", + fmt.Sprintf("%s/akash/deployment/%s/deployments/list?filters.owner=%s", val.APIAddress, + v1beta4.GatewayVersion, + deployment.Deployment.ID.Owner), + false, + deployment, + 1, + }, + { + "get deployments with wrong state filter", + fmt.Sprintf("%s/akash/deployment/%s/deployments/list?filters.state=%s", val.APIAddress, v1beta4.GatewayVersion, + v1.DeploymentStateInvalid.String()), + true, + v1beta4.QueryDeploymentResponse{}, + 0, + }, + { + "get deployments with two filters", + fmt.Sprintf("%s/akash/deployment/%s/deployments/list?filters.state=%s&filters.dseq=%d", + val.APIAddress, v1beta4.GatewayVersion, deployment.Deployment.State.String(), deployment.Deployment.ID.DSeq), + false, + deployment, + 1, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + resp, err := sdktestutil.GetRequest(tc.url) + s.Require().NoError(err) + + var deployments v1beta4.QueryDeploymentsResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp, &deployments) + + if tc.expErr { + s.Require().NotNil(err) + s.Require().Empty(deployments.Deployments) + } else { + s.Require().NoError(err) + s.Require().Len(deployments.Deployments, tc.expLen) + s.Require().Equal(tc.expResp, deployments.Deployments[0]) + } + }) + } +} + +func (s *deploymentGRPCRestTestSuite) TestGetDeployment() { + val := s.Network().Validators[0] + deployment := s.deployment + + testCases := []struct { + name string + url string + expErr bool + expResp v1beta4.QueryDeploymentResponse + }{ + { + "get deployment with empty input", + fmt.Sprintf("%s/akash/deployment/v1beta4/deployments/info", val.APIAddress), + true, + v1beta4.QueryDeploymentResponse{}, + }, + { + "get deployment with invalid input", + fmt.Sprintf("%s/akash/deployment/v1beta4/deployments/info?id.owner=%s", val.APIAddress, + deployment.Deployment.ID.Owner), + true, + v1beta4.QueryDeploymentResponse{}, + }, + { + "deployment not found", + fmt.Sprintf("%s/akash/deployment/v1beta4/deployments/info?id.owner=%s&id.dseq=%d", val.APIAddress, + deployment.Deployment.ID.Owner, + 249), + true, + v1beta4.QueryDeploymentResponse{}, + }, + { + "valid get deployment request", + fmt.Sprintf("%s/akash/deployment/v1beta4/deployments/info?id.owner=%s&id.dseq=%d", + val.APIAddress, + deployment.Deployment.ID.Owner, + deployment.Deployment.ID.DSeq), + false, + deployment, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + resp, err := sdktestutil.GetRequest(tc.url) + s.Require().NoError(err) + + var out v1beta4.QueryDeploymentResponse + err = s.cctx.Codec.UnmarshalJSON(resp, &out) + + if tc.expErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().Equal(tc.expResp, out) + } + }) + } +} + +func (s *deploymentGRPCRestTestSuite) TestGetGroup() { + val := s.Network().Validators[0] + deployment := s.deployment + s.Require().NotEqual(0, len(deployment.Groups)) + group := deployment.Groups[0] + + testCases := []struct { + name string + url string + expErr bool + expResp v1beta4.Group + }{ + { + "get group with empty input", + fmt.Sprintf("%s/akash/deployment/v1beta4/groups/info", val.APIAddress), + true, + v1beta4.Group{}, + }, + { + "get group with invalid input", + fmt.Sprintf("%s/akash/deployment/v1beta4/groups/info?id.owner=%s", val.APIAddress, + group.ID.Owner), + true, + v1beta4.Group{}, + }, + { + "group not found", + fmt.Sprintf("%s/akash/deployment/v1beta4/groups/info?id.owner=%s&id.dseq=%d", val.APIAddress, + group.ID.Owner, + 249), + true, + v1beta4.Group{}, + }, + { + "valid get group request", + fmt.Sprintf("%s/akash/deployment/v1beta4/groups/info?id.owner=%s&id.dseq=%d&id.gseq=%d", + val.APIAddress, + group.ID.Owner, + group.ID.DSeq, + group.ID.GSeq), + false, + group, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + resp, err := sdktestutil.GetRequest(tc.url) + s.Require().NoError(err) + + var out v1beta4.QueryGroupResponse + err = s.cctx.Codec.UnmarshalJSON(resp, &out) + + if tc.expErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().Equal(tc.expResp, out.Group) + } + }) + } +} diff --git a/tests/e2e/grpc_test.go b/tests/e2e/grpc_test.go new file mode 100644 index 0000000000..57768a574a --- /dev/null +++ b/tests/e2e/grpc_test.go @@ -0,0 +1,30 @@ +//go:build e2e.integration + +package e2e + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + "pkg.akt.dev/node/testutil" +) + +func TestIntegrationGRPC(t *testing.T) { + dg := &deploymentGRPCRestTestSuite{} + dg.NetworkTestSuite = testutil.NewNetworkTestSuite(nil, dg) + + cg := &certsGRPCRestTestSuite{} + cg.NetworkTestSuite = testutil.NewNetworkTestSuite(nil, cg) + + mg := &marketGRPCRestTestSuite{} + mg.NetworkTestSuite = testutil.NewNetworkTestSuite(nil, mg) + + pg := &providerGRPCRestTestSuite{} + pg.NetworkTestSuite = testutil.NewNetworkTestSuite(nil, pg) + + suite.Run(t, dg) + suite.Run(t, cg) + suite.Run(t, mg) + suite.Run(t, pg) +} diff --git a/tests/e2e/market_cli_test.go b/tests/e2e/market_cli_test.go new file mode 100644 index 0000000000..73346ae86d --- /dev/null +++ b/tests/e2e/market_cli_test.go @@ -0,0 +1,502 @@ +//go:build e2e.integration + +package e2e + +import ( + "context" + "path/filepath" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + sdk "github.com/cosmos/cosmos-sdk/types" + dtypes "pkg.akt.dev/go/node/deployment/v1beta4" + types "pkg.akt.dev/go/node/market/v1beta5" + ptypes "pkg.akt.dev/go/node/provider/v1beta4" + + "pkg.akt.dev/go/cli" + clitestutil "pkg.akt.dev/go/cli/testutil" + + "pkg.akt.dev/node/testutil" +) + +type marketIntegrationTestSuite struct { + *testutil.NetworkTestSuite + + cctx client.Context + keyDeployer *keyring.Record + keyProvider *keyring.Record + addrDeployer sdk.AccAddress + addrProvider sdk.AccAddress +} + +func (s *marketIntegrationTestSuite) SetupSuite() { + s.NetworkTestSuite.SetupSuite() + + ctx := context.Background() + + kb := s.Network().Validators[0].ClientCtx.Keyring + + _, _, err := kb.NewMnemonic("keyDeployer", keyring.English, sdk.FullFundraiserPath, "", hd.Secp256k1) + s.Require().NoError(err) + + _, _, err = kb.NewMnemonic("keyProvider", keyring.English, sdk.FullFundraiserPath, "", hd.Secp256k1) + s.Require().NoError(err) + + val := s.Network().Validators[0] + + s.cctx = val.ClientCtx + cctx := s.cctx + + s.keyDeployer, err = s.cctx.Keyring.Key("keyDeployer") + s.Require().NoError(err) + + s.keyProvider, err = s.cctx.Keyring.Key("keyProvider") + s.Require().NoError(err) + + s.addrDeployer, err = s.keyDeployer.GetAddress() + s.Require().NoError(err) + + s.addrProvider, err = s.keyProvider.GetAddress() + s.Require().NoError(err) + + res, err := clitestutil.ExecSend( + ctx, + cctx, + cli.TestFlags(). + With( + s.Network().Validators[0].Address.String(), + s.addrDeployer.String(), + sdk.NewCoins(sdk.NewInt64Coin(s.Config().BondDenom, 10000000)).String()). + WithFrom(s.Network().Validators[0].Address.String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + clitestutil.ValidateTxSuccessful(ctx, s.T(), cctx, res.Bytes()) + + res, err = clitestutil.ExecSend( + ctx, + cctx, + cli.TestFlags(). + With( + s.Network().Validators[0].Address.String(), + s.addrProvider.String(), + sdk.NewCoins(sdk.NewInt64Coin(s.Config().BondDenom, 10000000)).String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + clitestutil.ValidateTxSuccessful(ctx, s.T(), cctx, res.Bytes()) + + // Create client certificate + _, err = clitestutil.TxGenerateClientExec( + ctx, + cctx, + cli.TestFlags(). + WithFrom(s.addrDeployer.String())..., + ) + s.Require().NoError(err) + + _, err = clitestutil.TxPublishClientExec( + ctx, + cctx, + cli.TestFlags(). + WithFrom(s.addrDeployer.String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) +} + +// Naming as Test{number} just to run all tests sequentially +func (s *marketIntegrationTestSuite) Test1QueryOrders() { + deploymentPath, err := filepath.Abs("../../x/deployment/testdata/deployment.yaml") + s.Require().NoError(err) + + ctx := context.Background() + cctx := s.cctx + + // create deployment + _, err = clitestutil.TxCreateDeploymentExec( + ctx, + cctx, + deploymentPath, + cli.TestFlags(). + WithFrom(s.addrDeployer.String()). + WithDeposit(DefaultDeposit). + WithSkipConfirm(). + WithGasAutoFlags(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + + // test query deployments + resp, err := clitestutil.QueryDeploymentsExec( + ctx, + cctx, + cli.TestFlags().WithOutputJSON()..., + ) + s.Require().NoError(err) + + out := &dtypes.QueryDeploymentsResponse{} + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), out) + s.Require().NoError(err) + s.Require().Len(out.Deployments, 1) + s.Require().Equal(s.addrDeployer.String(), out.Deployments[0].Deployment.ID.Owner) + + // test query orders + resp, err = clitestutil.QueryOrdersExec( + ctx, + cctx, + cli.TestFlags().WithOutputJSON()..., + ) + s.Require().NoError(err) + + result := &types.QueryOrdersResponse{} + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), result) + s.Require().NoError(err) + s.Require().Len(result.Orders, 1) + orders := result.Orders + s.Require().Equal(s.addrDeployer.String(), orders[0].ID.Owner) + + // test query order + createdOrder := orders[0] + resp, err = clitestutil.QueryOrderExec( + ctx, + cctx, + cli.TestFlags(). + WithOutputJSON(). + WithOrderID(createdOrder.ID)..., + ) + s.Require().NoError(err) + + var order types.Order + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), &order) + s.Require().NoError(err) + s.Require().Equal(createdOrder, order) + + // test query orders with filters + resp, err = clitestutil.QueryOrdersExec( + ctx, + cctx, + cli.TestFlags(). + WithOwner(s.addrDeployer.String()). + WithState("open"). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + result = &types.QueryOrdersResponse{} + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), result) + s.Require().NoError(err) + s.Require().Len(result.Orders, 1) + s.Require().Equal(createdOrder, result.Orders[0]) + + // test query orders with wrong owner value + _, err = clitestutil.QueryOrdersExec( + ctx, + cctx, + cli.TestFlags(). + WithOwner("cosmos102ruvpv2srmunfffxavttxnhezln6fnc3pf7tt"). + WithOutputJSON()..., + ) + s.Require().Error(err) + + // test query orders with wrong state value + _, err = clitestutil.QueryOrdersExec( + ctx, + cctx, + cli.TestFlags(). + WithState("hello"). + WithOutputJSON()..., + ) + s.Require().Error(err) +} + +// Naming as Test{number} just to run all tests sequentially +func (s *marketIntegrationTestSuite) Test2CreateBid() { + providerPath, err := filepath.Abs("../../x/provider/testdata/provider.yaml") + s.Require().NoError(err) + + ctx := context.Background() + cctx := s.cctx + + addr := s.addrProvider + + // create provider + _, err = clitestutil.TxCreateProviderExec( + ctx, + cctx, + providerPath, + cli.TestFlags(). + WithFrom(addr.String()). + WithSkipConfirm(). + WithGasAutoFlags(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + + // test query providers + resp, err := clitestutil.QueryProvidersExec( + ctx, + cctx, + cli.TestFlags(). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + out := &ptypes.QueryProvidersResponse{} + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), out) + s.Require().NoError(err) + s.Require().Len(out.Providers, 1, "Provider Creation Failed in TestCreateBid") + s.Require().Equal(addr.String(), out.Providers[0].Owner) + + // fetch orders + resp, err = clitestutil.QueryOrdersExec( + ctx, + cctx, + cli.TestFlags(). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + result := &types.QueryOrdersResponse{} + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), result) + s.Require().NoError(err) + s.Require().Len(result.Orders, 1) + + createdOrder := result.Orders[0] + + // create bid + _, err = clitestutil.TxCreateBidExec( + ctx, + cctx, + cli.TestFlags(). + WithFrom(addr.String()). + WithOrderID(createdOrder.ID). + WithDeposit(sdk.NewCoin("uakt", sdk.NewInt(5000000))). + WithPrice(sdk.NewDecCoinFromDec(testutil.CoinDenom, sdk.MustNewDecFromStr("1.1"))). + WithSkipConfirm(). + WithGasAutoFlags(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + + // test query bids + resp, err = clitestutil.QueryBidsExec( + ctx, + cctx, + cli.TestFlags(). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + bidRes := &types.QueryBidsResponse{} + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), bidRes) + s.Require().NoError(err) + s.Require().Len(bidRes.Bids, 1) + bids := bidRes.Bids + s.Require().Equal(addr.String(), bids[0].Bid.ID.Provider) + + // test query bid + createdBid := bids[0].Bid + resp, err = clitestutil.QueryBidExec( + ctx, + cctx, + cli.TestFlags(). + WithBidID(createdBid.ID). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + var bid types.QueryBidResponse + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), &bid) + s.Require().NoError(err) + s.Require().Equal(createdBid, bid.Bid) + + // test query bids with filters + resp, err = clitestutil.QueryBidsExec( + ctx, + cctx, + cli.TestFlags(). + WithProvider(addr.String()). + WithState(bid.Bid.State.String()). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + bidRes = &types.QueryBidsResponse{} + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), bidRes) + s.Require().NoError(err) + s.Require().Len(bidRes.Bids, 1) + s.Require().Equal(createdBid, bidRes.Bids[0].Bid) + + // test query bids with wrong owner value + _, err = clitestutil.QueryBidsExec( + ctx, + cctx, + cli.TestFlags(). + WithOutputJSON(). + WithOwner("akash102ruvpv2srmunfffxavttxnhezln6fnc3pf7tt")..., + ) + s.Require().Error(err) + + // test query bids with wrong state value + _, err = clitestutil.QueryBidsExec( + ctx, + cctx, + cli.TestFlags(). + WithOutputJSON(). + WithState("hello")..., + ) + s.Require().Error(err) + + // create lease + _, err = clitestutil.TxCreateLeaseExec( + ctx, + cctx, + cli.TestFlags(). + WithFrom(s.addrDeployer.String()). + WithBidID(bid.Bid.ID). + WithSkipConfirm(). + WithGasAutoFlags(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) +} + +// Naming as Test{number} just to run all tests sequentially +func (s *marketIntegrationTestSuite) Test3QueryLeasesAndCloseBid() { + ctx := context.Background() + cctx := s.cctx + + // test query leases + resp, err := clitestutil.QueryLeasesExec( + ctx, + cctx, + cli.TestFlags(). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + leaseRes := &types.QueryLeasesResponse{} + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), leaseRes) + s.Require().NoError(err) + s.Require().Len(leaseRes.Leases, 1) + leases := leaseRes.Leases + s.Require().Equal(s.addrProvider.String(), leases[0].Lease.ID.Provider) + + // test query lease + createdLease := leases[0].Lease + resp, err = clitestutil.QueryLeaseExec( + ctx, + cctx, + cli.TestFlags(). + WithLeaseID(createdLease.ID). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + var lease types.QueryLeaseResponse + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), &lease) + s.Require().NoError(err) + s.Require().Equal(createdLease, lease.Lease) + + // create bid + _, err = clitestutil.TxCloseBidExec( + ctx, + cctx, + cli.TestFlags(). + WithFrom(s.addrProvider.String()). + WithBidID(lease.Lease.ID.BidID()). + WithSkipConfirm(). + WithGasAutoFlags(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + + // test query closed bids + resp, err = clitestutil.QueryBidsExec( + ctx, + cctx, + cli.TestFlags(). + WithState("closed"). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + bidRes := &types.QueryBidsResponse{} + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), bidRes) + s.Require().NoError(err) + s.Require().Len(bidRes.Bids, 1) + s.Require().Equal(s.addrProvider.String(), bidRes.Bids[0].Bid.ID.Provider) + + // test query leases with state value filter + resp, err = clitestutil.QueryLeasesExec( + ctx, + cctx, + cli.TestFlags(). + WithState("closed"). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + leaseRes = &types.QueryLeasesResponse{} + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), leaseRes) + s.Require().NoError(err) + s.Require().Len(leaseRes.Leases, 1) + + // test query leases with wrong owner value + _, err = clitestutil.QueryLeasesExec( + ctx, + cctx, + cli.TestFlags(). + WithOwner("akash102ruvpv2srmunfffxavttxnhezln6fnc3pf7tt"). + WithOutputJSON()..., + ) + s.Require().Error(err) + + // test query leases with wrong state value + _, err = clitestutil.QueryLeasesExec( + ctx, + cctx, + cli.TestFlags(). + WithState("hello"). + WithOutputJSON()..., + ) + s.Require().Error(err) +} + +// Naming as Test{number} just to run all tests sequentially +func (s *marketIntegrationTestSuite) Test4CloseOrder() { + ctx := context.Background() + cctx := s.cctx + + // fetch open orders + resp, err := clitestutil.QueryOrdersExec( + ctx, + cctx, + cli.TestFlags(). + WithState("open"). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + result := &types.QueryOrdersResponse{} + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), result) + s.Require().NoError(err) + openedOrders := result.Orders + s.Require().Len(openedOrders, 0) +} diff --git a/tests/e2e/market_grpc_test.go b/tests/e2e/market_grpc_test.go new file mode 100644 index 0000000000..e7009120e0 --- /dev/null +++ b/tests/e2e/market_grpc_test.go @@ -0,0 +1,632 @@ +//go:build e2e.integration + +package e2e + +import ( + "context" + "fmt" + "path/filepath" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + sdktestutil "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + + "pkg.akt.dev/go/node/market/v1" + "pkg.akt.dev/go/node/market/v1beta5" + + "pkg.akt.dev/go/cli" + clitestutil "pkg.akt.dev/go/cli/testutil" + + "pkg.akt.dev/node/testutil" +) + +type marketGRPCRestTestSuite struct { + *testutil.NetworkTestSuite + + cctx client.Context + order v1beta5.Order + bid v1beta5.Bid + lease v1.Lease +} + +func (s *marketGRPCRestTestSuite) SetupSuite() { + s.NetworkTestSuite.SetupSuite() + + val := s.Network().Validators[0] + + s.cctx = val.ClientCtx + + kb := s.cctx.Keyring + keyBar, _, err := kb.NewMnemonic("keyBar", keyring.English, sdk.FullFundraiserPath, "", hd.Secp256k1) + s.Require().NoError(err) + + keyAddr, err := keyBar.GetAddress() + s.Require().NoError(err) + + ctx := context.Background() + + // Generate client certificate + _, err = clitestutil.TxGenerateClientExec( + ctx, + s.cctx, + cli.TestFlags(). + WithFrom(val.Address.String())..., + ) + s.Require().NoError(err) + + // Publish client certificate + _, err = clitestutil.TxPublishClientExec( + ctx, + s.cctx, + cli.TestFlags(). + WithFrom(val.Address.String()). + WithSkipConfirm(). + WithBroadcastModeBlock(). + WithGasAutoFlags()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForBlocks(2)) + + deploymentPath, err := filepath.Abs("../../x/deployment/testdata/deployment.yaml") + s.Require().NoError(err) + + providerPath, err := filepath.Abs("../../x/provider/testdata/provider.yaml") + s.Require().NoError(err) + + // create deployment + _, err = clitestutil.TxCreateDeploymentExec( + ctx, + s.cctx, + deploymentPath, + cli.TestFlags(). + WithFrom(val.Address.String()). + WithSkipConfirm(). + WithBroadcastModeBlock(). + WithDeposit(DefaultDeposit). + WithGasAutoFlags()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForBlocks(2)) + + // test query orders + resp, err := clitestutil.QueryOrdersExec( + ctx, val.ClientCtx.WithOutputFormat("json"), + ) + s.Require().NoError(err) + + result := &v1beta5.QueryOrdersResponse{} + err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), result) + s.Require().NoError(err) + s.Require().Len(result.Orders, 1) + orders := result.Orders + s.Require().Equal(val.Address.String(), orders[0].ID.Owner) + + // test query order + s.order = orders[0] + + // Send coins from validator to keyBar + sendTokens := DefaultDeposit.Add(DefaultDeposit) + _, err = clitestutil.ExecSend( + ctx, + val.ClientCtx, + cli.TestFlags(). + With( + val.Address.String(), + keyAddr.String(), + sdk.NewCoins(sendTokens).String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + + s.Require().NoError(s.Network().WaitForNextBlock()) + + // create provider + _, err = clitestutil.TxCreateProviderExec( + ctx, + s.cctx, + providerPath, + cli.TestFlags(). + WithFrom(keyAddr.String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + + s.Require().NoError(s.Network().WaitForNextBlock()) + + _, err = clitestutil.TxCreateBidExec( + ctx, + s.cctx, + cli.TestFlags(). + WithFrom(keyAddr.String()). + WithOrderID(s.order.ID). + WithPrice(sdk.NewDecCoinFromDec(testutil.CoinDenom, sdk.MustNewDecFromStr("1.1"))). + WithDeposit(DefaultDeposit). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + + s.Require().NoError(s.Network().WaitForNextBlock()) + + // get bid + resp, err = clitestutil.QueryBidsExec( + ctx, val.ClientCtx.WithOutputFormat("json"), + ) + s.Require().NoError(err) + + bidRes := &v1beta5.QueryBidsResponse{} + err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), bidRes) + s.Require().NoError(err) + s.Require().Len(bidRes.Bids, 1) + bids := bidRes.Bids + s.Require().Equal(keyAddr.String(), bids[0].Bid.ID.Provider) + + s.bid = bids[0].Bid + + // create lease + _, err = clitestutil.TxCreateLeaseExec( + ctx, + s.cctx, + cli.TestFlags(). + WithFrom(val.Address.String()). + WithBidID(s.bid.ID). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + + s.Require().NoError(s.Network().WaitForNextBlock()) + + // test query leases + resp, err = clitestutil.QueryLeasesExec( + ctx, + s.cctx, + cli.TestFlags(). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + leaseRes := &v1beta5.QueryLeasesResponse{} + err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), leaseRes) + s.Require().NoError(err) + s.Require().Len(leaseRes.Leases, 1) + leases := leaseRes.Leases + s.Require().Equal(keyAddr.String(), leases[0].Lease.ID.Provider) + + s.order.State = v1beta5.OrderActive + s.bid.State = v1beta5.BidActive + + // test query lease + s.lease = leases[0].Lease +} + +func (s *marketGRPCRestTestSuite) TestGetOrders() { + val := s.Network().Validators[0] + order := s.order + + testCases := []struct { + name string + url string + expErr bool + expResp v1beta5.Order + expLen int + }{ + { + "get orders without filters", + fmt.Sprintf("%s/akash/market/%s/orders/list", val.APIAddress, v1beta5.GatewayVersion), + false, + order, + 1, + }, + { + "get orders with filters", + fmt.Sprintf("%s/akash/market/%s/orders/list?filters.owner=%s", val.APIAddress, + v1beta5.GatewayVersion, + order.ID.Owner), + false, + order, + 1, + }, + { + "get orders with wrong state filter", + fmt.Sprintf("%s/akash/market/%s/orders/list?filters.state=%s", val.APIAddress, + v1beta5.GatewayVersion, + v1beta5.OrderStateInvalid.String()), + true, + v1beta5.Order{}, + 0, + }, + { + "get orders with two filters", + fmt.Sprintf("%s/akash/market/%s/orders/list?filters.state=%s&filters.oseq=%d", + val.APIAddress, v1beta5.GatewayVersion, order.State.String(), order.ID.OSeq), + false, + order, + 1, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + resp, err := sdktestutil.GetRequest(tc.url) + s.Require().NoError(err) + + var orders v1beta5.QueryOrdersResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp, &orders) + + if tc.expErr { + s.Require().NotNil(err) + s.Require().Empty(orders.Orders) + } else { + s.Require().NoError(err) + s.Require().Len(orders.Orders, tc.expLen) + s.Require().Equal(tc.expResp, orders.Orders[0]) + } + }) + } +} + +func (s *marketGRPCRestTestSuite) TestGetOrder() { + val := s.Network().Validators[0] + order := s.order + + testCases := []struct { + name string + url string + expErr bool + expResp v1beta5.Order + }{ + { + "get order with empty input", + fmt.Sprintf("%s/akash/market/%s/orders/info", val.APIAddress, v1beta5.GatewayVersion), + true, + v1beta5.Order{}, + }, + { + "get order with invalid input", + fmt.Sprintf("%s/akash/market/%s/orders/info?id.owner=%s", val.APIAddress, + v1beta5.GatewayVersion, + order.ID.Owner), + true, + v1beta5.Order{}, + }, + { + "order not found", + fmt.Sprintf("%s/akash/market/%s/orders/info?id.owner=%s&id.dseq=%d&id.gseq=%d&id.oseq=%d", + val.APIAddress, + v1beta5.GatewayVersion, + order.ID.Owner, 249, 32, 235), + true, + v1beta5.Order{}, + }, + { + "valid get order request", + fmt.Sprintf("%s/akash/market/%s/orders/info?id.owner=%s&id.dseq=%d&id.gseq=%d&id.oseq=%d", + val.APIAddress, + v1beta5.GatewayVersion, + order.ID.Owner, + order.ID.DSeq, + order.ID.GSeq, + order.ID.OSeq), + false, + order, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + resp, err := sdktestutil.GetRequest(tc.url) + s.Require().NoError(err) + + var out v1beta5.QueryOrderResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp, &out) + + if tc.expErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().Equal(tc.expResp, out.Order) + } + }) + } +} + +func (s *marketGRPCRestTestSuite) TestGetBids() { + val := s.Network().Validators[0] + bid := s.bid + + testCases := []struct { + name string + url string + expErr bool + expResp v1beta5.Bid + expLen int + }{ + { + "get bids without filters", + fmt.Sprintf("%s/akash/market/%s/bids/list", val.APIAddress, v1beta5.GatewayVersion), + false, + bid, + 1, + }, + { + "get bids with filters", + fmt.Sprintf("%s/akash/market/%s/bids/list?filters.owner=%s", + val.APIAddress, + v1beta5.GatewayVersion, + bid.ID.Owner), + false, + bid, + 1, + }, + { + "get bids with wrong state filter", + fmt.Sprintf("%s/akash/market/%s/bids/list?filters.state=%s", + val.APIAddress, + v1beta5.GatewayVersion, + v1beta5.BidStateInvalid.String()), + true, + v1beta5.Bid{}, + 0, + }, + { + "get bids with more filters", + fmt.Sprintf("%s/akash/market/%s/bids/list?filters.state=%s&filters.oseq=%d&filters.provider=%s", + val.APIAddress, + v1beta5.GatewayVersion, + bid.State.String(), + bid.ID.OSeq, + bid.ID.Provider), + false, + bid, + 1, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + resp, err := sdktestutil.GetRequest(tc.url) + s.Require().NoError(err) + + var bids v1beta5.QueryBidsResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp, &bids) + + if tc.expErr { + s.Require().NotNil(err) + s.Require().Empty(bids.Bids) + } else { + s.Require().NoError(err) + s.Require().Len(bids.Bids, tc.expLen) + s.Require().Equal(tc.expResp, bids.Bids[0].Bid) + } + }) + } +} + +func (s *marketGRPCRestTestSuite) TestGetBid() { + val := s.Network().Validators[0] + bid := s.bid + + testCases := []struct { + name string + url string + expErr bool + expResp v1beta5.Bid + }{ + { + "get bid with empty input", + fmt.Sprintf("%s/akash/market/%s/bids/info", val.APIAddress, v1beta5.GatewayVersion), + true, + v1beta5.Bid{}, + }, + { + "get bid with invalid input", + fmt.Sprintf("%s/akash/market/%s/bids/info?id.owner=%s", + val.APIAddress, + v1beta5.GatewayVersion, + bid.ID.Owner), + true, + v1beta5.Bid{}, + }, + { + "bid not found", + fmt.Sprintf("%s/akash/market/%s/bids/info?id.owner=%s&id.dseq=%d&id.gseq=%d&id.oseq=%d&id.provider=%s", + val.APIAddress, + v1beta5.GatewayVersion, + bid.ID.Provider, + 249, + 32, + 235, + bid.ID.Owner), + true, + v1beta5.Bid{}, + }, + { + "valid get bid request", + fmt.Sprintf("%s/akash/market/%s/bids/info?id.owner=%s&id.dseq=%d&id.gseq=%d&id.oseq=%d&id.provider=%s", + val.APIAddress, + v1beta5.GatewayVersion, + bid.ID.Owner, + bid.ID.DSeq, + bid.ID.GSeq, + bid.ID.OSeq, + bid.ID.Provider), + false, + bid, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + resp, err := sdktestutil.GetRequest(tc.url) + s.Require().NoError(err) + + var out v1beta5.QueryBidResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp, &out) + + if tc.expErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().Equal(tc.expResp, out.Bid) + } + }) + } +} + +func (s *marketGRPCRestTestSuite) TestGetLeases() { + val := s.Network().Validators[0] + lease := s.lease + + testCases := []struct { + name string + url string + expErr bool + expResp v1.Lease + expLen int + }{ + { + "get leases without filters", + fmt.Sprintf("%s/akash/market/%s/leases/list", val.APIAddress, v1beta5.GatewayVersion), + false, + lease, + 1, + }, + { + "get leases with filters", + fmt.Sprintf("%s/akash/market/%s/leases/list?filters.owner=%s", + val.APIAddress, + v1beta5.GatewayVersion, + lease.ID.Owner), + false, + lease, + 1, + }, + { + "get leases with wrong state filter", + fmt.Sprintf("%s/akash/market/%s/leases/list?filters.state=%s", + val.APIAddress, + v1beta5.GatewayVersion, + v1.LeaseStateInvalid.String()), + true, + v1.Lease{}, + 0, + }, + { + "get leases with more filters", + fmt.Sprintf("%s/akash/market/%s/leases/list?filters.state=%s&filters.oseq=%d&filters.provider=%s", + val.APIAddress, + v1beta5.GatewayVersion, + lease.State.String(), + lease.ID.OSeq, + lease.ID.Provider), + false, + lease, + 1, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + resp, err := sdktestutil.GetRequest(tc.url) + s.Require().NoError(err) + + var leases v1beta5.QueryLeasesResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp, &leases) + + if tc.expErr { + s.Require().NotNil(err) + s.Require().Empty(leases.Leases) + } else { + s.Require().NoError(err) + s.Require().Len(leases.Leases, tc.expLen) + s.Require().Equal(tc.expResp, leases.Leases[0].Lease) + } + }) + } +} + +func (s *marketGRPCRestTestSuite) TestGetLease() { + val := s.Network().Validators[0] + lease := s.lease + + testCases := []struct { + name string + url string + expErr bool + expResp v1.Lease + }{ + { + "get lease with empty input", + fmt.Sprintf("%s/akash/market/%s/leases/info", val.APIAddress, v1beta5.GatewayVersion), + true, + v1.Lease{}, + }, + { + "get lease with invalid input", + fmt.Sprintf("%s/akash/market/%s/leases/info?id.owner=%s", + val.APIAddress, + v1beta5.GatewayVersion, + lease.ID.Owner), + true, + v1.Lease{}, + }, + { + "lease not found", + fmt.Sprintf("%s/akash/market/%s/leases/info?id.owner=%s&id.dseq=%d&id.gseq=%d&id.oseq=%d&id.provider=%s", + val.APIAddress, + v1beta5.GatewayVersion, + lease.ID.Provider, + 249, + 32, + 235, + lease.ID.Owner), + true, + v1.Lease{}, + }, + { + "valid get lease request", + fmt.Sprintf("%s/akash/market/%s/leases/info?id.owner=%s&id.dseq=%d&id.gseq=%d&id.oseq=%d&id.provider=%s", + val.APIAddress, + v1beta5.GatewayVersion, + lease.ID.Owner, + lease.ID.DSeq, + lease.ID.GSeq, + lease.ID.OSeq, + lease.ID.Provider), + false, + lease, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + resp, err := sdktestutil.GetRequest(tc.url) + s.Require().NoError(err) + + var out v1beta5.QueryLeaseResponse + err = val.ClientCtx.Codec.UnmarshalJSON(resp, &out) + + if tc.expErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().Equal(tc.expResp, out.Lease) + } + }) + } +} diff --git a/tests/e2e/provider_cli_test.go b/tests/e2e/provider_cli_test.go new file mode 100644 index 0000000000..93a6b122b9 --- /dev/null +++ b/tests/e2e/provider_cli_test.go @@ -0,0 +1,107 @@ +//go:build e2e.integration + +package e2e + +import ( + "context" + "path/filepath" + + "pkg.akt.dev/go/cli" + clitestutil "pkg.akt.dev/go/cli/testutil" + + types "pkg.akt.dev/go/node/provider/v1beta4" + + "pkg.akt.dev/node/testutil" +) + +type providerIntegrationTestSuite struct { + *testutil.NetworkTestSuite +} + +func (s *providerIntegrationTestSuite) TestProvider() { + cctx := s.ClientContextForTest() + addr := s.WalletForTest() + + providerPath, err := filepath.Abs("../../x/provider/testdata/provider.yaml") + s.Require().NoError(err) + + providerPath2, err := filepath.Abs("../../x/provider/testdata/provider2.yaml") + s.Require().NoError(err) + + ctx := context.Background() + + // create provider + _, err = clitestutil.TxCreateProviderExec( + ctx, + cctx, + providerPath, + cli.TestFlags(). + WithFrom(addr.String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + s.Require().NoError(s.Network().WaitForNextBlock()) + + // test query providers + resp, err := clitestutil.QueryProvidersExec( + ctx, + cctx, + cli.TestFlags(). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + out := &types.QueryProvidersResponse{} + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), out) + s.Require().NoError(err) + s.Require().Len(out.Providers, 1, "Provider Creation Failed") + providers := out.Providers + s.Require().Equal(addr.String(), providers[0].Owner) + + // test query provider + createdProvider := providers[0] + resp, err = clitestutil.QueryProviderExec( + ctx, + cctx, + cli.TestFlags(). + With(createdProvider.Owner). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + var provider types.Provider + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), &provider) + s.Require().NoError(err) + s.Require().Equal(createdProvider, provider) + + // test updating provider + _, err = clitestutil.TxUpdateProviderExec( + ctx, + cctx, + providerPath2, + cli.TestFlags(). + WithFrom(addr.String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + + s.Require().NoError(s.Network().WaitForNextBlock()) + + resp, err = clitestutil.QueryProviderExec( + ctx, + cctx, + cli.TestFlags(). + With(createdProvider.Owner). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + var providerV2 types.Provider + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), &providerV2) + s.Require().NoError(err) + s.Require().NotEqual(provider.HostURI, providerV2.HostURI) +} diff --git a/tests/e2e/provider_grpc_test.go b/tests/e2e/provider_grpc_test.go new file mode 100644 index 0000000000..ef26357ddd --- /dev/null +++ b/tests/e2e/provider_grpc_test.go @@ -0,0 +1,163 @@ +//go:build e2e.integration + +package e2e + +import ( + "context" + "fmt" + "path/filepath" + + "pkg.akt.dev/go/cli" + clitestutil "pkg.akt.dev/go/cli/testutil" + + sdktestutil "github.com/cosmos/cosmos-sdk/testutil" + types "pkg.akt.dev/go/node/provider/v1beta4" + + "pkg.akt.dev/node/testutil" +) + +type providerGRPCRestTestSuite struct { + *testutil.NetworkTestSuite + + provider types.Provider +} + +func (s *providerGRPCRestTestSuite) SetupSuite() { + s.NetworkTestSuite.SetupSuite() + + providerPath, err := filepath.Abs("../../x/provider/testdata/provider.yaml") + s.Require().NoError(err) + + ctx := context.Background() + + val := s.Network().Validators[0] + cctx := val.ClientCtx + + // create deployment + _, err = clitestutil.TxCreateProviderExec( + ctx, + cctx, + providerPath, + cli.TestFlags(). + WithFrom(val.Address.String()). + WithGasAutoFlags(). + WithSkipConfirm(). + WithBroadcastModeBlock()..., + ) + s.Require().NoError(err) + + s.Require().NoError(s.Network().WaitForNextBlock()) + + // get provider + resp, err := clitestutil.QueryProvidersExec( + ctx, + cctx, + cli.TestFlags(). + WithOutputJSON()..., + ) + s.Require().NoError(err) + + out := &types.QueryProvidersResponse{} + err = cctx.Codec.UnmarshalJSON(resp.Bytes(), out) + s.Require().NoError(err) + s.Require().Len(out.Providers, 1, "Provider Creation Failed") + providers := out.Providers + s.Require().Equal(val.Address.String(), providers[0].Owner) + + s.provider = providers[0] +} + +func (s *providerGRPCRestTestSuite) TestGetProviders() { + val := s.Network().Validators[0] + cctx := val.ClientCtx + + provider := s.provider + + testCases := []struct { + name string + url string + expResp types.Provider + expLen int + }{ + { + "get providers without pagination", + fmt.Sprintf("%s/akash/provider/v1beta4/providers", val.APIAddress), + provider, + 1, + }, + { + "get providers with pagination", + fmt.Sprintf("%s/akash/provider/v1beta4/providers?pagination.offset=2", val.APIAddress), + types.Provider{}, + 0, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + resp, err := sdktestutil.GetRequest(tc.url) + s.Require().NoError(err) + + var providers types.QueryProvidersResponse + err = cctx.Codec.UnmarshalJSON(resp, &providers) + + s.Require().NoError(err) + s.Require().Len(providers.Providers, tc.expLen) + if tc.expLen != 0 { + s.Require().Equal(tc.expResp, providers.Providers[0]) + } + }) + } +} + +func (s *providerGRPCRestTestSuite) TestGetProvider() { + val := s.Network().Validators[0] + cctx := val.ClientCtx + + provider := s.provider + + testCases := []struct { + name string + url string + expErr bool + expResp types.Provider + }{ + { + "get provider with empty input", + fmt.Sprintf("%s/akash/provider/v1beta4/providers/%s", val.APIAddress, ""), + true, + types.Provider{}, + }, + { + "get provider with invalid input", + fmt.Sprintf("%s/akash/provider/v1beta4/providers/%s", val.APIAddress, "hellohai"), + true, + types.Provider{}, + }, + { + "valid get provider request", + fmt.Sprintf("%s/akash/provider/v1beta4/providers/%s", val.APIAddress, provider.Owner), + false, + provider, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + resp, err := sdktestutil.GetRequest(tc.url) + s.Require().NoError(err) + + var out types.QueryProviderResponse + err = cctx.Codec.UnmarshalJSON(resp, &out) + + if tc.expErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().Equal(tc.expResp, out.Provider) + } + }) + } +} diff --git a/tests/upgrade/config.json b/tests/upgrade/config.json index b53fbddde4..85b2d24c0e 100644 --- a/tests/upgrade/config.json +++ b/tests/upgrade/config.json @@ -6,6 +6,42 @@ { "name": "validator0", "index": 0 + }, + { + "name": "validator1", + "index": 1 + }, + { + "name": "validator2", + "index": 2 + }, + { + "name": "test0", + "index": 3 + }, + { + "name": "test1", + "index": 4 + }, + { + "name": "test2", + "index": 5 + }, + { + "name": "test3", + "index": 6 + }, + { + "name": "test4", + "index": 7 + }, + { + "name": "test5", + "index": 8 + }, + { + "name": "test6", + "index": 9 } ] } diff --git a/tests/upgrade/test-cases.json b/tests/upgrade/test-cases.json index 3ad729b582..9edaacc110 100644 --- a/tests/upgrade/test-cases.json +++ b/tests/upgrade/test-cases.json @@ -1,25 +1,183 @@ { - "v0.38.0": { + "v1.0.0": { + "modules": { + "added": [ + "07-tendermint", + "consensus" + ] + }, "migrations": { + "auth": [ + { + "from": "2", + "to": "3" + }, + { + "from": "3", + "to": "4" + }, { + "from": "4", + "to": "5" + } + ], + "authz": [ + { + "from": "2", + "to": "3" + } + ], + "bank": [ + { + "from": "2", + "to": "3" + }, + { + "from": "3", + "to": "4" + } + ], "cert": [ + { + "from": "3", + "to": "4" + } + ], + "deployment": [ + { + "from": "4", + "to": "5" + } + ], + "distribution": [ { "from": "2", "to": "3" } ], - "market": [ + "audit": [ + { + "from": "2", + "to": "3" + } + ], + "escrow": [ + { + "from": "2", + "to": "3" + } + ], + "feegrant": [ + { + "from": "1", + "to": "2" + } + ], + "gov": [ + { + "from": "2", + "to": "3" + }, + { + "from": "3", + "to": "4" + }, + { + "from": "4", + "to": "5" + } + ], + "ibc": [ + { + "from": "2", + "to": "3" + }, + { + "from": "3", + "to": "4" + }, + { + "from": "4", + "to": "5" + }, { "from": "5", "to": "6" + }, + { + "from": "6", + "to": "7" + }, + { + "from": "7", + "to": "8" } ], - "deployment": [ + "market": [ + { + "from": "6", + "to": "7" + } + ], + "mint": [ + { + "from": "1", + "to": "2" + } + ], + "provider": [ + { + "from": "2", + "to": "3" + } + ], + "slashing": [ + { + "from": "2", + "to": "3" + }, { "from": "3", "to": "4" } ], - "authz": [ + "staking": [ + { + "from": "2", + "to": "3" + }, + { + "from": "3", + "to": "4" + }, + { + "from": "4", + "to": "5" + } + ], + "take": [ + { + "from": "2", + "to": "3" + } + ], + "transfer": [ + { + "from": "2", + "to": "3" + }, { + "from": "3", + "to": "4" + }, + { + "from": "4", + "to": "5" + }, + { + "from": "5", + "to": "6" + } + ], + "upgrade": [ { "from": "1", "to": "2" diff --git a/tests/upgrade/test-config-gha.json b/tests/upgrade/test-config-gha.json new file mode 100644 index 0000000000..a9ec58b481 --- /dev/null +++ b/tests/upgrade/test-config-gha.json @@ -0,0 +1,10 @@ +{ + "chain-id": "localakash", + "validators": [ + ".akash0" + ], + "work": { + "home": ".akash0", + "key": "validator0" + } +} diff --git a/tests/upgrade/test-config.json b/tests/upgrade/test-config.json index a9ec58b481..c6f36a4220 100644 --- a/tests/upgrade/test-config.json +++ b/tests/upgrade/test-config.json @@ -1,7 +1,8 @@ { "chain-id": "localakash", "validators": [ - ".akash0" + ".akash0", + ".akash1" ], "work": { "home": ".akash0", diff --git a/tests/upgrade/testnet.json b/tests/upgrade/testnet.json index 83252dd2be..65e2d9e4d5 100644 --- a/tests/upgrade/testnet.json +++ b/tests/upgrade/testnet.json @@ -6,20 +6,67 @@ } }, "accounts": [ - "akash1dge0lcc5rqxkw52rgav4q0fyhx7arcufmrkyww" + { + "address": "akash1dge0lcc5rqxkw52rgav4q0fyhx7arcufmrkyww", + "balances": [ + { + "denom": "uakt", + "amount": "1000000000000000" + }, + { + "denom": "ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D84", + "amount": "1000000000000" + } + ] + }, + { + "address": "akash18tdthhtcvfmzl60r0r6gvjdcelc0wtwfumqsdz", + "balances": [ + { + "denom": "uakt", + "amount": "1000000000000000" + }, + { + "denom": "ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D84", + "amount": "1000000000000" + } + ] + }, + { + "address": "akash1sdv7sz7y4j2z9l6nyrk9g4ztjh9dvml75gfgra", + "balances": [ + { + "denom": "uakt", + "amount": "1000000000000000" + }, + { + "denom": "ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D84", + "amount": "1000000000000" + } + ] + } ], "validators": [ { "moniker": "upgrade-tester-1", "operator": "akash1dge0lcc5rqxkw52rgav4q0fyhx7arcufmrkyww", - "bonded": true, + "status": 3, "home": ".akash0", "commission": { "rate": "0.05", "maxRate": "0.8", "maxChangeRate": "0.1" }, - "min_self_delegation": "1" + "min_self_delegation": "1", + "delegations": [ + { + "address": "akash1dge0lcc5rqxkw52rgav4q0fyhx7arcufmrkyww", + "amount": { + "denom": "uakt", + "amount": "900000000000000" + } + } + ] } ] } diff --git a/tests/upgrade/types/types.go b/tests/upgrade/types/types.go index eef62eaa88..cfc20f4cd5 100644 --- a/tests/upgrade/types/types.go +++ b/tests/upgrade/types/types.go @@ -1,4 +1,4 @@ -package types +package types //nolint: revive import ( "context" diff --git a/tests/upgrade/upgrade_test.go b/tests/upgrade/upgrade_test.go index 969afae3ea..8ff059ab5e 100644 --- a/tests/upgrade/upgrade_test.go +++ b/tests/upgrade/upgrade_test.go @@ -15,12 +15,14 @@ import ( "os/signal" "regexp" "runtime" + "runtime/debug" "strconv" "strings" "syscall" "testing" "time" + sdkmath "cosmossdk.io/math" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/mod/semver" @@ -29,11 +31,11 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" // init sdk config - _ "github.com/akash-network/akash-api/go/sdkutil" + _ "pkg.akt.dev/go/sdkutil" - "github.com/akash-network/node/pubsub" - uttypes "github.com/akash-network/node/tests/upgrade/types" - "github.com/akash-network/node/util/cli" + "pkg.akt.dev/node/pubsub" + uttypes "pkg.akt.dev/node/tests/upgrade/types" + "pkg.akt.dev/node/util/cli" ) const ( @@ -50,7 +52,7 @@ const ( nodeEventStart nodeEvent = iota nodeEventReplayBlocksStart nodeEventReplayBlocksDone - nodeEventBlockIndexed + nodeEventBlockCommited nodeEventUpgradeDetected nodeEventAddedModule nodeEventRemovedModule @@ -396,7 +398,9 @@ func TestUpgrade(t *testing.T) { fmt.Sprintf("AKASH_GAS_ADJUSTMENT=2"), fmt.Sprintf("AKASH_P2P_PEX=false"), fmt.Sprintf("AKASH_MINIMUM_GAS_PRICES=0.0025uakt"), - fmt.Sprintf("AKASH_GAS=auto"), + //fmt.Sprintf("AKASH_GAS=auto"), + // auto is failing with rpc error: code = Unknown desc = unknown query path: unknown request + fmt.Sprintf("AKASH_GAS=500000"), fmt.Sprintf("AKASH_YES=true"), }, } @@ -454,16 +458,16 @@ func TestUpgrade(t *testing.T) { listenAddr := "127.0.0.1" for name, params := range initParams { - var unconditionalPeerIDs string - var persistentPeers string + unconditionalPeerIDs := make([]string, 0, len(initParams)) + persistentPeers := make([]string, 0, len(initParams)) for nm1, params1 := range initParams { if name == nm1 { continue } - unconditionalPeerIDs += params1.nodeID + "," - persistentPeers += fmt.Sprintf("%s@%s:%d,", params1.nodeID, listenAddr, params1.p2pPort) + unconditionalPeerIDs = append(unconditionalPeerIDs, params1.nodeID) + persistentPeers = append(persistentPeers, fmt.Sprintf("%s@%s:%d", params1.nodeID, listenAddr, params1.p2pPort)) } validatorsParams[name] = validatorParams{ @@ -482,11 +486,11 @@ func TestUpgrade(t *testing.T) { fmt.Sprintf("HOME=%s", *workdir), fmt.Sprintf("AKASH_HOME=%s", params.homedir), fmt.Sprintf("AKASH_CHAIN_ID=%s", cfg.ChainID), - fmt.Sprintf("AKASH_P2P_PERSISTENT_PEERS=%s", strings.TrimSuffix(persistentPeers, ",")), - fmt.Sprintf("AKASH_P2P_UNCONDITIONAL_PEER_IDS=%s", strings.TrimSuffix(unconditionalPeerIDs, ",")), + fmt.Sprintf("AKASH_P2P_PERSISTENT_PEERS=%s", strings.Join(persistentPeers, ",")), + fmt.Sprintf("AKASH_P2P_UNCONDITIONAL_PEER_IDS=%s", strings.Join(unconditionalPeerIDs, ",")), fmt.Sprintf("AKASH_P2P_LADDR=tcp://%s:%d", listenAddr, params.p2pPort), fmt.Sprintf("AKASH_RPC_LADDR=tcp://%s:%d", listenAddr, params.rpc.port), - // fmt.Sprintf("AKASH_RPC_GRPC_LADDR=tcp://%s:%d", listenAddr, params.rpc.grpc), + fmt.Sprintf("AKASH_RPC_GRPC_LADDR=tcp://%s:%d", listenAddr, params.rpc.grpc), fmt.Sprintf("AKASH_RPC_PPROF_LADDR=%s:%d", listenAddr, params.pprofPort), fmt.Sprintf("AKASH_GRPC_ADDRESS=%s:%d", listenAddr, params.grpcPort), fmt.Sprintf("AKASH_GRPC_WEB_ADDRESS=%s:%d", listenAddr, params.grpcWebPort), @@ -498,7 +502,7 @@ func TestUpgrade(t *testing.T) { "COSMOVISOR_COLOR_LOGS=false", "UNSAFE_SKIP_BACKUP=true", "AKASH_KEYRING_BACKEND=test", - "AKASH_P2P_PEX=true", + "AKASH_P2P_PEX=false", "AKASH_P2P_ADDR_BOOK_STRICT=false", "AKASH_P2P_ALLOW_DUPLICATE_IP=true", "AKASH_P2P_SEEDS=", @@ -708,7 +712,7 @@ func (l *upgradeTest) submitUpgradeProposal() error { return err } - votePeriod, valid := sdk.NewIntFromString(params.VotingParams.VotingPeriod) + votePeriod, valid := sdkmath.NewIntFromString(params.VotingParams.VotingPeriod) if !valid { return fmt.Errorf("invalid vote period value (%s)", params.VotingParams.VotingPeriod) } @@ -868,13 +872,20 @@ func (l *validator) run() error { defer l.t.Logf("[%s] log scanner finished", l.params.name) l.t.Logf("[%s] log scanner started", l.params.name) + var err error defer func() { if r := recover(); r != nil { + l.t.Logf("%s", string(debug.Stack())) l.t.Fatal(r) } + + if err != nil { + l.t.Logf("%s", err.Error()) + } }() - return l.scanner(rStdout, l.pubsub) + err = l.scanner(rStdout, l.pubsub) + return err }) l.group.Go(func() error { @@ -1016,7 +1027,7 @@ loop: l.t.Logf("[%s][%s]: node done replaying blocks", l.params.name, nodeTestStageMapStr[stage]) wdCtrl(l.ctx, watchdogCtrlStart) replayDone = true - case nodeEventBlockIndexed: + case nodeEventBlockCommited: // ignore index events until replay done if !replayDone { break @@ -1150,7 +1161,7 @@ loop: switch module.status { case testModuleStatusChecked: if !module.expected.compare(module.actual) { - merr := "migration for module (%s) finished with mismatched versions:\n" + merr := fmt.Sprintf("migration for module (%s) finished with mismatched versions:\n", name) merr += "\texpected:\n" for _, m := range module.expected { @@ -1195,9 +1206,9 @@ func (l *validator) blocksWatchdog(ctx context.Context, sub pubsub.Subscriber) e }() // first few blocks may take a while to produce. - // give a dog generous timeout on them + // give a watchdog a generous timeout on them - blockWindow := 60 * time.Minute + blockWindow := 180 * time.Minute blocksTm := time.NewTicker(blockWindow) blocksTm.Stop() @@ -1223,9 +1234,9 @@ loop: case watchdogCtrlBlock: blocks++ - // if blocks > 3 { - // blockWindow = blockTimeWindow - // } + if blocks > 3 { + blockWindow = blockTimeWindow + } blocksTm.Reset(blockWindow) case watchdogCtrlPause: @@ -1248,15 +1259,21 @@ loop: func (l *validator) scanner(stdout io.Reader, p publisher) error { scanner := bufio.NewScanner(stdout) - serverStart := "INF starting node with ABCI Tendermint in-process" + serverStart := "INF starting node with ABCI " replayBlocksStart := "INF ABCI Replay Blocks appHeight" - replayBlocksDone := "INF Replay: Done module=consensus" + replayBlocksDone := "INF service start impl=Evidence" executedBlock := "INF indexed block " + executedBlock2 := "INF committed state block_app_hash=" upgradeNeeded := fmt.Sprintf(`ERR UPGRADE "%s" NEEDED at height:`, l.params.upgradeName) addingNewModule := "INF adding a new module: " migratingModule := "INF migrating module " - rNewModule, err := regexp.Compile(`^` + addingNewModule + `(\w+)$`) + rServerStart, err := regexp.Compile(`^` + serverStart + `(Tendermint|CometBFT) in-process`) + if err != nil { + return err + } + + rNewModule, err := regexp.Compile(`^` + addingNewModule + `(.+) (.+)$`) if err != nil { return err } @@ -1275,22 +1292,33 @@ scan: if strings.Contains(line, upgradeNeeded) { evt.id = nodeEventUpgradeDetected } else if strings.Contains(line, serverStart) { + res := rServerStart.FindAllStringSubmatch(line, -1) + if len(res) != 1 || len(res[0]) != 2 { + return fmt.Errorf("line \"%s\" does not match regex \"%s\"", line, rServerStart.String()) + } evt.id = nodeEventStart } else if strings.Contains(line, replayBlocksStart) { evt.id = nodeEventReplayBlocksStart } else if strings.Contains(line, replayBlocksDone) { evt.id = nodeEventReplayBlocksDone - } else if strings.Contains(line, executedBlock) { - evt.id = nodeEventBlockIndexed + } else if strings.Contains(line, executedBlock) || strings.Contains(line, executedBlock2) { + evt.id = nodeEventBlockCommited } else if strings.Contains(line, addingNewModule) { evt.id = nodeEventAddedModule res := rNewModule.FindAllStringSubmatch(line, -1) + if len(res) != 1 || len(res[0]) != 3 { + return fmt.Errorf("line \"%s\" does not match regex \"%s\"", line, rNewModule.String()) + } evt.ctx = eventCtxModule{ name: res[0][1], } } else if strings.Contains(line, migratingModule) { evt.id = nodeEventModuleMigration res := rModuleMigration.FindAllStringSubmatch(line, -1) + if len(res) != 1 || len(res[0]) != 4 { + return fmt.Errorf("line \"%s\" does not match regex \"%s\"", line, rModuleMigration.String()) + } + evt.ctx = eventCtxModuleMigration{ name: res[0][1], from: res[0][2], diff --git a/tests/upgrade/v0.26.0/postupgrade.go b/tests/upgrade/v0.26.0/postupgrade.go deleted file mode 100644 index 7931e3da2d..0000000000 --- a/tests/upgrade/v0.26.0/postupgrade.go +++ /dev/null @@ -1,176 +0,0 @@ -//go:build e2e.upgrade - -// Package v0_26_0 -// nolint revive -package v0_26_0 - -import ( - "context" - "fmt" - "strings" - "testing" - - // v1beta2dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta2" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/query" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/authz" - "github.com/cosmos/cosmos-sdk/x/params/types/proposal" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - astaking "github.com/akash-network/akash-api/go/node/staking/v1beta3" - - "github.com/akash-network/node/app" - uttypes "github.com/akash-network/node/tests/upgrade/types" -) - -func init() { - uttypes.RegisterPostUpgradeWorker("v0.26.0", &postUpgrade{}) -} - -type postUpgrade struct{} - -var _ uttypes.TestWorker = (*postUpgrade)(nil) - -func (pu *postUpgrade) Run(ctx context.Context, t *testing.T, params uttypes.TestParams) { - encodingConfig := app.MakeEncodingConfig() - - rpcClient, err := client.NewClientFromNode(params.Node) - require.NoError(t, err) - - cctx := client.Context{}. - WithCodec(encodingConfig.Marshaler). - WithInterfaceRegistry(encodingConfig.InterfaceRegistry). - WithTxConfig(encodingConfig.TxConfig). - WithLegacyAmino(encodingConfig.Amino). - WithAccountRetriever(authtypes.AccountRetriever{}). - WithBroadcastMode(flags.BroadcastBlock). - WithHomeDir(params.Home). - WithChainID(params.ChainID). - WithNodeURI(params.Node). - WithClient(rpcClient) - - kr, err := client.NewKeyringFromBackend(cctx, params.KeyringBackend) - require.NoError(t, err) - - cctx = cctx.WithKeyring(kr) - - validateValidatorsCommission(ctx, cctx, t) - validateDeploymentAuthz(ctx, cctx, t) -} - -func validateDeploymentAuthz(ctx context.Context, cctx client.Context, t *testing.T) { - authQc := authtypes.NewQueryClient(cctx) - authzQc := authz.NewQueryClient(cctx) - - var pkey []byte - - accs := make([]sdk.AccAddress, 0, 100000) - - for { - var pgn *query.PageRequest - if pkey != nil { - pgn = &query.PageRequest{ - Key: pkey, - } - } - - result, err := authQc.Accounts(ctx, &authtypes.QueryAccountsRequest{ - Pagination: pgn, - }) - - require.NoError(t, err) - - for _, accI := range result.Accounts { - var acc authtypes.AccountI - err := cctx.Codec.UnpackAny(accI, &acc) - require.NoError(t, err) - - accs = append(accs, acc.GetAddress()) - } - - if pg := result.Pagination; pg != nil && len(pg.NextKey) > 0 { - pkey = pg.NextKey - } else { - break - } - } - - for _, acc := range accs { - result, err := authzQc.GranterGrants(ctx, &authz.QueryGranterGrantsRequest{Granter: acc.String()}) - require.NoError(t, err) - - if len(result.Grants) == 0 { - continue - } - - for _, grant := range result.Grants { - assert.NotEqual(t, - "/akash.deployment.v1beta2.DepositDeploymentAuthorization", - grant.Authorization.GetTypeUrl(), - "detected non-migrated v1beta2.DepositDeploymentAuthorization. granter: (%s), grantee: (%s)", grant.Granter, grant.Grantee) - // authzOld := &v1beta2dtypes.DepositDeploymentAuthorization{} - // - // err := cctx.Codec.UnpackAny(grant.Authorization, authzOld) - // assert.Error(t, err, "detected non-migrated v1beta2.DepositDeploymentAuthorization. granter: (%s), grantee: (%s)", grant.Granter, grant.Grantee) - } - } -} - -func validateValidatorsCommission(ctx context.Context, cctx client.Context, t *testing.T) { - pqc := proposal.NewQueryClient(cctx) - res, err := pqc.Params(ctx, &proposal.QueryParamsRequest{ - Subspace: stakingtypes.ModuleName, - Key: string(stakingtypes.KeyMaxValidators), - }) - require.NoError(t, err) - - require.NoError(t, err) - - res, err = pqc.Params(ctx, &proposal.QueryParamsRequest{ - Subspace: astaking.ModuleName, - Key: string(astaking.KeyMinCommissionRate), - }) - require.NoError(t, err) - - minCommission, err := sdk.NewDecFromStr(strings.Trim(res.Param.Value, "\"")) - require.NoError(t, err) - - sqc := stakingtypes.NewQueryClient(cctx) - - var pkey []byte - - for { - var pgn *query.PageRequest - if pkey != nil { - pgn = &query.PageRequest{ - Key: pkey, - } - } - - result, err := sqc.Validators(ctx, &stakingtypes.QueryValidatorsRequest{ - Pagination: pgn, - }) - require.NoError(t, err) - - for _, validator := range result.Validators { - assert.True(t, validator.Commission.Rate.GTE(minCommission), - fmt.Sprintf("invalid commission Rate for validator (%s). (%s%%) < (%s%%)MinCommission", - validator.OperatorAddress, validator.Commission.Rate.String(), minCommission.String())) - - assert.True(t, validator.Commission.MaxRate.GTE(minCommission), - fmt.Sprintf("invalid commission MaxRate for validator (%s). (%s%%) < (%s%%)MinCommission", - validator.OperatorAddress, validator.Commission.MaxRate.String(), minCommission.String())) - } - - if pg := result.Pagination; pg != nil && len(pg.NextKey) > 0 { - pkey = pg.NextKey - } else { - break - } - } -} diff --git a/tests/upgrade/v0.32.0/postupgrade.go b/tests/upgrade/v0.32.0/postupgrade.go deleted file mode 100644 index 390649f183..0000000000 --- a/tests/upgrade/v0.32.0/postupgrade.go +++ /dev/null @@ -1,118 +0,0 @@ -//go:build e2e.upgrade - -// Package v0_32_0 -// nolint revive -package v0_32_0 - -import ( - "context" - "testing" - - types "github.com/akash-network/akash-api/go/node/types/v1beta3" - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/stretchr/testify/require" - - cltypes "github.com/akash-network/akash-api/go/node/client/types" - ptypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" - - "github.com/akash-network/node/app" - "github.com/akash-network/node/client" - uttypes "github.com/akash-network/node/tests/upgrade/types" -) - -func init() { - uttypes.RegisterPostUpgradeWorker("v0.32.0", &postUpgrade{}) -} - -type postUpgrade struct{} - -var _ uttypes.TestWorker = (*postUpgrade)(nil) - -func (pu *postUpgrade) Run(ctx context.Context, t *testing.T, params uttypes.TestParams) { - encodingConfig := app.MakeEncodingConfig() - - rpcClient, err := sdkclient.NewClientFromNode(params.Node) - require.NoError(t, err) - - cctx := sdkclient.Context{}. - WithCodec(encodingConfig.Marshaler). - WithInterfaceRegistry(encodingConfig.InterfaceRegistry). - WithTxConfig(encodingConfig.TxConfig). - WithLegacyAmino(encodingConfig.Amino). - WithAccountRetriever(authtypes.AccountRetriever{}). - WithBroadcastMode(flags.BroadcastBlock). - WithHomeDir(params.Home). - WithChainID(params.ChainID). - WithNodeURI(params.Node). - WithClient(rpcClient). - WithSkipConfirmation(true). - WithFrom(params.From). - WithKeyringDir(params.Home) - - kr, err := sdkclient.NewKeyringFromBackend(cctx, params.KeyringBackend) - require.NoError(t, err) - - info, err := kr.Key(params.From) - require.NoError(t, err) - - cctx = cctx.WithFromName(info.GetName()). - WithFromAddress(info.GetAddress()). - WithKeyring(kr) - - cl, err := client.DiscoverClient(ctx, cctx, cltypes.WithGasPrices("0.0025uakt"), cltypes.WithGas(flags.GasSetting{Simulate: false, Gas: 100000})) - require.NoError(t, err) - require.NotNil(t, cl) - - cmsg := &ptypes.MsgCreateProvider{ - Owner: cctx.GetFromAddress().String(), - HostURI: "https://example.com:443", - Info: ptypes.ProviderInfo{}, - Attributes: types.Attributes{ - { - Key: "test1", - Value: "test1", - }, - }, - } - - err = cmsg.ValidateBasic() - require.NoError(t, err) - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{cmsg}) - require.NoError(t, err) - require.NotNil(t, resp) - require.IsType(t, &sdk.TxResponse{}, resp) - - txResp := resp.(*sdk.TxResponse) - - require.Equal(t, uint32(0), txResp.Code) - - pmsg := &ptypes.MsgUpdateProvider{ - Owner: cctx.GetFromAddress().String(), - HostURI: "https://example.com:443", - Info: ptypes.ProviderInfo{}, - Attributes: types.Attributes{ - { - Key: "test1", - Value: "test1", - }, - }, - } - - err = cmsg.ValidateBasic() - require.NoError(t, err) - - resp, err = cl.Tx().Broadcast(ctx, []sdk.Msg{pmsg}) - require.NoError(t, err) - require.NotNil(t, resp) - require.IsType(t, &sdk.TxResponse{}, resp) - - txResp = resp.(*sdk.TxResponse) - - require.Equal(t, uint32(0), txResp.Code) - require.LessOrEqual(t, txResp.GasUsed, int64(100000)) -} diff --git a/tests/upgrade/v0.34.0/postupgrade.go b/tests/upgrade/v0.34.0/postupgrade.go deleted file mode 100644 index 80ceb65b96..0000000000 --- a/tests/upgrade/v0.34.0/postupgrade.go +++ /dev/null @@ -1,346 +0,0 @@ -//go:build e2e.upgrade - -// Package v0_34_0 -// nolint revive -package v0_34_0 - -import ( - "context" - "testing" - "time" - - "github.com/spf13/pflag" - "github.com/stretchr/testify/require" - - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/authz" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/go-bip39" - - cltypes "github.com/akash-network/akash-api/go/node/client/types" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - - "github.com/akash-network/node/app" - "github.com/akash-network/node/client" - "github.com/akash-network/node/cmd/common" - "github.com/akash-network/node/sdl" - uttypes "github.com/akash-network/node/tests/upgrade/types" -) - -const ( - mnemonicEntropySize = 256 -) - -const ( - testSDL = ` ---- -version: "2.0" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 2 -` -) - -func init() { - uttypes.RegisterPostUpgradeWorker("v0.34.0", &postUpgrade{}) -} - -type postUpgrade struct{} - -var _ uttypes.TestWorker = (*postUpgrade)(nil) - -func (pu *postUpgrade) Run(ctx context.Context, t *testing.T, params uttypes.TestParams) { - encodingConfig := app.MakeEncodingConfig() - - rpcClient, err := sdkclient.NewClientFromNode(params.Node) - require.NoError(t, err) - - cctx := sdkclient.Context{}. - WithCodec(encodingConfig.Marshaler). - WithInterfaceRegistry(encodingConfig.InterfaceRegistry). - WithTxConfig(encodingConfig.TxConfig). - WithLegacyAmino(encodingConfig.Amino). - WithAccountRetriever(authtypes.AccountRetriever{}). - WithBroadcastMode(flags.BroadcastBlock). - WithHomeDir(params.Home). - WithChainID(params.ChainID). - WithNodeURI(params.Node). - WithClient(rpcClient). - WithSkipConfirmation(true). - WithFrom(params.From). - WithKeyringDir(params.Home) - - kr, err := sdkclient.NewKeyringFromBackend(cctx, params.KeyringBackend) - require.NoError(t, err) - - cctx = cctx.WithKeyring(kr) - - info, err := kr.Key(params.From) - require.NoError(t, err) - - entropySeed, err := bip39.NewEntropy(mnemonicEntropySize) - require.NoError(t, err) - - mnemonic, err := bip39.NewMnemonic(entropySeed) - require.NoError(t, err) - - keyringAlgos, _ := kr.SupportedAlgorithms() - - algo, err := keyring.NewSigningAlgoFromString(string(hd.Secp256k1Type), keyringAlgos) - - coinType := sdk.GetConfig().GetCoinType() - hdPath := hd.CreateHDPath(coinType, 0, 0).String() - - deplAcc, err := kr.NewAccount("depl", mnemonic, "", hdPath, algo) - require.NoError(t, err) - - hdPath = hd.CreateHDPath(coinType, 0, 1).String() - authz1, err := kr.NewAccount("authz1", mnemonic, "", hdPath, algo) - require.NoError(t, err) - - hdPath = hd.CreateHDPath(coinType, 0, 2).String() - authz2, err := kr.NewAccount("authz2", mnemonic, "", hdPath, algo) - require.NoError(t, err) - - mcctx := cctx.WithFromName(info.GetName()). - WithFromAddress(info.GetAddress()) - - dcctx := cctx.WithFromName(deplAcc.GetName()). - WithFromAddress(deplAcc.GetAddress()) - - a1cctx := cctx.WithFromName(authz1.GetName()). - WithFromAddress(authz1.GetAddress()) - - a2cctx := cctx.WithFromName(authz2.GetName()). - WithFromAddress(authz2.GetAddress()) - - opts := []cltypes.ClientOption{ - cltypes.WithGasPrices("0.025uakt"), - cltypes.WithGas(flags.GasSetting{Simulate: false, Gas: 1000000}), - cltypes.WithGasAdjustment(2), - } - - mcl, err := client.DiscoverClient(ctx, mcctx, opts...) - require.NoError(t, err) - require.NotNil(t, mcl) - - msgs := []sdk.Msg{ - &banktypes.MsgSend{ - FromAddress: info.GetAddress().String(), - ToAddress: deplAcc.GetAddress().String(), - Amount: sdk.NewCoins(sdk.NewCoin("uakt", sdk.NewInt(100000000))), - }, - &banktypes.MsgSend{ - FromAddress: info.GetAddress().String(), - ToAddress: authz1.GetAddress().String(), - Amount: sdk.NewCoins(sdk.NewCoin("uakt", sdk.NewInt(100000000))), - }, - &banktypes.MsgSend{ - FromAddress: info.GetAddress().String(), - ToAddress: authz2.GetAddress().String(), - Amount: sdk.NewCoins(sdk.NewCoin("uakt", sdk.NewInt(100000000))), - }, - } - - // fund all new accounts with some tokens - resp, err := mcl.Tx().Broadcast(ctx, msgs) - require.NoError(t, err) - require.NotNil(t, resp) - require.IsType(t, &sdk.TxResponse{}, resp) - txResp := resp.(*sdk.TxResponse) - require.Equal(t, uint32(0), txResp.Code) - - dcl, err := client.DiscoverClient(ctx, dcctx, opts...) - require.NoError(t, err) - require.NotNil(t, mcl) - - a1cl, err := client.DiscoverClient(ctx, a1cctx, opts...) - require.NoError(t, err) - require.NotNil(t, mcl) - - a2cl, err := client.DiscoverClient(ctx, a2cctx, opts...) - require.NoError(t, err) - require.NotNil(t, mcl) - - // give deployment key deployment deposit authorization from two accounts - spendLimit := sdk.NewCoin("uakt", sdk.NewInt(10000000)) - authorization := dtypes.NewDepositDeploymentAuthorization(spendLimit) - - msg, err := authz.NewMsgGrant(a1cctx.FromAddress, deplAcc.GetAddress(), authorization, time.Now().AddDate(1, 0, 0)) - require.NoError(t, err) - require.NotNil(t, msg) - - resp, err = a1cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - require.NoError(t, err) - require.NotNil(t, resp) - require.IsType(t, &sdk.TxResponse{}, resp) - txResp = resp.(*sdk.TxResponse) - require.Equal(t, uint32(0), txResp.Code) - - msg, err = authz.NewMsgGrant(a2cctx.FromAddress, deplAcc.GetAddress(), authorization, time.Now().AddDate(1, 0, 0)) - require.NoError(t, err) - require.NotNil(t, msg) - - resp, err = a2cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - require.NoError(t, err) - require.NotNil(t, resp) - require.IsType(t, &sdk.TxResponse{}, resp) - txResp = resp.(*sdk.TxResponse) - require.Equal(t, uint32(0), txResp.Code) - - tsdl, err := sdl.Read([]byte(testSDL)) - require.NoError(t, err) - require.NotNil(t, tsdl) - - syncInfo, err := dcl.Node().SyncInfo(ctx) - require.NoError(t, err) - require.NotNil(t, syncInfo) - require.False(t, syncInfo.CatchingUp) - - dID := dtypes.DeploymentID{ - Owner: deplAcc.GetAddress().String(), - DSeq: uint64(syncInfo.LatestBlockHeight), - } - - dVersion, err := tsdl.Version() - require.NoError(t, err) - - dGroups, err := tsdl.DeploymentGroups() - require.NoError(t, err) - - deposit, err := common.DetectDeposit(ctx, &pflag.FlagSet{}, dcl.Query(), "deployment", "MinDeposits") - require.NoError(t, err) - - // create deployment with deposit from owner - // should not have any errors - deploymentMsg := &dtypes.MsgCreateDeployment{ - ID: dID, - Version: dVersion, - Groups: make([]dtypes.GroupSpec, 0, len(dGroups)), - Deposit: deposit, - Depositor: deplAcc.GetAddress().String(), - } - - for _, group := range dGroups { - deploymentMsg.Groups = append(deploymentMsg.Groups, *group) - } - - resp, err = dcl.Tx().Broadcast(ctx, []sdk.Msg{deploymentMsg}) - require.NoError(t, err) - require.NotNil(t, resp) - require.IsType(t, &sdk.TxResponse{}, resp) - txResp = resp.(*sdk.TxResponse) - require.Equal(t, uint32(0), txResp.Code) - - // should be able to fund escrow with owner as depositor - depositMsg := &dtypes.MsgDepositDeployment{ - ID: dID, - Amount: deposit, - Depositor: deplAcc.GetAddress().String(), - } - - resp, err = dcl.Tx().Broadcast(ctx, []sdk.Msg{depositMsg}) - require.NoError(t, err) - require.NotNil(t, resp) - require.IsType(t, &sdk.TxResponse{}, resp) - txResp = resp.(*sdk.TxResponse) - require.Equal(t, uint32(0), txResp.Code) - - // should be able to fund escrow with depositor from authz1 - depositMsg = &dtypes.MsgDepositDeployment{ - ID: dID, - Amount: deposit, - Depositor: authz1.GetAddress().String(), - } - - resp, err = dcl.Tx().Broadcast(ctx, []sdk.Msg{depositMsg}) - require.NoError(t, err) - require.NotNil(t, resp) - require.IsType(t, &sdk.TxResponse{}, resp) - txResp = resp.(*sdk.TxResponse) - require.Equal(t, uint32(0), txResp.Code) - - // should not be able to fund escrow with depositor from authz2 - depositMsg = &dtypes.MsgDepositDeployment{ - ID: dID, - Amount: deposit, - Depositor: authz2.GetAddress().String(), - } - - resp, err = dcl.Tx().Broadcast(ctx, []sdk.Msg{depositMsg}) - require.Error(t, err) - require.NotNil(t, resp) - require.IsType(t, &sdk.TxResponse{}, resp) - txResp = resp.(*sdk.TxResponse) - require.NotEqual(t, uint32(0), txResp.Code) - - dCloseMsg := &dtypes.MsgCloseDeployment{ID: dID} - - resp, err = dcl.Tx().Broadcast(ctx, []sdk.Msg{dCloseMsg}) - require.NoError(t, err) - require.NotNil(t, resp) - require.IsType(t, &sdk.TxResponse{}, resp) - txResp = resp.(*sdk.TxResponse) - require.Equal(t, uint32(0), txResp.Code) - - grants, err := dcl.Query().Authz().Grants(ctx, &authz.QueryGrantsRequest{ - Granter: authz1.GetAddress().String(), - Grantee: deplAcc.GetAddress().String(), - MsgTypeUrl: dtypes.DepositDeploymentAuthorization{}.MsgTypeURL(), - }) - require.NoError(t, err) - require.Len(t, grants.Grants, 1) - - var auth authz.Authorization - err = cctx.Codec.UnpackAny(grants.Grants[0].Authorization, &auth) - require.NoError(t, err) - - grant, valid := auth.(*dtypes.DepositDeploymentAuthorization) - require.True(t, valid) - require.Equal(t, spendLimit, grant.SpendLimit) -} diff --git a/tests/upgrade/v0.36.0/postupgrade.go b/tests/upgrade/v0.36.0/postupgrade.go deleted file mode 100644 index 5ef3544a5d..0000000000 --- a/tests/upgrade/v0.36.0/postupgrade.go +++ /dev/null @@ -1,239 +0,0 @@ -//go:build e2e.upgrade - -// Package v0_36_0 -// nolint revive -package v0_36_0 - -import ( - "context" - "testing" - "time" - - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/cosmos-sdk/x/feegrant" - "github.com/spf13/pflag" - "github.com/stretchr/testify/require" - - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/authz" - "github.com/cosmos/go-bip39" - - cltypes "github.com/akash-network/akash-api/go/node/client/types" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - - "github.com/akash-network/node/app" - "github.com/akash-network/node/client" - "github.com/akash-network/node/cmd/common" - "github.com/akash-network/node/sdl" - uttypes "github.com/akash-network/node/tests/upgrade/types" -) - -const ( - mnemonicEntropySize = 256 -) - -const ( - testSDL = ` ---- -version: "2.0" -services: - web: - image: nginx - expose: - - port: 80 - accept: - - ahostname.com - to: - - global: true - - port: 12345 - to: - - global: true - proto: udp -profiles: - compute: - web: - resources: - cpu: - units: "100m" - memory: - size: "128Mi" - storage: - size: "1Gi" - placement: - westcoast: - attributes: - region: us-west - signedBy: - anyOf: - - 1 - - 2 - allOf: - - 3 - - 4 - pricing: - web: - denom: uakt - amount: 50 -deployment: - web: - westcoast: - profile: web - count: 2 -` -) - -func init() { - uttypes.RegisterPostUpgradeWorker("v0.36.0", &postUpgrade{}) -} - -type postUpgrade struct{} - -var _ uttypes.TestWorker = (*postUpgrade)(nil) - -func (pu *postUpgrade) Run(ctx context.Context, t *testing.T, params uttypes.TestParams) { - encodingConfig := app.MakeEncodingConfig() - - rpcClient, err := sdkclient.NewClientFromNode(params.Node) - require.NoError(t, err) - - cctx := sdkclient.Context{}. - WithCodec(encodingConfig.Marshaler). - WithInterfaceRegistry(encodingConfig.InterfaceRegistry). - WithTxConfig(encodingConfig.TxConfig). - WithLegacyAmino(encodingConfig.Amino). - WithAccountRetriever(authtypes.AccountRetriever{}). - WithBroadcastMode(flags.BroadcastBlock). - WithHomeDir(params.Home). - WithChainID(params.ChainID). - WithNodeURI(params.Node). - WithClient(rpcClient). - WithSkipConfirmation(true). - WithFrom(params.From). - WithKeyringDir(params.Home) - - kr, err := sdkclient.NewKeyringFromBackend(cctx, params.KeyringBackend) - require.NoError(t, err) - - cctx = cctx.WithKeyring(kr) - - info, err := kr.Key(params.From) - require.NoError(t, err) - - entropySeed, err := bip39.NewEntropy(mnemonicEntropySize) - require.NoError(t, err) - - mnemonic, err := bip39.NewMnemonic(entropySeed) - require.NoError(t, err) - - keyringAlgos, _ := kr.SupportedAlgorithms() - - algo, err := keyring.NewSigningAlgoFromString(string(hd.Secp256k1Type), keyringAlgos) - - coinType := sdk.GetConfig().GetCoinType() - hdPath := hd.CreateHDPath(coinType, 0, 0).String() - - testAcc, err := kr.NewAccount("depl", mnemonic, "", hdPath, algo) - require.NoError(t, err) - - mainCctx := cctx.WithFromName(info.GetName()). - WithFromAddress(info.GetAddress()) - - testCctx := cctx.WithFromName(testAcc.GetName()). - WithFromAddress(testAcc.GetAddress()). - WithFeeGranterAddress(info.GetAddress()) - - opts := []cltypes.ClientOption{ - cltypes.WithGasPrices("0.025uakt"), - cltypes.WithGas(flags.GasSetting{Simulate: false, Gas: 1000000}), - cltypes.WithGasAdjustment(2), - } - - mcl, err := client.DiscoverClient(ctx, mainCctx, opts...) - require.NoError(t, err) - require.NotNil(t, mcl) - - basic := &feegrant.BasicAllowance{ - SpendLimit: sdk.Coins{sdk.NewCoin("uakt", sdk.NewInt(500000))}, - } - - fmsg, err := feegrant.NewMsgGrantAllowance(basic, info.GetAddress(), testAcc.GetAddress()) - require.NoError(t, err) - - // give test key deployment deposit authorization - spendLimit := sdk.NewCoin("uakt", sdk.NewInt(10000000)) - authorization := dtypes.NewDepositDeploymentAuthorization(spendLimit) - dmsg, err := authz.NewMsgGrant(info.GetAddress(), testAcc.GetAddress(), authorization, time.Now().AddDate(1, 0, 0)) - - msgs := []sdk.Msg{ - fmsg, - dmsg, - } - - // authorize test account with feegrant - resp, err := mcl.Tx().Broadcast(ctx, msgs) - require.NoError(t, err) - require.NotNil(t, resp) - require.IsType(t, &sdk.TxResponse{}, resp) - txResp := resp.(*sdk.TxResponse) - require.Equal(t, uint32(0), txResp.Code) - - dcl, err := client.DiscoverClient(ctx, testCctx, opts...) - require.NoError(t, err) - require.NotNil(t, mcl) - - tsdl, err := sdl.Read([]byte(testSDL)) - require.NoError(t, err) - require.NotNil(t, tsdl) - - syncInfo, err := dcl.Node().SyncInfo(ctx) - require.NoError(t, err) - require.NotNil(t, syncInfo) - require.False(t, syncInfo.CatchingUp) - - dID := dtypes.DeploymentID{ - Owner: testAcc.GetAddress().String(), - DSeq: uint64(syncInfo.LatestBlockHeight), - } - - dVersion, err := tsdl.Version() - require.NoError(t, err) - - dGroups, err := tsdl.DeploymentGroups() - require.NoError(t, err) - - deposit, err := common.DetectDeposit(ctx, &pflag.FlagSet{}, dcl.Query(), "deployment", "MinDeposits") - require.NoError(t, err) - - qresp, err := dcl.Query().Bank().Balance(ctx, &banktypes.QueryBalanceRequest{ - Denom: "uakt", - Address: testAcc.GetAddress().String(), - }) - require.NoError(t, err) - require.True(t, qresp.Balance.IsZero()) - - // create deployment with deposit with both fee&deposit grants - // should not have any errors - deploymentMsg := &dtypes.MsgCreateDeployment{ - ID: dID, - Version: dVersion, - Groups: make([]dtypes.GroupSpec, 0, len(dGroups)), - Deposit: deposit, - Depositor: info.GetAddress().String(), - } - - for _, group := range dGroups { - deploymentMsg.Groups = append(deploymentMsg.Groups, *group) - } - - resp, err = dcl.Tx().Broadcast(ctx, []sdk.Msg{deploymentMsg}) - require.NoError(t, err) - require.NotNil(t, resp) - require.IsType(t, &sdk.TxResponse{}, resp) - txResp = resp.(*sdk.TxResponse) - require.Equal(t, uint32(0), txResp.Code) -} diff --git a/tests/upgrade/workers_test.go b/tests/upgrade/workers_test.go index babb166567..171802ba3d 100644 --- a/tests/upgrade/workers_test.go +++ b/tests/upgrade/workers_test.go @@ -3,8 +3,142 @@ package upgrade import ( - _ "github.com/akash-network/node/tests/upgrade/v0.26.0" - _ "github.com/akash-network/node/tests/upgrade/v0.32.0" - _ "github.com/akash-network/node/tests/upgrade/v0.34.0" - _ "github.com/akash-network/node/tests/upgrade/v0.36.0" + "context" + "testing" + + "github.com/stretchr/testify/require" + + sdkmath "cosmossdk.io/math" + sdkclient "github.com/cosmos/cosmos-sdk/client" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "pkg.akt.dev/go/cli/flags" + arpcclient "pkg.akt.dev/go/node/client" + aclient "pkg.akt.dev/go/node/client/discovery" + cltypes "pkg.akt.dev/go/node/client/types" + "pkg.akt.dev/go/node/client/v1beta3" + "pkg.akt.dev/go/sdkutil" + + "pkg.akt.dev/node/app" + uttypes "pkg.akt.dev/node/tests/upgrade/types" ) + +func init() { + uttypes.RegisterPostUpgradeWorker("v1.0.0", &postUpgrade{}) +} + +type postUpgrade struct { + cl v1beta3.Client +} + +var _ uttypes.TestWorker = (*postUpgrade)(nil) + +func (pu *postUpgrade) Run(ctx context.Context, t *testing.T, params uttypes.TestParams) { + encodingConfig := sdkutil.MakeEncodingConfig() + app.ModuleBasics().RegisterInterfaces(encodingConfig.InterfaceRegistry) + + rpcClient, err := arpcclient.NewClient(ctx, params.Node) + require.NoError(t, err) + + cctx := sdkclient.Context{}. + WithCodec(encodingConfig.Codec). + WithInterfaceRegistry(encodingConfig.InterfaceRegistry). + WithTxConfig(encodingConfig.TxConfig). + WithLegacyAmino(encodingConfig.Amino). + WithAccountRetriever(authtypes.AccountRetriever{}). + WithBroadcastMode(flags.BroadcastBlock). + WithHomeDir(params.Home). + WithChainID(params.ChainID). + WithNodeURI(params.Node). + WithClient(rpcClient). + WithSkipConfirmation(true). + WithFrom(params.From). + WithFromName(params.From). + WithFromAddress(params.FromAddress). + WithKeyringDir(params.Home). + WithSignModeStr(flags.SignModeDirect). + WithSimulation(false) + + kr, err := sdkclient.NewKeyringFromBackend(cctx, params.KeyringBackend) + require.NoError(t, err) + + cctx = cctx.WithKeyring(kr) + + opts := []cltypes.ClientOption{ + cltypes.WithGasPrices("0.025uakt"), + cltypes.WithGas(cltypes.GasSetting{Simulate: false, Gas: 1000000}), + cltypes.WithGasAdjustment(2), + } + + pu.cl, err = aclient.DiscoverClient(ctx, cctx, opts...) + require.NoError(t, err) + require.NotNil(t, pu.cl) + + pu.testGov(ctx, t) + + pu.testStaking(ctx, t) +} + +func (pu *postUpgrade) testGov(ctx context.Context, t *testing.T) { + t.Logf("testing gov module") + cctx := pu.cl.ClientContext() + + paramsResp, err := pu.cl.Query().Gov().Params(ctx, &govtypes.QueryParamsRequest{ParamsType: "deposit"}) + require.NoError(t, err) + require.NotNil(t, paramsResp) + + // paramsResp.Params.ExpeditedMinDeposit. + require.Equal(t, sdk.Coins{sdk.NewCoin("uakt", sdkmath.NewInt(2000000000))}.String(), sdk.Coins(paramsResp.Params.ExpeditedMinDeposit).String(), "ExpeditedMinDeposit must have 2000AKT") + require.Equal(t, paramsResp.Params.MinInitialDepositRatio, sdkmath.LegacyNewDecWithPrec(40, 2).String(), "MinInitialDepositRatio must be 40%") + + opAddr := sdk.ValAddress(cctx.FromAddress) + + comVal := sdkmath.LegacyNewDecWithPrec(4, 2) + + valResp, err := pu.cl.Query().Staking().Validator(ctx, &stakingtypes.QueryValidatorRequest{ValidatorAddr: opAddr.String()}) + require.NoError(t, err) + + minSelfDelegation := sdkmath.NewInt(1) + + tx := stakingtypes.NewMsgEditValidator(opAddr.String(), valResp.Validator.Description, &comVal, &minSelfDelegation) + broadcastResp, err := pu.cl.Tx().BroadcastMsgs(ctx, []sdk.Msg{tx}) + require.Error(t, err) + require.NotNil(t, broadcastResp) + + require.IsType(t, &sdk.TxResponse{}, broadcastResp) + txResp := broadcastResp.(*sdk.TxResponse) + require.NotEqual(t, uint32(0), txResp.Code, "update validator commission should fail if new value is < 5%") +} + +func (pu *postUpgrade) testStaking(ctx context.Context, t *testing.T) { + t.Logf("testing staking module") + + cctx := pu.cl.ClientContext() + + paramsResp, err := pu.cl.Query().Staking().Params(ctx, &stakingtypes.QueryParamsRequest{}) + require.NoError(t, err) + require.NotNil(t, paramsResp) + + require.True(t, paramsResp.Params.MinCommissionRate.GTE(sdkmath.LegacyNewDecWithPrec(5, 2)), "per upgrade v1.0.0 MinCommissionRate should be 5%") + + opAddr := sdk.ValAddress(cctx.FromAddress) + + comVal := sdkmath.LegacyNewDecWithPrec(4, 2) + + valResp, err := pu.cl.Query().Staking().Validator(ctx, &stakingtypes.QueryValidatorRequest{ValidatorAddr: opAddr.String()}) + require.NoError(t, err) + + minSelfDelegation := sdkmath.NewInt(1) + + tx := stakingtypes.NewMsgEditValidator(opAddr.String(), valResp.Validator.Description, &comVal, &minSelfDelegation) + broadcastResp, err := pu.cl.Tx().BroadcastMsgs(ctx, []sdk.Msg{tx}) + require.Error(t, err) + require.NotNil(t, broadcastResp) + + require.IsType(t, &sdk.TxResponse{}, broadcastResp) + txResp := broadcastResp.(*sdk.TxResponse) + require.NotEqual(t, uint32(0), txResp.Code, "update validator commission should fail if new value is < 5%") +} diff --git a/testutil/audit.go b/testutil/audit.go deleted file mode 100644 index 6f2cf16876..0000000000 --- a/testutil/audit.go +++ /dev/null @@ -1,22 +0,0 @@ -package testutil - -import ( - "testing" - - atypes "github.com/akash-network/akash-api/go/node/audit/v1beta3" -) - -func AuditedProvider(t testing.TB) (atypes.ProviderID, atypes.Provider) { - t.Helper() - - id := atypes.ProviderID{ - Auditor: AccAddress(t), - Owner: AccAddress(t), - } - - return id, atypes.Provider{ - Auditor: id.Auditor.String(), - Owner: id.Owner.String(), - Attributes: Attributes(t), - } -} diff --git a/testutil/base.go b/testutil/base.go deleted file mode 100644 index 564acd22e9..0000000000 --- a/testutil/base.go +++ /dev/null @@ -1,119 +0,0 @@ -package testutil - -import ( - "fmt" - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/tendermint/tendermint/libs/rand" - - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/types/v1beta3" - - // ensure sdkutil.init() to seal SDK config for the tests - _ "github.com/akash-network/akash-api/go/sdkutil" -) - -// CoinDenom provides ability to create coins in test functions and -// pass them into testutil functionality. -const ( - CoinDenom = "uakt" -) - -// Name generates a random name with the given prefix -func Name(_ testing.TB, prefix string) string { - return fmt.Sprintf("%s-%v", prefix, rand.Uint64()) -} - -// Hostname generates a random hostname with a "test.com" domain -func Hostname(t testing.TB) string { - return Name(t, "hostname") + ".test.com" -} - -func ProviderHostname(t testing.TB) string { - return "https://" + Hostname(t) -} - -// Attribute generates a random sdk.Attribute -func Attribute(t testing.TB) types.Attribute { - t.Helper() - return types.NewStringAttribute(Name(t, "attr-key"), Name(t, "attr-value")) -} - -// Attributes generates a set of sdk.Attribute -func Attributes(t testing.TB) []types.Attribute { - t.Helper() - count := rand.Intn(10) + 1 - - vals := make([]types.Attribute, 0, count) - for i := 0; i < count; i++ { - vals = append(vals, Attribute(t)) - } - return vals -} - -// PlacementRequirements generates placement requirements -func PlacementRequirements(t testing.TB) types.PlacementRequirements { - return types.PlacementRequirements{ - Attributes: Attributes(t), - } -} - -func RandCPUUnits() uint { - return RandRangeUint( - dtypes.GetValidationConfig().Unit.Min.CPU, - dtypes.GetValidationConfig().Unit.Max.CPU) -} - -func RandGPUUnits() uint { - return RandRangeUint( - dtypes.GetValidationConfig().Unit.Min.GPU, - dtypes.GetValidationConfig().Unit.Max.GPU) -} - -func RandMemoryQuantity() uint64 { - return RandRangeUint64( - dtypes.GetValidationConfig().Unit.Min.Memory, - dtypes.GetValidationConfig().Unit.Max.Memory) -} - -func RandStorageQuantity() uint64 { - return RandRangeUint64( - dtypes.GetValidationConfig().Unit.Min.Storage, - dtypes.GetValidationConfig().Unit.Max.Storage) -} - -// Resources produces an attribute list for populating a Group's -// 'Resources' fields. -func Resources(t testing.TB) []dtypes.ResourceUnit { - t.Helper() - count := rand.Intn(10) + 1 - - vals := make(dtypes.ResourceUnits, 0, count) - for i := 0; i < count; i++ { - coin := sdk.NewDecCoin(CoinDenom, sdk.NewInt(rand.Int63n(9999)+1)) - res := dtypes.ResourceUnit{ - Resources: types.Resources{ - ID: uint32(i) + 1, - CPU: &types.CPU{ - Units: types.NewResourceValue(uint64(dtypes.GetValidationConfig().Unit.Min.CPU)), - }, - GPU: &types.GPU{ - Units: types.NewResourceValue(uint64(dtypes.GetValidationConfig().Unit.Min.GPU)), - }, - Memory: &types.Memory{ - Quantity: types.NewResourceValue(dtypes.GetValidationConfig().Unit.Min.Memory), - }, - Storage: types.Volumes{ - types.Storage{ - Quantity: types.NewResourceValue(dtypes.GetValidationConfig().Unit.Min.Storage), - }, - }, - }, - Count: 1, - Price: coin, - } - vals = append(vals, res) - } - return vals -} diff --git a/testutil/cert.go b/testutil/cert.go deleted file mode 100644 index 9a073c428a..0000000000 --- a/testutil/cert.go +++ /dev/null @@ -1,213 +0,0 @@ -package testutil - -import ( - "context" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/tls" - "crypto/x509" - "crypto/x509/pkix" - "encoding/pem" - "math/big" - "net" - "testing" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" - - clientmocks "github.com/akash-network/akash-api/go/node/client/v1beta2/mocks" - - certutils "github.com/akash-network/node/x/cert/utils" -) - -type TestCertificate struct { - Cert []tls.Certificate - Serial big.Int - PEM struct { - Cert []byte - Priv []byte - Pub []byte - } -} - -type certificateOption struct { - domains []string - nbf time.Time - naf time.Time - qclient *clientmocks.QueryClient -} - -type CertificateOption func(*certificateOption) - -func CertificateOptionDomains(domains []string) CertificateOption { - return func(opt *certificateOption) { - opt.domains = domains - } -} - -func CertificateOptionNotBefore(tm time.Time) CertificateOption { - return func(opt *certificateOption) { - opt.nbf = tm - } -} - -func CertificateOptionNotAfter(tm time.Time) CertificateOption { - return func(opt *certificateOption) { - opt.naf = tm - } -} - -func CertificateOptionMocks(val *clientmocks.QueryClient) CertificateOption { - return func(opt *certificateOption) { - opt.qclient = val - } -} - -func Certificate(t testing.TB, addr sdk.Address, opts ...CertificateOption) TestCertificate { - t.Helper() - - opt := &certificateOption{} - - for _, o := range opts { - o(opt) - } - - priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - if err != nil { - t.Fatal(err) - } - - if opt.nbf.IsZero() { - opt.nbf = time.Now() - } - - if opt.naf.IsZero() { - opt.naf = opt.nbf.Add(time.Hour * 24 * 365) - } - - extKeyUsage := []x509.ExtKeyUsage{ - x509.ExtKeyUsageClientAuth, - } - - if len(opt.domains) != 0 { - extKeyUsage = append(extKeyUsage, x509.ExtKeyUsageServerAuth) - } - - template := x509.Certificate{ - SerialNumber: new(big.Int).SetInt64(time.Now().UTC().UnixNano()), - Subject: pkix.Name{ - CommonName: addr.String(), - ExtraNames: []pkix.AttributeTypeAndValue{ - { - Type: certutils.AuthVersionOID, - Value: "v0.0.1", - }, - }, - }, - Issuer: pkix.Name{ - CommonName: addr.String(), - }, - NotBefore: opt.nbf, - NotAfter: opt.naf, - KeyUsage: x509.KeyUsageDataEncipherment | x509.KeyUsageKeyEncipherment, - ExtKeyUsage: extKeyUsage, - BasicConstraintsValid: true, - } - - var ips []net.IP - - for i := len(opt.domains) - 1; i >= 0; i-- { - if ip := net.ParseIP(opt.domains[i]); ip != nil { - ips = append(ips, ip) - opt.domains = append(opt.domains[:i], opt.domains[i+1:]...) - } - } - - if len(opt.domains) != 0 || len(ips) != 0 { - template.PermittedDNSDomainsCritical = true - template.PermittedDNSDomains = opt.domains - template.DNSNames = opt.domains - template.IPAddresses = ips - } - - var certDer []byte - if certDer, err = x509.CreateCertificate(rand.Reader, &template, &template, priv.Public(), priv); err != nil { - t.Fatal(err) - } - - var keyDer []byte - if keyDer, err = x509.MarshalPKCS8PrivateKey(priv); err != nil { - t.Fatal(err) - } - - var pubKeyDer []byte - if pubKeyDer, err = x509.MarshalPKIXPublicKey(priv.Public()); err != nil { - t.Fatal(err) - } - - res := TestCertificate{ - Serial: *template.SerialNumber, - PEM: struct { - Cert []byte - Priv []byte - Pub []byte - }{ - Cert: pem.EncodeToMemory(&pem.Block{ - Type: types.PemBlkTypeCertificate, - Bytes: certDer, - }), - Priv: pem.EncodeToMemory(&pem.Block{ - Type: types.PemBlkTypeECPrivateKey, - Bytes: keyDer, - }), - Pub: pem.EncodeToMemory(&pem.Block{ - Type: types.PemBlkTypeECPublicKey, - Bytes: pubKeyDer, - }), - }, - } - - cert, err := tls.X509KeyPair(res.PEM.Cert, res.PEM.Priv) - if err != nil { - t.Fatal(err) - } - - res.Cert = append(res.Cert, cert) - - if opt.qclient != nil { - opt.qclient.On("Certificates", - context.Background(), - &types.QueryCertificatesRequest{ - Filter: types.CertificateFilter{ - Owner: addr.String(), - Serial: res.Serial.String(), - State: "valid", - }, - }). - Return(&types.QueryCertificatesResponse{ - Certificates: types.CertificatesResponse{ - types.CertificateResponse{ - Certificate: types.Certificate{ - State: types.CertificateValid, - Cert: res.PEM.Cert, - Pubkey: res.PEM.Pub, - }, - Serial: res.Serial.String(), - }, - }, - }, nil) - } - return res -} - -func CertificateRequireEqualResponse(t *testing.T, cert TestCertificate, resp types.CertificateResponse, state types.Certificate_State) { - t.Helper() - - require.Equal(t, state, resp.Certificate.State) - require.Equal(t, cert.PEM.Cert, resp.Certificate.Cert) - require.Equal(t, cert.PEM.Pub, resp.Certificate.Pubkey) -} diff --git a/testutil/channel_wait.go b/testutil/channel_wait.go deleted file mode 100644 index f9ef17e4d9..0000000000 --- a/testutil/channel_wait.go +++ /dev/null @@ -1,71 +0,0 @@ -package testutil - -import ( - "reflect" - "testing" - "time" -) - -func ChannelWaitForValueUpTo(t *testing.T, waitOn interface{}, waitFor time.Duration) interface{} { - cases := make([]reflect.SelectCase, 2) - cases[0] = reflect.SelectCase{ - Dir: reflect.SelectRecv, - Chan: reflect.ValueOf(waitOn), - Send: reflect.Value{}, - } - - delayChan := time.After(waitFor) - - cases[1] = reflect.SelectCase{ - Dir: reflect.SelectRecv, - Chan: reflect.ValueOf(delayChan), - Send: reflect.Value{}, - } - - idx, v, ok := reflect.Select(cases) - if !ok { - t.Fatal("Channel has been closed") - } - if idx != 0 { - t.Fatalf("No message after waiting %v seconds", waitFor) - } - - return v.Interface() -} - -const waitForDefault = 10 * time.Second - -func ChannelWaitForValue(t *testing.T, waitOn interface{}) interface{} { - return ChannelWaitForValueUpTo(t, waitOn, waitForDefault) -} - -func ChannelWaitForCloseUpTo(t *testing.T, waitOn interface{}, waitFor time.Duration) { - cases := make([]reflect.SelectCase, 2) - cases[0] = reflect.SelectCase{ - Dir: reflect.SelectRecv, - Chan: reflect.ValueOf(waitOn), - Send: reflect.Value{}, - } - - delayChan := time.After(waitFor) - - cases[1] = reflect.SelectCase{ - Dir: reflect.SelectRecv, - Chan: reflect.ValueOf(delayChan), - Send: reflect.Value{}, - } - - idx, v, ok := reflect.Select(cases) - if !ok { - return // Channel closed, everything OK - } - if idx != 0 { - t.Fatalf("channel not closed after waiting %v seconds", waitOn) - } - - t.Fatalf("got unexpected message: %v", v.Interface()) -} - -func ChannelWaitForClose(t *testing.T, waitOn interface{}) { - ChannelWaitForCloseUpTo(t, waitOn, waitForDefault) -} diff --git a/testutil/cli/cmd.go b/testutil/cli/cmd.go deleted file mode 100644 index 20452b7589..0000000000 --- a/testutil/cli/cmd.go +++ /dev/null @@ -1,67 +0,0 @@ -package cli - -import ( - "bytes" - "context" - "testing" - - "github.com/cosmos/cosmos-sdk/server" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth/tx" - "github.com/gogo/protobuf/jsonpb" - - "github.com/stretchr/testify/require" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/testutil" - "github.com/spf13/cobra" -) - -// ExecTestCLICmd builds the client context, mocks the output and executes the command. -func ExecTestCLICmd(ctx context.Context, clientCtx client.Context, cmd *cobra.Command, extraArgs ...string) (testutil.BufferWriter, error) { - cmd.SetArgs(extraArgs) - - _, out := testutil.ApplyMockIO(cmd) - clientCtx = clientCtx.WithOutput(out) - - if ctx == nil { - ctx = context.Background() - } - ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) - ctx = context.WithValue(ctx, server.ServerContextKey, server.NewDefaultContext()) - - if err := cmd.ExecuteContext(ctx); err != nil { - return out, err - } - - return out, nil -} - -// ValidateTxSuccessful is a gentle response to inappropriate approach of cli test utils -// send transaction may fail and calling cli routine won't know about it -func ValidateTxSuccessful(t testing.TB, cctx client.Context, data []byte) { - t.Helper() - - res := getTxResponse(t, cctx, data) - require.Zero(t, res.Code, res) -} - -func ValidateTxUnSuccessful(t testing.TB, cctx client.Context, data []byte) { - t.Helper() - - res := getTxResponse(t, cctx, data) - require.NotZero(t, res.Code, res) -} - -func getTxResponse(t testing.TB, cctx client.Context, data []byte) *sdk.TxResponse { - var resp sdk.TxResponse - - err := jsonpb.Unmarshal(bytes.NewBuffer(data), &resp) - require.NoError(t, err) - - res, err := tx.QueryTx(cctx, resp.TxHash) - require.NoError(t, err) - - return res -} diff --git a/testutil/cosmos/keepers.go b/testutil/cosmos/keepers.go index 943959bff4..38f45e5e87 100644 --- a/testutil/cosmos/keepers.go +++ b/testutil/cosmos/keepers.go @@ -1,34 +1,30 @@ package keeper import ( + "context" "time" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/authz" - distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" ) -//go:generate mockery --name BankKeeper --output ./mocks type BankKeeper interface { - SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error - SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error - SendCoinsFromModuleToModule(ctx sdk.Context, senderModule string, recipientModule string, amt sdk.Coins) error + SpendableCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins + SpendableCoin(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin + SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt sdk.Coins) error + SendCoinsFromAccountToModule(ctx context.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error } -//go:generate mockery --name TakeKeeper --output ./mocks type TakeKeeper interface { SubtractFees(ctx sdk.Context, amt sdk.Coin) (sdk.Coin, sdk.Coin, error) } -//go:generate mockery --name DistrKeeper --output ./mocks -type DistrKeeper interface { - GetFeePool(ctx sdk.Context) distrtypes.FeePool - SetFeePool(ctx sdk.Context, pool distrtypes.FeePool) -} - -//go:generate mockery --name AuthzKeeper --output ./mocks type AuthzKeeper interface { - DeleteGrant(ctx sdk.Context, grantee, granter sdk.AccAddress, msgType string) error - GetCleanAuthorization(ctx sdk.Context, grantee, granter sdk.AccAddress, msgType string) (cap authz.Authorization, expiration time.Time) - SaveGrant(ctx sdk.Context, grantee, granter sdk.AccAddress, authorization authz.Authorization, expiration time.Time) error + DeleteGrant(ctx context.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) error + GetAuthorization(ctx context.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) (authz.Authorization, *time.Time) + SaveGrant(ctx context.Context, grantee sdk.AccAddress, granter sdk.AccAddress, authorization authz.Authorization, expiration *time.Time) error + IterateGrants(ctx context.Context, handler func(granterAddr sdk.AccAddress, granteeAddr sdk.AccAddress, grant authz.Grant) bool) + GetGranteeGrantsByMsgType(ctx context.Context, grantee sdk.AccAddress, msgType string, onGrant authzkeeper.OnGrantFn) } diff --git a/testutil/cosmos/mocks/AuthzKeeper_mock.go b/testutil/cosmos/mocks/AuthzKeeper_mock.go new file mode 100644 index 0000000000..fbb3b8ffc1 --- /dev/null +++ b/testutil/cosmos/mocks/AuthzKeeper_mock.go @@ -0,0 +1,372 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package keeper + +import ( + "context" + "time" + + "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/authz" + "github.com/cosmos/cosmos-sdk/x/authz/keeper" + mock "github.com/stretchr/testify/mock" +) + +// NewAuthzKeeper creates a new instance of AuthzKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewAuthzKeeper(t interface { + mock.TestingT + Cleanup(func()) +}) *AuthzKeeper { + mock := &AuthzKeeper{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// AuthzKeeper is an autogenerated mock type for the AuthzKeeper type +type AuthzKeeper struct { + mock.Mock +} + +type AuthzKeeper_Expecter struct { + mock *mock.Mock +} + +func (_m *AuthzKeeper) EXPECT() *AuthzKeeper_Expecter { + return &AuthzKeeper_Expecter{mock: &_m.Mock} +} + +// DeleteGrant provides a mock function for the type AuthzKeeper +func (_mock *AuthzKeeper) DeleteGrant(ctx context.Context, grantee types.AccAddress, granter types.AccAddress, msgType string) error { + ret := _mock.Called(ctx, grantee, granter, msgType) + + if len(ret) == 0 { + panic("no return value specified for DeleteGrant") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, types.AccAddress, types.AccAddress, string) error); ok { + r0 = returnFunc(ctx, grantee, granter, msgType) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// AuthzKeeper_DeleteGrant_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteGrant' +type AuthzKeeper_DeleteGrant_Call struct { + *mock.Call +} + +// DeleteGrant is a helper method to define mock.On call +// - ctx context.Context +// - grantee types.AccAddress +// - granter types.AccAddress +// - msgType string +func (_e *AuthzKeeper_Expecter) DeleteGrant(ctx interface{}, grantee interface{}, granter interface{}, msgType interface{}) *AuthzKeeper_DeleteGrant_Call { + return &AuthzKeeper_DeleteGrant_Call{Call: _e.mock.On("DeleteGrant", ctx, grantee, granter, msgType)} +} + +func (_c *AuthzKeeper_DeleteGrant_Call) Run(run func(ctx context.Context, grantee types.AccAddress, granter types.AccAddress, msgType string)) *AuthzKeeper_DeleteGrant_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 types.AccAddress + if args[1] != nil { + arg1 = args[1].(types.AccAddress) + } + var arg2 types.AccAddress + if args[2] != nil { + arg2 = args[2].(types.AccAddress) + } + var arg3 string + if args[3] != nil { + arg3 = args[3].(string) + } + run( + arg0, + arg1, + arg2, + arg3, + ) + }) + return _c +} + +func (_c *AuthzKeeper_DeleteGrant_Call) Return(err error) *AuthzKeeper_DeleteGrant_Call { + _c.Call.Return(err) + return _c +} + +func (_c *AuthzKeeper_DeleteGrant_Call) RunAndReturn(run func(ctx context.Context, grantee types.AccAddress, granter types.AccAddress, msgType string) error) *AuthzKeeper_DeleteGrant_Call { + _c.Call.Return(run) + return _c +} + +// GetAuthorization provides a mock function for the type AuthzKeeper +func (_mock *AuthzKeeper) GetAuthorization(ctx context.Context, grantee types.AccAddress, granter types.AccAddress, msgType string) (authz.Authorization, *time.Time) { + ret := _mock.Called(ctx, grantee, granter, msgType) + + if len(ret) == 0 { + panic("no return value specified for GetAuthorization") + } + + var r0 authz.Authorization + var r1 *time.Time + if returnFunc, ok := ret.Get(0).(func(context.Context, types.AccAddress, types.AccAddress, string) (authz.Authorization, *time.Time)); ok { + return returnFunc(ctx, grantee, granter, msgType) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, types.AccAddress, types.AccAddress, string) authz.Authorization); ok { + r0 = returnFunc(ctx, grantee, granter, msgType) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(authz.Authorization) + } + } + if returnFunc, ok := ret.Get(1).(func(context.Context, types.AccAddress, types.AccAddress, string) *time.Time); ok { + r1 = returnFunc(ctx, grantee, granter, msgType) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*time.Time) + } + } + return r0, r1 +} + +// AuthzKeeper_GetAuthorization_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAuthorization' +type AuthzKeeper_GetAuthorization_Call struct { + *mock.Call +} + +// GetAuthorization is a helper method to define mock.On call +// - ctx context.Context +// - grantee types.AccAddress +// - granter types.AccAddress +// - msgType string +func (_e *AuthzKeeper_Expecter) GetAuthorization(ctx interface{}, grantee interface{}, granter interface{}, msgType interface{}) *AuthzKeeper_GetAuthorization_Call { + return &AuthzKeeper_GetAuthorization_Call{Call: _e.mock.On("GetAuthorization", ctx, grantee, granter, msgType)} +} + +func (_c *AuthzKeeper_GetAuthorization_Call) Run(run func(ctx context.Context, grantee types.AccAddress, granter types.AccAddress, msgType string)) *AuthzKeeper_GetAuthorization_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 types.AccAddress + if args[1] != nil { + arg1 = args[1].(types.AccAddress) + } + var arg2 types.AccAddress + if args[2] != nil { + arg2 = args[2].(types.AccAddress) + } + var arg3 string + if args[3] != nil { + arg3 = args[3].(string) + } + run( + arg0, + arg1, + arg2, + arg3, + ) + }) + return _c +} + +func (_c *AuthzKeeper_GetAuthorization_Call) Return(authorization authz.Authorization, time1 *time.Time) *AuthzKeeper_GetAuthorization_Call { + _c.Call.Return(authorization, time1) + return _c +} + +func (_c *AuthzKeeper_GetAuthorization_Call) RunAndReturn(run func(ctx context.Context, grantee types.AccAddress, granter types.AccAddress, msgType string) (authz.Authorization, *time.Time)) *AuthzKeeper_GetAuthorization_Call { + _c.Call.Return(run) + return _c +} + +// GetGranteeGrantsByMsgType provides a mock function for the type AuthzKeeper +func (_mock *AuthzKeeper) GetGranteeGrantsByMsgType(ctx context.Context, grantee types.AccAddress, msgType string, onGrant keeper.OnGrantFn) { + _mock.Called(ctx, grantee, msgType, onGrant) + return +} + +// AuthzKeeper_GetGranteeGrantsByMsgType_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetGranteeGrantsByMsgType' +type AuthzKeeper_GetGranteeGrantsByMsgType_Call struct { + *mock.Call +} + +// GetGranteeGrantsByMsgType is a helper method to define mock.On call +// - ctx context.Context +// - grantee types.AccAddress +// - msgType string +// - onGrant keeper.OnGrantFn +func (_e *AuthzKeeper_Expecter) GetGranteeGrantsByMsgType(ctx interface{}, grantee interface{}, msgType interface{}, onGrant interface{}) *AuthzKeeper_GetGranteeGrantsByMsgType_Call { + return &AuthzKeeper_GetGranteeGrantsByMsgType_Call{Call: _e.mock.On("GetGranteeGrantsByMsgType", ctx, grantee, msgType, onGrant)} +} + +func (_c *AuthzKeeper_GetGranteeGrantsByMsgType_Call) Run(run func(ctx context.Context, grantee types.AccAddress, msgType string, onGrant keeper.OnGrantFn)) *AuthzKeeper_GetGranteeGrantsByMsgType_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 types.AccAddress + if args[1] != nil { + arg1 = args[1].(types.AccAddress) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + var arg3 keeper.OnGrantFn + if args[3] != nil { + arg3 = args[3].(keeper.OnGrantFn) + } + run( + arg0, + arg1, + arg2, + arg3, + ) + }) + return _c +} + +func (_c *AuthzKeeper_GetGranteeGrantsByMsgType_Call) Return() *AuthzKeeper_GetGranteeGrantsByMsgType_Call { + _c.Call.Return() + return _c +} + +func (_c *AuthzKeeper_GetGranteeGrantsByMsgType_Call) RunAndReturn(run func(ctx context.Context, grantee types.AccAddress, msgType string, onGrant keeper.OnGrantFn)) *AuthzKeeper_GetGranteeGrantsByMsgType_Call { + _c.Run(run) + return _c +} + +// IterateGrants provides a mock function for the type AuthzKeeper +func (_mock *AuthzKeeper) IterateGrants(ctx context.Context, handler func(granterAddr types.AccAddress, granteeAddr types.AccAddress, grant authz.Grant) bool) { + _mock.Called(ctx, handler) + return +} + +// AuthzKeeper_IterateGrants_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IterateGrants' +type AuthzKeeper_IterateGrants_Call struct { + *mock.Call +} + +// IterateGrants is a helper method to define mock.On call +// - ctx context.Context +// - handler func(granterAddr types.AccAddress, granteeAddr types.AccAddress, grant authz.Grant) bool +func (_e *AuthzKeeper_Expecter) IterateGrants(ctx interface{}, handler interface{}) *AuthzKeeper_IterateGrants_Call { + return &AuthzKeeper_IterateGrants_Call{Call: _e.mock.On("IterateGrants", ctx, handler)} +} + +func (_c *AuthzKeeper_IterateGrants_Call) Run(run func(ctx context.Context, handler func(granterAddr types.AccAddress, granteeAddr types.AccAddress, grant authz.Grant) bool)) *AuthzKeeper_IterateGrants_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 func(granterAddr types.AccAddress, granteeAddr types.AccAddress, grant authz.Grant) bool + if args[1] != nil { + arg1 = args[1].(func(granterAddr types.AccAddress, granteeAddr types.AccAddress, grant authz.Grant) bool) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *AuthzKeeper_IterateGrants_Call) Return() *AuthzKeeper_IterateGrants_Call { + _c.Call.Return() + return _c +} + +func (_c *AuthzKeeper_IterateGrants_Call) RunAndReturn(run func(ctx context.Context, handler func(granterAddr types.AccAddress, granteeAddr types.AccAddress, grant authz.Grant) bool)) *AuthzKeeper_IterateGrants_Call { + _c.Run(run) + return _c +} + +// SaveGrant provides a mock function for the type AuthzKeeper +func (_mock *AuthzKeeper) SaveGrant(ctx context.Context, grantee types.AccAddress, granter types.AccAddress, authorization authz.Authorization, expiration *time.Time) error { + ret := _mock.Called(ctx, grantee, granter, authorization, expiration) + + if len(ret) == 0 { + panic("no return value specified for SaveGrant") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, types.AccAddress, types.AccAddress, authz.Authorization, *time.Time) error); ok { + r0 = returnFunc(ctx, grantee, granter, authorization, expiration) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// AuthzKeeper_SaveGrant_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveGrant' +type AuthzKeeper_SaveGrant_Call struct { + *mock.Call +} + +// SaveGrant is a helper method to define mock.On call +// - ctx context.Context +// - grantee types.AccAddress +// - granter types.AccAddress +// - authorization authz.Authorization +// - expiration *time.Time +func (_e *AuthzKeeper_Expecter) SaveGrant(ctx interface{}, grantee interface{}, granter interface{}, authorization interface{}, expiration interface{}) *AuthzKeeper_SaveGrant_Call { + return &AuthzKeeper_SaveGrant_Call{Call: _e.mock.On("SaveGrant", ctx, grantee, granter, authorization, expiration)} +} + +func (_c *AuthzKeeper_SaveGrant_Call) Run(run func(ctx context.Context, grantee types.AccAddress, granter types.AccAddress, authorization authz.Authorization, expiration *time.Time)) *AuthzKeeper_SaveGrant_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 types.AccAddress + if args[1] != nil { + arg1 = args[1].(types.AccAddress) + } + var arg2 types.AccAddress + if args[2] != nil { + arg2 = args[2].(types.AccAddress) + } + var arg3 authz.Authorization + if args[3] != nil { + arg3 = args[3].(authz.Authorization) + } + var arg4 *time.Time + if args[4] != nil { + arg4 = args[4].(*time.Time) + } + run( + arg0, + arg1, + arg2, + arg3, + arg4, + ) + }) + return _c +} + +func (_c *AuthzKeeper_SaveGrant_Call) Return(err error) *AuthzKeeper_SaveGrant_Call { + _c.Call.Return(err) + return _c +} + +func (_c *AuthzKeeper_SaveGrant_Call) RunAndReturn(run func(ctx context.Context, grantee types.AccAddress, granter types.AccAddress, authorization authz.Authorization, expiration *time.Time) error) *AuthzKeeper_SaveGrant_Call { + _c.Call.Return(run) + return _c +} diff --git a/testutil/cosmos/mocks/BankKeeper_mock.go b/testutil/cosmos/mocks/BankKeeper_mock.go new file mode 100644 index 0000000000..82a7ce73f6 --- /dev/null +++ b/testutil/cosmos/mocks/BankKeeper_mock.go @@ -0,0 +1,368 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package keeper + +import ( + "context" + + "github.com/cosmos/cosmos-sdk/types" + mock "github.com/stretchr/testify/mock" +) + +// NewBankKeeper creates a new instance of BankKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewBankKeeper(t interface { + mock.TestingT + Cleanup(func()) +}) *BankKeeper { + mock := &BankKeeper{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// BankKeeper is an autogenerated mock type for the BankKeeper type +type BankKeeper struct { + mock.Mock +} + +type BankKeeper_Expecter struct { + mock *mock.Mock +} + +func (_m *BankKeeper) EXPECT() *BankKeeper_Expecter { + return &BankKeeper_Expecter{mock: &_m.Mock} +} + +// SendCoinsFromAccountToModule provides a mock function for the type BankKeeper +func (_mock *BankKeeper) SendCoinsFromAccountToModule(ctx context.Context, senderAddr types.AccAddress, recipientModule string, amt types.Coins) error { + ret := _mock.Called(ctx, senderAddr, recipientModule, amt) + + if len(ret) == 0 { + panic("no return value specified for SendCoinsFromAccountToModule") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, types.AccAddress, string, types.Coins) error); ok { + r0 = returnFunc(ctx, senderAddr, recipientModule, amt) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// BankKeeper_SendCoinsFromAccountToModule_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendCoinsFromAccountToModule' +type BankKeeper_SendCoinsFromAccountToModule_Call struct { + *mock.Call +} + +// SendCoinsFromAccountToModule is a helper method to define mock.On call +// - ctx context.Context +// - senderAddr types.AccAddress +// - recipientModule string +// - amt types.Coins +func (_e *BankKeeper_Expecter) SendCoinsFromAccountToModule(ctx interface{}, senderAddr interface{}, recipientModule interface{}, amt interface{}) *BankKeeper_SendCoinsFromAccountToModule_Call { + return &BankKeeper_SendCoinsFromAccountToModule_Call{Call: _e.mock.On("SendCoinsFromAccountToModule", ctx, senderAddr, recipientModule, amt)} +} + +func (_c *BankKeeper_SendCoinsFromAccountToModule_Call) Run(run func(ctx context.Context, senderAddr types.AccAddress, recipientModule string, amt types.Coins)) *BankKeeper_SendCoinsFromAccountToModule_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 types.AccAddress + if args[1] != nil { + arg1 = args[1].(types.AccAddress) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + var arg3 types.Coins + if args[3] != nil { + arg3 = args[3].(types.Coins) + } + run( + arg0, + arg1, + arg2, + arg3, + ) + }) + return _c +} + +func (_c *BankKeeper_SendCoinsFromAccountToModule_Call) Return(err error) *BankKeeper_SendCoinsFromAccountToModule_Call { + _c.Call.Return(err) + return _c +} + +func (_c *BankKeeper_SendCoinsFromAccountToModule_Call) RunAndReturn(run func(ctx context.Context, senderAddr types.AccAddress, recipientModule string, amt types.Coins) error) *BankKeeper_SendCoinsFromAccountToModule_Call { + _c.Call.Return(run) + return _c +} + +// SendCoinsFromModuleToAccount provides a mock function for the type BankKeeper +func (_mock *BankKeeper) SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr types.AccAddress, amt types.Coins) error { + ret := _mock.Called(ctx, senderModule, recipientAddr, amt) + + if len(ret) == 0 { + panic("no return value specified for SendCoinsFromModuleToAccount") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, string, types.AccAddress, types.Coins) error); ok { + r0 = returnFunc(ctx, senderModule, recipientAddr, amt) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// BankKeeper_SendCoinsFromModuleToAccount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendCoinsFromModuleToAccount' +type BankKeeper_SendCoinsFromModuleToAccount_Call struct { + *mock.Call +} + +// SendCoinsFromModuleToAccount is a helper method to define mock.On call +// - ctx context.Context +// - senderModule string +// - recipientAddr types.AccAddress +// - amt types.Coins +func (_e *BankKeeper_Expecter) SendCoinsFromModuleToAccount(ctx interface{}, senderModule interface{}, recipientAddr interface{}, amt interface{}) *BankKeeper_SendCoinsFromModuleToAccount_Call { + return &BankKeeper_SendCoinsFromModuleToAccount_Call{Call: _e.mock.On("SendCoinsFromModuleToAccount", ctx, senderModule, recipientAddr, amt)} +} + +func (_c *BankKeeper_SendCoinsFromModuleToAccount_Call) Run(run func(ctx context.Context, senderModule string, recipientAddr types.AccAddress, amt types.Coins)) *BankKeeper_SendCoinsFromModuleToAccount_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 types.AccAddress + if args[2] != nil { + arg2 = args[2].(types.AccAddress) + } + var arg3 types.Coins + if args[3] != nil { + arg3 = args[3].(types.Coins) + } + run( + arg0, + arg1, + arg2, + arg3, + ) + }) + return _c +} + +func (_c *BankKeeper_SendCoinsFromModuleToAccount_Call) Return(err error) *BankKeeper_SendCoinsFromModuleToAccount_Call { + _c.Call.Return(err) + return _c +} + +func (_c *BankKeeper_SendCoinsFromModuleToAccount_Call) RunAndReturn(run func(ctx context.Context, senderModule string, recipientAddr types.AccAddress, amt types.Coins) error) *BankKeeper_SendCoinsFromModuleToAccount_Call { + _c.Call.Return(run) + return _c +} + +// SendCoinsFromModuleToModule provides a mock function for the type BankKeeper +func (_mock *BankKeeper) SendCoinsFromModuleToModule(ctx context.Context, senderModule string, recipientModule string, amt types.Coins) error { + ret := _mock.Called(ctx, senderModule, recipientModule, amt) + + if len(ret) == 0 { + panic("no return value specified for SendCoinsFromModuleToModule") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, string, string, types.Coins) error); ok { + r0 = returnFunc(ctx, senderModule, recipientModule, amt) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// BankKeeper_SendCoinsFromModuleToModule_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendCoinsFromModuleToModule' +type BankKeeper_SendCoinsFromModuleToModule_Call struct { + *mock.Call +} + +// SendCoinsFromModuleToModule is a helper method to define mock.On call +// - ctx context.Context +// - senderModule string +// - recipientModule string +// - amt types.Coins +func (_e *BankKeeper_Expecter) SendCoinsFromModuleToModule(ctx interface{}, senderModule interface{}, recipientModule interface{}, amt interface{}) *BankKeeper_SendCoinsFromModuleToModule_Call { + return &BankKeeper_SendCoinsFromModuleToModule_Call{Call: _e.mock.On("SendCoinsFromModuleToModule", ctx, senderModule, recipientModule, amt)} +} + +func (_c *BankKeeper_SendCoinsFromModuleToModule_Call) Run(run func(ctx context.Context, senderModule string, recipientModule string, amt types.Coins)) *BankKeeper_SendCoinsFromModuleToModule_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + var arg3 types.Coins + if args[3] != nil { + arg3 = args[3].(types.Coins) + } + run( + arg0, + arg1, + arg2, + arg3, + ) + }) + return _c +} + +func (_c *BankKeeper_SendCoinsFromModuleToModule_Call) Return(err error) *BankKeeper_SendCoinsFromModuleToModule_Call { + _c.Call.Return(err) + return _c +} + +func (_c *BankKeeper_SendCoinsFromModuleToModule_Call) RunAndReturn(run func(ctx context.Context, senderModule string, recipientModule string, amt types.Coins) error) *BankKeeper_SendCoinsFromModuleToModule_Call { + _c.Call.Return(run) + return _c +} + +// SpendableCoin provides a mock function for the type BankKeeper +func (_mock *BankKeeper) SpendableCoin(ctx context.Context, addr types.AccAddress, denom string) types.Coin { + ret := _mock.Called(ctx, addr, denom) + + if len(ret) == 0 { + panic("no return value specified for SpendableCoin") + } + + var r0 types.Coin + if returnFunc, ok := ret.Get(0).(func(context.Context, types.AccAddress, string) types.Coin); ok { + r0 = returnFunc(ctx, addr, denom) + } else { + r0 = ret.Get(0).(types.Coin) + } + return r0 +} + +// BankKeeper_SpendableCoin_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SpendableCoin' +type BankKeeper_SpendableCoin_Call struct { + *mock.Call +} + +// SpendableCoin is a helper method to define mock.On call +// - ctx context.Context +// - addr types.AccAddress +// - denom string +func (_e *BankKeeper_Expecter) SpendableCoin(ctx interface{}, addr interface{}, denom interface{}) *BankKeeper_SpendableCoin_Call { + return &BankKeeper_SpendableCoin_Call{Call: _e.mock.On("SpendableCoin", ctx, addr, denom)} +} + +func (_c *BankKeeper_SpendableCoin_Call) Run(run func(ctx context.Context, addr types.AccAddress, denom string)) *BankKeeper_SpendableCoin_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 types.AccAddress + if args[1] != nil { + arg1 = args[1].(types.AccAddress) + } + var arg2 string + if args[2] != nil { + arg2 = args[2].(string) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *BankKeeper_SpendableCoin_Call) Return(coin types.Coin) *BankKeeper_SpendableCoin_Call { + _c.Call.Return(coin) + return _c +} + +func (_c *BankKeeper_SpendableCoin_Call) RunAndReturn(run func(ctx context.Context, addr types.AccAddress, denom string) types.Coin) *BankKeeper_SpendableCoin_Call { + _c.Call.Return(run) + return _c +} + +// SpendableCoins provides a mock function for the type BankKeeper +func (_mock *BankKeeper) SpendableCoins(ctx context.Context, addr types.AccAddress) types.Coins { + ret := _mock.Called(ctx, addr) + + if len(ret) == 0 { + panic("no return value specified for SpendableCoins") + } + + var r0 types.Coins + if returnFunc, ok := ret.Get(0).(func(context.Context, types.AccAddress) types.Coins); ok { + r0 = returnFunc(ctx, addr) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(types.Coins) + } + } + return r0 +} + +// BankKeeper_SpendableCoins_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SpendableCoins' +type BankKeeper_SpendableCoins_Call struct { + *mock.Call +} + +// SpendableCoins is a helper method to define mock.On call +// - ctx context.Context +// - addr types.AccAddress +func (_e *BankKeeper_Expecter) SpendableCoins(ctx interface{}, addr interface{}) *BankKeeper_SpendableCoins_Call { + return &BankKeeper_SpendableCoins_Call{Call: _e.mock.On("SpendableCoins", ctx, addr)} +} + +func (_c *BankKeeper_SpendableCoins_Call) Run(run func(ctx context.Context, addr types.AccAddress)) *BankKeeper_SpendableCoins_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 types.AccAddress + if args[1] != nil { + arg1 = args[1].(types.AccAddress) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *BankKeeper_SpendableCoins_Call) Return(coins types.Coins) *BankKeeper_SpendableCoins_Call { + _c.Call.Return(coins) + return _c +} + +func (_c *BankKeeper_SpendableCoins_Call) RunAndReturn(run func(ctx context.Context, addr types.AccAddress) types.Coins) *BankKeeper_SpendableCoins_Call { + _c.Call.Return(run) + return _c +} diff --git a/testutil/cosmos/mocks/take_keeper.go b/testutil/cosmos/mocks/TakeKeeper_mock.go similarity index 56% rename from testutil/cosmos/mocks/take_keeper.go rename to testutil/cosmos/mocks/TakeKeeper_mock.go index 1ecf9727be..fe7ac13a05 100644 --- a/testutil/cosmos/mocks/take_keeper.go +++ b/testutil/cosmos/mocks/TakeKeeper_mock.go @@ -1,12 +1,28 @@ -// Code generated by mockery v2.42.0. DO NOT EDIT. +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify -package mocks +package keeper import ( - types "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types" mock "github.com/stretchr/testify/mock" ) +// NewTakeKeeper creates a new instance of TakeKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewTakeKeeper(t interface { + mock.TestingT + Cleanup(func()) +}) *TakeKeeper { + mock := &TakeKeeper{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + // TakeKeeper is an autogenerated mock type for the TakeKeeper type type TakeKeeper struct { mock.Mock @@ -20,9 +36,9 @@ func (_m *TakeKeeper) EXPECT() *TakeKeeper_Expecter { return &TakeKeeper_Expecter{mock: &_m.Mock} } -// SubtractFees provides a mock function with given fields: ctx, amt -func (_m *TakeKeeper) SubtractFees(ctx types.Context, amt types.Coin) (types.Coin, types.Coin, error) { - ret := _m.Called(ctx, amt) +// SubtractFees provides a mock function for the type TakeKeeper +func (_mock *TakeKeeper) SubtractFees(ctx types.Context, amt types.Coin) (types.Coin, types.Coin, error) { + ret := _mock.Called(ctx, amt) if len(ret) == 0 { panic("no return value specified for SubtractFees") @@ -31,27 +47,24 @@ func (_m *TakeKeeper) SubtractFees(ctx types.Context, amt types.Coin) (types.Coi var r0 types.Coin var r1 types.Coin var r2 error - if rf, ok := ret.Get(0).(func(types.Context, types.Coin) (types.Coin, types.Coin, error)); ok { - return rf(ctx, amt) + if returnFunc, ok := ret.Get(0).(func(types.Context, types.Coin) (types.Coin, types.Coin, error)); ok { + return returnFunc(ctx, amt) } - if rf, ok := ret.Get(0).(func(types.Context, types.Coin) types.Coin); ok { - r0 = rf(ctx, amt) + if returnFunc, ok := ret.Get(0).(func(types.Context, types.Coin) types.Coin); ok { + r0 = returnFunc(ctx, amt) } else { r0 = ret.Get(0).(types.Coin) } - - if rf, ok := ret.Get(1).(func(types.Context, types.Coin) types.Coin); ok { - r1 = rf(ctx, amt) + if returnFunc, ok := ret.Get(1).(func(types.Context, types.Coin) types.Coin); ok { + r1 = returnFunc(ctx, amt) } else { r1 = ret.Get(1).(types.Coin) } - - if rf, ok := ret.Get(2).(func(types.Context, types.Coin) error); ok { - r2 = rf(ctx, amt) + if returnFunc, ok := ret.Get(2).(func(types.Context, types.Coin) error); ok { + r2 = returnFunc(ctx, amt) } else { r2 = ret.Error(2) } - return r0, r1, r2 } @@ -69,31 +82,28 @@ func (_e *TakeKeeper_Expecter) SubtractFees(ctx interface{}, amt interface{}) *T func (_c *TakeKeeper_SubtractFees_Call) Run(run func(ctx types.Context, amt types.Coin)) *TakeKeeper_SubtractFees_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Context), args[1].(types.Coin)) + var arg0 types.Context + if args[0] != nil { + arg0 = args[0].(types.Context) + } + var arg1 types.Coin + if args[1] != nil { + arg1 = args[1].(types.Coin) + } + run( + arg0, + arg1, + ) }) return _c } -func (_c *TakeKeeper_SubtractFees_Call) Return(_a0 types.Coin, _a1 types.Coin, _a2 error) *TakeKeeper_SubtractFees_Call { - _c.Call.Return(_a0, _a1, _a2) +func (_c *TakeKeeper_SubtractFees_Call) Return(coin types.Coin, coin1 types.Coin, err error) *TakeKeeper_SubtractFees_Call { + _c.Call.Return(coin, coin1, err) return _c } -func (_c *TakeKeeper_SubtractFees_Call) RunAndReturn(run func(types.Context, types.Coin) (types.Coin, types.Coin, error)) *TakeKeeper_SubtractFees_Call { +func (_c *TakeKeeper_SubtractFees_Call) RunAndReturn(run func(ctx types.Context, amt types.Coin) (types.Coin, types.Coin, error)) *TakeKeeper_SubtractFees_Call { _c.Call.Return(run) return _c } - -// NewTakeKeeper creates a new instance of TakeKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewTakeKeeper(t interface { - mock.TestingT - Cleanup(func()) -}) *TakeKeeper { - mock := &TakeKeeper{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/testutil/cosmos/mocks/authz_keeper.go b/testutil/cosmos/mocks/authz_keeper.go deleted file mode 100644 index 2109d51ead..0000000000 --- a/testutil/cosmos/mocks/authz_keeper.go +++ /dev/null @@ -1,200 +0,0 @@ -// Code generated by mockery v2.42.0. DO NOT EDIT. - -package mocks - -import ( - authz "github.com/cosmos/cosmos-sdk/x/authz" - - mock "github.com/stretchr/testify/mock" - - time "time" - - types "github.com/cosmos/cosmos-sdk/types" -) - -// AuthzKeeper is an autogenerated mock type for the AuthzKeeper type -type AuthzKeeper struct { - mock.Mock -} - -type AuthzKeeper_Expecter struct { - mock *mock.Mock -} - -func (_m *AuthzKeeper) EXPECT() *AuthzKeeper_Expecter { - return &AuthzKeeper_Expecter{mock: &_m.Mock} -} - -// DeleteGrant provides a mock function with given fields: ctx, grantee, granter, msgType -func (_m *AuthzKeeper) DeleteGrant(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, msgType string) error { - ret := _m.Called(ctx, grantee, granter, msgType) - - if len(ret) == 0 { - panic("no return value specified for DeleteGrant") - } - - var r0 error - if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, types.AccAddress, string) error); ok { - r0 = rf(ctx, grantee, granter, msgType) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// AuthzKeeper_DeleteGrant_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteGrant' -type AuthzKeeper_DeleteGrant_Call struct { - *mock.Call -} - -// DeleteGrant is a helper method to define mock.On call -// - ctx types.Context -// - grantee types.AccAddress -// - granter types.AccAddress -// - msgType string -func (_e *AuthzKeeper_Expecter) DeleteGrant(ctx interface{}, grantee interface{}, granter interface{}, msgType interface{}) *AuthzKeeper_DeleteGrant_Call { - return &AuthzKeeper_DeleteGrant_Call{Call: _e.mock.On("DeleteGrant", ctx, grantee, granter, msgType)} -} - -func (_c *AuthzKeeper_DeleteGrant_Call) Run(run func(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, msgType string)) *AuthzKeeper_DeleteGrant_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Context), args[1].(types.AccAddress), args[2].(types.AccAddress), args[3].(string)) - }) - return _c -} - -func (_c *AuthzKeeper_DeleteGrant_Call) Return(_a0 error) *AuthzKeeper_DeleteGrant_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *AuthzKeeper_DeleteGrant_Call) RunAndReturn(run func(types.Context, types.AccAddress, types.AccAddress, string) error) *AuthzKeeper_DeleteGrant_Call { - _c.Call.Return(run) - return _c -} - -// GetCleanAuthorization provides a mock function with given fields: ctx, grantee, granter, msgType -func (_m *AuthzKeeper) GetCleanAuthorization(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, msgType string) (authz.Authorization, time.Time) { - ret := _m.Called(ctx, grantee, granter, msgType) - - if len(ret) == 0 { - panic("no return value specified for GetCleanAuthorization") - } - - var r0 authz.Authorization - var r1 time.Time - if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, types.AccAddress, string) (authz.Authorization, time.Time)); ok { - return rf(ctx, grantee, granter, msgType) - } - if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, types.AccAddress, string) authz.Authorization); ok { - r0 = rf(ctx, grantee, granter, msgType) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(authz.Authorization) - } - } - - if rf, ok := ret.Get(1).(func(types.Context, types.AccAddress, types.AccAddress, string) time.Time); ok { - r1 = rf(ctx, grantee, granter, msgType) - } else { - r1 = ret.Get(1).(time.Time) - } - - return r0, r1 -} - -// AuthzKeeper_GetCleanAuthorization_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCleanAuthorization' -type AuthzKeeper_GetCleanAuthorization_Call struct { - *mock.Call -} - -// GetCleanAuthorization is a helper method to define mock.On call -// - ctx types.Context -// - grantee types.AccAddress -// - granter types.AccAddress -// - msgType string -func (_e *AuthzKeeper_Expecter) GetCleanAuthorization(ctx interface{}, grantee interface{}, granter interface{}, msgType interface{}) *AuthzKeeper_GetCleanAuthorization_Call { - return &AuthzKeeper_GetCleanAuthorization_Call{Call: _e.mock.On("GetCleanAuthorization", ctx, grantee, granter, msgType)} -} - -func (_c *AuthzKeeper_GetCleanAuthorization_Call) Run(run func(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, msgType string)) *AuthzKeeper_GetCleanAuthorization_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Context), args[1].(types.AccAddress), args[2].(types.AccAddress), args[3].(string)) - }) - return _c -} - -func (_c *AuthzKeeper_GetCleanAuthorization_Call) Return(cap authz.Authorization, expiration time.Time) *AuthzKeeper_GetCleanAuthorization_Call { - _c.Call.Return(cap, expiration) - return _c -} - -func (_c *AuthzKeeper_GetCleanAuthorization_Call) RunAndReturn(run func(types.Context, types.AccAddress, types.AccAddress, string) (authz.Authorization, time.Time)) *AuthzKeeper_GetCleanAuthorization_Call { - _c.Call.Return(run) - return _c -} - -// SaveGrant provides a mock function with given fields: ctx, grantee, granter, authorization, expiration -func (_m *AuthzKeeper) SaveGrant(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, authorization authz.Authorization, expiration time.Time) error { - ret := _m.Called(ctx, grantee, granter, authorization, expiration) - - if len(ret) == 0 { - panic("no return value specified for SaveGrant") - } - - var r0 error - if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, types.AccAddress, authz.Authorization, time.Time) error); ok { - r0 = rf(ctx, grantee, granter, authorization, expiration) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// AuthzKeeper_SaveGrant_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveGrant' -type AuthzKeeper_SaveGrant_Call struct { - *mock.Call -} - -// SaveGrant is a helper method to define mock.On call -// - ctx types.Context -// - grantee types.AccAddress -// - granter types.AccAddress -// - authorization authz.Authorization -// - expiration time.Time -func (_e *AuthzKeeper_Expecter) SaveGrant(ctx interface{}, grantee interface{}, granter interface{}, authorization interface{}, expiration interface{}) *AuthzKeeper_SaveGrant_Call { - return &AuthzKeeper_SaveGrant_Call{Call: _e.mock.On("SaveGrant", ctx, grantee, granter, authorization, expiration)} -} - -func (_c *AuthzKeeper_SaveGrant_Call) Run(run func(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, authorization authz.Authorization, expiration time.Time)) *AuthzKeeper_SaveGrant_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Context), args[1].(types.AccAddress), args[2].(types.AccAddress), args[3].(authz.Authorization), args[4].(time.Time)) - }) - return _c -} - -func (_c *AuthzKeeper_SaveGrant_Call) Return(_a0 error) *AuthzKeeper_SaveGrant_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *AuthzKeeper_SaveGrant_Call) RunAndReturn(run func(types.Context, types.AccAddress, types.AccAddress, authz.Authorization, time.Time) error) *AuthzKeeper_SaveGrant_Call { - _c.Call.Return(run) - return _c -} - -// NewAuthzKeeper creates a new instance of AuthzKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewAuthzKeeper(t interface { - mock.TestingT - Cleanup(func()) -}) *AuthzKeeper { - mock := &AuthzKeeper{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/testutil/cosmos/mocks/bank_keeper.go b/testutil/cosmos/mocks/bank_keeper.go deleted file mode 100644 index d68cc96ac2..0000000000 --- a/testutil/cosmos/mocks/bank_keeper.go +++ /dev/null @@ -1,182 +0,0 @@ -// Code generated by mockery v2.42.0. DO NOT EDIT. - -package mocks - -import ( - types "github.com/cosmos/cosmos-sdk/types" - mock "github.com/stretchr/testify/mock" -) - -// BankKeeper is an autogenerated mock type for the BankKeeper type -type BankKeeper struct { - mock.Mock -} - -type BankKeeper_Expecter struct { - mock *mock.Mock -} - -func (_m *BankKeeper) EXPECT() *BankKeeper_Expecter { - return &BankKeeper_Expecter{mock: &_m.Mock} -} - -// SendCoinsFromAccountToModule provides a mock function with given fields: ctx, senderAddr, recipientModule, amt -func (_m *BankKeeper) SendCoinsFromAccountToModule(ctx types.Context, senderAddr types.AccAddress, recipientModule string, amt types.Coins) error { - ret := _m.Called(ctx, senderAddr, recipientModule, amt) - - if len(ret) == 0 { - panic("no return value specified for SendCoinsFromAccountToModule") - } - - var r0 error - if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, string, types.Coins) error); ok { - r0 = rf(ctx, senderAddr, recipientModule, amt) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// BankKeeper_SendCoinsFromAccountToModule_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendCoinsFromAccountToModule' -type BankKeeper_SendCoinsFromAccountToModule_Call struct { - *mock.Call -} - -// SendCoinsFromAccountToModule is a helper method to define mock.On call -// - ctx types.Context -// - senderAddr types.AccAddress -// - recipientModule string -// - amt types.Coins -func (_e *BankKeeper_Expecter) SendCoinsFromAccountToModule(ctx interface{}, senderAddr interface{}, recipientModule interface{}, amt interface{}) *BankKeeper_SendCoinsFromAccountToModule_Call { - return &BankKeeper_SendCoinsFromAccountToModule_Call{Call: _e.mock.On("SendCoinsFromAccountToModule", ctx, senderAddr, recipientModule, amt)} -} - -func (_c *BankKeeper_SendCoinsFromAccountToModule_Call) Run(run func(ctx types.Context, senderAddr types.AccAddress, recipientModule string, amt types.Coins)) *BankKeeper_SendCoinsFromAccountToModule_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Context), args[1].(types.AccAddress), args[2].(string), args[3].(types.Coins)) - }) - return _c -} - -func (_c *BankKeeper_SendCoinsFromAccountToModule_Call) Return(_a0 error) *BankKeeper_SendCoinsFromAccountToModule_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *BankKeeper_SendCoinsFromAccountToModule_Call) RunAndReturn(run func(types.Context, types.AccAddress, string, types.Coins) error) *BankKeeper_SendCoinsFromAccountToModule_Call { - _c.Call.Return(run) - return _c -} - -// SendCoinsFromModuleToAccount provides a mock function with given fields: ctx, senderModule, recipientAddr, amt -func (_m *BankKeeper) SendCoinsFromModuleToAccount(ctx types.Context, senderModule string, recipientAddr types.AccAddress, amt types.Coins) error { - ret := _m.Called(ctx, senderModule, recipientAddr, amt) - - if len(ret) == 0 { - panic("no return value specified for SendCoinsFromModuleToAccount") - } - - var r0 error - if rf, ok := ret.Get(0).(func(types.Context, string, types.AccAddress, types.Coins) error); ok { - r0 = rf(ctx, senderModule, recipientAddr, amt) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// BankKeeper_SendCoinsFromModuleToAccount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendCoinsFromModuleToAccount' -type BankKeeper_SendCoinsFromModuleToAccount_Call struct { - *mock.Call -} - -// SendCoinsFromModuleToAccount is a helper method to define mock.On call -// - ctx types.Context -// - senderModule string -// - recipientAddr types.AccAddress -// - amt types.Coins -func (_e *BankKeeper_Expecter) SendCoinsFromModuleToAccount(ctx interface{}, senderModule interface{}, recipientAddr interface{}, amt interface{}) *BankKeeper_SendCoinsFromModuleToAccount_Call { - return &BankKeeper_SendCoinsFromModuleToAccount_Call{Call: _e.mock.On("SendCoinsFromModuleToAccount", ctx, senderModule, recipientAddr, amt)} -} - -func (_c *BankKeeper_SendCoinsFromModuleToAccount_Call) Run(run func(ctx types.Context, senderModule string, recipientAddr types.AccAddress, amt types.Coins)) *BankKeeper_SendCoinsFromModuleToAccount_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Context), args[1].(string), args[2].(types.AccAddress), args[3].(types.Coins)) - }) - return _c -} - -func (_c *BankKeeper_SendCoinsFromModuleToAccount_Call) Return(_a0 error) *BankKeeper_SendCoinsFromModuleToAccount_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *BankKeeper_SendCoinsFromModuleToAccount_Call) RunAndReturn(run func(types.Context, string, types.AccAddress, types.Coins) error) *BankKeeper_SendCoinsFromModuleToAccount_Call { - _c.Call.Return(run) - return _c -} - -// SendCoinsFromModuleToModule provides a mock function with given fields: ctx, senderModule, recipientModule, amt -func (_m *BankKeeper) SendCoinsFromModuleToModule(ctx types.Context, senderModule string, recipientModule string, amt types.Coins) error { - ret := _m.Called(ctx, senderModule, recipientModule, amt) - - if len(ret) == 0 { - panic("no return value specified for SendCoinsFromModuleToModule") - } - - var r0 error - if rf, ok := ret.Get(0).(func(types.Context, string, string, types.Coins) error); ok { - r0 = rf(ctx, senderModule, recipientModule, amt) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// BankKeeper_SendCoinsFromModuleToModule_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendCoinsFromModuleToModule' -type BankKeeper_SendCoinsFromModuleToModule_Call struct { - *mock.Call -} - -// SendCoinsFromModuleToModule is a helper method to define mock.On call -// - ctx types.Context -// - senderModule string -// - recipientModule string -// - amt types.Coins -func (_e *BankKeeper_Expecter) SendCoinsFromModuleToModule(ctx interface{}, senderModule interface{}, recipientModule interface{}, amt interface{}) *BankKeeper_SendCoinsFromModuleToModule_Call { - return &BankKeeper_SendCoinsFromModuleToModule_Call{Call: _e.mock.On("SendCoinsFromModuleToModule", ctx, senderModule, recipientModule, amt)} -} - -func (_c *BankKeeper_SendCoinsFromModuleToModule_Call) Run(run func(ctx types.Context, senderModule string, recipientModule string, amt types.Coins)) *BankKeeper_SendCoinsFromModuleToModule_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Context), args[1].(string), args[2].(string), args[3].(types.Coins)) - }) - return _c -} - -func (_c *BankKeeper_SendCoinsFromModuleToModule_Call) Return(_a0 error) *BankKeeper_SendCoinsFromModuleToModule_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *BankKeeper_SendCoinsFromModuleToModule_Call) RunAndReturn(run func(types.Context, string, string, types.Coins) error) *BankKeeper_SendCoinsFromModuleToModule_Call { - _c.Call.Return(run) - return _c -} - -// NewBankKeeper creates a new instance of BankKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewBankKeeper(t interface { - mock.TestingT - Cleanup(func()) -}) *BankKeeper { - mock := &BankKeeper{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/testutil/cosmos/mocks/distr_keeper.go b/testutil/cosmos/mocks/distr_keeper.go deleted file mode 100644 index d013b76750..0000000000 --- a/testutil/cosmos/mocks/distr_keeper.go +++ /dev/null @@ -1,118 +0,0 @@ -// Code generated by mockery v2.42.0. DO NOT EDIT. - -package mocks - -import ( - distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - - mock "github.com/stretchr/testify/mock" - - types "github.com/cosmos/cosmos-sdk/types" -) - -// DistrKeeper is an autogenerated mock type for the DistrKeeper type -type DistrKeeper struct { - mock.Mock -} - -type DistrKeeper_Expecter struct { - mock *mock.Mock -} - -func (_m *DistrKeeper) EXPECT() *DistrKeeper_Expecter { - return &DistrKeeper_Expecter{mock: &_m.Mock} -} - -// GetFeePool provides a mock function with given fields: ctx -func (_m *DistrKeeper) GetFeePool(ctx types.Context) distributiontypes.FeePool { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for GetFeePool") - } - - var r0 distributiontypes.FeePool - if rf, ok := ret.Get(0).(func(types.Context) distributiontypes.FeePool); ok { - r0 = rf(ctx) - } else { - r0 = ret.Get(0).(distributiontypes.FeePool) - } - - return r0 -} - -// DistrKeeper_GetFeePool_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetFeePool' -type DistrKeeper_GetFeePool_Call struct { - *mock.Call -} - -// GetFeePool is a helper method to define mock.On call -// - ctx types.Context -func (_e *DistrKeeper_Expecter) GetFeePool(ctx interface{}) *DistrKeeper_GetFeePool_Call { - return &DistrKeeper_GetFeePool_Call{Call: _e.mock.On("GetFeePool", ctx)} -} - -func (_c *DistrKeeper_GetFeePool_Call) Run(run func(ctx types.Context)) *DistrKeeper_GetFeePool_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Context)) - }) - return _c -} - -func (_c *DistrKeeper_GetFeePool_Call) Return(_a0 distributiontypes.FeePool) *DistrKeeper_GetFeePool_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *DistrKeeper_GetFeePool_Call) RunAndReturn(run func(types.Context) distributiontypes.FeePool) *DistrKeeper_GetFeePool_Call { - _c.Call.Return(run) - return _c -} - -// SetFeePool provides a mock function with given fields: ctx, pool -func (_m *DistrKeeper) SetFeePool(ctx types.Context, pool distributiontypes.FeePool) { - _m.Called(ctx, pool) -} - -// DistrKeeper_SetFeePool_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetFeePool' -type DistrKeeper_SetFeePool_Call struct { - *mock.Call -} - -// SetFeePool is a helper method to define mock.On call -// - ctx types.Context -// - pool distributiontypes.FeePool -func (_e *DistrKeeper_Expecter) SetFeePool(ctx interface{}, pool interface{}) *DistrKeeper_SetFeePool_Call { - return &DistrKeeper_SetFeePool_Call{Call: _e.mock.On("SetFeePool", ctx, pool)} -} - -func (_c *DistrKeeper_SetFeePool_Call) Run(run func(ctx types.Context, pool distributiontypes.FeePool)) *DistrKeeper_SetFeePool_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Context), args[1].(distributiontypes.FeePool)) - }) - return _c -} - -func (_c *DistrKeeper_SetFeePool_Call) Return() *DistrKeeper_SetFeePool_Call { - _c.Call.Return() - return _c -} - -func (_c *DistrKeeper_SetFeePool_Call) RunAndReturn(run func(types.Context, distributiontypes.FeePool)) *DistrKeeper_SetFeePool_Call { - _c.Call.Return(run) - return _c -} - -// NewDistrKeeper creates a new instance of DistrKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewDistrKeeper(t interface { - mock.TestingT - Cleanup(func()) -}) *DistrKeeper { - mock := &DistrKeeper{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/testutil/deployment.go b/testutil/deployment.go deleted file mode 100644 index 9e12036a9b..0000000000 --- a/testutil/deployment.go +++ /dev/null @@ -1,61 +0,0 @@ -package testutil - -import ( - "crypto/sha256" - "math/rand" - "testing" - - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" -) - -// sum256Seed provides a consistent sha256 value for initial Deployment.Version -const sum256Seed = "hihi" - -// DefaultDeploymentVersion provides consistent sha256 sum for initial Deployment.Version -var DefaultDeploymentVersion = sha256.Sum256([]byte(sum256Seed)) - -// Deployment generates a dtype.Deployment in state `DeploymentActive` -func Deployment(t testing.TB) dtypes.Deployment { - t.Helper() - return dtypes.Deployment{ - DeploymentID: DeploymentID(t), - State: dtypes.DeploymentActive, - Version: DefaultDeploymentVersion[:], - } -} - -// DeploymentGroup generates a dtype.DepDeploymentGroup in state `GroupOpen` -// with a set of random required attributes -func DeploymentGroup(t testing.TB, did dtypes.DeploymentID, gseq uint32) dtypes.Group { - t.Helper() - return dtypes.Group{ - GroupID: dtypes.MakeGroupID(did, gseq), - State: dtypes.GroupOpen, - GroupSpec: dtypes.GroupSpec{ - Name: Name(t, "dgroup"), - Requirements: PlacementRequirements(t), - Resources: Resources(t), - }, - } -} - -// GroupSpec generator -func GroupSpec(t testing.TB) dtypes.GroupSpec { - t.Helper() - return dtypes.GroupSpec{ - Name: Name(t, "dgroup"), - Requirements: PlacementRequirements(t), - Resources: Resources(t), - } -} - -// DeploymentGroups returns a set of deployment groups generated by DeploymentGroup -func DeploymentGroups(t testing.TB, did dtypes.DeploymentID, gseq uint32) []dtypes.Group { - t.Helper() - count := rand.Intn(5) + 5 // nolint:gosec - vals := make([]dtypes.Group, 0, count) - for i := 0; i < count; i++ { - vals = append(vals, DeploymentGroup(t, did, gseq+uint32(i))) - } - return vals -} diff --git a/testutil/event.go b/testutil/event.go deleted file mode 100644 index 0597fea6f9..0000000000 --- a/testutil/event.go +++ /dev/null @@ -1,60 +0,0 @@ -package testutil - -import ( - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" - - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - mtypes "github.com/akash-network/akash-api/go/node/market/v1beta4" - ptypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" - "github.com/akash-network/akash-api/go/sdkutil" -) - -func ParseEvent(t testing.TB, events []abci.Event) sdkutil.Event { - t.Helper() - - require.Equal(t, 1, len(events)) - - sev := sdk.StringifyEvent(events[0]) - ev, err := sdkutil.ParseEvent(sev) - - require.NoError(t, err) - - return ev -} - -func ParseDeploymentEvent(t testing.TB, events []abci.Event) sdkutil.ModuleEvent { - t.Helper() - - uev := ParseEvent(t, events) - - iev, err := dtypes.ParseEvent(uev) - require.NoError(t, err) - - return iev -} - -func ParseMarketEvent(t testing.TB, events []abci.Event) sdkutil.ModuleEvent { - t.Helper() - - uev := ParseEvent(t, events) - - iev, err := mtypes.ParseEvent(uev) - require.NoError(t, err) - - return iev -} - -func ParseProviderEvent(t testing.TB, events []abci.Event) sdkutil.ModuleEvent { - t.Helper() - - uev := ParseEvent(t, events) - - iev, err := ptypes.ParseEvent(uev) - require.NoError(t, err) - - return iev -} diff --git a/testutil/ids.go b/testutil/ids.go deleted file mode 100644 index 6ed7fa10f7..0000000000 --- a/testutil/ids.go +++ /dev/null @@ -1,102 +0,0 @@ -package testutil - -import ( - cryptorand "crypto/rand" - "crypto/sha256" - "math/rand" - "testing" - - "github.com/cosmos/cosmos-sdk/crypto/keyring" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/tendermint/tendermint/crypto/ed25519" - - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - mtypes "github.com/akash-network/akash-api/go/node/market/v1beta4" -) - -func Keyring(t testing.TB) keyring.Keyring { - t.Helper() - obj := keyring.NewInMemory() - return obj -} - -// AccAddress provides an Account's Address bytes from a ed25519 generated -// private key. -func AccAddress(t testing.TB) sdk.AccAddress { - t.Helper() - privKey := ed25519.GenPrivKey() - return sdk.AccAddress(privKey.PubKey().Address()) -} - -func Key(t testing.TB) ed25519.PrivKey { - t.Helper() - return ed25519.GenPrivKey() -} - -func DeploymentID(t testing.TB) dtypes.DeploymentID { - t.Helper() - return dtypes.DeploymentID{ - Owner: AccAddress(t).String(), - DSeq: uint64(rand.Uint32()), // nolint: gosec - } -} - -func DeploymentIDForAccount(t testing.TB, addr sdk.Address) dtypes.DeploymentID { - t.Helper() - return dtypes.DeploymentID{ - Owner: addr.String(), - DSeq: uint64(rand.Uint32()), // nolint: gosec - } -} - -// DeploymentVersion provides a random sha256 sum for simulating Deployments. -func DeploymentVersion(t testing.TB) []byte { - t.Helper() - src := make([]byte, 128) - _, err := cryptorand.Read(src) - if err != nil { - t.Fatal(err) - } - sum := sha256.Sum256(src) - return sum[:] -} - -func GroupID(t testing.TB) dtypes.GroupID { - t.Helper() - return dtypes.MakeGroupID(DeploymentID(t), rand.Uint32()) // nolint: gosec -} - -func GroupIDForAccount(t testing.TB, addr sdk.Address) dtypes.GroupID { - t.Helper() - return dtypes.MakeGroupID(DeploymentIDForAccount(t, addr), rand.Uint32()) // nolint: gosec -} - -func OrderID(t testing.TB) mtypes.OrderID { - t.Helper() - return mtypes.MakeOrderID(GroupID(t), rand.Uint32()) // nolint: gosec -} - -func OrderIDForAccount(t testing.TB, addr sdk.Address) mtypes.OrderID { - t.Helper() - return mtypes.MakeOrderID(GroupIDForAccount(t, addr), rand.Uint32()) // nolint: gosec -} - -func BidID(t testing.TB) mtypes.BidID { - t.Helper() - return mtypes.MakeBidID(OrderID(t), AccAddress(t)) -} - -func BidIDForAccount(t testing.TB, owner, provider sdk.Address) mtypes.BidID { - t.Helper() - return mtypes.MakeBidID(OrderIDForAccount(t, owner), provider.Bytes()) -} - -func LeaseID(t testing.TB) mtypes.LeaseID { - t.Helper() - return mtypes.MakeLeaseID(BidID(t)) -} - -func LeaseIDForAccount(t testing.TB, owner, provider sdk.Address) mtypes.LeaseID { - t.Helper() - return mtypes.MakeLeaseID(BidIDForAccount(t, owner, provider)) -} diff --git a/testutil/log.go b/testutil/log.go deleted file mode 100644 index 3935d5e078..0000000000 --- a/testutil/log.go +++ /dev/null @@ -1,27 +0,0 @@ -package testutil - -import ( - "sync" - "testing" - - "github.com/tendermint/tendermint/libs/log" -) - -func Logger(t testing.TB) log.Logger { - return log.NewTMLogger(&testWriter{TB: t}) -} - -// Source: https://git.sr.ht/~samwhited/testlog/tree/b1b3e8e82fd6990e91ce9d0fbcbe69ac2d9b1f98/testlog.go -type testWriter struct { - testing.TB - lock sync.Mutex -} - -func (tw *testWriter) Write(p []byte) (int, error) { - defer tw.lock.Unlock() - tw.lock.Lock() - - tw.Helper() - tw.Logf("%s", p) - return len(p), nil -} diff --git a/testutil/network/network.go b/testutil/network/network.go index 6d15ac4853..3c40c510a2 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -10,37 +10,35 @@ import ( "net/http" "net/url" "os" + "os/signal" "path/filepath" "sync" + "syscall" "testing" "time" "github.com/stretchr/testify/require" - - tmcfg "github.com/tendermint/tendermint/config" - tmflags "github.com/tendermint/tendermint/libs/cli/flags" - "github.com/tendermint/tendermint/libs/log" - "github.com/tendermint/tendermint/node" - tmclient "github.com/tendermint/tendermint/rpc/client" - cmtrpc "github.com/tendermint/tendermint/rpc/core" - cmtrpcsrv "github.com/tendermint/tendermint/rpc/jsonrpc/server" - dbm "github.com/tendermint/tm-db" + "golang.org/x/sync/errgroup" "google.golang.org/grpc" - "github.com/cosmos/cosmos-sdk/baseapp" + tmrand "github.com/cometbft/cometbft/libs/rand" + "github.com/cometbft/cometbft/node" + tmclient "github.com/cometbft/cometbft/rpc/client" + + "cosmossdk.io/log" + "cosmossdk.io/math" + pruningtypes "cosmossdk.io/store/pruning/types" sdkclient "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server/api" srvconfig "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" - "github.com/cosmos/cosmos-sdk/simapp" - "github.com/cosmos/cosmos-sdk/simapp/params" - storetypes "github.com/cosmos/cosmos-sdk/store/types" "github.com/cosmos/cosmos-sdk/testutil" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -48,13 +46,11 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/akash-network/node/client" -) + cflags "pkg.akt.dev/go/cli/flags" + "pkg.akt.dev/go/sdkutil" -func init() { - // register akash api routes - cmtrpc.Routes["akash"] = cmtrpcsrv.NewRPCFunc(client.RPCAkash, "") -} + "pkg.akt.dev/node/app" +) const ( portsPerValidator = 2 @@ -65,21 +61,29 @@ var ( lock = new(sync.Mutex) ) +type TestnetFixtureOptions struct { + EncCfg sdkutil.EncodingConfig +} + +type TestnetFixtureOption func(*TestnetFixtureOptions) + +func WithEncodingConfig(val sdkutil.EncodingConfig) TestnetFixtureOption { + return func(opts *TestnetFixtureOptions) { + opts.EncCfg = val + } +} + // AppConstructor defines a function which accepts a network configuration and // creates an ABCI Application to provide to Tendermint. -type AppConstructor = func(val Validator) servertypes.Application - -// NewAppConstructor returns a new simapp AppConstructor -func NewAppConstructor(encodingCfg params.EncodingConfig) AppConstructor { - return func(val Validator) servertypes.Application { - return simapp.NewSimApp( - val.Ctx.Logger, dbm.NewMemDB(), nil, true, make(map[int64]bool), val.Ctx.Config.RootDir, 0, - encodingCfg, - simapp.EmptyAppOptions{}, - baseapp.SetPruning(storetypes.NewPruningOptionsFromString(val.AppConfig.Pruning)), - baseapp.SetMinGasPrices(val.AppConfig.MinGasPrices), - ) - } +type ( + AppConstructor = func(val ValidatorI) servertypes.Application + TestFixtureFactory = func(opts ...TestnetFixtureOption) TestFixture +) + +type TestFixture struct { + AppConstructor AppConstructor + GenesisState map[string]json.RawMessage + EncodingConfig sdkutil.EncodingConfig } // Config defines the necessary configuration used to bootstrap and start an @@ -88,26 +92,25 @@ type Config struct { Codec codec.Codec LegacyAmino *codec.LegacyAmino // TODO: Remove! InterfaceRegistry codectypes.InterfaceRegistry - - TxConfig sdkclient.TxConfig - AccountRetriever sdkclient.AccountRetriever - AppConstructor AppConstructor // the ABCI application constructor - GenesisState map[string]json.RawMessage // custom genesis state to provide - TimeoutCommit time.Duration // the consensus commitment timeout - ChainID string // the network chain-id - NumValidators int // the total number of validators to create and bond - Mnemonics []string // custom user-provided validator operator mnemonics - BondDenom string // the staking bond denomination - Denoms []string // list of additional denoms could be used on network - MinGasPrices string // the minimum gas prices each validator will accept - AccountTokens sdk.Int // the amount of unique validator tokens (e.g. 1000node0) - StakingTokens sdk.Int // the amount of tokens each validator has available to stake - BondedTokens sdk.Int // the amount of tokens each validator stakes - PruningStrategy string // the pruning strategy each validator will have - EnableLogging bool // enable Tendermint logging to STDOUT - CleanupDir bool // remove base temporary directory during cleanup - SigningAlgo string // signing algorithm for keys - KeyringOptions []keyring.Option + TxConfig sdkclient.TxConfig + AccountRetriever sdkclient.AccountRetriever + AppConstructor AppConstructor // the ABCI application constructor + GenesisState map[string]json.RawMessage // custom genesis state to provide + TimeoutCommit time.Duration // the consensus commitment timeout + ChainID string // the network chain-id + NumValidators int // the total number of validators to create and bond + Mnemonics []string // custom user-provided validator operator mnemonics + BondDenom string // the staking bond denomination + Denoms []string // list of additional denoms could be used on network + MinGasPrices string // the minimum gas prices each validator will accept + AccountTokens math.Int // the amount of unique validator tokens (e.g. 1000node0) + StakingTokens math.Int // the amount of tokens each validator has available to stake + BondedTokens math.Int // the amount of tokens each validator stakes + PruningStrategy string // the pruning strategy each validator will have + EnableLogging bool // enable Tendermint logging to STDOUT + CleanupDir bool // remove base temporary directory during cleanup + SigningAlgo string // signing algorithm for keys + KeyringOptions []keyring.Option } // Network defines a local in-process testing network using SimApp. It can be @@ -146,10 +149,27 @@ type Validator struct { ValAddress sdk.ValAddress RPCClient tmclient.Client - tmNode *node.Node - api *api.Server - grpc *grpc.Server - grpcWeb *http.Server + app servertypes.Application + tmNode *node.Node + api *api.Server + grpc *grpc.Server + grpcWeb *http.Server + errGroup *errgroup.Group + cancelFn context.CancelFunc +} + +// ValidatorI expose a validator's context and configuration +type ValidatorI interface { + GetCtx() *server.Context + GetAppConfig() *srvconfig.Config +} + +func (v Validator) GetCtx() *server.Context { + return v.Ctx +} + +func (v Validator) GetAppConfig() *srvconfig.Config { + return v.AppConfig } // GetFreePorts asks the kernel for free open ports that are ready to use. @@ -158,12 +178,6 @@ func GetFreePorts(count int) ([]int, error) { listeners := make([]*net.TCPListener, 0, count) - defer func() { - for _, l := range listeners { - _ = l.Close() - } - }() - for i := 0; i < count; i++ { addr, err := net.ResolveTCPAddr("tcp", "localhost:0") if err != nil { @@ -179,9 +193,42 @@ func GetFreePorts(count int) ([]int, error) { ports = append(ports, l.Addr().(*net.TCPAddr).Port) } + for _, l := range listeners { + if err := l.Close(); err != nil { + return nil, err + } + } + return ports, nil } +type freePorts struct { + lock sync.Mutex + idx int + ports []int +} + +func newFreePorts(ports []int) *freePorts { + return &freePorts{ + idx: 0, + ports: ports, + } +} + +func (p *freePorts) mustGetPort() int { + defer p.lock.Unlock() + p.lock.Lock() + + if p.idx == len(p.ports) { + panic("no ports available") + } + + port := p.ports[p.idx] + p.idx++ + + return port +} + // New creates a new Network for integration tests. func New(t *testing.T, cfg Config) *Network { // only one caller/test can create and use a network at a time @@ -205,14 +252,20 @@ func New(t *testing.T, cfg Config) *Network { nodeIDs := make([]string, cfg.NumValidators) valPubKeys := make([]cryptotypes.PubKey, cfg.NumValidators) - var ( - genAccounts []authtypes.GenesisAccount - genBalances []banktypes.Balance - genFiles []string - ) + var genAccounts []authtypes.GenesisAccount + var genBalances []banktypes.Balance + var genFiles []string buf := bufio.NewReader(os.Stdin) + allocPortsCount := (portsPerValidator * cfg.NumValidators) + 4 + + availablePorts, err := GetFreePorts(allocPortsCount) + require.NoError(t, err) + require.Equal(t, allocPortsCount, len(availablePorts)) + + ports := newFreePorts(availablePorts) + // generate private keys, node IDs, and initial transactions for i := 0; i < cfg.NumValidators; i++ { appCfg := srvconfig.DefaultConfig() @@ -221,48 +274,43 @@ func New(t *testing.T, cfg Config) *Network { appCfg.API.Enable = true appCfg.API.Swagger = false appCfg.Telemetry.Enabled = false + appCfg.GRPC.Enable = false + appCfg.GRPCWeb.Enable = false ctx := server.NewDefaultContext() - tmCfg := ctx.Config - tmCfg.Consensus.TimeoutCommit = cfg.TimeoutCommit + ctx.Viper.Set(cflags.FlagChainID, cfg.ChainID) // Only allow the first validator to expose an RPC, API and gRPC // server/client due to Tendermint in-process constraints. apiAddr := "" - tmCfg.RPC.ListenAddress = "" - appCfg.GRPC.Enable = false - appCfg.GRPCWeb.Enable = false - allocPortsCount := portsPerValidator - if i == 0 { - allocPortsCount += 4 - } + tmCfg := ctx.Config + tmCfg.Consensus.TimeoutCommit = cfg.TimeoutCommit - ports, err := GetFreePorts(allocPortsCount) - require.NoError(t, err) - require.Equal(t, allocPortsCount, len(ports)) + tmCfg.RPC.ListenAddress = "" + tmCfg.ProxyApp = fmt.Sprintf("tcp://127.0.0.1:%d", ports.mustGetPort()) + tmCfg.P2P.ListenAddress = fmt.Sprintf("tcp://127.0.0.1:%d", ports.mustGetPort()) + tmCfg.P2P.AddrBookStrict = false + tmCfg.P2P.AllowDuplicateIP = true if i == 0 { - apiListenAddr := fmt.Sprintf("tcp://0.0.0.0:%d", ports[2]) + apiListenAddr := fmt.Sprintf("tcp://0.0.0.0:%d", ports.mustGetPort()) appCfg.API.Address = apiListenAddr apiURL, err := url.Parse(apiListenAddr) require.NoError(t, err) apiAddr = fmt.Sprintf("http://%s:%s", apiURL.Hostname(), apiURL.Port()) - tmCfg.RPC.ListenAddress = fmt.Sprintf("tcp://0.0.0.0:%d", ports[3]) - - appCfg.GRPC.Address = fmt.Sprintf("0.0.0.0:%d", ports[4]) + tmCfg.RPC.ListenAddress = fmt.Sprintf("tcp://127.0.0.1:%d", ports.mustGetPort()) + appCfg.GRPC.Address = fmt.Sprintf("127.0.0.1:%d", ports.mustGetPort()) appCfg.GRPC.Enable = true - appCfg.GRPCWeb.Address = fmt.Sprintf("0.0.0.0:%d", ports[5]) appCfg.GRPCWeb.Enable = true } logger := log.NewNopLogger() if cfg.EnableLogging { - logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) - logger, _ = tmflags.ParseLogLevel("info", logger, tmcfg.DefaultLogLevel) + logger = log.NewLogger(os.Stdout) } ctx.Logger = logger @@ -272,24 +320,19 @@ func New(t *testing.T, cfg Config) *Network { clientDir := filepath.Join(network.BaseDir, nodeDirName, "simcli") gentxsDir := filepath.Join(network.BaseDir, "gentxs") - require.NoError(t, os.MkdirAll(filepath.Join(nodeDir, "config"), 0o755)) - require.NoError(t, os.MkdirAll(clientDir, 0o755)) + require.NoError(t, os.MkdirAll(filepath.Join(nodeDir, "config"), 0o755)) //nolint: gosec + require.NoError(t, os.MkdirAll(clientDir, 0o755)) //nolint: gosec tmCfg.SetRoot(nodeDir) tmCfg.Moniker = nodeDirName monikers[i] = nodeDirName - tmCfg.ProxyApp = fmt.Sprintf("tcp://0.0.0.0:%d", ports[0]) - tmCfg.P2P.ListenAddress = fmt.Sprintf("tcp://0.0.0.0:%d", ports[1]) - tmCfg.P2P.AddrBookStrict = false - tmCfg.P2P.AllowDuplicateIP = true - nodeID, pubKey, err := genutil.InitializeNodeValidatorFiles(tmCfg) require.NoError(t, err) nodeIDs[i] = nodeID valPubKeys[i] = pubKey - kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, clientDir, buf, cfg.KeyringOptions...) + kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, clientDir, buf, cfg.Codec, cfg.KeyringOptions...) require.NoError(t, err) keyringAlgos, _ := kb.SupportedAlgorithms() @@ -322,16 +365,16 @@ func New(t *testing.T, cfg Config) *Network { genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: balances.Sort()}) genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0)) - commission, err := sdk.NewDecFromStr("0.5") + commission, err := math.LegacyNewDecFromStr("0.5") require.NoError(t, err) createValMsg, err := stakingtypes.NewMsgCreateValidator( - sdk.ValAddress(addr), + sdk.ValAddress(addr).String(), valPubKeys[i], sdk.NewCoin(cfg.BondDenom, cfg.BondedTokens), stakingtypes.NewDescription(nodeDirName, "", "", "", ""), - stakingtypes.NewCommissionRates(commission, sdk.OneDec(), sdk.OneDec()), - sdk.OneInt(), + stakingtypes.NewCommissionRates(commission, math.LegacyOneDec(), math.LegacyOneDec()), + math.OneInt(), ) require.NoError(t, err) @@ -339,7 +382,7 @@ func New(t *testing.T, cfg Config) *Network { require.NoError(t, err) memo := fmt.Sprintf("%s@%s:%s", nodeIDs[i], p2pURL.Hostname(), p2pURL.Port()) - fee := sdk.NewCoins(sdk.NewCoin(fmt.Sprintf("%stoken", nodeDirName), sdk.NewInt(0))) + fee := sdk.NewCoins(sdk.NewCoin(fmt.Sprintf("%stoken", nodeDirName), math.NewInt(0))) txBuilder := cfg.TxConfig.NewTxBuilder() require.NoError(t, txBuilder.SetMsgs(createValMsg)) txBuilder.SetFeeAmount(fee) // Arbitrary fee @@ -353,7 +396,7 @@ func New(t *testing.T, cfg Config) *Network { WithKeybase(kb). WithTxConfig(cfg.TxConfig) - err = tx.Sign(txFactory, nodeDirName, txBuilder, true) + err = tx.Sign(context.Background(), txFactory, nodeDirName, txBuilder, true) require.NoError(t, err) txBz, err := cfg.TxConfig.TxJSONEncoder()(txBuilder.GetTx()) @@ -372,7 +415,11 @@ func New(t *testing.T, cfg Config) *Network { WithLegacyAmino(cfg.LegacyAmino). WithTxConfig(cfg.TxConfig). WithAccountRetriever(cfg.AccountRetriever). - WithNodeURI(tmCfg.RPC.ListenAddress) + WithNodeURI(tmCfg.RPC.ListenAddress). + WithBroadcastMode("block"). + WithSignModeStr("direct"). + WithFromAddress(addr). + WithSkipConfirmation(true) network.Validators[i] = &Validator{ AppConfig: appCfg, @@ -402,11 +449,35 @@ func New(t *testing.T, cfg Config) *Network { // Ensure we clean up incase any test was abruptly halted (e.g. SIGINT) as any // defer in a test would not be called. - server.TrapSignal(network.Cleanup) + trapSignal(network.Cleanup) return network } +// trapSignal traps SIGINT and SIGTERM and calls os.Exit once a signal is received. +func trapSignal(cleanupFunc func()) { + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) + + go func() { + sig := <-sigs + + if cleanupFunc != nil { + cleanupFunc() + } + exitCode := 128 + + switch sig { + case syscall.SIGINT: + exitCode += int(syscall.SIGINT) + case syscall.SIGTERM: + exitCode += int(syscall.SIGTERM) + } + + os.Exit(exitCode) + }() +} + // LatestHeight returns the latest height of the network or an error if the // query fails or no validators exist. func (n *Network) LatestHeight() (int64, error) { @@ -475,10 +546,26 @@ func (n *Network) WaitForNextBlock() error { return err } +// WaitForBlocks waits for the next amount of blocks to be committed, returning an error +// upon failure. +func (n *Network) WaitForBlocks(blocks int64) error { + lastBlock, err := n.LatestHeight() + if err != nil { + return err + } + + _, err = n.WaitForHeight(lastBlock + blocks) + if err != nil { + return err + } + + return err +} + // Cleanup removes the root testing (temporary) directory and stops both the // Tendermint and API services. It allows other callers to create and start // test networks. This method must be called when a test is finished, typically -// in a defer. +// in defer. func (n *Network) Cleanup() { defer func() { lock.Unlock() @@ -510,3 +597,55 @@ func (n *Network) Cleanup() { n.T.Log("finished cleaning up test network") } + +// DefaultConfig returns a default configuration suitable for nearly all +// testing requirements. +func DefaultConfig(factory TestFixtureFactory, opts ...ConfigOption) Config { + fixture := factory() + + cfg := &networkConfigOptions{} + for _, opt := range opts { + opt(cfg) + } + + cdc := fixture.EncodingConfig.Codec + genesisState := app.NewDefaultGenesisState(cdc) + + if cfg.interceptState != nil { + for k, v := range genesisState { + res := cfg.interceptState(cdc, k, v) + if res != nil { + genesisState[k] = res + } + } + } + + fixture.GenesisState = genesisState + + const coinDenom = "uakt" + return Config{ + Codec: fixture.EncodingConfig.Codec, + TxConfig: fixture.EncodingConfig.TxConfig, + LegacyAmino: fixture.EncodingConfig.Amino, + InterfaceRegistry: fixture.EncodingConfig.InterfaceRegistry, + AccountRetriever: authtypes.AccountRetriever{}, + AppConstructor: fixture.AppConstructor, + GenesisState: fixture.GenesisState, + TimeoutCommit: 2 * time.Second, + ChainID: "chain-" + tmrand.NewRand().Str(6), + NumValidators: 4, + BondDenom: coinDenom, + Denoms: []string{ + coinDenom, + "ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D84", + }, + MinGasPrices: fmt.Sprintf("0.000006%s", coinDenom), + AccountTokens: sdk.TokensFromConsensusPower(1000000000000, sdk.DefaultPowerReduction), + StakingTokens: sdk.TokensFromConsensusPower(100000, sdk.DefaultPowerReduction), + BondedTokens: sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction), + PruningStrategy: pruningtypes.PruningOptionNothing, + CleanupDir: true, + SigningAlgo: string(hd.Secp256k1Type), + KeyringOptions: []keyring.Option{}, + } +} diff --git a/testutil/network/option.go b/testutil/network/option.go new file mode 100644 index 0000000000..f24f7e611f --- /dev/null +++ b/testutil/network/option.go @@ -0,0 +1,22 @@ +package network + +import ( + "encoding/json" + + "github.com/cosmos/cosmos-sdk/codec" +) + +type InterceptState func(codec.Codec, string, json.RawMessage) json.RawMessage + +type networkConfigOptions struct { + interceptState InterceptState +} + +type ConfigOption func(*networkConfigOptions) + +// WithInterceptState set custom name of the log object +func WithInterceptState(val InterceptState) ConfigOption { + return func(t *networkConfigOptions) { + t.interceptState = val + } +} diff --git a/testutil/network/util.go b/testutil/network/util.go index bdc6d72065..a8a0c57ce3 100644 --- a/testutil/network/util.go +++ b/testutil/network/util.go @@ -1,22 +1,28 @@ package network import ( + "context" "encoding/json" + "fmt" + "os" "path/filepath" - "time" - tmos "github.com/tendermint/tendermint/libs/os" - "github.com/tendermint/tendermint/node" - "github.com/tendermint/tendermint/p2p" - pvm "github.com/tendermint/tendermint/privval" - "github.com/tendermint/tendermint/proxy" - "github.com/tendermint/tendermint/rpc/client/local" - "github.com/tendermint/tendermint/types" - tmtime "github.com/tendermint/tendermint/types/time" + "golang.org/x/sync/errgroup" + "cosmossdk.io/log" + cmtcfg "github.com/cometbft/cometbft/config" + "github.com/cometbft/cometbft/node" + "github.com/cometbft/cometbft/p2p" + pvm "github.com/cometbft/cometbft/privval" + "github.com/cometbft/cometbft/proxy" + "github.com/cometbft/cometbft/rpc/client/local" + "github.com/cometbft/cometbft/types" + tmtime "github.com/cometbft/cometbft/types/time" + + "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server/api" servergrpc "github.com/cosmos/cosmos-sdk/server/grpc" - srvtypes "github.com/cosmos/cosmos-sdk/server/types" + servercmtlog "github.com/cosmos/cosmos-sdk/server/log" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/genutil" @@ -25,30 +31,48 @@ import ( func startInProcess(cfg Config, val *Validator) error { logger := val.Ctx.Logger - tmCfg := val.Ctx.Config - tmCfg.Instrumentation.Prometheus = false + cmtCfg := val.Ctx.Config + cmtCfg.Instrumentation.Prometheus = false if err := val.AppConfig.ValidateBasic(); err != nil { return err } - nodeKey, err := p2p.LoadOrGenNodeKey(tmCfg.NodeKeyFile()) + nodeKey, err := p2p.LoadOrGenNodeKey(cmtCfg.NodeKeyFile()) if err != nil { return err } app := cfg.AppConstructor(*val) + val.app = app + + appGenesisProvider := func() (node.ChecksummedGenesisDoc, error) { + appGenesis, err := genutiltypes.AppGenesisFromFile(cmtCfg.GenesisFile()) + if err != nil { + return node.ChecksummedGenesisDoc{}, err + } + + genDoc, err := appGenesis.ToGenesisDoc() + if err != nil { + return node.ChecksummedGenesisDoc{}, err + } + return node.ChecksummedGenesisDoc{ + GenesisDoc: genDoc, + Sha256Checksum: appGenesis.Sha256Checksum, + }, nil + } - genDocProvider := node.DefaultGenesisDocProviderFunc(tmCfg) - tmNode, err := node.NewNode( - tmCfg, - pvm.LoadOrGenFilePV(tmCfg.PrivValidatorKeyFile(), tmCfg.PrivValidatorStateFile()), + cmtApp := server.NewCometABCIWrapper(app) + tmNode, err := node.NewNode( //resleak:notresource + context.Background(), + cmtCfg, + pvm.LoadOrGenFilePV(cmtCfg.PrivValidatorKeyFile(), cmtCfg.PrivValidatorStateFile()), nodeKey, - proxy.NewLocalClientCreator(app), - genDocProvider, - node.DefaultDBProvider, - node.DefaultMetricsProvider(tmCfg.Instrumentation), - logger.With("module", val.Moniker), + proxy.NewLocalClientCreator(cmtApp), + appGenesisProvider, + cmtcfg.DefaultDBProvider, + node.DefaultMetricsProvider(cmtCfg.Instrumentation), + servercmtlog.CometLoggerWrapper{Logger: logger.With("module", val.Moniker)}, ) if err != nil { return err @@ -57,61 +81,51 @@ func startInProcess(cfg Config, val *Validator) error { if err := tmNode.Start(); err != nil { return err } - val.tmNode = tmNode if val.RPCAddress != "" { val.RPCClient = local.New(tmNode) } - // We'll need an RPC client if the validator exposes a gRPC or REST endpoint. + // We'll need a RPC client if the validator exposes a gRPC or REST endpoint. if val.APIAddress != "" || val.AppConfig.GRPC.Enable { - val.ClientCtx = val.ClientCtx. - WithClient(val.RPCClient) + val.ClientCtx = val.ClientCtx.WithClient(val.RPCClient) app.RegisterTxService(val.ClientCtx) app.RegisterTendermintService(val.ClientCtx) - - if a, ok := app.(srvtypes.ApplicationQueryService); ok { - a.RegisterNodeService(val.ClientCtx) - } + app.RegisterNodeService(val.ClientCtx, *val.AppConfig) } - if val.APIAddress != "" { - apiSrv := api.New(val.ClientCtx, logger.With("module", "api-server")) - app.RegisterAPIRoutes(apiSrv, val.AppConfig.API) - - errCh := make(chan error) + ctx := context.Background() + ctx, val.cancelFn = context.WithCancel(ctx) + val.errGroup, ctx = errgroup.WithContext(ctx) - go func() { - if err := apiSrv.Start(*val.AppConfig); err != nil { - errCh <- err - } - }() + grpcCfg := val.AppConfig.GRPC - select { - case err := <-errCh: + if grpcCfg.Enable { + grpcSrv, err := servergrpc.NewGRPCServer(val.ClientCtx, app, grpcCfg) + if err != nil { return err - case <-time.After(srvtypes.ServerStartTime): // assume server started successfully } - val.api = apiSrv + // Start the gRPC server in a goroutine. Note, the provided ctx will ensure + // that the server is gracefully shut down. + val.errGroup.Go(func() error { + return servergrpc.StartGRPCServer(ctx, logger.With(log.ModuleKey, "grpc-server"), grpcCfg, grpcSrv) + }) + + val.grpc = grpcSrv } - if val.AppConfig.GRPC.Enable { - grpcSrv, err := servergrpc.StartGRPCServer(val.ClientCtx, app, val.AppConfig.GRPC.Address) - if err != nil { - return err - } + if val.APIAddress != "" { + apiSrv := api.New(val.ClientCtx, logger.With(log.ModuleKey, "api-server"), val.grpc) + app.RegisterAPIRoutes(apiSrv, val.AppConfig.API) - val.grpc = grpcSrv + val.errGroup.Go(func() error { + return apiSrv.Start(ctx, *val.AppConfig) + }) - if val.AppConfig.GRPCWeb.Enable { - val.grpcWeb, err = servergrpc.StartGRPCWeb(grpcSrv, *val.AppConfig) - if err != nil { - return err - } - } + val.api = apiSrv } return nil @@ -121,24 +135,30 @@ func collectGenFiles(cfg Config, vals []*Validator, outputDir string) error { genTime := tmtime.Now() for i := 0; i < cfg.NumValidators; i++ { - tmCfg := vals[i].Ctx.Config + cmtCfg := vals[i].Ctx.Config nodeDir := filepath.Join(outputDir, vals[i].Moniker, "simd") gentxsDir := filepath.Join(outputDir, "gentxs") - tmCfg.Moniker = vals[i].Moniker - tmCfg.SetRoot(nodeDir) + cmtCfg.Moniker = vals[i].Moniker + cmtCfg.SetRoot(nodeDir) initCfg := genutiltypes.NewInitConfig(cfg.ChainID, gentxsDir, vals[i].NodeID, vals[i].PubKey) - genFile := tmCfg.GenesisFile() - genDoc, err := types.GenesisDocFromFile(genFile) + genFile := cmtCfg.GenesisFile() + appGenesis, err := genutiltypes.AppGenesisFromFile(genFile) if err != nil { return err } - appState, err := genutil.GenAppStateFromConfig(cfg.Codec, cfg.TxConfig, - tmCfg, initCfg, *genDoc, banktypes.GenesisBalancesIterator{}) + appState, err := genutil.GenAppStateFromConfig( + cfg.Codec, + cfg.TxConfig, + cmtCfg, + initCfg, appGenesis, + banktypes.GenesisBalancesIterator{}, + genutiltypes.DefaultMessageValidator, + cfg.TxConfig.SigningContext().ValidatorAddressCodec()) if err != nil { return err } @@ -194,16 +214,13 @@ func initGenFiles(cfg Config, genAccounts []authtypes.GenesisAccount, genBalance } func writeFile(name string, dir string, contents []byte) error { - writePath := filepath.Join(dir) //nolint:gocritic - file := filepath.Join(writePath, name) + file := filepath.Join(dir, name) - err := tmos.EnsureDir(writePath, 0o755) - if err != nil { - return err + if err := os.MkdirAll(dir, 0o755); err != nil { //nolint: gosec + return fmt.Errorf("could not create directory %q: %w", dir, err) } - err = tmos.WriteFile(file, contents, 0o644) - if err != nil { + if err := os.WriteFile(file, contents, 0o644); err != nil { //nolint: gosec return err } diff --git a/testutil/network_suite.go b/testutil/network_suite.go index 670af7bfe7..a4052329be 100644 --- a/testutil/network_suite.go +++ b/testutil/network_suite.go @@ -8,45 +8,46 @@ import ( "strings" "time" - "github.com/gogo/protobuf/jsonpb" - "github.com/spf13/pflag" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + sdkmath "cosmossdk.io/math" sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" cosmosauthtx "github.com/cosmos/cosmos-sdk/x/auth/tx" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/gogoproto/jsonpb" - "github.com/akash-network/node/testutil/network" + cflags "pkg.akt.dev/go/cli/flags" + aclient "pkg.akt.dev/go/node/client/discovery" + cltypes "pkg.akt.dev/go/node/client/types" + cclient "pkg.akt.dev/go/node/client/v1beta3" + sdktestutil "pkg.akt.dev/go/testutil" + + "pkg.akt.dev/node/testutil/network" ) type NetworkTestSuite struct { *suite.Suite - cfg network.Config - network *network.Network - testIdx int - - kr keyring.Keyring - container interface{} - + cfg network.Config + network *network.Network + testIdx int + kr keyring.Keyring testCtx context.Context cancelTestCtx context.CancelFunc + container interface{} } -func NewNetworkTestSuite(cfg *network.Config, container interface{}) NetworkTestSuite { - nts := NetworkTestSuite{ +func NewNetworkTestSuite(cfg *network.Config, container interface{}) *NetworkTestSuite { + nts := &NetworkTestSuite{ Suite: &suite.Suite{}, - container: container, testIdx: -1, + container: container, } if cfg == nil { - nts.cfg = DefaultConfig() + nts.cfg = network.DefaultConfig(NewTestNetworkFixture) nts.cfg.NumValidators = 1 } else { nts.cfg = *cfg @@ -75,7 +76,7 @@ func (nts *NetworkTestSuite) TearDownSuite() { } func (nts *NetworkTestSuite) SetupSuite() { - nts.kr = Keyring(nts.T()) + nts.kr = sdktestutil.NewTestKeyring(nts.cfg.Codec) nts.network = network.New(nts.T(), nts.cfg) _, err := nts.network.WaitForHeightWithTimeout(1, time.Second*30) @@ -84,66 +85,84 @@ func (nts *NetworkTestSuite) SetupSuite() { walletCount := nts.countTests() nts.T().Logf("setting up %d wallets for test", walletCount) var msgs []sdk.Msg - + // for i := 0; i != walletCount; i++ { name := fmt.Sprintf("wallet%d", i) kinfo, str, err := nts.kr.NewMnemonic(name, keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) require.NoError(nts.T(), err) require.NotEmpty(nts.T(), str) - toAddr := kinfo.GetAddress() + toAddr, err := kinfo.GetAddress() + require.NoError(nts.T(), err) - coins := sdk.NewCoins(sdk.NewCoin(nts.Config().BondDenom, sdk.NewInt(1000000))) + coins := sdk.NewCoins(sdk.NewCoin(nts.Config().BondDenom, sdkmath.NewInt(1000000))) msg := banktypes.NewMsgSend(nts.Validator().Address, toAddr, coins) msgs = append(msgs, msg) } - txf := tx.NewFactoryCLI(nts.Context(), &pflag.FlagSet{}) - txf = txf.WithSignMode(signing.SignMode_SIGN_MODE_DIRECT) - txf = txf.WithSimulateAndExecute(false) - - require.Equal(nts.T(), "node0", nts.Context().GetFromName()) - keyInfo, err := txf.Keybase().Key(nts.Context().GetFromName()) - require.NoError(nts.T(), err) - require.NotNil(nts.T(), keyInfo) - - num, seq, err := txf.AccountRetriever().GetAccountNumberSequence(nts.Context(), nts.Validator().Address) - require.NoError(nts.T(), err) - txf = txf.WithAccountNumber(num) - txf = txf.WithSequence(seq) - txf = txf.WithGas(uint64(150000 * nts.countTests())) // Just made this up - txf = txf.WithFees(fmt.Sprintf("%d%s", 100, nts.Config().BondDenom)) // Just made this up - - txb, err := tx.BuildUnsignedTx(txf, msgs...) - require.NoError(nts.T(), err) - - txb.SetFeeGranter(nts.Context().GetFeeGranterAddress()) + ctx := context.Background() + cctx := nts.ClientContext().WithFrom(nts.network.Validators[0].Address.String()) - require.NoError(nts.T(), tx.Sign(txf, nts.Context().GetFromName(), txb, true)) - txBytes, err := nts.Context().TxConfig.TxEncoder()(txb.GetTx()) + cl, err := aclient.DiscoverClient( + ctx, + cctx, + cltypes.WithGas(cltypes.GasSetting{Simulate: true}), + cltypes.WithGasAdjustment(1.5), + cltypes.WithGasPrices("0.0025uakt"), + ) require.NoError(nts.T(), err) - txr, err := nts.Context().BroadcastTxSync(txBytes) + _, err = cl.Tx().BroadcastMsgs(ctx, msgs, cclient.WithBroadcastMode("block")) require.NoError(nts.T(), err) - require.Equal(nts.T(), uint32(0), txr.Code) - lctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - - for lctx.Err() == nil { - // check the TX - txStatus, err := authtx.QueryTx(nts.Context(), txr.TxHash) - if err != nil { - if strings.Contains(err.Error(), ") not found") { - continue - } - } - require.NoError(nts.T(), err) - require.NotNil(nts.T(), txStatus) - require.Equalf(nts.T(), uint32(0), txStatus.Code, "tx status is %v", txStatus) - break - } - require.NoError(nts.T(), lctx.Err()) + // txf, err := tx.NewFactoryCLI(nts.ClientContext(), &pflag.FlagSet{}) + // require.NoError(nts.T(), err) + // + // txf = txf.WithSignMode(signing.SignMode_SIGN_MODE_DIRECT) + // txf = txf.WithSimulateAndExecute(false) + // + // require.Equal(nts.T(), "node0", nts.ClientContext().GetFromName()) + // keyInfo, err := txf.Keybase().Key(nts.ClientContext().GetFromName()) + // require.NoError(nts.T(), err) + // require.NotNil(nts.T(), keyInfo) + // + // num, seq, err := txf.AccountRetriever().GetAccountNumberSequence(nts.ClientContext(), nts.Validator().Address) + // require.NoError(nts.T(), err) + // txf = txf.WithAccountNumber(num) + // txf = txf.WithSequence(seq) + // // txf = txf.WithGas(uint64(150000 * nts.countTests())) // Just made this up + // txf = txf.WithFees(fmt.Sprintf("%d%s", 100, nts.Config().BondDenom)) // Just made this up + // + // txb, err := txf.BuildUnsignedTx(msgs...) + // require.NoError(nts.T(), err) + // + // txb.SetFeeGranter(nts.ClientContext().GetFeeGranterAddress()) + // + // require.NoError(nts.T(), tx.Sign(txf, nts.ClientContext().GetFromName(), txb, true)) + // txBytes, err := nts.ClientContext().TxConfig.TxEncoder()(txb.GetTx()) + // require.NoError(nts.T(), err) + // + // txr, err := nts.ClientContext().BroadcastTxSync(txBytes) + // require.NoError(nts.T(), err) + // require.Equal(nts.T(), uint32(0), txr.Code) + + // lctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + // defer cancel() + // + // for lctx.Err() == nil { + // // check the TX + // txStatus, err := cl.Query()..QueryTx(nts.Context(), txr.TxHash) + // if err != nil { + // if strings.Contains(err.Error(), ") not found") { + // continue + // } + // } + // require.NoError(nts.T(), err) + // require.NotNil(nts.T(), txStatus) + // require.Equalf(nts.T(), uint32(0), txStatus.Code, "tx status is %v", txStatus) + // break + // } + // require.NoError(nts.T(), lctx.Err()) } @@ -169,17 +188,30 @@ func (nts *NetworkTestSuite) WalletNameForTest() string { func (nts *NetworkTestSuite) WalletForTest() sdk.AccAddress { k, err := nts.kr.Key(nts.WalletNameForTest()) require.NoError(nts.T(), err) - return k.GetAddress() + addr, err := k.GetAddress() + require.NoError(nts.T(), err) + + return addr } -func (nts *NetworkTestSuite) ContextForTest() sdkclient.Context { - result := nts.Context() +func (nts *NetworkTestSuite) ClientContextForTest() sdkclient.Context { + cctx := nts.ClientContext() k, err := nts.kr.Key(nts.WalletNameForTest()) require.NoError(nts.T(), err) - return result.WithKeyring(nts.kr).WithFromAddress(k.GetAddress()).WithFromName(nts.WalletNameForTest()) + + addr, err := k.GetAddress() + require.NoError(nts.T(), err) + + cctx = cctx.WithKeyring(nts.kr). + WithFromAddress(addr). + WithFromName(nts.WalletNameForTest()). + WithBroadcastMode(cflags.BroadcastBlock). + WithSignModeStr("direct") + + return cctx } -func (nts *NetworkTestSuite) GoContextForTest() context.Context { +func (nts *NetworkTestSuite) ContextForTest() context.Context { return nts.testCtx } @@ -187,7 +219,7 @@ func (nts *NetworkTestSuite) Network() *network.Network { return nts.network } -func (nts *NetworkTestSuite) Context(idxT ...int) sdkclient.Context { +func (nts *NetworkTestSuite) ClientContext(idxT ...int) sdkclient.Context { validator := nts.Validator() idx := 0 if len(idxT) != 0 { @@ -220,16 +252,16 @@ func (nts *NetworkTestSuite) ValidateTx(resultData []byte) string { require.NoError(nts.T(), err, "failed trying to unmarshal JSON transaction result") for { - res, err := cosmosauthtx.QueryTx(nts.ContextForTest(), resp.TxHash) + res, err := cosmosauthtx.QueryTx(nts.ClientContextForTest(), resp.TxHash) if err != nil { - ctxDone := nts.GoContextForTest().Err() != nil + ctxDone := nts.ContextForTest().Err() != nil if ctxDone { require.NoErrorf(nts.T(), err, "failed querying for transaction %q", resp.TxHash) } else { nts.T().Logf("waiting before checking for TX %s", resp.TxHash) select { - case <-nts.GoContextForTest().Done(): - require.NoError(nts.T(), nts.GoContextForTest().Err()) + case <-nts.ContextForTest().Done(): + require.NoError(nts.T(), nts.ContextForTest().Err()) case <-time.After(500 * time.Millisecond): } diff --git a/testutil/provider.go b/testutil/provider.go deleted file mode 100644 index 49d41f4637..0000000000 --- a/testutil/provider.go +++ /dev/null @@ -1,21 +0,0 @@ -package testutil - -import ( - "testing" - - ptypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" -) - -func Provider(t testing.TB) ptypes.Provider { - t.Helper() - - return ptypes.Provider{ - Owner: AccAddress(t).String(), - HostURI: Hostname(t), - Attributes: Attributes(t), - Info: ptypes.ProviderInfo{ - EMail: "test@example.com", - Website: ProviderHostname(t), - }, - } -} diff --git a/testutil/rand.go b/testutil/rand.go deleted file mode 100644 index 00e2f36058..0000000000 --- a/testutil/rand.go +++ /dev/null @@ -1,12 +0,0 @@ -package testutil - -import ( - "math/rand" - "time" -) - -// non-constant random seed for math/rand functions - -func init() { - rand.Seed(time.Now().Unix()) // nolint: staticcheck -} diff --git a/testutil/sdk.go b/testutil/sdk.go deleted file mode 100644 index b530b7fdc1..0000000000 --- a/testutil/sdk.go +++ /dev/null @@ -1,43 +0,0 @@ -package testutil - -import ( - "testing" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func Coin(t testing.TB) sdk.Coin { - t.Helper() - return sdk.NewCoin("testcoin", sdk.NewInt(int64(RandRangeInt(1, 1000)))) // nolint: gosec -} - -func DecCoin(t testing.TB) sdk.DecCoin { - t.Helper() - return sdk.NewDecCoin("testcoin", sdk.NewInt(int64(RandRangeInt(1, 1000)))) // nolint: gosec -} - -// AkashCoinRandom provides simple interface to the Akash sdk.Coin type. -func AkashCoinRandom(t testing.TB) sdk.Coin { - t.Helper() - amt := sdk.NewInt(int64(RandRangeInt(1, 1000))) - return sdk.NewCoin(CoinDenom, amt) -} - -// AkashCoin provides simple interface to the Akash sdk.Coin type. -func AkashCoin(t testing.TB, amount int64) sdk.Coin { - t.Helper() - amt := sdk.NewInt(amount) - return sdk.NewCoin(CoinDenom, amt) -} - -func AkashDecCoin(t testing.TB, amount int64) sdk.DecCoin { - t.Helper() - amt := sdk.NewInt(amount) - return sdk.NewDecCoin(CoinDenom, amt) -} - -func AkashDecCoinRandom(t testing.TB) sdk.DecCoin { - t.Helper() - amt := sdk.NewInt(int64(RandRangeInt(1, 1000))) - return sdk.NewDecCoin(CoinDenom, amt) -} diff --git a/testutil/sims/address_helpers.go b/testutil/sims/address_helpers.go new file mode 100644 index 0000000000..b5a67bb332 --- /dev/null +++ b/testutil/sims/address_helpers.go @@ -0,0 +1,170 @@ +package sims + +import ( + "bytes" + "context" + "encoding/hex" + "fmt" + "strconv" + + errorsmod "cosmossdk.io/errors" + "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" +) + +type GenerateAccountStrategy func(int) []sdk.AccAddress + +// BondDenomProvider is a subset of the staking keeper's public interface that +// provides the staking bond denom. It is used in arguments in this package's +// functions so that a mock staking keeper can be passed instead of the real one. +type BondDenomProvider interface { + BondDenom(ctx context.Context) (string, error) +} + +// AddTestAddrsFromPubKeys adds the addresses into the SimApp providing only the public keys. +func AddTestAddrsFromPubKeys(bankKeeper bankkeeper.Keeper, stakingKeeper BondDenomProvider, ctx sdk.Context, pubKeys []cryptotypes.PubKey, accAmt math.Int) { + bondDenom, err := stakingKeeper.BondDenom(ctx) + if err != nil { + panic(err) + } + initCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, accAmt)) + + for _, pk := range pubKeys { + initAccountWithCoins(bankKeeper, ctx, sdk.AccAddress(pk.Address()), initCoins) + } +} + +// AddTestAddrs constructs and returns accNum amount of accounts with an +// initial balance of accAmt in random order +func AddTestAddrs(bankKeeper bankkeeper.Keeper, stakingKeeper BondDenomProvider, ctx sdk.Context, accNum int, accAmt math.Int) []sdk.AccAddress { + return addTestAddrs(bankKeeper, stakingKeeper, ctx, accNum, accAmt, CreateRandomAccounts) +} + +// AddTestAddrsIncremental constructs and returns accNum amount of accounts with an initial balance of accAmt in random order +func AddTestAddrsIncremental(bankKeeper bankkeeper.Keeper, stakingKeeper BondDenomProvider, ctx sdk.Context, accNum int, accAmt math.Int) []sdk.AccAddress { + return addTestAddrs(bankKeeper, stakingKeeper, ctx, accNum, accAmt, CreateIncrementalAccounts) +} + +func addTestAddrs(bankKeeper bankkeeper.Keeper, stakingKeeper BondDenomProvider, ctx sdk.Context, accNum int, accAmt math.Int, strategy GenerateAccountStrategy) []sdk.AccAddress { + testAddrs := strategy(accNum) + bondDenom, err := stakingKeeper.BondDenom(ctx) + if err != nil { + panic(err) + } + initCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, accAmt)) + + for _, addr := range testAddrs { + initAccountWithCoins(bankKeeper, ctx, addr, initCoins) + } + + return testAddrs +} + +func initAccountWithCoins(bankKeeper bankkeeper.Keeper, ctx sdk.Context, addr sdk.AccAddress, coins sdk.Coins) { + if err := bankKeeper.MintCoins(ctx, minttypes.ModuleName, coins); err != nil { + panic(err) + } + + if err := bankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, addr, coins); err != nil { + panic(err) + } +} + +// CreateIncrementalAccounts is a strategy used by addTestAddrs() in order to generated addresses in ascending order. +func CreateIncrementalAccounts(accNum int) []sdk.AccAddress { + var addresses []sdk.AccAddress + var buffer bytes.Buffer + + // start at 100 so we can make up to 999 test addresses with valid test addresses + for i := 100; i < (accNum + 100); i++ { + numString := strconv.Itoa(i) + buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") // base address string + + buffer.WriteString(numString) // adding on final two digits to make addresses unique + res, _ := sdk.AccAddressFromHexUnsafe(buffer.String()) + bech := res.String() + addr, _ := TestAddr(buffer.String(), bech) + + addresses = append(addresses, addr) + buffer.Reset() + } + + return addresses +} + +// CreateRandomAccounts is a strategy used by addTestAddrs() in order to generated addresses in random order. +func CreateRandomAccounts(accNum int) []sdk.AccAddress { + testAddrs := make([]sdk.AccAddress, accNum) + for i := range accNum { + pk := ed25519.GenPrivKey().PubKey() + testAddrs[i] = sdk.AccAddress(pk.Address()) + } + + return testAddrs +} + +func TestAddr(addr, bech string) (sdk.AccAddress, error) { + res, err := sdk.AccAddressFromHexUnsafe(addr) + if err != nil { + return nil, err + } + bechexpected := res.String() + if bech != bechexpected { + return nil, fmt.Errorf("bech encoding doesn't match reference") + } + + bechres, err := sdk.AccAddressFromBech32(bech) + if err != nil { + return nil, err + } + if !bytes.Equal(bechres, res) { + return nil, err + } + + return res, nil +} + +// ConvertAddrsToValAddrs converts the provided addresses to ValAddress. +func ConvertAddrsToValAddrs(addrs []sdk.AccAddress) []sdk.ValAddress { + valAddrs := make([]sdk.ValAddress, len(addrs)) + + for i, addr := range addrs { + valAddrs[i] = sdk.ValAddress(addr) + } + + return valAddrs +} + +// CreateTestPubKeys returns a total of numPubKeys public keys in ascending order. +func CreateTestPubKeys(numPubKeys int) []cryptotypes.PubKey { + var publicKeys []cryptotypes.PubKey + var buffer bytes.Buffer + + // start at 10 to avoid changing 1 to 01, 2 to 02, etc + for i := 100; i < (numPubKeys + 100); i++ { + numString := strconv.Itoa(i) + buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AF") // base pubkey string + buffer.WriteString(numString) // adding on final two digits to make pubkeys unique + publicKeys = append(publicKeys, NewPubKeyFromHex(buffer.String())) + buffer.Reset() + } + + return publicKeys +} + +// NewPubKeyFromHex returns a PubKey from a hex string. +func NewPubKeyFromHex(pk string) (res cryptotypes.PubKey) { + pkBytes, err := hex.DecodeString(pk) + if err != nil { + panic(err) + } + if len(pkBytes) != ed25519.PubKeySize { + panic(errorsmod.Wrap(sdkerrors.ErrInvalidPubKey, "invalid pubkey size")) + } + return &ed25519.PubKey{Key: pkBytes} +} diff --git a/testutil/sims/app_helpers.go b/testutil/sims/app_helpers.go new file mode 100644 index 0000000000..41dd460f3d --- /dev/null +++ b/testutil/sims/app_helpers.go @@ -0,0 +1,306 @@ +package sims + +import ( + "encoding/json" + "fmt" + "time" + + abci "github.com/cometbft/cometbft/abci/types" + cmtjson "github.com/cometbft/cometbft/libs/json" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + cmttypes "github.com/cometbft/cometbft/types" + + coreheader "cosmossdk.io/core/header" + "cosmossdk.io/depinject" + sdkmath "cosmossdk.io/math" + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/cosmos/cosmos-sdk/runtime" + servertypes "github.com/cosmos/cosmos-sdk/server/types" + "github.com/cosmos/cosmos-sdk/testutil/mock" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +const DefaultGenTxGas = 10000000 + +// DefaultConsensusParams defines the default CometBFT consensus params used in +// SimApp testing. +var DefaultConsensusParams = &cmtproto.ConsensusParams{ + Block: &cmtproto.BlockParams{ + MaxBytes: 200000, + MaxGas: 100_000_000, + }, + Evidence: &cmtproto.EvidenceParams{ + MaxAgeNumBlocks: 302400, + MaxAgeDuration: 504 * time.Hour, // 3 weeks is the max duration + MaxBytes: 10000, + }, + Validator: &cmtproto.ValidatorParams{ + PubKeyTypes: []string{ + cmttypes.ABCIPubKeyTypeEd25519, + }, + }, +} + +// CreateRandomValidatorSet creates a validator set with one random validator +func CreateRandomValidatorSet() (*cmttypes.ValidatorSet, error) { + privVal := mock.NewPV() + pubKey, err := privVal.GetPubKey() + if err != nil { + return nil, fmt.Errorf("failed to get pub key: %w", err) + } + + // create validator set with single validator + validator := cmttypes.NewValidator(pubKey, 1) + + return cmttypes.NewValidatorSet([]*cmttypes.Validator{validator}), nil +} + +type GenesisAccount struct { + authtypes.GenesisAccount + Coins sdk.Coins +} + +// StartupConfig defines the startup configuration new a test application. +// +// ValidatorSet defines a custom validator set to be validating the app. +// BaseAppOption defines the additional operations that must be run on baseapp before app start. +// AtGenesis defines if the app started should already have produced block or not. +type StartupConfig struct { + ValidatorSet func() (*cmttypes.ValidatorSet, error) + BaseAppOption runtime.BaseAppOption + AtGenesis bool + GenesisAccounts []GenesisAccount + DB dbm.DB +} + +func DefaultStartUpConfig() StartupConfig { + priv := secp256k1.GenPrivKey() + ba := authtypes.NewBaseAccount(priv.PubKey().Address().Bytes(), priv.PubKey(), 0, 0) + ga := GenesisAccount{ba, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(100000000000000)))} + return StartupConfig{ + ValidatorSet: CreateRandomValidatorSet, + AtGenesis: false, + GenesisAccounts: []GenesisAccount{ga}, + DB: dbm.NewMemDB(), + } +} + +// Setup initializes a new runtime.App and can inject values into extraOutputs. +// It uses SetupWithConfiguration under the hood. +func Setup(appConfig depinject.Config, extraOutputs ...any) (*runtime.App, error) { + return SetupWithConfiguration(appConfig, DefaultStartUpConfig(), extraOutputs...) +} + +// SetupAtGenesis initializes a new runtime.App at genesis and can inject values into extraOutputs. +// It uses SetupWithConfiguration under the hood. +func SetupAtGenesis(appConfig depinject.Config, extraOutputs ...any) (*runtime.App, error) { + cfg := DefaultStartUpConfig() + cfg.AtGenesis = true + return SetupWithConfiguration(appConfig, cfg, extraOutputs...) +} + +// NextBlock starts a new block. +func NextBlock(app *runtime.App, ctx sdk.Context, jumpTime time.Duration) (sdk.Context, error) { + _, err := app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: ctx.BlockHeight(), Time: ctx.BlockTime()}) + if err != nil { + return sdk.Context{}, err + } + _, err = app.Commit() + if err != nil { + return sdk.Context{}, err + } + + newBlockTime := ctx.BlockTime().Add(jumpTime) + + header := ctx.BlockHeader() + header.Time = newBlockTime + header.Height++ + + newCtx := app.BaseApp.NewUncachedContext(false, header).WithHeaderInfo(coreheader.Info{ + Height: header.Height, + Time: header.Time, + }) + + return newCtx, nil +} + +// SetupWithConfiguration initializes a new runtime.App. A Nop logger is set in runtime.App. +// appConfig defines the application configuration (f.e. app_config.go). +// extraOutputs defines the extra outputs to be assigned by the dependency injector (depinject). +func SetupWithConfiguration(appConfig depinject.Config, startupConfig StartupConfig, extraOutputs ...any) (*runtime.App, error) { + // create the app with depinject + var ( + app *runtime.App + appBuilder *runtime.AppBuilder + codec codec.Codec + ) + + if err := depinject.Inject(appConfig, append(extraOutputs, &appBuilder, &codec)...); err != nil { + return nil, fmt.Errorf("failed to inject dependencies: %w", err) + } + + if startupConfig.BaseAppOption != nil { + app = appBuilder.Build(startupConfig.DB, nil, startupConfig.BaseAppOption) + } else { + app = appBuilder.Build(startupConfig.DB, nil) + } + if err := app.Load(true); err != nil { + return nil, fmt.Errorf("failed to load app: %w", err) + } + + // create validator set + valSet, err := startupConfig.ValidatorSet() + if err != nil { + return nil, fmt.Errorf("failed to create validator set") + } + + balances := make([]banktypes.Balance, 0, len(startupConfig.GenesisAccounts)) + genAccounts := make([]authtypes.GenesisAccount, 0, len(startupConfig.GenesisAccounts)) + + for _, ga := range startupConfig.GenesisAccounts { + genAccounts = append(genAccounts, ga.GenesisAccount) + balances = append(balances, banktypes.Balance{Address: ga.GenesisAccount.GetAddress().String(), Coins: ga.Coins}) + } + + genesisState, err := GenesisStateWithValSet(codec, app.DefaultGenesis(), valSet, genAccounts, balances...) + if err != nil { + return nil, fmt.Errorf("failed to create genesis state: %w", err) + } + + // init chain must be called to stop deliverState from being nil + stateBytes, err := cmtjson.MarshalIndent(genesisState, "", " ") + if err != nil { + return nil, fmt.Errorf("failed to marshal default genesis state: %w", err) + } + + // init chain will set the validator set and initialize the genesis accounts + _, err = app.InitChain(&abci.RequestInitChain{ + Validators: []abci.ValidatorUpdate{}, + ConsensusParams: DefaultConsensusParams, + AppStateBytes: stateBytes, + }) + if err != nil { + return nil, fmt.Errorf("failed to init chain: %w", err) + } + + // commit genesis changes + if !startupConfig.AtGenesis { + _, err = app.FinalizeBlock(&abci.RequestFinalizeBlock{ + Height: app.LastBlockHeight() + 1, + NextValidatorsHash: valSet.Hash(), + }) + if err != nil { + return nil, fmt.Errorf("failed to finalize block: %w", err) + } + } + + return app, nil +} + +// GenesisStateWithValSet returns a new genesis state with the validator set +func GenesisStateWithValSet( + codec codec.Codec, + genesisState map[string]json.RawMessage, + valSet *cmttypes.ValidatorSet, + genAccs []authtypes.GenesisAccount, + balances ...banktypes.Balance, +) (map[string]json.RawMessage, error) { + // set genesis accounts + authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs) + genesisState[authtypes.ModuleName] = codec.MustMarshalJSON(authGenesis) + + validators := make([]stakingtypes.Validator, 0, len(valSet.Validators)) + delegations := make([]stakingtypes.Delegation, 0, len(valSet.Validators)) + + bondAmt := sdk.DefaultPowerReduction + + for _, val := range valSet.Validators { + pk, err := cryptocodec.FromCmtPubKeyInterface(val.PubKey) + if err != nil { + return nil, fmt.Errorf("failed to convert pubkey: %w", err) + } + + pkAny, err := codectypes.NewAnyWithValue(pk) + if err != nil { + return nil, fmt.Errorf("failed to create new any: %w", err) + } + + validator := stakingtypes.Validator{ + OperatorAddress: sdk.ValAddress(val.Address).String(), + ConsensusPubkey: pkAny, + Jailed: false, + Status: stakingtypes.Bonded, + Tokens: bondAmt, + DelegatorShares: sdkmath.LegacyOneDec(), + Description: stakingtypes.Description{}, + UnbondingHeight: int64(0), + UnbondingTime: time.Unix(0, 0).UTC(), + Commission: stakingtypes.NewCommission(sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec()), + MinSelfDelegation: sdkmath.ZeroInt(), + } + validators = append(validators, validator) + delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress().String(), sdk.ValAddress(val.Address).String(), sdkmath.LegacyOneDec())) + + } + + // set validators and delegations + stakingGenesis := stakingtypes.NewGenesisState(stakingtypes.DefaultParams(), validators, delegations) + genesisState[stakingtypes.ModuleName] = codec.MustMarshalJSON(stakingGenesis) + + totalSupply := sdk.NewCoins() + for _, b := range balances { + // add genesis acc tokens to total supply + totalSupply = totalSupply.Add(b.Coins...) + } + + for range delegations { + // add delegated tokens to total supply + totalSupply = totalSupply.Add(sdk.NewCoin(sdk.DefaultBondDenom, bondAmt)) + } + + // add bonded amount to bonded pool module account + balances = append(balances, banktypes.Balance{ + Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(), + Coins: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, bondAmt)}, + }) + + // update total supply + bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{}, []banktypes.SendEnabled{}) + genesisState[banktypes.ModuleName] = codec.MustMarshalJSON(bankGenesis) + + return genesisState, nil +} + +// EmptyAppOptions is a stub implementing AppOptions +type EmptyAppOptions struct{} + +// Get implements AppOptions +func (ao EmptyAppOptions) Get(_ string) any { + return nil +} + +// AppOptionsMap is a stub implementing AppOptions which can get data from a map +type AppOptionsMap map[string]any + +func (m AppOptionsMap) Get(key string) any { + v, ok := m[key] + if !ok { + return any(nil) + } + + return v +} + +func NewAppOptionsWithFlagHome(homePath string) servertypes.AppOptions { + return AppOptionsMap{ + flags.FlagHome: homePath, + } +} diff --git a/testutil/sims/expected_keepers.go b/testutil/sims/expected_keepers.go new file mode 100644 index 0000000000..5a6d9c9f0f --- /dev/null +++ b/testutil/sims/expected_keepers.go @@ -0,0 +1,19 @@ +package sims + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type BankKeeper interface { + SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + MintCoins(ctx context.Context, moduleName string, amt sdk.Coins) error +} + +// StakingKeeper is a subset of the staking keeper's public interface that +// provides the staking bond denom. It is used in arguments in this package's +// functions so that a mock staking keeper can be passed instead of the real one. +type StakingKeeper interface { + BondDenom(ctx context.Context) (string, error) +} diff --git a/testutil/sims/simulation_helpers.go b/testutil/sims/simulation_helpers.go new file mode 100644 index 0000000000..6876fde201 --- /dev/null +++ b/testutil/sims/simulation_helpers.go @@ -0,0 +1,246 @@ +package sims + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "sync" + + "cosmossdk.io/log" + storetypes "cosmossdk.io/store/types" + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/runtime" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/kv" + "github.com/cosmos/cosmos-sdk/types/module" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" +) + +// SetupSimulation creates the config, db (levelDB), temporary directory and logger for the simulation tests. +// If `skip` is false it skips the current test. `skip` should be set using the `FlagEnabledValue` flag. +// Returns error on an invalid db instantiation or temp dir creation. +func SetupSimulation(config simtypes.Config, dirPrefix, dbName string, verbose, skip bool) (dbm.DB, string, log.Logger, bool, error) { + if !skip { + return nil, "", nil, true, nil + } + + var logger log.Logger + if verbose { + logger = log.NewLogger(os.Stdout) + } else { + logger = log.NewNopLogger() + } + + dir, err := os.MkdirTemp("", dirPrefix) + if err != nil { + return nil, "", nil, false, err + } + + db, err := dbm.NewDB(dbName, dbm.BackendType(config.DBBackend), dir) + if err != nil { + return nil, "", nil, false, err + } + + return db, dir, logger, false, nil +} + +// SimulationOperations retrieves the simulation params from the provided file path +// and returns all the modules weighted operations +// Deprecated: use BuildSimulationOperations with TxConfig +func SimulationOperations(app runtime.AppI, cdc codec.JSONCodec, config simtypes.Config) []simtypes.WeightedOperation { + return BuildSimulationOperations(app, cdc, config, moduletestutil.MakeTestTxConfig()) +} + +// BuildSimulationOperations retrieves the simulation params from the provided file path +// and returns all the modules weighted operations +func BuildSimulationOperations(app runtime.AppI, cdc codec.JSONCodec, config simtypes.Config, txConfig client.TxConfig) []simtypes.WeightedOperation { + simState := module.SimulationState{ + AppParams: make(simtypes.AppParams), + Cdc: cdc, + TxConfig: txConfig, + BondDenom: sdk.DefaultBondDenom, + } + + if config.ParamsFile != "" { + bz, err := os.ReadFile(config.ParamsFile) + if err != nil { + panic(err) + } + + err = json.Unmarshal(bz, &simState.AppParams) + if err != nil { + panic(err) + } + } + + simState.LegacyProposalContents = app.SimulationManager().GetProposalContents(simState) //nolint:staticcheck // we're testing the old way here + simState.ProposalMsgs = app.SimulationManager().GetProposalMsgs(simState) + return app.SimulationManager().WeightedOperations(simState) +} + +// CheckExportSimulation exports the app state and simulation parameters to JSON +// if the export paths are defined. +func CheckExportSimulation(app runtime.AppI, config simtypes.Config, params simtypes.Params) error { + if config.ExportStatePath != "" { + fmt.Println("exporting app state...") + exported, err := app.ExportAppStateAndValidators(false, nil, nil) + if err != nil { + return err + } + + if err := os.WriteFile(config.ExportStatePath, []byte(exported.AppState), 0o600); err != nil { + return err + } + } + + if config.ExportParamsPath != "" { + fmt.Println("exporting simulation params...") + paramsBz, err := json.MarshalIndent(params, "", " ") + if err != nil { + return err + } + + if err := os.WriteFile(config.ExportParamsPath, paramsBz, 0o600); err != nil { + return err + } + } + return nil +} + +// PrintStats prints the corresponding statistics from the app DB. +func PrintStats(db dbm.DB) { + fmt.Println("\nLevelDB Stats") + fmt.Println(db.Stats()["leveldb.stats"]) + fmt.Println("LevelDB cached block size", db.Stats()["leveldb.cachedblock"]) +} + +// GetSimulationLog unmarshals the KVPair's Value to the corresponding type based on the +// each's module store key and the prefix bytes of the KVPair's key. +func GetSimulationLog(storeName string, sdr simtypes.StoreDecoderRegistry, kvAs, kvBs []kv.Pair) (log string) { + for i := range kvAs { + if len(kvAs[i].Value) == 0 && len(kvBs[i].Value) == 0 { + // skip if the value doesn't have any bytes + continue + } + + decoder, ok := sdr[storeName] + if ok { + log += decoder(kvAs[i], kvBs[i]) + } else { + log += fmt.Sprintf("store A %X => %X\nstore B %X => %X\n", kvAs[i].Key, kvAs[i].Value, kvBs[i].Key, kvBs[i].Value) + } + } + + return log +} + +// DiffKVStores compares two KVstores and returns all the key/value pairs +// that differ from one another. It also skips value comparison for a set of provided prefixes. +func DiffKVStores(a, b storetypes.KVStore, prefixesToSkip [][]byte) (diffA, diffB []kv.Pair) { + iterA := a.Iterator(nil, nil) + defer func() { + _ = iterA.Close() + }() + + iterB := b.Iterator(nil, nil) + defer func() { + _ = iterB.Close() + }() + + var wg sync.WaitGroup + + wg.Add(1) + kvAs := make([]kv.Pair, 0) + go func() { + defer wg.Done() + kvAs = getKVPairs(iterA, prefixesToSkip) + }() + + wg.Add(1) + kvBs := make([]kv.Pair, 0) + go func() { + defer wg.Done() + kvBs = getKVPairs(iterB, prefixesToSkip) + }() + + wg.Wait() + + if len(kvAs) != len(kvBs) { + fmt.Printf("KV stores are different: %d key/value pairs in store A and %d key/value pairs in store B\n", len(kvAs), len(kvBs)) + } + + return getDiffFromKVPair(kvAs, kvBs) +} + +// getDiffFromKVPair compares two KVstores and returns all the key/value pairs +func getDiffFromKVPair(kvAs, kvBs []kv.Pair) (diffA, diffB []kv.Pair) { + // we assume that kvBs is equal or larger than kvAs + // if not, we swap the two + if len(kvAs) > len(kvBs) { + kvAs, kvBs = kvBs, kvAs + // we need to swap the diffA and diffB as well + defer func() { + diffA, diffB = diffB, diffA + }() + } + + // in case kvAs is empty we can return early + // since there is nothing to compare + // if kvAs == kvBs, then diffA and diffB will be empty + if len(kvAs) == 0 { + return []kv.Pair{}, kvBs + } + + index := make(map[string][]byte, len(kvBs)) + for _, kv := range kvBs { + index[string(kv.Key)] = kv.Value + } + + for _, kvA := range kvAs { + if kvBValue, ok := index[string(kvA.Key)]; !ok { + diffA = append(diffA, kvA) + diffB = append(diffB, kv.Pair{Key: kvA.Key}) // the key is missing from kvB so we append a pair with an empty value + } else if !bytes.Equal(kvA.Value, kvBValue) { + diffA = append(diffA, kvA) + diffB = append(diffB, kv.Pair{Key: kvA.Key, Value: kvBValue}) + } else { + // values are equal, so we remove the key from the index + delete(index, string(kvA.Key)) + } + } + + // add the remaining keys from kvBs + for key, value := range index { + diffA = append(diffA, kv.Pair{Key: []byte(key)}) // the key is missing from kvA so we append a pair with an empty value + diffB = append(diffB, kv.Pair{Key: []byte(key), Value: value}) + } + + return diffA, diffB +} + +func getKVPairs(iter dbm.Iterator, prefixesToSkip [][]byte) (kvs []kv.Pair) { + for iter.Valid() { + key, value := iter.Key(), iter.Value() + + // do not add the KV pair if the key is prefixed to be skipped. + skip := false + for _, prefix := range prefixesToSkip { + if bytes.HasPrefix(key, prefix) { + skip = true + break + } + } + + if !skip { + kvs = append(kvs, kv.Pair{Key: key, Value: value}) + } + + iter.Next() + } + + return kvs +} diff --git a/testutil/sims/simulation_helpers_test.go b/testutil/sims/simulation_helpers_test.go new file mode 100644 index 0000000000..bf786e0748 --- /dev/null +++ b/testutil/sims/simulation_helpers_test.go @@ -0,0 +1,124 @@ +package sims + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + "gotest.tools/v3/assert" + + "cosmossdk.io/log" + "cosmossdk.io/store/metrics" + "cosmossdk.io/store/rootmulti" + storetypes "cosmossdk.io/store/types" + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/types/kv" + "github.com/cosmos/cosmos-sdk/types/simulation" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +func TestGetSimulationLog(t *testing.T) { + legacyAmino := codec.NewLegacyAmino() + decoders := make(simulation.StoreDecoderRegistry) + decoders[authtypes.StoreKey] = func(_, _ kv.Pair) string { return "10" } + + tests := []struct { + store string + kvPairs []kv.Pair + expectedLog string + }{ + { + "Empty", + []kv.Pair{{}}, + "", + }, + { + authtypes.StoreKey, + []kv.Pair{{Key: authtypes.GlobalAccountNumberKey, Value: legacyAmino.MustMarshal(uint64(10))}}, + "10", + }, + { + "OtherStore", + []kv.Pair{{Key: []byte("key"), Value: []byte("value")}}, + fmt.Sprintf("store A %X => %X\nstore B %X => %X\n", []byte("key"), []byte("value"), []byte("key"), []byte("value")), + }, + } + + for _, tt := range tests { + t.Run(tt.store, func(t *testing.T) { + require.Equal(t, tt.expectedLog, GetSimulationLog(tt.store, decoders, tt.kvPairs, tt.kvPairs), tt.store) + }) + } +} + +func TestDiffKVStores(t *testing.T) { + store1, store2 := initTestStores(t) + // Two equal stores + k1, v1 := []byte("k1"), []byte("v1") + store1.Set(k1, v1) + store2.Set(k1, v1) + + checkDiffResults(t, store1, store2, true, nil) + + // delete k1 from store2, which is now empty + store2.Delete(k1) + checkDiffResults(t, store1, store2, false, nil) + + // set k1 in store2, different value than what store1 holds for k1 + v2 := []byte("v2") + store2.Set(k1, v2) + checkDiffResults(t, store1, store2, false, nil) + + // add k2 to store2 + k2 := []byte("k2") + store2.Set(k2, v2) + checkDiffResults(t, store1, store2, false, nil) + + // add k3 to store1 + k3 := []byte("k3") + store1.Set(k3, v2) + checkDiffResults(t, store1, store2, false, nil) + + // Reset stores + store1.Delete(k1) + store1.Delete(k3) + store2.Delete(k1) + store2.Delete(k2) + + // Same keys, different value. Comparisons will be nil as prefixes are skipped. + var prefix []byte + prefix = append(prefix, []byte("prefix:")...) + prefix = append(prefix, k1...) + store1.Set(prefix, v1) + store2.Set(prefix, v2) + + checkDiffResults(t, store1, store2, true, [][]byte{prefix}) +} + +func checkDiffResults(t *testing.T, store1, store2 storetypes.KVStore, noDiff bool, skipPrefixes [][]byte) { + t.Helper() + + kvAs1, kvBs1 := DiffKVStores(store1, store2, skipPrefixes) + + if noDiff { + assert.Assert(t, len(kvAs1) == 0) + assert.Assert(t, len(kvBs1) == 0) + } else { + assert.Assert(t, len(kvAs1) > 0 || len(kvBs1) > 0) + } +} + +func initTestStores(t *testing.T) (storetypes.KVStore, storetypes.KVStore) { + t.Helper() + + db := dbm.NewMemDB() + ms := rootmulti.NewStore(db, log.NewNopLogger(), metrics.NewNoOpMetrics()) + + key1 := storetypes.NewKVStoreKey("store1") + key2 := storetypes.NewKVStoreKey("store2") + require.NotPanics(t, func() { ms.MountStoreWithDB(key1, storetypes.StoreTypeIAVL, db) }) + require.NotPanics(t, func() { ms.MountStoreWithDB(key2, storetypes.StoreTypeIAVL, db) }) + require.NotPanics(t, func() { _ = ms.LoadLatestVersion() }) + return ms.GetKVStore(key1), ms.GetKVStore(key2) +} diff --git a/testutil/sims/state_helpers.go b/testutil/sims/state_helpers.go new file mode 100644 index 0000000000..d99bc8ac36 --- /dev/null +++ b/testutil/sims/state_helpers.go @@ -0,0 +1,292 @@ +package sims + +import ( + "bufio" + "encoding/json" + "fmt" + "io" + "math/rand" + "os" + "path/filepath" + "time" + + "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/cosmos/gogoproto/proto" +) + +// Simulation parameter constants +const ( + StakePerAccount = "stake_per_account" + InitiallyBondedValidators = "initially_bonded_validators" +) + +// AppStateFn returns the initial application state using a genesis or the simulation parameters. +// It calls AppStateFnWithExtendedCb with nil rawStateCb. +func AppStateFn( + cdc codec.JSONCodec, + simManager *module.SimulationManager, + genesisState map[string]json.RawMessage, +) simtypes.AppStateFn { + return AppStateFnWithExtendedCb(cdc, simManager, genesisState, nil) +} + +// AppStateFnWithExtendedCb returns the initial application state using a genesis or the simulation parameters. +// It calls AppStateFnWithExtendedCbs with nil moduleStateCb. +func AppStateFnWithExtendedCb( + cdc codec.JSONCodec, + simManager *module.SimulationManager, + genesisState map[string]json.RawMessage, + rawStateCb func(rawState map[string]json.RawMessage), +) simtypes.AppStateFn { + return AppStateFnWithExtendedCbs(cdc, simManager, genesisState, nil, rawStateCb) +} + +// AppStateFnWithExtendedCbs returns the initial application state using a genesis or the simulation parameters. +// It panics if the user provides files for both of them. +// If a file is not given for the genesis or the sim params, it creates a randomized one. +// genesisState is the default genesis state of the whole app. +// moduleStateCb is the callback function to access moduleState. +// rawStateCb is the callback function to extend rawState. +func AppStateFnWithExtendedCbs( + cdc codec.JSONCodec, + simManager *module.SimulationManager, + genesisState map[string]json.RawMessage, + moduleStateCb func(moduleName string, genesisState any), + rawStateCb func(rawState map[string]json.RawMessage), +) simtypes.AppStateFn { + return func( + r *rand.Rand, + accs []simtypes.Account, + config simtypes.Config, + ) (appState json.RawMessage, simAccs []simtypes.Account, chainID string, genesisTimestamp time.Time) { + genesisTimestamp = time.Unix(1752298564, 0) + chainID = config.ChainID + + switch { + case config.ParamsFile != "" && config.GenesisFile != "": + panic("cannot provide both a genesis file and a params file") + + case config.GenesisFile != "": + // override the default chain-id from simapp to set it later to the config + genesisDoc, accounts, err := AppStateFromGenesisFileFn(r, cdc, config.GenesisFile) + if err != nil { + panic(err) + } + + if simcli.FlagGenesisTimeValue == 0 { + // use genesis timestamp if no custom timestamp is provided (i.e no random timestamp) + genesisTimestamp = genesisDoc.GenesisTime + } + + appState = genesisDoc.AppState + chainID = genesisDoc.ChainID + simAccs = accounts + + case config.ParamsFile != "": + appParams := make(simtypes.AppParams) + bz, err := os.ReadFile(config.ParamsFile) + if err != nil { + panic(err) + } + + err = json.Unmarshal(bz, &appParams) + if err != nil { + panic(err) + } + appState, simAccs = AppStateRandomizedFn(simManager, r, cdc, accs, genesisTimestamp, appParams, genesisState) + + default: + appParams := make(simtypes.AppParams) + appState, simAccs = AppStateRandomizedFn(simManager, r, cdc, accs, genesisTimestamp, appParams, genesisState) + } + + rawState := make(map[string]json.RawMessage) + err := json.Unmarshal(appState, &rawState) + if err != nil { + panic(err) + } + + stakingStateBz, ok := rawState[stakingtypes.ModuleName] + if !ok { + panic("staking genesis state is missing") + } + + stakingState := new(stakingtypes.GenesisState) + if err = cdc.UnmarshalJSON(stakingStateBz, stakingState); err != nil { + panic(err) + } + // compute not bonded balance + notBondedTokens := math.ZeroInt() + for _, val := range stakingState.Validators { + if val.Status != stakingtypes.Unbonded { + continue + } + notBondedTokens = notBondedTokens.Add(val.GetTokens()) + } + notBondedCoins := sdk.NewCoin(stakingState.Params.BondDenom, notBondedTokens) + // edit bank state to make it have the not bonded pool tokens + bankStateBz, ok := rawState[testutil.BankModuleName] + if !ok { + panic("bank genesis state is missing") + } + bankState := new(banktypes.GenesisState) + if err = cdc.UnmarshalJSON(bankStateBz, bankState); err != nil { + panic(err) + } + + stakingAddr := authtypes.NewModuleAddress(stakingtypes.NotBondedPoolName).String() + var found bool + for _, balance := range bankState.Balances { + if balance.Address == stakingAddr { + found = true + break + } + } + if !found { + bankState.Balances = append(bankState.Balances, banktypes.Balance{ + Address: stakingAddr, + Coins: sdk.NewCoins(notBondedCoins), + }) + } + + // change appState back + for name, state := range map[string]proto.Message{ + stakingtypes.ModuleName: stakingState, + testutil.BankModuleName: bankState, + } { + if moduleStateCb != nil { + moduleStateCb(name, state) + } + rawState[name] = cdc.MustMarshalJSON(state) + } + + // extend state from callback function + if rawStateCb != nil { + rawStateCb(rawState) + } + + // replace appstate + appState, err = json.Marshal(rawState) + if err != nil { + panic(err) + } + return appState, simAccs, chainID, genesisTimestamp + } +} + +// AppStateRandomizedFn creates calls each module's GenesisState generator function +// and creates the simulation params +func AppStateRandomizedFn( + simManager *module.SimulationManager, + r *rand.Rand, + cdc codec.JSONCodec, + accs []simtypes.Account, + genesisTimestamp time.Time, + appParams simtypes.AppParams, + genesisState map[string]json.RawMessage, +) (json.RawMessage, []simtypes.Account) { + numAccs := int64(len(accs)) + // generate a random amount of initial stake coins and a random initial + // number of bonded accounts + var ( + numInitiallyBonded int64 + initialStake math.Int + ) + appParams.GetOrGenerate( + StakePerAccount, &initialStake, r, + func(r *rand.Rand) { initialStake = sdk.DefaultPowerReduction.AddRaw(r.Int63n(1e12)) }, + ) + appParams.GetOrGenerate( + InitiallyBondedValidators, &numInitiallyBonded, r, + func(r *rand.Rand) { numInitiallyBonded = int64(r.Intn(299) + 1) }, + ) + + if numInitiallyBonded > numAccs { + numInitiallyBonded = numAccs + } + + simState := &module.SimulationState{ + AppParams: appParams, + Cdc: cdc, + Rand: r, + GenState: genesisState, + Accounts: accs, + InitialStake: initialStake, + NumBonded: numInitiallyBonded, + BondDenom: sdk.DefaultBondDenom, + GenTimestamp: genesisTimestamp, + } + + simManager.GenerateGenesisStates(simState) + + appState, err := json.Marshal(genesisState) + if err != nil { + panic(err) + } + + return appState, accs +} + +// AppStateFromGenesisFileFn util function to generate the genesis AppState +// from a genesis.json file. +func AppStateFromGenesisFileFn(r io.Reader, cdc codec.JSONCodec, genesisFile string) (genutiltypes.AppGenesis, []simtypes.Account, error) { + file, err := os.Open(filepath.Clean(genesisFile)) + if err != nil { + panic(err) + } + + genesis, err := genutiltypes.AppGenesisFromReader(bufio.NewReader(file)) + if err != nil { + return *genesis, nil, err + } + + if err := file.Close(); err != nil { + return *genesis, nil, err + } + + var appState map[string]json.RawMessage + if err = json.Unmarshal(genesis.AppState, &appState); err != nil { + return *genesis, nil, err + } + + var authGenesis authtypes.GenesisState + if appState[testutil.AuthModuleName] != nil { + cdc.MustUnmarshalJSON(appState[testutil.AuthModuleName], &authGenesis) + } + + newAccs := make([]simtypes.Account, len(authGenesis.Accounts)) + for i, acc := range authGenesis.Accounts { + // Pick a random private key, since we don't know the actual key + // This should be fine as it's only used for mock CometBFT validators + // and these keys are never actually used to sign by mock CometBFT. + privkeySeed := make([]byte, 15) + if _, err := r.Read(privkeySeed); err != nil { + panic(err) + } + + privKey := secp256k1.GenPrivKeyFromSecret(privkeySeed) + + a, ok := acc.GetCachedValue().(sdk.AccountI) + if !ok { + return *genesis, nil, fmt.Errorf("expected account") + } + + // create simulator accounts + simAcc := simtypes.Account{PrivKey: privKey, PubKey: privKey.PubKey(), Address: a.GetAddress(), ConsKey: ed25519.GenPrivKeyFromSecret(privkeySeed)} + newAccs[i] = simAcc + } + + return *genesis, newAccs, nil +} diff --git a/testutil/sims/tx_helpers.go b/testutil/sims/tx_helpers.go new file mode 100644 index 0000000000..be3566a4ee --- /dev/null +++ b/testutil/sims/tx_helpers.go @@ -0,0 +1,157 @@ +package sims + +import ( + "context" + "math/rand" + "testing" + "time" + + "github.com/stretchr/testify/require" + + types2 "github.com/cometbft/cometbft/abci/types" + "github.com/cometbft/cometbft/proto/tendermint/types" + + "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authsign "github.com/cosmos/cosmos-sdk/x/auth/signing" +) + +// GenSignedMockTx generates a signed mock transaction. +func GenSignedMockTx(r *rand.Rand, txConfig client.TxConfig, msgs []sdk.Msg, feeAmt sdk.Coins, gas uint64, chainID string, accNums, accSeqs []uint64, priv ...cryptotypes.PrivKey) (sdk.Tx, error) { + sigs := make([]signing.SignatureV2, len(priv)) + + // create a random length memo + memo := simulation.RandStringOfLength(r, simulation.RandIntBetween(r, 0, 100)) + + signMode, err := authsign.APISignModeToInternal(txConfig.SignModeHandler().DefaultMode()) + if err != nil { + return nil, err + } + + // 1st round: set SignatureV2 with empty signatures, to set correct + // signer infos. + for i, p := range priv { + sigs[i] = signing.SignatureV2{ + PubKey: p.PubKey(), + Data: &signing.SingleSignatureData{ + SignMode: signMode, + }, + Sequence: accSeqs[i], + } + } + + tx := txConfig.NewTxBuilder() + err = tx.SetMsgs(msgs...) + if err != nil { + return nil, err + } + err = tx.SetSignatures(sigs...) + if err != nil { + return nil, err + } + tx.SetMemo(memo) + tx.SetFeeAmount(feeAmt) + tx.SetGasLimit(gas) + + // 2nd round: once all signer infos are set, every signer can sign. + for i, p := range priv { + signerData := authsign.SignerData{ + Address: sdk.AccAddress(p.PubKey().Address()).String(), + ChainID: chainID, + AccountNumber: accNums[i], + Sequence: accSeqs[i], + PubKey: p.PubKey(), + } + + signBytes, err := authsign.GetSignBytesAdapter( + context.Background(), txConfig.SignModeHandler(), signMode, signerData, + tx.GetTx()) + if err != nil { + panic(err) + } + sig, err := p.Sign(signBytes) + if err != nil { + panic(err) + } + sigs[i].Data.(*signing.SingleSignatureData).Signature = sig + } + err = tx.SetSignatures(sigs...) + if err != nil { + panic(err) + } + + return tx.GetTx(), nil +} + +// SignCheckDeliver checks a generated signed transaction and simulates a +// block commitment with the given transaction. A test assertion is made using +// the parameter 'expPass' against the result. A corresponding result is +// returned. +func SignCheckDeliver( + t *testing.T, txCfg client.TxConfig, app *baseapp.BaseApp, header types.Header, msgs []sdk.Msg, + chainID string, accNums, accSeqs []uint64, expSimPass, expPass bool, priv ...cryptotypes.PrivKey, +) (sdk.GasInfo, *sdk.Result, error) { + t.Helper() + + tx, err := GenSignedMockTx( + rand.New(rand.NewSource(time.Now().UnixNano())), //nolint:gosec + txCfg, + msgs, + sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)}, + DefaultGenTxGas, + chainID, + accNums, + accSeqs, + priv..., + ) + require.NoError(t, err) + txBytes, err := txCfg.TxEncoder()(tx) + require.Nil(t, err) + + // Must simulate now as CheckTx doesn't run Msgs anymore + _, res, err := app.Simulate(txBytes) + + if expSimPass { + require.NoError(t, err) + require.NotNil(t, res) + } else { + require.Error(t, err) + require.Nil(t, res) + } + + bz, err := txCfg.TxEncoder()(tx) + require.NoError(t, err) + + resBlock, err := app.FinalizeBlock(&types2.RequestFinalizeBlock{ + Height: header.Height, + Txs: [][]byte{bz}, + }) + require.NoError(t, err) + + require.Equal(t, 1, len(resBlock.TxResults)) + txResult := resBlock.TxResults[0] + finalizeSuccess := txResult.Code == 0 + if expPass { + require.True(t, finalizeSuccess) + } else { + require.False(t, finalizeSuccess) + } + + _, err = app.Commit() + require.NoError(t, err) + + gInfo := sdk.GasInfo{GasWanted: uint64(txResult.GasWanted), GasUsed: uint64(txResult.GasUsed)} //nolint:gosec + txRes := sdk.Result{Data: txResult.Data, Log: txResult.Log, Events: txResult.Events} + if finalizeSuccess { + err = nil + } else { + err = errors.ABCIError(txResult.Codespace, txResult.Code, txResult.Log) + } + + return gInfo, &txRes, err +} diff --git a/testutil/state/suite.go b/testutil/state/suite.go index 7af5316d51..f068097faa 100644 --- a/testutil/state/suite.go +++ b/testutil/state/suite.go @@ -1,37 +1,47 @@ package state import ( + "fmt" + "os" "testing" + "time" - sdk "github.com/cosmos/cosmos-sdk/types" - distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" "github.com/stretchr/testify/mock" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - - atypes "github.com/akash-network/akash-api/go/node/audit/v1beta3" - ttypes "github.com/akash-network/akash-api/go/node/take/v1beta3" - - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - etypes "github.com/akash-network/akash-api/go/node/escrow/v1beta3" - mtypes "github.com/akash-network/akash-api/go/node/market/v1beta4" - ptypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" - - "github.com/akash-network/node/app" - emocks "github.com/akash-network/node/testutil/cosmos/mocks" - akeeper "github.com/akash-network/node/x/audit/keeper" - dkeeper "github.com/akash-network/node/x/deployment/keeper" - ekeeper "github.com/akash-network/node/x/escrow/keeper" - mhooks "github.com/akash-network/node/x/market/hooks" - mkeeper "github.com/akash-network/node/x/market/keeper" - pkeeper "github.com/akash-network/node/x/provider/keeper" - tkeeper "github.com/akash-network/node/x/take/keeper" + + "cosmossdk.io/collections" + "cosmossdk.io/store" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/runtime" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/distribution/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + + atypes "pkg.akt.dev/go/node/audit/v1" + dtypes "pkg.akt.dev/go/node/deployment/v1" + emodule "pkg.akt.dev/go/node/escrow/module" + mtypes "pkg.akt.dev/go/node/market/v1" + ptypes "pkg.akt.dev/go/node/provider/v1beta4" + ttypes "pkg.akt.dev/go/node/take/v1" + + "pkg.akt.dev/node/app" + emocks "pkg.akt.dev/node/testutil/cosmos/mocks" + akeeper "pkg.akt.dev/node/x/audit/keeper" + dkeeper "pkg.akt.dev/node/x/deployment/keeper" + ekeeper "pkg.akt.dev/node/x/escrow/keeper" + mhooks "pkg.akt.dev/node/x/market/hooks" + mkeeper "pkg.akt.dev/node/x/market/keeper" + pkeeper "pkg.akt.dev/node/x/provider/keeper" + tkeeper "pkg.akt.dev/node/x/take/keeper" ) // TestSuite encapsulates a functional Akash nodes data stores for // ephemeral testing. type TestSuite struct { t testing.TB - ms sdk.CommitMultiStore + ms store.CommitMultiStore ctx sdk.Context app *app.AkashApp keepers Keepers @@ -45,7 +55,6 @@ type Keepers struct { Deployment dkeeper.IKeeper Provider pkeeper.IKeeper Bank *emocks.BankKeeper - Distr *emocks.DistrKeeper Authz *emocks.AuthzKeeper } @@ -56,6 +65,15 @@ func SetupTestSuite(t testing.TB) *TestSuite { } func SetupTestSuiteWithKeepers(t testing.TB, keepers Keepers) *TestSuite { + dir, err := os.MkdirTemp("", "akashd-test-home") + if err != nil { + panic(fmt.Sprintf("failed creating temporary directory: %v", err)) + } + + t.Cleanup(func() { + _ = os.RemoveAll(dir) + }) + if keepers.Bank == nil { bkeeper := &emocks.BankKeeper{} bkeeper. @@ -67,18 +85,11 @@ func SetupTestSuiteWithKeepers(t testing.TB, keepers Keepers) *TestSuite { bkeeper. On("SendCoinsFromModuleToModule", mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(nil) - keepers.Bank = bkeeper - } - - if keepers.Distr == nil { - dkeeper := &emocks.DistrKeeper{} - dkeeper. - On("GetFeePool", mock.Anything). - Return(distrtypes.FeePool{}) - dkeeper.On("SetFeePool", mock.Anything, mock.Anything). - Return() + bkeeper. + On("SpendableCoin", mock.Anything, mock.Anything, mock.Anything). + Return(sdk.NewInt64Coin("uakt", 10000000)) - keepers.Distr = dkeeper + keepers.Bank = bkeeper } if keepers.Authz == nil { @@ -87,27 +98,62 @@ func SetupTestSuiteWithKeepers(t testing.TB, keepers Keepers) *TestSuite { keepers.Authz = keeper } - app := app.Setup(false) + app := app.Setup( + app.WithCheckTx(false), + app.WithHome(dir), + app.WithGenesis(app.GenesisStateWithValSet), + ) + + ctx := app.NewContext(false) + + cdc := app.AppCodec() + + vals, err := app.Keepers.Cosmos.Staking.GetAllValidators(ctx) + if err != nil { + t.Fatal(err.Error()) + } + + // Manually set validator signing info, otherwise we panic + for _, val := range vals { + consAddr, _ := val.GetConsAddr() + signingInfo := slashingtypes.NewValidatorSigningInfo( + consAddr, + 0, + ctx.BlockHeight(), + time.Unix(0, 0), + false, + 0, + ) + err = app.Keepers.Cosmos.Slashing.SetValidatorSigningInfo(ctx, consAddr, signingInfo) + if err != nil { + t.Fatal(err.Error()) + } + } if keepers.Audit == nil { - keepers.Audit = akeeper.NewKeeper(atypes.ModuleCdc, app.GetKey(atypes.ModuleName)) + keepers.Audit = akeeper.NewKeeper(cdc, app.GetKey(atypes.StoreKey)) } if keepers.Take == nil { - keepers.Take = tkeeper.NewKeeper(ttypes.ModuleCdc, app.GetKey(ttypes.ModuleName), app.GetSubspace(ttypes.ModuleName)) + keepers.Take = tkeeper.NewKeeper(cdc, app.GetKey(ttypes.StoreKey), authtypes.NewModuleAddress(govtypes.ModuleName).String()) } if keepers.Escrow == nil { - keepers.Escrow = ekeeper.NewKeeper(etypes.ModuleCdc, app.GetKey(etypes.ModuleName), keepers.Bank, keepers.Take, keepers.Distr, keepers.Authz) + storeService := runtime.NewKVStoreService(app.GetKey(types.StoreKey)) + sb := collections.NewSchemaBuilder(storeService) + + feepool := collections.NewItem(sb, types.FeePoolKey, "fee_pool", codec.CollValue[types.FeePool](cdc)) + keepers.Escrow = ekeeper.NewKeeper(cdc, app.GetKey(emodule.StoreKey), keepers.Bank, keepers.Take, keepers.Authz, feepool) } if keepers.Market == nil { - keepers.Market = mkeeper.NewKeeper(mtypes.ModuleCdc, app.GetKey(mtypes.ModuleName), app.GetSubspace(mtypes.ModuleName), keepers.Escrow) + keepers.Market = mkeeper.NewKeeper(cdc, app.GetKey(mtypes.StoreKey), keepers.Escrow, authtypes.NewModuleAddress(govtypes.ModuleName).String()) + } if keepers.Deployment == nil { - keepers.Deployment = dkeeper.NewKeeper(dtypes.ModuleCdc, app.GetKey(dtypes.ModuleName), app.GetSubspace(dtypes.ModuleName), keepers.Escrow) + keepers.Deployment = dkeeper.NewKeeper(cdc, app.GetKey(dtypes.StoreKey), keepers.Escrow, authtypes.NewModuleAddress(govtypes.ModuleName).String()) } if keepers.Provider == nil { - keepers.Provider = pkeeper.NewKeeper(ptypes.ModuleCdc, app.GetKey(ptypes.ModuleName)) + keepers.Provider = pkeeper.NewKeeper(cdc, app.GetKey(ptypes.StoreKey)) } hook := mhooks.New(keepers.Deployment, keepers.Market) @@ -118,7 +164,7 @@ func SetupTestSuiteWithKeepers(t testing.TB, keepers Keepers) *TestSuite { return &TestSuite{ t: t, app: app, - ctx: app.BaseApp.NewContext(false, tmproto.Header{}), + ctx: ctx, keepers: keepers, } } @@ -133,7 +179,7 @@ func (ts *TestSuite) SetBlockHeight(height int64) { } // Store provides access to the underlying KVStore -func (ts *TestSuite) Store() sdk.CommitMultiStore { +func (ts *TestSuite) Store() store.CommitMultiStore { return ts.ms } diff --git a/testutil/types.go b/testutil/types.go index 5199dec5cf..440853fd95 100644 --- a/testutil/types.go +++ b/testutil/types.go @@ -1,167 +1,74 @@ package testutil import ( - "bytes" - "encoding/json" "fmt" - "math/rand" - "strings" - "testing" - "time" + "os" - "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" + "cosmossdk.io/log" + pruningtypes "cosmossdk.io/store/pruning/types" + dbm "github.com/cosmos/cosmos-db" + bam "github.com/cosmos/cosmos-sdk/baseapp" servertypes "github.com/cosmos/cosmos-sdk/server/types" - "github.com/cosmos/cosmos-sdk/simapp" - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" - tmrand "github.com/tendermint/tendermint/libs/rand" - dbm "github.com/tendermint/tm-db" + cflags "pkg.akt.dev/go/cli/flags" + "pkg.akt.dev/go/sdkutil" - types "github.com/akash-network/akash-api/go/node/types/v1beta3" - - "github.com/akash-network/node/app" - "github.com/akash-network/node/testutil/network" + "pkg.akt.dev/node/app" + "pkg.akt.dev/node/testutil/network" ) -type InterceptState func(codec.Codec, string, json.RawMessage) json.RawMessage - -type networkConfigOptions struct { - interceptState InterceptState -} - -type ConfigOption func(*networkConfigOptions) - -// WithInterceptState set custom name of the log object -func WithInterceptState(val InterceptState) ConfigOption { - return func(t *networkConfigOptions) { - t.interceptState = val - } -} - -func RandRangeInt(min, max int) int { - return rand.Intn(max-min) + min // nolint: gosec -} - -func RandRangeUint(min, max uint) uint { - val := rand.Uint64() // nolint: gosec - val %= uint64(max - min) - val += uint64(min) - return uint(val) -} - -func RandRangeUint64(min, max uint64) uint64 { - val := rand.Uint64() // nolint: gosec - val %= max - min - val += min - return val -} - -func ResourceUnits(_ testing.TB) types.Resources { - return types.Resources{ - ID: 1, - CPU: &types.CPU{ - Units: types.NewResourceValue(uint64(RandCPUUnits())), - }, - Memory: &types.Memory{ - Quantity: types.NewResourceValue(RandMemoryQuantity()), - }, - GPU: &types.GPU{ - Units: types.NewResourceValue(uint64(RandGPUUnits())), - }, - Storage: types.Volumes{ - types.Storage{ - Quantity: types.NewResourceValue(RandStorageQuantity()), - }, - }, +// NewTestNetworkFixture returns a new simapp AppConstructor for network simulation tests +func NewTestNetworkFixture(opts ...network.TestnetFixtureOption) network.TestFixture { + dir, err := os.MkdirTemp("", "simapp") + if err != nil { + panic(fmt.Sprintf("failed creating temporary directory: %v", err)) } -} + defer func() { + _ = os.RemoveAll(dir) + }() -func NewApp(val network.Validator) servertypes.Application { - return app.NewApp( - val.Ctx.Logger, dbm.NewMemDB(), nil, true, 0, make(map[int64]bool), val.Ctx.Config.RootDir, - simapp.EmptyAppOptions{}, - baseapp.SetPruning(storetypes.NewPruningOptionsFromString(val.AppConfig.Pruning)), - baseapp.SetMinGasPrices(val.AppConfig.MinGasPrices), - ) -} + cfgOpts := &network.TestnetFixtureOptions{} -// DefaultConfig returns a default configuration suitable for nearly all -// testing requirements. -func DefaultConfig(opts ...ConfigOption) network.Config { - cfg := &networkConfigOptions{} for _, opt := range opts { - opt(cfg) + opt(cfgOpts) } - encCfg := app.MakeEncodingConfig() - origGenesisState := app.ModuleBasics().DefaultGenesis(encCfg.Marshaler) - - genesisState := make(map[string]json.RawMessage) - for k, v := range origGenesisState { - data, err := v.MarshalJSON() - if err != nil { - panic(err) - } - - buf := &bytes.Buffer{} - _, err = buf.Write(data) - if err != nil { - panic(err) - } - - stringData := buf.String() - stringDataAfter := strings.ReplaceAll(stringData, `"stake"`, `"uakt"`) - if stringData == stringDataAfter { - genesisState[k] = v - continue - } - - var val map[string]interface{} - err = json.Unmarshal(buf.Bytes(), &val) - if err != nil { - panic(err) - } - - replacementV := json.RawMessage(stringDataAfter) - genesisState[k] = replacementV + if cfgOpts.EncCfg.InterfaceRegistry == nil { + cfgOpts.EncCfg = sdkutil.MakeEncodingConfig() + app.ModuleBasics().RegisterInterfaces(cfgOpts.EncCfg.InterfaceRegistry) } - if cfg.interceptState != nil { - for k, v := range genesisState { - res := cfg.interceptState(encCfg.Marshaler, k, v) - if res != nil { - genesisState[k] = res - } - } + tapp := app.NewApp( + log.NewNopLogger(), + dbm.NewMemDB(), + nil, + true, + 0, + make(map[int64]bool), + cfgOpts.EncCfg, + simtestutil.NewAppOptionsWithFlagHome(dir), + ) + + appCtr := func(val network.ValidatorI) servertypes.Application { + return app.NewApp( + val.GetCtx().Logger, + dbm.NewMemDB(), + nil, + true, + 0, + make(map[int64]bool), + cfgOpts.EncCfg, + simtestutil.NewAppOptionsWithFlagHome(val.GetCtx().Config.RootDir), + bam.SetPruning(pruningtypes.NewPruningOptionsFromString(val.GetAppConfig().Pruning)), + bam.SetMinGasPrices(val.GetAppConfig().MinGasPrices), + bam.SetChainID(val.GetCtx().Viper.GetString(cflags.FlagChainID)), + ) } - return network.Config{ - Codec: encCfg.Marshaler, - TxConfig: encCfg.TxConfig, - LegacyAmino: encCfg.Amino, - InterfaceRegistry: encCfg.InterfaceRegistry, - AccountRetriever: authtypes.AccountRetriever{}, - AppConstructor: NewApp, - GenesisState: genesisState, - TimeoutCommit: 2 * time.Second, - ChainID: "chain-" + tmrand.NewRand().Str(6), - NumValidators: 4, - BondDenom: CoinDenom, - Denoms: []string{ - "ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D84", - }, - MinGasPrices: fmt.Sprintf("0.000006%s", CoinDenom), - AccountTokens: sdk.TokensFromConsensusPower(1000000000000, sdk.DefaultPowerReduction), - StakingTokens: sdk.TokensFromConsensusPower(100000, sdk.DefaultPowerReduction), - BondedTokens: sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction), - PruningStrategy: storetypes.PruningOptionNothing, - CleanupDir: true, - SigningAlgo: string(hd.Secp256k1Type), - KeyringOptions: []keyring.Option{}, + return network.TestFixture{ + AppConstructor: appCtr, + GenesisState: app.NewDefaultGenesisState(tapp.AppCodec()), + EncodingConfig: cfgOpts.EncCfg, } } diff --git a/tools/upgrade-info/main.go b/tools/upgrade-info/main.go index 18084045c7..2af65403b8 100644 --- a/tools/upgrade-info/main.go +++ b/tools/upgrade-info/main.go @@ -8,7 +8,7 @@ import ( "github.com/spf13/cobra" - utilcli "github.com/akash-network/node/util/cli" + utilcli "pkg.akt.dev/node/util/cli" ) func main() { diff --git a/types/config.go b/types/config.go deleted file mode 100644 index bbfdbbf06b..0000000000 --- a/types/config.go +++ /dev/null @@ -1,5 +0,0 @@ -package types - -const ( - ProtoAPIVersion = "v1beta3" -) diff --git a/upgrades/CHANGELOG.md b/upgrades/CHANGELOG.md index 05aa52edd1..c7dbc6bfbd 100644 --- a/upgrades/CHANGELOG.md +++ b/upgrades/CHANGELOG.md @@ -38,19 +38,38 @@ Goal of the upgrade here - `store` - Migrations (omit if all times below are not present in the upgrade) - - deployment 2 -> 3 - - market 2 -> 3 + - deployment `2 -> 3` + - market `2 -> 3` Add new upgrades after this line based on the template above ----- +##### v1.0.0 + +1. Migrate to cosmos-sdk v0.47.x + +- Stores + - deleted + - `astaking`: cosmos-sdk staking module is now offering `MinCommissionRate`. + - `agov`: cosmos-sdk staking module is now offering `MinDepositRatio`. + +- Migrations + - audit `2 -> 3` + - cert `2 -> 3` + - deployment `3 -> 4` + - escrow `2 -> 3` + - market `5 -> 6` + - provider `2 -> 3` + - take `2 -> 3` + - astaking `1 -> 2` + ##### v0.38.0 Upgrade x/stores keys to improve read performance of certain modules as described in [AEP-61](https://github.com/akash-network/AEP/blob/main/AEPS/AEP-61.md) - Migrations - cert `2 -> 3` - - deployment `3 -> 4` + - deployment `3 -> 4` - market `5 -> 6` - authz `1 -> 2` @@ -124,7 +143,7 @@ Upgrade x/stores keys to improve read performance of certain modules as describe - Migrations - deployment `2 -> 3` - - market `2 -> 3` + - market `2 -> 3` ##### v0.20.0 diff --git a/upgrades/software/v0.15.0/audit.go b/upgrades/software/v0.15.0/audit.go deleted file mode 100644 index 27b1cf17b8..0000000000 --- a/upgrades/software/v0.15.0/audit.go +++ /dev/null @@ -1,34 +0,0 @@ -// Package v0_15_0 -// nolint revive -package v0_15_0 - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - sdkmodule "github.com/cosmos/cosmos-sdk/types/module" - v043 "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v043" - - av1beta2 "github.com/akash-network/akash-api/go/node/audit/v1beta2" - - utypes "github.com/akash-network/node/upgrades/types" -) - -type auditMigrations struct { - utypes.Migrator -} - -func newAuditMigration(m utypes.Migrator) utypes.Migration { - return auditMigrations{Migrator: m} -} - -func (m auditMigrations) GetHandler() sdkmodule.MigrationHandler { - return m.handler -} - -// handler migrates provider from version 1 to 2. -func (m auditMigrations) handler(ctx sdk.Context) error { - store := ctx.KVStore(m.StoreKey()) - - v043.MigratePrefixAddressAddress(store, av1beta2.PrefixProviderID()) - - return nil -} diff --git a/upgrades/software/v0.15.0/cert.go b/upgrades/software/v0.15.0/cert.go deleted file mode 100644 index dd3997458b..0000000000 --- a/upgrades/software/v0.15.0/cert.go +++ /dev/null @@ -1,34 +0,0 @@ -// Package v0_15_0 -// nolint revive -package v0_15_0 - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - sdkmodule "github.com/cosmos/cosmos-sdk/types/module" - v043 "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v043" - - cv1beta2 "github.com/akash-network/akash-api/go/node/cert/v1beta2" - - utypes "github.com/akash-network/node/upgrades/types" -) - -type certMigrations struct { - utypes.Migrator -} - -func newCertMigration(m utypes.Migrator) utypes.Migration { - return certMigrations{Migrator: m} -} - -func (m certMigrations) GetHandler() sdkmodule.MigrationHandler { - return m.handler -} - -// handler migrates provider from version 1 to 2. -func (m certMigrations) handler(ctx sdk.Context) error { - store := ctx.KVStore(m.StoreKey()) - - v043.MigratePrefixAddressAddress(store, cv1beta2.PrefixCertificateID()) - - return nil -} diff --git a/upgrades/software/v0.15.0/deployment.go b/upgrades/software/v0.15.0/deployment.go deleted file mode 100644 index 6d14e49acb..0000000000 --- a/upgrades/software/v0.15.0/deployment.go +++ /dev/null @@ -1,48 +0,0 @@ -// Package v0_15_0 -// nolint revive -package v0_15_0 - -import ( - dv1beta1 "github.com/akash-network/akash-api/go/node/deployment/v1beta1" - dmigrate "github.com/akash-network/akash-api/go/node/deployment/v1beta2/migrate" - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkmodule "github.com/cosmos/cosmos-sdk/types/module" - - utypes "github.com/akash-network/node/upgrades/types" -) - -type deploymentMigrations struct { - utypes.Migrator -} - -func newDeploymentMigration(m utypes.Migrator) utypes.Migration { - return deploymentMigrations{Migrator: m} -} - -func (m deploymentMigrations) GetHandler() sdkmodule.MigrationHandler { - return m.handler -} - -// handler migrates deployment from version 1 to 2. -func (m deploymentMigrations) handler(ctx sdk.Context) error { - store := ctx.KVStore(m.StoreKey()) - - migratePrefixBech32AddrBytes(store, dv1beta1.DeploymentPrefix()) - migratePrefixBech32AddrBytes(store, dv1beta1.GroupPrefix()) - - err := utypes.MigrateValue(store, m.Codec(), dv1beta1.GroupPrefix(), migrateDeploymentGroup) - if err != nil { - return err - } - - return nil -} - -func migrateDeploymentGroup(fromBz []byte, cdc codec.BinaryCodec) codec.ProtoMarshaler { - var from dv1beta1.Group - cdc.MustUnmarshal(fromBz, &from) - - to := dmigrate.GroupFromV1Beta1(from) - return &to -} diff --git a/upgrades/software/v0.15.0/escrow.go b/upgrades/software/v0.15.0/escrow.go deleted file mode 100644 index 8ec2a73ce6..0000000000 --- a/upgrades/software/v0.15.0/escrow.go +++ /dev/null @@ -1,84 +0,0 @@ -// Package v0_15_0 -// nolint revive -package v0_15_0 - -import ( - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkmodule "github.com/cosmos/cosmos-sdk/types/module" - - ev1beta1 "github.com/akash-network/akash-api/go/node/escrow/v1beta1" - ev1beta2 "github.com/akash-network/akash-api/go/node/escrow/v1beta2" - - utypes "github.com/akash-network/node/upgrades/types" -) - -type escrowMigrations struct { - utypes.Migrator -} - -func newEscrowMigration(m utypes.Migrator) utypes.Migration { - return escrowMigrations{Migrator: m} -} - -func (m escrowMigrations) GetHandler() sdkmodule.MigrationHandler { - return m.handler -} - -// handler migrates deployment from version 1 to 2. -func (m escrowMigrations) handler(ctx sdk.Context) error { - store := ctx.KVStore(m.StoreKey()) - - err := utypes.MigrateValue(store, m.Codec(), ev1beta2.AccountKeyPrefix(), migrateAccount) - if err != nil { - return err - } - - err = utypes.MigrateValue(store, m.Codec(), ev1beta2.PaymentKeyPrefix(), migratePayment) - if err != nil { - return err - } - - return nil -} - -func migrateAccount(fromBz []byte, cdc codec.BinaryCodec) codec.ProtoMarshaler { - var from ev1beta1.Account - cdc.MustUnmarshal(fromBz, &from) - to := ev1beta2.Account{ - ID: ev1beta2.AccountID{ - Scope: from.ID.Scope, - XID: from.ID.XID, - }, - Owner: from.Owner, - State: ev1beta2.Account_State(from.State), - Balance: sdk.NewDecCoinFromCoin(from.Balance), - Transferred: sdk.NewDecCoinFromCoin(from.Transferred), - SettledAt: from.SettledAt, - // Correctly initialize the new fields - // - Account.Depositor as Account.Owner - // - Account.Funds as a DecCoin of zero value - Depositor: from.Owner, - Funds: sdk.NewDecCoin(from.Balance.Denom, sdk.ZeroInt()), - } - - return &to -} - -func migratePayment(fromBz []byte, cdc codec.BinaryCodec) codec.ProtoMarshaler { - var from ev1beta1.Payment - cdc.MustUnmarshal(fromBz, &from) - - return &ev1beta2.FractionalPayment{ - AccountID: ev1beta2.AccountID{ - Scope: from.AccountID.Scope, - XID: from.AccountID.XID, - }, - PaymentID: from.PaymentID, - Owner: from.Owner, - State: ev1beta2.FractionalPayment_State(from.State), - Rate: sdk.NewDecCoinFromCoin(from.Rate), - Balance: sdk.NewDecCoinFromCoin(from.Balance), - Withdrawn: from.Withdrawn, - } -} diff --git a/upgrades/software/v0.15.0/helpers.go b/upgrades/software/v0.15.0/helpers.go deleted file mode 100644 index efd54ae40b..0000000000 --- a/upgrades/software/v0.15.0/helpers.go +++ /dev/null @@ -1,41 +0,0 @@ -// Package v0_15_0 -// nolint revive -package v0_15_0 - -import ( - "github.com/cosmos/cosmos-sdk/store/prefix" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/address" -) - -const ( - V014Bech32AddrLen = 44 // length of an akash address when encoded as a bech32 string in v0.14 -) - -// migratePrefixBech32AddrBytes is a helper function that migrates all keys of format: -// prefix_bytes | address_bech32_bytes | arbitrary_bytes -// into format: -// prefix_bytes | address_len (1 byte) | address_bytes | arbitrary_bytes -func migratePrefixBech32AddrBytes(store sdk.KVStore, prefixBz []byte) { - oldStore := prefix.NewStore(store, prefixBz) - - oldStoreIter := oldStore.Iterator(nil, nil) - defer func() { - _ = oldStoreIter.Close() - }() - - for ; oldStoreIter.Valid(); oldStoreIter.Next() { - bech32Addr := string(oldStoreIter.Key()[:V014Bech32AddrLen]) - addr, err := sdk.AccAddressFromBech32(bech32Addr) - if err != nil { - panic(err) - } - - endBz := oldStoreIter.Key()[V014Bech32AddrLen:] - newStoreKey := append(append(prefixBz, address.MustLengthPrefix(addr)...), endBz...) - - // Set new key on store. Values don't change. - store.Set(newStoreKey, oldStoreIter.Value()) - oldStore.Delete(oldStoreIter.Key()) - } -} diff --git a/upgrades/software/v0.15.0/init.go b/upgrades/software/v0.15.0/init.go deleted file mode 100644 index 2e3d4e4e8a..0000000000 --- a/upgrades/software/v0.15.0/init.go +++ /dev/null @@ -1,25 +0,0 @@ -// Package v0_15_0 -// nolint revive -package v0_15_0 - -import ( - av1beta2 "github.com/akash-network/akash-api/go/node/audit/v1beta2" - cv1beta2 "github.com/akash-network/akash-api/go/node/cert/v1beta2" - dv1beta2 "github.com/akash-network/akash-api/go/node/deployment/v1beta2" - ev1beta2 "github.com/akash-network/akash-api/go/node/escrow/v1beta2" - mv1beta2 "github.com/akash-network/akash-api/go/node/market/v1beta2" - pv1beta2 "github.com/akash-network/akash-api/go/node/provider/v1beta2" - - utypes "github.com/akash-network/node/upgrades/types" -) - -func init() { - utypes.RegisterUpgrade(upgradeName, initUpgrade) - - utypes.RegisterMigration(av1beta2.ModuleName, 1, newAuditMigration) - utypes.RegisterMigration(cv1beta2.ModuleName, 1, newCertMigration) - utypes.RegisterMigration(dv1beta2.ModuleName, 1, newDeploymentMigration) - utypes.RegisterMigration(mv1beta2.ModuleName, 1, newMarketMigration) - utypes.RegisterMigration(pv1beta2.ModuleName, 1, newProviderMigration) - utypes.RegisterMigration(ev1beta2.ModuleName, 1, newEscrowMigration) -} diff --git a/upgrades/software/v0.15.0/market.go b/upgrades/software/v0.15.0/market.go deleted file mode 100644 index 230b5b04bb..0000000000 --- a/upgrades/software/v0.15.0/market.go +++ /dev/null @@ -1,183 +0,0 @@ -// Package v0_15_0 -// nolint revive -package v0_15_0 - -import ( - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store/prefix" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/address" - sdkmodule "github.com/cosmos/cosmos-sdk/types/module" - - dmigrate "github.com/akash-network/akash-api/go/node/deployment/v1beta2/migrate" - mv1beta1 "github.com/akash-network/akash-api/go/node/market/v1beta1" - mv1beta2 "github.com/akash-network/akash-api/go/node/market/v1beta2" - - utypes "github.com/akash-network/node/upgrades/types" - keys "github.com/akash-network/node/x/market/keeper/keys/v1beta2" -) - -type marketMigrations struct { - utypes.Migrator -} - -func newMarketMigration(m utypes.Migrator) utypes.Migration { - return marketMigrations{Migrator: m} -} - -func (m marketMigrations) GetHandler() sdkmodule.MigrationHandler { - return m.handler -} - -// handler migrates market from version 1 to 2. -func (m marketMigrations) handler(ctx sdk.Context) error { - store := ctx.KVStore(m.StoreKey()) - - // Change addresses to be length-prefixed - migratePrefixBech32AddrBytes(store, mv1beta1.OrderPrefix()) - err := migratePrefixBech32Uint64Uint32Uint32Bech32(store, mv1beta1.BidPrefix()) - if err != nil { - return err - } - - err = migratePrefixBech32Uint64Uint32Uint32Bech32(store, mv1beta1.LeasePrefix()) - if err != nil { - return err - } - - // Migrate protobuf - err = utypes.MigrateValue(store, m.Codec(), mv1beta1.OrderPrefix(), migrateOrder) - if err != nil { - return err - } - - err = utypes.MigrateValue(store, m.Codec(), mv1beta1.BidPrefix(), migrateBid) - if err != nil { - return err - } - - err = utypes.MigrateValue(store, m.Codec(), mv1beta1.LeasePrefix(), migrateLease) - if err != nil { - return err - } - - // add the mapping of secondary lease key -> lease key - addSecondaryLeaseKeys(store, m.Codec()) - - return nil -} - -func addSecondaryLeaseKeys(baseStore sdk.KVStore, cdc codec.BinaryCodec) { - store := prefix.NewStore(baseStore, mv1beta2.LeasePrefix()) - - iter := sdk.KVStorePrefixIterator(store, mv1beta2.LeasePrefix()) - defer func() { - _ = iter.Close() - }() - - for ; iter.Valid(); iter.Next() { - var from mv1beta2.Lease - cdc.MustUnmarshal(iter.Value(), &from) - - leaseKey := keys.LeaseKey(from.GetLeaseID()) - for _, secondaryKey := range keys.SecondaryKeysForLease(from.GetLeaseID()) { - store.Set(secondaryKey, leaseKey) - } - } -} - -// migratePrefixBech32Uint64Uint32Uint32Bech32 is a helper function that migrates all keys of format: -// prefix_bytes | address1_bech32_bytes | uint64 | uint32 | uint32 | address2_bech32_bytes -// into format: -// prefix_bytes | address1_len (1 byte) | address1_bytes | uint64 | uint32 | uint32 | address2_len (1 byte) | address2_bytes -func migratePrefixBech32Uint64Uint32Uint32Bech32(store sdk.KVStore, prefixBz []byte) error { - oldStore := prefix.NewStore(store, prefixBz) - - oldStoreIter := oldStore.Iterator(nil, nil) - defer func() { - _ = oldStoreIter.Close() - }() - - for ; oldStoreIter.Valid(); oldStoreIter.Next() { - bech32Addr1 := string(oldStoreIter.Key()[:V014Bech32AddrLen]) - addr1, err := sdk.AccAddressFromBech32(bech32Addr1) - if err != nil { - return err - } - - midBz := oldStoreIter.Key()[V014Bech32AddrLen : V014Bech32AddrLen+16] - - bech32Addr2 := string(oldStoreIter.Key()[V014Bech32AddrLen+16:]) - addr2, err := sdk.AccAddressFromBech32(bech32Addr2) - if err != nil { - return err - } - - newStoreKey := append(append(append(prefixBz, address.MustLengthPrefix(addr1)...), midBz...), address.MustLengthPrefix(addr2)...) - - // Set new key on store. Values don't change. - store.Set(newStoreKey, oldStoreIter.Value()) - oldStore.Delete(oldStoreIter.Key()) - } - - return nil -} - -func migrateLease(fromBz []byte, cdc codec.BinaryCodec) codec.ProtoMarshaler { - var oldObj mv1beta1.Lease - cdc.MustUnmarshal(fromBz, &oldObj) - to := mv1beta2.Lease{ - LeaseID: mv1beta2.LeaseID{ - Owner: oldObj.LeaseID.Owner, - DSeq: oldObj.LeaseID.DSeq, - GSeq: oldObj.LeaseID.GSeq, - OSeq: oldObj.LeaseID.OSeq, - Provider: oldObj.LeaseID.Provider, - }, - State: mv1beta2.Lease_State(oldObj.State), - Price: sdk.NewDecCoinFromCoin(oldObj.Price), - CreatedAt: oldObj.CreatedAt, - ClosedOn: 0, // For leases created prior to this change never report the data - } - - return &to -} - -func migrateBid(fromBz []byte, cdc codec.BinaryCodec) codec.ProtoMarshaler { - var oldObject mv1beta1.Bid - cdc.MustUnmarshal(fromBz, &oldObject) - - to := mv1beta2.Bid{ - BidID: mv1beta2.BidID{ - Owner: oldObject.BidID.Owner, - DSeq: oldObject.BidID.DSeq, - GSeq: oldObject.BidID.GSeq, - OSeq: oldObject.BidID.OSeq, - Provider: oldObject.BidID.Provider, - }, - State: mv1beta2.Bid_State(oldObject.State), - Price: sdk.NewDecCoinFromCoin(oldObject.Price), - CreatedAt: oldObject.CreatedAt, - } - - return &to -} - -func migrateOrder(fromBz []byte, cdc codec.BinaryCodec) codec.ProtoMarshaler { - var oldObject mv1beta1.Order - cdc.MustUnmarshal(fromBz, &oldObject) - - to := mv1beta2.Order{ - OrderID: mv1beta2.OrderID{ - Owner: oldObject.OrderID.Owner, - DSeq: oldObject.OrderID.DSeq, - GSeq: oldObject.OrderID.GSeq, - OSeq: oldObject.OrderID.OSeq, - }, - State: mv1beta2.Order_State(oldObject.State), - Spec: dmigrate.GroupSpecFromV1Beta1(oldObject.Spec), - CreatedAt: oldObject.CreatedAt, - } - - return &to -} diff --git a/upgrades/software/v0.15.0/proto_compatibility_test.go b/upgrades/software/v0.15.0/proto_compatibility_test.go deleted file mode 100644 index b460078ca1..0000000000 --- a/upgrades/software/v0.15.0/proto_compatibility_test.go +++ /dev/null @@ -1,290 +0,0 @@ -package v0_15_0_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - - dv1beta1 "github.com/akash-network/akash-api/go/node/deployment/v1beta1" - dv1beta2 "github.com/akash-network/akash-api/go/node/deployment/v1beta2" - ev1beta1 "github.com/akash-network/akash-api/go/node/escrow/v1beta1" - ev1beta2 "github.com/akash-network/akash-api/go/node/escrow/v1beta2" - mv1beta1 "github.com/akash-network/akash-api/go/node/market/v1beta1" - mv1beta2 "github.com/akash-network/akash-api/go/node/market/v1beta2" - types "github.com/akash-network/akash-api/go/node/types/v1beta1" - - "github.com/akash-network/node/app" -) - -var ( - cdc = app.MakeEncodingConfig().Marshaler.(codec.BinaryCodec) -) - -func TestDeployment_DeploymentProto_IsCompatible(t *testing.T) { - oldProto := dv1beta1.Deployment{ - DeploymentID: dv1beta1.DeploymentID{Owner: "A", DSeq: 1}, - State: dv1beta1.DeploymentActive, - Version: []byte{1, 2, 3, 4}, - CreatedAt: 5, - } - - expectedProto := dv1beta2.Deployment{ - DeploymentID: dv1beta2.DeploymentID{Owner: "A", DSeq: 1}, - State: dv1beta2.DeploymentActive, - Version: []byte{1, 2, 3, 4}, - CreatedAt: 5, - } - - var actualProto dv1beta2.Deployment - cdc.MustUnmarshal(cdc.MustMarshal(&oldProto), &actualProto) - require.Equal(t, expectedProto, actualProto) - require.Equal(t, cdc.MustMarshal(&oldProto), cdc.MustMarshal(&expectedProto)) -} - -func TestDeployment_GroupProto_IsNotCompatible(t *testing.T) { - oldProto := dv1beta1.Group{ - GroupID: dv1beta1.GroupID{ - Owner: "A", - DSeq: 1, - GSeq: 2, - }, - State: dv1beta1.GroupOpen, - GroupSpec: dv1beta1.GroupSpec{ - Name: "A", - Requirements: types.PlacementRequirements{ - SignedBy: types.SignedBy{ - AllOf: []string{"a"}, - AnyOf: []string{"a"}, - }, - Attributes: types.Attributes{{ - Key: "a", - Value: "a", - }}, - }, - Resources: []dv1beta1.Resource{{ - Resources: types.ResourceUnits{ - CPU: &types.CPU{ - Units: types.ResourceValue{Val: sdk.NewInt(1)}, - Attributes: types.Attributes{{ - Key: "a", - Value: "a", - }}, - }, - Memory: &types.Memory{ - Quantity: types.ResourceValue{Val: sdk.NewInt(1)}, - Attributes: types.Attributes{{ - Key: "a", - Value: "a", - }}, - }, - Storage: &types.Storage{ - Quantity: types.ResourceValue{Val: sdk.NewInt(1)}, - Attributes: types.Attributes{{ - Key: "a", - Value: "a", - }}, - }, - Endpoints: []types.Endpoint{{Kind: types.Endpoint_RANDOM_PORT}}, - }, - Count: 1, - Price: sdk.NewCoin("uakt", sdk.NewInt(1)), - }}, - }, - CreatedAt: 5, - } - - var actualProto dv1beta2.Group - require.Error(t, cdc.Unmarshal(cdc.MustMarshal(&oldProto), &actualProto)) // it doesn't unmarshal -} - -func TestEscrow_AccountProto_IsNotCompatible(t *testing.T) { - oldProto := ev1beta1.Account{ - ID: ev1beta1.AccountID{ - Scope: "a", - XID: "a", - }, - Owner: "a", - State: 1, - Balance: sdk.NewCoin("uakt", sdk.NewInt(1)), - Transferred: sdk.NewCoin("uakt", sdk.NewInt(1)), - SettledAt: 2, - } - - expectedProto := ev1beta2.Account{ - ID: ev1beta2.AccountID{ - Scope: "a", - XID: "a", - }, - Owner: "a", - State: 1, - Balance: sdk.NewDecCoin("uakt", sdk.NewInt(1)), - Transferred: sdk.NewDecCoin("uakt", sdk.NewInt(1)), - SettledAt: 2, - Depositor: "", - Funds: sdk.DecCoin{}, - } - - var actualProto ev1beta2.Account - cdc.MustUnmarshal(cdc.MustMarshal(&oldProto), &actualProto) // although it unmarshalls - require.NotEqual(t, expectedProto, actualProto) // but the result isn't equal - require.NotEqual(t, cdc.MustMarshal(&oldProto), cdc.MustMarshal(&expectedProto)) // neither is marshalled bytes -} - -func TestEscrow_PaymentProto_IsNotCompatible(t *testing.T) { - oldProto := ev1beta1.Payment{ - AccountID: ev1beta1.AccountID{ - Scope: "a", - XID: "a", - }, - PaymentID: "a", - Owner: "a", - State: 1, - Rate: sdk.NewCoin("uakt", sdk.NewInt(1)), - Balance: sdk.NewCoin("uakt", sdk.NewInt(1)), - Withdrawn: sdk.NewCoin("uakt", sdk.NewInt(1)), - } - - expectedProto := ev1beta2.FractionalPayment{ - AccountID: ev1beta2.AccountID{ - Scope: "a", - XID: "a", - }, - PaymentID: "a", - Owner: "a", - State: 1, - Rate: sdk.NewDecCoin("uakt", sdk.NewInt(1)), - Balance: sdk.NewDecCoin("uakt", sdk.NewInt(1)), - Withdrawn: sdk.NewCoin("uakt", sdk.NewInt(1)), - } - - var actualProto ev1beta2.FractionalPayment - cdc.MustUnmarshal(cdc.MustMarshal(&oldProto), &actualProto) // although it unmarshalls - require.NotEqual(t, expectedProto, actualProto) // but the result isn't equal - require.NotEqual(t, cdc.MustMarshal(&oldProto), cdc.MustMarshal(&expectedProto)) // neither is marshalled bytes -} - -func TestMarket_BidProto_IsNotCompatible(t *testing.T) { - oldProto := mv1beta1.Bid{ - BidID: mv1beta1.BidID{ - Owner: "a", - DSeq: 1, - GSeq: 2, - OSeq: 3, - Provider: "a", - }, - State: mv1beta1.BidActive, - Price: sdk.NewCoin("uakt", sdk.NewInt(1)), - CreatedAt: 1, - } - - expectedProto := mv1beta2.Bid{ - BidID: mv1beta2.BidID{ - Owner: "a", - DSeq: 1, - GSeq: 2, - OSeq: 3, - Provider: "a", - }, - State: mv1beta2.BidActive, - Price: sdk.NewDecCoin("uakt", sdk.NewInt(1)), - CreatedAt: 1, - } - - var actualProto mv1beta2.Bid - cdc.MustUnmarshal(cdc.MustMarshal(&oldProto), &actualProto) // although it unmarshalls - require.NotEqual(t, expectedProto, actualProto) // but the result isn't equal - require.NotEqual(t, cdc.MustMarshal(&oldProto), cdc.MustMarshal(&expectedProto)) // neither is marshalled bytes -} - -func TestMarket_LeaseProto_IsNotCompatible(t *testing.T) { - oldProto := mv1beta1.Lease{ - LeaseID: mv1beta1.LeaseID{ - Owner: "a", - DSeq: 1, - GSeq: 2, - OSeq: 3, - Provider: "a", - }, - State: mv1beta1.LeaseActive, - Price: sdk.NewCoin("uakt", sdk.NewInt(1)), - CreatedAt: 1, - } - - expectedProto := mv1beta2.Lease{ - LeaseID: mv1beta2.LeaseID{ - Owner: "a", - DSeq: 1, - GSeq: 2, - OSeq: 3, - Provider: "a", - }, - State: mv1beta2.LeaseActive, - Price: sdk.NewDecCoin("uakt", sdk.NewInt(1)), - CreatedAt: 1, - } - - var actualProto mv1beta2.Lease - cdc.MustUnmarshal(cdc.MustMarshal(&oldProto), &actualProto) // although it unmarshalls - require.NotEqual(t, expectedProto, actualProto) // but the result isn't equal - require.NotEqual(t, cdc.MustMarshal(&oldProto), cdc.MustMarshal(&expectedProto)) // neither is marshalled bytes -} - -func TestMarket_OrderProto_IsNotCompatible(t *testing.T) { - oldProto := mv1beta1.Order{ - OrderID: mv1beta1.OrderID{ - Owner: "a", - DSeq: 1, - GSeq: 2, - OSeq: 3, - }, - State: mv1beta1.OrderActive, - Spec: dv1beta1.GroupSpec{ - Name: "A", - Requirements: types.PlacementRequirements{ - SignedBy: types.SignedBy{ - AllOf: []string{"a"}, - AnyOf: []string{"a"}, - }, - Attributes: types.Attributes{{ - Key: "a", - Value: "a", - }}, - }, - Resources: []dv1beta1.Resource{{ - Resources: types.ResourceUnits{ - CPU: &types.CPU{ - Units: types.ResourceValue{Val: sdk.NewInt(1)}, - Attributes: types.Attributes{{ - Key: "a", - Value: "a", - }}, - }, - Memory: &types.Memory{ - Quantity: types.ResourceValue{Val: sdk.NewInt(1)}, - Attributes: types.Attributes{{ - Key: "a", - Value: "a", - }}, - }, - Storage: &types.Storage{ - Quantity: types.ResourceValue{Val: sdk.NewInt(1)}, - Attributes: types.Attributes{{ - Key: "a", - Value: "a", - }}, - }, - Endpoints: []types.Endpoint{{Kind: types.Endpoint_RANDOM_PORT}}, - }, - Count: 1, - Price: sdk.NewCoin("uakt", sdk.NewInt(1)), - }}, - }, - CreatedAt: 1, - } - - var actualProto mv1beta2.Order - require.Error(t, cdc.Unmarshal(cdc.MustMarshal(&oldProto), &actualProto)) // it doesn't unmarshal -} diff --git a/upgrades/software/v0.15.0/provider.go b/upgrades/software/v0.15.0/provider.go deleted file mode 100644 index e6f803c51d..0000000000 --- a/upgrades/software/v0.15.0/provider.go +++ /dev/null @@ -1,46 +0,0 @@ -// Package v0_15_0 -// nolint revive -package v0_15_0 - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/address" - sdkmodule "github.com/cosmos/cosmos-sdk/types/module" - - utypes "github.com/akash-network/node/upgrades/types" -) - -type providerMigrations struct { - utypes.Migrator -} - -func newProviderMigration(m utypes.Migrator) utypes.Migration { - return providerMigrations{Migrator: m} -} - -func (m providerMigrations) GetHandler() sdkmodule.MigrationHandler { - return m.handler -} - -// handler migrates provider from version 1 to 2. -func (m providerMigrations) handler(ctx sdk.Context) error { - store := ctx.KVStore(m.StoreKey()) - - // old key is of format: - // ownerAddrBytes (20 bytes) - // new key is of format - // ownerAddrLen (1 byte) || ownerAddrBytes - oldStoreIter := store.Iterator(nil, nil) - defer func() { - _ = oldStoreIter.Close() - }() - - for ; oldStoreIter.Valid(); oldStoreIter.Next() { - newStoreKey := address.MustLengthPrefix(oldStoreIter.Key()) - - // Set new key on store. Values don't change. - store.Set(newStoreKey, oldStoreIter.Value()) - store.Delete(oldStoreIter.Key()) - } - return nil -} diff --git a/upgrades/software/v0.15.0/upgrade.go b/upgrades/software/v0.15.0/upgrade.go deleted file mode 100644 index 90a1b6c7e7..0000000000 --- a/upgrades/software/v0.15.0/upgrade.go +++ /dev/null @@ -1,93 +0,0 @@ -// Package v0_15_0 -// nolint revive -package v0_15_0 - -import ( - inflationtypes "github.com/akash-network/akash-api/go/node/inflation/v1beta3" - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - "github.com/cosmos/cosmos-sdk/x/authz" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - ibcconnectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - ibckeeper "github.com/cosmos/ibc-go/v4/modules/core/keeper" - "github.com/tendermint/tendermint/libs/log" - - apptypes "github.com/akash-network/node/app/types" - utypes "github.com/akash-network/node/upgrades/types" -) - -const ( - upgradeName = "akash_v0.15.0_cosmos_v0.44.x" -) - -type upgrade struct { - *apptypes.App - ibc *ibckeeper.Keeper -} - -var _ utypes.IUpgrade = (*upgrade)(nil) - -func initUpgrade(_ log.Logger, app *apptypes.App) (utypes.IUpgrade, error) { - up := &upgrade{ - App: app, - } - - val, err := apptypes.FindStructField[*ibckeeper.Keeper](&app.Keepers.Cosmos, "IBC") - if err != nil { - return nil, err - } - - up.ibc = val - - return up, nil -} - -func (up *upgrade) StoreLoader() *storetypes.StoreUpgrades { - upgrades := &storetypes.StoreUpgrades{ - Added: []string{ - authz.ModuleName, - inflationtypes.ModuleName, - }, - } - - return upgrades -} - -func (up *upgrade) UpgradeHandler() upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, plan upgradetypes.Plan, versionMap module.VersionMap) (module.VersionMap, error) { - // set max expected block time parameter. Replace the default with your expected value - up.ibc.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) - - // 1st-time running in-store migrations, using 1 as fromVersion to - // avoid running InitGenesis. - fromVM := map[string]uint64{ - "auth": 1, - "bank": 1, - "capability": 1, - "crisis": 1, - "distribution": 1, - "evidence": 1, - "gov": 1, - "mint": 1, - "params": 1, - "slashing": 1, - "staking": 1, - "upgrade": 1, - "vesting": 1, - "ibc": 1, - "genutil": 1, - "transfer": 1, - - // akash modules - "audit": 1, - "cert": 1, - "deployment": 1, - "escrow": 1, - "market": 1, - "provider": 1, - } - - return up.MM.RunMigrations(ctx, up.Configurator, fromVM) - } -} diff --git a/upgrades/software/v0.18.0/init.go b/upgrades/software/v0.18.0/init.go deleted file mode 100644 index 5eef63ed6f..0000000000 --- a/upgrades/software/v0.18.0/init.go +++ /dev/null @@ -1,11 +0,0 @@ -// Package v0_18_0 -// nolint revive -package v0_18_0 - -import ( - utypes "github.com/akash-network/node/upgrades/types" -) - -func init() { - utypes.RegisterUpgrade(upgradeName, initUpgrade) -} diff --git a/upgrades/software/v0.18.0/upgrade.go b/upgrades/software/v0.18.0/upgrade.go deleted file mode 100644 index 172ec79da7..0000000000 --- a/upgrades/software/v0.18.0/upgrade.go +++ /dev/null @@ -1,79 +0,0 @@ -// Package v0_18_0 -// nolint revive -package v0_18_0 - -import ( - "fmt" - - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - ica "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts" - icacontrollertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - icahosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - "github.com/tendermint/tendermint/libs/log" - - apptypes "github.com/akash-network/node/app/types" - utypes "github.com/akash-network/node/upgrades/types" -) - -const ( - upgradeName = "v0.18.0" -) - -type upgrade struct { - *apptypes.App -} - -var _ utypes.IUpgrade = (*upgrade)(nil) - -func initUpgrade(_ log.Logger, app *apptypes.App) (utypes.IUpgrade, error) { - up := &upgrade{ - App: app, - } - - if _, exists := up.MM.Modules[icatypes.ModuleName]; !exists { - return nil, fmt.Errorf("module %s has not been initialized", icatypes.ModuleName) // nolint: goerr113 - } - - return up, nil -} - -func (up *upgrade) StoreLoader() *storetypes.StoreUpgrades { - upgrades := &storetypes.StoreUpgrades{ - Added: []string{ - icacontrollertypes.StoreKey, - icahosttypes.StoreKey, - }, - } - - return upgrades -} - -func (up *upgrade) UpgradeHandler() upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - fromVM[icatypes.ModuleName] = up.MM.Modules[icatypes.ModuleName].ConsensusVersion() - - // create ICS27 Controller submodule params - // enable the controller chain - controllerParams := icacontrollertypes.Params{ControllerEnabled: true} - - // create ICS27 Host submodule params - hostParams := icahosttypes.Params{ - // enable the host chain - HostEnabled: true, - // allowing the all messages - AllowMessages: []string{"*"}, - } - - ctx.Logger().Info("start to init interchainaccount module...") - // initialize ICS27 module - up.MM.Modules[icatypes.ModuleName].(ica.AppModule).InitModule(ctx, controllerParams, hostParams) - - ctx.Logger().Info("start to run module migrations...") - - return up.MM.RunMigrations(ctx, up.Configurator, fromVM) - } -} diff --git a/upgrades/software/v0.20.0/init.go b/upgrades/software/v0.20.0/init.go deleted file mode 100644 index 4ed992e4a1..0000000000 --- a/upgrades/software/v0.20.0/init.go +++ /dev/null @@ -1,11 +0,0 @@ -// Package v0_20_0 -// nolint revive -package v0_20_0 - -import ( - utypes "github.com/akash-network/node/upgrades/types" -) - -func init() { - utypes.RegisterUpgrade(upgradeName, initUpgrade) -} diff --git a/upgrades/software/v0.20.0/upgrade.go b/upgrades/software/v0.20.0/upgrade.go deleted file mode 100644 index 5e92347e65..0000000000 --- a/upgrades/software/v0.20.0/upgrade.go +++ /dev/null @@ -1,58 +0,0 @@ -// Package v0_20_0 -// nolint revive -package v0_20_0 - -import ( - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - icacontrollertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - icahosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - "github.com/tendermint/tendermint/libs/log" - - apptypes "github.com/akash-network/node/app/types" - utypes "github.com/akash-network/node/upgrades/types" -) - -const ( - upgradeName = "v0.20.0" -) - -type upgrade struct { - *apptypes.App -} - -var _ utypes.IUpgrade = (*upgrade)(nil) - -func initUpgrade(_ log.Logger, app *apptypes.App) (utypes.IUpgrade, error) { - up := &upgrade{ - App: app, - } - - return up, nil -} - -func (up *upgrade) StoreLoader() *storetypes.StoreUpgrades { - upgrades := &storetypes.StoreUpgrades{ - Deleted: []string{ - icacontrollertypes.StoreKey, - icahosttypes.StoreKey, - }, - } - - return upgrades -} - -func (up *upgrade) UpgradeHandler() upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - ctx.Logger().Info("start to roll-back interchainaccount module...") - - delete(fromVM, icatypes.ModuleName) - - ctx.Logger().Info("start to run module migrations...") - - return up.MM.RunMigrations(ctx, up.Configurator, fromVM) - } -} diff --git a/upgrades/software/v0.24.0/deployment.go b/upgrades/software/v0.24.0/deployment.go deleted file mode 100644 index e1b2b800d1..0000000000 --- a/upgrades/software/v0.24.0/deployment.go +++ /dev/null @@ -1,48 +0,0 @@ -// Package v0_24_0 -// nolint revive -package v0_24_0 - -import ( - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkmodule "github.com/cosmos/cosmos-sdk/types/module" - - dv1beta2 "github.com/akash-network/akash-api/go/node/deployment/v1beta2" - dmigrate "github.com/akash-network/akash-api/go/node/deployment/v1beta3/migrate" - - utypes "github.com/akash-network/node/upgrades/types" -) - -type deploymentMigrations struct { - utypes.Migrator -} - -func newDeploymentMigration(m utypes.Migrator) utypes.Migration { - return deploymentMigrations{Migrator: m} -} - -func (m deploymentMigrations) GetHandler() sdkmodule.MigrationHandler { - return m.handler -} - -// handler migrates deployment from version 2 to 3. -func (m deploymentMigrations) handler(ctx sdk.Context) error { - store := ctx.KVStore(m.StoreKey()) - - err := utypes.MigrateValue(store, m.Codec(), dv1beta2.GroupPrefix(), migrateDeploymentGroup) - - if err != nil { - return err - } - - return nil -} - -func migrateDeploymentGroup(fromBz []byte, cdc codec.BinaryCodec) codec.ProtoMarshaler { - var from dv1beta2.Group - cdc.MustUnmarshal(fromBz, &from) - - to := dmigrate.GroupFromV1Beta2(from) - - return &to -} diff --git a/upgrades/software/v0.24.0/init.go b/upgrades/software/v0.24.0/init.go deleted file mode 100644 index 0b464e0469..0000000000 --- a/upgrades/software/v0.24.0/init.go +++ /dev/null @@ -1,17 +0,0 @@ -// Package v0_24_0 -// nolint revive -package v0_24_0 - -import ( - dv1beta3 "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - mv1beta3 "github.com/akash-network/akash-api/go/node/market/v1beta3" - - utypes "github.com/akash-network/node/upgrades/types" -) - -func init() { - utypes.RegisterUpgrade(upgradeName, initUpgrade) - - utypes.RegisterMigration(dv1beta3.ModuleName, 2, newDeploymentMigration) - utypes.RegisterMigration(mv1beta3.ModuleName, 2, newMarketMigration) -} diff --git a/upgrades/software/v0.24.0/market.go b/upgrades/software/v0.24.0/market.go deleted file mode 100644 index 93dd3708f8..0000000000 --- a/upgrades/software/v0.24.0/market.go +++ /dev/null @@ -1,59 +0,0 @@ -// Package v0_24_0 -// nolint revive -package v0_24_0 - -import ( - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkmodule "github.com/cosmos/cosmos-sdk/types/module" - - dmigrate "github.com/akash-network/akash-api/go/node/deployment/v1beta3/migrate" - mv1beta2 "github.com/akash-network/akash-api/go/node/market/v1beta2" - mv1beta3 "github.com/akash-network/akash-api/go/node/market/v1beta3" - - utypes "github.com/akash-network/node/upgrades/types" -) - -type marketMigrations struct { - utypes.Migrator -} - -func newMarketMigration(m utypes.Migrator) utypes.Migration { - return marketMigrations{Migrator: m} -} - -func (m marketMigrations) GetHandler() sdkmodule.MigrationHandler { - return m.handler -} - -// handler migrates deployment from version 2 to 3. -func (m marketMigrations) handler(ctx sdk.Context) error { - store := ctx.KVStore(m.StoreKey()) - - err := utypes.MigrateValue(store, m.Codec(), mv1beta3.OrderPrefix(), migrateOrder) - - if err != nil { - return err - } - - return nil -} - -func migrateOrder(fromBz []byte, cdc codec.BinaryCodec) codec.ProtoMarshaler { - var oldObject mv1beta2.Order - cdc.MustUnmarshal(fromBz, &oldObject) - - to := mv1beta3.Order{ - OrderID: mv1beta3.OrderID{ - Owner: oldObject.OrderID.Owner, - DSeq: oldObject.OrderID.DSeq, - GSeq: oldObject.OrderID.GSeq, - OSeq: oldObject.OrderID.OSeq, - }, - State: mv1beta3.Order_State(oldObject.State), - Spec: dmigrate.GroupSpecFromV1Beta2(oldObject.Spec), - CreatedAt: oldObject.CreatedAt, - } - - return &to -} diff --git a/upgrades/software/v0.24.0/upgrade.go b/upgrades/software/v0.24.0/upgrade.go deleted file mode 100644 index 810bb0bcd7..0000000000 --- a/upgrades/software/v0.24.0/upgrade.go +++ /dev/null @@ -1,220 +0,0 @@ -// Package v0_24_0 -// nolint revive -package v0_24_0 - -import ( - "fmt" - "time" - - "github.com/tendermint/tendermint/libs/log" - - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - "github.com/cosmos/cosmos-sdk/x/feegrant" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - "github.com/akash-network/akash-api/go/node/escrow/v1beta3" - astakingtypes "github.com/akash-network/akash-api/go/node/staking/v1beta3" - - apptypes "github.com/akash-network/node/app/types" - utypes "github.com/akash-network/node/upgrades/types" - agov "github.com/akash-network/node/x/gov" - astaking "github.com/akash-network/node/x/staking" - atake "github.com/akash-network/node/x/take" -) - -const ( - upgradeName = "v0.24.0" -) - -type upgrade struct { - *apptypes.App - log log.Logger -} - -var _ utypes.IUpgrade = (*upgrade)(nil) - -func initUpgrade(log log.Logger, app *apptypes.App) (utypes.IUpgrade, error) { - up := &upgrade{ - App: app, - log: log.With(fmt.Sprintf("upgrade/%s", upgradeName)), - } - - if _, exists := up.MM.Modules[agov.ModuleName]; !exists { - return nil, fmt.Errorf( - "module %s has not been initialized", - agov.ModuleName, - ) // nolint: goerr113 - } - - if _, exists := up.MM.Modules[astaking.ModuleName]; !exists { - return nil, fmt.Errorf( - "module %s has not been initialized", - astaking.ModuleName, - ) // nolint: goerr113 - } - - if _, exists := up.MM.Modules[atake.ModuleName]; !exists { - return nil, fmt.Errorf( - "module %s has not been initialized", - atake.ModuleName, - ) // nolint: goerr113 - } - - if _, exists := up.MM.Modules[feegrant.ModuleName]; !exists { - return nil, fmt.Errorf( - "module %s has not been initialized", - feegrant.ModuleName, - ) // nolint: goerr113 - } - - return up, nil -} - -func (up *upgrade) StoreLoader() *storetypes.StoreUpgrades { - upgrades := &storetypes.StoreUpgrades{ - Added: []string{ - feegrant.StoreKey, - agov.StoreKey, - astaking.StoreKey, - atake.StoreKey, - }, - } - - return upgrades -} - -func (up *upgrade) UpgradeHandler() upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - // initializing akash staking module here so enforceMinValidatorCommission below can use params - ctx.Logger().Info("initializing parameters in astaking module...") - if err := up.Keepers.Akash.Staking.SetParams(ctx, astakingtypes.DefaultParams()); err != nil { - return nil, err - } - - if err := up.enforceMinValidatorCommission(ctx); err != nil { - return nil, err - } - - up.patchDanglingEscrowPayments(ctx) - - ctx.Logger().Info("starting module migrations...") - - // migrate to new deployment params schema - up.Keepers.Akash.Deployment.SetParams(ctx, dtypes.DefaultParams()) - - return up.MM.RunMigrations(ctx, up.Configurator, fromVM) - } -} - -func (up *upgrade) enforceMinValidatorCommission(ctx sdk.Context) error { - minRate := up.Keepers.Akash.Staking.MinCommissionRate(ctx) - - validators := up.Keepers.Cosmos.Staking.GetAllValidators(ctx) - - for _, validator := range validators { - // update MaxRate if it is less than minimum required rate - if validator.Commission.MaxRate.LT(minRate) { - validator.Commission.MaxRate = minRate - } - - if validator.GetCommission().LT(minRate) { - up.log.Info( - fmt.Sprintf( - "validator's `%s` current commission is %s%% < %[3]s%%(min required). Force updating to %[3]s%%", - validator.OperatorAddress, - validator.Commission.Rate, - minRate, - ), - ) - // set max change rate temporarily to 100% - maxRateCh := validator.Commission.MaxChangeRate - validator.Commission.MaxChangeRate = sdk.NewDecWithPrec(1, 0) - if _, err := updateValidatorCommission(ctx, validator, minRate); err != nil { - return err - } - - validator.Commission.MaxChangeRate = maxRateCh - - up.Keepers.Cosmos.Staking.BeforeValidatorModified(ctx, validator.GetOperator()) - up.Keepers.Cosmos.Staking.SetValidator(ctx, validator) - } - } - - return nil -} - -// updateValidatorCommission use custom implementation of update commission, -// this prevents panic during upgrade if any of validators have changed their -// commission within 24h of upgrade height -func updateValidatorCommission( - ctx sdk.Context, - validator stakingtypes.Validator, - newRate sdk.Dec, -) (stakingtypes.Commission, error) { - commission := validator.Commission - blockTime := ctx.BlockHeader().Time - - if err := validateNewRate(commission, newRate, blockTime); err != nil { - return commission, err - } - - commission.Rate = newRate - commission.UpdateTime = blockTime - - return commission, nil -} - -// validateNewRate performs basic sanity validation checks of a new commission -// rate. If validation fails, an SDK error is returned. -func validateNewRate(commission stakingtypes.Commission, newRate sdk.Dec, _ time.Time) error { - switch { - case newRate.IsNegative(): - // new rate cannot be negative - return stakingtypes.ErrCommissionNegative - - case newRate.GT(commission.MaxRate): - // new rate cannot be greater than the max rate - return stakingtypes.ErrCommissionGTMaxRate - - case newRate.Sub(commission.Rate).GT(commission.MaxChangeRate): - // new rate % points change cannot be greater than the max change rate - return stakingtypes.ErrCommissionGTMaxChangeRate - } - - return nil -} - -func (up *upgrade) patchDanglingEscrowPayments(ctx sdk.Context) { - up.Keepers.Akash.Escrow.WithPayments(ctx, func(payment v1beta3.FractionalPayment) bool { - acc, _ := up.Keepers.Akash.Escrow.GetAccount(ctx, payment.AccountID) - if (payment.State == v1beta3.PaymentOpen && acc.State != v1beta3.AccountOpen) || - (payment.State == v1beta3.PaymentOverdrawn && acc.State != v1beta3.AccountOverdrawn) { - - up.log.Info( - fmt.Sprintf( - "payment id state `%s:%s` does not match account state `%s:%s`. forcing payment state to %[4]s", - payment.PaymentID, - payment.State, - acc.ID, - acc.State, - ), - ) - - switch acc.State { - case v1beta3.AccountOpen: - payment.State = v1beta3.PaymentOpen - case v1beta3.AccountClosed: - payment.State = v1beta3.PaymentClosed - case v1beta3.AccountOverdrawn: - payment.State = v1beta3.PaymentOverdrawn - } - } - - up.Keepers.Akash.Escrow.SavePayment(ctx, payment) - return true - }) -} diff --git a/upgrades/software/v0.26.0/init.go b/upgrades/software/v0.26.0/init.go deleted file mode 100644 index e1df58ebd3..0000000000 --- a/upgrades/software/v0.26.0/init.go +++ /dev/null @@ -1,11 +0,0 @@ -// Package v0_26_0 -// nolint revive -package v0_26_0 - -import ( - utypes "github.com/akash-network/node/upgrades/types" -) - -func init() { - utypes.RegisterUpgrade(UpgradeName, initUpgrade) -} diff --git a/upgrades/software/v0.26.0/upgrade.go b/upgrades/software/v0.26.0/upgrade.go deleted file mode 100644 index 78ac996eef..0000000000 --- a/upgrades/software/v0.26.0/upgrade.go +++ /dev/null @@ -1,206 +0,0 @@ -// Package v0_26_0 -// nolint revive -package v0_26_0 - -import ( - "fmt" - "reflect" - "time" - - "github.com/tendermint/tendermint/libs/log" - - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - "github.com/cosmos/cosmos-sdk/x/authz" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - - v1beta2dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta2" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - - apptypes "github.com/akash-network/node/app/types" - utypes "github.com/akash-network/node/upgrades/types" -) - -const ( - UpgradeName = "v0.26.0" -) - -type upgrade struct { - *apptypes.App - log log.Logger -} - -var _ utypes.IUpgrade = (*upgrade)(nil) - -func initUpgrade(log log.Logger, app *apptypes.App) (utypes.IUpgrade, error) { - up := &upgrade{ - App: app, - log: log.With("module", fmt.Sprintf("upgrade/%s", UpgradeName)), - } - - return up, nil -} - -func (up *upgrade) StoreLoader() *storetypes.StoreUpgrades { - return &storetypes.StoreUpgrades{} -} - -func (up *upgrade) UpgradeHandler() upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - if err := up.enforceMinValidatorCommission(ctx); err != nil { - return nil, err - } - - if err := up.migrateDeploymentAuthz(ctx); err != nil { - return nil, err - } - - return up.MM.RunMigrations(ctx, up.Configurator, fromVM) - } -} - -type grantBackup struct { - granter sdk.AccAddress - grantee sdk.AccAddress - grant authz.Grant -} - -func (up *upgrade) migrateDeploymentAuthz(ctx sdk.Context) error { - msgUrlOld := v1beta2dtypes.DepositDeploymentAuthorization{}.MsgTypeURL() - - grants := make([]grantBackup, 0, 10000) - - up.Keepers.Cosmos.Authz.IterateGrants(ctx, func(granterAddr sdk.AccAddress, granteeAddr sdk.AccAddress, grant authz.Grant) bool { - authorization := grant.GetAuthorization() - if authorization.MsgTypeURL() == msgUrlOld { - grants = append(grants, grantBackup{ - granter: granterAddr, - grantee: granteeAddr, - grant: grant, - }) - } - return false - }) - - expiredCnt := 0 - - for _, grant := range grants { - authzGen := grant.grant.GetAuthorization() - authzOld, valid := authzGen.(*v1beta2dtypes.DepositDeploymentAuthorization) - if !valid { - return fmt.Errorf("unexpected authorization type. expected (%s), actual (%s)", reflect.TypeOf(&v1beta2dtypes.DepositDeploymentAuthorization{}), reflect.TypeOf(authzGen)) - } - - err := up.Keepers.Cosmos.Authz.DeleteGrant(ctx, grant.grantee, grant.granter, msgUrlOld) - if err != nil { - return err - } - - // Save only grants that are still active at upgrade block - if grant.grant.Expiration.Before(ctx.BlockHeader().Time) { - expiredCnt++ - continue - } - - authzNew := dtypes.NewDepositDeploymentAuthorization(authzOld.SpendLimit) - - err = up.Keepers.Cosmos.Authz.SaveGrant(ctx, grant.grantee, grant.granter, authzNew, grant.grant.Expiration) - if err != nil { - return err - } - } - - up.log.Info("updated DepositDeploymentAuthorizations from v1beta2 to v1beta3", "total", len(grants), "expired", expiredCnt) - - return nil -} - -func (up *upgrade) enforceMinValidatorCommission(ctx sdk.Context) error { - minRate := up.Keepers.Akash.Staking.MinCommissionRate(ctx) - validators := up.Keepers.Cosmos.Staking.GetAllValidators(ctx) - - for _, validator := range validators { - if validator.Commission.MaxRate.LT(minRate) || validator.GetCommission().LT(minRate) { - // update MaxRate if it is less than minimum required rate - if validator.Commission.MaxRate.LT(minRate) { - up.log.Info(fmt.Sprintf("force updating validator commission MaxRate to %s", minRate), - "address", - validator.OperatorAddress, - "currentMaxRate", - validator.Commission.MaxRate, - ) - - validator.Commission.MaxRate = minRate - } - - if validator.GetCommission().LT(minRate) { - up.log.Info(fmt.Sprintf("force updating validator commission Rate to %s", minRate), - "address", - validator.OperatorAddress, - "currentRate", - validator.Commission.Rate, - ) - - // set max change rate temporarily to 100% - maxRateCh := validator.Commission.MaxChangeRate - validator.Commission.MaxChangeRate = sdk.NewDecWithPrec(1, 0) - - newCommission, err := updateValidatorCommission(ctx, validator, minRate) - if err != nil { - return err - } - - validator.Commission = newCommission - validator.Commission.MaxChangeRate = maxRateCh - } - - up.Keepers.Cosmos.Staking.BeforeValidatorModified(ctx, validator.GetOperator()) - up.Keepers.Cosmos.Staking.SetValidator(ctx, validator) - } - } - - return nil -} - -// updateValidatorCommission use custom implementation of update commission, -// this prevents panic during upgrade if any of validators have changed their -// commission within 24h of upgrade height -func updateValidatorCommission( - ctx sdk.Context, - validator stakingtypes.Validator, - newRate sdk.Dec, -) (stakingtypes.Commission, error) { - commission := validator.Commission - blockTime := ctx.BlockHeader().Time - - if err := validateNewRate(commission, newRate, blockTime); err != nil { - return commission, err - } - - commission.Rate = newRate - commission.UpdateTime = blockTime - - return commission, nil -} - -// validateNewRate performs basic sanity validation checks of a new commission -// rate. If validation fails, an SDK error is returned. -func validateNewRate(commission stakingtypes.Commission, newRate sdk.Dec, _ time.Time) error { - switch { - case newRate.IsNegative(): - // new rate cannot be negative - return stakingtypes.ErrCommissionNegative - - case newRate.GT(commission.MaxRate): - // new rate cannot be greater than the max rate - return stakingtypes.ErrCommissionGTMaxRate - - case newRate.Sub(commission.Rate).GT(commission.MaxChangeRate): - // new rate % points change cannot be greater than the max change rate - return stakingtypes.ErrCommissionGTMaxChangeRate - } - - return nil -} diff --git a/upgrades/software/v0.28.0/init.go b/upgrades/software/v0.28.0/init.go deleted file mode 100644 index 5a9247158e..0000000000 --- a/upgrades/software/v0.28.0/init.go +++ /dev/null @@ -1,14 +0,0 @@ -// Package v0_28_0 -// nolint revive -package v0_28_0 - -import ( - mv1beta4 "github.com/akash-network/akash-api/go/node/market/v1beta4" - - utypes "github.com/akash-network/node/upgrades/types" -) - -func init() { - utypes.RegisterUpgrade(UpgradeName, initUpgrade) - utypes.RegisterMigration(mv1beta4.ModuleName, 3, newMarketMigration) -} diff --git a/upgrades/software/v0.28.0/market.go b/upgrades/software/v0.28.0/market.go deleted file mode 100644 index eab6909cc1..0000000000 --- a/upgrades/software/v0.28.0/market.go +++ /dev/null @@ -1,48 +0,0 @@ -// Package v0_28_0 -// nolint revive -package v0_28_0 - -import ( - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkmodule "github.com/cosmos/cosmos-sdk/types/module" - - mv1beta3 "github.com/akash-network/akash-api/go/node/market/v1beta3" - mmigrate "github.com/akash-network/akash-api/go/node/market/v1beta4/migrate" - - utypes "github.com/akash-network/node/upgrades/types" -) - -type marketMigrations struct { - utypes.Migrator -} - -func newMarketMigration(m utypes.Migrator) utypes.Migration { - return marketMigrations{Migrator: m} -} - -func (m marketMigrations) GetHandler() sdkmodule.MigrationHandler { - return m.handler -} - -// handler migrates deployment from version 2 to 3. -func (m marketMigrations) handler(ctx sdk.Context) error { - store := ctx.KVStore(m.StoreKey()) - - err := utypes.MigrateValue(store, m.Codec(), mv1beta3.BidPrefix(), migrateBid) - - if err != nil { - return err - } - - return nil -} - -func migrateBid(fromBz []byte, cdc codec.BinaryCodec) codec.ProtoMarshaler { - var oldObject mv1beta3.Bid - cdc.MustUnmarshal(fromBz, &oldObject) - - to := mmigrate.BidFromV1beta3(oldObject) - - return &to -} diff --git a/upgrades/software/v0.28.0/upgrade.go b/upgrades/software/v0.28.0/upgrade.go deleted file mode 100644 index fa26681e97..0000000000 --- a/upgrades/software/v0.28.0/upgrade.go +++ /dev/null @@ -1,47 +0,0 @@ -// Package v0_28_0 -// nolint revive -package v0_28_0 - -import ( - "fmt" - - "github.com/tendermint/tendermint/libs/log" - - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - - apptypes "github.com/akash-network/node/app/types" - utypes "github.com/akash-network/node/upgrades/types" -) - -const ( - UpgradeName = "v0.28.0" -) - -type upgrade struct { - *apptypes.App - log log.Logger -} - -var _ utypes.IUpgrade = (*upgrade)(nil) - -func initUpgrade(log log.Logger, app *apptypes.App) (utypes.IUpgrade, error) { - up := &upgrade{ - App: app, - log: log.With("module", fmt.Sprintf("upgrade/%s", UpgradeName)), - } - - return up, nil -} - -func (up *upgrade) StoreLoader() *storetypes.StoreUpgrades { - return &storetypes.StoreUpgrades{} -} - -func (up *upgrade) UpgradeHandler() upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - return up.MM.RunMigrations(ctx, up.Configurator, fromVM) - } -} diff --git a/upgrades/software/v0.30.0/init.go b/upgrades/software/v0.30.0/init.go deleted file mode 100644 index 74a2ea72b1..0000000000 --- a/upgrades/software/v0.30.0/init.go +++ /dev/null @@ -1,11 +0,0 @@ -// Package v0_30_0 -// nolint revive -package v0_30_0 - -import ( - utypes "github.com/akash-network/node/upgrades/types" -) - -func init() { - utypes.RegisterUpgrade(UpgradeName, initUpgrade) -} diff --git a/upgrades/software/v0.30.0/upgrade.go b/upgrades/software/v0.30.0/upgrade.go deleted file mode 100644 index cfefa26118..0000000000 --- a/upgrades/software/v0.30.0/upgrade.go +++ /dev/null @@ -1,47 +0,0 @@ -// Package v0_30_0 -// nolint revive -package v0_30_0 - -import ( - "fmt" - - "github.com/tendermint/tendermint/libs/log" - - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - - apptypes "github.com/akash-network/node/app/types" - utypes "github.com/akash-network/node/upgrades/types" -) - -const ( - UpgradeName = "v0.30.0" -) - -type upgrade struct { - *apptypes.App - log log.Logger -} - -var _ utypes.IUpgrade = (*upgrade)(nil) - -func initUpgrade(log log.Logger, app *apptypes.App) (utypes.IUpgrade, error) { - up := &upgrade{ - App: app, - log: log.With("module", fmt.Sprintf("upgrade/%s", UpgradeName)), - } - - return up, nil -} - -func (up *upgrade) StoreLoader() *storetypes.StoreUpgrades { - return &storetypes.StoreUpgrades{} -} - -func (up *upgrade) UpgradeHandler() upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - return up.MM.RunMigrations(ctx, up.Configurator, fromVM) - } -} diff --git a/upgrades/software/v0.32.0/init.go b/upgrades/software/v0.32.0/init.go deleted file mode 100644 index c92faed6f1..0000000000 --- a/upgrades/software/v0.32.0/init.go +++ /dev/null @@ -1,14 +0,0 @@ -// Package v0_32_0 -// nolint revive -package v0_32_0 - -import ( - mv1beta4 "github.com/akash-network/akash-api/go/node/market/v1beta4" - - utypes "github.com/akash-network/node/upgrades/types" -) - -func init() { - utypes.RegisterUpgrade(UpgradeName, initUpgrade) - utypes.RegisterMigration(mv1beta4.ModuleName, 4, newMarketMigration) -} diff --git a/upgrades/software/v0.32.0/market.go b/upgrades/software/v0.32.0/market.go deleted file mode 100644 index d5056951b3..0000000000 --- a/upgrades/software/v0.32.0/market.go +++ /dev/null @@ -1,39 +0,0 @@ -// Package v0_32_0 -// nolint revive -package v0_32_0 - -import ( - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkmodule "github.com/cosmos/cosmos-sdk/types/module" - - utypes "github.com/akash-network/node/upgrades/types" - "github.com/akash-network/node/x/market/keeper/keys/v1beta4" -) - -type marketMigrations struct { - utypes.Migrator -} - -func newMarketMigration(m utypes.Migrator) utypes.Migration { - return marketMigrations{Migrator: m} -} - -func (m marketMigrations) GetHandler() sdkmodule.MigrationHandler { - return m.handler -} - -// handler migrates market from version 3 to 4. -func (m marketMigrations) handler(ctx sdk.Context) error { - store := ctx.KVStore(m.StoreKey()) - iter := sdk.KVStorePrefixIterator(store, types.LeasePrefix()) - defer iter.Close() - for ; iter.Valid(); iter.Next() { - var val types.Lease - m.Codec().MustUnmarshal(iter.Value(), &val) - - store.Delete(v1beta4.SecondaryLeaseKeyByProviderLegacy(val.LeaseID)) - } - - return nil -} diff --git a/upgrades/software/v0.32.0/upgrade.go b/upgrades/software/v0.32.0/upgrade.go deleted file mode 100644 index cf6326cd0e..0000000000 --- a/upgrades/software/v0.32.0/upgrade.go +++ /dev/null @@ -1,47 +0,0 @@ -// Package v0_32_0 -// nolint revive -package v0_32_0 - -import ( - "fmt" - - "github.com/tendermint/tendermint/libs/log" - - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - - apptypes "github.com/akash-network/node/app/types" - utypes "github.com/akash-network/node/upgrades/types" -) - -const ( - UpgradeName = "v0.32.0" -) - -type upgrade struct { - *apptypes.App - log log.Logger -} - -var _ utypes.IUpgrade = (*upgrade)(nil) - -func initUpgrade(log log.Logger, app *apptypes.App) (utypes.IUpgrade, error) { - up := &upgrade{ - App: app, - log: log.With("module", fmt.Sprintf("upgrade/%s", UpgradeName)), - } - - return up, nil -} - -func (up *upgrade) StoreLoader() *storetypes.StoreUpgrades { - return &storetypes.StoreUpgrades{} -} - -func (up *upgrade) UpgradeHandler() upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - return up.MM.RunMigrations(ctx, up.Configurator, fromVM) - } -} diff --git a/upgrades/software/v0.34.0/init.go b/upgrades/software/v0.34.0/init.go deleted file mode 100644 index 85fac9c593..0000000000 --- a/upgrades/software/v0.34.0/init.go +++ /dev/null @@ -1,11 +0,0 @@ -// Package v0_34_0 -// nolint revive -package v0_34_0 - -import ( - utypes "github.com/akash-network/node/upgrades/types" -) - -func init() { - utypes.RegisterUpgrade(UpgradeName, initUpgrade) -} diff --git a/upgrades/software/v0.34.0/upgrade.go b/upgrades/software/v0.34.0/upgrade.go deleted file mode 100644 index 1a20e1ad17..0000000000 --- a/upgrades/software/v0.34.0/upgrade.go +++ /dev/null @@ -1,47 +0,0 @@ -// Package v0_34_0 -// nolint revive -package v0_34_0 - -import ( - "fmt" - - "github.com/tendermint/tendermint/libs/log" - - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - - apptypes "github.com/akash-network/node/app/types" - utypes "github.com/akash-network/node/upgrades/types" -) - -const ( - UpgradeName = "v0.34.0" -) - -type upgrade struct { - *apptypes.App - log log.Logger -} - -var _ utypes.IUpgrade = (*upgrade)(nil) - -func initUpgrade(log log.Logger, app *apptypes.App) (utypes.IUpgrade, error) { - up := &upgrade{ - App: app, - log: log.With("module", fmt.Sprintf("upgrade/%s", UpgradeName)), - } - - return up, nil -} - -func (up *upgrade) StoreLoader() *storetypes.StoreUpgrades { - return &storetypes.StoreUpgrades{} -} - -func (up *upgrade) UpgradeHandler() upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - return up.MM.RunMigrations(ctx, up.Configurator, fromVM) - } -} diff --git a/upgrades/software/v0.36.0/init.go b/upgrades/software/v0.36.0/init.go deleted file mode 100644 index da505525a7..0000000000 --- a/upgrades/software/v0.36.0/init.go +++ /dev/null @@ -1,11 +0,0 @@ -// Package v0_36_0 -// nolint revive -package v0_36_0 - -import ( - utypes "github.com/akash-network/node/upgrades/types" -) - -func init() { - utypes.RegisterUpgrade(UpgradeName, initUpgrade) -} diff --git a/upgrades/software/v0.36.0/upgrade.go b/upgrades/software/v0.36.0/upgrade.go deleted file mode 100644 index 7a342587da..0000000000 --- a/upgrades/software/v0.36.0/upgrade.go +++ /dev/null @@ -1,47 +0,0 @@ -// Package v0_36_0 -// nolint revive -package v0_36_0 - -import ( - "fmt" - - "github.com/tendermint/tendermint/libs/log" - - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - - apptypes "github.com/akash-network/node/app/types" - utypes "github.com/akash-network/node/upgrades/types" -) - -const ( - UpgradeName = "v0.36.0" -) - -type upgrade struct { - *apptypes.App - log log.Logger -} - -var _ utypes.IUpgrade = (*upgrade)(nil) - -func initUpgrade(log log.Logger, app *apptypes.App) (utypes.IUpgrade, error) { - up := &upgrade{ - App: app, - log: log.With("module", fmt.Sprintf("upgrade/%s", UpgradeName)), - } - - return up, nil -} - -func (up *upgrade) StoreLoader() *storetypes.StoreUpgrades { - return &storetypes.StoreUpgrades{} -} - -func (up *upgrade) UpgradeHandler() upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - return up.MM.RunMigrations(ctx, up.Configurator, fromVM) - } -} diff --git a/upgrades/software/v0.38.0/authz.go b/upgrades/software/v0.38.0/authz.go deleted file mode 100644 index 3156b26e0a..0000000000 --- a/upgrades/software/v0.38.0/authz.go +++ /dev/null @@ -1,42 +0,0 @@ -// Package v0_38_0 -// nolint revive -package v0_38_0 - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - sdkmodule "github.com/cosmos/cosmos-sdk/types/module" - - utypes "github.com/akash-network/node/upgrades/types" - - "github.com/cosmos/cosmos-sdk/x/authz/keeper" -) - -type authzMigrations struct { - utypes.Migrator -} - -func newAuthzMigration(m utypes.Migrator) utypes.Migration { - return authzMigrations{Migrator: m} -} - -func (m authzMigrations) GetHandler() sdkmodule.MigrationHandler { - return m.handler -} - -// handler migrates authz from version 1 to 2. -func (m authzMigrations) handler(ctx sdk.Context) error { - store := ctx.KVStore(m.StoreKey()) - - iter := sdk.KVStorePrefixIterator(store, keeper.GrantKey) - - defer func() { - _ = iter.Close() - }() - - for ; iter.Valid(); iter.Next() { - granter, grantee := keeper.AddressesFromGrantStoreKey(iter.Key()) - keeper.IncGranteeGrants(store, grantee, granter) - } - - return nil -} diff --git a/upgrades/software/v0.38.0/cert.go b/upgrades/software/v0.38.0/cert.go deleted file mode 100644 index 3829debeeb..0000000000 --- a/upgrades/software/v0.38.0/cert.go +++ /dev/null @@ -1,68 +0,0 @@ -// Package v0_38_0 -// nolint revive -package v0_38_0 - -import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" - sdkmodule "github.com/cosmos/cosmos-sdk/types/module" - - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" - - utypes "github.com/akash-network/node/upgrades/types" - "github.com/akash-network/node/x/cert/keeper" -) - -type certMigrations struct { - utypes.Migrator -} - -func newCertMigration(m utypes.Migrator) utypes.Migration { - return certMigrations{Migrator: m} -} - -func (m certMigrations) GetHandler() sdkmodule.MigrationHandler { - return m.handler -} - -// handler migrates x/cert from version 2 to 3. -func (m certMigrations) handler(ctx sdk.Context) error { - store := ctx.KVStore(m.StoreKey()) - - iter := sdk.KVStorePrefixIterator(store, types.PrefixCertificateID()) - - defer func() { - _ = iter.Close() - }() - - var total int - - for ; iter.Valid(); iter.Next() { - id, err := keeper.ParseCertIDLegacy(types.PrefixCertificateID(), iter.Key()) - if err != nil { - return err - } - - item := types.Certificate{} - - err = m.Codec().Unmarshal(iter.Value(), &item) - if err != nil { - return err - } - - key, err := keeper.CertificateKey(item.State, id) - if err != nil { - return err - } - - store.Delete(iter.Key()) - store.Set(key, iter.Value()) - - total++ - } - - ctx.Logger().Info(fmt.Sprintf("[upgrade %s]: updated x/cert store keys. total=%d", UpgradeName, total)) - - return nil -} diff --git a/upgrades/software/v0.38.0/deployment.go b/upgrades/software/v0.38.0/deployment.go deleted file mode 100644 index b34ec76ed3..0000000000 --- a/upgrades/software/v0.38.0/deployment.go +++ /dev/null @@ -1,130 +0,0 @@ -// Package v0_38_0 -// nolint revive -package v0_38_0 - -import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" - sdkmodule "github.com/cosmos/cosmos-sdk/types/module" - - dtypesbeta "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - - utypes "github.com/akash-network/node/upgrades/types" - "github.com/akash-network/node/x/deployment/keeper" -) - -type deploymentMigrations struct { - utypes.Migrator -} - -func newDeploymentMigration(m utypes.Migrator) utypes.Migration { - return deploymentMigrations{Migrator: m} -} - -func (m deploymentMigrations) GetHandler() sdkmodule.MigrationHandler { - return m.handler -} - -// handler migrates deployment from version 2 to 3. -func (m deploymentMigrations) handler(ctx sdk.Context) error { - store := ctx.KVStore(m.StoreKey()) - diter := sdk.KVStorePrefixIterator(store, dtypesbeta.DeploymentPrefix()) - - defer func() { - _ = diter.Close() - }() - - var deploymentsTotal uint64 - var deploymentsActive uint64 - var deploymentsClosed uint64 - - for ; diter.Valid(); diter.Next() { - var val dtypesbeta.Deployment - m.Codec().MustUnmarshal(diter.Value(), &val) - - switch val.State { - case dtypesbeta.DeploymentActive: - deploymentsActive++ - case dtypesbeta.DeploymentClosed: - deploymentsClosed++ - default: - return fmt.Errorf("[upgrade %s]: unknown deployment state %d", UpgradeName, val.State) - } - - key, err := keeper.DeploymentKey(keeper.DeploymentStateToPrefix(val.State), val.DeploymentID) - if err != nil { - return err - } - - data, err := m.Codec().Marshal(&val) - if err != nil { - return err - } - - store.Delete(keeper.DeploymentKeyLegacy(val.DeploymentID)) - store.Set(key, data) - - deploymentsTotal++ - } - - giter := sdk.KVStorePrefixIterator(store, dtypesbeta.GroupPrefix()) - - defer func() { - _ = giter.Close() - }() - - var groupsTotal uint64 - var groupsOpen uint64 - var groupsPaused uint64 - var groupsInsufficientFunds uint64 - var groupsClosed uint64 - - for ; giter.Valid(); giter.Next() { - var val dtypesbeta.Group - m.Codec().MustUnmarshal(giter.Value(), &val) - - switch val.State { - case dtypesbeta.GroupOpen: - groupsOpen++ - case dtypesbeta.GroupPaused: - groupsPaused++ - case dtypesbeta.GroupInsufficientFunds: - groupsInsufficientFunds++ - case dtypesbeta.GroupClosed: - groupsClosed++ - default: - return fmt.Errorf("[upgrade %s]: unknown deployment group state %d", UpgradeName, val.State) - } - - key, err := keeper.GroupKey(keeper.GroupStateToPrefix(val.State), val.GroupID) - if err != nil { - return err - } - - data, err := m.Codec().Marshal(&val) - if err != nil { - return err - } - - store.Delete(keeper.GroupKeyLegacy(val.GroupID)) - store.Set(key, data) - - groupsTotal++ - } - - ctx.Logger().Info(fmt.Sprintf("[upgrade %s]: updated x/deployment store keys:"+ - "\n\tdeployments total: %d"+ - "\n\tdeployments active: %d"+ - "\n\tdeployments closed: %d"+ - "\n\tgroups total: %d"+ - "\n\tgroups open: %d"+ - "\n\tgroups paused: %d"+ - "\n\tgroups insufficient funds: %d"+ - "\n\tgroups closed: %d", - UpgradeName, - deploymentsTotal, deploymentsActive, deploymentsClosed, - groupsTotal, groupsOpen, groupsPaused, groupsInsufficientFunds, groupsClosed)) - - return nil -} diff --git a/upgrades/software/v0.38.0/init.go b/upgrades/software/v0.38.0/init.go deleted file mode 100644 index fe6fa0a5d4..0000000000 --- a/upgrades/software/v0.38.0/init.go +++ /dev/null @@ -1,21 +0,0 @@ -// Package v0_38_0 -// nolint revive -package v0_38_0 - -import ( - ctypesbeta "github.com/akash-network/akash-api/go/node/cert/v1beta3" - dv1beta3 "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - mtypesbeta "github.com/akash-network/akash-api/go/node/market/v1beta4" - - "github.com/cosmos/cosmos-sdk/x/authz" - - utypes "github.com/akash-network/node/upgrades/types" -) - -func init() { - utypes.RegisterUpgrade(UpgradeName, initUpgrade) - utypes.RegisterMigration(ctypesbeta.ModuleName, 2, newCertMigration) - utypes.RegisterMigration(mtypesbeta.ModuleName, 5, newMarketMigration) - utypes.RegisterMigration(dv1beta3.ModuleName, 3, newDeploymentMigration) - utypes.RegisterMigration(authz.ModuleName, 1, newAuthzMigration) -} diff --git a/upgrades/software/v0.38.0/upgrade.go b/upgrades/software/v0.38.0/upgrade.go deleted file mode 100644 index 539a60e28d..0000000000 --- a/upgrades/software/v0.38.0/upgrade.go +++ /dev/null @@ -1,47 +0,0 @@ -// Package v0_38_0 -// nolint revive -package v0_38_0 - -import ( - "fmt" - - "github.com/tendermint/tendermint/libs/log" - - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - - apptypes "github.com/akash-network/node/app/types" - utypes "github.com/akash-network/node/upgrades/types" -) - -const ( - UpgradeName = "v0.38.0" -) - -type upgrade struct { - *apptypes.App - log log.Logger -} - -var _ utypes.IUpgrade = (*upgrade)(nil) - -func initUpgrade(log log.Logger, app *apptypes.App) (utypes.IUpgrade, error) { - up := &upgrade{ - App: app, - log: log.With("module", fmt.Sprintf("upgrade/%s", UpgradeName)), - } - - return up, nil -} - -func (up *upgrade) StoreLoader() *storetypes.StoreUpgrades { - return &storetypes.StoreUpgrades{} -} - -func (up *upgrade) UpgradeHandler() upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - return up.MM.RunMigrations(ctx, up.Configurator, fromVM) - } -} diff --git a/upgrades/software/v1.0.0/audit.go b/upgrades/software/v1.0.0/audit.go new file mode 100644 index 0000000000..27608de207 --- /dev/null +++ b/upgrades/software/v1.0.0/audit.go @@ -0,0 +1,56 @@ +// Package v1_0_0 +// nolint revive +package v1_0_0 + +import ( + "cosmossdk.io/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkmodule "github.com/cosmos/cosmos-sdk/types/module" + types "pkg.akt.dev/go/node/audit/v1" + + "pkg.akt.dev/go/node/migrate" + + utypes "pkg.akt.dev/node/upgrades/types" + akeeper "pkg.akt.dev/node/x/audit/keeper" +) + +type auditMigrations struct { + utypes.Migrator +} + +func newAuditMigration(m utypes.Migrator) utypes.Migration { + return auditMigrations{Migrator: m} +} + +func (m auditMigrations) GetHandler() sdkmodule.MigrationHandler { + return m.handler +} + +// handler migrates audit store from version 2 to 3. +func (m auditMigrations) handler(ctx sdk.Context) (err error) { + cdc := m.Codec() + + store := ctx.KVStore(m.StoreKey()) + oStore := prefix.NewStore(store, migrate.AuditedAttributesV1beta3Prefix()) + + iter := oStore.Iterator(nil, nil) + defer func() { + err = iter.Close() + }() + + for ; iter.Valid(); iter.Next() { + val := migrate.AuditedProviderFromV1beta3(cdc, iter.Value()) + + owner := sdk.MustAccAddressFromBech32(val.Owner) + auditor := sdk.MustAccAddressFromBech32(val.Auditor) + + key := akeeper.ProviderKey(types.ProviderID{Owner: owner, Auditor: auditor}) + + bz := cdc.MustMarshal(&types.AuditedAttributesStore{Attributes: val.Attributes}) + + oStore.Delete(iter.Key()) + store.Set(key, bz) + } + + return nil +} diff --git a/upgrades/software/v1.0.0/cert.go b/upgrades/software/v1.0.0/cert.go new file mode 100644 index 0000000000..b9ec7eafe2 --- /dev/null +++ b/upgrades/software/v1.0.0/cert.go @@ -0,0 +1,54 @@ +// Package v1_0_0 +// nolint revive +package v1_0_0 + +import ( + "cosmossdk.io/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkmodule "github.com/cosmos/cosmos-sdk/types/module" + "pkg.akt.dev/go/node/migrate" + + utypes "pkg.akt.dev/node/upgrades/types" + ckeeper "pkg.akt.dev/node/x/cert/keeper" +) + +type certsMigrations struct { + utypes.Migrator +} + +func newCertsMigration(m utypes.Migrator) utypes.Migration { + return certsMigrations{Migrator: m} +} + +func (m certsMigrations) GetHandler() sdkmodule.MigrationHandler { + return m.handler +} + +// handler migrates certificates store from version 2 to 3. +func (m certsMigrations) handler(ctx sdk.Context) (err error) { + cdc := m.Codec() + + store := ctx.KVStore(m.StoreKey()) + oStore := prefix.NewStore(store, migrate.CertV1beta3Prefix()) + + iter := oStore.Iterator(nil, nil) + defer func() { + err = iter.Close() + }() + + for ; iter.Valid(); iter.Next() { + val := migrate.CertFromV1beta3(cdc, iter.Value()) + + id, err := ckeeper.ParseCertID(nil, iter.Key()) + if err != nil { + return err + } + + bz := cdc.MustMarshal(&val) + key := ckeeper.MustCertificateKey(val.State, id) + oStore.Delete(iter.Key()) + store.Set(key, bz) + } + + return nil +} diff --git a/upgrades/software/v1.0.0/deployment.go b/upgrades/software/v1.0.0/deployment.go new file mode 100644 index 0000000000..f3085bd6ed --- /dev/null +++ b/upgrades/software/v1.0.0/deployment.go @@ -0,0 +1,123 @@ +// Package v1_0_0 +// nolint revive +package v1_0_0 + +import ( + "fmt" + + "cosmossdk.io/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkmodule "github.com/cosmos/cosmos-sdk/types/module" + dv1 "pkg.akt.dev/go/node/deployment/v1" + dv1beta "pkg.akt.dev/go/node/deployment/v1beta4" + "pkg.akt.dev/go/node/migrate" + + utypes "pkg.akt.dev/node/upgrades/types" + dkeeper "pkg.akt.dev/node/x/deployment/keeper" +) + +type deploymentsMigrations struct { + utypes.Migrator +} + +func newDeploymentsMigration(m utypes.Migrator) utypes.Migration { + return deploymentsMigrations{Migrator: m} +} + +func (m deploymentsMigrations) GetHandler() sdkmodule.MigrationHandler { + return m.handler +} + +// handler migrates deployment store from version 4 to 5 +func (m deploymentsMigrations) handler(ctx sdk.Context) error { + store := ctx.KVStore(m.StoreKey()) + + // deployment prefix does not change in this upgrade + oStore := prefix.NewStore(store, dkeeper.DeploymentPrefix) + + iter := oStore.Iterator(nil, nil) + defer func() { + _ = iter.Close() + }() + + var deploymentsTotal uint64 + var deploymentsActive uint64 + var deploymentsClosed uint64 + + cdc := m.Codec() + + for ; iter.Valid(); iter.Next() { + nVal := migrate.DeploymentFromV1beta3(cdc, iter.Value()) + bz := cdc.MustMarshal(&nVal) + + switch nVal.State { + case dv1.DeploymentActive: + deploymentsActive++ + case dv1.DeploymentClosed: + deploymentsClosed++ + default: + return fmt.Errorf("unknown order state %d", nVal.State) + } + + deploymentsTotal++ + + key := dkeeper.MustDeploymentKey(dkeeper.DeploymentStateToPrefix(nVal.State), nVal.ID) + + oStore.Delete(iter.Key()) + store.Set(key, bz) + } + + // group prefix does not change in this upgrade + oStore = prefix.NewStore(store, dkeeper.GroupPrefix) + + iter = oStore.Iterator(nil, nil) + defer func() { + _ = iter.Close() + }() + + var groupsTotal uint64 + var groupsOpen uint64 + var groupsPaused uint64 + var groupsInsufficientFunds uint64 + var groupsClosed uint64 + + for ; iter.Valid(); iter.Next() { + nVal := migrate.GroupFromV1Beta3(cdc, iter.Value()) + bz := cdc.MustMarshal(&nVal) + + switch nVal.State { + case dv1beta.GroupOpen: + groupsOpen++ + case dv1beta.GroupPaused: + groupsPaused++ + case dv1beta.GroupInsufficientFunds: + groupsInsufficientFunds++ + case dv1beta.GroupClosed: + groupsClosed++ + default: + return fmt.Errorf("unknown order state %d", nVal.State) + } + + groupsTotal++ + + key := dkeeper.MustGroupKey(dkeeper.GroupStateToPrefix(nVal.State), nVal.ID) + + oStore.Delete(iter.Key()) + store.Set(key, bz) + } + + ctx.Logger().Info(fmt.Sprintf("[upgrade %s]: updated x/deployment store keys:"+ + "\n\tdeployments total: %d"+ + "\n\tdeployments active: %d"+ + "\n\tdeployments closed: %d"+ + "\n\tgroups total: %d"+ + "\n\tgroups open: %d"+ + "\n\tgroups paused: %d"+ + "\n\tgroups insufficient funds: %d"+ + "\n\tgroups closed: %d", + UpgradeName, + deploymentsTotal, deploymentsActive, deploymentsClosed, + groupsTotal, groupsOpen, groupsPaused, groupsInsufficientFunds, groupsClosed)) + + return nil +} diff --git a/upgrades/software/v1.0.0/escrow.go b/upgrades/software/v1.0.0/escrow.go new file mode 100644 index 0000000000..60bf5563e8 --- /dev/null +++ b/upgrades/software/v1.0.0/escrow.go @@ -0,0 +1,120 @@ +// Package v1_0_0 +// nolint revive +package v1_0_0 + +import ( + "fmt" + + "cosmossdk.io/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkmodule "github.com/cosmos/cosmos-sdk/types/module" + etypes "pkg.akt.dev/go/node/escrow/types/v1" + "pkg.akt.dev/go/node/migrate" + + utypes "pkg.akt.dev/node/upgrades/types" + ekeeper "pkg.akt.dev/node/x/escrow/keeper" +) + +type escrowMigrations struct { + utypes.Migrator +} + +func newEscrowMigration(m utypes.Migrator) utypes.Migration { + return escrowMigrations{Migrator: m} +} + +func (m escrowMigrations) GetHandler() sdkmodule.MigrationHandler { + return m.handler +} + +// handler migrates escrow store from version 2 to 3. +func (m escrowMigrations) handler(ctx sdk.Context) error { + store := ctx.KVStore(m.StoreKey()) + + oStore := prefix.NewStore(store, migrate.AccountV1beta3Prefix()) + + iter := oStore.Iterator(nil, nil) + defer func() { + _ = iter.Close() + }() + + cdc := m.Codec() + + var accountsTotal uint64 + var accountsActive uint64 + var accountsClosed uint64 + var accountsOverdrawn uint64 + + for ; iter.Valid(); iter.Next() { + key := append(migrate.AccountV1beta3Prefix(), iter.Key()...) + + nVal := migrate.AccountFromV1beta3(cdc, key, iter.Value()) + bz := cdc.MustMarshal(&nVal.State) + + switch nVal.State.State { + case etypes.StateOpen: + accountsActive++ + case etypes.StateClosed: + accountsClosed++ + case etypes.StateOverdrawn: + accountsOverdrawn++ + } + + accountsTotal++ + + oStore.Delete(key) + + key = ekeeper.BuildAccountsKey(nVal.State.State, &nVal.ID) + store.Set(key, bz) + } + + oStore = prefix.NewStore(store, migrate.PaymentV1beta3Prefix()) + + iter = oStore.Iterator(nil, nil) + defer func() { + _ = iter.Close() + }() + + var paymentsTotal uint64 + var paymentsActive uint64 + var paymentsClosed uint64 + var paymentsOverdrawn uint64 + + for ; iter.Valid(); iter.Next() { + key := append(migrate.PaymentV1beta3Prefix(), iter.Key()...) + + nVal := migrate.PaymentFromV1beta3(cdc, key, iter.Value()) + bz := cdc.MustMarshal(&nVal.State) + + switch nVal.State.State { + case etypes.StateOpen: + paymentsActive++ + case etypes.StateClosed: + paymentsClosed++ + case etypes.StateOverdrawn: + paymentsOverdrawn++ + } + + paymentsTotal++ + + oStore.Delete(key) + + key = ekeeper.BuildPaymentsKey(nVal.State.State, &nVal.ID) + store.Set(key, bz) + } + + ctx.Logger().Info(fmt.Sprintf("[upgrade %s]: updated x/escrow store keys:"+ + "\n\taccounts total: %d"+ + "\n\taccounts open: %d"+ + "\n\taccounts closed: %d"+ + "\n\taccounts overdrawn: %d"+ + "\n\tpayments total: %d"+ + "\n\tpayments open: %d"+ + "\n\tpayments closed: %d"+ + "\n\tpayments overdrawn: %d", + UpgradeName, + accountsTotal, accountsActive, accountsClosed, accountsOverdrawn, + paymentsTotal, paymentsActive, paymentsClosed, paymentsOverdrawn)) + + return nil +} diff --git a/upgrades/software/v1.0.0/init.go b/upgrades/software/v1.0.0/init.go new file mode 100644 index 0000000000..94567250d0 --- /dev/null +++ b/upgrades/software/v1.0.0/init.go @@ -0,0 +1,27 @@ +// Package v1_0_0 +// nolint revive +package v1_0_0 + +import ( + av1 "pkg.akt.dev/go/node/audit/v1" + cv1 "pkg.akt.dev/go/node/cert/v1" + dv1 "pkg.akt.dev/go/node/deployment/v1" + emodule "pkg.akt.dev/go/node/escrow/module" + mv1 "pkg.akt.dev/go/node/market/v1" + pv1 "pkg.akt.dev/go/node/provider/v1beta4" + tv1 "pkg.akt.dev/go/node/take/v1" + + utypes "pkg.akt.dev/node/upgrades/types" +) + +func init() { + utypes.RegisterUpgrade(UpgradeName, initUpgrade) + + utypes.RegisterMigration(av1.ModuleName, 2, newAuditMigration) + utypes.RegisterMigration(cv1.ModuleName, 3, newCertsMigration) + utypes.RegisterMigration(dv1.ModuleName, 4, newDeploymentsMigration) + utypes.RegisterMigration(emodule.ModuleName, 2, newEscrowMigration) + utypes.RegisterMigration(mv1.ModuleName, 6, newMarketMigration) + utypes.RegisterMigration(pv1.ModuleName, 2, newProviderMigration) + utypes.RegisterMigration(tv1.ModuleName, 2, newTakeMigration) +} diff --git a/upgrades/software/v0.38.0/market.go b/upgrades/software/v1.0.0/market.go similarity index 53% rename from upgrades/software/v0.38.0/market.go rename to upgrades/software/v1.0.0/market.go index fc21538268..6274f2caf0 100644 --- a/upgrades/software/v0.38.0/market.go +++ b/upgrades/software/v1.0.0/market.go @@ -1,17 +1,20 @@ -// Package v0_38_0 +// Package v1_0_0 // nolint revive -package v0_38_0 +package v1_0_0 import ( "fmt" + storetypes "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkmodule "github.com/cosmos/cosmos-sdk/types/module" + mv1 "pkg.akt.dev/go/node/market/v1" + mv1beta "pkg.akt.dev/go/node/market/v1beta5" - mtypesbeta "github.com/akash-network/akash-api/go/node/market/v1beta4" + "pkg.akt.dev/go/node/migrate" - utypes "github.com/akash-network/node/upgrades/types" - "github.com/akash-network/node/x/market/keeper/keys/v1beta4" + utypes "pkg.akt.dev/node/upgrades/types" + mkeys "pkg.akt.dev/node/x/market/keeper/keys" ) type marketMigrations struct { @@ -26,10 +29,14 @@ func (m marketMigrations) GetHandler() sdkmodule.MigrationHandler { return m.handler } -// handler migrates market from version 5 to 6. +// handler migrates market from version 6 to 7. func (m marketMigrations) handler(ctx sdk.Context) error { store := ctx.KVStore(m.StoreKey()) - oiter := sdk.KVStorePrefixIterator(store, mtypesbeta.OrderPrefix()) + + cdc := m.Codec() + + // order prefix does not change in this upgrade + oiter := storetypes.KVStorePrefixIterator(store, mkeys.OrderPrefix) defer func() { _ = oiter.Close() }() @@ -38,42 +45,34 @@ func (m marketMigrations) handler(ctx sdk.Context) error { var ordersOpen uint64 var ordersActive uint64 var ordersClosed uint64 + for ; oiter.Valid(); oiter.Next() { - var val mtypesbeta.Order - m.Codec().MustUnmarshal(oiter.Value(), &val) + nVal := migrate.OrderFromV1beta4(cdc, oiter.Value()) - var state []byte - switch val.State { - case mtypesbeta.OrderOpen: - state = v1beta4.OrderStateOpenPrefix + switch nVal.State { + case mv1beta.OrderOpen: ordersOpen++ - case mtypesbeta.OrderActive: - state = v1beta4.OrderStateActivePrefix + case mv1beta.OrderActive: ordersActive++ - case mtypesbeta.OrderClosed: - state = v1beta4.OrderStateClosedPrefix + case mv1beta.OrderClosed: ordersClosed++ default: - panic(fmt.Sprintf("unknown order state %d", val.State)) + return fmt.Errorf("unknown order state %d", nVal.State) } ordersTotal++ - store.Delete(v1beta4.OrderKeyLegacy(val.OrderID)) - key, err := v1beta4.OrderKey(state, val.OrderID) - if err != nil { - return err - } + bz := cdc.MustMarshal(&nVal) - data, err := m.Codec().Marshal(&val) - if err != nil { - return err - } + store.Delete(oiter.Key()) - store.Set(key, data) + key := mkeys.MustOrderKey(mkeys.OrderStateToPrefix(nVal.State), nVal.ID) + store.Set(key, bz) } - biter := sdk.KVStorePrefixIterator(store, mtypesbeta.BidPrefix()) + // bid prefixes do not change in this upgrade + store.Delete(mkeys.BidPrefixReverse) + biter := storetypes.KVStorePrefixIterator(store, mkeys.BidPrefix) defer func() { _ = biter.Close() }() @@ -85,37 +84,37 @@ func (m marketMigrations) handler(ctx sdk.Context) error { var bidsClosed uint64 for ; biter.Valid(); biter.Next() { - var val mtypesbeta.Bid - m.Codec().MustUnmarshal(biter.Value(), &val) + nVal := migrate.BidFromV1beta4(cdc, biter.Value()) - switch val.State { - case mtypesbeta.BidOpen: + switch nVal.State { + case mv1beta.BidOpen: bidsOpen++ - case mtypesbeta.BidActive: + case mv1beta.BidActive: bidsActive++ - case mtypesbeta.BidLost: + case mv1beta.BidLost: bidsLost++ - case mtypesbeta.BidClosed: + case mv1beta.BidClosed: bidsClosed++ default: - panic(fmt.Sprintf("unknown order state %d", val.State)) + panic(fmt.Sprintf("unknown order state %d", nVal.State)) } bidsTotal++ - store.Delete(v1beta4.BidKeyLegacy(val.BidID)) - data, err := m.Codec().Marshal(&val) + store.Delete(biter.Key()) + + data, err := m.Codec().Marshal(&nVal) if err != nil { return err } - state := v1beta4.BidStateToPrefix(val.State) - key, err := v1beta4.BidKey(state, val.BidID) + state := mkeys.BidStateToPrefix(nVal.State) + key, err := mkeys.BidKey(state, nVal.ID) if err != nil { return err } - revKey, err := v1beta4.BidStateReverseKey(val.State, val.BidID) + revKey, err := mkeys.BidReverseKey(state, nVal.ID) if err != nil { return err } @@ -126,7 +125,9 @@ func (m marketMigrations) handler(ctx sdk.Context) error { } } - liter := sdk.KVStorePrefixIterator(store, mtypesbeta.LeasePrefix()) + // lease prefixes do not change in this upgrade + store.Delete(mkeys.LeasePrefixReverse) + liter := storetypes.KVStorePrefixIterator(store, mkeys.LeasePrefix) defer func() { _ = liter.Close() }() @@ -137,35 +138,34 @@ func (m marketMigrations) handler(ctx sdk.Context) error { var leasesClosed uint64 for ; liter.Valid(); liter.Next() { - var val mtypesbeta.Lease - m.Codec().MustUnmarshal(liter.Value(), &val) + nVal := migrate.LeaseFromV1beta4(cdc, liter.Value()) - switch val.State { - case mtypesbeta.LeaseActive: + switch nVal.State { + case mv1.LeaseActive: leasesActive++ - case mtypesbeta.LeaseInsufficientFunds: + case mv1.LeaseInsufficientFunds: leasesInsufficientFunds++ - case mtypesbeta.LeaseClosed: + case mv1.LeaseClosed: leasesClosed++ default: - panic(fmt.Sprintf("unknown order state %d", val.State)) + panic(fmt.Sprintf("unknown order state %d", nVal.State)) } leasesTotal++ - store.Delete(v1beta4.LeaseKeyLegacy(val.LeaseID)) + store.Delete(liter.Key()) - data, err := m.Codec().Marshal(&val) + data, err := m.Codec().Marshal(&nVal) if err != nil { return err } - state := v1beta4.LeaseStateToPrefix(val.State) - key, err := v1beta4.LeaseKey(state, val.LeaseID) + state := mkeys.LeaseStateToPrefix(nVal.State) + key, err := mkeys.LeaseKey(state, nVal.ID) if err != nil { return err } - revKey, err := v1beta4.LeaseStateReverseKey(val.State, val.LeaseID) + revKey, err := mkeys.LeaseReverseKey(state, nVal.ID) if err != nil { return err } diff --git a/upgrades/software/v1.0.0/provider.go b/upgrades/software/v1.0.0/provider.go new file mode 100644 index 0000000000..50d2c77920 --- /dev/null +++ b/upgrades/software/v1.0.0/provider.go @@ -0,0 +1,65 @@ +// Package v1_0_0 +// nolint revive +package v1_0_0 + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + sdkmodule "github.com/cosmos/cosmos-sdk/types/module" + "pkg.akt.dev/go/node/migrate" + "pkg.akt.dev/go/sdkutil" + + utypes "pkg.akt.dev/node/upgrades/types" + pkeeper "pkg.akt.dev/node/x/provider/keeper" +) + +type providerMigrations struct { + utypes.Migrator +} + +func newProviderMigration(m utypes.Migrator) utypes.Migration { + return providerMigrations{Migrator: m} +} + +func (m providerMigrations) GetHandler() sdkmodule.MigrationHandler { + return m.handler +} + +func ProviderKey(id sdk.Address) []byte { + return address.MustLengthPrefix(id.Bytes()) +} + +// handler migrates provider store from version 2 to 3. +func (m providerMigrations) handler(ctx sdk.Context) (err error) { + store := ctx.KVStore(m.StoreKey()) + + iter := store.Iterator(nil, nil) + defer func() { + err = iter.Close() + }() + + cdc := m.Codec() + + var providersTotal uint64 + + for ; iter.Valid(); iter.Next() { + to := migrate.ProviderFromV1beta3(cdc, iter.Value()) + + id := sdkutil.MustAccAddressFromBech32(to.Owner) + bz := cdc.MustMarshal(&to) + + providersTotal++ + + store.Delete(iter.Key()) + store.Set(pkeeper.ProviderKey(id), bz) + } + + ctx.Logger().Info(fmt.Sprintf("[upgrade %s]: updated x/provider store keys:"+ + "\n\tproviders total: %d", + UpgradeName, + providersTotal)) + + return nil +} diff --git a/upgrades/software/v1.0.0/take.go b/upgrades/software/v1.0.0/take.go new file mode 100644 index 0000000000..ef06f2e2a4 --- /dev/null +++ b/upgrades/software/v1.0.0/take.go @@ -0,0 +1,27 @@ +// Package v1_0_0 +// nolint revive +package v1_0_0 + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkmodule "github.com/cosmos/cosmos-sdk/types/module" + + utypes "pkg.akt.dev/node/upgrades/types" +) + +type takeMigrations struct { + utypes.Migrator +} + +func newTakeMigration(m utypes.Migrator) utypes.Migration { + return takeMigrations{Migrator: m} +} + +func (m takeMigrations) GetHandler() sdkmodule.MigrationHandler { + return m.handler +} + +// handler migrates provider store from version 2 to 3. +func (m takeMigrations) handler(_ sdk.Context) error { + return nil +} diff --git a/upgrades/software/v1.0.0/upgrade.go b/upgrades/software/v1.0.0/upgrade.go new file mode 100644 index 0000000000..06dc36c2a3 --- /dev/null +++ b/upgrades/software/v1.0.0/upgrade.go @@ -0,0 +1,346 @@ +// Package v1_0_0 +// nolint revive +package v1_0_0 + +import ( + "context" + "fmt" + "reflect" + "time" + + "cosmossdk.io/log" + sdkmath "cosmossdk.io/math" + storetypes "cosmossdk.io/store/types" + upgradetypes "cosmossdk.io/x/upgrade/types" + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" + "github.com/cosmos/cosmos-sdk/x/authz" + consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types" + crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + dv1 "pkg.akt.dev/go/node/deployment/v1" + dv1beta3 "pkg.akt.dev/go/node/deployment/v1beta3" + dv1beta "pkg.akt.dev/go/node/deployment/v1beta4" + ev1 "pkg.akt.dev/go/node/escrow/v1" + agovtypes "pkg.akt.dev/go/node/gov/v1beta3" + mv1 "pkg.akt.dev/go/node/market/v1" + mv1beta4 "pkg.akt.dev/go/node/market/v1beta4" + mv1beta "pkg.akt.dev/go/node/market/v1beta5" + astakingtypes "pkg.akt.dev/go/node/staking/v1beta3" + taketypes "pkg.akt.dev/go/node/take/v1" + + apptypes "pkg.akt.dev/node/app/types" + utypes "pkg.akt.dev/node/upgrades/types" +) + +const ( + UpgradeName = "v1.0.0" +) + +type upgrade struct { + *apptypes.App + log log.Logger +} + +var _ utypes.IUpgrade = (*upgrade)(nil) + +func initUpgrade(log log.Logger, app *apptypes.App) (utypes.IUpgrade, error) { + up := &upgrade{ + App: app, + log: log.With("module", fmt.Sprintf("upgrade/%s", UpgradeName)), + } + + return up, nil +} + +func (up *upgrade) StoreLoader() *storetypes.StoreUpgrades { + return &storetypes.StoreUpgrades{ + Added: []string{ + // With the migrations of all modules away from x/params, the crisis module now has a store. + // The store must be created during a chain upgrade to v0.53.x. + consensustypes.ModuleName, + }, + Deleted: []string{ + "agov", + "astaking", + crisistypes.ModuleName, + }, + } +} + +type AccountKeeper interface { + NewAccount(sdk.Context, sdk.AccountI) sdk.AccountI + + GetAccount(ctx sdk.Context, addr sdk.AccAddress) sdk.AccountI + SetAccount(ctx sdk.Context, acc sdk.AccountI) +} + +// AkashUtilsExtraAccountTypes is a map of extra account types that can be overridden. +// This is defined as a global variable, so it can be modified in the chain's app.go and used here without +// having to import the chain. Specifically, this is used for compatibility with Akash' Cosmos SDK fork +var AkashUtilsExtraAccountTypes map[reflect.Type]struct{} + +// CanCreateModuleAccountAtAddr tells us if we can safely make a module account at +// a given address. By collision resistance of the address (given API safe construction), +// the only way for an account to be already be at this address is if its claimed by the same +// pre-image from the correct module, +// or some SDK command breaks assumptions and creates an account at designated address. +// This function checks if there is an account at that address, and runs some safety checks +// to be extra-sure its not a user account (e.g. non-zero sequence, pubkey, of fore-seen account types). +// If there is no account, or if we believe its not a user-spendable account, we allow module account +// creation at the address. +// else, we do not. +// +// TODO: This is generally from an SDK design flaw +// code based off wasmd code: https://github.com/CosmWasm/wasmd/pull/996 +// Its _mandatory_ that the caller do the API safe construction to generate a module account addr, +// namely, address.Module(ModuleName, {key}) +func CanCreateModuleAccountAtAddr(ctx sdk.Context, ak AccountKeeper, addr sdk.AccAddress) error { + existingAcct := ak.GetAccount(ctx, addr) + if existingAcct == nil { + return nil + } + if existingAcct.GetSequence() != 0 || existingAcct.GetPubKey() != nil { + return fmt.Errorf("cannot create module account %s, "+ + "due to an account at that address already existing & having sent txs", addr) + } + overrideAccountTypes := map[reflect.Type]struct{}{ + reflect.TypeOf(&authtypes.BaseAccount{}): {}, + reflect.TypeOf(&vestingtypes.DelayedVestingAccount{}): {}, + reflect.TypeOf(&vestingtypes.ContinuousVestingAccount{}): {}, + reflect.TypeOf(&vestingtypes.BaseVestingAccount{}): {}, + reflect.TypeOf(&vestingtypes.PeriodicVestingAccount{}): {}, + reflect.TypeOf(&vestingtypes.PermanentLockedAccount{}): {}, + } + for extraAccountType := range AkashUtilsExtraAccountTypes { + overrideAccountTypes[extraAccountType] = struct{}{} + } + + if _, isClear := overrideAccountTypes[reflect.TypeOf(existingAcct)]; isClear { + return nil + } + + return fmt.Errorf("cannot create module account %s, "+ + "due to an account at that address already existing & not being an overridable type", existingAcct) +} + +// CreateModuleAccountByName creates a module account at the provided name +func CreateModuleAccountByName(ctx sdk.Context, ak AccountKeeper, name string) error { + addr := authtypes.NewModuleAddress(name) + err := CanCreateModuleAccountAtAddr(ctx, ak, addr) + if err != nil { + return err + } + + acc := ak.NewAccount( + ctx, + authtypes.NewModuleAccount( + authtypes.NewBaseAccountWithAddress(addr), + name, + ), + ) + ak.SetAccount(ctx, acc) + return nil +} + +func (up *upgrade) UpgradeHandler() upgradetypes.UpgradeHandler { + baseAppLegacySS := up.Keepers.Cosmos.Params.Subspace(baseapp.Paramspace).WithKeyTable(paramstypes.ConsensusParamsKeyTable()) + + return func(ctx context.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + // Migrate Tendermint consensus parameters from x/params module to a + // dedicated x/consensus module. + sctx := sdk.UnwrapSDKContext(ctx) + + err := baseapp.MigrateParams(sctx, baseAppLegacySS, up.Keepers.Cosmos.ConsensusParams.ParamsStore) + if err != nil { + return nil, err + } + sspace, exists := up.Keepers.Cosmos.Params.GetSubspace(stakingtypes.ModuleName) + if !exists { + return nil, fmt.Errorf("params subspace \"%s\" not found", stakingtypes.ModuleName) + } + + up.log.Info("migrating x/take to self-managed params") + sspace, exists = up.Keepers.Cosmos.Params.GetSubspace(taketypes.ModuleName) + if !exists { + return nil, fmt.Errorf("params subspace \"%s\" not found", taketypes.ModuleName) + } + + tparams := taketypes.Params{} + sspace.Get(sctx, taketypes.KeyDefaultTakeRate, &tparams.DefaultTakeRate) + sspace.Get(sctx, taketypes.KeyDenomTakeRates, &tparams.DenomTakeRates) + + err = up.Keepers.Akash.Take.SetParams(sctx, tparams) + if err != nil { + return nil, err + } + + up.log.Info("migrating x/deployment to self-managed params") + sspace, exists = up.Keepers.Cosmos.Params.GetSubspace(dv1.ModuleName) + if !exists { + return nil, fmt.Errorf("params subspace \"%s\" not found", dv1.ModuleName) + } + + deplParams := &dv1beta3.Params{} + sspace.GetParamSet(sctx, deplParams) + + nDeplParams := dv1beta.Params{ + MinDeposits: make(sdk.Coins, 0, len(deplParams.MinDeposits)), + } + + for _, coin := range deplParams.MinDeposits { + nDeplParams.MinDeposits = append(nDeplParams.MinDeposits, sdk.Coin{ + Denom: coin.Denom, + Amount: sdkmath.NewIntFromBigInt(coin.Amount.BigInt()), + }) + } + err = up.Keepers.Akash.Deployment.SetParams(sctx, nDeplParams) + if err != nil { + return nil, err + } + + up.log.Info("migrating x/market to self-managed params") + sspace, exists = up.Keepers.Cosmos.Params.GetSubspace(mv1.ModuleName) + if !exists { + return nil, fmt.Errorf("params subspace \"%s\" not found", mv1.ModuleName) + } + + mParams := &mv1beta4.Params{} + sspace.GetParamSet(sctx, mParams) + + err = up.Keepers.Akash.Market.SetParams(sctx, mv1beta.Params{ + BidMinDeposit: mParams.BidMinDeposit, + OrderMaxBids: mParams.OrderMaxBids, + }) + if err != nil { + return nil, err + } + + sspace, exists = up.Keepers.Cosmos.Params.GetSubspace("agov") + if !exists { + return nil, fmt.Errorf("params subspace \"%s\" not found", "agov") + } + + dparams := agovtypes.DepositParams{} + sspace.Get(sctx, agovtypes.KeyDepositParams, &dparams) + + sspace, exists = up.Keepers.Cosmos.Params.GetSubspace(astakingtypes.ModuleName) + if !exists { + return nil, fmt.Errorf("params subspace \"%s\" not found", astakingtypes.ModuleName) + } + + sparam := sdkmath.LegacyDec{} + sspace.Get(sctx, astakingtypes.KeyMinCommissionRate, &sparam) + + toVM, err := up.MM.RunMigrations(ctx, up.Configurator, fromVM) + if err != nil { + return nil, err + } + + // patch deposit authorizations after authz store upgrade + err = up.patchDepositAuthorizations(sctx) + if err != nil { + return nil, err + } + + up.log.Info(fmt.Sprintf("migrating param agov.MinInitialDepositRate to gov.MinInitialDepositRatio")) + up.log.Info(fmt.Sprintf("setting gov.ExpeditedMinDeposit to 2000akt")) + up.log.Info(fmt.Sprintf("setting gov.ExpeditedThreshold to 67%%")) + + // Migrate governance min deposit parameter to builtin gov params + gparams, err := up.Keepers.Cosmos.Gov.Params.Get(ctx) + if err != nil { + return nil, err + } + + gparams.MinInitialDepositRatio = dparams.MinInitialDepositRate.String() + + // min deposit for an expedited proposal is set to 2000AKT + gparams.ExpeditedMinDeposit = sdk.NewCoins(sdk.NewCoin("uakt", sdkmath.NewInt(2000000000))) + gparams.ExpeditedThreshold = sdkmath.LegacyNewDecWithPrec(667, 3).String() + + eVotePeriod := time.Hour * 24 + gparams.ExpeditedVotingPeriod = &eVotePeriod + + err = up.Keepers.Cosmos.Gov.Params.Set(ctx, gparams) + if err != nil { + return nil, err + } + + up.log.Info(fmt.Sprintf("migrating param astaking.MinCommissionRate to staking.MinCommissionRate")) + sparams, err := up.Keepers.Cosmos.Staking.GetParams(sctx) + if err != nil { + return nil, err + } + sparams.MinCommissionRate = sparam + + err = up.Keepers.Cosmos.Staking.SetParams(ctx, sparams) + if err != nil { + return nil, err + } + + up.log.Info(fmt.Sprintf("all migrations have been completed")) + + return toVM, err + } +} + +func (up *upgrade) patchDepositAuthorizations(ctx sdk.Context) error { + msgUrlOld := "/akash.deployment.v1beta3.MsgDepositDeployment" + + var err error + up.log.Info(fmt.Sprintf("migrating \"%s\" to \"%s\"", msgUrlOld, (&ev1.DepositAuthorization{}).MsgTypeURL())) + up.Keepers.Cosmos.Authz.IterateGrants(ctx, func(granterAddr sdk.AccAddress, granteeAddr sdk.AccAddress, grant authz.Grant) bool { + var authorization authz.Authorization + authorization, err = grant.GetAuthorization() + if err != nil { + up.log.Error(fmt.Sprintf("unable to get authorization. err=%s", err.Error())) + return false + } + + var nAuthz authz.Authorization + + switch authorization.MsgTypeURL() { + case msgUrlOld: + authzOld, valid := authorization.(*dv1beta3.DepositDeploymentAuthorization) + if !valid { + up.log.Error(fmt.Sprintf("invalid authorization type %s", reflect.TypeOf(authorization).String())) + return false + } + nAuthz = ev1.NewDepositAuthorization(ev1.DepositAuthorizationScopes{ev1.DepositScopeDeployment}, authzOld.SpendLimit) + default: + return false + } + + err = up.Keepers.Cosmos.Authz.DeleteGrant(ctx, granteeAddr, granterAddr, authorization.MsgTypeURL()) + if err != nil { + up.log.Error(fmt.Sprintf("unable to delete autorization. err=%s", err.Error())) + return false + } + + err = up.Keepers.Cosmos.Authz.SaveGrant(ctx, granteeAddr, granterAddr, nAuthz, grant.Expiration) + if err != nil { + up.log.Error(fmt.Sprintf("unable to save autorization. err=%s", err.Error())) + return true + } + + return false + }) + if err != nil { + return err + } + + up.log.Info("cleaning expired grants") + err = up.Keepers.Cosmos.Authz.DequeueAndDeleteExpiredGrants(ctx) + if err != nil { + return err + } + up.log.Info("cleaning expired grants - DONE") + + return nil +} diff --git a/upgrades/types/helpers.go b/upgrades/types/helpers.go index 0ce8206594..779ea233a2 100644 --- a/upgrades/types/helpers.go +++ b/upgrades/types/helpers.go @@ -1,26 +1,32 @@ +//nolint: revive + package types import ( + "cosmossdk.io/store/prefix" + storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store/prefix" - sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/gogoproto/proto" ) // ValueMigrator migrates a value to the new protobuf type given its old protobuf serialized bytes. -type ValueMigrator func(oldValueBz []byte, cdc codec.BinaryCodec) codec.ProtoMarshaler +type ValueMigrator func(fromBz []byte, cdc codec.BinaryCodec) proto.Message // MigrateValue is a helper function that migrates values stored in a KV store for the given // key prefix using the given value migrator function. -func MigrateValue(store sdk.KVStore, cdc codec.BinaryCodec, prefixBz []byte, migrator ValueMigrator) (err error) { +func MigrateValue(store storetypes.KVStore, cdc codec.BinaryCodec, prefixBz []byte, pStart, pEnd []byte, migrator ValueMigrator) (err error) { pStore := prefix.NewStore(store, prefixBz) - iter := pStore.Iterator(nil, nil) + iter := pStore.Iterator(pStart, pEnd) defer func() { err = iter.Close() }() for ; iter.Valid(); iter.Next() { - pStore.Set(iter.Key(), cdc.MustMarshal(migrator(iter.Value(), cdc))) + nVal := migrator(iter.Value(), cdc) + bz := cdc.MustMarshal(nVal) + + pStore.Set(iter.Key(), bz) } return nil diff --git a/upgrades/types/types.go b/upgrades/types/types.go index ec2e01563b..cbd69bca1d 100644 --- a/upgrades/types/types.go +++ b/upgrades/types/types.go @@ -3,15 +3,14 @@ package types import ( "fmt" + "cosmossdk.io/log" + storetypes "cosmossdk.io/store/types" + upgradetypes "cosmossdk.io/x/upgrade/types" "github.com/cosmos/cosmos-sdk/codec" - sdkmodule "github.com/cosmos/cosmos-sdk/types/module" - "github.com/tendermint/tendermint/libs/log" - - storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + sdkmodule "github.com/cosmos/cosmos-sdk/types/module" - apptypes "github.com/akash-network/node/app/types" + apptypes "pkg.akt.dev/node/app/types" ) var ( @@ -47,18 +46,18 @@ type IHeightPatch interface { } type Migrator interface { - StoreKey() sdk.StoreKey + StoreKey() storetypes.StoreKey Codec() codec.BinaryCodec } type migrator struct { cdc codec.BinaryCodec - skey sdk.StoreKey + skey storetypes.StoreKey } var _ Migrator = (*migrator)(nil) -func NewMigrator(cdc codec.BinaryCodec, skey sdk.StoreKey) Migrator { +func NewMigrator(cdc codec.BinaryCodec, skey storetypes.StoreKey) Migrator { return &migrator{ cdc: cdc, skey: skey, @@ -69,7 +68,7 @@ func (m *migrator) Codec() codec.BinaryCodec { return m.cdc } -func (m *migrator) StoreKey() sdk.StoreKey { +func (m *migrator) StoreKey() storetypes.StoreKey { return m.skey } @@ -101,6 +100,10 @@ func GetHeightPatchesList() map[int64]IHeightPatch { return heightPatches } +// RegisterMigration registers module migration within particular network upgrade +// - module: module name +// - version: current module version +// - initFn: migrator fn func RegisterMigration(module string, version uint64, initFn NewMigrationFn) { if _, exists := migrations[module]; !exists { migrations[module] = make(moduleMigrations) @@ -120,3 +123,15 @@ func IterateMigrations(fn func(module string, version uint64, initfn NewMigratio } } } + +func ModuleMigrations(module string, migrator Migrator, fn func(string, uint64, sdkmodule.MigrationHandler)) { + moduleMigrations, exists := migrations[module] + if !exists { + return + } + + for version, initFn := range moduleMigrations { + migration := initFn(migrator) + fn(module, version, migration.GetHandler()) + } +} diff --git a/upgrades/upgrades.go b/upgrades/upgrades.go index 3c7a556677..ea143ded18 100644 --- a/upgrades/upgrades.go +++ b/upgrades/upgrades.go @@ -2,5 +2,5 @@ package upgrades import ( // nolint: revive - _ "github.com/akash-network/node/upgrades/software/v0.38.0" + _ "pkg.akt.dev/node/upgrades/software/v1.0.0" ) diff --git a/upgrades/upgrades_test.go b/upgrades/upgrades_test.go index 1c4acb96f4..fc379aa757 100644 --- a/upgrades/upgrades_test.go +++ b/upgrades/upgrades_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/mod/semver" - utypes "github.com/akash-network/node/upgrades/types" + utypes "pkg.akt.dev/node/upgrades/types" ) func TestUpgradesName(t *testing.T) { diff --git a/util/cli/configs.go b/util/cli/configs.go index 60e76482ae..08633d8fae 100644 --- a/util/cli/configs.go +++ b/util/cli/configs.go @@ -9,27 +9,132 @@ import ( "strings" "time" + "cosmossdk.io/log" + perrors "github.com/pkg/errors" "github.com/rs/zerolog" + "github.com/rs/zerolog/pkgerrors" "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/spf13/viper" + cflags "pkg.akt.dev/go/cli/flags" - tmcfg "github.com/tendermint/tendermint/config" + tmcfg "github.com/cometbft/cometbft/config" + tmlog "github.com/cometbft/cometbft/libs/log" - "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server/config" ) -const ( - FlagLogColor = "log_color" - FlagLogTimestamp = "log_timestamp" -) - var ( ErrEmptyEnvPrefix = errors.New("envPrefixes parameter must contain at least one prefix") ) +type zeroLogWrapper struct { + *zerolog.Logger +} + +// Info takes a message and a set of key/value pairs and logs with level INFO. +// The key of the tuple must be a string. +func (l zeroLogWrapper) Info(msg string, keyVals ...interface{}) { + l.Logger.Info().Fields(keyVals).Msg(msg) +} + +// Warn takes a message and a set of key/value pairs and logs with level INFO. +// The key of the tuple must be a string. +func (l zeroLogWrapper) Warn(msg string, keyVals ...interface{}) { + l.Logger.Warn().Fields(keyVals).Msg(msg) +} + +// Error takes a message and a set of key/value pairs and logs with level DEBUG. +// The key of the tuple must be a string. +func (l zeroLogWrapper) Error(msg string, keyVals ...interface{}) { + l.Logger.Error().Fields(keyVals).Msg(msg) +} + +// Debug takes a message and a set of key/value pairs and logs with level ERR. +// The key of the tuple must be a string. +func (l zeroLogWrapper) Debug(msg string, keyVals ...interface{}) { + l.Logger.Debug().Fields(keyVals).Msg(msg) +} + +// With returns a new wrapped logger with additional context provided by a set. +func (l zeroLogWrapper) With(keyVals ...interface{}) log.Logger { + logger := l.Logger.With().Fields(keyVals).Logger() + return zeroLogWrapper{&logger} +} + +// Impl returns the underlying zerolog logger. +// It can be used to used zerolog structured API directly instead of the wrapper. +func (l zeroLogWrapper) Impl() interface{} { + return l.Logger +} + +// NewLogger returns a new logger that writes to the given destination. +// +// Typical usage from a main function is: +// +// logger := log.NewLogger(os.Stderr) +// +// Stderr is the typical destination for logs, +// so that any output from your application can still be piped to other processes. +func NewLogger(dst io.Writer, options ...log.Option) log.Logger { + logCfg := log.Config{ + Level: zerolog.NoLevel, + Filter: nil, + OutputJSON: false, + Color: true, + StackTrace: false, + TimeFormat: time.Kitchen, + Hooks: nil, + } + + for _, opt := range options { + opt(&logCfg) + } + + output := dst + if !logCfg.OutputJSON { + cl := zerolog.ConsoleWriter{ + Out: dst, + NoColor: !logCfg.Color, + TimeFormat: logCfg.TimeFormat, + } + + if logCfg.TimeFormat == "" { + cl.PartsExclude = []string{ + zerolog.TimestampFieldName, + } + } + + output = cl + } + + if logCfg.Filter != nil { + output = log.NewFilterWriter(output, logCfg.Filter) + } + + logger := zerolog.New(output) + if logCfg.StackTrace { + zerolog.ErrorStackMarshaler = func(err error) interface{} { + return pkgerrors.MarshalStack(perrors.WithStack(err)) + } + + logger = logger.With().Stack().Logger() + } + + if logCfg.TimeFormat != "" { + logger = logger.With().Timestamp().Logger() + } + + if logCfg.Level != zerolog.NoLevel { + logger = logger.Level(logCfg.Level) + } + + logger = logger.Hook(logCfg.Hooks...) + + return zeroLogWrapper{&logger} +} + // InterceptConfigsPreRunHandler performs a pre-run function for the root daemon // application command. It will create a Viper literal and a default server // Context. The server Tendermint configuration will either be read and parsed @@ -67,53 +172,76 @@ func InterceptConfigsPreRunHandler( serverCtx.Viper.AllowEmptyEnv(allowEmptyEnv) serverCtx.Viper.AutomaticEnv() + if err := bindFlags(cmd, serverCtx.Viper, envPrefixes); err != nil { + return err + } + // intercept configuration files, using both Viper instances separately cfg, err := interceptConfigs(serverCtx.Viper, customAppConfigTemplate, customAppConfig) if err != nil { return err } + + // return value is a tendermint configuration object serverCtx.Config = cfg - logTimeFmt, err := parseTimestampFormat(serverCtx.Viper.GetString(FlagLogTimestamp)) - if err != nil { - return err + var opts []log.Option + + logFmt := serverCtx.Viper.GetString(cflags.FlagLogFormat) + switch logFmt { + case tmcfg.LogFormatJSON: + opts = append(opts, log.OutputJSONOption()) + case "": + fallthrough + case tmcfg.LogFormatPlain: + // cl := zerolog.ConsoleWriter{ + // Out: os.Stdout, + // NoColor: !serverCtx.Viper.GetBool(cflags.FlagLogColor), + // TimeFormat: logTimeFmt, + // } + // + // if logTimeFmt == "" { + // cl.PartsExclude = []string{ + // zerolog.TimestampFieldName, + // } + // } + // logWriter = cl + default: + return fmt.Errorf("unsupported value \"%s\" for log_format flag. can be either plain|json", logFmt) } - logLvlStr := serverCtx.Viper.GetString(flags.FlagLogLevel) - serverCtx.Viper.GetString(flags.FlagLogLevel) - logLvl, err := zerolog.ParseLevel(logLvlStr) + logTimeFmt, err := parseTimestampFormat(serverCtx.Viper.GetString(cflags.FlagLogTimestamp)) if err != nil { - return fmt.Errorf("failed to parse log level (%s): %w", logLvlStr, err) + return err } - logWriter := io.Writer(os.Stdout) - - if strings.ToLower(serverCtx.Viper.GetString(flags.FlagLogFormat)) == tmcfg.LogFormatPlain { - cl := zerolog.ConsoleWriter{ - Out: os.Stdout, - NoColor: !serverCtx.Viper.GetBool(FlagLogColor), - TimeFormat: logTimeFmt, - } - - if logTimeFmt == "" { - cl.PartsExclude = []string{ - zerolog.TimestampFieldName, + opts = append(opts, + log.ColorOption(serverCtx.Viper.GetBool(cflags.FlagLogColor)), + log.TraceOption(serverCtx.Viper.GetBool(cflags.FlagTrace)), + log.TimeFormatOption(logTimeFmt), + ) + + // check and set filter level or keys for the logger if any + logLvlStr := serverCtx.Viper.GetString(cflags.FlagLogLevel) + if logLvlStr != "" { + logLvl, err := zerolog.ParseLevel(logLvlStr) + switch { + case err != nil: + // If the log level is not a valid zerolog level, then we try to parse it as a key filter. + filterFunc, err := log.ParseLogLevel(logLvlStr) + if err != nil { + return err } - } - logWriter = cl - } - - logger := zerolog.New(logWriter).Level(logLvl) - if logTimeFmt != "" { - logger = logger.With().Timestamp().Logger() + opts = append(opts, log.FilterOption(filterFunc)) + default: + opts = append(opts, log.LevelOption(logLvl)) + } } - serverCtx.Logger = server.ZeroLogWrapper{Logger: logger} + logger := NewLogger(tmlog.NewSyncWriter(os.Stdout), opts...).With(log.ModuleKey, "server") - if err = bindFlags(cmd, serverCtx.Viper, envPrefixes); err != nil { - return err - } + serverCtx.Logger = logger return server.SetCmdServerContext(cmd, serverCtx) } @@ -130,7 +258,7 @@ func parseTimestampFormat(val string) (string, error) { return time.Kitchen, nil } - return "", fmt.Errorf("invalid timestamp format (%s)", val) // nolint goerr113 + return "", fmt.Errorf("invalid timestamp format (%s)", val) } func bindFlags(cmd *cobra.Command, v *viper.Viper, envPrefixes []string) error { @@ -176,7 +304,7 @@ func bindFlags(cmd *cobra.Command, v *viper.Viper, envPrefixes []string) error { // Viper object, whereas the application is parsed with the private package-aware // viperCfg object. func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customConfig interface{}) (*tmcfg.Config, error) { - rootDir := rootViper.GetString(flags.FlagHome) + rootDir := rootViper.GetString(cflags.FlagHome) configPath := filepath.Join(rootDir, "config") tmCfgFile := filepath.Join(configPath, "config.toml") @@ -187,7 +315,7 @@ func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customCo tmcfg.EnsureRoot(rootDir) if err = conf.ValidateBasic(); err != nil { - return nil, fmt.Errorf("error in config file: %v", err) // nolint: goerr113 + return nil, fmt.Errorf("error in config file: %v", err) } conf.RPC.PprofListenAddress = "localhost:6060" @@ -205,7 +333,7 @@ func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customCo rootViper.AddConfigPath(configPath) if err := rootViper.ReadInConfig(); err != nil { - return nil, fmt.Errorf("failed to read in %s: %w", tmCfgFile, err) // nolint: goerr113 + return nil, fmt.Errorf("failed to read in %s: %w", tmCfgFile, err) } } @@ -224,14 +352,15 @@ func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customCo config.SetConfigTemplate(customAppTemplate) if err = rootViper.Unmarshal(&customConfig); err != nil { - return nil, fmt.Errorf("failed to parse %s: %w", appCfgFilePath, err) // nolint: goerr113 + return nil, fmt.Errorf("failed to parse %s: %w", appCfgFilePath, err) } config.WriteConfigFile(appCfgFilePath, customConfig) } else { appConf, err := config.ParseConfig(rootViper) + appConf.MinGasPrices = "0.025uakt" if err != nil { - return nil, fmt.Errorf("failed to parse %s: %w", appCfgFilePath, err) // nolint: goerr113 + return nil, fmt.Errorf("failed to parse %s: %w", appCfgFilePath, err) } config.WriteConfigFile(appCfgFilePath, appConf) @@ -243,7 +372,7 @@ func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customCo rootViper.AddConfigPath(configPath) if err := rootViper.MergeInConfig(); err != nil { - return nil, fmt.Errorf("failed to merge configuration: %w", err) // nolint: goerr113 + return nil, fmt.Errorf("failed to merge configuration: %w", err) } return conf, nil diff --git a/util/cli/upgrade_info.go b/util/cli/upgrade_info.go index 5a6f98f2ed..519d0af5a4 100644 --- a/util/cli/upgrade_info.go +++ b/util/cli/upgrade_info.go @@ -9,7 +9,7 @@ import ( "os" "strings" - "github.com/google/go-github/v56/github" + "github.com/google/go-github/v62/github" "github.com/gregjones/httpcache" "golang.org/x/oauth2" ) @@ -73,14 +73,16 @@ func UpgradeInfoFromTag(ctx context.Context, tag string, pretty bool) (string, e return "", fmt.Errorf("invalid checksum format") } + link := fmt.Sprintf("%s/%s?checksum=sha256:%s", urlBase, tuple[1], tuple[0]) + switch tuple[1] { case "akash_linux_amd64.zip": - info.Binaries["linux/amd64"] = fmt.Sprintf("%s/%s?checksum=sha256:%s", urlBase, tuple[1], tuple[0]) + info.Binaries["linux/amd64"] = link case "akash_linux_arm64.zip": - info.Binaries["linux/arm64"] = fmt.Sprintf("%s/%s?checksum=sha256:%s", urlBase, tuple[1], tuple[0]) + info.Binaries["linux/arm64"] = link case "akash_darwin_all.zip": - info.Binaries["darwin/amd64"] = fmt.Sprintf("%s/%s?checksum=sha256:%s", urlBase, tuple[1], tuple[0]) - info.Binaries["darwin/arm64"] = fmt.Sprintf("%s/%s?checksum=sha256:%s", urlBase, tuple[1], tuple[0]) + info.Binaries["darwin/amd64"] = link + info.Binaries["darwin/arm64"] = link } } diff --git a/util/metrics/metrics.go b/util/metrics/metrics.go index 144f8a144e..e194827a6c 100644 --- a/util/metrics/metrics.go +++ b/util/metrics/metrics.go @@ -3,8 +3,8 @@ package metrics import ( "time" - "github.com/akash-network/node/util/runner" "github.com/prometheus/client_golang/prometheus" + "pkg.akt.dev/go/util/runner" ) const SuccessLabel = "success" diff --git a/util/partialord/internal/dag/dag.go b/util/partialord/internal/dag/dag.go new file mode 100644 index 0000000000..c2dbd5b232 --- /dev/null +++ b/util/partialord/internal/dag/dag.go @@ -0,0 +1,316 @@ +package dag + +import ( + "fmt" + "sort" +) + +// DAG struct maintains a directed acyclic graph, using adjacency lists to track edges. +type DAG struct { + // there is a directed edge from u -> v, if directedEdgeList[u][v] = 1 + // there is a directed edge from v -> u, if directedEdgeList[u][v] = -1 + directedEdgeList []map[int]int8 + nodeNameToID map[string]int + idToNodeNames map[int]string +} + +func NewDAG(nodes []string) DAG { + nodeNameToID := make(map[string]int, len(nodes)) + idToNodeNames := make(map[int]string, len(nodes)) + directedEdgeList := make([]map[int]int8, len(nodes)) + for i, node := range nodes { + nodeNameToID[node] = i + idToNodeNames[i] = node + directedEdgeList[i] = map[int]int8{} + } + if len(nodeNameToID) != len(nodes) { + panic("provided multiple nodes with the same name") + } + return DAG{ + directedEdgeList: directedEdgeList, + nodeNameToID: nodeNameToID, + idToNodeNames: idToNodeNames, + } +} + +// Copy returns a new dag struct that is a copy of the original dag. +// Edges can be mutated in the copy, without altering the original. +func (dag DAG) Copy() DAG { + directedEdgeList := make([]map[int]int8, len(dag.nodeNameToID)) + for i := 0; i < len(dag.nodeNameToID); i++ { + originalEdgeList := dag.directedEdgeList[i] + directedEdgeList[i] = make(map[int]int8, len(originalEdgeList)) + for k, v := range originalEdgeList { + directedEdgeList[i][k] = v + } + } + // we reuse nodeNameToID and idToNodeNames as these are fixed at dag creation. + return DAG{ + directedEdgeList: directedEdgeList, + nodeNameToID: dag.nodeNameToID, + idToNodeNames: dag.idToNodeNames, + } +} + +func (dag DAG) hasDirectedEdge(u, v int) bool { + uAdjacencyList := dag.directedEdgeList[u] + _, exists := uAdjacencyList[v] + return exists +} + +// addEdge adds a directed edge from u -> v. +func (dag *DAG) addEdge(u, v int) error { + if u == v { + return fmt.Errorf("can't make self-edge") + } + if dag.hasDirectedEdge(v, u) { + return fmt.Errorf("dag has conflicting edge") + } + dag.directedEdgeList[u][v] = 1 + dag.directedEdgeList[v][u] = -1 + return nil +} + +// replaceEdge adds a directed edge from u -> v. +// it removes any edge that may already exist between the two. +func (dag *DAG) replaceEdge(u, v int) error { + if u == v { + return fmt.Errorf("can't make self-edge") + } + + dag.directedEdgeList[u][v] = 1 + dag.directedEdgeList[v][u] = -1 + return nil +} + +// resetEdges deletes all edges directed to or from node `u` +func (dag *DAG) resetEdges(u int) { + edges := dag.directedEdgeList[u] + for v := range edges { + delete(dag.directedEdgeList[v], u) + } + dag.directedEdgeList[u] = map[int]int8{} +} + +// deleteEdge deletes edges between u and v. +func (dag *DAG) deleteEdge(u, v int) { + delete(dag.directedEdgeList[u], v) + delete(dag.directedEdgeList[v], u) +} + +// AddEdge checks if either edge between u and v exists and adds a directed edge from u -> v +func (dag *DAG) AddEdge(u, v string) error { + uIndex, uExists := dag.nodeNameToID[u] + vIndex, vExists := dag.nodeNameToID[v] + if !uExists || !vExists { + return fmt.Errorf("one of %s, %s does not exist in dag", u, v) + } + return dag.addEdge(uIndex, vIndex) +} + +// ReplaceEdge adds a directed edge from u -> v. +// it removes any edge that may already exist between the two. +func (dag *DAG) ReplaceEdge(u, v string) error { + uIndex, uExists := dag.nodeNameToID[u] + vIndex, vExists := dag.nodeNameToID[v] + if !uExists || !vExists { + return fmt.Errorf("one of %s, %s does not exist in dag", u, v) + } + return dag.replaceEdge(uIndex, vIndex) +} + +// AddFirstElements sets the provided elements to be first in all orderings. +// So if were making an ordering over {A, B, C, D, E}, and elems provided is {D, B, A} +// then we are guaranteed that the total ordering will begin with {D, B, A} +func (dag *DAG) AddFirstElements(nodes ...string) error { + nodeIDs, err := dag.namesToIDs(nodes) + if err != nil { + return err + } + + return dag.addFirst(nodeIDs) +} + +func (dag *DAG) addFirst(nodes []int) error { + nodeMap := map[int]bool{} + for i := 0; i < len(nodes); i++ { + nodeMap[nodes[i]] = true + } + // First we add an edge from nodes[-1] to every node in the graph aside from the provided first nodes. + // then we make nodes[-1] depend on nodes[-2], etc. + // We also clear all other edges from nodes[-2], to override previous settings. + lastOfFirstNodes := nodes[len(nodes)-1] + for i := 0; i < len(dag.nodeNameToID); i++ { + // skip any node in the 'first set' + _, inMap := nodeMap[i] + if inMap { + continue + } + // We make everything on `lastOfFirstNodes`, and therefore have an edge from `lastOfFirstNodes` to it + err := dag.replaceEdge(lastOfFirstNodes, i) + // can't happen by above check + if err != nil { + return err + } + } + + // Make nodes[i+1] depend on nodes[i] + for i := len(nodes) - 2; i >= 0; i-- { + dag.resetEdges(nodes[i]) + err := dag.replaceEdge(nodes[i], nodes[i+1]) + // can't happen by above check + if err != nil { + return err + } + } + return nil +} + +// AddLastElements sets the provided elements to be last in all orderings. +// So if were making an ordering over {A, B, C, D, E}, and elems provided is {D, B, A} +// then we are guaranteed that the total ordering will end with {D, B, A} +func (dag *DAG) AddLastElements(nodes ...string) error { + nodeIDs, err := dag.namesToIDs(nodes) + if err != nil { + return err + } + + return dag.addLast(nodeIDs) +} + +func (dag *DAG) addLast(nodes []int) error { + nodeMap := map[int]bool{} + for i := 0; i < len(nodes); i++ { + nodeMap[nodes[i]] = true + } + // First we add an edge from every node in the graph aside from the provided last nodes, to nodes[0] + // then we make nodes[1] depend on nodes[0], etc. + // We also clear all other edges from nodes[1], to override previous settings. + firstOfLastNodes := nodes[0] + for i := 0; i < len(dag.nodeNameToID); i++ { + // skip any node in the 'last set' + _, inMap := nodeMap[i] + if inMap { + continue + } + // We make `firstOfLastNodes` depend on every node, and therefore have an edge from each node to `firstOfLastNodes` + err := dag.replaceEdge(i, firstOfLastNodes) + // can't happen by above check + if err != nil { + return err + } + } + + // Make nodes[i] depend on nodes[i-1], and clear all other edges from nodes[i] + for i := 1; i < len(nodes); i++ { + dag.resetEdges(nodes[i]) + err := dag.replaceEdge(nodes[i-1], nodes[i]) + // can't happen by above check + if err != nil { + return err + } + } + return nil +} + +func (dag DAG) hasEdges() bool { + for _, m := range dag.directedEdgeList { + if len(m) > 0 { + return true + } + } + return false +} + +func (dag *DAG) namesToIDs(names []string) ([]int, error) { + nodeIDs := []int{} + for _, name := range names { + nodeIndex, nodeExists := dag.nodeNameToID[name] + if !nodeExists { + return []int{}, fmt.Errorf("%s does not exist in dag", name) + } + nodeIDs = append(nodeIDs, nodeIndex) + } + return nodeIDs, nil +} + +func (dag DAG) idsToNames(ids []int) []string { + sortedNames := make([]string, 0, len(ids)) + for i := 0; i < len(dag.nodeNameToID); i++ { + id := ids[i] + sortedNames = append(sortedNames, dag.idToNodeNames[id]) + } + return sortedNames +} + +func (dag DAG) hasIncomingEdge(u int) bool { + adjacencyList := dag.directedEdgeList[u] + for _, v := range adjacencyList { + if v == -1 { + return true + } + } + return false +} + +// returns nodes with no incoming edges. +func (dag *DAG) topologicalTopLevelNodes() []int { + topLevelNodes := []int{} + + for i := 0; i < len(dag.nodeNameToID); i++ { + if !dag.hasIncomingEdge(i) { + topLevelNodes = append(topLevelNodes, i) + } + } + + return topLevelNodes +} + +// Returns a Topological Sort of the DAG, using Kahn's algorithm. +// https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm +func (dag DAG) TopologicalSort() []string { + // G is the mutable graph we work on, which we remove edges from. + G := dag.Copy() + // L in pseudocode + sortedIDs := make([]int, 0, len(dag.nodeNameToID)) + topLevelNodes := dag.topologicalTopLevelNodes() + + for len(topLevelNodes) != 0 { + // pop a node `n`` off of topLevelNodes + n := topLevelNodes[0] + topLevelNodes = topLevelNodes[1:] + // add it to the sorted list + sortedIDs = append(sortedIDs, n) + nEdgeList := G.directedEdgeList[n] + + // normally we'd do map iteration, but because we need cross-machine determinism, + // we gather all the nodes M for which there is an edge n -> m, sort that list, + // and then iterate over it. + nodesM := make([]int, 0, len(nEdgeList)) + for m, direction := range nEdgeList { + if direction != 1 { + panic("dag: topological sort correctness error. " + + "Popped node n was expected to have no incoming edges") + } + nodesM = append(nodesM, m) + } + + sort.Ints(nodesM) + + for _, m := range nodesM { + // remove edge from n -> m + G.deleteEdge(n, m) + // if m has no incomingEdges, add to topLevelNodes + if !G.hasIncomingEdge(m) { + topLevelNodes = append(topLevelNodes, m) + } + } + } + + if G.hasEdges() { + fmt.Println(G) + panic("dag: invalid construction, attempted to topologically sort a tree that is not a dag. A cycle exists") + } + + return dag.idsToNames(sortedIDs) +} diff --git a/util/partialord/internal/dag/dag_test.go b/util/partialord/internal/dag/dag_test.go new file mode 100644 index 0000000000..7a7cbf4551 --- /dev/null +++ b/util/partialord/internal/dag/dag_test.go @@ -0,0 +1,158 @@ +package dag_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "pkg.akt.dev/node/util/partialord/internal/dag" +) + +type edge struct { + start, end string +} + +func TestTopologicalSort(t *testing.T) { + // Tests that topological sort works for various inputs. + // We hardcode the satisfying solution in the tests, even though it suffices + // to check that the partial ordering is sufficient. (and that's the only guarantee given externally) + // This is to ensure we catch differences in order between changes, and across machines. + simpleNodes := []string{"dog", "cat", "banana", "apple"} + simpleNodesRev := []string{"apple", "banana", "cat", "dog"} + tests := []struct { + nodes []string + edges []edge + expectedTopologicalOrder []string + }{ + { + // alphabetical ordering of simple nodes + nodes: simpleNodes, + edges: []edge{{"banana", "apple"}, {"cat", "banana"}, {"dog", "cat"}}, + expectedTopologicalOrder: simpleNodes, + }, + { + // apple > dog + nodes: simpleNodes, + edges: []edge{{"apple", "dog"}}, + expectedTopologicalOrder: []string{"cat", "banana", "apple", "dog"}, + }, + { + // apple > everything + nodes: simpleNodes, + edges: []edge{{"apple", "banana"}, {"apple", "cat"}, {"apple", "dog"}}, + expectedTopologicalOrder: []string{"apple", "dog", "cat", "banana"}, + }, + { + // apple > everything, on list with reversed initial order + nodes: simpleNodesRev, + edges: []edge{{"apple", "banana"}, {"apple", "cat"}, {"apple", "dog"}}, + expectedTopologicalOrder: []string{"apple", "banana", "cat", "dog"}, + }, + } + for _, tc := range tests { + dag := dag.NewDAG(tc.nodes) + for _, edge := range tc.edges { + err := dag.AddEdge(edge.start, edge.end) + require.NoError(t, err) + } + order := dag.TopologicalSort() + require.Equal(t, tc.expectedTopologicalOrder, order) + } +} + +func TestAddFirst(t *testing.T) { + simpleNodes := []string{"frog", "elephant", "dog", "cat", "banana", "apple"} + tests := []struct { + nodes []string + first []string + replaceEdges []edge + expectedTopologicalOrder []string + }{ + { + nodes: simpleNodes, + first: []string{"frog"}, + replaceEdges: []edge{{"banana", "apple"}, {"cat", "banana"}, {"dog", "cat"}}, + expectedTopologicalOrder: simpleNodes, + }, + { + nodes: simpleNodes, + first: []string{"elephant"}, + replaceEdges: []edge{{"banana", "apple"}, {"apple", "frog"}, {"dog", "cat"}}, + expectedTopologicalOrder: []string{"elephant", "dog", "banana", "cat", "apple", "frog"}, + }, + { + nodes: simpleNodes, + first: []string{"elephant", "frog"}, + replaceEdges: []edge{}, + expectedTopologicalOrder: []string{"elephant", "frog", "dog", "cat", "banana", "apple"}, + }, + { + // add three items in first, if implemented incorrectly could cause a cycle + nodes: simpleNodes, + first: []string{"dog", "elephant", "frog"}, + replaceEdges: []edge{}, + expectedTopologicalOrder: []string{"dog", "elephant", "frog", "cat", "banana", "apple"}, + }, + } + for _, tc := range tests { + dag := dag.NewDAG(tc.nodes) + err := dag.AddFirstElements(tc.first...) + require.NoError(t, err) + + for _, edge := range tc.replaceEdges { + err := dag.ReplaceEdge(edge.start, edge.end) + require.NoError(t, err) + } + order := dag.TopologicalSort() + require.Equal(t, tc.expectedTopologicalOrder, order) + } +} + +func TestAddLast(t *testing.T) { + simpleNodes := []string{"frog", "elephant", "dog", "cat", "banana", "apple"} + tests := []struct { + nodes []string + last []string + replaceEdges []edge + expectedTopologicalOrder []string + }{ + { + // causes no order change + nodes: simpleNodes, + last: []string{"apple"}, + replaceEdges: []edge{{"banana", "apple"}, {"cat", "banana"}, {"dog", "cat"}}, + expectedTopologicalOrder: simpleNodes, + }, + { + nodes: simpleNodes, + last: []string{"elephant"}, + replaceEdges: []edge{{"banana", "apple"}, {"apple", "frog"}, {"dog", "cat"}}, + expectedTopologicalOrder: []string{"dog", "banana", "cat", "apple", "frog", "elephant"}, + }, + { + nodes: simpleNodes, + last: []string{"elephant", "frog"}, + replaceEdges: []edge{}, + expectedTopologicalOrder: []string{"dog", "cat", "banana", "apple", "elephant", "frog"}, + }, + { + // add three items in last, if implemented incorrectly could cause a cycle + nodes: simpleNodes, + last: []string{"dog", "elephant", "frog"}, + replaceEdges: []edge{}, + expectedTopologicalOrder: []string{"cat", "banana", "apple", "dog", "elephant", "frog"}, + }, + } + for _, tc := range tests { + dag := dag.NewDAG(tc.nodes) + err := dag.AddLastElements(tc.last...) + require.NoError(t, err) + + for _, edge := range tc.replaceEdges { + err := dag.ReplaceEdge(edge.start, edge.end) + require.NoError(t, err) + } + order := dag.TopologicalSort() + require.Equal(t, tc.expectedTopologicalOrder, order) + } +} diff --git a/util/partialord/internal/dag/module.go b/util/partialord/internal/dag/module.go new file mode 100644 index 0000000000..4b4bcd971c --- /dev/null +++ b/util/partialord/internal/dag/module.go @@ -0,0 +1,9 @@ +// Package dag implements a simple Directed Acyclical Graph (DAG) for deterministic topological sorts +// +// It should not be externally exposed, and is intended to be a very simple dag implementation +// utilizing adjacency lists to store edges. +// +// This package is intended to be used for small scales, where performance of the algorithms is not critical. +// (e.g. sub 10k entries) +// Thus none of the algorithms in here are benchmarked, and just have correctness checks. +package dag diff --git a/util/partialord/module.go b/util/partialord/module.go new file mode 100644 index 0000000000..771816b2f7 --- /dev/null +++ b/util/partialord/module.go @@ -0,0 +1,2 @@ +// Package partialord allows one to define partial orderings, and derive a total ordering +package partialord diff --git a/util/partialord/partialord.go b/util/partialord/partialord.go new file mode 100644 index 0000000000..d1d4387e5f --- /dev/null +++ b/util/partialord/partialord.go @@ -0,0 +1,97 @@ +package partialord + +import ( + "sort" + + "pkg.akt.dev/node/util/partialord/internal/dag" +) + +type PartialOrdering struct { + // underlying dag, the partial ordering is stored via a dag + // https://en.wikipedia.org/wiki/Topological_sorting#Relation_to_partial_orders + dag dag.DAG + // bools for sealing, to prevent repeated invocation of first or last methods. + firstSealed bool + lastSealed bool +} + +// NewPartialOrdering creates a new partial ordering over the set of provided elements. +func NewPartialOrdering(elements []string) PartialOrdering { + elementsCopy := make([]string, len(elements)) + copy(elementsCopy, elements) + sort.Strings(elementsCopy) + return PartialOrdering{ + dag: dag.NewDAG(elementsCopy), + firstSealed: false, + lastSealed: false, + } +} + +func handleDAGErr(err error) { + // all dag errors are logic errors that the intended users of this package should not make. + if err != nil { + panic(err) + } +} + +// After marks that A should come after B +func (ord *PartialOrdering) After(a string, b string) { + // Set that A depends on B / an edge from B -> A + err := ord.dag.AddEdge(b, a) + handleDAGErr(err) +} + +// Before marks that A should come before B +func (ord *PartialOrdering) Before(a string, b string) { + // Set that B depends on A / an edge from A -> B + err := ord.dag.AddEdge(a, b) + handleDAGErr(err) +} + +// FirstElements Sets elems to be the first elements in the ordering. +// So if were making an ordering over {A, B, C, D, E}, and elems provided is {D, B, A} +// then we are guaranteed that the total ordering will begin with {D, B, A} +func (ord *PartialOrdering) FirstElements(elems ...string) { + if ord.firstSealed { + panic("FirstElements has already been called") + } + // We make every node in the dag have a dependency on elems[-1] + // then we change elems[-1] to depend on elems[-2], and so forth. + err := ord.dag.AddFirstElements(elems...) + handleDAGErr(err) + ord.firstSealed = true +} + +// LastElements Sets elems to be the last elements in the ordering. +// So if were making an ordering over {A, B, C, D, E}, and elems provided is {D, B, A} +// then we are guaranteed that the total ordering will end with {D, B, A} +func (ord *PartialOrdering) LastElements(elems ...string) { + if ord.lastSealed { + panic("FirstElements has already been called") + } + // We make every node in the dag have a dependency on elems[0] + // then we make elems[1] depend on elems[0], and so forth. + err := ord.dag.AddLastElements(elems...) + handleDAGErr(err) + ord.lastSealed = true +} + +// Sequence sets a sequence of ordering constraints. +// So if were making an ordering over {A, B, C, D, E}, and elems provided is {D, B, A} +// then we are guaranteed that the total ordering will have D comes before B comes before A. +// (They're may be elements interspersed, e.g. {D, C, E, B, A} is a valid ordering) +func (ord *PartialOrdering) Sequence(seq ...string) { + // We make every node in the sequence have a prior node + for i := 0; i < (len(seq) - 1); i++ { + err := ord.dag.AddEdge(seq[i], seq[i+1]) + handleDAGErr(err) + } +} + +// TotalOrdering returns a deterministically chosen total ordering that satisfies all specified +// partial ordering constraints. +// +// Panics if no total ordering exists. +func (ord *PartialOrdering) TotalOrdering() []string { + return ord.dag.TopologicalSort() +} diff --git a/util/partialord/partialord_test.go b/util/partialord/partialord_test.go new file mode 100644 index 0000000000..451cf29718 --- /dev/null +++ b/util/partialord/partialord_test.go @@ -0,0 +1,74 @@ +package partialord_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "pkg.akt.dev/node/util/partialord" +) + +func TestAPI(t *testing.T) { + // begin block use case, we have a dozen modules, but only care about a couple orders. + // In practice this will be gotten from some API, e.g. app.AllModuleNames() + moduleNames := []string{ + "auth", "authz", "bank", "capabilities", + "staking", "distribution", "epochs", "mint", "upgrades", "wasm", "ibc", + "ibctransfers", + } + beginBlockOrd := partialord.NewPartialOrdering(moduleNames) + beginBlockOrd.FirstElements("upgrades", "epochs", "capabilities") + beginBlockOrd.After("ibctransfers", "ibc") + beginBlockOrd.Before("mint", "distribution") + // This is purely just to test last functionality, doesn't make sense in context + beginBlockOrd.LastElements("auth", "authz", "wasm") + + totalOrd := beginBlockOrd.TotalOrdering() + expTotalOrd := []string{ + "upgrades", "epochs", "capabilities", + "bank", "ibc", "mint", "staking", "ibctransfers", "distribution", + "auth", "authz", "wasm", + } + require.Equal(t, expTotalOrd, totalOrd) +} + +func TestNonStandardAPIOrder(t *testing.T) { + // This test uses direct ordering before First, and after Last + names := []string{"A", "B", "C", "D", "E", "F", "G"} + ord := partialord.NewPartialOrdering(names) + ord.After("A", "C") + ord.After("A", "D") + ord.After("E", "B") + // overrides the "A" after "C" & "A" after "D" constraints + ord.FirstElements("A", "B", "C") + expOrdering := []string{"A", "B", "C", "D", "E", "F", "G"} + require.Equal(t, expOrdering, ord.TotalOrdering()) + + ord.After("E", "D") + expOrdering = []string{"A", "B", "C", "D", "F", "G", "E"} + require.Equal(t, expOrdering, ord.TotalOrdering()) + + ord.LastElements("G") + ord.After("F", "E") + expOrdering = []string{"A", "B", "C", "D", "E", "F", "G"} + require.Equal(t, expOrdering, ord.TotalOrdering()) +} + +// This test ad-hocly tests combination of multiple sequences, first elements, and an After +// invocation. +func TestSequence(t *testing.T) { + // This test uses direct ordering before First, and after Last + names := []string{"A", "B", "C", "D", "E", "F", "G"} + ord := partialord.NewPartialOrdering(names) + // Make B A C a sequence + ord.Sequence("B", "A", "C") + // Make A G E a sub-sequence + ord.Sequence("A", "G", "E") + // make first elements D B F + ord.FirstElements("D", "B", "F") + // make C come after E + ord.After("C", "G") + + expOrdering := []string{"D", "B", "F", "A", "G", "C", "E"} + require.Equal(t, expOrdering, ord.TotalOrdering()) +} diff --git a/util/query/pagination.go b/util/query/pagination.go index a0a6bf4deb..9138469a60 100644 --- a/util/query/pagination.go +++ b/util/query/pagination.go @@ -5,7 +5,7 @@ import ( "fmt" "hash/crc32" - "github.com/akash-network/node/util/validation" + "pkg.akt.dev/node/util/validation" ) var ( @@ -36,9 +36,7 @@ func DecodePaginationKey(key []byte) ([]byte, []byte, []byte, []byte, error) { } states := make([]byte, 0, statesC) - for _, state := range key[:statesC] { - states = append(states, state) - } + states = append(states, key[:statesC]...) key = key[len(states):] @@ -47,9 +45,7 @@ func DecodePaginationKey(key []byte) ([]byte, []byte, []byte, []byte, error) { } prefixLength := int(key[0]) - key = key[1:] - if len(key) < prefixLength { return nil, nil, nil, nil, fmt.Errorf("%w: invalid state length", ErrInvalidPaginationKey) } diff --git a/util/server/server.go b/util/server/server.go index c8d9af514d..454f7aa09c 100644 --- a/util/server/server.go +++ b/util/server/server.go @@ -6,29 +6,29 @@ import ( "os" "path/filepath" - "github.com/cosmos/cosmos-sdk/client/flags" + tmcmd "github.com/cometbft/cometbft/cmd/cometbft/commands" + tmjson "github.com/cometbft/cometbft/libs/json" + tmtypes "github.com/cometbft/cometbft/types" + dbm "github.com/cosmos/cosmos-db" + "github.com/spf13/cast" + cflags "pkg.akt.dev/go/cli/flags" + + servertypes "github.com/cosmos/cosmos-sdk/server/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - tmjson "github.com/tendermint/tendermint/libs/json" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - tmtypes "github.com/tendermint/tendermint/types" - dbm "github.com/tendermint/tm-db" - tmcmd "github.com/tendermint/tendermint/cmd/cometbft/commands" + "github.com/spf13/cobra" sdkserver "github.com/cosmos/cosmos-sdk/server" - "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/version" ) const ( // Tendermint full-node start flags flagTraceStore = "trace-store" - flagToFile = "to-file" ) // Commands server commands -func Commands(defaultNodeHome string, appCreator types.AppCreator, appExport types.AppExporter, addStartFlags types.ModuleInitFlags) []*cobra.Command { +func Commands(defaultNodeHome string, appCreator servertypes.AppCreator, appExport servertypes.AppExporter, addStartFlags servertypes.ModuleInitFlags) []*cobra.Command { tendermintCmd := &cobra.Command{ Use: "tendermint", Short: "Tendermint subcommands", @@ -58,34 +58,36 @@ func Commands(defaultNodeHome string, appCreator types.AppCreator, appExport typ } // ExportCmd dumps app state to JSON. -func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Command { +func ExportCmd(appExporter servertypes.AppExporter, defaultNodeHome string) *cobra.Command { cmd := &cobra.Command{ Use: "export", Short: "Export state to JSON", - RunE: func(cmd *cobra.Command, args []string) error { - serverCtx := sdkserver.GetServerContextFromCmd(cmd) - config := serverCtx.Config + RunE: func(cmd *cobra.Command, _ []string) error { + sctx := sdkserver.GetServerContextFromCmd(cmd) + config := sctx.Config - homeDir, _ := cmd.Flags().GetString(flags.FlagHome) + homeDir, _ := cmd.Flags().GetString(cflags.FlagHome) config.SetRoot(homeDir) if _, err := os.Stat(config.GenesisFile()); os.IsNotExist(err) { return err } - db, err := openDB(config.RootDir) + db, err := openDB(config.RootDir, sdkserver.GetAppDBBackend(sctx.Viper)) if err != nil { return err } outFile := os.Stdout - if toFile, _ := cmd.Flags().GetString(flagToFile); toFile != "" { - outFile, err = os.Create(toFile) + var outputDocument string + + if outputDocument, _ = cmd.Flags().GetString(cflags.FlagOutputDocument); outputDocument != "-" { + outFile, err = os.Create(outputDocument) //nolint: gosec if err != nil { return err } } - + // defer func() { if outFile != os.Stdout { _ = outFile.Close() @@ -116,16 +118,27 @@ func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Com return err } - height, _ := cmd.Flags().GetInt64(sdkserver.FlagHeight) - forZeroHeight, _ := cmd.Flags().GetBool(sdkserver.FlagForZeroHeight) - jailAllowedAddrs, _ := cmd.Flags().GetStringSlice(sdkserver.FlagJailAllowedAddrs) + height, _ := cmd.Flags().GetInt64(cflags.FlagHeight) + forZeroHeight, _ := cmd.Flags().GetBool(cflags.FlagForZeroHeight) + jailAllowedAddrs, _ := cmd.Flags().GetStringSlice(cflags.FlagJailAllowedAddrs) + modulesToExport, _ := cmd.Flags().GetStringSlice(cflags.FlagModulesToExport) + + exported, err := appExporter( + sctx.Logger, + db, + traceWriter, + height, + forZeroHeight, + jailAllowedAddrs, + sctx.Viper, + modulesToExport, + ) - exported, err := appExporter(serverCtx.Logger, db, traceWriter, height, forZeroHeight, jailAllowedAddrs, serverCtx.Viper) if err != nil { return fmt.Errorf("error exporting state: %v", err) } - doc, err := tmtypes.GenesisDocFromFile(serverCtx.Config.GenesisFile()) + doc, err := tmtypes.GenesisDocFromFile(sctx.Config.GenesisFile()) if err != nil { return err } @@ -133,18 +146,17 @@ func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Com doc.AppState = exported.AppState doc.Validators = exported.Validators doc.InitialHeight = exported.Height - doc.ConsensusParams = &tmproto.ConsensusParams{ - Block: tmproto.BlockParams{ - MaxBytes: exported.ConsensusParams.Block.MaxBytes, - MaxGas: exported.ConsensusParams.Block.MaxGas, - TimeIotaMs: doc.ConsensusParams.Block.TimeIotaMs, + doc.ConsensusParams = &tmtypes.ConsensusParams{ + Block: tmtypes.BlockParams{ + MaxBytes: exported.ConsensusParams.Block.MaxBytes, + MaxGas: exported.ConsensusParams.Block.MaxGas, }, - Evidence: tmproto.EvidenceParams{ + Evidence: tmtypes.EvidenceParams{ MaxAgeNumBlocks: exported.ConsensusParams.Evidence.MaxAgeNumBlocks, MaxAgeDuration: exported.ConsensusParams.Evidence.MaxAgeDuration, MaxBytes: exported.ConsensusParams.Evidence.MaxBytes, }, - Validator: tmproto.ValidatorParams{ + Validator: tmtypes.ValidatorParams{ PubKeyTypes: exported.ConsensusParams.Validator.PubKeyTypes, }, } @@ -157,8 +169,21 @@ func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Com return err } - _, err = fmt.Fprintln(outFile, string(sdk.MustSortJSON(encoded))) - if err != nil { + out := sdk.MustSortJSON(encoded) + if outputDocument == "-" { + cmd.Println(string(out)) + _, err = fmt.Fprintln(outFile, string(out)) + if err != nil { + return err + } + return nil + } + + var exportedGenDoc tmtypes.GenesisDoc + if err = tmjson.Unmarshal(out, &exportedGenDoc); err != nil { + return err + } + if err = exportedGenDoc.SaveAs(outputDocument); err != nil { return err } @@ -166,34 +191,41 @@ func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Com }, } - cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") - cmd.Flags().Int64(sdkserver.FlagHeight, -1, "Export state from a particular height (-1 means latest height)") - cmd.Flags().Bool(sdkserver.FlagForZeroHeight, false, "Export state to start at height zero (perform preprocessing)") - cmd.Flags().StringSlice(sdkserver.FlagJailAllowedAddrs, []string{}, "Comma-separated list of operator addresses of jailed validators to unjail") - cmd.Flags().String(flagToFile, "", "Export Genesis to specified file") + cmd.Flags().String(cflags.FlagHome, defaultNodeHome, "The application home directory") + cmd.Flags().Int64(cflags.FlagHeight, -1, "Export state from a particular height (-1 means latest height)") + cmd.Flags().Bool(cflags.FlagForZeroHeight, false, "Export state to start at height zero (perform preprocessing)") + cmd.Flags().StringSlice(cflags.FlagJailAllowedAddrs, []string{}, "Comma-separated list of operator addresses of jailed validators to unjail") + cmd.Flags().StringSlice(cflags.FlagModulesToExport, []string{}, "Comma-separated list of modules to export. If empty, will export all modules") + cmd.Flags().String(cflags.FlagOutputDocument, "-", "Exported state is written to the given file instead of STDOUT") return cmd } -func openDB(rootDir string) (dbm.DB, error) { +func openDB(rootDir string, backendType dbm.BackendType) (dbm.DB, error) { dataDir := filepath.Join(rootDir, "data") - return sdk.NewLevelDB("application", dataDir) + return dbm.NewDB("application", backendType, dataDir) } func openTraceWriter(traceWriterFile string) (w io.Writer, err error) { if traceWriterFile == "" { return } - return os.OpenFile( + return os.OpenFile( //nolint: gosec traceWriterFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, - 0o666, + 0o600, ) } -// AddTestnetCreatorCommand allows chains to create a testnet from the state existing in their node's data directory. -func AddTestnetCreatorCommand(rootCmd *cobra.Command, appCreator types.AppCreator, addStartFlags types.ModuleInitFlags) { - testnetCreateCmd := sdkserver.InPlaceTestnetCreator(appCreator) - addStartFlags(testnetCreateCmd) - rootCmd.AddCommand(testnetCreateCmd) +// GetAppDBBackend gets the backend type to use for the application DBs. +func GetAppDBBackend(opts servertypes.AppOptions) dbm.BackendType { + rv := cast.ToString(opts.Get("app-db-backend")) + if len(rv) == 0 { + rv = cast.ToString(opts.Get("db_backend")) + } + if len(rv) != 0 { + return dbm.BackendType(rv) + } + + return dbm.GoLevelDBBackend } diff --git a/util/server/utils.go b/util/server/utils.go new file mode 100644 index 0000000000..98317bc356 --- /dev/null +++ b/util/server/utils.go @@ -0,0 +1,38 @@ +package server + +import ( + "context" + "os" + "os/signal" + "syscall" + + "cosmossdk.io/log" + "golang.org/x/sync/errgroup" +) + +// ListenForQuitSignals listens for SIGINT and SIGTERM. When a signal is received, +// the cleanup function is called, indicating the caller can gracefully exit or +// return. +// +// Note, the blocking behavior of this depends on the block argument. +// The caller must ensure the corresponding context derived from the cancelFn is used correctly. +func ListenForQuitSignals(g *errgroup.Group, block bool, cancelFn context.CancelFunc, logger log.Logger) { + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) + + f := func() { + sig := <-sigCh + cancelFn() + + logger.Info("caught signal", "signal", sig.String()) + } + + if block { + g.Go(func() error { + f() + return nil + }) + } else { + go f() + } +} diff --git a/util/wsutil/wsutil.go b/util/wsutil/wsutil.go index 1226867fd7..b06664d963 100644 --- a/util/wsutil/wsutil.go +++ b/util/wsutil/wsutil.go @@ -2,9 +2,10 @@ package wsutil import ( "bytes" - "github.com/gorilla/websocket" "io" "sync" + + "github.com/gorilla/websocket" ) // This type exposes the single method that this wrapper uses diff --git a/util/wsutil/wsutil_test.go b/util/wsutil/wsutil_test.go index 42eff5c8d7..1b5c1ea8f1 100644 --- a/util/wsutil/wsutil_test.go +++ b/util/wsutil/wsutil_test.go @@ -1,11 +1,12 @@ package wsutil import ( - "github.com/gorilla/websocket" - "github.com/stretchr/testify/require" "io" "sync" "testing" + + "github.com/gorilla/websocket" + "github.com/stretchr/testify/require" ) type dummyConnection struct { diff --git a/x/audit/alias.go b/x/audit/alias.go index e566c57275..4500cd1be4 100644 --- a/x/audit/alias.go +++ b/x/audit/alias.go @@ -1,9 +1,9 @@ package audit import ( - types "github.com/akash-network/akash-api/go/node/audit/v1beta3" + types "pkg.akt.dev/go/node/audit/v1" - "github.com/akash-network/node/x/audit/keeper" + "pkg.akt.dev/node/x/audit/keeper" ) const ( diff --git a/x/audit/client/cli/cli_test.go b/x/audit/client/cli/cli_test.go deleted file mode 100644 index 7f1e458cd3..0000000000 --- a/x/audit/client/cli/cli_test.go +++ /dev/null @@ -1 +0,0 @@ -package cli diff --git a/x/audit/client/cli/query.go b/x/audit/client/cli/query.go deleted file mode 100644 index bb12780a8c..0000000000 --- a/x/audit/client/cli/query.go +++ /dev/null @@ -1,129 +0,0 @@ -package cli - -import ( - "context" - - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - - types "github.com/akash-network/akash-api/go/node/audit/v1beta3" - - aclient "github.com/akash-network/node/client" - clientutils "github.com/akash-network/node/client" -) - -func GetQueryCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: "Audit query commands", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - - cmd.AddCommand( - cmdGetProviders(), - cmdGetProvider(), - ) - - return cmd -} - -func cmdGetProviders() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "Query for all providers", - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientQueryContext(cmd) - if err != nil { - return err - } - - qq, err := aclient.DiscoverQueryClient(ctx, cctx) - if err != nil { - return err - } - - pageReq, err := clientutils.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - params := &types.QueryAllProvidersAttributesRequest{ - Pagination: pageReq, - } - - res, err := qq.AllProvidersAttributes(context.Background(), params) - if err != nil { - return err - } - - return qq.ClientContext().PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "providers") - - return cmd -} - -func cmdGetProvider() *cobra.Command { - cmd := &cobra.Command{ - Use: "get [owner address] [auditor address]", - Short: "Query provider", - Args: cobra.RangeArgs(1, 2), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientQueryContext(cmd) - if err != nil { - return err - } - - qq, err := aclient.DiscoverQueryClient(ctx, cctx) - if err != nil { - return err - } - - owner, err := sdk.AccAddressFromBech32(args[0]) - if err != nil { - return err - } - - var res *types.QueryProvidersResponse - if len(args) == 1 { - res, err = qq.ProviderAttributes(context.Background(), - &types.QueryProviderAttributesRequest{ - Owner: owner.String(), - }, - ) - } else { - var auditor sdk.AccAddress - if auditor, err = sdk.AccAddressFromBech32(args[1]); err != nil { - return err - } - - res, err = qq.ProviderAuditorAttributes(context.Background(), - &types.QueryProviderAuditorRequest{ - Auditor: auditor.String(), - Owner: owner.String(), - }, - ) - } - - if err != nil { - return err - } - - return qq.ClientContext().PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} diff --git a/x/audit/client/cli/tx.go b/x/audit/client/cli/tx.go deleted file mode 100644 index 9fbdb243c7..0000000000 --- a/x/audit/client/cli/tx.go +++ /dev/null @@ -1,252 +0,0 @@ -package cli - -import ( - "fmt" - "sort" - - cltypes "github.com/akash-network/akash-api/go/node/client/types" - "github.com/spf13/cobra" - - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - - types "github.com/akash-network/akash-api/go/node/audit/v1beta3" - ptypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" - akashtypes "github.com/akash-network/akash-api/go/node/types/v1beta3" - atypes "github.com/akash-network/akash-api/go/node/types/v1beta3" - - aclient "github.com/akash-network/node/client" -) - -// GetTxCmd returns the transaction commands for audit module -func GetTxCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: "Audit transaction subcommands", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - - cmd.AddCommand( - cmdAttributes(), - ) - - return cmd -} - -func cmdAttributes() *cobra.Command { - cmd := &cobra.Command{ - Use: "attr", - Short: "Manage provider attributes", - } - - cmd.AddCommand( - cmdCreateProviderAttributes(), - cmdDeleteProviderAttributes(), - ) - - return cmd -} - -func cmdCreateProviderAttributes() *cobra.Command { - cmd := &cobra.Command{ - Use: "create [provider]", - Short: "Create/update provider attributes", - Args: cobra.MinimumNArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - if ((len(args) - 1) % 2) != 0 { - return fmt.Errorf("attributes must be provided as pairs") - } - - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - providerAddress, err := sdk.AccAddressFromBech32(args[0]) - if err != nil { - return err - } - - attr, err := readAttributes(cmd, cctx, providerAddress.String(), args[1:]) - if err != nil { - return err - } - - if len(attr) == 0 { - return fmt.Errorf("no attributes provided|found") - } - - msg := &types.MsgSignProviderAttributes{ - Auditor: cctx.GetFromAddress().String(), - Owner: providerAddress.String(), - Attributes: attr, - } - - if err = msg.ValidateBasic(); err != nil { - return err - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - setCmdProviderFlags(cmd) - - return cmd -} - -func cmdDeleteProviderAttributes() *cobra.Command { - cmd := &cobra.Command{ - Use: "delete [provider]", - Short: "Delete provider attributes", - Args: cobra.MinimumNArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - providerAddress, err := sdk.AccAddressFromBech32(args[0]) - if err != nil { - return err - } - - keys, err := readKeys(args[1:]) - if err != nil { - return err - } - - msg := &types.MsgDeleteProviderAttributes{ - Auditor: cctx.GetFromAddress().String(), - Owner: providerAddress.String(), - Keys: keys, - } - - if err = msg.ValidateBasic(); err != nil { - return err - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - setCmdProviderFlags(cmd) - - return cmd -} - -func setCmdProviderFlags(cmd *cobra.Command) { - flags.AddTxFlagsToCmd(cmd) - - if err := cmd.MarkFlagRequired(flags.FlagFrom); err != nil { - panic(err.Error()) - } -} - -// readAttributes try read attributes from both cobra arguments or query -// if no arguments were provided then query provider and sign all found -// read from stdin uses trick to check if it's file descriptor is a pipe -// which happens when some data is piped for example cat attr.yaml | akash ... -func readAttributes(cmd *cobra.Command, cctx sdkclient.Context, provider string, args []string) (akashtypes.Attributes, error) { - var attr akashtypes.Attributes - - if len(args) != 0 { - for i := 0; i < len(args); i += 2 { - attr = append(attr, atypes.Attribute{ - Key: args[i], - Value: args[i+1], - }) - } - } else { - resp, err := ptypes.NewQueryClient(cctx).Provider(cmd.Context(), &ptypes.QueryProviderRequest{Owner: provider}) - if err != nil { - return nil, err - } - - attr = append(attr, resp.Provider.Attributes...) - } - - sort.SliceStable(attr, func(i, j int) bool { - return attr[i].Key < attr[j].Value - }) - - if checkAttributeDuplicates(attr) { - return nil, fmt.Errorf("supplied attributes with duplicate keys") - } - - return attr, nil -} - -func readKeys(args []string) ([]string, error) { - sort.SliceStable(args, func(i, j int) bool { - return args[i] < args[j] - }) - - if checkKeysDuplicates(args) { - return nil, fmt.Errorf("supplied attributes with duplicate keys") - } - - return args, nil -} - -func checkAttributeDuplicates(attr akashtypes.Attributes) bool { - keys := make(map[string]bool) - - for _, entry := range attr { - if _, value := keys[entry.Key]; !value { - keys[entry.Key] = true - } else { - return true - } - } - return false -} - -func checkKeysDuplicates(k []string) bool { - keys := make(map[string]bool) - - for _, entry := range k { - if _, value := keys[entry]; !value { - keys[entry] = true - } else { - return true - } - } - return false -} diff --git a/x/audit/client/rest/rest.go b/x/audit/client/rest/rest.go deleted file mode 100644 index 83afbf38dd..0000000000 --- a/x/audit/client/rest/rest.go +++ /dev/null @@ -1,87 +0,0 @@ -package rest - -import ( - "fmt" - "net/http" - - "github.com/cosmos/cosmos-sdk/client" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/gorilla/mux" - - types "github.com/akash-network/akash-api/go/node/audit/v1beta3" - - "github.com/akash-network/node/x/audit/query" -) - -// RegisterRoutes registers all query routes -func RegisterRoutes(ctx client.Context, r *mux.Router, ns string) { - prefix := fmt.Sprintf("/%s/attributes", ns) - - // Get all signed - r.HandleFunc(fmt.Sprintf("/%s/list", prefix), listAllSignedHandler(ctx, ns)).Methods("GET") - r.HandleFunc(fmt.Sprintf("/%s/owner/{providerOwner}/list", prefix), listProviderAttributes(ctx, ns)).Methods("GET") - r.HandleFunc(fmt.Sprintf("/%s/auditor/{auditor}/{providerOwner}", prefix), listAuditorProviderAttributes(ctx, ns)).Methods("GET") -} - -func listAllSignedHandler(ctx client.Context, ns string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - res, err := query.NewRawClient(ctx, ns).AllProviders() - if err != nil { - rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") - return - } - rest.PostProcessResponse(w, ctx, res) - } -} - -func listProviderAttributes(ctx client.Context, ns string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - id, err := sdk.AccAddressFromBech32(mux.Vars(r)["providerOwner"]) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, "Invalid address") - return - } - - res, err := query.NewRawClient(ctx, ns).Provider(id) - if err != nil { - rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") - return - } - rest.PostProcessResponse(w, ctx, res) - } -} - -func listAuditorProviderAttributes(ctx client.Context, ns string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - auditor, err := sdk.AccAddressFromBech32(mux.Vars(r)["auditor"]) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, "Invalid address") - return - } - - var res []byte - - if addr := mux.Vars(r)["providerOwner"]; addr == "list" { - res, err = query.NewRawClient(ctx, ns).Auditor(auditor) - } else { - var owner sdk.AccAddress - if owner, err = sdk.AccAddressFromBech32(addr); err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, "Invalid address") - return - } - - res, err = query.NewRawClient(ctx, ns).ProviderID(types.ProviderID{ - Owner: owner, - Auditor: auditor, - }) - } - - if err != nil { - rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") - return - } - - rest.PostProcessResponse(w, ctx, res) - } -} diff --git a/x/audit/genesis.go b/x/audit/genesis.go index fca1b78838..0ffcffadf8 100644 --- a/x/audit/genesis.go +++ b/x/audit/genesis.go @@ -2,21 +2,20 @@ package audit import ( "encoding/json" - "sort" + + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/akash-network/node/x/audit/keeper" + types "pkg.akt.dev/go/node/audit/v1" - types "github.com/akash-network/akash-api/go/node/audit/v1beta3" + "pkg.akt.dev/node/x/audit/keeper" ) -// ValidateGenesis does validation check of the Genesis and returns error incase of failure +// ValidateGenesis does validation check of the Genesis and returns error in-case of failure func ValidateGenesis(data *types.GenesisState) error { - for _, record := range data.Attributes { + for _, record := range data.Providers { if _, err := sdk.AccAddressFromBech32(record.Owner); err != nil { return sdkerrors.ErrInvalidAddress.Wrap("audited attributes: invalid owner address") } @@ -26,7 +25,7 @@ func ValidateGenesis(data *types.GenesisState) error { } if err := record.Attributes.Validate(); err != nil { - return sdkerrors.Wrap(err, "audited attributes: invalid attributes") + return errorsmod.Wrap(err, "audited attributes: invalid attributes") } } @@ -34,12 +33,10 @@ func ValidateGenesis(data *types.GenesisState) error { } // InitGenesis initiate genesis state and return updated validator details -func InitGenesis(ctx sdk.Context, kpr keeper.Keeper, data *types.GenesisState) []abci.ValidatorUpdate { - store := ctx.KVStore(kpr.StoreKey()) - cdc := kpr.Codec() - - for _, record := range data.Attributes { +func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, data *types.GenesisState) { + for _, record := range data.Providers { owner, err := sdk.AccAddressFromBech32(record.Owner) + if err != nil { panic(sdkerrors.ErrInvalidAddress.Wrap("audited attributes: invalid owner address").Error()) } @@ -49,33 +46,22 @@ func InitGenesis(ctx sdk.Context, kpr keeper.Keeper, data *types.GenesisState) [ panic(sdkerrors.ErrInvalidAddress.Wrap("audited attributes: invalid auditor address")) } - key := keeper.ProviderKey(types.ProviderID{ + err = keeper.CreateOrUpdateProviderAttributes(ctx, types.ProviderID{ Owner: owner, Auditor: auditor, - }) - - prov := types.Provider{ - Owner: record.Owner, - Auditor: record.Auditor, - Attributes: record.Attributes, + }, record.Attributes) + if err != nil { + panic(errorsmod.Wrap(err, "unable to init genesis with provider")) } - - sort.SliceStable(prov.Attributes, func(i, j int) bool { - return prov.Attributes[i].Key < prov.Attributes[j].Key - }) - - store.Set(key, cdc.MustMarshal(&prov)) } - - return []abci.ValidatorUpdate{} } // ExportGenesis returns genesis state as raw bytes for the provider module func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { - var records []types.AuditedAttributes + var records []types.AuditedProvider - k.WithProviders(ctx, func(provider types.Provider) bool { - records = append(records, types.AuditedAttributes{ + k.WithProviders(ctx, func(provider types.AuditedProvider) bool { + records = append(records, types.AuditedProvider{ Owner: provider.Owner, Auditor: provider.Auditor, Attributes: provider.Attributes.Dup(), @@ -84,7 +70,7 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { }) return &types.GenesisState{ - Attributes: records, + Providers: records, } } diff --git a/x/audit/handler/handler.go b/x/audit/handler/handler.go index f064702478..112323a8e8 100644 --- a/x/audit/handler/handler.go +++ b/x/audit/handler/handler.go @@ -1,28 +1,31 @@ package handler import ( + errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - types "github.com/akash-network/akash-api/go/node/audit/v1beta3" + types "pkg.akt.dev/go/node/audit/v1" - "github.com/akash-network/node/x/audit/keeper" + "pkg.akt.dev/node/x/audit/keeper" ) // NewHandler returns a handler for "provider" type messages. -func NewHandler(keeper keeper.Keeper) sdk.Handler { +func NewHandler(keeper keeper.Keeper) baseapp.MsgServiceHandler { ms := NewMsgServerImpl(keeper) return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { switch msg := msg.(type) { case *types.MsgSignProviderAttributes: - res, err := ms.SignProviderAttributes(sdk.WrapSDKContext(ctx), msg) + res, err := ms.SignProviderAttributes(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) case *types.MsgDeleteProviderAttributes: - res, err := ms.DeleteProviderAttributes(sdk.WrapSDKContext(ctx), msg) + res, err := ms.DeleteProviderAttributes(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) } - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized message type: %T", msg) + return nil, errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized message type: %T", msg) } } diff --git a/x/audit/handler/handler_test.go b/x/audit/handler/handler_test.go index 96008766ec..b1fecf6232 100644 --- a/x/audit/handler/handler_test.go +++ b/x/audit/handler/handler_test.go @@ -5,27 +5,34 @@ import ( "sort" "testing" - "github.com/cosmos/cosmos-sdk/store" + "github.com/stretchr/testify/require" + + "cosmossdk.io/log" + "cosmossdk.io/store" + storemetrics "cosmossdk.io/store/metrics" + storetypes "cosmossdk.io/store/types" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/baseapp" sdktestdata "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/stretchr/testify/require" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - dbm "github.com/tendermint/tm-db" + testutilmod "github.com/cosmos/cosmos-sdk/types/module/testutil" - types "github.com/akash-network/akash-api/go/node/audit/v1beta3" + types "pkg.akt.dev/go/node/audit/v1" - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/x/audit/handler" - "github.com/akash-network/node/x/audit/keeper" + "pkg.akt.dev/go/testutil" + + "pkg.akt.dev/node/x/audit/handler" + "pkg.akt.dev/node/x/audit/keeper" ) type testSuite struct { t testing.TB - ms sdk.CommitMultiStore + ms store.CommitMultiStore ctx sdk.Context keeper keeper.Keeper - handler sdk.Handler + handler baseapp.MsgServiceHandler } func setupTestSuite(t *testing.T) *testSuite { @@ -33,18 +40,21 @@ func setupTestSuite(t *testing.T) *testSuite { t: t, } - aKey := sdk.NewTransientStoreKey(types.StoreKey) + cfg := testutilmod.MakeTestEncodingConfig() + cdc := cfg.Codec + + aKey := storetypes.NewTransientStoreKey(types.StoreKey) db := dbm.NewMemDB() - suite.ms = store.NewCommitMultiStore(db) - suite.ms.MountStoreWithDB(aKey, sdk.StoreTypeIAVL, db) + suite.ms = store.NewCommitMultiStore(db, log.NewNopLogger(), storemetrics.NewNoOpMetrics()) + suite.ms.MountStoreWithDB(aKey, storetypes.StoreTypeIAVL, db) err := suite.ms.LoadLatestVersion() require.NoError(t, err) suite.ctx = sdk.NewContext(suite.ms, tmproto.Header{}, true, testutil.Logger(t)) - suite.keeper = keeper.NewKeeper(types.ModuleCdc, aKey) + suite.keeper = keeper.NewKeeper(cdc, aKey) suite.handler = handler.NewHandler(suite.keeper) @@ -190,14 +200,14 @@ func TestProviderDeleteAttribute(t *testing.T) { require.Equal(t, prov, msgSignProviderAttributesToResponse(msg)) } -func msgSignProviderAttributesToResponse(msg *types.MsgSignProviderAttributes) types.Providers { +func msgSignProviderAttributesToResponse(msg *types.MsgSignProviderAttributes) types.AuditedProviders { // create handler sorts attributes, so do we to ensure same order sort.SliceStable(msg.Attributes, func(i, j int) bool { return msg.Attributes[i].Key < msg.Attributes[j].Key }) - return types.Providers{ + return types.AuditedProviders{ { Owner: msg.Owner, Auditor: msg.Auditor, diff --git a/x/audit/handler/msg_server.go b/x/audit/handler/msg_server.go index 157d3b8bc7..f5aac32c55 100644 --- a/x/audit/handler/msg_server.go +++ b/x/audit/handler/msg_server.go @@ -5,9 +5,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - types "github.com/akash-network/akash-api/go/node/audit/v1beta3" + types "pkg.akt.dev/go/node/audit/v1" - "github.com/akash-network/node/x/audit/keeper" + "pkg.akt.dev/node/x/audit/keeper" ) type msgServer struct { diff --git a/x/audit/keeper/grpc_query.go b/x/audit/keeper/grpc_query.go index 51e68b237a..b7799b16bb 100644 --- a/x/audit/keeper/grpc_query.go +++ b/x/audit/keeper/grpc_query.go @@ -3,12 +3,13 @@ package keeper import ( "context" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkquery "github.com/cosmos/cosmos-sdk/types/query" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - types "github.com/akash-network/akash-api/go/node/audit/v1beta3" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkquery "github.com/cosmos/cosmos-sdk/types/query" + + types "pkg.akt.dev/go/node/audit/v1" ) // Querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over keeper @@ -26,13 +27,13 @@ func (q Querier) AllProvidersAttributes( return nil, status.Error(codes.InvalidArgument, "empty request") } - var providers types.Providers + var providers types.AuditedProviders ctx := sdk.UnwrapSDKContext(c) store := ctx.KVStore(q.skey) - pageRes, err := sdkquery.Paginate(store, req.Pagination, func(key []byte, value []byte) error { - var provider types.Provider + pageRes, err := sdkquery.Paginate(store, req.Pagination, func(_ []byte, value []byte) error { + var provider types.AuditedProvider err := q.cdc.Unmarshal(value, &provider) if err != nil { @@ -107,7 +108,7 @@ func (q Querier) ProviderAuditorAttributes( } return &types.QueryProvidersResponse{ - Providers: types.Providers{provider}, + Providers: types.AuditedProviders{provider}, Pagination: nil, }, nil } @@ -120,13 +121,13 @@ func (q Querier) AuditorAttributes( return nil, status.Error(codes.InvalidArgument, "empty request") } - var providers types.Providers + var providers types.AuditedProviders ctx := sdk.UnwrapSDKContext(c) store := ctx.KVStore(q.skey) - pageRes, err := sdkquery.Paginate(store, req.Pagination, func(key []byte, value []byte) error { - var provider types.Provider + pageRes, err := sdkquery.Paginate(store, req.Pagination, func(_ []byte, value []byte) error { + var provider types.AuditedProvider err := q.cdc.Unmarshal(value, &provider) if err != nil { diff --git a/x/audit/keeper/grpc_query_test.go b/x/audit/keeper/grpc_query_test.go index 0903dd3603..f267e7ff7c 100644 --- a/x/audit/keeper/grpc_query_test.go +++ b/x/audit/keeper/grpc_query_test.go @@ -4,17 +4,17 @@ import ( "fmt" "testing" - sdkquery "github.com/cosmos/cosmos-sdk/types/query" "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" + sdkquery "github.com/cosmos/cosmos-sdk/types/query" - types "github.com/akash-network/akash-api/go/node/audit/v1beta3" + types "pkg.akt.dev/go/node/audit/v1" + "pkg.akt.dev/go/testutil" - "github.com/akash-network/node/app" - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/x/audit/keeper" + "pkg.akt.dev/node/app" + "pkg.akt.dev/node/x/audit/keeper" ) type grpcTestSuite struct { @@ -31,7 +31,8 @@ func setupTest(t *testing.T) *grpcTestSuite { t: t, } - suite.app = app.Setup(false) + suite.app = app.Setup(app.WithGenesis(app.GenesisStateWithValSet)) + suite.ctx, suite.keeper = setupKeeper(t) querier := keeper.Querier{Keeper: suite.keeper} @@ -51,7 +52,7 @@ func TestGRPCQueryProvider(t *testing.T) { require.NoError(t, err) var req *types.QueryProviderAuditorRequest - var expProvider types.Provider + var expProvider types.AuditedProvider testCases := []struct { msg string @@ -91,7 +92,7 @@ func TestGRPCQueryProvider(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { tc.malleate() - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx res, err := suite.queryClient.ProviderAuditorAttributes(ctx, req) @@ -151,7 +152,7 @@ func TestGRPCQueryProviders(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { tc.malleate() - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx res, err := suite.queryClient.AllProvidersAttributes(ctx, req) diff --git a/x/audit/keeper/keeper.go b/x/audit/keeper/keeper.go index 9b398c44f6..a90486c7ef 100644 --- a/x/audit/keeper/keeper.go +++ b/x/audit/keeper/keeper.go @@ -3,34 +3,31 @@ package keeper import ( "sort" + storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - types "github.com/akash-network/akash-api/go/node/audit/v1beta3" - - akashtypes "github.com/akash-network/akash-api/go/node/types/v1beta3" - atypes "github.com/akash-network/akash-api/go/node/types/v1beta3" + types "pkg.akt.dev/go/node/audit/v1" + attrv1 "pkg.akt.dev/go/node/types/attributes/v1" ) -// TODO: use interfaces for keepers, queriers type IKeeper interface { - GetProviderByAuditor(ctx sdk.Context, id types.ProviderID) (types.Provider, bool) - GetProviderAttributes(ctx sdk.Context, id sdk.Address) (types.Providers, bool) - CreateOrUpdateProviderAttributes(ctx sdk.Context, id types.ProviderID, attr akashtypes.Attributes) error + GetProviderByAuditor(ctx sdk.Context, id types.ProviderID) (types.AuditedProvider, bool) + GetProviderAttributes(ctx sdk.Context, id sdk.Address) (types.AuditedProviders, bool) + CreateOrUpdateProviderAttributes(ctx sdk.Context, id types.ProviderID, attr attrv1.Attributes) error DeleteProviderAttributes(ctx sdk.Context, id types.ProviderID, keys []string) error - WithProviders(ctx sdk.Context, fn func(types.Provider) bool) - WithProvider(ctx sdk.Context, id sdk.Address, fn func(types.Provider) bool) + WithProviders(ctx sdk.Context, fn func(types.AuditedProvider) bool) + WithProvider(ctx sdk.Context, id sdk.Address, fn func(types.AuditedProvider) bool) } // Keeper of the provider store type Keeper struct { - skey sdk.StoreKey + skey storetypes.StoreKey cdc codec.BinaryCodec } // NewKeeper creates and returns an instance for Market keeper -func NewKeeper(cdc codec.BinaryCodec, skey sdk.StoreKey) Keeper { +func NewKeeper(cdc codec.BinaryCodec, skey storetypes.StoreKey) Keeper { return Keeper{cdc: cdc, skey: skey} } @@ -40,65 +37,74 @@ func (k Keeper) Codec() codec.BinaryCodec { } // StoreKey returns store key -func (k Keeper) StoreKey() sdk.StoreKey { +func (k Keeper) StoreKey() storetypes.StoreKey { return k.skey } // GetProviderByAuditor returns a provider with given auditor and owner id -func (k Keeper) GetProviderByAuditor(ctx sdk.Context, id types.ProviderID) (types.Provider, bool) { +func (k Keeper) GetProviderByAuditor(ctx sdk.Context, id types.ProviderID) (types.AuditedProvider, bool) { store := ctx.KVStore(k.skey) buf := store.Get(ProviderKey(id)) if buf == nil { - return types.Provider{}, false + return types.AuditedProvider{}, false } - var val types.Provider - k.cdc.MustUnmarshal(buf, &val) + var sVal types.AuditedAttributesStore + k.cdc.MustUnmarshal(buf, &sVal) - return val, true + return types.AuditedProvider{ + Owner: id.Owner.String(), + Auditor: id.Auditor.String(), + Attributes: sVal.Attributes, + }, true } // GetProviderAttributes returns a provider with given auditor and owner id's -func (k Keeper) GetProviderAttributes(ctx sdk.Context, id sdk.Address) (types.Providers, bool) { +func (k Keeper) GetProviderAttributes(ctx sdk.Context, id sdk.Address) (types.AuditedProviders, bool) { store := ctx.KVStore(k.skey) - var attr types.Providers + var res types.AuditedProviders - iter := sdk.KVStorePrefixIterator(store, ProviderPrefix(id)) + prefix := ProviderPrefix(id) + iter := storetypes.KVStorePrefixIterator(store, prefix) defer func() { _ = iter.Close() }() for ; iter.Valid(); iter.Next() { - var val types.Provider - k.cdc.MustUnmarshal(iter.Value(), &val) - attr = append(attr, val) + aID := ParseIDFromKey(iter.Key()) + + var sVal types.AuditedAttributesStore + k.cdc.MustUnmarshal(iter.Value(), &sVal) + res = append(res, types.AuditedProvider{ + Owner: id.String(), + Auditor: aID.Auditor.String(), + Attributes: sVal.Attributes, + }) } - if len(attr) == 0 { + if len(res) == 0 { return nil, false } - return attr, true + return res, true } // CreateOrUpdateProviderAttributes update signed provider attributes. // creates new if key does not exist // if key exists, existing values for matching pairs will be replaced -func (k Keeper) CreateOrUpdateProviderAttributes(ctx sdk.Context, id types.ProviderID, attr akashtypes.Attributes) error { +func (k Keeper) CreateOrUpdateProviderAttributes(ctx sdk.Context, id types.ProviderID, attr attrv1.Attributes) error { store := ctx.KVStore(k.skey) key := ProviderKey(id) - prov := types.Provider{ - Owner: id.Owner.String(), - Auditor: id.Auditor.String(), + attrRec := types.AuditedAttributesStore{ Attributes: attr, } buf := store.Get(key) if buf != nil { - tmp := types.Provider{} + tmp := types.AuditedAttributesStore{} k.cdc.MustUnmarshal(buf, &tmp) kv := make(map[string]string) @@ -107,31 +113,35 @@ func (k Keeper) CreateOrUpdateProviderAttributes(ctx sdk.Context, id types.Provi kv[entry.Key] = entry.Value } - for _, entry := range prov.Attributes { + for _, entry := range attrRec.Attributes { kv[entry.Key] = entry.Value } - attr = akashtypes.Attributes{} + attr = attrv1.Attributes{} for ky, val := range kv { - attr = append(attr, atypes.Attribute{ + attr = append(attr, attrv1.Attribute{ Key: ky, Value: val, }) } - prov.Attributes = attr + attrRec.Attributes = attr } - sort.SliceStable(prov.Attributes, func(i, j int) bool { - return prov.Attributes[i].Key < prov.Attributes[j].Key - }) + sort.Stable(attrRec.Attributes) - store.Set(key, k.cdc.MustMarshal(&prov)) + store.Set(key, k.cdc.MustMarshal(&attrRec)) - ctx.EventManager().EmitEvent( - types.NewEventTrustedAuditorCreated(id.Owner, id.Auditor).ToSDKEvent(), + err := ctx.EventManager().EmitTypedEvent( + &types.EventTrustedAuditorCreated{ + Owner: id.Owner.String(), + Auditor: id.Auditor.String(), + }, ) + if err != nil { + return err + } return nil } @@ -148,12 +158,9 @@ func (k Keeper) DeleteProviderAttributes(ctx sdk.Context, id types.ProviderID, k if keys == nil { store.Delete(key) } else { - prov := types.Provider{ - Owner: id.Owner.String(), - Auditor: id.Auditor.String(), - } + prov := types.AuditedAttributesStore{} - tmp := types.Provider{} + tmp := types.AuditedAttributesStore{} k.cdc.MustUnmarshal(buf, &tmp) kv := make(map[string]string) @@ -164,19 +171,19 @@ func (k Keeper) DeleteProviderAttributes(ctx sdk.Context, id types.ProviderID, k for _, entry := range keys { if _, exists := kv[entry]; !exists { - return sdkerrors.Wrapf(types.ErrAttributeNotFound, "trying to delete non-existing attribute \"%s\" for auditor/provider \"%s/%s\"", + return types.ErrAttributeNotFound.Wrapf("trying to delete non-existing attribute \"%s\" for auditor/provider \"%s/%s\"", entry, - prov.Auditor, - prov.Owner) + id.Auditor, + id.Owner) } delete(kv, entry) } - var attr akashtypes.Attributes + var attr attrv1.Attributes for ky, val := range kv { - attr = append(attr, atypes.Attribute{ + attr = append(attr, attrv1.Attribute{ Key: ky, Value: val, }) @@ -195,41 +202,65 @@ func (k Keeper) DeleteProviderAttributes(ctx sdk.Context, id types.ProviderID, k } } - ctx.EventManager().EmitEvent( - types.NewEventTrustedAuditorDeleted(id.Owner, id.Auditor).ToSDKEvent(), + err := ctx.EventManager().EmitTypedEvent( + &types.EventTrustedAuditorDeleted{ + Owner: id.Owner.String(), + Auditor: id.Auditor.String(), + }, ) + if err != nil { + return err + } return nil } // WithProviders iterates all signed provider's attributes -func (k Keeper) WithProviders(ctx sdk.Context, fn func(types.Provider) bool) { +func (k Keeper) WithProviders(ctx sdk.Context, fn func(types.AuditedProvider) bool) { store := ctx.KVStore(k.skey) - iter := store.Iterator(nil, nil) + iter := storetypes.KVStorePrefixIterator(store, types.PrefixProviderID()) defer func() { _ = iter.Close() }() for ; iter.Valid(); iter.Next() { - var val types.Provider - k.cdc.MustUnmarshal(iter.Value(), &val) + id := ParseIDFromKey(iter.Key()) + + var attr types.AuditedAttributesStore + k.cdc.MustUnmarshal(iter.Value(), &attr) + + val := types.AuditedProvider{ + Owner: id.Owner.String(), + Auditor: id.Auditor.String(), + Attributes: attr.Attributes, + } + if stop := fn(val); stop { break } } } -// WithProvider iterates all signed provider's attributes -func (k Keeper) WithProvider(ctx sdk.Context, id sdk.Address, fn func(types.Provider) bool) { +// WithProvider returns requested signed provider attributes +func (k Keeper) WithProvider(ctx sdk.Context, id sdk.Address, fn func(types.AuditedProvider) bool) { store := ctx.KVStore(k.skey) - iter := sdk.KVStorePrefixIterator(store, ProviderPrefix(id)) + iter := storetypes.KVStorePrefixIterator(store, ProviderPrefix(id)) defer func() { _ = iter.Close() }() for ; iter.Valid(); iter.Next() { - var val types.Provider + aID := ParseIDFromKey(iter.Key()) + + var attr types.AuditedAttributesStore + k.cdc.MustUnmarshal(iter.Value(), &attr) + + val := types.AuditedProvider{ + Owner: id.String(), + Auditor: aID.Auditor.String(), + Attributes: attr.Attributes, + } k.cdc.MustUnmarshal(iter.Value(), &val) if stop := fn(val); stop { break diff --git a/x/audit/keeper/keeper_test.go b/x/audit/keeper/keeper_test.go index c1449ba9dd..23f1f05215 100644 --- a/x/audit/keeper/keeper_test.go +++ b/x/audit/keeper/keeper_test.go @@ -6,17 +6,22 @@ import ( "testing" "time" - "github.com/cosmos/cosmos-sdk/store" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/libs/rand" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - dbm "github.com/tendermint/tm-db" - types "github.com/akash-network/akash-api/go/node/audit/v1beta3" + "cosmossdk.io/log" + "cosmossdk.io/store" + storemetrics "cosmossdk.io/store/metrics" + storetypes "cosmossdk.io/store/types" + "github.com/cometbft/cometbft/libs/rand" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + dbm "github.com/cosmos/cosmos-db" + sdk "github.com/cosmos/cosmos-sdk/types" + testutilmod "github.com/cosmos/cosmos-sdk/types/module/testutil" + + types "pkg.akt.dev/go/node/audit/v1" + "pkg.akt.dev/go/testutil" - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/x/audit/keeper" + "pkg.akt.dev/node/x/audit/keeper" ) func TestProviderCreate(t *testing.T) { @@ -28,7 +33,7 @@ func TestProviderCreate(t *testing.T) { foundProv, found := keeper.GetProviderAttributes(ctx, id.Owner) require.True(t, found) - require.Equal(t, types.Providers{prov}, foundProv) + require.Equal(t, types.AuditedProviders{prov}, foundProv) } func TestProviderUpdateAppendNewAttributes(t *testing.T) { @@ -54,7 +59,7 @@ func TestProviderUpdateAppendNewAttributes(t *testing.T) { foundProv, found := keeper.GetProviderAttributes(ctx, id.Owner) require.True(t, found) - require.Equal(t, types.Providers{prov}, foundProv) + require.Equal(t, types.AuditedProviders{prov}, foundProv) } func TestProviderUpdateOverrideAttributes(t *testing.T) { @@ -77,7 +82,7 @@ func TestProviderUpdateOverrideAttributes(t *testing.T) { foundProv, found := keeper.GetProviderAttributes(ctx, id.Owner) require.True(t, found) - require.Equal(t, types.Providers{prov}, foundProv) + require.Equal(t, types.AuditedProviders{prov}, foundProv) } func TestProviderDeleteExistingAttributes(t *testing.T) { @@ -101,7 +106,7 @@ func TestProviderDeleteExistingAttributes(t *testing.T) { foundProv, found := keeper.GetProviderAttributes(ctx, id.Owner) require.True(t, found) - require.Equal(t, types.Providers{prov}, foundProv) + require.Equal(t, types.AuditedProviders{prov}, foundProv) } func TestProviderDeleteNonExistingAttributes(t *testing.T) { @@ -152,12 +157,19 @@ func TestKeeperCoder(t *testing.T) { func setupKeeper(t testing.TB) (sdk.Context, keeper.Keeper) { t.Helper() - key := sdk.NewKVStoreKey(types.StoreKey) + + cfg := testutilmod.MakeTestEncodingConfig() + cdc := cfg.Codec + + key := storetypes.NewKVStoreKey(types.StoreKey) db := dbm.NewMemDB() - ms := store.NewCommitMultiStore(db) - ms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db) + + ms := store.NewCommitMultiStore(db, log.NewNopLogger(), storemetrics.NewNoOpMetrics()) + ms.MountStoreWithDB(key, storetypes.StoreTypeIAVL, db) + err := ms.LoadLatestVersion() require.NoError(t, err) + ctx := sdk.NewContext(ms, tmproto.Header{Time: time.Unix(0, 0)}, false, testutil.Logger(t)) - return ctx, keeper.NewKeeper(types.ModuleCdc, key) + return ctx, keeper.NewKeeper(cdc, key) } diff --git a/x/audit/keeper/key.go b/x/audit/keeper/key.go index dc7e597ff4..75cf186c2f 100644 --- a/x/audit/keeper/key.go +++ b/x/audit/keeper/key.go @@ -2,12 +2,15 @@ package keeper import ( "bytes" + "encoding/hex" + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" - sdk "github.com/cosmos/cosmos-sdk/types" + types "pkg.akt.dev/go/node/audit/v1" - types "github.com/akash-network/akash-api/go/node/audit/v1beta3" + "pkg.akt.dev/node/util/validation" ) func ProviderKey(id types.ProviderID) []byte { @@ -31,3 +34,35 @@ func ProviderPrefix(id sdk.Address) []byte { return buf.Bytes() } + +func ParseIDFromKey(key []byte) types.ProviderID { + // skip prefix if set + + validation.AssertKeyAtLeastLength(key, len(types.PrefixProviderID())+1) + if !bytes.HasPrefix(key, types.PrefixProviderID()) { + panic(fmt.Sprintf("invalid key prefix. expected 0x%s, actual 0x%s", hex.EncodeToString(key[:1]), types.PrefixProviderID())) + } + + // remove a prefix key + key = key[len(types.PrefixProviderID()):] + + dataLen := int(key[0]) + key = key[1:] + validation.AssertKeyAtLeastLength(key, dataLen) + + owner := make([]byte, dataLen) + copy(owner, key[:dataLen]) + key = key[dataLen:] + validation.AssertKeyAtLeastLength(key, 1) + + dataLen = int(key[0]) + key = key[1:] + validation.AssertKeyLength(key, dataLen) + auditor := make([]byte, dataLen) + copy(auditor, key[:dataLen]) + + return types.ProviderID{ + Owner: sdk.AccAddress(owner), + Auditor: sdk.AccAddress(auditor), + } +} diff --git a/x/audit/module.go b/x/audit/module.go index a935a74aea..b4d0078e2e 100644 --- a/x/audit/module.go +++ b/x/audit/module.go @@ -4,38 +4,35 @@ import ( "context" "encoding/json" "fmt" - "math/rand" - "github.com/spf13/cobra" - - "github.com/gogo/protobuf/grpc" - "github.com/gorilla/mux" + "cosmossdk.io/core/appmodule" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/grpc-ecosystem/grpc-gateway/runtime" - - abci "github.com/tendermint/tendermint/abci/types" + "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - sim "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/gogoproto/grpc" - v1beta1types "github.com/akash-network/akash-api/go/node/audit/v1beta1" - v1beta2types "github.com/akash-network/akash-api/go/node/audit/v1beta2" - types "github.com/akash-network/akash-api/go/node/audit/v1beta3" + types "pkg.akt.dev/go/node/audit/v1" - "github.com/akash-network/node/x/audit/client/cli" - "github.com/akash-network/node/x/audit/client/rest" - "github.com/akash-network/node/x/audit/handler" - "github.com/akash-network/node/x/audit/keeper" - pkeeper "github.com/akash-network/node/x/provider/keeper" + "pkg.akt.dev/node/x/audit/handler" + "pkg.akt.dev/node/x/audit/keeper" ) var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} - _ module.AppModuleSimulation = AppModuleSimulation{} + _ module.AppModuleBasic = AppModuleBasic{} + _ module.HasGenesisBasics = AppModuleBasic{} + + _ appmodule.AppModule = AppModule{} + _ module.HasConsensusVersion = AppModule{} + _ module.HasGenesis = AppModule{} + _ module.HasServices = AppModule{} + + _ module.AppModuleSimulation = AppModule{} ) // AppModuleBasic defines the basic application module used by the provider module. @@ -50,14 +47,12 @@ func (AppModuleBasic) Name() string { // RegisterLegacyAminoCodec registers the provider module's types for the given codec. func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { - types.RegisterLegacyAminoCodec(cdc) + types.RegisterLegacyAminoCodec(cdc) // nolint: staticcheck } // RegisterInterfaces registers the module's interface types func (b AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) { types.RegisterInterfaces(registry) - v1beta2types.RegisterInterfaces(registry) - v1beta1types.RegisterInterfaces(registry) } // DefaultGenesis returns default genesis state as raw bytes for the provider @@ -84,10 +79,10 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingCo return ValidateGenesis(&data) } -// RegisterRESTRoutes registers rest routes for this module -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { - rest.RegisterRoutes(clientCtx, rtr, StoreKey) -} +// // RegisterRESTRoutes registers rest routes for this module +// func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { +// rest.RegisterRoutes(clientCtx, rtr, StoreKey) +// } // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the provider module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { @@ -107,12 +102,12 @@ func (AppModuleBasic) RegisterGRPCRoutes(clientCtx client.Context, mux *runtime. // GetQueryCmd returns the root query command of this module func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.GetQueryCmd() + panic("akash modules do not export cli commands via cosmos interface") } // GetTxCmd returns the transaction commands for this module func (AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.GetTxCmd() + panic("akash modules do not export cli commands via cosmos interface") } // GetQueryClient returns a new query client for this module @@ -139,28 +134,23 @@ func (AppModule) Name() string { return types.ModuleName } -// RegisterInvariants registers module invariants -func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (am AppModule) IsOnePerModuleType() {} -// Route returns the message routing key for the audit module. -func (am AppModule) Route() sdk.Route { - return sdk.NewRoute(types.RouterKey, handler.NewHandler(am.keeper)) -} +// IsAppModule implements the appmodule.AppModule interface. +func (am AppModule) IsAppModule() {} // QuerierRoute returns the audit module's querier route name. func (am AppModule) QuerierRoute() string { - return "" -} - -// LegacyQuerierHandler returns the sdk.Querier for audit module -func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { - return nil + return types.QuerierRoute } // RegisterServices registers the module's services func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterMsgServer(cfg.MsgServer(), handler.NewMsgServerImpl(am.keeper)) + querier := keeper.Querier{Keeper: am.keeper} + types.RegisterQueryServer(cfg.QueryServer(), querier) } @@ -172,73 +162,46 @@ func (am AppModule) RegisterQueryService(server grpc.Server) { } // BeginBlock performs no-op -func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} +func (am AppModule) BeginBlock(_ context.Context) error { + return nil +} -// EndBlock returns the end blocker for the audit module. It returns no auditor +// EndBlock returns the end blocker for the deployment module. It returns no validator // updates. -func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - return []abci.ValidatorUpdate{} +func (am AppModule) EndBlock(_ context.Context) error { + return nil } // InitGenesis performs genesis initialization for the audit module. It returns // no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) { var genesisState types.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) - return InitGenesis(ctx, am.keeper, &genesisState) + InitGenesis(ctx, am.keeper, &genesisState) } // ExportGenesis returns the exported genesis state as raw bytes for the audit // module. func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { gs := ExportGenesis(ctx, am.keeper) + return cdc.MustMarshalJSON(gs) } // ConsensusVersion implements module.AppModule#ConsensusVersion func (am AppModule) ConsensusVersion() uint64 { - return 2 + return 3 } -// ____________________________________________________________________________ - -// AppModuleSimulation implements an application simulation module for the audit module. -type AppModuleSimulation struct { - keeper keeper.Keeper - pkeeper pkeeper.Keeper -} +// RegisterStoreDecoder registers a decoder for take module's types. +func (am AppModule) RegisterStoreDecoder(_ simtypes.StoreDecoderRegistry) {} -// NewAppModuleSimulation creates a new AppModuleSimulation instance -func NewAppModuleSimulation(k keeper.Keeper, pkeeper pkeeper.Keeper) AppModuleSimulation { - return AppModuleSimulation{ - keeper: k, - pkeeper: pkeeper, - } +// WeightedOperations doesn't return any take module operation. +func (am AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { + return []simtypes.WeightedOperation{} } -// AppModuleSimulation functions - // GenerateGenesisState creates a randomized GenState of the staking module. -func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) { - // simulation.RandomizedGenState(simState) -} - -// ProposalContents doesn't return any content functions for governance proposals. -func (AppModuleSimulation) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent { - return nil -} - -// RandomizedParams creates randomized staking param changes for the simulator. -func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange { - return nil -} +func (AppModule) GenerateGenesisState(_ *module.SimulationState) { -// RegisterStoreDecoder registers a decoder for staking module's types -func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { - -} - -// WeightedOperations returns the all the staking module operations with their respective weights. -func (am AppModuleSimulation) WeightedOperations(simState module.SimulationState) []sim.WeightedOperation { - return nil } diff --git a/x/audit/query/rawclient.go b/x/audit/query/rawclient.go index 215bb7a25b..f4384720cd 100644 --- a/x/audit/query/rawclient.go +++ b/x/audit/query/rawclient.go @@ -6,7 +6,7 @@ import ( sdkclient "github.com/cosmos/cosmos-sdk/client" sdk "github.com/cosmos/cosmos-sdk/types" - types "github.com/akash-network/akash-api/go/node/audit/v1beta3" + types "pkg.akt.dev/go/node/audit/v1" ) // RawClient interface diff --git a/x/cert/alias.go b/x/cert/alias.go index 13f0af11d3..97dc00d932 100644 --- a/x/cert/alias.go +++ b/x/cert/alias.go @@ -1,9 +1,9 @@ package cert import ( - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" + types "pkg.akt.dev/go/node/cert/v1" - "github.com/akash-network/node/x/cert/keeper" + "pkg.akt.dev/node/x/cert/keeper" ) const ( diff --git a/x/cert/client/cli/errors.go b/x/cert/client/cli/errors.go deleted file mode 100644 index 7c07f899c5..0000000000 --- a/x/cert/client/cli/errors.go +++ /dev/null @@ -1,9 +0,0 @@ -package cli - -import ( - "errors" -) - -var ( - errInvalidSerialFlag = errors.New("invalid value in serial flag. expected integer") -) diff --git a/x/cert/client/cli/grpc_rest_test.go b/x/cert/client/cli/grpc_rest_test.go deleted file mode 100644 index 088472e199..0000000000 --- a/x/cert/client/cli/grpc_rest_test.go +++ /dev/null @@ -1,138 +0,0 @@ -package cli_test - -import ( - "context" - "crypto/x509" - "encoding/pem" - "fmt" - "testing" - - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkrest "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" - - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/testutil/network" - atypes "github.com/akash-network/node/types" - ccli "github.com/akash-network/node/x/cert/client/cli" -) - -type GRPCRestTestSuite struct { - suite.Suite - - cfg network.Config - network *network.Network - certs types.CertificatesResponse -} - -func (s *GRPCRestTestSuite) SetupSuite() { - s.T().Log("setting up integration test suite") - - cfg := testutil.DefaultConfig() - cfg.NumValidators = 1 - - s.cfg = cfg - s.network = network.New(s.T(), s.cfg) - - _, err := s.network.WaitForHeight(1) - s.Require().NoError(err) - - val := s.network.Validators[0] - - // Generate client certificate - _, err = ccli.TxGenerateClientExec( - context.Background(), - val.ClientCtx, - val.Address, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // Publish client certificate - _, err = ccli.TxPublishClientExec( - context.Background(), - val.ClientCtx, - val.Address, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // get certs - resp, err := ccli.QueryCertificatesExec(val.ClientCtx.WithOutputFormat("json")) - s.Require().NoError(err) - - out := &types.QueryCertificatesResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), out) - s.Require().NoError(err) - s.Require().Len(out.Certificates, 1, "Certificate Create Failed") - block, rest := pem.Decode(out.Certificates[0].Certificate.Cert) - require.NotNil(s.T(), block) - require.Len(s.T(), rest, 0) - - require.Equal(s.T(), block.Type, types.PemBlkTypeCertificate) - - cert, err := x509.ParseCertificate(block.Bytes) - s.Require().NoError(err) - s.Require().NotNil(cert) - - s.Require().Equal(val.Address.String(), cert.Issuer.CommonName) - - s.certs = out.Certificates -} - -func (s *GRPCRestTestSuite) TestGetCertificates() { - val := s.network.Validators[0] - certs := s.certs - - testCases := []struct { - name string - url string - expErr bool - expResp types.CertificatesResponse - expLen int - }{ - { - "get certificates without filters", - fmt.Sprintf("%s/akash/cert/%s/certificates/list", val.APIAddress, atypes.ProtoAPIVersion), - false, - certs, - 1, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := sdkrest.GetRequest(tc.url) - s.Require().NoError(err) - - var certs types.QueryCertificatesResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp, &certs) - - if tc.expErr { - s.Require().NotNil(err) - s.Require().Empty(certs.Certificates) - } else { - s.Require().NoError(err) - s.Require().Len(certs.Certificates, tc.expLen) - s.Require().Equal(tc.expResp, certs.Certificates) - } - }) - } -} - -func (s *GRPCRestTestSuite) TearDownSuite() { - s.T().Log("tearing down integration test suite") - s.network.Cleanup() -} - -func TestGRPCRestTestSuite(t *testing.T) { - suite.Run(t, new(GRPCRestTestSuite)) -} diff --git a/x/cert/client/cli/query.go b/x/cert/client/cli/query.go deleted file mode 100644 index 7b70868052..0000000000 --- a/x/cert/client/cli/query.go +++ /dev/null @@ -1,111 +0,0 @@ -package cli - -import ( - "fmt" - "math/big" - - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" - - aclient "github.com/akash-network/node/client" - clientutils "github.com/akash-network/node/client" -) - -const ( - stateValid = "valid" - stateRevoked = "revoked" -) - -func GetQueryCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: "Certificate query commands", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - - cmd.AddCommand( - cmdGetCertificates(), - ) - - return cmd -} - -func cmdGetCertificates() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "Query for all certificates", - SilenceUsage: true, - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientQueryContext(cmd) - if err != nil { - return err - } - - qq, err := aclient.DiscoverQueryClient(ctx, cctx) - if err != nil { - return err - } - - pageReq, err := clientutils.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - params := &types.QueryCertificatesRequest{ - Pagination: pageReq, - } - - if value := cmd.Flag("owner").Value.String(); value != "" { - var owner sdk.Address - if owner, err = sdk.AccAddressFromBech32(value); err != nil { - return err - } - - params.Filter.Owner = owner.String() - } - - if value := cmd.Flag("serial").Value.String(); value != "" { - if params.Filter.Owner == "" { - return fmt.Errorf("--serial flag requires --owner to be set") - } - val, valid := new(big.Int).SetString(value, 10) - if !valid { - return errInvalidSerialFlag - } - - params.Filter.Serial = val.String() - } - - if value := cmd.Flag("state").Value.String(); value != "" { - if value != stateValid && value != stateRevoked { - return fmt.Errorf("invalid value of --state flag. expected valid|revoked") - } - - params.Filter.State = value - } - - res, err := qq.Certificates(cmd.Context(), params) - if err != nil { - return err - } - - return qq.ClientContext().PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "certificates") - - cmd.Flags().String("serial", "", "filter certificates by serial number") - cmd.Flags().String("owner", "", "filter certificates by owner") - cmd.Flags().String("state", "", "filter certificates by valid|revoked") - - return cmd -} diff --git a/x/cert/client/cli/test_helpers.go b/x/cert/client/cli/test_helpers.go deleted file mode 100644 index 84a577afef..0000000000 --- a/x/cert/client/cli/test_helpers.go +++ /dev/null @@ -1,89 +0,0 @@ -package cli - -import ( - "context" - "fmt" - - "github.com/cosmos/cosmos-sdk/client" - sdktest "github.com/cosmos/cosmos-sdk/testutil" - - testutilcli "github.com/akash-network/node/testutil/cli" -) - -// TxGenerateServerExec is used for testing create server certificate tx -func TxGenerateServerExec(ctx context.Context, clientCtx client.Context, from fmt.Stringer, host string, extraArgs ...string) (sdktest.BufferWriter, error) { - var args []string - - if len(host) != 0 { // for testing purposes, of passing no arguments - args = []string{host} - } - args = append(args, fmt.Sprintf("--from=%s", from.String())) - args = append(args, extraArgs...) - return testutilcli.ExecTestCLICmd(ctx, clientCtx, cmdGenerateServer(), args...) -} - -// TxGenerateClientExec is used for testing create client certificate tx -func TxGenerateClientExec(ctx context.Context, clientCtx client.Context, from fmt.Stringer, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--from=%s", from.String()), - } - - args = append(args, extraArgs...) - return testutilcli.ExecTestCLICmd(ctx, clientCtx, cmdGenerateClient(), args...) -} - -// TxPublishServerExec is used for testing create server certificate tx -func TxPublishServerExec(ctx context.Context, clientCtx client.Context, from fmt.Stringer, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--from=%s", from.String()), - } - - args = append(args, extraArgs...) - return testutilcli.ExecTestCLICmd(ctx, clientCtx, cmdPublishServer(), args...) -} - -// TxPublishClientExec is used for testing create client certificate tx -func TxPublishClientExec(ctx context.Context, clientCtx client.Context, from fmt.Stringer, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--from=%s", from.String()), - } - - args = append(args, extraArgs...) - return testutilcli.ExecTestCLICmd(ctx, clientCtx, cmdPublishClient(), args...) -} - -// TxRevokeServerExec is used for testing create server certificate tx -func TxRevokeServerExec(ctx context.Context, clientCtx client.Context, from fmt.Stringer, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--from=%s", from.String()), - } - - args = append(args, extraArgs...) - return testutilcli.ExecTestCLICmd(ctx, clientCtx, cmdRevokeServer(), args...) -} - -// TxRevokeClientExec is used for testing create client certificate tx -func TxRevokeClientExec(ctx context.Context, clientCtx client.Context, from fmt.Stringer, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--from=%s", from.String()), - } - - args = append(args, extraArgs...) - return testutilcli.ExecTestCLICmd(ctx, clientCtx, cmdRevokeClient(), args...) -} - -// QueryCertificatesExec is used for testing certificates query -func QueryCertificatesExec(clientCtx client.Context, extraArgs ...string) (sdktest.BufferWriter, error) { - return testutilcli.ExecTestCLICmd(context.Background(), clientCtx, cmdGetCertificates(), extraArgs...) -} - -// QueryCertificateExec is used for testing certificate query -func QueryCertificateExec(clientCtx client.Context, owner string, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--owner=%s", owner), - } - - args = append(args, extraArgs...) - - return testutilcli.ExecTestCLICmd(context.Background(), clientCtx, cmdGetCertificates(), args...) -} diff --git a/x/cert/client/cli/tx.go b/x/cert/client/cli/tx.go deleted file mode 100644 index 3b31dae764..0000000000 --- a/x/cert/client/cli/tx.go +++ /dev/null @@ -1,250 +0,0 @@ -package cli - -import ( - "crypto/x509" - "encoding/pem" - "fmt" - "math/big" - "time" - - cltypes "github.com/akash-network/akash-api/go/node/client/types" - sdkclient "github.com/cosmos/cosmos-sdk/client" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - "github.com/spf13/viper" - - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" - - aclient "github.com/akash-network/node/client" - certerrors "github.com/akash-network/node/x/cert/errors" - "github.com/akash-network/node/x/cert/utils" -) - -const ( - flagSerial = "serial" - flagOverwrite = "overwrite" - flagValidTime = "valid-duration" - flagStart = "start-time" - flagToGenesis = "to-genesis" -) - -var ( - errCertificateDoesNotExist = fmt.Errorf("%w: does not exist", certerrors.ErrCertificate) - errCannotOverwriteCertificate = fmt.Errorf("%w: cannot overwrite certificate", certerrors.ErrCertificate) -) - -func GetTxCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: "Certificates transaction subcommands", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - - /** - Commands - 1. Generate - create public / private key pair - 2. Publish - publish a key pair to the blockchain - 3. Revoke - revoke a key pair on the blockchain - - */ - - cmd.AddCommand( - cmdGenerate(), - cmdPublish(), - cmdRevoke(), - ) - - return cmd -} - -func doGenerateCmd(cmd *cobra.Command, domains []string) error { - allowOverwrite := viper.GetBool(flagOverwrite) - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - fromAddress := cctx.GetFromAddress() - - kpm, err := utils.NewKeyPairManager(cctx, fromAddress) - if err != nil { - return err - } - - exists, err := kpm.KeyExists() - if err != nil { - return err - } - if !allowOverwrite && exists { - return errCannotOverwriteCertificate - } - - var startTime time.Time - startTimeStr := viper.GetString(flagStart) - if len(startTimeStr) == 0 { - startTime = time.Now().Truncate(time.Second) - } else { - startTime, err = time.Parse(time.RFC3339, startTimeStr) - if err != nil { - return err - } - } - validDuration := viper.GetDuration(flagValidTime) - - return kpm.Generate(startTime, startTime.Add(validDuration), domains) -} - -func doPublishCmd(cmd *cobra.Command) error { - toGenesis := viper.GetBool(flagToGenesis) - - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - fromAddress := cctx.GetFromAddress() - - kpm, err := utils.NewKeyPairManager(cctx, fromAddress) - if err != nil { - return err - } - - exists, err := kpm.KeyExists() - if err != nil { - return err - } - if !exists { - return errCertificateDoesNotExist - } - - cert, _, pubKey, err := kpm.Read() - if err != nil { - return err - } - - msg := &types.MsgCreateCertificate{ - Owner: fromAddress.String(), - Cert: pem.EncodeToMemory(&pem.Block{ - Type: types.PemBlkTypeCertificate, - Bytes: cert, - }), - Pubkey: pem.EncodeToMemory(&pem.Block{ - Type: types.PemBlkTypeECPublicKey, - Bytes: pubKey, - }), - } - - if err = msg.ValidateBasic(); err != nil { - return err - } - - if toGenesis { - return addCertToGenesis(cmd, types.GenesisCertificate{ - Owner: msg.Owner, - Certificate: types.Certificate{ - State: types.CertificateValid, - Cert: msg.Cert, - Pubkey: msg.Pubkey, - }, - }) - - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) -} - -func doRevokeCmd(cmd *cobra.Command) error { - serial := viper.GetString(flagSerial) - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - fromAddress := cctx.GetFromAddress() - - if len(serial) != 0 { - if _, valid := new(big.Int).SetString(serial, 10); !valid { - return errInvalidSerialFlag - } - } else { - kpm, err := utils.NewKeyPairManager(cctx, fromAddress) - if err != nil { - return err - } - - cert, _, _, err := kpm.Read() - if err != nil { - return err - } - - parsedCert, err := x509.ParseCertificate(cert) - if err != nil { - return err - } - - serial = parsedCert.SerialNumber.String() - } - - params := &types.QueryCertificatesRequest{ - Filter: types.CertificateFilter{ - Owner: fromAddress.String(), - Serial: serial, - State: stateValid, - }, - } - - ctx := cmd.Context() - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - res, err := cl.Query().Certificates(cmd.Context(), params) - if err != nil { - return err - } - - exists := len(res.Certificates) != 0 - if !exists { - return fmt.Errorf("%w: certificate with serial %v does not exist on chain and cannot be revoked", certerrors.ErrCertificate, serial) - } - - msg := &types.MsgRevokeCertificate{ - ID: types.CertificateID{ - Owner: cctx.FromAddress.String(), - Serial: serial, - }, - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) -} diff --git a/x/cert/client/cli/tx_cmd.go b/x/cert/client/cli/tx_cmd.go deleted file mode 100644 index d37898ac3e..0000000000 --- a/x/cert/client/cli/tx_cmd.go +++ /dev/null @@ -1,255 +0,0 @@ -package cli - -import ( - "encoding/json" - "fmt" - "time" - - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/server" - "github.com/cosmos/cosmos-sdk/x/genutil" - genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - "github.com/spf13/cobra" - "github.com/spf13/viper" - - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" -) - -func cmdGenerate() *cobra.Command { - cmd := &cobra.Command{ - Use: "generate", - Short: "", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - - cmd.AddCommand(cmdGenerateClient(), - cmdGenerateServer(), - ) - - return cmd -} - -func addGenerateFlags(cmd *cobra.Command) error { - cmd.Flags().String(flagStart, "", "certificate is not valid before this date. default current timestamp. RFC3339") - if err := viper.BindPFlag(flagStart, cmd.Flags().Lookup(flagStart)); err != nil { - return err - } - - cmd.Flags().Duration(flagValidTime, time.Hour*24*365, "certificate is not valid after this date. RFC3339") - if err := viper.BindPFlag(flagValidTime, cmd.Flags().Lookup(flagValidTime)); err != nil { - return err - } - cmd.Flags().Bool(flagOverwrite, false, "overwrite existing certificate if present") - if err := viper.BindPFlag(flagOverwrite, cmd.Flags().Lookup(flagOverwrite)); err != nil { - return err - } - - flags.AddTxFlagsToCmd(cmd) // TODO - add just the keyring flags? not all the TX ones - return nil -} - -func cmdGenerateClient() *cobra.Command { - cmd := &cobra.Command{ - Use: "client", - Short: "", - SuggestionsMinimumDistance: 2, - RunE: doGenerateCmd, - SilenceUsage: true, - Args: cobra.ExactArgs(0), - } - err := addGenerateFlags(cmd) - if err != nil { - panic(err) - } - - return cmd -} - -func cmdGenerateServer() *cobra.Command { - cmd := &cobra.Command{ - Use: "server", - Short: "", - SuggestionsMinimumDistance: 2, - RunE: doGenerateCmd, - SilenceUsage: true, - Args: cobra.MinimumNArgs(1), - } - err := addGenerateFlags(cmd) - if err != nil { - panic(err) - } - - return cmd -} - -func cmdPublish() *cobra.Command { - cmd := &cobra.Command{ - Use: "publish", - Short: "", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - - cmd.AddCommand(cmdPublishClient(), - cmdPublishServer()) - - return cmd -} - -func cmdPublishClient() *cobra.Command { - cmd := &cobra.Command{ - Use: "client", - Short: "", - SuggestionsMinimumDistance: 2, - RunE: func(cmd *cobra.Command, args []string) error { - return doPublishCmd(cmd) - }, - SilenceUsage: true, - Args: cobra.ExactArgs(0), - } - err := addPublishFlags(cmd) - if err != nil { - panic(err) - } - - return cmd -} - -func cmdPublishServer() *cobra.Command { - cmd := &cobra.Command{ - Use: "server", - Short: "", - SuggestionsMinimumDistance: 2, - RunE: func(cmd *cobra.Command, args []string) error { - return doPublishCmd(cmd) - }, - SilenceUsage: true, - Args: cobra.ExactArgs(0), - } - err := addPublishFlags(cmd) - if err != nil { - panic(err) - } - - return cmd -} - -func addPublishFlags(cmd *cobra.Command) error { - cmd.Flags().Bool(flagToGenesis, false, "add to genesis") - if err := viper.BindPFlag(flagToGenesis, cmd.Flags().Lookup(flagToGenesis)); err != nil { - return err - } - - flags.AddTxFlagsToCmd(cmd) - - return nil -} - -func addCertToGenesis(cmd *cobra.Command, cert types.GenesisCertificate) error { - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - cdc := cctx.Codec - - serverCtx := server.GetServerContextFromCmd(cmd) - config := serverCtx.Config - - config.SetRoot(cctx.HomeDir) - - if err := cert.Validate(); err != nil { - return fmt.Errorf("%w: failed to validate new genesis certificate", err) - } - - genFile := config.GenesisFile() - appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile) - if err != nil { - return fmt.Errorf("%w: failed to unmarshal genesis state", err) - } - - certsGenState := types.GetGenesisStateFromAppState(cdc, appState) - - if certsGenState.Certificates.Contains(cert) { - return fmt.Errorf("%w: cannot add already existing certificate", err) - } - certsGenState.Certificates = append(certsGenState.Certificates, cert) - - certsGenStateBz, err := cdc.MarshalJSON(certsGenState) - if err != nil { - return fmt.Errorf("%w: failed to marshal auth genesis state", err) - } - - appState[types.ModuleName] = certsGenStateBz - - appStateJSON, err := json.Marshal(appState) - if err != nil { - return fmt.Errorf("%w: failed to marshal application genesis state", err) - } - - genDoc.AppState = appStateJSON - return genutil.ExportGenesisFile(genDoc, genFile) -} - -func cmdRevoke() *cobra.Command { - cmd := &cobra.Command{ - Use: "revoke", - Short: "", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - cmd.AddCommand(cmdRevokeClient(), - cmdRevokeServer()) - - return cmd -} - -func cmdRevokeClient() *cobra.Command { - cmd := &cobra.Command{ - Use: "client", - Short: "", - SuggestionsMinimumDistance: 2, - RunE: func(cmd *cobra.Command, args []string) error { - return doRevokeCmd(cmd) - }, - SilenceUsage: true, - Args: cobra.ExactArgs(0), - } - err := addRevokeCmdFlags(cmd) - if err != nil { - panic(err) - } - - return cmd -} - -func cmdRevokeServer() *cobra.Command { - cmd := &cobra.Command{ - Use: "server", - Short: "", - SuggestionsMinimumDistance: 2, - RunE: func(cmd *cobra.Command, args []string) error { - return doRevokeCmd(cmd) - }, - SilenceUsage: true, - Args: cobra.ExactArgs(0), - } - err := addRevokeCmdFlags(cmd) - if err != nil { - panic(err) - } - - return cmd -} - -func addRevokeCmdFlags(cmd *cobra.Command) error { - cmd.Flags().String(flagSerial, "", "revoke certificate by serial number") - if err := viper.BindPFlag(flagSerial, cmd.Flags().Lookup(flagSerial)); err != nil { - return err - } - - flags.AddTxFlagsToCmd(cmd) - return nil -} diff --git a/x/cert/client/cli/tx_test.go b/x/cert/client/cli/tx_test.go deleted file mode 100644 index cc3e2ec00c..0000000000 --- a/x/cert/client/cli/tx_test.go +++ /dev/null @@ -1,135 +0,0 @@ -package cli_test - -import ( - "fmt" - "testing" - - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/x/cert/client/cli" - - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - - certerrors "github.com/akash-network/node/x/cert/errors" -) - -const testHost = "foobar.dev" - -type certificateCLISuite struct { - testutil.NetworkTestSuite -} - -func (s *certificateCLISuite) TestGeneratePublishAndRevokeServer() { - result, err := cli.TxGenerateServerExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest(), - testHost, - fmt.Sprintf("--fees=%d%s", 1000, s.Config().BondDenom)) - require.NoError(s.T(), err) - require.NotNil(s.T(), result) - - result, err = cli.TxPublishServerExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest(), - fmt.Sprintf("--fees=%d%s", 1000, s.Config().BondDenom), - "--yes") - require.NoError(s.T(), err) - require.NoError(s.T(), s.Network().WaitForNextBlock()) - _ = s.ValidateTx(result.Bytes()) - - result, err = cli.TxRevokeServerExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest(), - fmt.Sprintf("--fees=%d%s", 1000, s.Config().BondDenom), - "--yes") - - require.NoError(s.T(), err) - require.NoError(s.T(), s.Network().WaitForNextBlock()) - _ = s.ValidateTx(result.Bytes()) -} - -func (s *certificateCLISuite) TestGenerateServerRequiresArguments() { - _, err := cli.TxGenerateServerExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest(), "") - require.Error(s.T(), err) - require.Contains(s.T(), err.Error(), "requires at least 1 arg(s), only received 0") -} - -func (s *certificateCLISuite) TestGenerateServerAllowsManyArguments() { - _, err := cli.TxGenerateServerExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest(), "a.dev", "b.dev") - require.NoError(s.T(), err) -} - -func (s *certificateCLISuite) TestGenerateClientRejectsArguments() { - _, err := cli.TxGenerateClientExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest(), testHost) - require.Error(s.T(), err) - require.Contains(s.T(), err.Error(), "accepts 0 arg(s), received 1") -} - -func (s *certificateCLISuite) TestGeneratePublishAndRevokeClient() { - result, err := cli.TxGenerateClientExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest()) - require.NoError(s.T(), err) - require.NotNil(s.T(), result) - - result, err = cli.TxPublishClientExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest(), - fmt.Sprintf("--fees=%d%s", 1000, s.Config().BondDenom), - "--yes") - require.NoError(s.T(), err) - require.NoError(s.T(), s.Network().WaitForNextBlock()) - _ = s.ValidateTx(result.Bytes()) - - result, err = cli.TxRevokeClientExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest(), - fmt.Sprintf("--fees=%d%s", 1000, s.Config().BondDenom), - "--yes") - - require.NoError(s.T(), err) - require.NoError(s.T(), s.Network().WaitForNextBlock()) - _ = s.ValidateTx(result.Bytes()) -} - -func (s *certificateCLISuite) TestGenerateAndRevokeFailsServer() { - result, err := cli.TxGenerateServerExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest(), testHost) - require.NoError(s.T(), err) - require.NotNil(s.T(), result) - - _, err = cli.TxRevokeServerExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest(), - fmt.Sprintf("--fees=%d%s", 1000, s.Config().BondDenom), - "--yes") - require.ErrorIs(s.T(), err, certerrors.ErrCertificate) - require.Contains(s.T(), err.Error(), "does not exist on chain") -} - -func (s *certificateCLISuite) TestRevokeFailsServer() { - _, err := cli.TxRevokeServerExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest(), - fmt.Sprintf("--fees=%d%s", 1000, s.Config().BondDenom), - "--yes", - "--serial=1") - require.ErrorIs(s.T(), err, certerrors.ErrCertificate) - require.Contains(s.T(), err.Error(), "serial 1 does not exist on chain") -} - -func (s *certificateCLISuite) TestRevokeFailsClient() { - _, err := cli.TxRevokeClientExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest(), - fmt.Sprintf("--fees=%d%s", 1000, s.Config().BondDenom), - "--yes", - "--serial=1") - require.ErrorIs(s.T(), err, certerrors.ErrCertificate) - require.Contains(s.T(), err.Error(), "serial 1 does not exist on chain") -} - -func (s *certificateCLISuite) TestGenerateServerNoOverwrite() { - result, err := cli.TxGenerateServerExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest(), testHost) - require.NoError(s.T(), err) - require.NotNil(s.T(), result) - - _, err = cli.TxGenerateServerExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest(), testHost) - require.ErrorIs(s.T(), err, certerrors.ErrCertificate) - require.Contains(s.T(), err.Error(), "cannot overwrite") -} - -func (s *certificateCLISuite) TestGenerateClientNoOverwrite() { - result, err := cli.TxGenerateClientExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest()) - require.NoError(s.T(), err) - require.NotNil(s.T(), result) - - _, err = cli.TxGenerateClientExec(s.GoContextForTest(), s.ContextForTest(), s.WalletForTest()) - require.ErrorIs(s.T(), err, certerrors.ErrCertificate) - require.Contains(s.T(), err.Error(), "cannot overwrite") -} - -func TestCertificateCLI(t *testing.T) { - suite.Run(t, &certificateCLISuite{NetworkTestSuite: testutil.NewNetworkTestSuite(nil, &certificateCLISuite{})}) -} diff --git a/x/cert/genesis.go b/x/cert/genesis.go index bc1ecca719..5e902d4f24 100644 --- a/x/cert/genesis.go +++ b/x/cert/genesis.go @@ -8,11 +8,10 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/akash-network/node/x/cert/keeper" + "pkg.akt.dev/node/x/cert/keeper" - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" + types "pkg.akt.dev/go/node/cert/v1" ) // ValidateGenesis does validation check of the Genesis and returns error in case of failure @@ -27,7 +26,7 @@ func ValidateGenesis(data *types.GenesisState) error { } // InitGenesis initiate genesis state and return updated validator details -func InitGenesis(ctx sdk.Context, kpr keeper.Keeper, data *types.GenesisState) []abci.ValidatorUpdate { +func InitGenesis(ctx sdk.Context, kpr keeper.Keeper, data *types.GenesisState) { store := ctx.KVStore(kpr.StoreKey()) cdc := kpr.Codec() @@ -53,8 +52,6 @@ func InitGenesis(ctx sdk.Context, kpr keeper.Keeper, data *types.GenesisState) [ store.Set(key, cdc.MustMarshal(&record.Certificate)) } - - return []abci.ValidatorUpdate{} } // ExportGenesis returns genesis state as raw bytes for the provider module diff --git a/x/cert/handler/handler.go b/x/cert/handler/handler.go index 49e6bf763e..e80a034e42 100644 --- a/x/cert/handler/handler.go +++ b/x/cert/handler/handler.go @@ -1,28 +1,29 @@ package handler import ( + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" + types "pkg.akt.dev/go/node/cert/v1" - "github.com/akash-network/node/x/cert/keeper" + "pkg.akt.dev/node/x/cert/keeper" ) // NewHandler returns a handler for "provider" type messages. -func NewHandler(keeper keeper.Keeper) sdk.Handler { +func NewHandler(keeper keeper.Keeper) baseapp.MsgServiceHandler { ms := NewMsgServerImpl(keeper) return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { switch msg := msg.(type) { case *types.MsgCreateCertificate: - res, err := ms.CreateCertificate(sdk.WrapSDKContext(ctx), msg) + res, err := ms.CreateCertificate(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) case *types.MsgRevokeCertificate: - res, err := ms.RevokeCertificate(sdk.WrapSDKContext(ctx), msg) + res, err := ms.RevokeCertificate(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) } - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized message type: %T", msg) + return nil, sdkerrors.ErrUnknownRequest.Wrapf("unrecognized message type: %T", msg) } } diff --git a/x/cert/handler/handler_test.go b/x/cert/handler/handler_test.go index 91883f5ae6..73345eef06 100644 --- a/x/cert/handler/handler_test.go +++ b/x/cert/handler/handler_test.go @@ -4,46 +4,60 @@ import ( "errors" "testing" - "github.com/cosmos/cosmos-sdk/store" + "github.com/stretchr/testify/require" + "pkg.akt.dev/go/sdkutil" + + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + + "cosmossdk.io/log" + "cosmossdk.io/store" + storemetrics "cosmossdk.io/store/metrics" + storetypes "cosmossdk.io/store/types" + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/baseapp" sdktestdata "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/stretchr/testify/require" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - dbm "github.com/tendermint/tm-db" - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" + types "pkg.akt.dev/go/node/cert/v1" + "pkg.akt.dev/go/testutil" - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/x/cert/handler" - "github.com/akash-network/node/x/cert/keeper" + "pkg.akt.dev/node/x/cert/handler" + "pkg.akt.dev/node/x/cert/keeper" ) type testSuite struct { t testing.TB - ms sdk.CommitMultiStore + encCfg sdkutil.EncodingConfig + kr testutil.Keyring + ms storetypes.CommitMultiStore ctx sdk.Context keeper keeper.Keeper - handler sdk.Handler + handler baseapp.MsgServiceHandler } func setupTestSuite(t *testing.T) *testSuite { + cfg := sdkutil.MakeEncodingConfig() suite := &testSuite{ - t: t, + t: t, + encCfg: cfg, + kr: testutil.NewTestKeyring(cfg.Codec), } - aKey := sdk.NewTransientStoreKey(types.StoreKey) + cdc := cfg.Codec + + aKey := storetypes.NewTransientStoreKey(types.StoreKey) db := dbm.NewMemDB() - suite.ms = store.NewCommitMultiStore(db) - suite.ms.MountStoreWithDB(aKey, sdk.StoreTypeIAVL, db) + suite.ms = store.NewCommitMultiStore(db, log.NewNopLogger(), storemetrics.NewNoOpMetrics()) + suite.ms.MountStoreWithDB(aKey, storetypes.StoreTypeIAVL, db) err := suite.ms.LoadLatestVersion() require.NoError(t, err) suite.ctx = sdk.NewContext(suite.ms, tmproto.Header{}, true, testutil.Logger(t)) - suite.keeper = keeper.NewKeeper(types.ModuleCdc, aKey) + suite.keeper = keeper.NewKeeper(cdc, aKey) suite.handler = handler.NewHandler(suite.keeper) @@ -72,8 +86,8 @@ func TestCertHandlerCreate(t *testing.T) { } res, err := suite.handler(suite.ctx, msg) - require.NotNil(t, res) require.NoError(t, err) + require.NotNil(t, res) resp, exists := suite.keeper.GetCertificateByID(suite.ctx, types.CertID{ Owner: owner, @@ -87,7 +101,6 @@ func TestCertHandlerCreateOwnerMismatch(t *testing.T) { suite := setupTestSuite(t) owner := testutil.AccAddress(t) - cert := testutil.Certificate(t, owner) msg := &types.MsgCreateCertificate{ @@ -97,8 +110,8 @@ func TestCertHandlerCreateOwnerMismatch(t *testing.T) { } res, err := suite.handler(suite.ctx, msg) - require.Nil(t, res) require.Error(t, err, types.ErrInvalidCertificateValue.Error()) + require.Nil(t, res) _, exists := suite.keeper.GetCertificateByID(suite.ctx, types.CertID{ Owner: owner, @@ -116,7 +129,6 @@ func TestCertHandlerDuplicate(t *testing.T) { suite := setupTestSuite(t) owner := testutil.AccAddress(t) - cert := testutil.Certificate(t, owner) msg := &types.MsgCreateCertificate{ @@ -126,8 +138,8 @@ func TestCertHandlerDuplicate(t *testing.T) { } res, err := suite.handler(suite.ctx, msg) - require.NotNil(t, res) require.NoError(t, err) + require.NotNil(t, res) resp, exists := suite.keeper.GetCertificateByID(suite.ctx, types.CertID{ Owner: owner, @@ -148,8 +160,8 @@ func TestCertHandlerDuplicate(t *testing.T) { } res, err = suite.handler(suite.ctx, msg) - require.NotNil(t, res) require.NoError(t, err) + require.NotNil(t, res) resp, exists = suite.keeper.GetCertificateByID(suite.ctx, types.CertID{ Owner: owner, @@ -170,7 +182,6 @@ func TestCertHandlerRevoke(t *testing.T) { suite := setupTestSuite(t) owner := testutil.AccAddress(t) - cert := testutil.Certificate(t, owner) msgCreate := &types.MsgCreateCertificate{ @@ -180,8 +191,8 @@ func TestCertHandlerRevoke(t *testing.T) { } res, err := suite.handler(suite.ctx, msgCreate) - require.NotNil(t, res) require.NoError(t, err) + require.NotNil(t, res) resp, exists := suite.keeper.GetCertificateByID(suite.ctx, types.CertID{ Owner: owner, @@ -191,15 +202,15 @@ func TestCertHandlerRevoke(t *testing.T) { testutil.CertificateRequireEqualResponse(t, cert, resp, types.CertificateValid) msgRevoke := &types.MsgRevokeCertificate{ - ID: types.CertificateID{ + ID: types.ID{ Owner: owner.String(), Serial: cert.Serial.String(), }, } res, err = suite.handler(suite.ctx, msgRevoke) - require.NotNil(t, res) require.NoError(t, err) + require.NotNil(t, res) resp, exists = suite.keeper.GetCertificateByID(suite.ctx, types.CertID{ Owner: owner, @@ -209,15 +220,14 @@ func TestCertHandlerRevoke(t *testing.T) { testutil.CertificateRequireEqualResponse(t, cert, resp, types.CertificateRevoked) res, err = suite.handler(suite.ctx, msgRevoke) - require.Nil(t, res) require.Error(t, err, types.ErrCertificateAlreadyRevoked.Error()) + require.Nil(t, res) } func TestCertHandlerRevokeCreateRevoked(t *testing.T) { suite := setupTestSuite(t) owner := testutil.AccAddress(t) - cert := testutil.Certificate(t, owner) msgCreate := &types.MsgCreateCertificate{ @@ -227,8 +237,8 @@ func TestCertHandlerRevokeCreateRevoked(t *testing.T) { } res, err := suite.handler(suite.ctx, msgCreate) - require.NotNil(t, res) require.NoError(t, err) + require.NotNil(t, res) resp, exists := suite.keeper.GetCertificateByID(suite.ctx, types.CertID{ Owner: owner, @@ -238,15 +248,15 @@ func TestCertHandlerRevokeCreateRevoked(t *testing.T) { testutil.CertificateRequireEqualResponse(t, cert, resp, types.CertificateValid) msgRevoke := &types.MsgRevokeCertificate{ - ID: types.CertificateID{ + ID: types.ID{ Owner: owner.String(), Serial: cert.Serial.String(), }, } res, err = suite.handler(suite.ctx, msgRevoke) - require.NotNil(t, res) require.NoError(t, err) + require.NotNil(t, res) resp, exists = suite.keeper.GetCertificateByID(suite.ctx, types.CertID{ Owner: owner, @@ -256,12 +266,13 @@ func TestCertHandlerRevokeCreateRevoked(t *testing.T) { testutil.CertificateRequireEqualResponse(t, cert, resp, types.CertificateRevoked) res, err = suite.handler(suite.ctx, msgCreate) - require.Nil(t, res) require.Error(t, err, types.ErrCertificateExists.Error()) + require.Nil(t, res) } func TestCertHandlerRevokeCreate(t *testing.T) { suite := setupTestSuite(t) + owner := testutil.AccAddress(t) cert := testutil.Certificate(t, owner) @@ -272,8 +283,8 @@ func TestCertHandlerRevokeCreate(t *testing.T) { } res, err := suite.handler(suite.ctx, msgCreate) - require.NotNil(t, res) require.NoError(t, err) + require.NotNil(t, res) resp, exists := suite.keeper.GetCertificateByID(suite.ctx, types.CertID{ Owner: owner, @@ -283,15 +294,15 @@ func TestCertHandlerRevokeCreate(t *testing.T) { testutil.CertificateRequireEqualResponse(t, cert, resp, types.CertificateValid) msgRevoke := &types.MsgRevokeCertificate{ - ID: types.CertificateID{ + ID: types.ID{ Owner: owner.String(), Serial: cert.Serial.String(), }, } res, err = suite.handler(suite.ctx, msgRevoke) - require.NotNil(t, res) require.NoError(t, err) + require.NotNil(t, res) resp, exists = suite.keeper.GetCertificateByID(suite.ctx, types.CertID{ Owner: owner, @@ -309,6 +320,6 @@ func TestCertHandlerRevokeCreate(t *testing.T) { } res, err = suite.handler(suite.ctx, msgCreate) - require.NotNil(t, res) require.NoError(t, err) + require.NotNil(t, res) } diff --git a/x/cert/handler/msg_server.go b/x/cert/handler/msg_server.go index e3559d5e5c..b92685765e 100644 --- a/x/cert/handler/msg_server.go +++ b/x/cert/handler/msg_server.go @@ -5,9 +5,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" + types "pkg.akt.dev/go/node/cert/v1" - "github.com/akash-network/node/x/cert/keeper" + "pkg.akt.dev/node/x/cert/keeper" ) type msgServer struct { diff --git a/x/cert/keeper/grpc_query.go b/x/cert/keeper/grpc_query.go index 598086f111..9826cb2ba2 100644 --- a/x/cert/keeper/grpc_query.go +++ b/x/cert/keeper/grpc_query.go @@ -3,15 +3,16 @@ package keeper import ( "context" - "github.com/cosmos/cosmos-sdk/store/prefix" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkquery "github.com/cosmos/cosmos-sdk/types/query" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" + "cosmossdk.io/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkquery "github.com/cosmos/cosmos-sdk/types/query" + + types "pkg.akt.dev/go/node/cert/v1" - "github.com/akash-network/node/util/query" + "pkg.akt.dev/node/util/query" ) // Querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over keeper @@ -39,7 +40,6 @@ func (q querier) Certificates(c context.Context, req *types.QueryCertificatesReq } states := make([]byte, 0, 2) - var searchPrefix []byte // setup for case 3 - cross-index search @@ -54,7 +54,7 @@ func (q querier) Certificates(c context.Context, req *types.QueryCertificatesReq req.Pagination.Key = key } else if req.Filter.State != "" { - stateVal := types.Certificate_State(types.Certificate_State_value[req.Filter.State]) + stateVal := types.State(types.State_value[req.Filter.State]) if req.Filter.State != "" && stateVal == types.CertificateStateInvalid { return nil, status.Error(codes.InvalidArgument, "invalid state value") @@ -73,7 +73,7 @@ func (q querier) Certificates(c context.Context, req *types.QueryCertificatesReq total := uint64(0) for idx := range states { - state := types.Certificate_State(states[idx]) + state := types.State(states[idx]) var err error if idx > 0 { diff --git a/x/cert/keeper/grpc_query_test.go b/x/cert/keeper/grpc_query_test.go index cb1fc98d69..44ee036d71 100644 --- a/x/cert/keeper/grpc_query_test.go +++ b/x/cert/keeper/grpc_query_test.go @@ -5,16 +5,17 @@ import ( "sort" "testing" + "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" sdkquery "github.com/cosmos/cosmos-sdk/types/query" - "github.com/stretchr/testify/require" - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" + types "pkg.akt.dev/go/node/cert/v1" + "pkg.akt.dev/go/testutil" - "github.com/akash-network/node/app" - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/x/cert/keeper" + "pkg.akt.dev/node/app" + "pkg.akt.dev/node/x/cert/keeper" ) type grpcTestSuite struct { @@ -30,7 +31,8 @@ func setupTest(t *testing.T) *grpcTestSuite { t: t, } - suite.app = app.Setup(false) + suite.app = app.Setup(app.WithGenesis(app.GenesisStateWithValSet)) + suite.ctx, suite.keeper = setupKeeper(t) querier := suite.keeper.Querier() @@ -55,10 +57,10 @@ func TestCertGRPCQueryCertificates(t *testing.T) { suite := setupTest(t) owner := testutil.AccAddress(t) - cert := testutil.Certificate(t, owner) - owner2 := testutil.AccAddress(t) owner3 := testutil.AccAddress(t) + + cert := testutil.Certificate(t, owner) cert2 := testutil.Certificate(t, owner2) cert3 := testutil.Certificate(t, owner3) @@ -259,7 +261,7 @@ func TestCertGRPCQueryCertificates(t *testing.T) { func() { req = &types.QueryCertificatesRequest{ Filter: types.CertificateFilter{ - State: types.Certificate_State_name[int32(types.CertificateValid)], + State: types.CertificateValid.String(), }, Pagination: &sdkquery.PageRequest{ Limit: 10, @@ -324,7 +326,7 @@ func TestCertGRPCQueryCertificates(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { tc.malleate() - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx res, err := suite.qclient.Certificates(ctx, req) @@ -342,7 +344,7 @@ func TestCertGRPCQueryCertificates(t *testing.T) { sortCerts(respCerts) if req.Pagination != nil && req.Pagination.Limit > 0 { - require.LessOrEqual(t, len(respCerts), int(req.Pagination.Limit)) + require.LessOrEqual(t, len(respCerts), int(req.Pagination.Limit)) //nolint:gosec } require.Len(t, respCerts, len(expCertificates)) @@ -360,7 +362,7 @@ func TestCertGRPCQueryCertificates(t *testing.T) { require.NoError(t, err) require.NotNil(t, res) if req.Pagination != nil && req.Pagination.Limit > 0 { - require.LessOrEqual(t, len(res.Certificates), int(req.Pagination.Limit)) + require.LessOrEqual(t, len(res.Certificates), int(req.Pagination.Limit)) //nolint:gosec } require.Nil(t, res.Pagination.NextKey) diff --git a/x/cert/keeper/keeper.go b/x/cert/keeper/keeper.go index 78e83681f6..99d9d8f39d 100644 --- a/x/cert/keeper/keeper.go +++ b/x/cert/keeper/keeper.go @@ -1,35 +1,35 @@ package keeper import ( + storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" + types "pkg.akt.dev/go/node/cert/v1" ) // Keeper of the provider store type Keeper interface { Querier() types.QueryServer Codec() codec.BinaryCodec - StoreKey() sdk.StoreKey + StoreKey() storetypes.StoreKey CreateCertificate(sdk.Context, sdk.Address, []byte, []byte) error RevokeCertificate(sdk.Context, types.CertID) error GetCertificateByID(ctx sdk.Context, id types.CertID) (types.CertificateResponse, bool) WithCertificates(ctx sdk.Context, fn func(id types.CertID, certificate types.CertificateResponse) bool) - WithCertificatesState(ctx sdk.Context, state types.Certificate_State, fn func(certificate types.CertificateResponse) bool) WithOwner(ctx sdk.Context, id sdk.Address, fn func(types.CertificateResponse) bool) - WithOwnerState(ctx sdk.Context, id sdk.Address, state types.Certificate_State, fn func(types.CertificateResponse) bool) + WithOwnerState(ctx sdk.Context, id sdk.Address, state types.State, fn func(types.CertificateResponse) bool) } type keeper struct { - skey sdk.StoreKey + skey storetypes.StoreKey cdc codec.BinaryCodec } var _ Keeper = (*keeper)(nil) // NewKeeper creates and returns an instance for Market keeper -func NewKeeper(cdc codec.BinaryCodec, skey sdk.StoreKey) Keeper { +func NewKeeper(cdc codec.BinaryCodec, skey storetypes.StoreKey) Keeper { return &keeper{cdc: cdc, skey: skey} } @@ -44,7 +44,7 @@ func (k keeper) Codec() codec.BinaryCodec { } // StoreKey returns store key -func (k keeper) StoreKey() sdk.StoreKey { +func (k keeper) StoreKey() storetypes.StoreKey { return k.skey } @@ -83,6 +83,7 @@ func (k keeper) CreateCertificate(ctx sdk.Context, owner sdk.Address, crt []byte func (k keeper) RevokeCertificate(ctx sdk.Context, id types.CertID) error { store := ctx.KVStore(k.skey) + key := k.findCertificate(ctx, id) if len(key) == 0 { return types.ErrCertificateNotFound @@ -133,7 +134,7 @@ func (k keeper) GetCertificateByID(ctx sdk.Context, id types.CertID) (types.Cert // WithCertificates iterates all certificates func (k keeper) WithCertificates(ctx sdk.Context, fn func(id types.CertID, certificate types.CertificateResponse) bool) { store := ctx.KVStore(k.skey) - iter := sdk.KVStorePrefixIterator(store, CertPrefix) + iter := storetypes.KVStorePrefixIterator(store, CertPrefix) defer func() { _ = iter.Close() @@ -148,7 +149,7 @@ func (k keeper) WithCertificates(ctx sdk.Context, fn func(id types.CertID, certi } // WithCertificatesState iterates all certificates in certain state -func (k keeper) WithCertificatesState(ctx sdk.Context, state types.Certificate_State, fn func(certificate types.CertificateResponse) bool) { +func (k keeper) WithCertificatesState(ctx sdk.Context, state types.State, fn func(certificate types.CertificateResponse) bool) { store := ctx.KVStore(k.skey) searchPrefix, err := filterToPrefix(types.CertificateFilter{ @@ -158,7 +159,7 @@ func (k keeper) WithCertificatesState(ctx sdk.Context, state types.Certificate_S panic(err) } - iter := sdk.KVStorePrefixIterator(store, searchPrefix) + iter := storetypes.KVStorePrefixIterator(store, searchPrefix) defer func() { _ = iter.Close() @@ -176,12 +177,12 @@ func (k keeper) WithCertificatesState(ctx sdk.Context, state types.Certificate_S func (k keeper) WithOwner(ctx sdk.Context, id sdk.Address, fn func(types.CertificateResponse) bool) { store := ctx.KVStore(k.skey) - states := []types.Certificate_State{ + states := []types.State{ types.CertificateValid, types.CertificateRevoked, } - iters := make([]sdk.Iterator, 0, len(states)) + iters := make([]storetypes.Iterator, 0, len(states)) defer func() { for _, iter := range iters { _ = iter.Close() @@ -197,7 +198,7 @@ func (k keeper) WithOwner(ctx sdk.Context, id sdk.Address, fn func(types.Certifi panic(err) } - iter := sdk.KVStorePrefixIterator(store, searchPrefix) + iter := storetypes.KVStorePrefixIterator(store, searchPrefix) iters = append(iters, iter) for ; iter.Valid(); iter.Next() { @@ -210,7 +211,7 @@ func (k keeper) WithOwner(ctx sdk.Context, id sdk.Address, fn func(types.Certifi } // WithOwnerState iterates all certificates by owner in certain state -func (k keeper) WithOwnerState(ctx sdk.Context, id sdk.Address, state types.Certificate_State, fn func(types.CertificateResponse) bool) { +func (k keeper) WithOwnerState(ctx sdk.Context, id sdk.Address, state types.State, fn func(types.CertificateResponse) bool) { store := ctx.KVStore(k.skey) searchPrefix, err := filterToPrefix(types.CertificateFilter{ @@ -221,7 +222,7 @@ func (k keeper) WithOwnerState(ctx sdk.Context, id sdk.Address, state types.Cert panic(err) } - iter := sdk.KVStorePrefixIterator(store, searchPrefix) + iter := storetypes.KVStorePrefixIterator(store, searchPrefix) defer func() { _ = iter.Close() }() diff --git a/x/cert/keeper/keeper_test.go b/x/cert/keeper/keeper_test.go index bb8084d69f..83da5c9142 100644 --- a/x/cert/keeper/keeper_test.go +++ b/x/cert/keeper/keeper_test.go @@ -4,22 +4,29 @@ import ( "testing" "time" - "github.com/cosmos/cosmos-sdk/store" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - dbm "github.com/tendermint/tm-db" - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + + "cosmossdk.io/log" + "cosmossdk.io/store" + storemetrics "cosmossdk.io/store/metrics" + storetypes "cosmossdk.io/store/types" + dbm "github.com/cosmos/cosmos-db" + sdk "github.com/cosmos/cosmos-sdk/types" + testutilmod "github.com/cosmos/cosmos-sdk/types/module/testutil" - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/x/cert/keeper" + types "pkg.akt.dev/go/node/cert/v1" + "pkg.akt.dev/go/testutil" + + "pkg.akt.dev/node/x/cert/keeper" ) func TestCertKeeperCreate(t *testing.T) { ctx, keeper := setupKeeper(t) owner := testutil.AccAddress(t) + cert := testutil.Certificate(t, owner) err := keeper.CreateCertificate(ctx, owner, cert.PEM.Cert, cert.PEM.Pub) @@ -35,7 +42,9 @@ func TestCertKeeperCreate(t *testing.T) { func TestCertKeeperCreateOwnerMismatch(t *testing.T) { ctx, keeper := setupKeeper(t) + owner := testutil.AccAddress(t) + cert := testutil.Certificate(t, owner) err := keeper.CreateCertificate(ctx, testutil.AccAddress(t), cert.PEM.Cert, cert.PEM.Pub) @@ -55,6 +64,7 @@ func TestCertKeeperCreateOwnerMismatch(t *testing.T) { func TestCertKeeperMultipleActive(t *testing.T) { ctx, keeper := setupKeeper(t) + owner := testutil.AccAddress(t) cert := testutil.Certificate(t, owner) @@ -92,7 +102,9 @@ func TestCertKeeperMultipleActive(t *testing.T) { func TestCertKeeperRevoke(t *testing.T) { ctx, keeper := setupKeeper(t) + owner := testutil.AccAddress(t) + cert := testutil.Certificate(t, owner) err := keeper.CreateCertificate(ctx, owner, cert.PEM.Cert, cert.PEM.Pub) @@ -127,7 +139,9 @@ func TestCertKeeperRevoke(t *testing.T) { func TestCertKeeperRevokeCreateRevoked(t *testing.T) { ctx, keeper := setupKeeper(t) + owner := testutil.AccAddress(t) + cert := testutil.Certificate(t, owner) err := keeper.CreateCertificate(ctx, owner, cert.PEM.Cert, cert.PEM.Pub) @@ -158,7 +172,9 @@ func TestCertKeeperRevokeCreateRevoked(t *testing.T) { func TestCertKeeperRevokeCreate(t *testing.T) { ctx, keeper := setupKeeper(t) + owner := testutil.AccAddress(t) + cert := testutil.Certificate(t, owner) err := keeper.CreateCertificate(ctx, owner, cert.PEM.Cert, cert.PEM.Pub) @@ -184,18 +200,25 @@ func TestCertKeeperRevokeCreate(t *testing.T) { testutil.CertificateRequireEqualResponse(t, cert, resp, types.CertificateRevoked) cert1 := testutil.Certificate(t, owner) + err = keeper.CreateCertificate(ctx, owner, cert1.PEM.Cert, cert1.PEM.Pub) require.NoError(t, err) } func setupKeeper(t testing.TB) (sdk.Context, keeper.Keeper) { t.Helper() - key := sdk.NewKVStoreKey(types.StoreKey) + + cfg := testutilmod.MakeTestEncodingConfig() + cdc := cfg.Codec + + key := storetypes.NewKVStoreKey(types.StoreKey) db := dbm.NewMemDB() - ms := store.NewCommitMultiStore(db) - ms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db) + ms := store.NewCommitMultiStore(db, log.NewNopLogger(), storemetrics.NewNoOpMetrics()) + ms.MountStoreWithDB(key, storetypes.StoreTypeIAVL, db) + err := ms.LoadLatestVersion() require.NoError(t, err) + ctx := sdk.NewContext(ms, tmproto.Header{Time: time.Unix(0, 0)}, false, testutil.Logger(t)) - return ctx, keeper.NewKeeper(types.ModuleCdc, key) + return ctx, keeper.NewKeeper(cdc, key) } diff --git a/x/cert/keeper/key.go b/x/cert/keeper/key.go index 7b20b43eed..87f02a7d35 100644 --- a/x/cert/keeper/key.go +++ b/x/cert/keeper/key.go @@ -4,14 +4,16 @@ import ( "bytes" "math/big" + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/kv" - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" + types "pkg.akt.dev/go/node/cert/v1" - "github.com/akash-network/node/util/validation" + "pkg.akt.dev/node/util/validation" ) const ( @@ -29,7 +31,7 @@ var ( CertStateRevokedPrefix = []byte{CertStateRevokedPrefixID} ) -func certStateToPrefix(state types.Certificate_State) []byte { +func certStateToPrefix(state types.State) []byte { var idx []byte switch state { @@ -44,7 +46,7 @@ func certStateToPrefix(state types.Certificate_State) []byte { return idx } -func buildCertPrefix(state types.Certificate_State) []byte { +func buildCertPrefix(state types.State) []byte { idx := certStateToPrefix(state) res := make([]byte, 0, len(CertPrefix)+len(idx)) @@ -55,7 +57,7 @@ func buildCertPrefix(state types.Certificate_State) []byte { } func filterToPrefix(filter types.CertificateFilter) ([]byte, error) { - prefix := buildCertPrefix(types.Certificate_State(types.Certificate_State_value[filter.State])) + prefix := buildCertPrefix(types.State(types.State_value[filter.State])) buf := bytes.NewBuffer(prefix) if len(filter.Owner) == 0 { @@ -96,9 +98,9 @@ func filterToPrefix(filter types.CertificateFilter) ([]byte, error) { // CertificateKey creates a store key of the format: // prefix_bytes | state 1 byte | owner_address_len (1 byte) | owner_address_bytes | serial length (1 byte) | serial_bytes -func CertificateKey(state types.Certificate_State, id types.CertID) ([]byte, error) { +func CertificateKey(state types.State, id types.CertID) ([]byte, error) { if id.Owner.Empty() { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "owner address is empty") + return nil, errorsmod.Wrap(sdkerrors.ErrInvalidAddress, "owner address is empty") } addr, err := address.LengthPrefix(id.Owner.Bytes()) @@ -123,7 +125,7 @@ func CertificateKey(state types.Certificate_State, id types.CertID) ([]byte, err return buf.Bytes(), nil } -func MustCertificateKey(state types.Certificate_State, id types.CertID) []byte { +func MustCertificateKey(state types.State, id types.CertID) []byte { key, err := CertificateKey(state, id) if err != nil { panic(err) @@ -134,7 +136,7 @@ func MustCertificateKey(state types.Certificate_State, id types.CertID) []byte { // ParseCertKey parse certificate key into id // format <0x11> -func ParseCertKey(from []byte) (types.Certificate_State, types.CertID, error) { +func ParseCertKey(from []byte) (types.State, types.CertID, error) { res := types.CertID{ Serial: *big.NewInt(0), } @@ -146,7 +148,7 @@ func ParseCertKey(from []byte) (types.Certificate_State, types.CertID, error) { // skip prefix from = from[len(CertPrefix):] - state := types.Certificate_State(from[0]) + state := types.State(from[0]) from = from[1:] // parse address length @@ -247,7 +249,7 @@ func serialPrefix(bz []byte) ([]byte, error) { } if bzLen > maxSerialLength { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "serial length should be max %d bytes, got %d", maxSerialLength, bzLen) + return nil, errorsmod.Wrapf(sdkerrors.ErrUnknownAddress, "serial length should be max %d bytes, got %d", maxSerialLength, bzLen) } return append([]byte{byte(bzLen)}, bz...), nil @@ -262,3 +264,31 @@ func mustSerialPrefix(bz []byte) []byte { return res } + +func ParseCertID(prefix []byte, from []byte) (types.CertID, error) { + res := types.CertID{ + Serial: *big.NewInt(0), + } + + // skip prefix if set + if len(prefix) > 0 { + from = from[len(prefix):] + } + + addLen := from[0] + + from = from[1:] + + addr := from[:addLen-1] + serial := from[addLen:] + + err := sdk.VerifyAddressFormat(addr) + if err != nil { + return res, err + } + + res.Owner = sdk.AccAddress(addr) + res.Serial.SetBytes(serial) + + return res, nil +} diff --git a/x/cert/keeper/key_test.go b/x/cert/keeper/key_test.go index 5fe45bf09c..7d30b51ca5 100644 --- a/x/cert/keeper/key_test.go +++ b/x/cert/keeper/key_test.go @@ -4,18 +4,18 @@ import ( "math/big" "testing" + "github.com/cometbft/cometbft/crypto/ed25519" "github.com/cosmos/cosmos-sdk/types/address" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto/ed25519" - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" sdk "github.com/cosmos/cosmos-sdk/types" + types "pkg.akt.dev/go/node/cert/v1" ) func TestCertStateToPrefix(t *testing.T) { tests := []struct { name string - state types.Certificate_State + state types.State expected []byte }{ { @@ -47,7 +47,7 @@ func TestCertStateToPrefixPanics(t *testing.T) { func TestBuildCertPrefix(t *testing.T) { tests := []struct { name string - state types.Certificate_State + state types.State expected []byte }{ { @@ -82,7 +82,7 @@ func TestCertificateKey(t *testing.T) { tests := []struct { name string - state types.Certificate_State + state types.State certID types.CertID expected []byte wantErr bool @@ -143,7 +143,7 @@ func TestCertificateKeyRaw(t *testing.T) { tests := []struct { name string - state types.Certificate_State + state types.State certID types.CertID expected []byte wantErr bool @@ -218,7 +218,7 @@ func TestParseCertKey(t *testing.T) { tests := []struct { name string key []byte - state types.Certificate_State + state types.State certID types.CertID wantErr bool }{ diff --git a/x/cert/module.go b/x/cert/module.go index d5748af552..29b5e14259 100644 --- a/x/cert/module.go +++ b/x/cert/module.go @@ -4,34 +4,35 @@ import ( "context" "encoding/json" "fmt" - "math/rand" - "github.com/cosmos/cosmos-sdk/client" - sdk "github.com/cosmos/cosmos-sdk/types" - sim "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/spf13/cobra" - - "github.com/gorilla/mux" + "cosmossdk.io/core/appmodule" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/grpc-ecosystem/grpc-gateway/runtime" - abci "github.com/tendermint/tendermint/abci/types" + "github.com/spf13/cobra" - "github.com/akash-network/akash-api/go/node/cert/v1beta1" - "github.com/akash-network/akash-api/go/node/cert/v1beta2" - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - "github.com/akash-network/node/x/cert/client/cli" - "github.com/akash-network/node/x/cert/handler" - "github.com/akash-network/node/x/cert/keeper" - "github.com/akash-network/node/x/cert/simulation" + types "pkg.akt.dev/go/node/cert/v1" + + "pkg.akt.dev/node/x/cert/handler" + "pkg.akt.dev/node/x/cert/keeper" + "pkg.akt.dev/node/x/cert/simulation" ) var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} - _ module.AppModuleSimulation = AppModuleSimulation{} + _ module.AppModuleBasic = AppModuleBasic{} + _ module.HasGenesisBasics = AppModuleBasic{} + + _ appmodule.AppModule = AppModule{} + _ module.HasConsensusVersion = AppModule{} + _ module.HasGenesis = AppModule{} + _ module.HasServices = AppModule{} + + _ module.AppModuleSimulation = AppModule{} ) // AppModuleBasic defines the basic application module used by the provider module. @@ -39,6 +40,12 @@ type AppModuleBasic struct { cdc codec.Codec } +// AppModule implements an application module for the audit module. +type AppModule struct { + AppModuleBasic + keeper keeper.Keeper +} + // Name returns provider module's name func (AppModuleBasic) Name() string { return types.ModuleName @@ -46,14 +53,12 @@ func (AppModuleBasic) Name() string { // RegisterLegacyAminoCodec registers the provider module's types for the given codec. func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { - types.RegisterLegacyAminoCodec(cdc) + types.RegisterLegacyAminoCodec(cdc) // nolint: staticcheck } // RegisterInterfaces registers the module's interface types func (b AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) { types.RegisterInterfaces(registry) - v1beta2.RegisterInterfaces(registry) - v1beta1.RegisterInterfaces(registry) } // DefaultGenesis returns default genesis state as raw bytes for the provider @@ -78,11 +83,6 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingCo return ValidateGenesis(&data) } -// RegisterRESTRoutes registers rest routes for this module -func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) { - -} - // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the provider module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) @@ -93,12 +93,12 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *r // GetQueryCmd returns the root query command of this module func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.GetQueryCmd() + panic("akash modules do not export cli commands via cosmos interface") } // GetTxCmd returns the transaction commands for this module func (AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.GetTxCmd() + panic("akash modules do not export cli commands via cosmos interface") } // GetQueryClient returns a new query client for this module @@ -106,12 +106,6 @@ func (AppModuleBasic) GetQueryClient(clientCtx client.Context) types.QueryClient return types.NewQueryClient(clientCtx) } -// AppModule implements an application module for the audit module. -type AppModule struct { - AppModuleBasic - keeper keeper.Keeper -} - // NewAppModule creates a new AppModule object func NewAppModule(cdc codec.Codec, k keeper.Keeper) AppModule { return AppModule{ @@ -125,23 +119,11 @@ func (AppModule) Name() string { return types.ModuleName } -// RegisterInvariants registers module invariants -func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} - -// Route returns the message routing key for the audit module. -func (am AppModule) Route() sdk.Route { - return sdk.NewRoute(types.RouterKey, handler.NewHandler(am.keeper)) -} - -// QuerierRoute returns the audit module's querier route name. -func (am AppModule) QuerierRoute() string { - return "" -} +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (am AppModule) IsOnePerModuleType() {} -// LegacyQuerierHandler returns the sdk.Querier for audit module -func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { - return nil -} +// IsAppModule implements the appmodule.AppModule interface. +func (am AppModule) IsAppModule() {} // RegisterServices registers the module's services func (am AppModule) RegisterServices(cfg module.Configurator) { @@ -150,71 +132,52 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { } // BeginBlock performs no-op -func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} +func (am AppModule) BeginBlock(_ context.Context) error { + return nil +} -// EndBlock returns the end blocker for the audit module. It returns no auditor +// EndBlock returns the end blocker for the deployment module. It returns no validator // updates. -func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - return []abci.ValidatorUpdate{} +func (am AppModule) EndBlock(_ context.Context) error { + return nil } -// InitGenesis performs genesis initialization for the audit module. It returns +// InitGenesis performs genesis initialization for the cert module. It returns // no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) { var genesisState types.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) - return InitGenesis(ctx, am.keeper, &genesisState) + InitGenesis(ctx, am.keeper, &genesisState) } // ExportGenesis returns the exported genesis state as raw bytes for the audit // module. func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { gs := ExportGenesis(ctx, am.keeper) + return cdc.MustMarshalJSON(gs) } // ConsensusVersion implements module.AppModule#ConsensusVersion func (am AppModule) ConsensusVersion() uint64 { - return 3 -} - -// ____________________________________________________________________________ - -// AppModuleSimulation implements an application simulation module for the audit module. -type AppModuleSimulation struct { - keeper keeper.Keeper -} - -// NewAppModuleSimulation creates a new AppModuleSimulation instance -func NewAppModuleSimulation(k keeper.Keeper) AppModuleSimulation { - return AppModuleSimulation{ - keeper: k, - } + return 4 } // AppModuleSimulation functions // GenerateGenesisState creates a randomized GenState of the staking module. -func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) { +func (AppModule) GenerateGenesisState(simState *module.SimulationState) { simulation.RandomizedGenState(simState) } -// ProposalContents doesn't return any content functions for governance proposals. -func (AppModuleSimulation) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent { +// ProposalMsgs returns msgs used for governance proposals for simulations. +func (AppModule) ProposalMsgs(_ module.SimulationState) []simtypes.WeightedProposalMsg { return nil } -// RandomizedParams creates randomized staking param changes for the simulator. -func (AppModuleSimulation) RandomizedParams(_ *rand.Rand) []sim.ParamChange { - return nil -} - -// RegisterStoreDecoder registers a decoder for staking module's types -func (AppModuleSimulation) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) { - -} +func (am AppModule) RegisterStoreDecoder(_ simtypes.StoreDecoderRegistry) {} -// WeightedOperations returns the all the staking module operations with their respective weights. -func (am AppModuleSimulation) WeightedOperations(_ module.SimulationState) []sim.WeightedOperation { +// WeightedOperations doesn't return any take module operation. +func (am AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { return nil } diff --git a/x/cert/simulation/genesis.go b/x/cert/simulation/genesis.go index 35937b336d..e2e03d75b3 100644 --- a/x/cert/simulation/genesis.go +++ b/x/cert/simulation/genesis.go @@ -3,7 +3,7 @@ package simulation import ( "github.com/cosmos/cosmos-sdk/types/module" - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" + types "pkg.akt.dev/go/node/cert/v1" ) func RandomizedGenState(simState *module.SimulationState) { diff --git a/x/cert/utils/constants.go b/x/cert/utils/constants.go index 1e9eaaa797..3e21a489d5 100644 --- a/x/cert/utils/constants.go +++ b/x/cert/utils/constants.go @@ -1,3 +1,5 @@ +//nolint: revive + package utils import "encoding/asn1" diff --git a/x/cert/utils/key_pair_manager.go b/x/cert/utils/key_pair_manager.go index 3b9e070f77..5ab6776154 100644 --- a/x/cert/utils/key_pair_manager.go +++ b/x/cert/utils/key_pair_manager.go @@ -1,3 +1,5 @@ +//nolint: revive + package utils import ( @@ -17,13 +19,15 @@ import ( "os" "time" + "github.com/cosmos/cosmos-sdk/types/tx/signing" "go.step.sm/crypto/pemutil" - types "github.com/akash-network/akash-api/go/node/cert/v1beta3" sdkclient "github.com/cosmos/cosmos-sdk/client" sdk "github.com/cosmos/cosmos-sdk/types" - certerrors "github.com/akash-network/node/x/cert/errors" + types "pkg.akt.dev/go/node/cert/v1" + + certerrors "pkg.akt.dev/node/x/cert/errors" ) var ( @@ -51,7 +55,7 @@ type keyPairManager struct { } func NewKeyPairManager(cctx sdkclient.Context, fromAddress sdk.AccAddress) (KeyPairManager, error) { - sig, _, err := cctx.Keyring.SignByAddress(fromAddress, []byte(fromAddress.String())) + sig, _, err := cctx.Keyring.SignByAddress(fromAddress, []byte(fromAddress.String()), signing.SignMode_SIGN_MODE_DIRECT) if err != nil { return nil, err } @@ -59,7 +63,7 @@ func NewKeyPairManager(cctx sdkclient.Context, fromAddress sdk.AccAddress) (KeyP // ignore error if ledger device is being used // due to its jsonparser not liking bech address sent as data in binary format // if test or file keyring used it will allow to decode old private keys for the mTLS cert - sigLegacy, _, _ := cctx.Keyring.SignByAddress(fromAddress, fromAddress.Bytes()) + sigLegacy, _, _ := cctx.Keyring.SignByAddress(fromAddress, fromAddress.Bytes(), signing.SignMode_SIGN_MODE_DIRECT) return &keyPairManager{ addr: fromAddress, diff --git a/x/cert/utils/utils.go b/x/cert/utils/utils.go index 21653c9e4c..19f854e980 100644 --- a/x/cert/utils/utils.go +++ b/x/cert/utils/utils.go @@ -7,11 +7,11 @@ import ( "io" "time" - certerrors "github.com/akash-network/node/x/cert/errors" + certerrors "pkg.akt.dev/node/x/cert/errors" "github.com/cosmos/cosmos-sdk/client" - ctypes "github.com/akash-network/akash-api/go/node/cert/v1beta3" + ctypes "pkg.akt.dev/go/node/cert/v1" ) // LoadAndQueryCertificateForAccount wraps LoadAndQueryPEMForAccount and tls.X509KeyPair diff --git a/x/deployment/alias.go b/x/deployment/alias.go index ad74d2dd8e..8ffc73a9b0 100644 --- a/x/deployment/alias.go +++ b/x/deployment/alias.go @@ -1,9 +1,9 @@ package deployment import ( - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + types "pkg.akt.dev/go/node/deployment/v1" - "github.com/akash-network/node/x/deployment/keeper" + "pkg.akt.dev/node/x/deployment/keeper" ) const ( diff --git a/x/deployment/client/cli/cli_test.go b/x/deployment/client/cli/cli_test.go deleted file mode 100644 index 71f46544a5..0000000000 --- a/x/deployment/client/cli/cli_test.go +++ /dev/null @@ -1,463 +0,0 @@ -package cli_test - -import ( - "context" - "fmt" - "path/filepath" - "testing" - - "github.com/stretchr/testify/suite" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - sdk "github.com/cosmos/cosmos-sdk/types" - banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - - "github.com/akash-network/node/testutil" - clitestutil "github.com/akash-network/node/testutil/cli" - "github.com/akash-network/node/testutil/network" - ccli "github.com/akash-network/node/x/cert/client/cli" - "github.com/akash-network/node/x/deployment/client/cli" -) - -type IntegrationTestSuite struct { - suite.Suite - cfg network.Config - network *network.Network - keyFunder keyring.Info - defaultDeposit sdk.Coin -} - -func (s *IntegrationTestSuite) SetupSuite() { - s.T().Log("setting up integration test suite") - - cfg := testutil.DefaultConfig() - cfg.NumValidators = 1 - // cfg.EnableLogging = true - - s.cfg = cfg - s.network = network.New(s.T(), cfg) - - kb := s.network.Validators[0].ClientCtx.Keyring - _, _, err := kb.NewMnemonic("keyFoo", keyring.English, sdk.FullFundraiserPath, "", hd.Secp256k1) - s.Require().NoError(err) - - _, err = s.network.WaitForHeight(1) - s.Require().NoError(err) - - val := s.network.Validators[0] - - // Initialize funder keys with coins - s.keyFunder, err = val.ClientCtx.Keyring.Key("keyFoo") - s.Require().NoError(err) - - s.defaultDeposit, err = types.DefaultParams().MinDepositFor("uakt") - s.Require().NoError(err) - - res, err := banktestutil.MsgSendExec( - val.ClientCtx, - val.Address, - s.keyFunder.GetAddress(), - sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, s.defaultDeposit.Amount.MulRaw(4))), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - clitestutil.ValidateTxSuccessful(s.T(), val.ClientCtx, res.Bytes()) - - // Create client certificate - _, err = ccli.TxGenerateClientExec( - context.Background(), - val.ClientCtx, - val.Address, - ) - s.Require().NoError(err) - - // Publish client certificate - _, err = ccli.TxPublishClientExec( - context.Background(), - val.ClientCtx, - val.Address, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) -} - -func (s *IntegrationTestSuite) TearDownSuite() { - s.T().Log("tearing down integration test suite") - s.network.Cleanup() -} - -func (s *IntegrationTestSuite) TestDeployment() { - val := s.network.Validators[0] - - deploymentPath, err := filepath.Abs("../../testdata/deployment.yaml") - s.Require().NoError(err) - - deploymentPath2, err := filepath.Abs("../../testdata/deployment-v2.yaml") - s.Require().NoError(err) - - // create deployment - _, err = cli.TxCreateDeploymentExec( - val.ClientCtx, - val.Address, - deploymentPath, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - fmt.Sprintf("--deposit=%s", cli.DefaultDeposit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - // test query deployments - resp, err := cli.QueryDeploymentsExec(val.ClientCtx.WithOutputFormat("json")) - s.Require().NoError(err) - - out := &types.QueryDeploymentsResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), out) - s.Require().NoError(err) - s.Require().Len(out.Deployments, 1, "Deployment Create Failed") - deployments := out.Deployments - s.Require().Equal(val.Address.String(), deployments[0].Deployment.DeploymentID.Owner) - - // test query deployment - createdDep := deployments[0] - resp, err = cli.QueryDeploymentExec(val.ClientCtx.WithOutputFormat("json"), createdDep.Deployment.DeploymentID) - s.Require().NoError(err) - - var deployment types.QueryDeploymentResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &deployment) - s.Require().NoError(err) - s.Require().Equal(createdDep, deployment) - - // test query deployments with filters - resp, err = cli.QueryDeploymentsExec( - val.ClientCtx.WithOutputFormat("json"), - fmt.Sprintf("--owner=%s", val.Address.String()), - fmt.Sprintf("--dseq=%v", createdDep.Deployment.DeploymentID.DSeq), - ) - s.Require().NoError(err, "Error when fetching deployments with owner filter") - - out = &types.QueryDeploymentsResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), out) - s.Require().NoError(err) - s.Require().Len(out.Deployments, 1) - - // test updating deployment - _, err = cli.TxUpdateDeploymentExec( - val.ClientCtx, - val.Address, - deploymentPath2, - fmt.Sprintf("--dseq=%v", createdDep.Deployment.DeploymentID.DSeq), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - resp, err = cli.QueryDeploymentExec(val.ClientCtx.WithOutputFormat("json"), createdDep.Deployment.DeploymentID) - s.Require().NoError(err) - - var deploymentV2 types.QueryDeploymentResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &deploymentV2) - s.Require().NoError(err) - s.Require().NotEqual(deployment.Deployment.Version, deploymentV2.Deployment.Version) - - // test query deployments with wrong owner value - _, err = cli.QueryDeploymentsExec( - val.ClientCtx.WithOutputFormat("json"), - "--owner=cosmos102ruvpv2srmunfffxavttxnhezln6fnc3pf7tt", - ) - s.Require().Error(err) - - // test query deployments with wrong state value - _, err = cli.QueryDeploymentsExec( - val.ClientCtx.WithOutputFormat("json"), - "--state=hello", - ) - s.Require().Error(err) - - // test close deployment - _, err = cli.TxCloseDeploymentExec( - val.ClientCtx, - val.Address, - fmt.Sprintf("--dseq=%v", createdDep.Deployment.DeploymentID.DSeq), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - // test query deployments with state filter closed - resp, err = cli.QueryDeploymentsExec( - val.ClientCtx.WithOutputFormat("json"), - "--state=closed", - ) - s.Require().NoError(err) - - out = &types.QueryDeploymentsResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), out) - s.Require().NoError(err) - s.Require().Len(out.Deployments, 1, "Deployment Close Failed") -} - -func (s *IntegrationTestSuite) TestGroup() { - val := s.network.Validators[0] - - deploymentPath, err := filepath.Abs("../../testdata/deployment.yaml") - s.Require().NoError(err) - - // create deployment - _, err = cli.TxCreateDeploymentExec( - val.ClientCtx, - val.Address, - deploymentPath, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - fmt.Sprintf("--deposit=%s", cli.DefaultDeposit), - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // test query deployments - resp, err := cli.QueryDeploymentsExec( - val.ClientCtx.WithOutputFormat("json"), - "--state=active", - ) - s.Require().NoError(err) - - out := &types.QueryDeploymentsResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), out) - s.Require().NoError(err) - s.Require().Len(out.Deployments, 1, "Deployment Create Failed") - deployments := out.Deployments - s.Require().Equal(val.Address.String(), deployments[0].Deployment.DeploymentID.Owner) - - createdDep := deployments[0] - - s.Require().NotEqual(0, len(createdDep.Groups)) - - // test close group tx - _, err = cli.TxCloseGroupExec( - val.ClientCtx, - createdDep.Groups[0].GroupID, - val.Address, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - resp, err = cli.QueryGroupExec(val.ClientCtx.WithOutputFormat("json"), createdDep.Groups[0].GroupID) - s.Require().NoError(err) - - var group types.Group - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &group) - s.Require().NoError(err) - s.Require().Equal(types.GroupClosed, group.State) -} - -func (s *IntegrationTestSuite) TestFundedDeployment() { - // setup - val := s.network.Validators[0] - deploymentPath, err := filepath.Abs("../../testdata/deployment-v2.yaml") - s.Require().NoError(err) - - deploymentID := types.DeploymentID{ - Owner: val.Address.String(), - DSeq: uint64(105), - } - - prevFunderBal := s.getAccountBalance(s.keyFunder.GetAddress()) - - // Creating deployment paid by funder's account without any authorization from funder should fail - _, err = cli.TxCreateDeploymentExec( - val.ClientCtx, - val.Address, - deploymentPath, - fmt.Sprintf("--%s", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(20))).String()), - fmt.Sprintf("--dseq=%v", deploymentID.DSeq), - fmt.Sprintf("--depositor-account=%s", s.keyFunder.GetAddress().String()), - ) - s.Require().Error(err) - - // funder's balance shouldn't be deducted - s.Require().Equal(prevFunderBal, s.getAccountBalance(s.keyFunder.GetAddress())) - - // Grant the tenant authorization to use funds from the funder's account - res, err := cli.TxGrantAuthorizationExec( - val.ClientCtx, - s.keyFunder.GetAddress(), - val.Address, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - clitestutil.ValidateTxSuccessful(s.T(), val.ClientCtx, res.Bytes()) - prevFunderBal = s.getAccountBalance(s.keyFunder.GetAddress()) - - ownerBal := s.getAccountBalance(val.Address) - - // Creating deployment paid by funder's account should work now - res, err = cli.TxCreateDeploymentExec( - val.ClientCtx, - val.Address, - deploymentPath, - fmt.Sprintf("--%s", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(20))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - fmt.Sprintf("--dseq=%v", deploymentID.DSeq), - fmt.Sprintf("--depositor-account=%s", s.keyFunder.GetAddress().String()), - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - clitestutil.ValidateTxSuccessful(s.T(), val.ClientCtx, res.Bytes()) - - // funder's balance should be deducted correctly - curFunderBal := s.getAccountBalance(s.keyFunder.GetAddress()) - s.Require().Equal(prevFunderBal.Sub(s.defaultDeposit.Amount), curFunderBal) - prevFunderBal = curFunderBal - - // owner's balance should be deducted correctly - curOwnerBal := s.getAccountBalance(val.Address) - s.Require().Equal(ownerBal.SubRaw(20), curOwnerBal) - ownerBal = curOwnerBal - - // depositing additional funds from the owner's account should work - res, err = cli.TxDepositDeploymentExec( - val.ClientCtx, - s.defaultDeposit, - val.Address, - fmt.Sprintf("--%s", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(20))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - fmt.Sprintf("--dseq=%v", deploymentID.DSeq), - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - clitestutil.ValidateTxSuccessful(s.T(), val.ClientCtx, res.Bytes()) - - // owner's balance should be deducted correctly - curOwnerBal = s.getAccountBalance(val.Address) - s.Require().Equal(ownerBal.Sub(s.defaultDeposit.Amount).SubRaw(20), curOwnerBal) - // s.Require().Equal(prevOwnerBal.Sub(types.DefaultDeploymentMinDeposit.Amount), curOwnerBal) - ownerBal = curOwnerBal - - // depositing additional funds from the funder's account should work - res, err = cli.TxDepositDeploymentExec( - val.ClientCtx, - s.defaultDeposit, - val.Address, - fmt.Sprintf("--%s", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(20))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - fmt.Sprintf("--dseq=%v", deploymentID.DSeq), - fmt.Sprintf("--depositor-account=%s", s.keyFunder.GetAddress().String()), - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - clitestutil.ValidateTxSuccessful(s.T(), val.ClientCtx, res.Bytes()) - - // funder's balance should be deducted correctly - curFunderBal = s.getAccountBalance(s.keyFunder.GetAddress()) - s.Require().Equal(prevFunderBal.Sub(s.defaultDeposit.Amount), curFunderBal) - prevFunderBal = curFunderBal - - // revoke the authorization given to the deployment owner by the funder - res, err = cli.TxRevokeAuthorizationExec( - val.ClientCtx, - s.keyFunder.GetAddress(), - val.Address, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - clitestutil.ValidateTxSuccessful(s.T(), val.ClientCtx, res.Bytes()) - prevFunderBal = s.getAccountBalance(s.keyFunder.GetAddress()) - - // depositing additional funds from the funder's account should fail now - _, err = cli.TxDepositDeploymentExec( - val.ClientCtx, - s.defaultDeposit, - val.Address, - fmt.Sprintf("--%s", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(20))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - fmt.Sprintf("--dseq=%v", deploymentID.DSeq), - fmt.Sprintf("--depositor-account=%s", s.keyFunder.GetAddress().String()), - ) - s.Require().Error(err) - - // funder's balance shouldn't be deducted - s.Require().Equal(prevFunderBal, s.getAccountBalance(s.keyFunder.GetAddress())) - ownerBal = s.getAccountBalance(val.Address) - - // closing the deployment should return the funds and balance in escrow to the funder and - // owner's account - res, err = cli.TxCloseDeploymentExec( - val.ClientCtx, - val.Address, - fmt.Sprintf("--%s", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(20))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - fmt.Sprintf("--dseq=%v", deploymentID.DSeq), - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - clitestutil.ValidateTxSuccessful(s.T(), val.ClientCtx, res.Bytes()) - s.Require().Equal(prevFunderBal.Add(s.defaultDeposit.Amount.MulRaw(2)), s.getAccountBalance(s.keyFunder.GetAddress())) - s.Require().Equal(ownerBal.Add(s.defaultDeposit.Amount).SubRaw(20), s.getAccountBalance(val.Address)) -} - -func TestIntegrationTestSuite(t *testing.T) { - suite.Run(t, new(IntegrationTestSuite)) -} - -func (s *IntegrationTestSuite) getAccountBalance(address sdk.AccAddress) sdk.Int { - cctxJSON := s.network.Validators[0].ClientCtx.WithOutputFormat("json") - res, err := banktestutil.QueryBalancesExec(cctxJSON, address) - s.Require().NoError(err) - var balRes banktypes.QueryAllBalancesResponse - err = cctxJSON.Codec.UnmarshalJSON(res.Bytes(), &balRes) - s.Require().NoError(err) - return balRes.Balances.AmountOf(s.cfg.BondDenom) -} diff --git a/x/deployment/client/cli/flags.go b/x/deployment/client/cli/flags.go deleted file mode 100644 index 5715318189..0000000000 --- a/x/deployment/client/cli/flags.go +++ /dev/null @@ -1,212 +0,0 @@ -package cli - -import ( - "errors" - "strings" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" -) - -const ( - FlagDepositorAccount = "depositor-account" - FlagExpiration = "expiration" -) - -var ( - ErrStateValue = errors.New("query: invalid state value") - DefaultDeposit, _ = types.DefaultParams().MinDepositFor("uakt") -) - -type DeploymentIDOptions struct { - NoOwner bool -} - -type DeploymentIDOption func(*DeploymentIDOptions) - -// DeploymentIDOptionNoOwner do not add mark as required owner flag -func DeploymentIDOptionNoOwner(val bool) DeploymentIDOption { - return func(opt *DeploymentIDOptions) { - opt.NoOwner = val - } -} - -type MarketOptions struct { - Owner sdk.AccAddress - Provider sdk.AccAddress -} - -type MarketOption func(*MarketOptions) - -func WithOwner(val sdk.AccAddress) MarketOption { - return func(opt *MarketOptions) { - opt.Owner = val - } -} - -func WithProvider(val sdk.AccAddress) MarketOption { - return func(opt *MarketOptions) { - opt.Provider = val - } -} - -// AddDeploymentIDFlags add flags for deployment except for Owner when NoOwner is set -func AddDeploymentIDFlags(flags *pflag.FlagSet, opts ...DeploymentIDOption) { - opt := &DeploymentIDOptions{} - - for _, o := range opts { - o(opt) - } - - if !opt.NoOwner { - flags.String("owner", "", "Deployment Owner") - } - - flags.Uint64("dseq", 0, "Deployment Sequence") -} - -// MarkReqDeploymentIDFlags marks flags required except for Owner when NoOwner is set -func MarkReqDeploymentIDFlags(cmd *cobra.Command, opts ...DeploymentIDOption) { - opt := &DeploymentIDOptions{} - - for _, o := range opts { - o(opt) - } - - if !opt.NoOwner { - _ = cmd.MarkFlagRequired("owner") - } - - _ = cmd.MarkFlagRequired("dseq") -} - -// DeploymentIDFromFlags returns DeploymentID with given flags, owner and error if occurred -func DeploymentIDFromFlags(flags *pflag.FlagSet, opts ...MarketOption) (types.DeploymentID, error) { - var id types.DeploymentID - opt := &MarketOptions{} - - for _, o := range opts { - o(opt) - } - - var owner string - if flag := flags.Lookup("owner"); flag != nil { - owner = flag.Value.String() - } - - // if --owner flag was explicitly provided, use that. - var err error - if owner != "" { - opt.Owner, err = sdk.AccAddressFromBech32(owner) - if err != nil { - return id, err - } - } - - id.Owner = opt.Owner.String() - - if id.DSeq, err = flags.GetUint64("dseq"); err != nil { - return id, err - } - return id, nil -} - -// DeploymentIDFromFlagsForOwner returns DeploymentID with given flags, owner and error if occurred -func DeploymentIDFromFlagsForOwner(flags *pflag.FlagSet, owner sdk.Address) (types.DeploymentID, error) { - id := types.DeploymentID{ - Owner: owner.String(), - } - - var err error - if id.DSeq, err = flags.GetUint64("dseq"); err != nil { - return id, err - } - - return id, nil -} - -// AddGroupIDFlags add flags for Group -func AddGroupIDFlags(flags *pflag.FlagSet, opts ...DeploymentIDOption) { - AddDeploymentIDFlags(flags, opts...) - flags.Uint32("gseq", 1, "Group Sequence") -} - -// MarkReqGroupIDFlags marks flags required for group -func MarkReqGroupIDFlags(cmd *cobra.Command, opts ...DeploymentIDOption) { - MarkReqDeploymentIDFlags(cmd, opts...) -} - -// GroupIDFromFlags returns GroupID with given flags and error if occurred -func GroupIDFromFlags(flags *pflag.FlagSet, opts ...MarketOption) (types.GroupID, error) { - var id types.GroupID - prev, err := DeploymentIDFromFlags(flags, opts...) - if err != nil { - return id, err - } - - gseq, err := flags.GetUint32("gseq") - if err != nil { - return id, err - } - return types.MakeGroupID(prev, gseq), nil -} - -// AddDeploymentFilterFlags add flags to filter for deployment list -func AddDeploymentFilterFlags(flags *pflag.FlagSet) { - flags.String("owner", "", "deployment owner address to filter") - flags.String("state", "", "deployment state to filter (active,closed)") - flags.Uint64("dseq", 0, "deployment sequence to filter") -} - -// DepFiltersFromFlags returns DeploymentFilters with given flags and error if occurred -func DepFiltersFromFlags(flags *pflag.FlagSet) (types.DeploymentFilters, error) { - var dfilters types.DeploymentFilters - owner, err := flags.GetString("owner") - if err != nil { - return dfilters, err - } - - if owner != "" { - _, err = sdk.AccAddressFromBech32(owner) - if err != nil { - return dfilters, err - } - } - - dfilters.Owner = owner - - if dfilters.State, err = flags.GetString("state"); err != nil { - return dfilters, err - } - - if dfilters.DSeq, err = flags.GetUint64("dseq"); err != nil { - return dfilters, err - } - - return dfilters, nil -} - -// AddDepositorFlag adds the `--depositor-account` flag -func AddDepositorFlag(flags *pflag.FlagSet) { - flags.String(FlagDepositorAccount, "", "Depositor account pays for the deposit instead of deducting from the owner") -} - -// DepositorFromFlags returns the depositor account if one was specified in flags, -// otherwise it returns the owner's account. -func DepositorFromFlags(flags *pflag.FlagSet, owner string) (string, error) { - depositorAcc, err := flags.GetString(FlagDepositorAccount) - if err != nil { - return "", err - } - - // if no depositor is specified, owner is the default depositor - if strings.TrimSpace(depositorAcc) == "" { - return owner, nil - } - - _, err = sdk.AccAddressFromBech32(depositorAcc) - return depositorAcc, err -} diff --git a/x/deployment/client/cli/grpc_rest_test.go b/x/deployment/client/cli/grpc_rest_test.go deleted file mode 100644 index 6e4746d13f..0000000000 --- a/x/deployment/client/cli/grpc_rest_test.go +++ /dev/null @@ -1,301 +0,0 @@ -package cli_test - -import ( - "context" - "fmt" - "path/filepath" - "testing" - - "github.com/stretchr/testify/suite" - - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkrest "github.com/cosmos/cosmos-sdk/types/rest" - - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/testutil/network" - atypes "github.com/akash-network/node/types" - ccli "github.com/akash-network/node/x/cert/client/cli" - "github.com/akash-network/node/x/deployment/client/cli" -) - -type GRPCRestTestSuite struct { - suite.Suite - - cfg network.Config - network *network.Network - deployment types.QueryDeploymentResponse -} - -func (s *GRPCRestTestSuite) SetupSuite() { - s.T().Log("setting up integration test suite") - - cfg := testutil.DefaultConfig() - cfg.NumValidators = 1 - - s.cfg = cfg - s.network = network.New(s.T(), cfg) - - _, err := s.network.WaitForHeight(1) - s.Require().NoError(err) - - val := s.network.Validators[0] - - deploymentPath, err := filepath.Abs("../../testdata/deployment.yaml") - s.Require().NoError(err) - - // Generate client certificate - _, err = ccli.TxGenerateClientExec( - context.Background(), - val.ClientCtx, - val.Address, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // Publish client certificate - _, err = ccli.TxPublishClientExec( - context.Background(), - val.ClientCtx, - val.Address, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // create deployment - _, err = cli.TxCreateDeploymentExec( - val.ClientCtx, - val.Address, - deploymentPath, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - fmt.Sprintf("--deposit=%s", cli.DefaultDeposit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - // get deployment - resp, err := cli.QueryDeploymentsExec(val.ClientCtx.WithOutputFormat("json")) - s.Require().NoError(err) - - out := &types.QueryDeploymentsResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), out) - s.Require().NoError(err) - s.Require().Len(out.Deployments, 1, "Cert Create Failed") - deployments := out.Deployments - s.Require().Equal(val.Address.String(), deployments[0].Deployment.DeploymentID.Owner) - - s.deployment = deployments[0] -} - -func (s *GRPCRestTestSuite) TestGetDeployments() { - val := s.network.Validators[0] - deployment := s.deployment - - testCases := []struct { - name string - url string - expErr bool - expResp types.QueryDeploymentResponse - expLen int - }{ - { - "get deployments without filters", - fmt.Sprintf("%s/akash/deployment/%s/deployments/list", val.APIAddress, atypes.ProtoAPIVersion), - false, - deployment, - 1, - }, - { - "get deployments with filters", - fmt.Sprintf("%s/akash/deployment/%s/deployments/list?filters.owner=%s", val.APIAddress, - atypes.ProtoAPIVersion, - deployment.Deployment.DeploymentID.Owner), - false, - deployment, - 1, - }, - { - "get deployments with wrong state filter", - fmt.Sprintf("%s/akash/deployment/%s/deployments/list?filters.state=%s", val.APIAddress, atypes.ProtoAPIVersion, - types.DeploymentStateInvalid.String()), - true, - types.QueryDeploymentResponse{}, - 0, - }, - { - "get deployments with two filters", - fmt.Sprintf("%s/akash/deployment/%s/deployments/list?filters.state=%s&filters.dseq=%d", - val.APIAddress, atypes.ProtoAPIVersion, deployment.Deployment.State.String(), deployment.Deployment.DeploymentID.DSeq), - false, - deployment, - 1, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := sdkrest.GetRequest(tc.url) - s.Require().NoError(err) - - var deployments types.QueryDeploymentsResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp, &deployments) - - if tc.expErr { - s.Require().NotNil(err) - s.Require().Empty(deployments.Deployments) - } else { - s.Require().NoError(err) - s.Require().Len(deployments.Deployments, tc.expLen) - s.Require().Equal(tc.expResp, deployments.Deployments[0]) - } - }) - } -} - -func (s *GRPCRestTestSuite) TestGetDeployment() { - val := s.network.Validators[0] - deployment := s.deployment - - testCases := []struct { - name string - url string - expErr bool - expResp types.QueryDeploymentResponse - }{ - { - "get deployment with empty input", - fmt.Sprintf("%s/akash/deployment/%s/deployments/info", val.APIAddress, atypes.ProtoAPIVersion), - true, - types.QueryDeploymentResponse{}, - }, - { - "get deployment with invalid input", - fmt.Sprintf("%s/akash/deployment/%s/deployments/info?id.owner=%s", val.APIAddress, - atypes.ProtoAPIVersion, - deployment.Deployment.DeploymentID.Owner), - true, - types.QueryDeploymentResponse{}, - }, - { - "deployment not found", - fmt.Sprintf("%s/akash/deployment/%s/deployments/info?id.owner=%s&id.dseq=%d", val.APIAddress, - atypes.ProtoAPIVersion, - deployment.Deployment.DeploymentID.Owner, - 249), - true, - types.QueryDeploymentResponse{}, - }, - { - "valid get deployment request", - fmt.Sprintf("%s/akash/deployment/%s/deployments/info?id.owner=%s&id.dseq=%d", - val.APIAddress, - atypes.ProtoAPIVersion, - deployment.Deployment.DeploymentID.Owner, - deployment.Deployment.DeploymentID.DSeq), - false, - deployment, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := sdkrest.GetRequest(tc.url) - s.Require().NoError(err) - - var out types.QueryDeploymentResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp, &out) - - if tc.expErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().Equal(tc.expResp, out) - } - }) - } -} - -func (s *GRPCRestTestSuite) TestGetGroup() { - val := s.network.Validators[0] - deployment := s.deployment - s.Require().NotEqual(0, len(deployment.Groups)) - group := deployment.Groups[0] - - testCases := []struct { - name string - url string - expErr bool - expResp types.Group - }{ - { - "get group with empty input", - fmt.Sprintf("%s/akash/deployment/%s/groups/info", val.APIAddress, atypes.ProtoAPIVersion), - true, - types.Group{}, - }, - { - "get group with invalid input", - fmt.Sprintf("%s/akash/deployment/%s/groups/info?id.owner=%s", val.APIAddress, - atypes.ProtoAPIVersion, - group.GroupID.Owner), - true, - types.Group{}, - }, - { - "group not found", - fmt.Sprintf("%s/akash/deployment/%s/groups/info?id.owner=%s&id.dseq=%d", val.APIAddress, - atypes.ProtoAPIVersion, - group.GroupID.Owner, - 249), - true, - types.Group{}, - }, - { - "valid get group request", - fmt.Sprintf("%s/akash/deployment/%s/groups/info?id.owner=%s&id.dseq=%d&id.gseq=%d", - val.APIAddress, - atypes.ProtoAPIVersion, - group.GroupID.Owner, - group.GroupID.DSeq, - group.GroupID.GSeq), - false, - group, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := sdkrest.GetRequest(tc.url) - s.Require().NoError(err) - - var out types.QueryGroupResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp, &out) - - if tc.expErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().Equal(tc.expResp, out.Group) - } - }) - } -} - -func (s *GRPCRestTestSuite) TearDownSuite() { - s.T().Log("tearing down integration test suite") - s.network.Cleanup() -} - -func TestGRPCRestTestSuite(t *testing.T) { - suite.Run(t, new(GRPCRestTestSuite)) -} diff --git a/x/deployment/client/cli/query.go b/x/deployment/client/cli/query.go deleted file mode 100644 index d6dc4aef7b..0000000000 --- a/x/deployment/client/cli/query.go +++ /dev/null @@ -1,174 +0,0 @@ -package cli - -import ( - "context" - - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/spf13/cobra" - - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - - aclient "github.com/akash-network/node/client" - clientutils "github.com/akash-network/node/client" -) - -// GetQueryCmd returns the query commands for the deployment module -func GetQueryCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: "Deployment query commands", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - - cmd.AddCommand( - cmdDeployments(), - cmdDeployment(), - getGroupCmd(), - ) - - return cmd -} - -func cmdDeployments() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "Query for all deployments", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientQueryContext(cmd) - if err != nil { - return err - } - - qq, err := aclient.DiscoverQueryClient(ctx, cctx) - if err != nil { - return err - } - - dfilters, err := DepFiltersFromFlags(cmd.Flags()) - if err != nil { - return err - } - - pageReq, err := clientutils.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - params := &types.QueryDeploymentsRequest{ - Filters: dfilters, - Pagination: pageReq, - } - - res, err := qq.Deployments(context.Background(), params) - if err != nil { - return err - } - - return qq.ClientContext().PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "deployments") - AddDeploymentFilterFlags(cmd.Flags()) - - return cmd -} - -func cmdDeployment() *cobra.Command { - cmd := &cobra.Command{ - Use: "get", - Short: "Query deployment", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientQueryContext(cmd) - if err != nil { - return err - } - - qq, err := aclient.DiscoverQueryClient(ctx, cctx) - if err != nil { - return err - } - - id, err := DeploymentIDFromFlags(cmd.Flags()) - if err != nil { - return err - } - - res, err := qq.Deployment(context.Background(), &types.QueryDeploymentRequest{ID: id}) - if err != nil { - return err - } - - return qq.ClientContext().PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - AddDeploymentIDFlags(cmd.Flags()) - MarkReqDeploymentIDFlags(cmd) - - return cmd -} - -func getGroupCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "group", - Short: "Deployment group query commands", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - - cmd.AddCommand( - cmdGetGroup(), - ) - - return cmd -} - -func cmdGetGroup() *cobra.Command { - cmd := &cobra.Command{ - Use: "get", - Short: "Query group of deployment", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientQueryContext(cmd) - if err != nil { - return err - } - - qq, err := aclient.DiscoverQueryClient(ctx, cctx) - if err != nil { - return err - } - - id, err := GroupIDFromFlags(cmd.Flags()) - if err != nil { - return err - } - - res, err := qq.Group(cmd.Context(), &types.QueryGroupRequest{ID: id}) - if err != nil { - return err - } - - return qq.ClientContext().PrintProto(&res.Group) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - AddGroupIDFlags(cmd.Flags()) - MarkReqGroupIDFlags(cmd) - - return cmd -} diff --git a/x/deployment/client/cli/test_helpers.go b/x/deployment/client/cli/test_helpers.go deleted file mode 100644 index be86a43a95..0000000000 --- a/x/deployment/client/cli/test_helpers.go +++ /dev/null @@ -1,136 +0,0 @@ -package cli - -import ( - "context" - "fmt" - - "github.com/cosmos/cosmos-sdk/client" - sdktest "github.com/cosmos/cosmos-sdk/testutil" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - sdk "github.com/cosmos/cosmos-sdk/types" - - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - - testutilcli "github.com/akash-network/node/testutil/cli" -) - -const key string = types.StoreKey - -// XXX: WHY TF DON'T THESE RETURN OBJECTS - -// TxCreateDeploymentExec is used for testing create deployment tx -func TxCreateDeploymentExec(clientCtx client.Context, from fmt.Stringer, filePath string, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--from=%s", from.String()), - filePath, - } - - args = append(args, extraArgs...) - - return testutilcli.ExecTestCLICmd(context.Background(), clientCtx, cmdCreate(key), args...) -} - -// TxUpdateDeploymentExec is used for testing update deployment tx -func TxUpdateDeploymentExec(clientCtx client.Context, from fmt.Stringer, filePath string, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--from=%s", from.String()), - filePath, - } - - args = append(args, extraArgs...) - - return testutilcli.ExecTestCLICmd(context.Background(), clientCtx, cmdUpdate(key), args...) -} - -// TxCloseDeploymentExec is used for testing close deployment tx -// requires --dseq, --fees -func TxCloseDeploymentExec(clientCtx client.Context, from fmt.Stringer, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--from=%s", from.String()), - } - - args = append(args, extraArgs...) - - return testutilcli.ExecTestCLICmd(context.Background(), clientCtx, cmdClose(key), args...) -} - -// TxDepositDeploymentExec is used for testing deposit deployment tx -func TxDepositDeploymentExec(clientCtx client.Context, deposit sdk.Coin, from fmt.Stringer, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - deposit.String(), - fmt.Sprintf("--from=%s", from.String()), - } - - args = append(args, extraArgs...) - - return testutilcli.ExecTestCLICmd(context.Background(), clientCtx, cmdDeposit(key), args...) -} - -// TxCloseGroupExec is used for testing close group tx -func TxCloseGroupExec(clientCtx client.Context, groupID types.GroupID, from fmt.Stringer, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--from=%s", from.String()), - fmt.Sprintf("--owner=%s", groupID.Owner), - fmt.Sprintf("--dseq=%v", groupID.DSeq), - fmt.Sprintf("--gseq=%v", groupID.GSeq), - } - - args = append(args, extraArgs...) - - return testutilcli.ExecTestCLICmd(context.Background(), clientCtx, cmdGroupClose(key), args...) -} - -// QueryDeploymentsExec is used for testing deployments query -func QueryDeploymentsExec(clientCtx client.Context, extraArgs ...string) (sdktest.BufferWriter, error) { - return testutilcli.ExecTestCLICmd(context.Background(), clientCtx, cmdDeployments(), extraArgs...) -} - -// QueryDeploymentExec is used for testing deployment query -func QueryDeploymentExec(clientCtx client.Context, id types.DeploymentID, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--owner=%s", id.Owner), - fmt.Sprintf("--dseq=%v", id.DSeq), - } - - args = append(args, extraArgs...) - - return testutilcli.ExecTestCLICmd(context.Background(), clientCtx, cmdDeployment(), args...) -} - -// QueryGroupExec is used for testing group query -func QueryGroupExec(clientCtx client.Context, id types.GroupID, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--owner=%s", id.Owner), - fmt.Sprintf("--dseq=%v", id.DSeq), - fmt.Sprintf("--gseq=%v", id.GSeq), - } - - args = append(args, extraArgs...) - - return testutilcli.ExecTestCLICmd(context.Background(), clientCtx, cmdGetGroup(), args...) -} - -func TxGrantAuthorizationExec(clientCtx client.Context, granter, grantee sdk.AccAddress, extraArgs ...string) (sdktest.BufferWriter, error) { - - dmin, _ := types.DefaultParams().MinDepositFor("uakt") - - spendLimit := sdk.NewCoin(dmin.Denom, dmin.Amount.MulRaw(3)) - args := []string{ - grantee.String(), - spendLimit.String(), - fmt.Sprintf("--from=%s", granter.String()), - } - args = append(args, extraArgs...) - - return clitestutil.ExecTestCLICmd(clientCtx, cmdGrantAuthorization(), args) -} - -func TxRevokeAuthorizationExec(clientCtx client.Context, granter, grantee sdk.AccAddress, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - grantee.String(), - fmt.Sprintf("--from=%s", granter.String()), - } - args = append(args, extraArgs...) - - return clitestutil.ExecTestCLICmd(clientCtx, cmdRevokeAuthorization(), args) -} diff --git a/x/deployment/client/cli/tx.go b/x/deployment/client/cli/tx.go deleted file mode 100644 index 154c665b7e..0000000000 --- a/x/deployment/client/cli/tx.go +++ /dev/null @@ -1,678 +0,0 @@ -package cli - -import ( - "errors" - "fmt" - "os" - "reflect" - "strings" - "time" - - cltypes "github.com/akash-network/akash-api/go/node/client/types" - "github.com/spf13/cobra" - tmrpc "github.com/tendermint/tendermint/rpc/core/types" - - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/authz" - - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - "github.com/akash-network/akash-api/go/node/types/constants" - - aclient "github.com/akash-network/node/client" - "github.com/akash-network/node/cmd/common" - "github.com/akash-network/node/sdl" - cutils "github.com/akash-network/node/x/cert/utils" -) - -var ( - errDeploymentUpdate = errors.New("deployment update failed") - errDeploymentUpdateGroupsChanged = fmt.Errorf("%w: groups are different than existing deployment, you cannot update groups", errDeploymentUpdate) -) - -// GetTxCmd returns the transaction commands for this module -func GetTxCmd(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: "Deployment transaction subcommands", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - cmd.AddCommand( - cmdCreate(key), - cmdUpdate(key), - cmdDeposit(key), - cmdClose(key), - cmdGroup(key), - cmdAuthz(), - ) - return cmd -} - -func cmdCreate(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: "create [sdl-file]", - Short: fmt.Sprintf("Create %s", key), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - // first lets validate certificate exists for given account - if _, err = cutils.LoadAndQueryCertificateForAccount(ctx, cctx, nil); err != nil { - if os.IsNotExist(err) { - err = fmt.Errorf("no certificate file found for account %q.\n"+ - "consider creating it as certificate required to submit manifest", cctx.FromAddress.String()) - } - - return err - } - - sdlManifest, err := sdl.ReadFile(args[0]) - if err != nil { - return err - } - - groups, err := sdlManifest.DeploymentGroups() - if err != nil { - return err - } - - warnIfGroupVolumesExceeds(cctx, groups) - - id, err := DeploymentIDFromFlags(cmd.Flags(), WithOwner(cctx.FromAddress)) - if err != nil { - return err - } - - // Default DSeq to the current block height - if id.DSeq == 0 { - var syncInfo *tmrpc.SyncInfo - if syncInfo, err = cl.Node().SyncInfo(ctx); err != nil { - return err - } - - if syncInfo.CatchingUp { - return fmt.Errorf("cannot generate DSEQ from last block height. node is catching up") - } - - id.DSeq = uint64(syncInfo.LatestBlockHeight) - } - - version, err := sdlManifest.Version() - if err != nil { - return err - } - - deposit, err := common.DetectDeposit(ctx, cmd.Flags(), cl.Query(), "deployment", "MinDeposits") - if err != nil { - return err - } - - depositorAcc, err := DepositorFromFlags(cmd.Flags(), id.Owner) - if err != nil { - return err - } - - msg := &types.MsgCreateDeployment{ - ID: id, - Version: version, - Groups: make([]types.GroupSpec, 0, len(groups)), - Deposit: deposit, - Depositor: depositorAcc, - } - - for _, group := range groups { - msg.Groups = append(msg.Groups, *group) - } - - if err := msg.ValidateBasic(); err != nil { - return err - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - AddDeploymentIDFlags(cmd.Flags()) - AddDepositorFlag(cmd.Flags()) - common.AddDepositFlags(cmd.Flags()) - - return cmd -} - -func cmdDeposit(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: "deposit ", - Short: fmt.Sprintf("Deposit %s", key), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - id, err := DeploymentIDFromFlags(cmd.Flags(), WithOwner(cctx.FromAddress)) - if err != nil { - return err - } - - deposit, err := sdk.ParseCoinNormalized(args[0]) - if err != nil { - return err - } - - depositorAcc, err := DepositorFromFlags(cmd.Flags(), id.Owner) - if err != nil { - return err - } - - msg := &types.MsgDepositDeployment{ - ID: id, - Amount: deposit, - Depositor: depositorAcc, - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - AddDeploymentIDFlags(cmd.Flags()) - AddDepositorFlag(cmd.Flags()) - - return cmd -} - -func cmdClose(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: "close", - Short: fmt.Sprintf("Close %s", key), - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - id, err := DeploymentIDFromFlags(cmd.Flags(), WithOwner(cctx.FromAddress)) - if err != nil { - return err - } - - msg := &types.MsgCloseDeployment{ID: id} - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - AddDeploymentIDFlags(cmd.Flags()) - return cmd -} - -func cmdUpdate(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: "update [sdl-file]", - Short: fmt.Sprintf("update %s", key), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - id, err := DeploymentIDFromFlags(cmd.Flags(), WithOwner(cctx.FromAddress)) - if err != nil { - return err - } - - sdlManifest, err := sdl.ReadFile(args[0]) - if err != nil { - return err - } - - version, err := sdlManifest.Version() - if err != nil { - return err - } - - groups, err := sdlManifest.DeploymentGroups() - if err != nil { - return err - } - - // Query the RPC node to make sure the existing groups are identical - existingDeployment, err := cl.Query().Deployment(cmd.Context(), &types.QueryDeploymentRequest{ - ID: id, - }) - if err != nil { - return err - } - - // do not send the transaction if the groups have changed - existingGroups := existingDeployment.GetGroups() - if len(existingGroups) != len(groups) { - return errDeploymentUpdateGroupsChanged - } - - for i, existingGroup := range existingGroups { - if reflect.DeepEqual(groups[i], existingGroup.GroupSpec) { - return errDeploymentUpdateGroupsChanged - } - } - - warnIfGroupVolumesExceeds(cctx, groups) - - msg := &types.MsgUpdateDeployment{ - ID: id, - Version: version, - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - AddDeploymentIDFlags(cmd.Flags()) - - return cmd -} - -func cmdGroup(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: "group", - Short: "Modify a Deployment's specific Group", - } - - cmd.AddCommand( - cmdGroupClose(key), - cmdGroupPause(key), - cmdGroupStart(key), - ) - - return cmd -} - -func cmdGroupClose(_ string) *cobra.Command { - cmd := &cobra.Command{ - Use: "close", - Short: "close a Deployment's specific Group", - Example: "akash tx deployment group-close --owner=[Account Address] --dseq=[uint64] --gseq=[uint32]", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - id, err := GroupIDFromFlags(cmd.Flags()) - if err != nil { - return err - } - - msg := &types.MsgCloseGroup{ - ID: id, - } - - if err := msg.ValidateBasic(); err != nil { - return err - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - AddGroupIDFlags(cmd.Flags()) - MarkReqGroupIDFlags(cmd) - - return cmd -} - -func cmdGroupPause(_ string) *cobra.Command { - cmd := &cobra.Command{ - Use: "pause", - Short: "pause a Deployment's specific Group", - Example: "akash tx deployment group pause --owner=[Account Address] --dseq=[uint64] --gseq=[uint32]", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - id, err := GroupIDFromFlags(cmd.Flags()) - if err != nil { - return err - } - - msg := &types.MsgPauseGroup{ - ID: id, - } - - if err := msg.ValidateBasic(); err != nil { - return err - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - AddGroupIDFlags(cmd.Flags()) - MarkReqGroupIDFlags(cmd) - - return cmd -} - -func cmdGroupStart(_ string) *cobra.Command { - cmd := &cobra.Command{ - Use: "start", - Short: "start a Deployment's specific Group", - Example: "akash tx deployment group pause --owner=[Account Address] --dseq=[uint64] --gseq=[uint32]", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - id, err := GroupIDFromFlags(cmd.Flags()) - if err != nil { - return err - } - - msg := &types.MsgStartGroup{ - ID: id, - } - - if err := msg.ValidateBasic(); err != nil { - return err - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - AddGroupIDFlags(cmd.Flags()) - MarkReqGroupIDFlags(cmd) - - return cmd -} - -func cmdAuthz() *cobra.Command { - cmd := &cobra.Command{ - Use: "authz", - Short: "Deployment authorization transaction subcommands", - Long: "Authorize and revoke access to pay for deployments on behalf of your address", - } - - cmd.AddCommand( - cmdGrantAuthorization(), - cmdRevokeAuthorization(), - ) - - return cmd -} - -func cmdGrantAuthorization() *cobra.Command { - cmd := &cobra.Command{ - Use: "grant --from ", - Short: "Grant deposit deployment authorization to an address", - Long: strings.TrimSpace( - fmt.Sprintf(`grant authorization to an address to pay for a deployment on your behalf: - -Examples: - $ akash tx %s authz grant akash1skjw.. 50akt --from=akash1skl.. - $ akash tx %s authz grant akash1skjw.. 50akt --from=akash1skl.. --expiration=1661020200 - `, types.ModuleName, types.ModuleName), - ), - Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - grantee, err := sdk.AccAddressFromBech32(args[0]) - if err != nil { - return err - } - - spendLimit, err := sdk.ParseCoinNormalized(args[1]) - if err != nil { - return err - } - if spendLimit.IsZero() || spendLimit.IsNegative() { - return fmt.Errorf("spend-limit should be greater than zero, got: %s", spendLimit) - } - - exp, err := cmd.Flags().GetInt64(FlagExpiration) - if err != nil { - return err - } - - granter := cctx.GetFromAddress() - authorization := types.NewDepositDeploymentAuthorization(spendLimit) - - msg, err := authz.NewMsgGrant(granter, grantee, authorization, time.Unix(exp, 0)) - if err != nil { - return err - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - cmd.Flags().Int64(FlagExpiration, time.Now().AddDate(1, 0, 0).Unix(), "The Unix timestamp. Default is one year.") - _ = cmd.MarkFlagRequired(flags.FlagFrom) - - return cmd -} - -func cmdRevokeAuthorization() *cobra.Command { - cmd := &cobra.Command{ - Use: "revoke [grantee] --from=[granter]", - Short: "Revoke deposit deployment authorization given to an address", - Long: strings.TrimSpace( - fmt.Sprintf(`revoke deposit deployment authorization from a granter to a grantee: -Example: - $ akash tx %s authz revoke akash1skj.. --from=akash1skj.. - `, types.ModuleName), - ), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - grantee, err := sdk.AccAddressFromBech32(args[0]) - if err != nil { - return err - } - - granter := cctx.GetFromAddress() - msgTypeURL := types.DepositDeploymentAuthorization{}.MsgTypeURL() - msg := authz.NewMsgRevoke(granter, grantee, msgTypeURL) - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{&msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - _ = cmd.MarkFlagRequired(flags.FlagFrom) - - return cmd -} - -func warnIfGroupVolumesExceeds(cctx sdkclient.Context, dgroups []*types.GroupSpec) { - for _, group := range dgroups { - for _, resources := range group.GetResourceUnits() { - if len(resources.Resources.Storage) > constants.DefaultMaxGroupVolumes { - _ = cctx.PrintString(fmt.Sprintf("amount of volumes for service exceeds recommended value (%v > %v)\n"+ - "there may no providers on network to bid", len(resources.Resources.Storage), constants.DefaultMaxGroupVolumes)) - } - } - } -} diff --git a/x/deployment/client/cli/util.go b/x/deployment/client/cli/util.go deleted file mode 100644 index ccd40339f8..0000000000 --- a/x/deployment/client/cli/util.go +++ /dev/null @@ -1,20 +0,0 @@ -package cli - -import ( - "context" - - "github.com/cosmos/cosmos-sdk/client" -) - -// CurrentBlockHeight returns current block height of node -func CurrentBlockHeight(ctx client.Context) (uint64, error) { - client, err := ctx.GetNode() - if err != nil { - return 0, err - } - status, err := client.Status(context.Background()) - if err != nil { - return 0, err - } - return uint64(status.SyncInfo.LatestBlockHeight), nil -} diff --git a/x/deployment/client/rest/params.go b/x/deployment/client/rest/params.go deleted file mode 100644 index 353490cd85..0000000000 --- a/x/deployment/client/rest/params.go +++ /dev/null @@ -1,95 +0,0 @@ -package rest - -import ( - "net/http" - "strconv" - - sdk "github.com/cosmos/cosmos-sdk/types" - - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - "github.com/akash-network/node/x/deployment/query" -) - -// DeploymentIDFromRequest returns DeploymentID from parsing request -func DeploymentIDFromRequest(r *http.Request) (types.DeploymentID, string) { - ownerAddr := r.URL.Query().Get("owner") - dseqNo := r.URL.Query().Get("dseq") - var id types.DeploymentID - - if len(ownerAddr) != 0 { - _, err := sdk.AccAddressFromBech32(ownerAddr) - if err != nil { - return types.DeploymentID{}, err.Error() - } - id.Owner = ownerAddr - } else { - return types.DeploymentID{}, "Missing owner query param" - } - - if len(dseqNo) != 0 { - dseq, err := strconv.ParseUint(dseqNo, 10, 64) - if err != nil { - return types.DeploymentID{}, err.Error() - } - id.DSeq = dseq - } else { - return types.DeploymentID{}, "Missing dseq query param" - } - return id, "" -} - -// DepFiltersFromRequest returns DeploymentFilters with given params in request -func DepFiltersFromRequest(r *http.Request) (query.DeploymentFilters, string) { - ownerAddr := r.URL.Query().Get("owner") - state := r.URL.Query().Get("state") - var dfilters query.DeploymentFilters - - if len(ownerAddr) != 0 { - owner, err := sdk.AccAddressFromBech32(ownerAddr) - if err != nil { - return query.DeploymentFilters{}, err.Error() - } - dfilters.Owner = owner - } - - if len(state) != 0 { - dfilters.StateFlagVal = state - } - return dfilters, "" -} - -// GroupIDFromRequest returns GroupID from parsing request -func GroupIDFromRequest(r *http.Request) (types.GroupID, string) { - dID, errMsg := DeploymentIDFromRequest(r) - if len(errMsg) != 0 { - return types.GroupID{}, errMsg - } - gseqNo := r.URL.Query().Get("gseq") - - var gseq uint32 - - if len(gseqNo) != 0 { - num, err := strconv.ParseUint(gseqNo, 10, 32) - if err != nil { - return types.GroupID{}, err.Error() - } - gseq = uint32(num) - } else { - return types.GroupID{}, "Missing oseq query param" - } - return types.MakeGroupID(dID, gseq), "" -} - -// GroupFiltersFromRequest returns GroupFilters with given params in request -func GroupFiltersFromRequest(r *http.Request) (query.GroupFilters, string) { - dfilters, errMsg := DepFiltersFromRequest(r) - if len(errMsg) != 0 { - return query.GroupFilters{}, errMsg - } - - gfilters := query.GroupFilters{ - Owner: dfilters.Owner, - StateFlagVal: dfilters.StateFlagVal, - } - return gfilters, "" -} diff --git a/x/deployment/client/rest/rest.go b/x/deployment/client/rest/rest.go deleted file mode 100644 index c4ee5fdbf9..0000000000 --- a/x/deployment/client/rest/rest.go +++ /dev/null @@ -1,80 +0,0 @@ -package rest - -import ( - "fmt" - "net/http" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/types/rest" - "github.com/gorilla/mux" - - "github.com/akash-network/node/x/deployment/query" -) - -// RegisterRoutes registers all query routes -func RegisterRoutes(ctx client.Context, r *mux.Router, ns string) { - // Get all deployments - r.HandleFunc(fmt.Sprintf("/%s/list", ns), listDeploymentsHandler(ctx, ns)).Methods("GET") - - // Get single deployment info - r.HandleFunc(fmt.Sprintf("/%s/info", ns), getDeploymentHandler(ctx, ns)).Methods("GET") - - // Get single group info - r.HandleFunc(fmt.Sprintf("/%s/group/info", ns), getGroupHandler(ctx, ns)).Methods("GET") -} - -func listDeploymentsHandler(ctx client.Context, ns string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - dfilters, errMsg := DepFiltersFromRequest(r) - - if len(errMsg) != 0 { - rest.WriteErrorResponse(w, http.StatusBadRequest, errMsg) - return - } - - res, err := query.NewRawClient(ctx, ns).Deployments(dfilters) - if err != nil { - rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") - return - } - rest.PostProcessResponse(w, ctx, res) - } -} - -func getDeploymentHandler(ctx client.Context, ns string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - id, errMsg := DeploymentIDFromRequest(r) - - if len(errMsg) != 0 { - rest.WriteErrorResponse(w, http.StatusBadRequest, errMsg) - return - } - - res, err := query.NewRawClient(ctx, ns).Deployment(id) - if err != nil { - rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") - return - } - rest.PostProcessResponse(w, ctx, res) - } -} - -func getGroupHandler(ctx client.Context, ns string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - id, errMsg := GroupIDFromRequest(r) - - if len(errMsg) != 0 { - rest.WriteErrorResponse(w, http.StatusBadRequest, errMsg) - return - } - - res, err := query.NewRawClient(ctx, ns).Group(id) - if err != nil { - rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") - return - } - rest.PostProcessResponse(w, ctx, res) - } -} diff --git a/x/deployment/genesis.go b/x/deployment/genesis.go index ccd0f5a482..e60754a3bb 100644 --- a/x/deployment/genesis.go +++ b/x/deployment/genesis.go @@ -7,18 +7,17 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" + "pkg.akt.dev/go/node/deployment/v1" + "pkg.akt.dev/go/node/deployment/v1beta4" - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - - "github.com/akash-network/node/x/deployment/keeper" + "pkg.akt.dev/node/x/deployment/keeper" ) // ValidateGenesis does validation check of the Genesis and return error in case of failure -func ValidateGenesis(data *types.GenesisState) error { +func ValidateGenesis(data *v1beta4.GenesisState) error { for _, record := range data.Deployments { - if err := record.Deployment.ID().Validate(); err != nil { - return fmt.Errorf("%w: %s", err, types.ErrInvalidDeployment.Error()) + if err := record.Deployment.ID.Validate(); err != nil { + return fmt.Errorf("%w: %s", err, v1.ErrInvalidDeployment.Error()) } } return data.Params.Validate() @@ -26,46 +25,47 @@ func ValidateGenesis(data *types.GenesisState) error { // DefaultGenesisState returns default genesis state as raw bytes for the deployment // module. -func DefaultGenesisState() *types.GenesisState { - return &types.GenesisState{ - Params: types.DefaultParams(), +func DefaultGenesisState() *v1beta4.GenesisState { + return &v1beta4.GenesisState{ + Params: v1beta4.DefaultParams(), } } // InitGenesis initiate genesis state and return updated validator details -func InitGenesis(ctx sdk.Context, kpr keeper.IKeeper, data *types.GenesisState) []abci.ValidatorUpdate { +func InitGenesis(ctx sdk.Context, kpr keeper.IKeeper, data *v1beta4.GenesisState) { cdc := kpr.Codec() store := ctx.KVStore(kpr.StoreKey()) for _, record := range data.Deployments { - key := keeper.MustDeploymentKey(keeper.DeploymentStateToPrefix(record.Deployment.State), record.Deployment.DeploymentID) + key := keeper.MustDeploymentKey(keeper.DeploymentStateToPrefix(record.Deployment.State), record.Deployment.ID) store.Set(key, cdc.MustMarshal(&record.Deployment)) for idx := range record.Groups { group := record.Groups[idx] - if !group.ID().DeploymentID().Equals(record.Deployment.ID()) { - panic(types.ErrInvalidGroupID) + if !group.ID.DeploymentID().Equals(record.Deployment.ID) { + panic(v1.ErrInvalidGroupID) } - gkey := keeper.MustGroupKey(keeper.GroupStateToPrefix(group.State), group.ID()) + gkey := keeper.MustGroupKey(keeper.GroupStateToPrefix(group.State), group.ID) store.Set(gkey, cdc.MustMarshal(&group)) } } - kpr.SetParams(ctx, data.Params) - - return []abci.ValidatorUpdate{} + err := kpr.SetParams(ctx, data.Params) + if err != nil { + panic(err.Error()) + } } // ExportGenesis returns genesis state for the deployment module -func ExportGenesis(ctx sdk.Context, k keeper.IKeeper) *types.GenesisState { - var records []types.GenesisDeployment - k.WithDeployments(ctx, func(deployment types.Deployment) bool { - groups := k.GetGroups(ctx, deployment.ID()) +func ExportGenesis(ctx sdk.Context, k keeper.IKeeper) *v1beta4.GenesisState { + var records []v1beta4.GenesisDeployment + k.WithDeployments(ctx, func(deployment v1.Deployment) bool { + groups := k.GetGroups(ctx, deployment.ID) - records = append(records, types.GenesisDeployment{ + records = append(records, v1beta4.GenesisDeployment{ Deployment: deployment, Groups: groups, }) @@ -73,7 +73,7 @@ func ExportGenesis(ctx sdk.Context, k keeper.IKeeper) *types.GenesisState { }) params := k.GetParams(ctx) - return &types.GenesisState{ + return &v1beta4.GenesisState{ Deployments: records, Params: params, } @@ -81,8 +81,8 @@ func ExportGenesis(ctx sdk.Context, k keeper.IKeeper) *types.GenesisState { // GetGenesisStateFromAppState returns x/deployment GenesisState given raw application // genesis state. -func GetGenesisStateFromAppState(cdc codec.JSONCodec, appState map[string]json.RawMessage) *types.GenesisState { - var genesisState types.GenesisState +func GetGenesisStateFromAppState(cdc codec.JSONCodec, appState map[string]json.RawMessage) *v1beta4.GenesisState { + var genesisState v1beta4.GenesisState if appState[ModuleName] != nil { cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState) diff --git a/x/deployment/handler/handler.go b/x/deployment/handler/handler.go index 4643f252d4..865b819961 100644 --- a/x/deployment/handler/handler.go +++ b/x/deployment/handler/handler.go @@ -1,48 +1,39 @@ package handler import ( + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + types "pkg.akt.dev/go/node/deployment/v1beta4" - "github.com/akash-network/node/x/deployment/keeper" + "pkg.akt.dev/node/x/deployment/keeper" ) // NewHandler returns a handler for "deployment" type messages -func NewHandler(keeper keeper.IKeeper, mkeeper MarketKeeper, ekeeper EscrowKeeper, authzKeeper AuthzKeeper) sdk.Handler { - ms := NewServer(keeper, mkeeper, ekeeper, authzKeeper) +func NewHandler(keeper keeper.IKeeper, mkeeper MarketKeeper, ekeeper EscrowKeeper) baseapp.MsgServiceHandler { + ms := NewServer(keeper, mkeeper, ekeeper) return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { switch msg := msg.(type) { case *types.MsgCreateDeployment: - res, err := ms.CreateDeployment(sdk.WrapSDKContext(ctx), msg) + res, err := ms.CreateDeployment(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) - - case *types.MsgDepositDeployment: - res, err := ms.DepositDeployment(sdk.WrapSDKContext(ctx), msg) - return sdk.WrapServiceResult(ctx, res, err) - case *types.MsgUpdateDeployment: - res, err := ms.UpdateDeployment(sdk.WrapSDKContext(ctx), msg) + res, err := ms.UpdateDeployment(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) - case *types.MsgCloseDeployment: - res, err := ms.CloseDeployment(sdk.WrapSDKContext(ctx), msg) + res, err := ms.CloseDeployment(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) - case *types.MsgCloseGroup: - res, err := ms.CloseGroup(sdk.WrapSDKContext(ctx), msg) + res, err := ms.CloseGroup(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) - case *types.MsgPauseGroup: - res, err := ms.PauseGroup(sdk.WrapSDKContext(ctx), msg) + res, err := ms.PauseGroup(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) - case *types.MsgStartGroup: - res, err := ms.StartGroup(sdk.WrapSDKContext(ctx), msg) + res, err := ms.StartGroup(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) - default: return nil, sdkerrors.ErrUnknownRequest } diff --git a/x/deployment/handler/handler_test.go b/x/deployment/handler/handler_test.go index 62730b26c7..f058b32f31 100644 --- a/x/deployment/handler/handler_test.go +++ b/x/deployment/handler/handler_test.go @@ -1,29 +1,36 @@ package handler_test import ( + "context" "crypto/sha256" "errors" "testing" "time" - "github.com/akash-network/node/sdl" - - "github.com/akash-network/node/x/deployment/handler" - - sdktestdata "github.com/cosmos/cosmos-sdk/testutil/testdata" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + sdkmath "cosmossdk.io/math" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + mtypes "pkg.akt.dev/go/node/market/v1" - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + "github.com/cosmos/cosmos-sdk/baseapp" + sdktestdata "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/akash-network/node/testutil" - cmocks "github.com/akash-network/node/testutil/cosmos/mocks" - "github.com/akash-network/node/testutil/state" - "github.com/akash-network/node/x/deployment/keeper" - mkeeper "github.com/akash-network/node/x/market/keeper" + "pkg.akt.dev/go/node/deployment/v1" + "pkg.akt.dev/go/node/deployment/v1beta4" + ev1 "pkg.akt.dev/go/node/escrow/v1" + deposit "pkg.akt.dev/go/node/types/deposit/v1" + "pkg.akt.dev/go/testutil" + + cmocks "pkg.akt.dev/node/testutil/cosmos/mocks" + "pkg.akt.dev/node/testutil/state" + "pkg.akt.dev/node/x/deployment/handler" + "pkg.akt.dev/node/x/deployment/keeper" + ehandler "pkg.akt.dev/node/x/escrow/handler" + mkeeper "pkg.akt.dev/node/x/market/keeper" ) type testSuite struct { @@ -33,43 +40,68 @@ type testSuite struct { mkeeper mkeeper.IKeeper dkeeper keeper.IKeeper authzKeeper handler.AuthzKeeper - depositor string - handler sdk.Handler + bankKeeper handler.BankKeeper + owner sdk.AccAddress + granter sdk.AccAddress + dhandler baseapp.MsgServiceHandler + ehandler baseapp.MsgServiceHandler defaultDeposit sdk.Coin } func setupTestSuite(t *testing.T) *testSuite { - defaultDeposit, err := types.DefaultParams().MinDepositFor("uakt") + defaultDeposit, err := v1beta4.DefaultParams().MinDepositFor("uakt") require.NoError(t, err) - depositor := testutil.AccAddress(t) + owner := testutil.AccAddress(t) + granter := testutil.AccAddress(t) authzKeeper := &cmocks.AuthzKeeper{} + bankKeeper := &cmocks.BankKeeper{} + msgTypeUrl := (&ev1.DepositAuthorization{}).MsgTypeURL() + authzKeeper. - On("GetCleanAuthorization", mock.Anything, mock.Anything, depositor, sdk.MsgTypeURL(&types.MsgDepositDeployment{})). - Return(&types.DepositDeploymentAuthorization{ - SpendLimit: defaultDeposit.Add(defaultDeposit), - }, time.Time{}). - Once(). - On("GetCleanAuthorization", mock.Anything, mock.Anything, depositor, sdk.MsgTypeURL(&types.MsgDepositDeployment{})). - Return(&types.DepositDeploymentAuthorization{ - SpendLimit: defaultDeposit, - }, time.Time{}). - Once(). - On("GetCleanAuthorization", mock.Anything, mock.Anything, depositor, sdk.MsgTypeURL(&types.MsgDepositDeployment{})). - Return(&types.DepositDeploymentAuthorization{ - SpendLimit: defaultDeposit, - }, time.Time{}). - Once(). - On("GetCleanAuthorization", mock.Anything, mock.Anything, depositor, sdk.MsgTypeURL(&types.MsgDepositDeployment{})). - Return(&types.DepositDeploymentAuthorization{ - SpendLimit: defaultDeposit, - }, time.Time{}). + On("GetGranteeGrantsByMsgType", mock.Anything, owner, msgTypeUrl, mock.Anything). + Run(func(args mock.Arguments) { + onGrant := args.Get(3).(authzkeeper.OnGrantFn) + authorization := &ev1.DepositAuthorization{ + Scopes: ev1.DepositAuthorizationScopes{ev1.DepositScopeDeployment}, + SpendLimit: defaultDeposit.Add(defaultDeposit), + } + + _ = onGrant(context.TODO(), granter, authorization, &time.Time{}) + }).Once(). + On("GetGranteeGrantsByMsgType", mock.Anything, owner, msgTypeUrl, mock.Anything). + Run(func(args mock.Arguments) { + onGrant := args.Get(3).(authzkeeper.OnGrantFn) + authorization := &ev1.DepositAuthorization{ + Scopes: ev1.DepositAuthorizationScopes{ev1.DepositScopeDeployment}, + SpendLimit: defaultDeposit, + } + + _ = onGrant(context.TODO(), granter, authorization, &time.Time{}) + }).Once(). + On("GetGranteeGrantsByMsgType", mock.Anything, owner, msgTypeUrl, mock.Anything). + Run(func(args mock.Arguments) { + onGrant := args.Get(3).(authzkeeper.OnGrantFn) + authorization := &ev1.DepositAuthorization{ + Scopes: ev1.DepositAuthorizationScopes{ev1.DepositScopeDeployment}, + SpendLimit: defaultDeposit, + } + + _ = onGrant(context.TODO(), granter, authorization, &time.Time{}) + }).Once(). + On("GetGranteeGrantsByMsgType", mock.Anything, owner, msgTypeUrl, mock.Anything). + Run(func(args mock.Arguments) { + onGrant := args.Get(3).(authzkeeper.OnGrantFn) + authorization := &ev1.DepositAuthorization{ + Scopes: ev1.DepositAuthorizationScopes{ev1.DepositScopeDeployment}, + SpendLimit: defaultDeposit, + } + + _ = onGrant(context.TODO(), granter, authorization, &time.Time{}) + }). Once(). - On("GetCleanAuthorization", mock.Anything, mock.Anything, - mock.MatchedBy(func(addr sdk.AccAddress) bool { - return !depositor.Equals(addr) - }), sdk.MsgTypeURL(&types.MsgDepositDeployment{})). - Return(nil, time.Time{}) + On("GetAuthorization", mock.Anything, mock.Anything, mock.Anything, msgTypeUrl). + Return(nil, nil) authzKeeper. On("DeleteGrant", mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(nil) @@ -77,8 +109,22 @@ func setupTestSuite(t *testing.T) *testSuite { On("SaveGrant", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(nil) + bankKeeper. + On("SpendableCoin", mock.Anything, mock.Anything, mock.Anything). + Return(sdk.NewInt64Coin("uakt", 10000000)) + bankKeeper. + On("SendCoinsFromAccountToModule", mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(nil) + bankKeeper. + On("SendCoinsFromModuleToAccount", mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(nil) + bankKeeper. + On("SendCoinsFromModuleToModule", mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(nil) + keepers := state.Keepers{ Authz: authzKeeper, + Bank: bankKeeper, } ssuite := state.SetupTestSuiteWithKeepers(t, keepers) @@ -89,12 +135,14 @@ func setupTestSuite(t *testing.T) *testSuite { mkeeper: ssuite.MarketKeeper(), dkeeper: ssuite.DeploymentKeeper(), authzKeeper: ssuite.AuthzKeeper(), - depositor: depositor.String(), + bankKeeper: ssuite.BankKeeper(), + owner: owner, + granter: granter, defaultDeposit: defaultDeposit, } - suite.handler = handler.NewHandler(suite.dkeeper, suite.mkeeper, ssuite.EscrowKeeper(), - suite.authzKeeper) + suite.dhandler = handler.NewHandler(suite.dkeeper, suite.mkeeper, ssuite.EscrowKeeper()) + suite.ehandler = ehandler.NewHandler(suite.EscrowKeeper(), suite.authzKeeper, suite.BankKeeper()) return suite } @@ -102,7 +150,7 @@ func setupTestSuite(t *testing.T) *testSuite { func TestProviderBadMessageType(t *testing.T) { suite := setupTestSuite(t) - res, err := suite.handler(suite.ctx, sdk.Msg(sdktestdata.NewTestMsg())) + res, err := suite.dhandler(suite.ctx, sdk.Msg(sdktestdata.NewTestMsg())) require.Nil(t, res) require.Error(t, err) require.True(t, errors.Is(err, sdkerrors.ErrUnknownRequest)) @@ -113,36 +161,38 @@ func TestCreateDeployment(t *testing.T) { deployment, groups := suite.createDeployment() - msg := &types.MsgCreateDeployment{ - ID: deployment.ID(), - Groups: make([]types.GroupSpec, 0, len(groups)), - Deposit: suite.defaultDeposit, - Depositor: deployment.ID().Owner, + msg := &v1beta4.MsgCreateDeployment{ + ID: deployment.ID, + Groups: make(v1beta4.GroupSpecs, 0, len(groups)), + Deposit: deposit.Deposit{ + Amount: suite.defaultDeposit, + Sources: deposit.Sources{deposit.SourceBalance}, + }, } for _, group := range groups { msg.Groups = append(msg.Groups, group.GroupSpec) } - res, err := suite.handler(suite.ctx, msg) + res, err := suite.dhandler(suite.ctx, msg) require.NoError(t, err) require.NotNil(t, res) t.Run("ensure event created", func(t *testing.T) { - t.Skip("now has more events") - iev := testutil.ParseDeploymentEvent(t, res.Events) - require.IsType(t, types.EventDeploymentCreated{}, iev) + iev, err := sdk.ParseTypedEvent(res.Events[0]) + require.NoError(t, err) + require.IsType(t, &v1.EventDeploymentCreated{}, iev) - dev := iev.(types.EventDeploymentCreated) + dev := iev.(*v1.EventDeploymentCreated) require.Equal(t, msg.ID, dev.ID) }) - deploymentResult, exists := suite.dkeeper.GetDeployment(suite.ctx, deployment.ID()) + deploymentResult, exists := suite.dkeeper.GetDeployment(suite.ctx, deployment.ID) require.True(t, exists) - require.Equal(t, deploymentResult.Version, msg.Version) + require.Equal(t, deploymentResult.Hash, msg.Hash) - groupsResult := suite.dkeeper.GetGroups(suite.ctx, deployment.ID()) + groupsResult := suite.dkeeper.GetGroups(suite.ctx, deployment.ID) require.NotEmpty(t, groupsResult) require.Equal(t, len(groupsResult), len(groups)) @@ -150,8 +200,8 @@ func TestCreateDeployment(t *testing.T) { require.Equal(t, groups[i].GetName(), g.GetName()) } - res, err = suite.handler(suite.ctx, msg) - require.EqualError(t, err, types.ErrDeploymentExists.Error()) + res, err = suite.dhandler(suite.ctx, msg) + require.EqualError(t, err, v1.ErrDeploymentExists.Error()) require.Nil(t, res) } @@ -160,14 +210,17 @@ func TestCreateDeploymentEmptyGroups(t *testing.T) { deployment := testutil.Deployment(suite.t) - msg := &types.MsgCreateDeployment{ - ID: deployment.ID(), - Deposit: suite.defaultDeposit, + msg := &v1beta4.MsgCreateDeployment{ + ID: deployment.ID, + Deposit: deposit.Deposit{ + Amount: suite.defaultDeposit, + Sources: deposit.Sources{deposit.SourceBalance}, + }, } - res, err := suite.handler(suite.ctx, msg) + res, err := suite.dhandler(suite.ctx, msg) require.Nil(t, res) - require.True(t, errors.Is(err, types.ErrInvalidGroups)) + require.True(t, errors.Is(err, v1.ErrInvalidGroups)) } func TestUpdateDeploymentNonExisting(t *testing.T) { @@ -175,13 +228,13 @@ func TestUpdateDeploymentNonExisting(t *testing.T) { deployment := testutil.Deployment(suite.t) - msg := &types.MsgUpdateDeployment{ - ID: deployment.ID(), + msg := &v1beta4.MsgUpdateDeployment{ + ID: deployment.ID, } - res, err := suite.handler(suite.ctx, msg) + res, err := suite.dhandler(suite.ctx, msg) require.Nil(t, res) - require.EqualError(t, err, types.ErrDeploymentNotFound.Error()) + require.EqualError(t, err, v1.ErrDeploymentNotFound.Error()) } func TestUpdateDeploymentExisting(t *testing.T) { @@ -189,71 +242,64 @@ func TestUpdateDeploymentExisting(t *testing.T) { deployment, groups := suite.createDeployment() - sdlObj, err := sdl.ReadFile("../../../sdl/_testdata/simple.yaml") - require.NoError(t, err) - - dgroups, err := sdlObj.DeploymentGroups() - require.NoError(t, err) - - msgGroups := make([]types.GroupSpec, 0) - for _, g := range dgroups { - msgGroups = append(msgGroups, *g) + msgGroupSpecs := make(v1beta4.GroupSpecs, 0) + for _, g := range groups { + msgGroupSpecs = append(msgGroupSpecs, g.GroupSpec) } - require.NotEmpty(t, msgGroups) - require.Equal(t, len(msgGroups), 1) - - msg := &types.MsgCreateDeployment{ - ID: deployment.ID(), - Groups: msgGroups, - Version: testutil.DefaultDeploymentVersion[:], - Deposit: suite.defaultDeposit, - Depositor: deployment.ID().Owner, - } - - for _, group := range groups { - msg.Groups = append(msg.Groups, group.GroupSpec) + require.NotEmpty(t, msgGroupSpecs) + require.Equal(t, len(msgGroupSpecs), 1) + + msg := &v1beta4.MsgCreateDeployment{ + ID: deployment.ID, + Groups: msgGroupSpecs, + Hash: testutil.DefaultDeploymentHash[:], + Deposit: deposit.Deposit{ + Amount: suite.defaultDeposit, + Sources: deposit.Sources{deposit.SourceBalance}, + }, } - res, err := suite.handler(suite.ctx, msg) + res, err := suite.dhandler(suite.ctx, msg) require.NoError(t, err) require.NotNil(t, res) t.Run("assert deployment version", func(t *testing.T) { - d, ok := suite.dkeeper.GetDeployment(suite.ctx, deployment.DeploymentID) + d, ok := suite.dkeeper.GetDeployment(suite.ctx, deployment.ID) require.True(t, ok) - assert.Equal(t, d.Version, testutil.DefaultDeploymentVersion[:]) + assert.Equal(t, d.Hash, testutil.DefaultDeploymentHash[:]) }) // Change the version - depSum := sha256.Sum256(testutil.DefaultDeploymentVersion[:]) + depSum := sha256.Sum256(testutil.DefaultDeploymentHash[:]) - msgUpdate := &types.MsgUpdateDeployment{ - ID: msg.ID, - Version: depSum[:], + msgUpdate := &v1beta4.MsgUpdateDeployment{ + ID: msg.ID, + Hash: depSum[:], } - res, err = suite.handler(suite.ctx, msgUpdate) + res, err = suite.dhandler(suite.ctx, msgUpdate) require.NoError(t, err) require.NotNil(t, res) t.Run("ensure event created", func(t *testing.T) { - t.Skip("now has more events") - iev := testutil.ParseDeploymentEvent(t, res.Events[1:]) - require.IsType(t, types.EventDeploymentUpdated{}, iev) + iev, err := sdk.ParseTypedEvent(res.Events[2]) + require.NoError(t, err) + require.IsType(t, &v1.EventDeploymentUpdated{}, iev) - dev := iev.(types.EventDeploymentUpdated) + dev := iev.(*v1.EventDeploymentUpdated) require.Equal(t, msg.ID, dev.ID) }) + t.Run("assert version updated", func(t *testing.T) { - d, ok := suite.dkeeper.GetDeployment(suite.ctx, deployment.DeploymentID) + d, ok := suite.dkeeper.GetDeployment(suite.ctx, deployment.ID) require.True(t, ok) - assert.Equal(t, d.Version, depSum[:]) + assert.Equal(t, d.Hash, depSum[:]) }) // Run the same update, should fail since nothing is different - res, err = suite.handler(suite.ctx, msgUpdate) + res, err = suite.dhandler(suite.ctx, msgUpdate) require.Error(t, err) - require.Contains(t, err.Error(), "Invalid: deployment version") + require.Contains(t, err.Error(), "Invalid: deployment hash") } @@ -262,13 +308,13 @@ func TestCloseDeploymentNonExisting(t *testing.T) { deployment := testutil.Deployment(suite.t) - msg := &types.MsgCloseDeployment{ - ID: deployment.ID(), + msg := &v1beta4.MsgCloseDeployment{ + ID: deployment.ID, } - res, err := suite.handler(suite.ctx, msg) + res, err := suite.dhandler(suite.ctx, msg) require.Nil(t, res) - require.EqualError(t, err, types.ErrDeploymentNotFound.Error()) + require.EqualError(t, err, v1.ErrDeploymentNotFound.Error()) } func TestCloseDeploymentExisting(t *testing.T) { @@ -276,189 +322,240 @@ func TestCloseDeploymentExisting(t *testing.T) { deployment, groups := suite.createDeployment() - msg := &types.MsgCreateDeployment{ - ID: deployment.ID(), - Groups: make([]types.GroupSpec, 0, len(groups)), - Deposit: suite.defaultDeposit, - Depositor: deployment.ID().Owner, + msg := &v1beta4.MsgCreateDeployment{ + ID: deployment.ID, + Groups: make(v1beta4.GroupSpecs, 0, len(groups)), + Deposit: deposit.Deposit{ + Amount: suite.defaultDeposit, + Sources: deposit.Sources{deposit.SourceBalance}, + }, } for _, group := range groups { msg.Groups = append(msg.Groups, group.GroupSpec) } - res, err := suite.handler(suite.ctx, msg) + res, err := suite.dhandler(suite.ctx, msg) require.NoError(t, err) require.NotNil(t, res) t.Run("ensure event created", func(t *testing.T) { - t.Skip("now has more events") - iev := testutil.ParseDeploymentEvent(t, res.Events) - require.IsType(t, types.EventDeploymentCreated{}, iev) + iev, err := sdk.ParseTypedEvent(res.Events[0]) + require.NoError(t, err) + + require.IsType(t, &v1.EventDeploymentCreated{}, iev) - dev := iev.(types.EventDeploymentCreated) + dev := iev.(*v1.EventDeploymentCreated) require.Equal(t, msg.ID, dev.ID) }) - msgClose := &types.MsgCloseDeployment{ - ID: deployment.ID(), + msgClose := &v1beta4.MsgCloseDeployment{ + ID: deployment.ID, } - res, err = suite.handler(suite.ctx, msgClose) + res, err = suite.dhandler(suite.ctx, msgClose) require.NotNil(t, res) require.NoError(t, err) - t.Run("ensure event updated", func(t *testing.T) { - t.Skip("now has more events") - iev := testutil.ParseDeploymentEvent(t, res.Events[1:2]) - require.IsType(t, types.EventDeploymentUpdated{}, iev) - - dev := iev.(types.EventDeploymentUpdated) - - require.Equal(t, msg.ID, dev.ID) - }) - t.Run("ensure event close", func(t *testing.T) { - t.Skip("now has more events") - iev := testutil.ParseDeploymentEvent(t, res.Events[2:]) - require.IsType(t, types.EventDeploymentClosed{}, iev) + iev, err := sdk.ParseTypedEvent(res.Events[2]) + require.NoError(t, err) - dev := iev.(types.EventDeploymentClosed) + require.IsType(t, &v1.EventDeploymentClosed{}, iev) + + dev := iev.(*v1.EventDeploymentClosed) require.Equal(t, msg.ID, dev.ID) }) - res, err = suite.handler(suite.ctx, msgClose) + res, err = suite.dhandler(suite.ctx, msgClose) require.Nil(t, res) - require.EqualError(t, err, types.ErrDeploymentClosed.Error()) + require.EqualError(t, err, v1.ErrDeploymentClosed.Error()) } func TestFundedDeployment(t *testing.T) { suite := setupTestSuite(t) deployment, groups := suite.createDeployment() + deployment.ID.Owner = suite.owner.String() // create a funded deployment - msg := &types.MsgCreateDeployment{ - ID: deployment.ID(), - Groups: make([]types.GroupSpec, 0, len(groups)), - Deposit: suite.defaultDeposit, - Depositor: suite.depositor, + msg := &v1beta4.MsgCreateDeployment{ + ID: deployment.ID, + Groups: make(v1beta4.GroupSpecs, 0, len(groups)), + Deposit: deposit.Deposit{ + Amount: suite.defaultDeposit, + Sources: deposit.Sources{deposit.SourceGrant}, + }, } for _, group := range groups { msg.Groups = append(msg.Groups, group.GroupSpec) } - res, err := suite.handler(suite.ctx, msg) + res, err := suite.dhandler(suite.ctx, msg) require.NoError(t, err) require.NotNil(t, res) // ensure that it got created - _, exists := suite.dkeeper.GetDeployment(suite.ctx, deployment.ID()) + _, exists := suite.dkeeper.GetDeployment(suite.ctx, deployment.ID) require.True(t, exists) - // ensure that the escrow account has correct state - accID := types.EscrowAccountForDeployment(deployment.ID()) + fundsAmount := sdkmath.LegacyZeroDec() + fundsAmount.AddMut(sdkmath.LegacyNewDecFromInt(msg.Deposit.Amount.Amount)) + + // ensure that the escrow account has the correct state + accID := deployment.ID.ToEscrowAccountID() acc, err := suite.EscrowKeeper().GetAccount(suite.ctx, accID) require.NoError(t, err) - require.Equal(t, deployment.ID().Owner, acc.Owner) - require.Equal(t, suite.depositor, acc.Depositor) - require.Equal(t, sdk.NewDecCoin(msg.Deposit.Denom, sdk.ZeroInt()), acc.Balance) - require.Equal(t, sdk.NewDecCoinFromCoin(msg.Deposit), acc.Funds) + require.Equal(t, deployment.ID.Owner, acc.State.Owner) + require.Len(t, acc.State.Deposits, 1) + require.Len(t, acc.State.Funds, 1) + require.Equal(t, msg.Deposit.Amount.Denom, acc.State.Funds[0].Denom) + require.Equal(t, suite.granter.String(), acc.State.Deposits[0].Owner) + require.Equal(t, deposit.SourceGrant, acc.State.Deposits[0].Source) + require.Equal(t, fundsAmount, acc.State.Funds[0].Amount) // deposit additional amount from the owner - depositMsg := &types.MsgDepositDeployment{ - ID: deployment.ID(), - Amount: suite.defaultDeposit, - Depositor: deployment.ID().Owner, + depositMsg := &ev1.MsgAccountDeposit{ + Signer: deployment.ID.Owner, + ID: deployment.ID.ToEscrowAccountID(), + Deposit: deposit.Deposit{ + Amount: suite.defaultDeposit, + Sources: deposit.Sources{deposit.SourceBalance}, + }, } - res, err = suite.handler(suite.ctx, depositMsg) + res, err = suite.ehandler(suite.ctx, depositMsg) require.NoError(t, err) require.NotNil(t, res) + fundsAmount.AddMut(sdkmath.LegacyNewDecFromInt(depositMsg.Deposit.Amount.Amount)) + // ensure that the escrow account's state gets updated correctly acc, err = suite.EscrowKeeper().GetAccount(suite.ctx, accID) require.NoError(t, err) - require.Equal(t, deployment.ID().Owner, acc.Owner) - require.Equal(t, suite.depositor, acc.Depositor) - require.Equal(t, sdk.NewDecCoinFromCoin(depositMsg.Amount), acc.Balance) - require.Equal(t, sdk.NewDecCoinFromCoin(msg.Deposit), acc.Funds) - - // deposit additional amount from the depositor - depositMsg1 := &types.MsgDepositDeployment{ - ID: deployment.ID(), - Amount: suite.defaultDeposit, - Depositor: suite.depositor, + require.Equal(t, deployment.ID.Owner, acc.State.Owner) + require.Len(t, acc.State.Deposits, 2) + require.Len(t, acc.State.Funds, 1) + require.Equal(t, suite.owner.String(), acc.State.Deposits[1].Owner) + require.Equal(t, sdk.NewDecCoinFromCoin(depositMsg.Deposit.Amount).Amount, acc.State.Deposits[1].Balance.Amount) + require.Equal(t, fundsAmount, acc.State.Funds[0].Amount) + + // deposit additional amount from the grant + depositMsg1 := &ev1.MsgAccountDeposit{ + Signer: deployment.ID.Owner, + ID: deployment.ID.ToEscrowAccountID(), + Deposit: deposit.Deposit{ + Amount: suite.defaultDeposit, + Sources: deposit.Sources{deposit.SourceGrant}, + }, } - res, err = suite.handler(suite.ctx, depositMsg1) + res, err = suite.ehandler(suite.ctx, depositMsg1) require.NoError(t, err) require.NotNil(t, res) + fundsAmount.AddMut(sdkmath.LegacyNewDecFromInt(depositMsg1.Deposit.Amount.Amount)) + // ensure that the escrow account's state gets updated correctly acc, err = suite.EscrowKeeper().GetAccount(suite.ctx, accID) require.NoError(t, err) - require.Equal(t, deployment.ID().Owner, acc.Owner) - require.Equal(t, suite.depositor, acc.Depositor) - require.Equal(t, sdk.NewDecCoinFromCoin(depositMsg.Amount), acc.Balance) - require.Equal(t, sdk.NewDecCoinFromCoin(msg.Deposit.Add(depositMsg1.Amount)), acc.Funds) - - // depositing additional amount from a random depositor should fail - depositMsg2 := &types.MsgDepositDeployment{ - ID: deployment.ID(), - Amount: suite.defaultDeposit, - Depositor: testutil.AccAddress(t).String(), + require.Equal(t, deployment.ID.Owner, acc.State.Owner) + require.Len(t, acc.State.Deposits, 3) + require.Len(t, acc.State.Funds, 1) + require.Equal(t, suite.granter.String(), acc.State.Deposits[2].Owner) + require.Equal(t, sdk.NewDecCoinFromCoin(depositMsg1.Deposit.Amount).Amount, acc.State.Deposits[2].Balance.Amount) + require.Equal(t, fundsAmount, acc.State.Funds[0].Amount) + + // depositing additional amount from a random depositor should pass + depositMsg2 := &ev1.MsgAccountDeposit{ + Signer: testutil.AccAddress(t).String(), + ID: deployment.ID.ToEscrowAccountID(), + Deposit: deposit.Deposit{ + Amount: suite.defaultDeposit, + Sources: deposit.Sources{deposit.SourceBalance}, + }, } - res, err = suite.handler(suite.ctx, depositMsg2) - require.Error(t, err) - require.Nil(t, res) + res, err = suite.ehandler(suite.ctx, depositMsg2) + require.NoError(t, err) + require.NotNil(t, res) + + fundsAmount.AddMut(sdkmath.LegacyNewDecFromInt(depositMsg2.Deposit.Amount.Amount)) + + // ensure that the escrow account's state gets updated correctly + acc, err = suite.EscrowKeeper().GetAccount(suite.ctx, accID) + require.NoError(t, err) + require.Equal(t, deployment.ID.Owner, acc.State.Owner) + require.Len(t, acc.State.Deposits, 4) + require.Len(t, acc.State.Funds, 1) + require.Equal(t, depositMsg2.Signer, acc.State.Deposits[3].Owner) + require.Equal(t, sdk.NewDecCoinFromCoin(depositMsg2.Deposit.Amount).Amount, acc.State.Deposits[3].Balance.Amount) + require.Equal(t, fundsAmount, acc.State.Funds[0].Amount) // make some payment from the escrow account - pid := "test_pid" providerAddr := testutil.AccAddress(t) - rate := sdk.NewDecCoin(msg.Deposit.Denom, suite.defaultDeposit.Amount) - require.NoError(t, suite.EscrowKeeper().PaymentCreate(suite.ctx, accID, pid, providerAddr, rate)) - ctx := suite.ctx.WithBlockHeight(acc.SettledAt + 1) - require.NoError(t, suite.EscrowKeeper().PaymentWithdraw(ctx, accID, pid)) + + lid := mtypes.LeaseID{ + Owner: deployment.ID.Owner, + DSeq: deployment.ID.DSeq, + GSeq: 0, + OSeq: 0, + Provider: providerAddr.String(), + } + + pid := lid.ToEscrowPaymentID() + + rate := sdk.NewDecCoin(msg.Deposit.Amount.Denom, suite.defaultDeposit.Amount) + err = suite.EscrowKeeper().PaymentCreate(suite.ctx, pid, providerAddr, rate) + require.NoError(t, err) + + ctx := suite.ctx.WithBlockHeight(acc.State.SettledAt + 1) + + err = suite.EscrowKeeper().PaymentWithdraw(ctx, pid) + require.NoError(t, err) + + fundsAmount.SubMut(sdkmath.LegacyNewDecFromInt(suite.defaultDeposit.Amount)) // ensure that the escrow account's state gets updated correctly acc, err = suite.EscrowKeeper().GetAccount(ctx, accID) require.NoError(t, err) - require.Equal(t, sdk.NewDecCoin(msg.Deposit.Denom, suite.defaultDeposit.Amount), acc.Balance) - require.Equal(t, sdk.NewDecCoin(msg.Deposit.Denom, suite.defaultDeposit.Amount), acc.Funds) + require.Equal(t, deployment.ID.Owner, acc.State.Owner) + require.Len(t, acc.State.Deposits, 3) + require.Len(t, acc.State.Funds, 1) + require.Equal(t, fundsAmount, acc.State.Funds[0].Amount) + require.Equal(t, sdkmath.LegacyNewDecFromInt(suite.defaultDeposit.Amount), acc.State.Transferred[0].Amount) // close the deployment - closeMsg := &types.MsgCloseDeployment{ID: deployment.ID()} - res, err = suite.handler(ctx, closeMsg) + closeMsg := &v1beta4.MsgCloseDeployment{ID: deployment.ID} + res, err = suite.dhandler(ctx, closeMsg) require.NoError(t, err) require.NotNil(t, res) // ensure that the escrow account has no balance left acc, err = suite.EscrowKeeper().GetAccount(ctx, accID) require.NoError(t, err) - require.Equal(t, sdk.NewDecCoin(msg.Deposit.Denom, sdk.ZeroInt()), acc.Balance) - require.Equal(t, sdk.NewDecCoin(msg.Deposit.Denom, sdk.ZeroInt()), acc.Funds) + require.Equal(t, sdkmath.LegacyZeroDec(), acc.State.Funds[0].Amount) + require.Len(t, acc.State.Deposits, 0) } -func (st *testSuite) createDeployment() (types.Deployment, []types.Group) { +func (st *testSuite) createDeployment() (v1.Deployment, v1beta4.Groups) { st.t.Helper() deployment := testutil.Deployment(st.t) - group := testutil.DeploymentGroup(st.t, deployment.ID(), 0) - group.GroupSpec.Resources = types.ResourceUnits{ + group := testutil.DeploymentGroup(st.t, deployment.ID, 0) + group.GroupSpec.Resources = v1beta4.ResourceUnits{ { Resources: testutil.ResourceUnits(st.t), Count: 1, Price: testutil.AkashDecCoinRandom(st.t), }, } - groups := []types.Group{ + groups := v1beta4.Groups{ group, } for i := range groups { - groups[i].State = types.GroupOpen + groups[i].State = v1beta4.GroupOpen } return deployment, groups diff --git a/x/deployment/handler/keepers.go b/x/deployment/handler/keepers.go index fa0e76470c..bf8a55adc7 100644 --- a/x/deployment/handler/keepers.go +++ b/x/deployment/handler/keepers.go @@ -1,33 +1,40 @@ package handler import ( + "context" "time" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/authz" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - etypes "github.com/akash-network/akash-api/go/node/escrow/v1beta3" - - mtypes "github.com/akash-network/akash-api/go/node/market/v1beta4" + types "pkg.akt.dev/go/node/deployment/v1" + "pkg.akt.dev/go/node/deployment/v1beta4" + escrowid "pkg.akt.dev/go/node/escrow/id/v1" + etypes "pkg.akt.dev/go/node/escrow/types/v1" + mtypes "pkg.akt.dev/go/node/market/v1beta5" ) // MarketKeeper Interface includes market methods type MarketKeeper interface { - CreateOrder(ctx sdk.Context, id types.GroupID, spec types.GroupSpec) (mtypes.Order, error) - OnGroupClosed(ctx sdk.Context, id types.GroupID) + CreateOrder(ctx sdk.Context, id types.GroupID, spec v1beta4.GroupSpec) (mtypes.Order, error) + OnGroupClosed(ctx sdk.Context, id types.GroupID) error } type EscrowKeeper interface { - AccountCreate(ctx sdk.Context, id etypes.AccountID, owner, depositor sdk.AccAddress, deposit sdk.Coin) error - AccountDeposit(ctx sdk.Context, id etypes.AccountID, depositor sdk.AccAddress, amount sdk.Coin) error - AccountClose(ctx sdk.Context, id etypes.AccountID) error - GetAccount(ctx sdk.Context, id etypes.AccountID) (etypes.Account, error) + AccountCreate(ctx sdk.Context, id escrowid.Account, owner sdk.AccAddress, deposits []etypes.Depositor) error + AccountDeposit(ctx sdk.Context, id escrowid.Account, deposits []etypes.Depositor) error + AccountClose(ctx sdk.Context, id escrowid.Account) error + AuthorizeDeposits(sctx sdk.Context, msg sdk.Msg) ([]etypes.Depositor, error) } -//go:generate mockery --name AuthzKeeper --output ./mocks type AuthzKeeper interface { - DeleteGrant(ctx sdk.Context, grantee, granter sdk.AccAddress, msgType string) error - GetCleanAuthorization(ctx sdk.Context, grantee, granter sdk.AccAddress, msgType string) (cap authz.Authorization, expiration time.Time) - SaveGrant(ctx sdk.Context, grantee, granter sdk.AccAddress, authorization authz.Authorization, expiration time.Time) error + DeleteGrant(ctx context.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) error + GetAuthorization(ctx context.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) (authz.Authorization, *time.Time) + SaveGrant(ctx context.Context, grantee sdk.AccAddress, granter sdk.AccAddress, authorization authz.Authorization, expiration *time.Time) error + GetGranteeGrantsByMsgType(ctx context.Context, grantee sdk.AccAddress, msgType string, onGrant authzkeeper.OnGrantFn) +} + +type BankKeeper interface { + SpendableCoin(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin } diff --git a/x/deployment/handler/mocks/authz_keeper.go b/x/deployment/handler/mocks/authz_keeper.go deleted file mode 100644 index 2109d51ead..0000000000 --- a/x/deployment/handler/mocks/authz_keeper.go +++ /dev/null @@ -1,200 +0,0 @@ -// Code generated by mockery v2.42.0. DO NOT EDIT. - -package mocks - -import ( - authz "github.com/cosmos/cosmos-sdk/x/authz" - - mock "github.com/stretchr/testify/mock" - - time "time" - - types "github.com/cosmos/cosmos-sdk/types" -) - -// AuthzKeeper is an autogenerated mock type for the AuthzKeeper type -type AuthzKeeper struct { - mock.Mock -} - -type AuthzKeeper_Expecter struct { - mock *mock.Mock -} - -func (_m *AuthzKeeper) EXPECT() *AuthzKeeper_Expecter { - return &AuthzKeeper_Expecter{mock: &_m.Mock} -} - -// DeleteGrant provides a mock function with given fields: ctx, grantee, granter, msgType -func (_m *AuthzKeeper) DeleteGrant(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, msgType string) error { - ret := _m.Called(ctx, grantee, granter, msgType) - - if len(ret) == 0 { - panic("no return value specified for DeleteGrant") - } - - var r0 error - if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, types.AccAddress, string) error); ok { - r0 = rf(ctx, grantee, granter, msgType) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// AuthzKeeper_DeleteGrant_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteGrant' -type AuthzKeeper_DeleteGrant_Call struct { - *mock.Call -} - -// DeleteGrant is a helper method to define mock.On call -// - ctx types.Context -// - grantee types.AccAddress -// - granter types.AccAddress -// - msgType string -func (_e *AuthzKeeper_Expecter) DeleteGrant(ctx interface{}, grantee interface{}, granter interface{}, msgType interface{}) *AuthzKeeper_DeleteGrant_Call { - return &AuthzKeeper_DeleteGrant_Call{Call: _e.mock.On("DeleteGrant", ctx, grantee, granter, msgType)} -} - -func (_c *AuthzKeeper_DeleteGrant_Call) Run(run func(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, msgType string)) *AuthzKeeper_DeleteGrant_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Context), args[1].(types.AccAddress), args[2].(types.AccAddress), args[3].(string)) - }) - return _c -} - -func (_c *AuthzKeeper_DeleteGrant_Call) Return(_a0 error) *AuthzKeeper_DeleteGrant_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *AuthzKeeper_DeleteGrant_Call) RunAndReturn(run func(types.Context, types.AccAddress, types.AccAddress, string) error) *AuthzKeeper_DeleteGrant_Call { - _c.Call.Return(run) - return _c -} - -// GetCleanAuthorization provides a mock function with given fields: ctx, grantee, granter, msgType -func (_m *AuthzKeeper) GetCleanAuthorization(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, msgType string) (authz.Authorization, time.Time) { - ret := _m.Called(ctx, grantee, granter, msgType) - - if len(ret) == 0 { - panic("no return value specified for GetCleanAuthorization") - } - - var r0 authz.Authorization - var r1 time.Time - if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, types.AccAddress, string) (authz.Authorization, time.Time)); ok { - return rf(ctx, grantee, granter, msgType) - } - if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, types.AccAddress, string) authz.Authorization); ok { - r0 = rf(ctx, grantee, granter, msgType) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(authz.Authorization) - } - } - - if rf, ok := ret.Get(1).(func(types.Context, types.AccAddress, types.AccAddress, string) time.Time); ok { - r1 = rf(ctx, grantee, granter, msgType) - } else { - r1 = ret.Get(1).(time.Time) - } - - return r0, r1 -} - -// AuthzKeeper_GetCleanAuthorization_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCleanAuthorization' -type AuthzKeeper_GetCleanAuthorization_Call struct { - *mock.Call -} - -// GetCleanAuthorization is a helper method to define mock.On call -// - ctx types.Context -// - grantee types.AccAddress -// - granter types.AccAddress -// - msgType string -func (_e *AuthzKeeper_Expecter) GetCleanAuthorization(ctx interface{}, grantee interface{}, granter interface{}, msgType interface{}) *AuthzKeeper_GetCleanAuthorization_Call { - return &AuthzKeeper_GetCleanAuthorization_Call{Call: _e.mock.On("GetCleanAuthorization", ctx, grantee, granter, msgType)} -} - -func (_c *AuthzKeeper_GetCleanAuthorization_Call) Run(run func(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, msgType string)) *AuthzKeeper_GetCleanAuthorization_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Context), args[1].(types.AccAddress), args[2].(types.AccAddress), args[3].(string)) - }) - return _c -} - -func (_c *AuthzKeeper_GetCleanAuthorization_Call) Return(cap authz.Authorization, expiration time.Time) *AuthzKeeper_GetCleanAuthorization_Call { - _c.Call.Return(cap, expiration) - return _c -} - -func (_c *AuthzKeeper_GetCleanAuthorization_Call) RunAndReturn(run func(types.Context, types.AccAddress, types.AccAddress, string) (authz.Authorization, time.Time)) *AuthzKeeper_GetCleanAuthorization_Call { - _c.Call.Return(run) - return _c -} - -// SaveGrant provides a mock function with given fields: ctx, grantee, granter, authorization, expiration -func (_m *AuthzKeeper) SaveGrant(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, authorization authz.Authorization, expiration time.Time) error { - ret := _m.Called(ctx, grantee, granter, authorization, expiration) - - if len(ret) == 0 { - panic("no return value specified for SaveGrant") - } - - var r0 error - if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, types.AccAddress, authz.Authorization, time.Time) error); ok { - r0 = rf(ctx, grantee, granter, authorization, expiration) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// AuthzKeeper_SaveGrant_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveGrant' -type AuthzKeeper_SaveGrant_Call struct { - *mock.Call -} - -// SaveGrant is a helper method to define mock.On call -// - ctx types.Context -// - grantee types.AccAddress -// - granter types.AccAddress -// - authorization authz.Authorization -// - expiration time.Time -func (_e *AuthzKeeper_Expecter) SaveGrant(ctx interface{}, grantee interface{}, granter interface{}, authorization interface{}, expiration interface{}) *AuthzKeeper_SaveGrant_Call { - return &AuthzKeeper_SaveGrant_Call{Call: _e.mock.On("SaveGrant", ctx, grantee, granter, authorization, expiration)} -} - -func (_c *AuthzKeeper_SaveGrant_Call) Run(run func(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, authorization authz.Authorization, expiration time.Time)) *AuthzKeeper_SaveGrant_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(types.Context), args[1].(types.AccAddress), args[2].(types.AccAddress), args[3].(authz.Authorization), args[4].(time.Time)) - }) - return _c -} - -func (_c *AuthzKeeper_SaveGrant_Call) Return(_a0 error) *AuthzKeeper_SaveGrant_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *AuthzKeeper_SaveGrant_Call) RunAndReturn(run func(types.Context, types.AccAddress, types.AccAddress, authz.Authorization, time.Time) error) *AuthzKeeper_SaveGrant_Call { - _c.Call.Return(run) - return _c -} - -// NewAuthzKeeper creates a new instance of AuthzKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewAuthzKeeper(t interface { - mock.TestingT - Cleanup(func()) -}) *AuthzKeeper { - mock := &AuthzKeeper{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/x/deployment/handler/server.go b/x/deployment/handler/server.go index 3399abb094..54f6b2a6e4 100644 --- a/x/deployment/handler/server.go +++ b/x/deployment/handler/server.go @@ -6,62 +6,59 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + v1 "pkg.akt.dev/go/node/deployment/v1" + types "pkg.akt.dev/go/node/deployment/v1beta4" - "github.com/akash-network/node/x/deployment/keeper" + "pkg.akt.dev/node/x/deployment/keeper" ) var _ types.MsgServer = msgServer{} type msgServer struct { - deployment keeper.IKeeper - market MarketKeeper - escrow EscrowKeeper - authzKeeper AuthzKeeper + deployment keeper.IKeeper + market MarketKeeper + escrow EscrowKeeper } // NewServer returns an implementation of the deployment MsgServer interface // for the provided Keeper. -func NewServer(k keeper.IKeeper, mkeeper MarketKeeper, ekeeper EscrowKeeper, authzKeeper AuthzKeeper) types.MsgServer { - return &msgServer{deployment: k, market: mkeeper, escrow: ekeeper, authzKeeper: authzKeeper} +func NewServer(k keeper.IKeeper, mkeeper MarketKeeper, ekeeper EscrowKeeper) types.MsgServer { + return &msgServer{ + deployment: k, + market: mkeeper, + escrow: ekeeper, + } } func (ms msgServer) CreateDeployment(goCtx context.Context, msg *types.MsgCreateDeployment) (*types.MsgCreateDeploymentResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - if _, found := ms.deployment.GetDeployment(ctx, msg.ID); found { - return nil, types.ErrDeploymentExists + did := msg.ID + + if _, found := ms.deployment.GetDeployment(ctx, did); found { + return nil, v1.ErrDeploymentExists } params := ms.deployment.GetParams(ctx) - if err := params.ValidateDeposit(msg.Deposit); err != nil { + if err := params.ValidateDeposit(msg.Deposit.Amount); err != nil { return nil, err } - deployment := types.Deployment{ - DeploymentID: msg.ID, - State: types.DeploymentActive, - Version: msg.Version, - CreatedAt: ctx.BlockHeight(), + deployment := v1.Deployment{ + ID: did, + State: v1.DeploymentActive, + Hash: msg.Hash, + CreatedAt: ctx.BlockHeight(), } if err := types.ValidateDeploymentGroups(msg.Groups); err != nil { - return nil, fmt.Errorf("%w: %s", types.ErrInvalidGroups, err.Error()) - } - - owner, err := sdk.AccAddressFromBech32(msg.ID.Owner) - if err != nil { - return &types.MsgCreateDeploymentResponse{}, err + return nil, fmt.Errorf("%w: %s", v1.ErrInvalidGroups, err.Error()) } - depositor, err := sdk.AccAddressFromBech32(msg.Depositor) + deposits, err := ms.escrow.AuthorizeDeposits(ctx, msg) if err != nil { - return &types.MsgCreateDeploymentResponse{}, err - } - - if err = ms.authorizeDeposit(ctx, owner, depositor, msg.Deposit); err != nil { return nil, err } @@ -69,7 +66,7 @@ func (ms msgServer) CreateDeployment(goCtx context.Context, msg *types.MsgCreate for idx, spec := range msg.Groups { groups = append(groups, types.Group{ - GroupID: types.MakeGroupID(deployment.ID(), uint32(idx+1)), + ID: v1.MakeGroupID(deployment.ID, uint32(idx+1)), // nolint gosec State: types.GroupOpen, GroupSpec: spec, CreatedAt: ctx.BlockHeight(), @@ -77,133 +74,46 @@ func (ms msgServer) CreateDeployment(goCtx context.Context, msg *types.MsgCreate } if err := ms.deployment.Create(ctx, deployment, groups); err != nil { - return nil, fmt.Errorf("%w: %s", types.ErrInternal, err.Error()) + return nil, fmt.Errorf("%w: %s", v1.ErrInternal, err.Error()) } // create orders for _, group := range groups { - if _, err := ms.market.CreateOrder(ctx, group.ID(), group.GroupSpec); err != nil { + if _, err := ms.market.CreateOrder(ctx, group.ID, group.GroupSpec); err != nil { return &types.MsgCreateDeploymentResponse{}, err } } - if err := ms.escrow.AccountCreate(ctx, - types.EscrowAccountForDeployment(deployment.ID()), - owner, - depositor, - msg.Deposit, - ); err != nil { + owner, _ := sdk.AccAddressFromBech32(did.Owner) + if err := ms.escrow.AccountCreate(ctx, deployment.ID.ToEscrowAccountID(), owner, deposits); err != nil { return &types.MsgCreateDeploymentResponse{}, err } return &types.MsgCreateDeploymentResponse{}, nil } -func (ms msgServer) authorizeDeposit(ctx sdk.Context, owner, depositor sdk.AccAddress, deposit sdk.Coin) error { - // if owner is the depositor, then no need to check authorization - if owner.Equals(depositor) { - return nil - } - - // find the DepositDeploymentAuthorization given to the owner by the depositor and check - // acceptance - msg := &types.MsgDepositDeployment{Amount: deposit} - authorization, expiration := ms.authzKeeper.GetCleanAuthorization(ctx, owner, depositor, sdk.MsgTypeURL(msg)) - if authorization == nil { - return sdkerrors.ErrUnauthorized.Wrap("authorization not found") - } - - resp, err := authorization.Accept(ctx, msg) - if err != nil { - return err - } - - if resp.Delete { - err = ms.authzKeeper.DeleteGrant(ctx, owner, depositor, sdk.MsgTypeURL(msg)) - } else if resp.Updated != nil { - err = ms.authzKeeper.SaveGrant(ctx, owner, depositor, resp.Updated, expiration) - } - if err != nil { - return err - } - - if !resp.Accept { - return sdkerrors.ErrUnauthorized - } - - return nil -} - -func (ms msgServer) DepositDeployment(goCtx context.Context, msg *types.MsgDepositDeployment) (*types.MsgDepositDeploymentResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - - deployment, found := ms.deployment.GetDeployment(ctx, msg.ID) - if !found { - return &types.MsgDepositDeploymentResponse{}, types.ErrDeploymentNotFound - } - - if deployment.State != types.DeploymentActive { - return &types.MsgDepositDeploymentResponse{}, types.ErrDeploymentClosed - } - - owner, err := sdk.AccAddressFromBech32(deployment.ID().Owner) - if err != nil { - return &types.MsgDepositDeploymentResponse{}, err - } - - depositor, err := sdk.AccAddressFromBech32(msg.Depositor) - if err != nil { - return &types.MsgDepositDeploymentResponse{}, err - } - - eID := types.EscrowAccountForDeployment(msg.ID) - - eAccount, err := ms.escrow.GetAccount(ctx, eID) - if err != nil { - return &types.MsgDepositDeploymentResponse{}, err - } - - // error if depositor is not an owner and there is already exists authorization from another account - if (msg.Depositor != msg.ID.Owner) && eAccount.HasDepositor() && (eAccount.Depositor != msg.Depositor) { - return &types.MsgDepositDeploymentResponse{}, types.ErrInvalidDeploymentDepositor - } - - if err = ms.authorizeDeposit(ctx, owner, depositor, msg.Amount); err != nil { - return nil, err - } - - if err := ms.escrow.AccountDeposit(ctx, - eID, - depositor, - msg.Amount); err != nil { - return &types.MsgDepositDeploymentResponse{}, err - } - - return &types.MsgDepositDeploymentResponse{}, nil -} - func (ms msgServer) UpdateDeployment(goCtx context.Context, msg *types.MsgUpdateDeployment) (*types.MsgUpdateDeploymentResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) deployment, found := ms.deployment.GetDeployment(ctx, msg.ID) if !found { - return nil, types.ErrDeploymentNotFound + return nil, v1.ErrDeploymentNotFound } // If the deployment is not active, do not allow it to be updated - if deployment.State != types.DeploymentActive { - return &types.MsgUpdateDeploymentResponse{}, types.ErrDeploymentClosed + if deployment.State != v1.DeploymentActive { + return &types.MsgUpdateDeploymentResponse{}, v1.ErrDeploymentClosed } // If the version is not identical do not allow the update, there is nothing to change in this transaction - if bytes.Equal(msg.Version, deployment.Version) { - return &types.MsgUpdateDeploymentResponse{}, types.ErrInvalidVersion + if bytes.Equal(msg.Hash, deployment.Hash) { + return &types.MsgUpdateDeploymentResponse{}, v1.ErrInvalidHash } - deployment.Version = msg.Version + deployment.Hash = msg.Hash if err := ms.deployment.UpdateDeployment(ctx, deployment); err != nil { - return &types.MsgUpdateDeploymentResponse{}, fmt.Errorf("%w: %s", types.ErrInternal, err.Error()) + return &types.MsgUpdateDeploymentResponse{}, fmt.Errorf("%w: %s", v1.ErrInternal, err.Error()) } return &types.MsgUpdateDeploymentResponse{}, nil @@ -214,21 +124,18 @@ func (ms msgServer) CloseDeployment(goCtx context.Context, msg *types.MsgCloseDe deployment, found := ms.deployment.GetDeployment(ctx, msg.ID) if !found { - return &types.MsgCloseDeploymentResponse{}, types.ErrDeploymentNotFound + return &types.MsgCloseDeploymentResponse{}, v1.ErrDeploymentNotFound } - if deployment.State != types.DeploymentActive { - return &types.MsgCloseDeploymentResponse{}, types.ErrDeploymentClosed + if deployment.State != v1.DeploymentActive { + return &types.MsgCloseDeploymentResponse{}, v1.ErrDeploymentClosed } - if err := ms.escrow.AccountClose(ctx, - types.EscrowAccountForDeployment(deployment.ID()), - ); err != nil { + if err := ms.escrow.AccountClose(ctx, deployment.ID.ToEscrowAccountID()); err != nil { return &types.MsgCloseDeploymentResponse{}, err } // Update state via escrow hooks. - return &types.MsgCloseDeploymentResponse{}, nil } @@ -237,7 +144,7 @@ func (ms msgServer) CloseGroup(goCtx context.Context, msg *types.MsgCloseGroup) group, found := ms.deployment.GetGroup(ctx, msg.ID) if !found { - return nil, types.ErrGroupNotFound + return nil, v1.ErrGroupNotFound } // if Group already closed; return the validation error @@ -251,7 +158,7 @@ func (ms msgServer) CloseGroup(goCtx context.Context, msg *types.MsgCloseGroup) if err != nil { return nil, err } - ms.market.OnGroupClosed(ctx, group.ID()) + _ = ms.market.OnGroupClosed(ctx, group.ID) return &types.MsgCloseGroupResponse{}, nil } @@ -261,7 +168,7 @@ func (ms msgServer) PauseGroup(goCtx context.Context, msg *types.MsgPauseGroup) group, found := ms.deployment.GetGroup(ctx, msg.ID) if !found { - return nil, types.ErrGroupNotFound + return nil, v1.ErrGroupNotFound } // if Group already closed; return the validation error @@ -275,7 +182,7 @@ func (ms msgServer) PauseGroup(goCtx context.Context, msg *types.MsgPauseGroup) if err != nil { return nil, err } - ms.market.OnGroupClosed(ctx, group.ID()) + _ = ms.market.OnGroupClosed(ctx, group.ID) return &types.MsgPauseGroupResponse{}, nil } @@ -285,7 +192,7 @@ func (ms msgServer) StartGroup(goCtx context.Context, msg *types.MsgStartGroup) group, found := ms.deployment.GetGroup(ctx, msg.ID) if !found { - return &types.MsgStartGroupResponse{}, types.ErrGroupNotFound + return &types.MsgStartGroupResponse{}, v1.ErrGroupNotFound } err := group.ValidateStartable() @@ -297,9 +204,22 @@ func (ms msgServer) StartGroup(goCtx context.Context, msg *types.MsgStartGroup) if err != nil { return &types.MsgStartGroupResponse{}, err } - if _, err := ms.market.CreateOrder(ctx, group.ID(), group.GroupSpec); err != nil { + if _, err := ms.market.CreateOrder(ctx, group.ID, group.GroupSpec); err != nil { return &types.MsgStartGroupResponse{}, err } return &types.MsgStartGroupResponse{}, nil } + +func (ms msgServer) UpdateParams(goCtx context.Context, req *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + if ms.deployment.GetAuthority() != req.Authority { + return nil, govtypes.ErrInvalidSigner.Wrapf("invalid authority; expected %s, got %s", ms.deployment.GetAuthority(), req.Authority) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + if err := ms.deployment.SetParams(ctx, req.Params); err != nil { + return nil, err + } + + return &types.MsgUpdateParamsResponse{}, nil +} diff --git a/x/deployment/keeper/external.go b/x/deployment/keeper/external.go index 66a4f84fac..c3b91c6dcc 100644 --- a/x/deployment/keeper/external.go +++ b/x/deployment/keeper/external.go @@ -2,10 +2,11 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" + eid "pkg.akt.dev/go/node/escrow/id/v1" - etypes "github.com/akash-network/akash-api/go/node/escrow/v1beta3" + etypes "pkg.akt.dev/go/node/escrow/types/v1" ) type EscrowKeeper interface { - GetAccount(ctx sdk.Context, id etypes.AccountID) (etypes.Account, error) + GetAccount(ctx sdk.Context, id eid.Account) (etypes.Account, error) } diff --git a/x/deployment/keeper/grpc_query.go b/x/deployment/keeper/grpc_query.go index 4864abb079..14d75f97bc 100644 --- a/x/deployment/keeper/grpc_query.go +++ b/x/deployment/keeper/grpc_query.go @@ -7,13 +7,14 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/cosmos/cosmos-sdk/store/prefix" + "cosmossdk.io/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" sdkquery "github.com/cosmos/cosmos-sdk/types/query" - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + "pkg.akt.dev/go/node/deployment/v1" + types "pkg.akt.dev/go/node/deployment/v1beta4" - "github.com/akash-network/node/util/query" + "pkg.akt.dev/node/util/query" ) // Querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over keeper @@ -27,11 +28,6 @@ var _ types.QueryServer = Querier{} func (k Querier) Deployments(c context.Context, req *types.QueryDeploymentsRequest) (*types.QueryDeploymentsResponse, error) { ctx := sdk.UnwrapSDKContext(c) - defer func() { - if r := recover(); r != nil { - ctx.Logger().Error(fmt.Sprintf("%v", r)) - } - }() if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") } @@ -62,17 +58,17 @@ func (k Querier) Deployments(c context.Context, req *types.QueryDeploymentsReque req.Pagination.Key = key } else if req.Filters.State != "" { - stateVal := types.Deployment_State(types.Deployment_State_value[req.Filters.State]) + stateVal := v1.Deployment_State(v1.Deployment_State_value[req.Filters.State]) - if req.Filters.State != "" && stateVal == types.DeploymentStateInvalid { + if req.Filters.State != "" && stateVal == v1.DeploymentStateInvalid { return nil, status.Error(codes.InvalidArgument, "invalid state value") } states = append(states, byte(stateVal)) } else { - // request does not have pagination set. Start from active store - states = append(states, byte(types.DeploymentActive)) - states = append(states, byte(types.DeploymentClosed)) + // request does not have a pagination set. Start from active store + states = append(states, byte(v1.DeploymentActive)) + states = append(states, byte(v1.DeploymentClosed)) } var deployments types.DeploymentResponses @@ -81,10 +77,9 @@ func (k Querier) Deployments(c context.Context, req *types.QueryDeploymentsReque total := uint64(0) for idx := range states { - state := types.Deployment_State(states[idx]) + state := v1.Deployment_State(states[idx]) var err error - if idx > 0 { req.Pagination.Key = nil } @@ -102,8 +97,8 @@ func (k Querier) Deployments(c context.Context, req *types.QueryDeploymentsReque count := uint64(0) - pageRes, err = sdkquery.FilteredPaginate(searchStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) { - var deployment types.Deployment + pageRes, err = sdkquery.FilteredPaginate(searchStore, req.Pagination, func(_ []byte, value []byte, accumulate bool) (bool, error) { + var deployment v1.Deployment err := k.cdc.Unmarshal(value, &deployment) if err != nil { @@ -113,17 +108,14 @@ func (k Querier) Deployments(c context.Context, req *types.QueryDeploymentsReque // filter deployments with provided filters if req.Filters.Accept(deployment, state) { if accumulate { - account, err := k.ekeeper.GetAccount( - ctx, - types.EscrowAccountForDeployment(deployment.ID()), - ) + account, err := k.ekeeper.GetAccount(ctx, deployment.ID.ToEscrowAccountID()) if err != nil { - return true, fmt.Errorf("%w: fetching escrow account for DeploymentID=%s", err, deployment.DeploymentID) + return true, fmt.Errorf("%w: fetching escrow account for DeploymentID=%s", err, deployment.ID) } value := types.QueryDeploymentResponse{ Deployment: deployment, - Groups: k.GetGroups(ctx, deployment.ID()), + Groups: k.GetGroups(ctx, deployment.ID), EscrowAccount: account, } @@ -181,13 +173,10 @@ func (k Querier) Deployment(c context.Context, req *types.QueryDeploymentRequest deployment, found := k.GetDeployment(ctx, req.ID) if !found { - return nil, types.ErrDeploymentNotFound + return nil, v1.ErrDeploymentNotFound } - account, err := k.ekeeper.GetAccount( - ctx, - types.EscrowAccountForDeployment(req.ID), - ) + account, err := k.ekeeper.GetAccount(ctx, req.ID.ToEscrowAccountID()) if err != nil { return &types.QueryDeploymentResponse{}, err } @@ -215,8 +204,19 @@ func (k Querier) Group(c context.Context, req *types.QueryGroupRequest) (*types. group, found := k.GetGroup(ctx, req.ID) if !found { - return nil, types.ErrGroupNotFound + return nil, v1.ErrGroupNotFound } return &types.QueryGroupResponse{Group: group}, nil } + +func (k Querier) Params(ctx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { + if req == nil { + return nil, status.Errorf(codes.InvalidArgument, "empty request") + } + + sdkCtx := sdk.UnwrapSDKContext(ctx) + params := k.GetParams(sdkCtx) + + return &types.QueryParamsResponse{Params: params}, nil +} diff --git a/x/deployment/keeper/grpc_query_test.go b/x/deployment/keeper/grpc_query_test.go index 54fe311698..f48a4baf7d 100644 --- a/x/deployment/keeper/grpc_query_test.go +++ b/x/deployment/keeper/grpc_query_test.go @@ -6,49 +6,53 @@ import ( "strings" "testing" - "github.com/stretchr/testify/assert" - - "github.com/stretchr/testify/require" - "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" sdkquery "github.com/cosmos/cosmos-sdk/types/query" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + deposit "pkg.akt.dev/go/node/types/deposit/v1" - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - etypes "github.com/akash-network/akash-api/go/node/escrow/v1beta3" + "pkg.akt.dev/go/node/deployment/v1" + "pkg.akt.dev/go/node/deployment/v1beta4" + eid "pkg.akt.dev/go/node/escrow/id/v1" + "pkg.akt.dev/go/testutil" - "github.com/akash-network/node/app" - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/testutil/state" - "github.com/akash-network/node/x/deployment/keeper" - ekeeper "github.com/akash-network/node/x/escrow/keeper" + "pkg.akt.dev/node/app" + "pkg.akt.dev/node/testutil/state" + "pkg.akt.dev/node/x/deployment/keeper" + ekeeper "pkg.akt.dev/node/x/escrow/keeper" ) type grpcTestSuite struct { - t *testing.T - app *app.AkashApp - ctx sdk.Context - keeper keeper.IKeeper - ekeeper ekeeper.Keeper - - queryClient types.QueryClient + t *testing.T + app *app.AkashApp + ctx sdk.Context + keeper keeper.IKeeper + ekeeper ekeeper.Keeper + authzKeeper ekeeper.AuthzKeeper + bankKeeper ekeeper.BankKeeper + + queryClient v1beta4.QueryClient } func setupTest(t *testing.T) *grpcTestSuite { ssuite := state.SetupTestSuite(t) suite := &grpcTestSuite{ - t: t, - app: ssuite.App(), - ctx: ssuite.Context(), - keeper: ssuite.DeploymentKeeper(), - ekeeper: ssuite.EscrowKeeper(), + t: t, + app: ssuite.App(), + ctx: ssuite.Context(), + keeper: ssuite.DeploymentKeeper(), + ekeeper: ssuite.EscrowKeeper(), + authzKeeper: ssuite.AuthzKeeper(), + bankKeeper: ssuite.BankKeeper(), } querier := suite.keeper.NewQuerier() queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.app.InterfaceRegistry()) - types.RegisterQueryServer(queryHelper, querier) - suite.queryClient = types.NewQueryClient(queryHelper) + v1beta4.RegisterQueryServer(queryHelper, querier) + suite.queryClient = v1beta4.NewQueryClient(queryHelper) return suite } @@ -61,11 +65,11 @@ func TestGRPCQueryDeployment(t *testing.T) { err := suite.keeper.Create(suite.ctx, deployment, groups) require.NoError(t, err) - eid := suite.createEscrowAccount(deployment.ID()) + eid := suite.createEscrowAccount(deployment.ID) var ( - req *types.QueryDeploymentRequest - expDeployment types.QueryDeploymentResponse + req *v1beta4.QueryDeploymentRequest + expDeployment v1beta4.QueryDeploymentResponse ) testCases := []struct { @@ -76,21 +80,21 @@ func TestGRPCQueryDeployment(t *testing.T) { { "empty request", func() { - req = &types.QueryDeploymentRequest{} + req = &v1beta4.QueryDeploymentRequest{} }, false, }, { "invalid request", func() { - req = &types.QueryDeploymentRequest{ID: types.DeploymentID{}} + req = &v1beta4.QueryDeploymentRequest{ID: v1.DeploymentID{}} }, false, }, { "deployment not found", func() { - req = &types.QueryDeploymentRequest{ID: types.DeploymentID{ + req = &v1beta4.QueryDeploymentRequest{ID: v1.DeploymentID{ Owner: testutil.AccAddress(t).String(), DSeq: 32, }} @@ -100,8 +104,8 @@ func TestGRPCQueryDeployment(t *testing.T) { { "success", func() { - req = &types.QueryDeploymentRequest{ID: deployment.DeploymentID} - expDeployment = types.QueryDeploymentResponse{ + req = &v1beta4.QueryDeploymentRequest{ID: deployment.ID} + expDeployment = v1beta4.QueryDeploymentResponse{ Deployment: deployment, Groups: groups, } @@ -113,7 +117,7 @@ func TestGRPCQueryDeployment(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { tc.malleate() - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx res, err := suite.queryClient.Deployment(ctx, req) @@ -139,21 +143,21 @@ func TestGRPCQueryDeployments(t *testing.T) { deployment, groups := suite.createDeployment() err := suite.keeper.Create(suite.ctx, deployment, groups) require.NoError(t, err) - suite.createEscrowAccount(deployment.ID()) + suite.createEscrowAccount(deployment.ID) deployment2, groups2 := suite.createDeployment() - deployment2.State = types.DeploymentActive + deployment2.State = v1.DeploymentActive err = suite.keeper.Create(suite.ctx, deployment2, groups2) require.NoError(t, err) - suite.createEscrowAccount(deployment2.ID()) + suite.createEscrowAccount(deployment2.ID) deployment3, groups3 := suite.createDeployment() - deployment3.State = types.DeploymentClosed + deployment3.State = v1.DeploymentClosed err = suite.keeper.Create(suite.ctx, deployment3, groups3) require.NoError(t, err) - suite.createEscrowAccount(deployment3.ID()) + suite.createEscrowAccount(deployment3.ID) - var req *types.QueryDeploymentsRequest + var req *v1beta4.QueryDeploymentsRequest testCases := []struct { msg string @@ -164,7 +168,7 @@ func TestGRPCQueryDeployments(t *testing.T) { { "query deployments without any filters and pagination", func() { - req = &types.QueryDeploymentsRequest{} + req = &v1beta4.QueryDeploymentsRequest{} }, 3, false, @@ -172,9 +176,9 @@ func TestGRPCQueryDeployments(t *testing.T) { { "query deployments with state filter", func() { - req = &types.QueryDeploymentsRequest{ - Filters: types.DeploymentFilters{ - State: types.DeploymentActive.String(), + req = &v1beta4.QueryDeploymentsRequest{ + Filters: v1beta4.DeploymentFilters{ + State: v1.DeploymentActive.String(), }, } }, @@ -184,10 +188,10 @@ func TestGRPCQueryDeployments(t *testing.T) { { "query deployments with filters having non existent data", func() { - req = &types.QueryDeploymentsRequest{ - Filters: types.DeploymentFilters{ + req = &v1beta4.QueryDeploymentsRequest{ + Filters: v1beta4.DeploymentFilters{ DSeq: 37, - State: types.DeploymentClosed.String(), + State: v1.DeploymentClosed.String(), }} }, 0, @@ -196,8 +200,7 @@ func TestGRPCQueryDeployments(t *testing.T) { { "query deployments with state filter", func() { - req = &types.QueryDeploymentsRequest{ - Filters: types.DeploymentFilters{State: types.DeploymentClosed.String()}} + req = &v1beta4.QueryDeploymentsRequest{Filters: v1beta4.DeploymentFilters{State: v1.DeploymentClosed.String()}} }, 1, false, @@ -205,7 +208,7 @@ func TestGRPCQueryDeployments(t *testing.T) { { "query deployments with pagination", func() { - req = &types.QueryDeploymentsRequest{Pagination: &sdkquery.PageRequest{Limit: 1}} + req = &v1beta4.QueryDeploymentsRequest{Pagination: &sdkquery.PageRequest{Limit: 1}} }, 1, false, @@ -213,8 +216,8 @@ func TestGRPCQueryDeployments(t *testing.T) { { "query deployments with pagination next key", func() { - req = &types.QueryDeploymentsRequest{ - Filters: types.DeploymentFilters{State: types.DeploymentActive.String()}, + req = &v1beta4.QueryDeploymentsRequest{ + Filters: v1beta4.DeploymentFilters{State: v1.DeploymentActive.String()}, Pagination: &sdkquery.PageRequest{Limit: 1}, } }, @@ -226,7 +229,7 @@ func TestGRPCQueryDeployments(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { tc.malleate() - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx res, err := suite.queryClient.Deployments(ctx, req) @@ -249,8 +252,8 @@ func TestGRPCQueryDeployments(t *testing.T) { type deploymentFilterModifier struct { fieldName string - f func(leaseID types.DeploymentID, filter types.DeploymentFilters) types.DeploymentFilters - getField func(leaseID types.DeploymentID) interface{} + f func(leaseID v1.DeploymentID, filter v1beta4.DeploymentFilters) v1beta4.DeploymentFilters + getField func(leaseID v1.DeploymentID) interface{} } func TestGRPCQueryDeploymentsWithFilter(t *testing.T) { @@ -265,7 +268,7 @@ func TestGRPCQueryDeploymentsWithFilter(t *testing.T) { suite.createEscrowAccount(depB) suite.createEscrowAccount(depC) - deps := []types.DeploymentID{ + deps := []v1.DeploymentID{ depA, depB, depC, @@ -274,32 +277,32 @@ func TestGRPCQueryDeploymentsWithFilter(t *testing.T) { modifiers := []deploymentFilterModifier{ { "owner", - func(depID types.DeploymentID, filter types.DeploymentFilters) types.DeploymentFilters { + func(depID v1.DeploymentID, filter v1beta4.DeploymentFilters) v1beta4.DeploymentFilters { filter.Owner = depID.GetOwner() return filter }, - func(depID types.DeploymentID) interface{} { + func(depID v1.DeploymentID) interface{} { return depID.Owner }, }, { "dseq", - func(depID types.DeploymentID, filter types.DeploymentFilters) types.DeploymentFilters { + func(depID v1.DeploymentID, filter v1beta4.DeploymentFilters) v1beta4.DeploymentFilters { filter.DSeq = depID.DSeq return filter }, - func(depID types.DeploymentID) interface{} { + func(depID v1.DeploymentID) interface{} { return depID.DSeq }, }, } - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx for _, depID := range deps { for _, m := range modifiers { - req := &types.QueryDeploymentsRequest{ - Filters: m.f(depID, types.DeploymentFilters{}), + req := &v1beta4.QueryDeploymentsRequest{ + Filters: m.f(depID, v1beta4.DeploymentFilters{}), } res, err := suite.queryClient.Deployments(ctx, req) @@ -310,7 +313,7 @@ func TestGRPCQueryDeploymentsWithFilter(t *testing.T) { assert.GreaterOrEqual(t, len(res.Deployments), 1, "testing %v", m.fieldName) for _, dep := range res.Deployments { - assert.Equal(t, m.getField(depID), m.getField(dep.Deployment.DeploymentID), "testing %v", m.fieldName) + assert.Equal(t, m.getField(depID), m.getField(dep.Deployment.ID), "testing %v", m.fieldName) } } } @@ -318,7 +321,7 @@ func TestGRPCQueryDeploymentsWithFilter(t *testing.T) { limit := int(math.Pow(2, float64(len(modifiers)))) // Use an order ID that matches absolutely nothing in any field - bogusOrderID := types.DeploymentID{ + bogusOrderID := v1.DeploymentID{ Owner: testutil.AccAddress(t).String(), DSeq: 9999999, } @@ -332,7 +335,7 @@ func TestGRPCQueryDeploymentsWithFilter(t *testing.T) { } for _, orderID := range deps { - filter := types.DeploymentFilters{} + filter := v1beta4.DeploymentFilters{} msg := strings.Builder{} msg.WriteString("testing filtering on: ") for k, useModifier := range modifiersToUse { @@ -345,7 +348,7 @@ func TestGRPCQueryDeploymentsWithFilter(t *testing.T) { msg.WriteString(", ") } - req := &types.QueryDeploymentsRequest{ + req := &v1beta4.QueryDeploymentsRequest{ Filters: filter, } @@ -362,12 +365,12 @@ func TestGRPCQueryDeploymentsWithFilter(t *testing.T) { continue } m := modifiers[k] - require.Equal(t, m.getField(orderID), m.getField(dep.Deployment.DeploymentID), "testing %v", m.fieldName) + require.Equal(t, m.getField(orderID), m.getField(dep.Deployment.ID), "testing %v", m.fieldName) } } } - filter := types.DeploymentFilters{} + filter := v1beta4.DeploymentFilters{} msg := strings.Builder{} msg.WriteString("testing filtering on (using non matching ID): ") for k, useModifier := range modifiersToUse { @@ -380,7 +383,7 @@ func TestGRPCQueryDeploymentsWithFilter(t *testing.T) { msg.WriteString(", ") } - req := &types.QueryDeploymentsRequest{ + req := &v1beta4.QueryDeploymentsRequest{ Filters: filter, } @@ -397,8 +400,8 @@ func TestGRPCQueryDeploymentsWithFilter(t *testing.T) { for _, depID := range deps { // Query by owner - req := &types.QueryDeploymentsRequest{ - Filters: types.DeploymentFilters{ + req := &v1beta4.QueryDeploymentsRequest{ + Filters: v1beta4.DeploymentFilters{ Owner: depID.Owner, }, } @@ -410,11 +413,11 @@ func TestGRPCQueryDeploymentsWithFilter(t *testing.T) { // Just 1 result require.Len(t, res.Deployments, 1) depResult := res.Deployments[0] - require.Equal(t, depID, depResult.GetDeployment().DeploymentID) + require.Equal(t, depID, depResult.GetDeployment().ID) // Query with valid DSeq - req = &types.QueryDeploymentsRequest{ - Filters: types.DeploymentFilters{ + req = &v1beta4.QueryDeploymentsRequest{ + Filters: v1beta4.DeploymentFilters{ Owner: depID.Owner, DSeq: depID.DSeq, }, @@ -427,11 +430,11 @@ func TestGRPCQueryDeploymentsWithFilter(t *testing.T) { require.NotNil(t, res) require.Len(t, res.Deployments, 1) depResult = res.Deployments[0] - require.Equal(t, depID, depResult.Deployment.DeploymentID) + require.Equal(t, depID, depResult.Deployment.ID) // Query with a bogus DSeq - req = &types.QueryDeploymentsRequest{ - Filters: types.DeploymentFilters{ + req = &v1beta4.QueryDeploymentsRequest{ + Filters: v1beta4.DeploymentFilters{ Owner: depID.Owner, DSeq: depID.DSeq + 1, }, @@ -455,8 +458,8 @@ func TestGRPCQueryGroup(t *testing.T) { require.NoError(t, err) var ( - req *types.QueryGroupRequest - expDeployment types.Group + req *v1beta4.QueryGroupRequest + expDeployment v1beta4.Group ) testCases := []struct { @@ -467,21 +470,21 @@ func TestGRPCQueryGroup(t *testing.T) { { "empty request", func() { - req = &types.QueryGroupRequest{} + req = &v1beta4.QueryGroupRequest{} }, false, }, { "invalid request", func() { - req = &types.QueryGroupRequest{ID: types.GroupID{}} + req = &v1beta4.QueryGroupRequest{ID: v1.GroupID{}} }, false, }, { "group not found", func() { - req = &types.QueryGroupRequest{ID: types.GroupID{ + req = &v1beta4.QueryGroupRequest{ID: v1.GroupID{ Owner: testutil.AccAddress(t).String(), DSeq: 32, GSeq: 45, @@ -492,7 +495,7 @@ func TestGRPCQueryGroup(t *testing.T) { { "success", func() { - req = &types.QueryGroupRequest{ID: groups[0].GroupID} + req = &v1beta4.QueryGroupRequest{ID: groups[0].GetID()} expDeployment = groups[0] }, true, @@ -502,7 +505,7 @@ func TestGRPCQueryGroup(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { tc.malleate() - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx res, err := suite.queryClient.Group(ctx, req) @@ -519,43 +522,48 @@ func TestGRPCQueryGroup(t *testing.T) { } } -func (suite *grpcTestSuite) createDeployment() (types.Deployment, []types.Group) { +func (suite *grpcTestSuite) createDeployment() (v1.Deployment, v1beta4.Groups) { suite.t.Helper() deployment := testutil.Deployment(suite.t) - group := testutil.DeploymentGroup(suite.t, deployment.ID(), 0) - group.GroupSpec.Resources = types.ResourceUnits{ + group := testutil.DeploymentGroup(suite.t, deployment.ID, 0) + group.GroupSpec.Resources = v1beta4.ResourceUnits{ { Resources: testutil.ResourceUnits(suite.t), Count: 1, Price: testutil.DecCoin(suite.t), }, } - groups := []types.Group{ + groups := []v1beta4.Group{ group, } for i := range groups { - groups[i].State = types.GroupOpen + groups[i].State = v1beta4.GroupOpen } return deployment, groups } -func (suite *grpcTestSuite) createEscrowAccount(id types.DeploymentID) etypes.AccountID { +func (suite *grpcTestSuite) createEscrowAccount(id v1.DeploymentID) eid.Account { owner, err := sdk.AccAddressFromBech32(id.Owner) require.NoError(suite.t, err) - eid := types.EscrowAccountForDeployment(id) - defaultDeposit, err := types.DefaultParams().MinDepositFor("uakt") + eid := id.ToEscrowAccountID() + defaultDeposit, err := v1beta4.DefaultParams().MinDepositFor("uakt") require.NoError(suite.t, err) - err = suite.ekeeper.AccountCreate(suite.ctx, - eid, - owner, - owner, - defaultDeposit, - ) + msg := &v1beta4.MsgCreateDeployment{ + ID: id, + Deposit: deposit.Deposit{ + Amount: defaultDeposit, + Sources: deposit.Sources{deposit.SourceBalance}, + }} + + deposits, err := suite.ekeeper.AuthorizeDeposits(suite.ctx, msg) + require.NoError(suite.t, err) + + err = suite.ekeeper.AccountCreate(suite.ctx, eid, owner, deposits) require.NoError(suite.t, err) return eid } diff --git a/x/deployment/keeper/keeper.go b/x/deployment/keeper/keeper.go index 3c712cf9b1..e7ff3b835d 100644 --- a/x/deployment/keeper/keeper.go +++ b/x/deployment/keeper/keeper.go @@ -1,55 +1,55 @@ package keeper import ( + "fmt" + + storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/errors" - - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + "pkg.akt.dev/go/node/deployment/v1" + types "pkg.akt.dev/go/node/deployment/v1beta4" ) type IKeeper interface { - StoreKey() sdk.StoreKey + StoreKey() storetypes.StoreKey Codec() codec.BinaryCodec - GetDeployment(ctx sdk.Context, id types.DeploymentID) (types.Deployment, bool) - GetGroup(ctx sdk.Context, id types.GroupID) (types.Group, bool) - GetGroups(ctx sdk.Context, id types.DeploymentID) []types.Group - Create(ctx sdk.Context, deployment types.Deployment, groups []types.Group) error - UpdateDeployment(ctx sdk.Context, deployment types.Deployment) error - CloseDeployment(ctx sdk.Context, deployment types.Deployment) + GetDeployment(ctx sdk.Context, id v1.DeploymentID) (v1.Deployment, bool) + GetGroup(ctx sdk.Context, id v1.GroupID) (types.Group, bool) + GetGroups(ctx sdk.Context, id v1.DeploymentID) types.Groups + Create(ctx sdk.Context, deployment v1.Deployment, groups []types.Group) error + UpdateDeployment(ctx sdk.Context, deployment v1.Deployment) error + CloseDeployment(ctx sdk.Context, deployment v1.Deployment) error OnCloseGroup(ctx sdk.Context, group types.Group, state types.Group_State) error OnPauseGroup(ctx sdk.Context, group types.Group) error OnStartGroup(ctx sdk.Context, group types.Group) error - WithDeployments(ctx sdk.Context, fn func(types.Deployment) bool) - OnBidClosed(ctx sdk.Context, id types.GroupID) error - OnLeaseClosed(ctx sdk.Context, id types.GroupID) (types.Group, error) + WithDeployments(ctx sdk.Context, fn func(v1.Deployment) bool) + OnBidClosed(ctx sdk.Context, id v1.GroupID) error + OnLeaseClosed(ctx sdk.Context, id v1.GroupID) (types.Group, error) GetParams(ctx sdk.Context) (params types.Params) - SetParams(ctx sdk.Context, params types.Params) + SetParams(ctx sdk.Context, params types.Params) error + GetAuthority() string NewQuerier() Querier } // Keeper of the deployment store type Keeper struct { - skey sdk.StoreKey + skey storetypes.StoreKey cdc codec.BinaryCodec - pspace paramtypes.Subspace ekeeper EscrowKeeper + + // The address capable of executing a MsgUpdateParams message. + // This should be the x/gov module account. + authority string } // NewKeeper creates and returns an instance for deployment keeper -func NewKeeper(cdc codec.BinaryCodec, skey sdk.StoreKey, pspace paramtypes.Subspace, ekeeper EscrowKeeper) IKeeper { - if !pspace.HasKeyTable() { - pspace = pspace.WithKeyTable(types.ParamKeyTable()) - } - +func NewKeeper(cdc codec.BinaryCodec, skey storetypes.StoreKey, ekeeper EscrowKeeper, authority string) IKeeper { return Keeper{ - skey: skey, - cdc: cdc, - pspace: pspace, - ekeeper: ekeeper, + skey: skey, + cdc: cdc, + ekeeper: ekeeper, + authority: authority, } } @@ -62,23 +62,54 @@ func (k Keeper) Codec() codec.BinaryCodec { return k.cdc } -func (k Keeper) StoreKey() sdk.StoreKey { +func (k Keeper) StoreKey() storetypes.StoreKey { return k.skey } +// GetAuthority returns the x/mint module's authority. +func (k Keeper) GetAuthority() string { + return k.authority +} + +// SetParams sets the x/deployment module parameters. +func (k Keeper) SetParams(ctx sdk.Context, p types.Params) error { + if err := p.Validate(); err != nil { + return err + } + + store := ctx.KVStore(k.skey) + bz := k.cdc.MustMarshal(&p) + store.Set(v1.ParamsPrefix(), bz) + + return nil +} + +// GetParams returns the current x/deployment module parameters. +func (k Keeper) GetParams(ctx sdk.Context) (p types.Params) { + store := ctx.KVStore(k.skey) + bz := store.Get(v1.ParamsPrefix()) + if bz == nil { + return p + } + + k.cdc.MustUnmarshal(bz, &p) + + return p +} + // GetDeployment returns deployment details with provided DeploymentID -func (k Keeper) GetDeployment(ctx sdk.Context, id types.DeploymentID) (types.Deployment, bool) { +func (k Keeper) GetDeployment(ctx sdk.Context, id v1.DeploymentID) (v1.Deployment, bool) { store := ctx.KVStore(k.skey) key := k.findDeployment(ctx, id) if len(key) == 0 { - return types.Deployment{}, false + return v1.Deployment{}, false } buf := store.Get(key) - var val types.Deployment + var val v1.Deployment k.cdc.MustUnmarshal(buf, &val) @@ -86,11 +117,10 @@ func (k Keeper) GetDeployment(ctx sdk.Context, id types.DeploymentID) (types.Dep } // GetGroup returns group details with given GroupID from deployment store -func (k Keeper) GetGroup(ctx sdk.Context, id types.GroupID) (types.Group, bool) { +func (k Keeper) GetGroup(ctx sdk.Context, id v1.GroupID) (types.Group, bool) { store := ctx.KVStore(k.skey) key := k.findGroup(ctx, id) - if len(key) == 0 { return types.Group{}, false } @@ -105,8 +135,9 @@ func (k Keeper) GetGroup(ctx sdk.Context, id types.GroupID) (types.Group, bool) } // GetGroups returns all groups of a deployment with given DeploymentID from deployment store -func (k Keeper) GetGroups(ctx sdk.Context, id types.DeploymentID) []types.Group { +func (k Keeper) GetGroups(ctx sdk.Context, id v1.DeploymentID) types.Groups { store := ctx.KVStore(k.skey) + keys := [][]byte{ MustGroupsKey(GroupStateOpenPrefix, id), MustGroupsKey(GroupStatePausedPrefix, id), @@ -114,9 +145,9 @@ func (k Keeper) GetGroups(ctx sdk.Context, id types.DeploymentID) []types.Group MustGroupsKey(GroupStateClosedPrefix, id), } - var vals []types.Group + var vals types.Groups - iters := make([]sdk.Iterator, 0, len(keys)) + iters := make([]storetypes.Iterator, 0, len(keys)) defer func() { for _, iter := range iters { @@ -125,7 +156,7 @@ func (k Keeper) GetGroups(ctx sdk.Context, id types.DeploymentID) []types.Group }() for _, key := range keys { - iter := sdk.KVStorePrefixIterator(store, key) + iter := storetypes.KVStorePrefixIterator(store, key) iters = append(iters, iter) for ; iter.Valid(); iter.Next() { @@ -139,38 +170,42 @@ func (k Keeper) GetGroups(ctx sdk.Context, id types.DeploymentID) []types.Group } // Create creates a new deployment with given deployment and group specifications -func (k Keeper) Create(ctx sdk.Context, deployment types.Deployment, groups []types.Group) error { +func (k Keeper) Create(ctx sdk.Context, deployment v1.Deployment, groups []types.Group) error { store := ctx.KVStore(k.skey) - key := k.findDeployment(ctx, deployment.ID()) - + key := k.findDeployment(ctx, deployment.ID) if len(key) != 0 { - return types.ErrDeploymentExists + return v1.ErrDeploymentExists } - key = MustDeploymentKey(DeploymentStateToPrefix(deployment.State), deployment.ID()) + key = MustDeploymentKey(DeploymentStateToPrefix(deployment.State), deployment.ID) store.Set(key, k.cdc.MustMarshal(&deployment)) for idx := range groups { group := groups[idx] - if !group.ID().DeploymentID().Equals(deployment.ID()) { - return types.ErrInvalidGroupID + if !group.ID.DeploymentID().Equals(deployment.ID) { + return v1.ErrInvalidGroupID } - gkey, err := GroupKey(GroupStateToPrefix(group.State), group.ID()) + gkey, err := GroupKey(GroupStateToPrefix(group.State), group.ID) if err != nil { - return errors.Wrap(err, "failed to create group key") + return fmt.Errorf("%w: failed to create group key", err) } store.Set(gkey, k.cdc.MustMarshal(&group)) } - ctx.EventManager().EmitEvent( - types.NewEventDeploymentCreated(deployment.ID(), deployment.Version). - ToSDKEvent(), + err := ctx.EventManager().EmitTypedEvent( + &v1.EventDeploymentCreated{ + ID: deployment.ID, + Hash: deployment.Hash, + }, ) + if err != nil { + return err + } telemetry.IncrCounter(1.0, "akash.deployment_created") @@ -178,78 +213,89 @@ func (k Keeper) Create(ctx sdk.Context, deployment types.Deployment, groups []ty } // UpdateDeployment updates deployment details -func (k Keeper) UpdateDeployment(ctx sdk.Context, deployment types.Deployment) error { +func (k Keeper) UpdateDeployment(ctx sdk.Context, deployment v1.Deployment) error { store := ctx.KVStore(k.skey) - - key := k.findDeployment(ctx, deployment.ID()) + key := k.findDeployment(ctx, deployment.ID) if len(key) == 0 { - return types.ErrDeploymentNotFound + return v1.ErrDeploymentNotFound } - key = MustDeploymentKey(DeploymentStateToPrefix(deployment.State), deployment.ID()) + key = MustDeploymentKey(DeploymentStateToPrefix(deployment.State), deployment.ID) store.Set(key, k.cdc.MustMarshal(&deployment)) - ctx.EventManager().EmitEvent( - types.NewEventDeploymentUpdated(deployment.ID(), deployment.Version). - ToSDKEvent(), + err := ctx.EventManager().EmitTypedEvent( + &v1.EventDeploymentUpdated{ + ID: deployment.ID, + Hash: deployment.Hash, + }, ) + if err != nil { + return err + } return nil } -// CloseDeployment updates deployment details -func (k Keeper) CloseDeployment(ctx sdk.Context, deployment types.Deployment) { - if deployment.State == types.DeploymentClosed { - return +// CloseDeployment close deployment +func (k Keeper) CloseDeployment(ctx sdk.Context, deployment v1.Deployment) error { + if deployment.State == v1.DeploymentClosed { + return v1.ErrDeploymentClosed } store := ctx.KVStore(k.skey) - key := k.findDeployment(ctx, deployment.ID()) - + key := k.findDeployment(ctx, deployment.ID) if len(key) == 0 { - return + return v1.ErrDeploymentNotFound } store.Delete(key) - deployment.State = types.DeploymentClosed + deployment.State = v1.DeploymentClosed - key = MustDeploymentKey(DeploymentStateToPrefix(deployment.State), deployment.DeploymentID) + key = MustDeploymentKey(DeploymentStateToPrefix(deployment.State), deployment.ID) store.Set(key, k.cdc.MustMarshal(&deployment)) - ctx.EventManager().EmitEvent( - types.NewEventDeploymentClosed(deployment.ID()). - ToSDKEvent(), + err := ctx.EventManager().EmitTypedEvent( + &v1.EventDeploymentClosed{ + ID: deployment.ID, + }, ) + if err != nil { + return err + } + return nil } // OnCloseGroup provides shutdown API for a Group func (k Keeper) OnCloseGroup(ctx sdk.Context, group types.Group, state types.Group_State) error { store := ctx.KVStore(k.skey) - - key := k.findGroup(ctx, group.ID()) + key := k.findGroup(ctx, group.ID) if len(key) == 0 { - return types.ErrGroupNotFound + return v1.ErrGroupNotFound } store.Delete(key) group.State = state - key, err := GroupKey(GroupStateToPrefix(group.State), group.ID()) + key, err := GroupKey(GroupStateToPrefix(group.State), group.ID) if err != nil { - return errors.Wrap(err, "failed to encode group key") + return fmt.Errorf("%s: failed to encode group key", err) } store.Set(key, k.cdc.MustMarshal(&group)) - ctx.EventManager().EmitEvent( - types.NewEventGroupClosed(group.ID()). - ToSDKEvent(), + err = ctx.EventManager().EmitTypedEvent( + &v1.EventGroupClosed{ + ID: group.ID, + }, ) + if err != nil { + return err + } return nil } @@ -257,10 +303,9 @@ func (k Keeper) OnCloseGroup(ctx sdk.Context, group types.Group, state types.Gro // OnPauseGroup provides shutdown API for a Group func (k Keeper) OnPauseGroup(ctx sdk.Context, group types.Group) error { store := ctx.KVStore(k.skey) - - key := k.findGroup(ctx, group.ID()) + key := k.findGroup(ctx, group.ID) if len(key) == 0 { - return types.ErrGroupNotFound + return v1.ErrGroupNotFound } store.Delete(key) @@ -268,10 +313,14 @@ func (k Keeper) OnPauseGroup(ctx sdk.Context, group types.Group) error { group.State = types.GroupPaused store.Set(key, k.cdc.MustMarshal(&group)) - ctx.EventManager().EmitEvent( - types.NewEventGroupPaused(group.ID()). - ToSDKEvent(), + err := ctx.EventManager().EmitTypedEvent( + &v1.EventGroupPaused{ + ID: group.ID, + }, ) + if err != nil { + return err + } store.Set(key, k.cdc.MustMarshal(&group)) return nil @@ -281,40 +330,44 @@ func (k Keeper) OnPauseGroup(ctx sdk.Context, group types.Group) error { func (k Keeper) OnStartGroup(ctx sdk.Context, group types.Group) error { store := ctx.KVStore(k.skey) - key := k.findGroup(ctx, group.ID()) + key := k.findGroup(ctx, group.ID) if len(key) == 0 { - return types.ErrGroupNotFound + return v1.ErrGroupNotFound } store.Delete(key) group.State = types.GroupOpen - key, err := GroupKey(GroupStateToPrefix(group.State), group.ID()) + key, err := GroupKey(GroupStateToPrefix(group.State), group.ID) if err != nil { - return errors.Wrap(err, "failed to encode group key") + return fmt.Errorf("%w: failed to encode group key", err) } store.Set(key, k.cdc.MustMarshal(&group)) - ctx.EventManager().EmitEvent( - types.NewEventGroupStarted(group.ID()). - ToSDKEvent(), + err = ctx.EventManager().EmitTypedEvent( + &v1.EventGroupStarted{ + ID: group.ID, + }, ) + if err != nil { + return err + } return nil } // WithDeployments iterates all deployments in deployment store -func (k Keeper) WithDeployments(ctx sdk.Context, fn func(types.Deployment) bool) { +func (k Keeper) WithDeployments(ctx sdk.Context, fn func(v1.Deployment) bool) { store := ctx.KVStore(k.skey) - iter := sdk.KVStorePrefixIterator(store, DeploymentPrefix) + iter := storetypes.KVStorePrefixIterator(store, DeploymentPrefix) defer func() { _ = iter.Close() }() for ; iter.Valid(); iter.Next() { - var val types.Deployment + var val v1.Deployment k.cdc.MustUnmarshal(iter.Value(), &val) if stop := fn(val); stop { break @@ -323,35 +376,24 @@ func (k Keeper) WithDeployments(ctx sdk.Context, fn func(types.Deployment) bool) } // OnBidClosed sets the group to state paused. -func (k Keeper) OnBidClosed(ctx sdk.Context, id types.GroupID) error { +func (k Keeper) OnBidClosed(ctx sdk.Context, id v1.GroupID) error { group, ok := k.GetGroup(ctx, id) if !ok { - return types.ErrGroupNotFound + return v1.ErrGroupNotFound } return k.OnPauseGroup(ctx, group) } // OnLeaseClosed keeps the group at state open -func (k Keeper) OnLeaseClosed(ctx sdk.Context, id types.GroupID) (types.Group, error) { +func (k Keeper) OnLeaseClosed(ctx sdk.Context, id v1.GroupID) (types.Group, error) { group, ok := k.GetGroup(ctx, id) if !ok { - return types.Group{}, types.ErrGroupNotFound + return types.Group{}, v1.ErrGroupNotFound } return group, nil } -// GetParams returns the total set of deployment parameters. -func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { - k.pspace.GetParamSet(ctx, ¶ms) - return params -} - -// SetParams sets the deployment parameters to the paramspace. -func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { - k.pspace.SetParamSet(ctx, ¶ms) -} - -func (k Keeper) findDeployment(ctx sdk.Context, id types.DeploymentID) []byte { +func (k Keeper) findDeployment(ctx sdk.Context, id v1.DeploymentID) []byte { store := ctx.KVStore(k.skey) aKey := MustDeploymentKey(DeploymentStateActivePrefix, id) @@ -368,7 +410,7 @@ func (k Keeper) findDeployment(ctx sdk.Context, id types.DeploymentID) []byte { return key } -func (k Keeper) findGroup(ctx sdk.Context, id types.GroupID) []byte { +func (k Keeper) findGroup(ctx sdk.Context, id v1.GroupID) []byte { store := ctx.KVStore(k.skey) oKey := MustGroupKey(GroupStateOpenPrefix, id) diff --git a/x/deployment/keeper/keeper_test.go b/x/deployment/keeper/keeper_test.go index 1ef1eefd14..834edec661 100644 --- a/x/deployment/keeper/keeper_test.go +++ b/x/deployment/keeper/keeper_test.go @@ -6,18 +6,20 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "pkg.akt.dev/go/node/deployment/v1beta4" - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/testutil/state" - "github.com/akash-network/node/x/deployment/keeper" + types "pkg.akt.dev/go/node/deployment/v1" + "pkg.akt.dev/go/testutil" + + "pkg.akt.dev/node/testutil/state" + "pkg.akt.dev/node/x/deployment/keeper" ) func Test_Create(t *testing.T) { ctx, keeper := setupKeeper(t) deployment := testutil.Deployment(t) - groups := testutil.DeploymentGroups(t, deployment.ID(), 0) + groups := testutil.DeploymentGroups(t, deployment.ID, 0) err := keeper.Create(ctx, deployment, groups) require.NoError(t, err) @@ -26,7 +28,7 @@ func Test_Create(t *testing.T) { assert.Len(t, ctx.EventManager().Events(), 1) t.Run("deployment written", func(t *testing.T) { - result, ok := keeper.GetDeployment(ctx, deployment.ID()) + result, ok := keeper.GetDeployment(ctx, deployment.ID) assert.True(t, ok) assert.Equal(t, deployment, result) }) @@ -34,7 +36,7 @@ func Test_Create(t *testing.T) { t.Run("one deployment exists", func(t *testing.T) { count := 0 keeper.WithDeployments(ctx, func(d types.Deployment) bool { - if assert.Equal(t, deployment.ID(), d.ID()) { + if assert.Equal(t, deployment.ID, d.ID) { count++ } return false @@ -45,18 +47,18 @@ func Test_Create(t *testing.T) { // write more data. { deployment := testutil.Deployment(t) - groups := testutil.DeploymentGroups(t, deployment.ID(), 0) + groups := testutil.DeploymentGroups(t, deployment.ID, 0) assert.NoError(t, keeper.Create(ctx, deployment, groups)) } t.Run("groups written - read all", func(t *testing.T) { - result := keeper.GetGroups(ctx, deployment.ID()) + result := keeper.GetGroups(ctx, deployment.ID) assert.Equal(t, groups, result) }) // assert groups written - read single for i := 0; i < len(groups); i++ { - result, ok := keeper.GetGroup(ctx, groups[i].ID()) + result, ok := keeper.GetGroup(ctx, groups[i].ID) assert.True(t, ok) assert.Equal(t, groups[i], result) } @@ -71,7 +73,7 @@ func Test_Create_dupe(t *testing.T) { ctx, keeper := setupKeeper(t) deployment := testutil.Deployment(t) - groups := testutil.DeploymentGroups(t, deployment.ID(), 0) + groups := testutil.DeploymentGroups(t, deployment.ID, 0) err := keeper.Create(ctx, deployment, groups) require.NoError(t, err) @@ -97,7 +99,7 @@ func Test_UpdateDeployment(t *testing.T) { ctx, keeper := setupKeeper(t) deployment := testutil.Deployment(t) - groups := testutil.DeploymentGroups(t, deployment.ID(), 0) + groups := testutil.DeploymentGroups(t, deployment.ID, 0) err := keeper.UpdateDeployment(ctx, deployment) require.Error(t, err) @@ -105,12 +107,12 @@ func Test_UpdateDeployment(t *testing.T) { err = keeper.Create(ctx, deployment, groups) require.NoError(t, err) - deployment.Version = []byte{5, 6, 7, 8} + deployment.Hash = []byte{5, 6, 7, 8} err = keeper.UpdateDeployment(ctx, deployment) require.NoError(t, err) - result, ok := keeper.GetDeployment(ctx, deployment.ID()) + result, ok := keeper.GetDeployment(ctx, deployment.ID) require.True(t, ok) require.Equal(t, deployment, result) } @@ -121,7 +123,7 @@ func Test_OnEscrowAccountClosed_overdrawn(t *testing.T) { _, groups := createActiveDeployment(t, ctx, keeper) - did := groups[0].ID().DeploymentID() + did := groups[0].ID.DeploymentID() // eid := types.EscrowAccountForDeployment(did) @@ -133,15 +135,15 @@ func Test_OnEscrowAccountClosed_overdrawn(t *testing.T) { // keeper.OnEscrowAccountClosed(ctx, eobj) { - group, ok := keeper.GetGroup(ctx, groups[0].ID()) + group, ok := keeper.GetGroup(ctx, groups[0].ID) assert.True(t, ok) - assert.Equal(t, types.GroupInsufficientFunds, group.State) + assert.Equal(t, v1beta4.GroupInsufficientFunds, group.State) } { - group, ok := keeper.GetGroup(ctx, groups[1].ID()) + group, ok := keeper.GetGroup(ctx, groups[1].ID) assert.True(t, ok) - assert.Equal(t, types.GroupInsufficientFunds, group.State) + assert.Equal(t, v1beta4.GroupInsufficientFunds, group.State) } { @@ -156,19 +158,19 @@ func Test_OnBidClosed(t *testing.T) { _, groups := createActiveDeployment(t, ctx, keeper) - err := keeper.OnBidClosed(ctx, groups[0].ID()) + err := keeper.OnBidClosed(ctx, groups[0].ID) require.NoError(t, err) t.Run("target group changed", func(t *testing.T) { - group, ok := keeper.GetGroup(ctx, groups[0].ID()) + group, ok := keeper.GetGroup(ctx, groups[0].ID) assert.True(t, ok) - assert.Equal(t, types.GroupPaused, group.State) + assert.Equal(t, v1beta4.GroupPaused, group.State) }) t.Run("non-target group state unchanged", func(t *testing.T) { - group, ok := keeper.GetGroup(ctx, groups[1].ID()) + group, ok := keeper.GetGroup(ctx, groups[1].ID) assert.True(t, ok) - assert.Equal(t, types.GroupOpen, group.State) + assert.Equal(t, v1beta4.GroupOpen, group.State) }) } @@ -177,47 +179,47 @@ func Test_CloseGroup(t *testing.T) { _, groups := createActiveDeployment(t, ctx, keeper) t.Run("assert group 0 state closed", func(t *testing.T) { - assert.NoError(t, keeper.OnCloseGroup(ctx, groups[0], types.GroupClosed)) - group, ok := keeper.GetGroup(ctx, groups[0].ID()) + assert.NoError(t, keeper.OnCloseGroup(ctx, groups[0], v1beta4.GroupClosed)) + group, ok := keeper.GetGroup(ctx, groups[0].ID) assert.True(t, ok) - assert.Equal(t, types.GroupClosed, group.State) + assert.Equal(t, v1beta4.GroupClosed, group.State) - assert.Equal(t, types.GroupClosed, group.State) + assert.Equal(t, v1beta4.GroupClosed, group.State) }) t.Run("group 1 matched-state orderable", func(t *testing.T) { group := groups[1] - assert.Equal(t, types.GroupOpen, group.State) + assert.Equal(t, v1beta4.GroupOpen, group.State) }) } func Test_Empty_CloseGroup(t *testing.T) { ctx, keeper := setupKeeper(t) - group := types.Group{ - GroupID: testutil.GroupID(t), + group := v1beta4.Group{ + ID: testutil.GroupID(t), } t.Run("assert non-existent group returns error", func(t *testing.T) { - err := keeper.OnCloseGroup(ctx, group, types.GroupClosed) + err := keeper.OnCloseGroup(ctx, group, v1beta4.GroupClosed) assert.Error(t, err, "'group not found' error should be returned") }) } -func createActiveDeployment(t testing.TB, ctx sdk.Context, keeper keeper.IKeeper) (types.DeploymentID, []types.Group) { +func createActiveDeployment(t testing.TB, ctx sdk.Context, keeper keeper.IKeeper) (types.DeploymentID, v1beta4.Groups) { t.Helper() deployment := testutil.Deployment(t) - groups := []types.Group{ - testutil.DeploymentGroup(t, deployment.ID(), 0), - testutil.DeploymentGroup(t, deployment.ID(), 1), + groups := v1beta4.Groups{ + testutil.DeploymentGroup(t, deployment.ID, 0), + testutil.DeploymentGroup(t, deployment.ID, 1), } for i := range groups { - groups[i].State = types.GroupOpen + groups[i].State = v1beta4.GroupOpen } err := keeper.Create(ctx, deployment, groups) require.NoError(t, err) - return deployment.DeploymentID, groups + return deployment.ID, groups } func setupKeeper(t testing.TB) (sdk.Context, keeper.IKeeper) { diff --git a/x/deployment/keeper/key.go b/x/deployment/keeper/key.go index 13ba2a9e52..76893b92c6 100644 --- a/x/deployment/keeper/key.go +++ b/x/deployment/keeper/key.go @@ -7,8 +7,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - "github.com/akash-network/akash-api/go/sdkutil" + "pkg.akt.dev/go/node/deployment/v1" + "pkg.akt.dev/go/node/deployment/v1beta4" + "pkg.akt.dev/go/sdkutil" ) const ( @@ -31,7 +32,7 @@ var ( GroupStateClosedPrefix = []byte{GroupStateClosedPrefixID} ) -func DeploymentKey(statePrefix []byte, id types.DeploymentID) ([]byte, error) { +func DeploymentKey(statePrefix []byte, id v1.DeploymentID) ([]byte, error) { owner, err := sdk.AccAddressFromBech32(id.Owner) if err != nil { return nil, err @@ -53,7 +54,7 @@ func DeploymentKey(statePrefix []byte, id types.DeploymentID) ([]byte, error) { return buf.Bytes(), nil } -func MustDeploymentKey(statePrefix []byte, id types.DeploymentID) []byte { +func MustDeploymentKey(statePrefix []byte, id v1.DeploymentID) []byte { key, err := DeploymentKey(statePrefix, id) if err != nil { panic(err) @@ -62,7 +63,7 @@ func MustDeploymentKey(statePrefix []byte, id types.DeploymentID) []byte { } // GroupKey provides prefixed key for a Group's marshalled data. -func GroupKey(statePrefix []byte, id types.GroupID) ([]byte, error) { +func GroupKey(statePrefix []byte, id v1.GroupID) ([]byte, error) { owner, err := sdk.AccAddressFromBech32(id.Owner) if err != nil { return nil, err @@ -87,16 +88,17 @@ func GroupKey(statePrefix []byte, id types.GroupID) ([]byte, error) { return buf.Bytes(), nil } -func MustGroupKey(statePrefix []byte, id types.GroupID) []byte { +func MustGroupKey(statePrefix []byte, id v1.GroupID) []byte { key, err := GroupKey(statePrefix, id) if err != nil { panic(err) } + return key } // GroupsKey provides default store Key for Group data. -func GroupsKey(statePrefix []byte, id types.DeploymentID) ([]byte, error) { +func GroupsKey(statePrefix []byte, id v1.DeploymentID) ([]byte, error) { owner, err := sdk.AccAddressFromBech32(id.Owner) if err != nil { return nil, err @@ -118,7 +120,7 @@ func GroupsKey(statePrefix []byte, id types.DeploymentID) ([]byte, error) { return buf.Bytes(), nil } -func MustGroupsKey(statePrefix []byte, id types.DeploymentID) []byte { +func MustGroupsKey(statePrefix []byte, id v1.DeploymentID) []byte { key, err := GroupsKey(statePrefix, id) if err != nil { panic(err) @@ -126,36 +128,36 @@ func MustGroupsKey(statePrefix []byte, id types.DeploymentID) []byte { return key } -func DeploymentStateToPrefix(state types.Deployment_State) []byte { +func DeploymentStateToPrefix(state v1.Deployment_State) []byte { var idx []byte switch state { - case types.DeploymentActive: + case v1.DeploymentActive: idx = DeploymentStateActivePrefix - case types.DeploymentClosed: + case v1.DeploymentClosed: idx = DeploymentStateClosedPrefix } return idx } -func GroupStateToPrefix(state types.Group_State) []byte { +func GroupStateToPrefix(state v1beta4.Group_State) []byte { var idx []byte switch state { - case types.GroupOpen: + case v1beta4.GroupOpen: idx = GroupStateOpenPrefix - case types.GroupPaused: + case v1beta4.GroupPaused: idx = GroupStatePausedPrefix - case types.GroupInsufficientFunds: + case v1beta4.GroupInsufficientFunds: idx = GroupStateInsufficientFundsPrefix - case types.GroupClosed: + case v1beta4.GroupClosed: idx = GroupStateClosedPrefix } return idx } -func buildDeploymentPrefix(state types.Deployment_State) []byte { +func buildDeploymentPrefix(state v1.Deployment_State) []byte { idx := DeploymentStateToPrefix(state) res := make([]byte, 0, len(DeploymentPrefix)+len(idx)) @@ -166,7 +168,7 @@ func buildDeploymentPrefix(state types.Deployment_State) []byte { } // nolint: unused -func buildGroupPrefix(state types.Group_State) []byte { +func buildGroupPrefix(state v1beta4.Group_State) []byte { idx := GroupStateToPrefix(state) res := make([]byte, 0, len(GroupPrefix)+len(idx)) @@ -216,12 +218,12 @@ func filterToPrefix(prefix []byte, owner string, dseq uint64, gseq uint32) ([]by return buf.Bytes(), nil } -func deploymentPrefixFromFilter(f types.DeploymentFilters) ([]byte, error) { - return filterToPrefix(buildDeploymentPrefix(types.Deployment_State(types.Deployment_State_value[f.State])), f.Owner, f.DSeq, 0) +func deploymentPrefixFromFilter(f v1beta4.DeploymentFilters) ([]byte, error) { + return filterToPrefix(buildDeploymentPrefix(v1.Deployment_State(v1.Deployment_State_value[f.State])), f.Owner, f.DSeq, 0) } -func DeploymentKeyLegacy(id types.DeploymentID) []byte { - buf := bytes.NewBuffer(types.DeploymentPrefix()) +func DeploymentKeyLegacy(id v1.DeploymentID) []byte { + buf := bytes.NewBuffer(v1.DeploymentPrefix()) buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { @@ -232,8 +234,8 @@ func DeploymentKeyLegacy(id types.DeploymentID) []byte { } // GroupKeyLegacy provides prefixed key for a Group's marshalled data. -func GroupKeyLegacy(id types.GroupID) []byte { - buf := bytes.NewBuffer(types.GroupPrefix()) +func GroupKeyLegacy(id v1.GroupID) []byte { + buf := bytes.NewBuffer(v1.GroupPrefix()) buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { panic(err) @@ -245,8 +247,8 @@ func GroupKeyLegacy(id types.GroupID) []byte { } // GroupsKeyLegacy provides default store Key for Group data. -func GroupsKeyLegacy(id types.DeploymentID) []byte { - buf := bytes.NewBuffer(types.GroupPrefix()) +func GroupsKeyLegacy(id v1.DeploymentID) []byte { + buf := bytes.NewBuffer(v1.GroupPrefix()) buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { panic(err) @@ -255,6 +257,6 @@ func GroupsKeyLegacy(id types.DeploymentID) []byte { } // nolint: unused -func deploymentPrefixFromFilterLegacy(f types.DeploymentFilters) ([]byte, error) { - return filterToPrefix(types.DeploymentPrefix(), f.Owner, f.DSeq, 0) +func deploymentPrefixFromFilterLegacy(f v1beta4.DeploymentFilters) ([]byte, error) { + return filterToPrefix(v1.DeploymentPrefix(), f.Owner, f.DSeq, 0) } diff --git a/x/deployment/module.go b/x/deployment/module.go index 422cb8f3c5..a6a8bcc87a 100644 --- a/x/deployment/module.go +++ b/x/deployment/module.go @@ -4,39 +4,40 @@ import ( "context" "encoding/json" "fmt" - "math/rand" - "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" - + "cosmossdk.io/core/appmodule" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - sim "github.com/cosmos/cosmos-sdk/types/simulation" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - v1beta1types "github.com/akash-network/akash-api/go/node/deployment/v1beta1" - v1beta2types "github.com/akash-network/akash-api/go/node/deployment/v1beta2" - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + v1 "pkg.akt.dev/go/node/deployment/v1" + types "pkg.akt.dev/go/node/deployment/v1beta4" + "pkg.akt.dev/go/node/migrate" - "github.com/akash-network/node/x/deployment/client/cli" - "github.com/akash-network/node/x/deployment/client/rest" - "github.com/akash-network/node/x/deployment/handler" - "github.com/akash-network/node/x/deployment/keeper" - "github.com/akash-network/node/x/deployment/simulation" + "pkg.akt.dev/node/x/deployment/handler" + "pkg.akt.dev/node/x/deployment/keeper" + "pkg.akt.dev/node/x/deployment/simulation" ) // type check to ensure the interface is properly implemented var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} - _ module.AppModuleSimulation = AppModuleSimulation{} + _ module.AppModuleBasic = AppModuleBasic{} + _ module.HasGenesisBasics = AppModuleBasic{} + + _ appmodule.AppModule = AppModule{} + _ module.HasConsensusVersion = AppModule{} + _ module.HasGenesis = AppModule{} + _ module.HasServices = AppModule{} + + _ module.AppModuleSimulation = AppModule{} ) // AppModuleBasic defines the basic application module used by the deployment module. @@ -44,21 +45,32 @@ type AppModuleBasic struct { cdc codec.Codec } +// AppModule implements an application module for the deployment module. +type AppModule struct { + AppModuleBasic + keeper keeper.IKeeper + mkeeper handler.MarketKeeper + ekeeper handler.EscrowKeeper + coinKeeper bankkeeper.Keeper + authzKeeper handler.AuthzKeeper + acckeeper govtypes.AccountKeeper +} + // Name returns deployment module's name func (AppModuleBasic) Name() string { - return types.ModuleName + return v1.ModuleName } // RegisterLegacyAminoCodec registers the deployment module's types for the given codec. func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { - types.RegisterLegacyAminoCodec(cdc) + types.RegisterLegacyAminoCodec(cdc) // nolint staticcheck } // RegisterInterfaces registers the module's interface types func (b AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) { types.RegisterInterfaces(registry) - v1beta2types.RegisterInterfaces(registry) - v1beta1types.RegisterInterfaces(registry) + + migrate.RegisterDeploymentInterfaces(registry) } // DefaultGenesis returns default genesis state as raw bytes for the deployment @@ -67,21 +79,16 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { return cdc.MustMarshalJSON(DefaultGenesisState()) } -// ValidateGenesis does validation check of the Genesis and returns error incase of failure -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { +// ValidateGenesis does validation check of the Genesis and returns error in case of failure +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { var data types.GenesisState err := cdc.UnmarshalJSON(bz, &data) if err != nil { - return fmt.Errorf("failed to unmarshal %s genesis state: %v", types.ModuleName, err) + return fmt.Errorf("failed to unmarshal %s genesis state: %v", v1.ModuleName, err) } return ValidateGenesis(&data) } -// RegisterRESTRoutes registers rest routes for this module -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { - rest.RegisterRoutes(clientCtx, rtr, StoreKey) -} - // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the deployment module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) @@ -92,36 +99,30 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *r // GetQueryCmd get the root query command of this module func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.GetQueryCmd() + panic("akash modules do not export cli commands via cosmos interface") } // GetTxCmd get the root tx command of this module func (AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.GetTxCmd(StoreKey) -} - -// GetQueryClient returns a new query client for this module -func (AppModuleBasic) GetQueryClient(clientCtx client.Context) types.QueryClient { - return types.NewQueryClient(clientCtx) -} - -// AppModule implements an application module for the deployment module. -type AppModule struct { - AppModuleBasic - keeper keeper.IKeeper - mkeeper handler.MarketKeeper - ekeeper handler.EscrowKeeper - coinKeeper bankkeeper.Keeper - authzKeeper handler.AuthzKeeper + panic("akash modules do not export cli commands via cosmos interface") } // NewAppModule creates a new AppModule Object -func NewAppModule(cdc codec.Codec, k keeper.IKeeper, mkeeper handler.MarketKeeper, ekeeper handler.EscrowKeeper, bankKeeper bankkeeper.Keeper, authzKeeper handler.AuthzKeeper) AppModule { +func NewAppModule( + cdc codec.Codec, + k keeper.IKeeper, + mkeeper handler.MarketKeeper, + ekeeper handler.EscrowKeeper, + acckeeper govtypes.AccountKeeper, + bankKeeper bankkeeper.Keeper, + authzKeeper handler.AuthzKeeper, +) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{cdc: cdc}, keeper: k, mkeeper: mkeeper, ekeeper: ekeeper, + acckeeper: acckeeper, coinKeeper: bankKeeper, authzKeeper: authzKeeper, } @@ -129,49 +130,42 @@ func NewAppModule(cdc codec.Codec, k keeper.IKeeper, mkeeper handler.MarketKeepe // Name returns the deployment module name func (AppModule) Name() string { - return types.ModuleName + return v1.ModuleName } -// RegisterInvariants registers module invariants -func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (am AppModule) IsOnePerModuleType() {} -// Route returns the message routing key for the deployment module -func (am AppModule) Route() sdk.Route { - return sdk.NewRoute(types.RouterKey, handler.NewHandler(am.keeper, am.mkeeper, am.ekeeper, am.authzKeeper)) -} - -// QuerierRoute returns the deployment module's querier route name. -func (am AppModule) QuerierRoute() string { - return "" -} - -// LegacyQuerierHandler returns the sdk.Querier for deployment module -func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { - return nil -} +// IsAppModule implements the appmodule.AppModule interface. +func (am AppModule) IsAppModule() {} // RegisterServices registers the module's services func (am AppModule) RegisterServices(cfg module.Configurator) { - types.RegisterMsgServer(cfg.MsgServer(), handler.NewServer(am.keeper, am.mkeeper, am.ekeeper, am.authzKeeper)) + types.RegisterMsgServer(cfg.MsgServer(), handler.NewServer(am.keeper, am.mkeeper, am.ekeeper)) + querier := am.keeper.NewQuerier() + types.RegisterQueryServer(cfg.QueryServer(), querier) } // BeginBlock performs no-op -func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} +func (am AppModule) BeginBlock(_ context.Context) error { + return nil +} // EndBlock returns the end blocker for the deployment module. It returns no validator // updates. -func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - return []abci.ValidatorUpdate{} +func (am AppModule) EndBlock(_ context.Context) error { + return nil } // InitGenesis performs genesis initialization for the deployment module. It returns // no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) { var genesisState types.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) - return InitGenesis(ctx, am.keeper, &genesisState) + + InitGenesis(ctx, am.keeper, &genesisState) } // ExportGenesis returns the exported genesis state as raw bytes for the deployment @@ -183,49 +177,25 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw // ConsensusVersion implements module.AppModule#ConsensusVersion func (am AppModule) ConsensusVersion() uint64 { - return 4 -} - -// AppModuleSimulation implements an application simulation module for the deployment module. -type AppModuleSimulation struct { - keeper keeper.IKeeper - akeeper govtypes.AccountKeeper - bkeeper bankkeeper.Keeper -} - -// NewAppModuleSimulation creates a new AppModuleSimulation instance -func NewAppModuleSimulation(k keeper.IKeeper, akeeper govtypes.AccountKeeper, bankKeeper bankkeeper.Keeper) AppModuleSimulation { - return AppModuleSimulation{ - keeper: k, - akeeper: akeeper, - bkeeper: bankKeeper, - } + return 5 } // AppModuleSimulation functions // GenerateGenesisState creates a randomized GenState of the staking module. -func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) { +func (AppModule) GenerateGenesisState(simState *module.SimulationState) { simulation.RandomizedGenState(simState) } -// ProposalContents doesn't return any content functions for governance proposals. -func (AppModuleSimulation) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent { - return nil -} - -// RandomizedParams creates randomized staking param changes for the simulator. -func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange { - return nil +// ProposalMsgs returns msgs used for governance proposals for simulations. +func (AppModule) ProposalMsgs(_ module.SimulationState) []simtypes.WeightedProposalMsg { + return simulation.ProposalMsgs() } -// RegisterStoreDecoder registers a decoder for staking module's types -func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { - // sdr[StoreKey] = simulation.DecodeStore -} +// RegisterStoreDecoder registers a decoder for take module's types. +func (am AppModule) RegisterStoreDecoder(_ simtypes.StoreDecoderRegistry) {} -// WeightedOperations returns the all the staking module operations with their respective weights. -func (am AppModuleSimulation) WeightedOperations(simState module.SimulationState) []sim.WeightedOperation { - return simulation.WeightedOperations(simState.AppParams, simState.Cdc, - am.akeeper, am.bkeeper, am.keeper) +// WeightedOperations doesn't return any take module operation. +func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { + return simulation.WeightedOperations(simState.AppParams, simState.Cdc, am.acckeeper, am.coinKeeper, am.keeper) } diff --git a/x/deployment/query/client.go b/x/deployment/query/client.go index a1cf623da7..048d0813db 100644 --- a/x/deployment/query/client.go +++ b/x/deployment/query/client.go @@ -3,7 +3,7 @@ package query import ( sdkclient "github.com/cosmos/cosmos-sdk/client" - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + types "pkg.akt.dev/go/node/deployment/v1" ) // Client interface diff --git a/x/deployment/query/path.go b/x/deployment/query/path.go index 342704b79b..3174ec1e4b 100644 --- a/x/deployment/query/path.go +++ b/x/deployment/query/path.go @@ -5,7 +5,7 @@ import ( "fmt" "strconv" - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + types "pkg.akt.dev/go/node/deployment/v1" ) const ( diff --git a/x/deployment/query/rawclient.go b/x/deployment/query/rawclient.go index 1f7b88db97..4287d94fbe 100644 --- a/x/deployment/query/rawclient.go +++ b/x/deployment/query/rawclient.go @@ -5,7 +5,7 @@ import ( sdkclient "github.com/cosmos/cosmos-sdk/client" - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + types "pkg.akt.dev/go/node/deployment/v1" ) // RawClient interface diff --git a/x/deployment/query/types.go b/x/deployment/query/types.go index fb54477c91..8713ae928e 100644 --- a/x/deployment/query/types.go +++ b/x/deployment/query/types.go @@ -6,7 +6,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + "pkg.akt.dev/go/node/deployment/v1" + "pkg.akt.dev/go/node/deployment/v1beta4" ) // DeploymentFilters defines flags for deployment list filter @@ -15,15 +16,15 @@ type DeploymentFilters struct { // State flag value given StateFlagVal string // Actual state value decoded from DeploymentStateMap - State types.Deployment_State + State v1.Deployment_State } // Accept returns whether deployment filters valid or not -func (filters DeploymentFilters) Accept(obj types.Deployment, isValidState bool) bool { +func (filters DeploymentFilters) Accept(obj v1.Deployment, isValidState bool) bool { if (filters.Owner.Empty() && !isValidState) || (filters.Owner.Empty() && (obj.State == filters.State)) || - (!isValidState && (obj.DeploymentID.Owner == filters.Owner.String())) || - (obj.DeploymentID.Owner == filters.Owner.String() && obj.State == filters.State) { + (!isValidState && (obj.ID.Owner == filters.Owner.String())) || + (obj.ID.Owner == filters.Owner.String() && obj.State == filters.State) { return true } @@ -32,8 +33,8 @@ func (filters DeploymentFilters) Accept(obj types.Deployment, isValidState bool) // Deployment stores deployment and groups details type Deployment struct { - types.Deployment `json:"deployment"` - Groups []types.Group `json:"groups"` + v1.Deployment `json:"deployment"` + Groups v1beta4.Groups `json:"groups"` } func (d Deployment) String() string { @@ -43,8 +44,7 @@ func (d Deployment) String() string { State: %v Version: %s Num Groups: %d - `, d.Deployment.DeploymentID.Owner, d.Deployment.DeploymentID.DSeq, - d.Deployment.State, d.Deployment.Version, len(d.Groups)) + `, d.ID.Owner, d.ID.DSeq, d.State, d.Hash, len(d.Groups)) } // Deployments represents slice of deployment struct @@ -68,7 +68,7 @@ func (ds Deployments) String() string { } // Group stores group ID, state and other specifications -type Group types.Group +type Group v1beta4.Group // GroupFilters defines flags for group list filter type GroupFilters struct { @@ -76,5 +76,5 @@ type GroupFilters struct { // State flag value given StateFlagVal string // Actual state value decoded from GroupStateMap - State types.Group_State + State v1beta4.Group_State } diff --git a/x/deployment/simulation/genesis.go b/x/deployment/simulation/genesis.go index d603a1e534..7724ec9106 100644 --- a/x/deployment/simulation/genesis.go +++ b/x/deployment/simulation/genesis.go @@ -3,8 +3,8 @@ package simulation import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + "pkg.akt.dev/go/node/deployment/v1" + types "pkg.akt.dev/go/node/deployment/v1beta4" ) var ( @@ -13,13 +13,32 @@ var ( // RandomizedGenState generates a random GenesisState for supply func RandomizedGenState(simState *module.SimulationState) { + // numDeployments := simulation.RandIntBetween(simState.Rand, 0, len(simState.Accounts)) + deploymentGenesis := &types.GenesisState{ Params: types.Params{ MinDeposits: sdk.Coins{ minDeposit, }, }, + // Deployments: make([]types.GenesisDeployment, 0, numDeployments), } - simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(deploymentGenesis) + // for range cap(deploymentGenesis.Deployments) { + // acc, _ := simtypes.RandomAcc(simState.Rand, simState.Accounts) + // + // t := &testing.T{} + // + // depl := testutil.Deployment(t) + // depl.ID.Owner = acc.Address.String() + // + // dgroups := testutil.DeploymentGroups(t, depl.ID, 1) + // + // deploymentGenesis.Deployments = append(deploymentGenesis.Deployments, types.GenesisDeployment{ + // Deployment: depl, + // Groups: dgroups, + // }) + // } + + simState.GenState[v1.ModuleName] = simState.Cdc.MustMarshalJSON(deploymentGenesis) } diff --git a/x/deployment/simulation/operations.go b/x/deployment/simulation/operations.go index a3b09853f0..c3c87c291b 100644 --- a/x/deployment/simulation/operations.go +++ b/x/deployment/simulation/operations.go @@ -7,20 +7,23 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/simapp/helpers" - simappparams "github.com/cosmos/cosmos-sdk/simapp/params" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/cosmos-sdk/x/simulation" + deposit "pkg.akt.dev/go/node/types/deposit/v1" + "pkg.akt.dev/go/sdkutil" - types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + "pkg.akt.dev/go/node/deployment/v1" + "pkg.akt.dev/go/node/deployment/v1beta4" - appparams "github.com/akash-network/node/app/params" - sdlv1 "github.com/akash-network/node/sdl" - testsim "github.com/akash-network/node/testutil/sim" - "github.com/akash-network/node/x/deployment/keeper" + sdlv1 "pkg.akt.dev/go/sdl" + + appparams "pkg.akt.dev/node/app/params" + testsim "pkg.akt.dev/node/testutil/sim" + "pkg.akt.dev/node/x/deployment/keeper" ) // Simulation operation weights constants @@ -33,7 +36,7 @@ const ( // WeightedOperations returns all the operations from the module with their respective weights func WeightedOperations( - appParams simtypes.AppParams, cdc codec.JSONCodec, ak govtypes.AccountKeeper, + appParams simtypes.AppParams, _ codec.JSONCodec, ak govtypes.AccountKeeper, bk bankkeeper.Keeper, k keeper.IKeeper) simulation.WeightedOperations { var ( weightMsgCreateDeployment int @@ -43,25 +46,25 @@ func WeightedOperations( ) appParams.GetOrGenerate( - cdc, OpWeightMsgCreateDeployment, &weightMsgCreateDeployment, nil, func(r *rand.Rand) { + OpWeightMsgCreateDeployment, &weightMsgCreateDeployment, nil, func(_ *rand.Rand) { weightMsgCreateDeployment = appparams.DefaultWeightMsgCreateDeployment }, ) appParams.GetOrGenerate( - cdc, OpWeightMsgUpdateDeployment, &weightMsgUpdateDeployment, nil, func(r *rand.Rand) { + OpWeightMsgUpdateDeployment, &weightMsgUpdateDeployment, nil, func(_ *rand.Rand) { weightMsgUpdateDeployment = appparams.DefaultWeightMsgUpdateDeployment }, ) appParams.GetOrGenerate( - cdc, OpWeightMsgCloseDeployment, &weightMsgCloseDeployment, nil, func(r *rand.Rand) { + OpWeightMsgCloseDeployment, &weightMsgCloseDeployment, nil, func(_ *rand.Rand) { weightMsgCloseDeployment = appparams.DefaultWeightMsgCloseDeployment }, ) appParams.GetOrGenerate( - cdc, OpWeightMsgCloseGroup, &weightMsgCloseGroup, nil, func(r *rand.Rand) { + OpWeightMsgCloseGroup, &weightMsgCloseGroup, nil, func(_ *rand.Rand) { weightMsgCloseGroup = appparams.DefaultWeightMsgCloseGroup }, ) @@ -92,73 +95,77 @@ func SimulateMsgCreateDeployment(ak govtypes.AccountKeeper, bk bankkeeper.Keeper chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { simAccount, _ := simtypes.RandomAcc(r, accounts) - dID := types.DeploymentID{ + params := k.GetParams(ctx) + + dID := v1.DeploymentID{ Owner: simAccount.Address.String(), - DSeq: uint64(ctx.BlockHeight()), + DSeq: uint64(ctx.BlockHeight()), // nolint gosec } _, found := k.GetDeployment(ctx, dID) if found { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateDeployment, "no deployment found"), nil, nil + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCreateDeployment{}).Type(), "no deployment found"), nil, nil } sdl, readError := sdlv1.ReadFile("../x/deployment/testdata/deployment.yaml") if readError != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateDeployment, "unable to read config file"), + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCreateDeployment{}).Type(), "unable to read config file"), nil, readError } groupSpecs, groupErr := sdl.DeploymentGroups() if groupErr != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateDeployment, "unable to read groups"), nil, groupErr + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCreateDeployment{}).Type(), "unable to read groups"), nil, groupErr } sdlSum, err := sdl.Version() if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateDeployment, "error parsing deployment version sum"), + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCreateDeployment{}).Type(), "error parsing deployment version sum"), nil, err } - depositAmount := minDeposit + depositAmount := params.MinDeposits[0] account := ak.GetAccount(ctx, simAccount.Address) spendable := bk.SpendableCoins(ctx, account.GetAddress()) if spendable.AmountOf(depositAmount.Denom).LT(depositAmount.Amount.MulRaw(2)) { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateDeployment, "out of money"), nil, nil + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCreateDeployment{}).Type(), "out of money"), nil, nil } - spendable = spendable.Sub(sdk.NewCoins(depositAmount)) + spendable = spendable.Sub(depositAmount) fees, err := simtypes.RandomFees(r, ctx, spendable) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateDeployment, "unable to generate fees"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCreateDeployment{}).Type(), "unable to generate fees"), nil, err } - msg := types.NewMsgCreateDeployment(dID, make([]types.GroupSpec, 0, len(groupSpecs)), sdlSum, depositAmount, simAccount.Address) + msg := v1beta4.NewMsgCreateDeployment(dID, make([]v1beta4.GroupSpec, 0, len(groupSpecs)), sdlSum, deposit.Deposit{ + Amount: depositAmount, + Sources: deposit.Sources{deposit.SourceBalance}, + }) - for _, spec := range groupSpecs { - msg.Groups = append(msg.Groups, *spec) - } + msg.Groups = append(msg.Groups, groupSpecs...) - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( + txGen := sdkutil.MakeEncodingConfig().TxConfig + tx, err := simtestutil.GenSignedMockTx( + r, txGen, []sdk.Msg{msg}, fees, - helpers.DefaultGenTxGas, + simtestutil.DefaultGenTxGas, chainID, []uint64{account.GetAccountNumber()}, []uint64{account.GetSequence()}, simAccount.PrivKey, ) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err } - _, _, err = app.Deliver(txGen.TxEncoder(), tx) + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "create deployment - unable to deliver mock tx"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, msg.Type(), "create deployment - unable to deliver mock tx"), nil, err } - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + return simtypes.NewOperationMsg(msg, true, ""), nil, nil } } @@ -166,22 +173,22 @@ func SimulateMsgCreateDeployment(ak govtypes.AccountKeeper, bk bankkeeper.Keeper func SimulateMsgUpdateDeployment(ak govtypes.AccountKeeper, bk bankkeeper.Keeper, k keeper.IKeeper) simtypes.Operation { return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { - var deployments []types.Deployment + var deployments []v1.Deployment sdl, readError := sdlv1.ReadFile("../x/deployment/testdata/deployment-v2.yaml") if readError != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeUpdateDeployment, "unable to read config file"), nil, readError + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgUpdateDeployment{}).Type(), "unable to read config file"), nil, readError } sdlSum, err := sdl.Version() if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeUpdateDeployment, "error parsing deployment version sum"), + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgUpdateDeployment{}).Type(), "error parsing deployment version sum"), nil, err } - k.WithDeployments(ctx, func(deployment types.Deployment) bool { + k.WithDeployments(ctx, func(deployment v1.Deployment) bool { // skip deployments that already have been updated - if !bytes.Equal(deployment.Version, sdlSum) { + if !bytes.Equal(deployment.Hash, sdlSum) { deployments = append(deployments, deployment) } @@ -189,25 +196,25 @@ func SimulateMsgUpdateDeployment(ak govtypes.AccountKeeper, bk bankkeeper.Keeper }) if len(deployments) == 0 { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeUpdateDeployment, "no deployments found"), nil, nil + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgUpdateDeployment{}).Type(), "no deployments found"), nil, nil } // Get random deployment deployment := deployments[testsim.RandIdx(r, len(deployments)-1)] - if deployment.State != types.DeploymentActive { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeUpdateDeployment, "deployment closed"), nil, nil + if deployment.State != v1.DeploymentActive { + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgUpdateDeployment{}).Type(), "deployment closed"), nil, nil } - owner, convertErr := sdk.AccAddressFromBech32(deployment.ID().Owner) + owner, convertErr := sdk.AccAddressFromBech32(deployment.ID.Owner) if convertErr != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeUpdateDeployment, "error while converting address"), nil, convertErr + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgUpdateDeployment{}).Type(), "error while converting address"), nil, convertErr } simAccount, found := simtypes.FindAccount(accounts, owner) if !found { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeUpdateDeployment, "unable to find deployment with given id"), - nil, fmt.Errorf("deployment with %s not found", deployment.ID().Owner) + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgUpdateDeployment{}).Type(), "unable to find deployment with given id"), + nil, fmt.Errorf("deployment with %s not found", deployment.ID.Owner) } account := ak.GetAccount(ctx, simAccount.Address) @@ -215,32 +222,33 @@ func SimulateMsgUpdateDeployment(ak govtypes.AccountKeeper, bk bankkeeper.Keeper fees, err := simtypes.RandomFees(r, ctx, spendable) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeUpdateDeployment, "unable to generate fees"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgUpdateDeployment{}).Type(), "unable to generate fees"), nil, err } - msg := types.NewMsgUpdateDeployment(deployment.ID(), sdlSum) + msg := v1beta4.NewMsgUpdateDeployment(deployment.ID, sdlSum) - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( + txGen := sdkutil.MakeEncodingConfig().TxConfig + tx, err := simtestutil.GenSignedMockTx( + r, txGen, []sdk.Msg{msg}, fees, - helpers.DefaultGenTxGas, + simtestutil.DefaultGenTxGas, chainID, []uint64{account.GetAccountNumber()}, []uint64{account.GetSequence()}, simAccount.PrivKey, ) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err } - _, _, err = app.Deliver(txGen.TxEncoder(), tx) + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "update deployment - unable to deliver mock tx"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, msg.Type(), "update deployment - unable to deliver mock tx"), nil, err } - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + return simtypes.NewOperationMsg(msg, true, ""), nil, nil } } @@ -248,10 +256,10 @@ func SimulateMsgUpdateDeployment(ak govtypes.AccountKeeper, bk bankkeeper.Keeper func SimulateMsgCloseDeployment(ak govtypes.AccountKeeper, bk bankkeeper.Keeper, k keeper.IKeeper) simtypes.Operation { return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { - var deployments []types.Deployment + var deployments []v1.Deployment - k.WithDeployments(ctx, func(deployment types.Deployment) bool { - if deployment.State == types.DeploymentActive { + k.WithDeployments(ctx, func(deployment v1.Deployment) bool { + if deployment.State == v1.DeploymentActive { deployments = append(deployments, deployment) } @@ -259,21 +267,21 @@ func SimulateMsgCloseDeployment(ak govtypes.AccountKeeper, bk bankkeeper.Keeper, }) if len(deployments) == 0 { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseDeployment, "no deployments found"), nil, nil + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCloseDeployment{}).Type(), "no deployments found"), nil, nil } // Get random deployment deployment := deployments[testsim.RandIdx(r, len(deployments)-1)] - owner, convertErr := sdk.AccAddressFromBech32(deployment.ID().Owner) + owner, convertErr := sdk.AccAddressFromBech32(deployment.ID.Owner) if convertErr != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseDeployment, "error while converting address"), nil, convertErr + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCloseDeployment{}).Type(), "error while converting address"), nil, convertErr } simAccount, found := simtypes.FindAccount(accounts, owner) if !found { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseDeployment, "unable to find deployment"), nil, - fmt.Errorf("deployment with %s not found", deployment.ID().Owner) + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCloseDeployment{}).Type(), "unable to find deployment"), nil, + fmt.Errorf("deployment with %s not found", deployment.ID.Owner) } account := ak.GetAccount(ctx, simAccount.Address) @@ -281,32 +289,33 @@ func SimulateMsgCloseDeployment(ak govtypes.AccountKeeper, bk bankkeeper.Keeper, fees, err := simtypes.RandomFees(r, ctx, spendable) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseDeployment, "unable to generate fees"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCloseDeployment{}).Type(), "unable to generate fees"), nil, err } - msg := types.NewMsgCloseDeployment(deployment.ID()) + msg := v1beta4.NewMsgCloseDeployment(deployment.ID) - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( + txGen := sdkutil.MakeEncodingConfig().TxConfig + tx, err := simtestutil.GenSignedMockTx( + r, txGen, []sdk.Msg{msg}, fees, - helpers.DefaultGenTxGas, + simtestutil.DefaultGenTxGas, chainID, []uint64{account.GetAccountNumber()}, []uint64{account.GetSequence()}, simAccount.PrivKey, ) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err } - _, _, err = app.Deliver(txGen.TxEncoder(), tx) + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "close deployment - unable to deliver mock tx"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, msg.Type(), "close deployment - unable to deliver mock tx"), nil, err } - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + return simtypes.NewOperationMsg(msg, true, ""), nil, nil } } @@ -314,10 +323,10 @@ func SimulateMsgCloseDeployment(ak govtypes.AccountKeeper, bk bankkeeper.Keeper, func SimulateMsgCloseGroup(ak govtypes.AccountKeeper, bk bankkeeper.Keeper, k keeper.IKeeper) simtypes.Operation { return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { - var deployments []types.Deployment + var deployments []v1.Deployment - k.WithDeployments(ctx, func(deployment types.Deployment) bool { - if deployment.State == types.DeploymentActive { + k.WithDeployments(ctx, func(deployment v1.Deployment) bool { + if deployment.State == v1.DeploymentActive { deployments = append(deployments, deployment) } @@ -325,21 +334,21 @@ func SimulateMsgCloseGroup(ak govtypes.AccountKeeper, bk bankkeeper.Keeper, k ke }) if len(deployments) == 0 { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseGroup, "no deployments found"), nil, nil + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCloseGroup{}).Type(), "no deployments found"), nil, nil } // Get random deployment deployment := deployments[testsim.RandIdx(r, len(deployments)-1)] - owner, convertErr := sdk.AccAddressFromBech32(deployment.ID().Owner) + owner, convertErr := sdk.AccAddressFromBech32(deployment.ID.Owner) if convertErr != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseGroup, "error while converting address"), nil, convertErr + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCloseGroup{}).Type(), "error while converting address"), nil, convertErr } simAccount, found := simtypes.FindAccount(accounts, owner) if !found { - err := fmt.Errorf("deployment with %s not found", deployment.ID().Owner) - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseGroup, err.Error()), nil, err + err := fmt.Errorf("deployment with %s not found", deployment.ID.Owner) + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCloseGroup{}).Type(), err.Error()), nil, err } account := ak.GetAccount(ctx, simAccount.Address) @@ -347,48 +356,49 @@ func SimulateMsgCloseGroup(ak govtypes.AccountKeeper, bk bankkeeper.Keeper, k ke fees, err := simtypes.RandomFees(r, ctx, spendable) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseGroup, "unable to generate fees"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCloseGroup{}).Type(), "unable to generate fees"), nil, err } // Select Group to close - groups := k.GetGroups(ctx, deployment.ID()) + groups := k.GetGroups(ctx, deployment.ID) if len(groups) < 1 { // No groups to close - err := fmt.Errorf("no groups for deployment ID: %v", deployment.ID()) - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseGroup, err.Error()), nil, err + err := fmt.Errorf("no groups for deployment ID: %v", deployment.ID) + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCloseGroup{}).Type(), err.Error()), nil, err } group := groups[testsim.RandIdx(r, len(groups)-1)] - if group.State == types.GroupClosed { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseGroup, "group already closed"), nil, nil + if group.State == v1beta4.GroupClosed { + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCloseGroup{}).Type(), "group already closed"), nil, nil } - msg := types.NewMsgCloseGroup(group.ID()) + msg := v1beta4.NewMsgCloseGroup(group.ID) err = msg.ValidateBasic() if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseGroup, "msg validation failure"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, (&v1beta4.MsgCloseGroup{}).Type(), "msg validation failure"), nil, err } - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( + txGen := sdkutil.MakeEncodingConfig().TxConfig + tx, err := simtestutil.GenSignedMockTx( + r, txGen, []sdk.Msg{msg}, fees, - helpers.DefaultGenTxGas, + simtestutil.DefaultGenTxGas, chainID, []uint64{account.GetAccountNumber()}, []uint64{account.GetSequence()}, simAccount.PrivKey, ) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "close group - unable to generate mock tx"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, msg.Type(), "close group - unable to generate mock tx"), nil, err } - _, _, err = app.Deliver(txGen.TxEncoder(), tx) + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) if err != nil { - err = fmt.Errorf("%w: %s: msg delivery error closing group: %v", err, types.ModuleName, group.ID()) - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), err.Error()), nil, err + err = fmt.Errorf("%w: %s: msg delivery error closing group: %v", err, v1.ModuleName, group.ID) + return simtypes.NoOpMsg(v1.ModuleName, msg.Type(), err.Error()), nil, err } - return simtypes.NewOperationMsg(msg, true, "submitting MsgCloseGroup", nil), nil, nil + return simtypes.NewOperationMsg(msg, true, "submitting MsgCloseGroup"), nil, nil } } diff --git a/x/deployment/simulation/proposals.go b/x/deployment/simulation/proposals.go new file mode 100644 index 0000000000..3d83567a5a --- /dev/null +++ b/x/deployment/simulation/proposals.go @@ -0,0 +1,57 @@ +package simulation + +import ( + "math/rand" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/simulation" + + types "pkg.akt.dev/go/node/deployment/v1beta4" +) + +// Simulation operation weights constants +const ( + DefaultWeightMsgUpdateParams int = 100 + + OpWeightMsgUpdateParams = "op_weight_msg_update_params" //nolint:gosec +) + +// ProposalMsgs defines the module weighted proposals' contents +func ProposalMsgs() []simtypes.WeightedProposalMsg { + return []simtypes.WeightedProposalMsg{ + simulation.NewWeightedProposalMsg( + OpWeightMsgUpdateParams, + DefaultWeightMsgUpdateParams, + SimulateMsgUpdateParams, + ), + } +} + +func SimulateMsgUpdateParams(r *rand.Rand, _ sdk.Context, _ []simtypes.Account) sdk.Msg { + // use the default gov module account address as authority + var authority sdk.AccAddress = address.Module("gov") + + coins := simtypes.RandSubsetCoins(r, sdk.Coins{ + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D84", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D85", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D86", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D87", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D88", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D89", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D8A", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D8B", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + }) + + // uakt must always be present + coins = append(coins, sdk.NewInt64Coin("uakt", int64(simtypes.RandIntBetween(r, 500000, 50000000)))) + + params := types.DefaultParams() + params.MinDeposits = coins + + return &types.MsgUpdateParams{ + Authority: authority.String(), + Params: params, + } +} diff --git a/x/escrow/alias.go b/x/escrow/alias.go index 0191c57dcf..7cedba7cf5 100644 --- a/x/escrow/alias.go +++ b/x/escrow/alias.go @@ -1,12 +1,12 @@ package escrow import ( - types "github.com/akash-network/akash-api/go/node/escrow/v1beta3" + "pkg.akt.dev/go/node/escrow/module" ) const ( // StoreKey represents storekey of deployment module - StoreKey = types.StoreKey + StoreKey = module.StoreKey // ModuleName represents current module name - ModuleName = types.ModuleName + ModuleName = module.ModuleName ) diff --git a/x/escrow/client/cli/query.go b/x/escrow/client/cli/query.go deleted file mode 100644 index 915afc1c7f..0000000000 --- a/x/escrow/client/cli/query.go +++ /dev/null @@ -1,142 +0,0 @@ -package cli - -import ( - "encoding/json" - "errors" - "time" - - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/spf13/cobra" - "gopkg.in/yaml.v3" - - deploymentTypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/escrow/v1beta3" - - marketTypes "github.com/akash-network/akash-api/go/node/market/v1beta4" - - aclient "github.com/akash-network/node/client" - netutil "github.com/akash-network/node/util/network" - "github.com/akash-network/node/x/deployment/client/cli" - "github.com/akash-network/node/x/escrow/client/util" -) - -func GetQueryCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: "Escrow query commands", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - - cmd.AddCommand( - cmdBlocksRemaining(), - ) - - return cmd -} - -var errNoLeaseMatches = errors.New("leases for deployment do not exist") - -func cmdBlocksRemaining() *cobra.Command { - cmd := &cobra.Command{ - Use: "blocks-remaining", - Short: "Compute the number of blocks remaining for an ecrow account", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientQueryContext(cmd) - if err != nil { - return err - } - - qq, err := aclient.DiscoverQueryClient(ctx, cctx) - if err != nil { - return err - } - - id, err := cli.DeploymentIDFromFlags(cmd.Flags()) - if err != nil { - return err - } - - // Fetch leases matching owner & dseq - leaseRequest := marketTypes.QueryLeasesRequest{ - Filters: marketTypes.LeaseFilters{ - Owner: id.Owner, - DSeq: id.DSeq, - GSeq: 0, - OSeq: 0, - Provider: "", - State: "active", - }, - Pagination: nil, - } - - leasesResponse, err := qq.Leases(cmd.Context(), &leaseRequest) - if err != nil { - return err - } - - if len(leasesResponse.Leases) == 0 { - return errNoLeaseMatches - } - - // Fetch the balance of the escrow account - totalLeaseAmount := leasesResponse.TotalPriceAmount() - blockchainHeight, err := cli.CurrentBlockHeight(qq.ClientContext()) - if err != nil { - return err - } - - res, err := qq.Deployment(cmd.Context(), &deploymentTypes.QueryDeploymentRequest{ - ID: deploymentTypes.DeploymentID{Owner: id.Owner, DSeq: id.DSeq}, - }) - if err != nil { - return err - } - - balanceRemain := util.LeaseCalcBalanceRemain(res.EscrowAccount.TotalBalance().Amount, - int64(blockchainHeight), - res.EscrowAccount.SettledAt, - totalLeaseAmount) - - blocksRemain := util.LeaseCalcBlocksRemain(balanceRemain, totalLeaseAmount) - - output := struct { - BalanceRemain float64 `json:"balance_remaining" yaml:"balance_remaining"` - BlocksRemain int64 `json:"blocks_remaining" yaml:"blocks_remaining"` - EstimatedTimeRemain time.Duration `json:"estimated_time_remaining" yaml:"estimated_time_remaining"` - }{ - BalanceRemain: balanceRemain, - BlocksRemain: blocksRemain, - EstimatedTimeRemain: netutil.AverageBlockTime * time.Duration(blocksRemain), - } - - outputType, err := cmd.Flags().GetString("output") - if err != nil { - return err - } - - var data []byte - if outputType == "json" { - data, err = json.MarshalIndent(output, " ", "\t") - } else { - data, err = yaml.Marshal(output) - } - - if err != nil { - return err - } - - return qq.ClientContext().PrintBytes(data) - - }, - } - - flags.AddQueryFlagsToCmd(cmd) - cli.AddDeploymentIDFlags(cmd.Flags()) - cli.MarkReqDeploymentIDFlags(cmd) - return cmd -} diff --git a/x/escrow/client/cli/tx.go b/x/escrow/client/cli/tx.go deleted file mode 100644 index 6fd92889b2..0000000000 --- a/x/escrow/client/cli/tx.go +++ /dev/null @@ -1,7 +0,0 @@ -package cli - -import "github.com/spf13/cobra" - -func GetTxCmd() *cobra.Command { - return nil -} diff --git a/x/escrow/client/rest/rest.go b/x/escrow/client/rest/rest.go index 0fe9350432..79c2b1605a 100644 --- a/x/escrow/client/rest/rest.go +++ b/x/escrow/client/rest/rest.go @@ -5,5 +5,5 @@ import ( "github.com/gorilla/mux" ) -func RegisterRoutes(ctx client.Context, r *mux.Router, ns string) { +func RegisterRoutes(_ client.Context, _ *mux.Router, _ string) { } diff --git a/x/escrow/client/util/util.go b/x/escrow/client/util/util.go index 3bac5f66d5..5c398d1403 100644 --- a/x/escrow/client/util/util.go +++ b/x/escrow/client/util/util.go @@ -1,13 +1,15 @@ +//nolint: revive + package util import ( - sdk "github.com/cosmos/cosmos-sdk/types" + sdkmath "cosmossdk.io/math" ) -func LeaseCalcBalanceRemain(balance sdk.Dec, currBlock, settledAt int64, leasePrice sdk.Dec) float64 { +func LeaseCalcBalanceRemain(balance sdkmath.LegacyDec, currBlock, settledAt int64, leasePrice sdkmath.LegacyDec) float64 { return balance.MustFloat64() - (float64(currBlock-settledAt))*leasePrice.MustFloat64() } -func LeaseCalcBlocksRemain(balance float64, leasePrice sdk.Dec) int64 { +func LeaseCalcBlocksRemain(balance float64, leasePrice sdkmath.LegacyDec) int64 { return int64(balance / leasePrice.MustFloat64()) } diff --git a/x/escrow/genesis.go b/x/escrow/genesis.go index 93cdfc57ba..4e276d6c4e 100644 --- a/x/escrow/genesis.go +++ b/x/escrow/genesis.go @@ -6,86 +6,87 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/akash-network/node/x/escrow/keeper" + eid "pkg.akt.dev/go/node/escrow/id/v1" + emodule "pkg.akt.dev/go/node/escrow/module" + etypes "pkg.akt.dev/go/node/escrow/types/v1" - types "github.com/akash-network/akash-api/go/node/escrow/v1beta3" + "pkg.akt.dev/node/x/escrow/keeper" + + types "pkg.akt.dev/go/node/escrow/v1" ) -// ValidateGenesis does validation check of the Genesis and returns error in case of failure +// ValidateGenesis does validation check of the Genesis and returns an error in case of failure func ValidateGenesis(data *types.GenesisState) error { - amap := make(map[types.AccountID]types.Account, len(data.Accounts)) - pmap := make(map[types.AccountID][]types.FractionalPayment, len(data.Payments)) + amap := make(map[eid.Account]etypes.Account, len(data.Accounts)) + pmap := make(map[eid.Payment]etypes.Payment, len(data.Payments)) for idx, account := range data.Accounts { if err := account.ValidateBasic(); err != nil { return fmt.Errorf("%w: error with account %s (idx %v)", err, account.ID, idx) } if _, found := amap[account.ID]; found { - return fmt.Errorf("%w: duplicate account %s (idx %v)", types.ErrAccountExists, account.ID, idx) + return fmt.Errorf("%w: duplicate account %s (idx %v)", emodule.ErrAccountExists, account.ID, idx) } amap[account.ID] = account } for idx, payment := range data.Payments { if err := payment.ValidateBasic(); err != nil { - return fmt.Errorf("%w: error with payment %s %s (idx %v)", err, payment.AccountID, payment.PaymentID, idx) + return fmt.Errorf("%w: error with payment %s (idx %v)", err, payment.ID, idx) } // make sure there's an account - account, found := amap[payment.AccountID] + account, found := amap[payment.ID.Account()] if !found { return fmt.Errorf( - "%w: no account for payment %s %s (idx %v)", types.ErrAccountNotFound, payment.AccountID, payment.PaymentID, idx) + "%w: no account %s for payment %s (idx %v)", emodule.ErrAccountNotFound, payment.ID.Account(), payment.ID, idx) } - // ensure state is in sync with payment + // ensure the state is in sync with payment switch { - case payment.State == types.PaymentOpen && account.State != types.AccountOpen: - return fmt.Errorf("%w: invalid payment statefor payment %s %s (idx %v)", - types.ErrInvalidPayment, payment.AccountID, payment.PaymentID, idx) - case payment.State == types.PaymentOverdrawn && account.State != types.AccountOverdrawn: - return fmt.Errorf("%w: invalid payment statefor payment %s %s (idx %v)", - types.ErrInvalidPayment, payment.AccountID, payment.PaymentID, idx) + case payment.State.State == etypes.StateOpen && account.State.State != etypes.StateOpen: + return fmt.Errorf("%w: invalid payment state for payment %s (idx %v)", + emodule.ErrInvalidPayment, payment.ID, idx) + case payment.State.State == etypes.StateOverdrawn && account.State.State != etypes.StateOverdrawn: + return fmt.Errorf("%w: invalid payment statefor payment %s (idx %v)", + emodule.ErrInvalidPayment, payment.ID, idx) } // check for duplicates - for _, p2 := range pmap[payment.AccountID] { - if p2.PaymentID == payment.PaymentID { - return fmt.Errorf( - "%w, dupliate payment for %s %s (idx %v)", types.ErrPaymentExists, payment.AccountID, payment.PaymentID, idx) - } + if _, exists := pmap[payment.ID]; exists { + return fmt.Errorf("%w, dupliate payment for %s (idx %v)", emodule.ErrPaymentExists, payment.ID, idx) } - pmap[payment.AccountID] = append(pmap[payment.AccountID], payment) + pmap[payment.ID] = payment } return nil } // InitGenesis initiate genesis state and return updated validator details -func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, data *types.GenesisState) []abci.ValidatorUpdate { +func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, data *types.GenesisState) { for idx := range data.Accounts { - keeper.SaveAccount(ctx, data.Accounts[idx]) + err := keeper.SaveAccount(ctx, data.Accounts[idx]) + if err != nil { + panic(fmt.Sprintf("error saving account: %s", err.Error())) + } } for idx := range data.Payments { keeper.SavePayment(ctx, data.Payments[idx]) } - - return []abci.ValidatorUpdate{} } // ExportGenesis returns genesis state as raw bytes for the provider module func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { state := &types.GenesisState{} - k.WithAccounts(ctx, func(obj types.Account) bool { + k.WithAccounts(ctx, func(obj etypes.Account) bool { state.Accounts = append(state.Accounts, obj) return false }) - k.WithPayments(ctx, func(obj types.FractionalPayment) bool { + k.WithPayments(ctx, func(obj etypes.Payment) bool { state.Payments = append(state.Payments, obj) return false }) diff --git a/x/escrow/handler/handler.go b/x/escrow/handler/handler.go new file mode 100644 index 0000000000..a4a227418d --- /dev/null +++ b/x/escrow/handler/handler.go @@ -0,0 +1,25 @@ +package handler + +import ( + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + types "pkg.akt.dev/go/node/escrow/v1" + + "pkg.akt.dev/node/x/escrow/keeper" +) + +// NewHandler returns a handler for "deployment" type messages +func NewHandler(keeper keeper.Keeper, authzKeeper AuthzKeeper, bkeeper BankKeeper) baseapp.MsgServiceHandler { + ms := NewServer(keeper, authzKeeper, bkeeper) + + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { + switch msg := msg.(type) { + case *types.MsgAccountDeposit: + res, err := ms.AccountDeposit(ctx, msg) + return sdk.WrapServiceResult(ctx, res, err) + default: + return nil, sdkerrors.ErrUnknownRequest + } + } +} diff --git a/x/escrow/handler/keepers.go b/x/escrow/handler/keepers.go new file mode 100644 index 0000000000..1f7f1ab65c --- /dev/null +++ b/x/escrow/handler/keepers.go @@ -0,0 +1,21 @@ +package handler + +import ( + "context" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/authz" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" +) + +type AuthzKeeper interface { + DeleteGrant(ctx context.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) error + GetAuthorization(ctx context.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) (authz.Authorization, *time.Time) + SaveGrant(ctx context.Context, grantee sdk.AccAddress, granter sdk.AccAddress, authorization authz.Authorization, expiration *time.Time) error + GetGranteeGrantsByMsgType(ctx context.Context, grantee sdk.AccAddress, msgType string, onGrant authzkeeper.OnGrantFn) +} + +type BankKeeper interface { + SpendableCoin(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin +} diff --git a/x/escrow/handler/server.go b/x/escrow/handler/server.go new file mode 100644 index 0000000000..d86e52bdfd --- /dev/null +++ b/x/escrow/handler/server.go @@ -0,0 +1,43 @@ +package handler + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + types "pkg.akt.dev/go/node/escrow/v1" + + "pkg.akt.dev/node/x/escrow/keeper" +) + +var _ types.MsgServer = msgServer{} + +type msgServer struct { + keeper keeper.Keeper + authzKeeper AuthzKeeper + bkeeper BankKeeper +} + +// NewServer returns an implementation of the deployment MsgServer interface +// for the provided Keeper. +func NewServer(k keeper.Keeper, authzKeeper AuthzKeeper, bkeeper BankKeeper) types.MsgServer { + return &msgServer{ + keeper: k, + authzKeeper: authzKeeper, + bkeeper: bkeeper, + } +} + +func (ms msgServer) AccountDeposit(goCtx context.Context, msg *types.MsgAccountDeposit) (*types.MsgAccountDepositResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + deposits, err := ms.keeper.AuthorizeDeposits(ctx, msg) + if err != nil { + return &types.MsgAccountDepositResponse{}, err + } + + if err := ms.keeper.AccountDeposit(ctx, msg.ID, deposits); err != nil { + return &types.MsgAccountDepositResponse{}, err + } + + return &types.MsgAccountDepositResponse{}, nil +} diff --git a/x/escrow/keeper/external.go b/x/escrow/keeper/external.go index d4fef815b1..38f45e5e87 100644 --- a/x/escrow/keeper/external.go +++ b/x/escrow/keeper/external.go @@ -1,30 +1,30 @@ package keeper import ( + "context" "time" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/authz" - distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" ) type BankKeeper interface { - SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error - SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error - SendCoinsFromModuleToModule(ctx sdk.Context, senderModule string, recipientModule string, amt sdk.Coins) error + SpendableCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins + SpendableCoin(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin + SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt sdk.Coins) error + SendCoinsFromAccountToModule(ctx context.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error } type TakeKeeper interface { SubtractFees(ctx sdk.Context, amt sdk.Coin) (sdk.Coin, sdk.Coin, error) } -type DistrKeeper interface { - GetFeePool(ctx sdk.Context) distrtypes.FeePool - SetFeePool(ctx sdk.Context, pool distrtypes.FeePool) -} - type AuthzKeeper interface { - DeleteGrant(ctx sdk.Context, grantee, granter sdk.AccAddress, msgType string) error - GetCleanAuthorization(ctx sdk.Context, grantee, granter sdk.AccAddress, msgType string) (cap authz.Authorization, expiration time.Time) - SaveGrant(ctx sdk.Context, grantee, granter sdk.AccAddress, authorization authz.Authorization, expiration time.Time) error + DeleteGrant(ctx context.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) error + GetAuthorization(ctx context.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) (authz.Authorization, *time.Time) + SaveGrant(ctx context.Context, grantee sdk.AccAddress, granter sdk.AccAddress, authorization authz.Authorization, expiration *time.Time) error + IterateGrants(ctx context.Context, handler func(granterAddr sdk.AccAddress, granteeAddr sdk.AccAddress, grant authz.Grant) bool) + GetGranteeGrantsByMsgType(ctx context.Context, grantee sdk.AccAddress, msgType string, onGrant authzkeeper.OnGrantFn) } diff --git a/x/escrow/keeper/grpc_query.go b/x/escrow/keeper/grpc_query.go new file mode 100644 index 0000000000..92233f491f --- /dev/null +++ b/x/escrow/keeper/grpc_query.go @@ -0,0 +1,264 @@ +package keeper + +import ( + "bytes" + "context" + + "cosmossdk.io/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkquery "github.com/cosmos/cosmos-sdk/types/query" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + types "pkg.akt.dev/go/node/escrow/types/v1" + "pkg.akt.dev/go/node/escrow/v1" + + "pkg.akt.dev/node/util/query" +) + +// Querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over keeper +type Querier struct { + *keeper +} + +var _ v1.QueryServer = Querier{} + +func (k Querier) Accounts(c context.Context, req *v1.QueryAccountsRequest) (*v1.QueryAccountsResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + if req.Pagination == nil { + req.Pagination = &sdkquery.PageRequest{} + } + + if req.Pagination.Limit == 0 { + req.Pagination.Limit = sdkquery.DefaultLimit + } + + states := make([]byte, 0, 3) + + var searchPrefix []byte + + // setup for case 3 - cross-index search + // nolint: gocritic + if len(req.Pagination.Key) > 0 { + var key []byte + var err error + states, searchPrefix, key, _, err = query.DecodePaginationKey(req.Pagination.Key) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + req.Pagination.Key = key + } else if req.State != "" { + stateVal := types.State(types.State_value[req.State]) + + if req.State != "" && stateVal == types.StateInvalid { + return nil, status.Error(codes.InvalidArgument, "invalid state value") + } + + states = append(states, byte(stateVal)) + } else { + // request does not have a pagination set. Start from active store + states = append(states, []byte{byte(types.StateOpen), byte(types.StateClosed), byte(types.StateOverdrawn)}...) + } + + var accounts types.Accounts + var pageRes *sdkquery.PageResponse + + total := uint64(0) + + for idx := range states { + state := types.State(states[idx]) + + var err error + if idx > 0 { + req.Pagination.Key = nil + } + + if len(req.Pagination.Key) == 0 { + req.State = state.String() + + searchPrefix = buildSearchPrefix(AccountPrefix, req.State, req.XID) + } + + searchStore := prefix.NewStore(ctx.KVStore(k.skey), searchPrefix) + + count := uint64(0) + + pageRes, err = sdkquery.FilteredPaginate(searchStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) { + id, _ := ParseAccountKey(append(searchPrefix, key...)) + acc := types.Account{ + ID: id, + } + + er := k.cdc.Unmarshal(value, &acc.State) + if er != nil { + return false, er + } + + accounts = append(accounts, acc) + count++ + + return false, nil + }) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + req.Pagination.Limit -= count + total += count + + if req.Pagination.Limit == 0 { + if len(pageRes.NextKey) > 0 { + pageRes.NextKey, err = query.EncodePaginationKey(states[idx:], searchPrefix, pageRes.NextKey, nil) + if err != nil { + pageRes.Total = total + return &v1.QueryAccountsResponse{ + Accounts: accounts, + Pagination: pageRes, + }, status.Error(codes.Internal, err.Error()) + } + } + + break + } + } + + pageRes.Total = total + + return &v1.QueryAccountsResponse{ + Accounts: accounts, + Pagination: pageRes, + }, nil +} + +func (k Querier) Payments(c context.Context, req *v1.QueryPaymentsRequest) (*v1.QueryPaymentsResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + if req.Pagination == nil { + req.Pagination = &sdkquery.PageRequest{} + } + + if req.Pagination.Limit == 0 { + req.Pagination.Limit = sdkquery.DefaultLimit + } + + states := make([]byte, 0, 3) + + var searchPrefix []byte + + // setup for case 3 - cross-index search + // nolint: gocritic + if len(req.Pagination.Key) > 0 { + var key []byte + var err error + states, searchPrefix, key, _, err = query.DecodePaginationKey(req.Pagination.Key) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + req.Pagination.Key = key + } else if req.State != "" { + stateVal := types.State(types.State_value[req.State]) + + if req.State != "" && stateVal == types.StateInvalid { + return nil, status.Error(codes.InvalidArgument, "invalid state value") + } + + states = append(states, byte(stateVal)) + } else { + // request does not have a pagination set. Start from active store + states = append(states, []byte{byte(types.StateOpen), byte(types.StateClosed), byte(types.StateOverdrawn)}...) + } + + var payments types.Payments + var pageRes *sdkquery.PageResponse + + total := uint64(0) + + for idx := range states { + state := types.State(states[idx]) + + var err error + if idx > 0 { + req.Pagination.Key = nil + } + + if len(req.Pagination.Key) == 0 { + req.State = state.String() + + searchPrefix = buildSearchPrefix(PaymentPrefix, req.State, req.XID) + } + + searchStore := prefix.NewStore(ctx.KVStore(k.skey), searchPrefix) + + count := uint64(0) + + pageRes, err = sdkquery.FilteredPaginate(searchStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) { + id, _ := ParsePaymentKey(append(searchPrefix, key...)) + pmnt := types.Payment{ + ID: id, + } + + er := k.cdc.Unmarshal(value, &pmnt.State) + if er != nil { + return false, er + } + + payments = append(payments, pmnt) + count++ + + return false, nil + }) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + req.Pagination.Limit -= count + total += count + + if req.Pagination.Limit == 0 { + if len(pageRes.NextKey) > 0 { + pageRes.NextKey, err = query.EncodePaginationKey(states[idx:], searchPrefix, pageRes.NextKey, nil) + if err != nil { + pageRes.Total = total + return &v1.QueryPaymentsResponse{ + Payments: payments, + Pagination: pageRes, + }, status.Error(codes.Internal, err.Error()) + } + } + + break + } + } + + pageRes.Total = total + + return &v1.QueryPaymentsResponse{ + Payments: payments, + Pagination: pageRes, + }, nil +} + +func buildSearchPrefix(prefix []byte, state string, xid string) []byte { + buf := &bytes.Buffer{} + + buf.Write(prefix) + if state != "" { + st := types.State(types.State_value[state]) + buf.Write(stateToPrefix(st)) + if xid != "" { + buf.WriteRune('/') + buf.WriteString(xid) + } + } + + return buf.Bytes() +} diff --git a/x/escrow/keeper/grpc_query_test.go b/x/escrow/keeper/grpc_query_test.go new file mode 100644 index 0000000000..b2b2e8ed4f --- /dev/null +++ b/x/escrow/keeper/grpc_query_test.go @@ -0,0 +1,299 @@ +package keeper_test + +import ( + "fmt" + "testing" + + sdkmath "cosmossdk.io/math" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + + dv1 "pkg.akt.dev/go/node/deployment/v1" + "pkg.akt.dev/go/node/deployment/v1beta4" + eid "pkg.akt.dev/go/node/escrow/id/v1" + types "pkg.akt.dev/go/node/escrow/types/v1" + "pkg.akt.dev/go/node/escrow/v1" + mv1 "pkg.akt.dev/go/node/market/v1" + deposit "pkg.akt.dev/go/node/types/deposit/v1" + "pkg.akt.dev/go/testutil" + + "pkg.akt.dev/node/app" + "pkg.akt.dev/node/testutil/state" + ekeeper "pkg.akt.dev/node/x/escrow/keeper" +) + +type grpcTestSuite struct { + t *testing.T + app *app.AkashApp + ctx sdk.Context + keeper ekeeper.Keeper + authzKeeper ekeeper.AuthzKeeper + bankKeeper ekeeper.BankKeeper + + queryClient v1.QueryClient +} + +func setupTest(t *testing.T) *grpcTestSuite { + ssuite := state.SetupTestSuite(t) + suite := &grpcTestSuite{ + t: t, + app: ssuite.App(), + ctx: ssuite.Context(), + keeper: ssuite.EscrowKeeper(), + authzKeeper: ssuite.AuthzKeeper(), + bankKeeper: ssuite.BankKeeper(), + } + + querier := suite.keeper.NewQuerier() + + queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.app.InterfaceRegistry()) + v1.RegisterQueryServer(queryHelper, querier) + suite.queryClient = v1.NewQueryClient(queryHelper) + + return suite +} + +func TestGRPCQueryAccounts(t *testing.T) { + suite := setupTest(t) + + did1 := testutil.DeploymentID(t) + eid1 := suite.createEscrowAccount(did1) + + expAccounts1 := types.Accounts{ + { + ID: eid1, + State: types.AccountState{ + Owner: did1.Owner, + State: types.StateOpen, + Transferred: sdk.DecCoins{ + sdk.NewDecCoin("uakt", sdkmath.ZeroInt()), + }, + SettledAt: 0, + Funds: []types.Balance{ + { + Denom: "uakt", + Amount: sdkmath.LegacyNewDec(500000), + }, + }, + Deposits: []types.Depositor{ + { + Owner: did1.Owner, + Height: 0, + Source: deposit.SourceBalance, + Balance: sdk.NewDecCoin("uakt", sdkmath.NewInt(500000)), + }, + }, + }, + }, + } + + testCases := []struct { + msg string + req *v1.QueryAccountsRequest + expResp v1.QueryAccountsResponse + expPass bool + }{ + { + "empty request", + &v1.QueryAccountsRequest{}, + v1.QueryAccountsResponse{ + Accounts: expAccounts1, + }, + true, + }, + { + "no closed accounts", + &v1.QueryAccountsRequest{State: "closed"}, + v1.QueryAccountsResponse{}, + true, + }, + { + "no overdrawn accounts", + &v1.QueryAccountsRequest{State: "overdrawn"}, + v1.QueryAccountsResponse{}, + true, + }, + { + "invalid state", + &v1.QueryAccountsRequest{State: "inv"}, + v1.QueryAccountsResponse{}, + false, + }, + { + "account with full XID", + &v1.QueryAccountsRequest{State: "open", XID: fmt.Sprintf("deployment/%s", did1.Owner)}, + v1.QueryAccountsResponse{ + Accounts: expAccounts1, + }, + true, + }, + { + "account with full XID", + &v1.QueryAccountsRequest{State: "open", XID: fmt.Sprintf("deployment/%s/%d", did1.Owner, did1.DSeq)}, + v1.QueryAccountsResponse{ + Accounts: expAccounts1, + }, + true, + }, + { + "account not found", + &v1.QueryAccountsRequest{State: "open", XID: fmt.Sprintf("deployment/%s/%d", did1.Owner, did1.DSeq+1)}, + v1.QueryAccountsResponse{}, + true, + }, + } + + for _, tc := range testCases { + t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { + ctx := suite.ctx + + res, err := suite.queryClient.Accounts(ctx, tc.req) + + if tc.expPass { + require.NoError(t, err) + require.NotNil(t, res) + require.Equal(t, tc.expResp.Accounts, res.Accounts) + } else { + require.Error(t, err) + require.Nil(t, res) + } + + }) + } +} + +func TestGRPCQueryPayments(t *testing.T) { + suite := setupTest(t) + + lid1 := testutil.LeaseID(t) + did1 := lid1.DeploymentID() + + _ = suite.createEscrowAccount(did1) + pid1 := suite.createEscrowPayment(lid1, sdk.NewDecCoin("uakt", sdkmath.NewInt(1))) + + expPayments1 := types.Payments{ + { + ID: pid1, + State: types.PaymentState{ + Owner: lid1.Provider, + State: types.StateOpen, + Rate: sdk.NewDecCoin("uakt", sdkmath.NewInt(1)), + Balance: sdk.NewDecCoin("uakt", sdkmath.NewInt(0)), + Unsettled: sdk.NewDecCoin("uakt", sdkmath.ZeroInt()), + Withdrawn: sdk.NewCoin("uakt", sdkmath.NewInt(0)), + }, + }, + } + + testCases := []struct { + msg string + req *v1.QueryPaymentsRequest + expResp v1.QueryPaymentsResponse + expPass bool + }{ + { + "empty request", + &v1.QueryPaymentsRequest{}, + v1.QueryPaymentsResponse{ + Payments: expPayments1, + }, + true, + }, + { + "no closed accounts", + &v1.QueryPaymentsRequest{State: "closed"}, + v1.QueryPaymentsResponse{}, + true, + }, + { + "no overdrawn accounts", + &v1.QueryPaymentsRequest{State: "overdrawn"}, + v1.QueryPaymentsResponse{}, + true, + }, + { + "invalid state", + &v1.QueryPaymentsRequest{State: "inv"}, + v1.QueryPaymentsResponse{}, + false, + }, + { + "account with full XID", + &v1.QueryPaymentsRequest{State: "open", XID: fmt.Sprintf("deployment/%s", lid1.Owner)}, + v1.QueryPaymentsResponse{ + Payments: expPayments1, + }, + true, + }, + { + "account with full XID", + &v1.QueryPaymentsRequest{State: "open", XID: fmt.Sprintf("deployment/%s/%d", lid1.Owner, lid1.DSeq)}, + v1.QueryPaymentsResponse{ + Payments: expPayments1, + }, + true, + }, + { + "account not found", + &v1.QueryPaymentsRequest{State: "open", XID: fmt.Sprintf("deployment/%s/%d", lid1.Owner, lid1.DSeq+1)}, + v1.QueryPaymentsResponse{}, + true, + }, + } + + for _, tc := range testCases { + t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { + ctx := suite.ctx + + res, err := suite.queryClient.Payments(ctx, tc.req) + + if tc.expPass { + require.NoError(t, err) + require.NotNil(t, res) + require.Equal(t, tc.expResp.Payments, res.Payments) + } else { + require.Error(t, err) + require.Nil(t, res) + } + + }) + } +} + +func (suite *grpcTestSuite) createEscrowAccount(id dv1.DeploymentID) eid.Account { + owner, err := sdk.AccAddressFromBech32(id.Owner) + require.NoError(suite.t, err) + + aid := id.ToEscrowAccountID() + defaultDeposit, err := v1beta4.DefaultParams().MinDepositFor("uakt") + require.NoError(suite.t, err) + + msg := &v1beta4.MsgCreateDeployment{ + ID: id, + Deposit: deposit.Deposit{ + Amount: defaultDeposit, + Sources: deposit.Sources{deposit.SourceBalance}, + }} + + deposits, err := suite.keeper.AuthorizeDeposits(suite.ctx, msg) + require.NoError(suite.t, err) + + err = suite.keeper.AccountCreate(suite.ctx, aid, owner, deposits) + require.NoError(suite.t, err) + + return aid +} + +func (suite *grpcTestSuite) createEscrowPayment(id mv1.LeaseID, rate sdk.DecCoin) eid.Payment { + owner, err := sdk.AccAddressFromBech32(id.Provider) + require.NoError(suite.t, err) + + pid := id.ToEscrowPaymentID() + + err = suite.keeper.PaymentCreate(suite.ctx, pid, owner, rate) + require.NoError(suite.t, err) + + return pid +} diff --git a/x/escrow/keeper/keeper.go b/x/escrow/keeper/keeper.go index a521c11af8..6321f7b692 100644 --- a/x/escrow/keeper/keeper.go +++ b/x/escrow/keeper/keeper.go @@ -1,315 +1,579 @@ package keeper import ( + "context" "fmt" + "reflect" + "time" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/escrow/v1beta3" + "cosmossdk.io/collections" + sdkmath "cosmossdk.io/math" + storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/authz" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + dv1beta "pkg.akt.dev/go/node/deployment/v1beta4" + mv1beta "pkg.akt.dev/go/node/market/v1beta5" + + escrowid "pkg.akt.dev/go/node/escrow/id/v1" + "pkg.akt.dev/go/node/escrow/module" + etypes "pkg.akt.dev/go/node/escrow/types/v1" + ev1 "pkg.akt.dev/go/node/escrow/v1" + types "pkg.akt.dev/go/node/market/v1" + deposit "pkg.akt.dev/go/node/types/deposit/v1" ) -type AccountHook func(sdk.Context, types.Account) -type PaymentHook func(sdk.Context, types.FractionalPayment) +type AccountHook func(sdk.Context, etypes.Account) +type PaymentHook func(sdk.Context, etypes.Payment) type Keeper interface { Codec() codec.BinaryCodec - StoreKey() sdk.StoreKey - AccountCreate(ctx sdk.Context, id types.AccountID, owner, depositor sdk.AccAddress, deposit sdk.Coin) error - AccountDeposit(ctx sdk.Context, id types.AccountID, depositor sdk.AccAddress, amount sdk.Coin) error - AccountSettle(ctx sdk.Context, id types.AccountID) (bool, error) - AccountClose(ctx sdk.Context, id types.AccountID) error - PaymentCreate(ctx sdk.Context, id types.AccountID, pid string, owner sdk.AccAddress, rate sdk.DecCoin) error - PaymentWithdraw(ctx sdk.Context, id types.AccountID, pid string) error - PaymentClose(ctx sdk.Context, id types.AccountID, pid string) error - GetAccount(ctx sdk.Context, id types.AccountID) (types.Account, error) - GetPayment(ctx sdk.Context, id types.AccountID, pid string) (types.FractionalPayment, error) + StoreKey() storetypes.StoreKey + AuthorizeDeposits(sctx sdk.Context, msg sdk.Msg) ([]etypes.Depositor, error) + AccountCreate(ctx sdk.Context, id escrowid.Account, owner sdk.AccAddress, deposits []etypes.Depositor) error + AccountDeposit(ctx sdk.Context, id escrowid.Account, deposits []etypes.Depositor) error + AccountSettle(ctx sdk.Context, id escrowid.Account) (bool, error) + AccountClose(ctx sdk.Context, id escrowid.Account) error + PaymentCreate(ctx sdk.Context, id escrowid.Payment, owner sdk.AccAddress, rate sdk.DecCoin) error + PaymentWithdraw(ctx sdk.Context, id escrowid.Payment) error + PaymentClose(ctx sdk.Context, id escrowid.Payment) error + GetAccount(ctx sdk.Context, id escrowid.Account) (etypes.Account, error) + GetPayment(ctx sdk.Context, id escrowid.Payment) (etypes.Payment, error) AddOnAccountClosedHook(AccountHook) Keeper AddOnPaymentClosedHook(PaymentHook) Keeper - WithAccounts(sdk.Context, func(types.Account) bool) - WithPayments(sdk.Context, func(types.FractionalPayment) bool) - SaveAccount(sdk.Context, types.Account) - SavePayment(sdk.Context, types.FractionalPayment) + WithAccounts(sdk.Context, func(etypes.Account) bool) + WithPayments(sdk.Context, func(etypes.Payment) bool) + SaveAccount(sdk.Context, etypes.Account) error + SavePayment(sdk.Context, etypes.Payment) + NewQuerier() Querier } -func NewKeeper(cdc codec.BinaryCodec, skey sdk.StoreKey, bkeeper BankKeeper, tkeeper TakeKeeper, dkeeper DistrKeeper, akeeper AuthzKeeper) Keeper { +func NewKeeper( + cdc codec.BinaryCodec, + skey storetypes.StoreKey, + bkeeper BankKeeper, + tkeeper TakeKeeper, + akeeper AuthzKeeper, + feepool collections.Item[distrtypes.FeePool], +) Keeper { return &keeper{ cdc: cdc, skey: skey, bkeeper: bkeeper, tkeeper: tkeeper, - dkeeper: dkeeper, authzKeeper: akeeper, + feepool: feepool, } } type keeper struct { cdc codec.BinaryCodec - skey sdk.StoreKey + skey storetypes.StoreKey bkeeper BankKeeper tkeeper TakeKeeper - dkeeper DistrKeeper authzKeeper AuthzKeeper - - hooks struct { + feepool collections.Item[distrtypes.FeePool] + hooks struct { onAccountClosed []AccountHook onPaymentClosed []PaymentHook } } +type account struct { + etypes.Account + dirty bool + prevState etypes.State +} + +type payment struct { + etypes.Payment + dirty bool + prevState etypes.State +} + func (k *keeper) Codec() codec.BinaryCodec { return k.cdc } // StoreKey returns store key -func (k *keeper) StoreKey() sdk.StoreKey { +func (k *keeper) StoreKey() storetypes.StoreKey { return k.skey } -func (k *keeper) AccountCreate(ctx sdk.Context, id types.AccountID, owner, depositor sdk.AccAddress, deposit sdk.Coin) error { +func (k *keeper) NewQuerier() Querier { + return Querier{k} +} + +func (k *keeper) AccountCreate(ctx sdk.Context, id escrowid.Account, owner sdk.AccAddress, deposits []etypes.Depositor) error { store := ctx.KVStore(k.skey) - key := accountKey(id) - if store.Has(key) { - return types.ErrAccountExists + key := k.findAccount(ctx, &id) + if len(key) != 0 { + return module.ErrAccountExists } - obj := &types.Account{ - ID: id, - Owner: owner.String(), - State: types.AccountOpen, - Balance: sdk.NewDecCoin(deposit.Denom, sdk.ZeroInt()), - Transferred: sdk.NewDecCoin(deposit.Denom, sdk.ZeroInt()), - SettledAt: ctx.BlockHeight(), - Depositor: depositor.String(), - Funds: sdk.NewDecCoin(deposit.Denom, sdk.ZeroInt()), + denoms := make(map[string]int) + + for _, d := range deposits { + denoms[d.Balance.Denom] = 1 + } + + transferred := make(sdk.DecCoins, 0, len(denoms)) + funds := make([]etypes.Balance, 0, len(denoms)) + + for denom := range denoms { + transferred = append(transferred, sdk.NewDecCoin(denom, sdkmath.ZeroInt())) + funds = append(funds, etypes.Balance{ + Denom: denom, + Amount: sdkmath.LegacyZeroDec(), + }) + } + + obj := &account{ + Account: etypes.Account{ + ID: id, + State: etypes.AccountState{ + Owner: owner.String(), + State: etypes.StateOpen, + Transferred: transferred, + SettledAt: ctx.BlockHeight(), + Funds: funds, + Deposits: make([]etypes.Depositor, 0), + }, + }, + dirty: true, + prevState: etypes.StateOpen, } if err := obj.ValidateBasic(); err != nil { return err } - if err := k.fetchDepositToAccount(ctx, obj, owner, depositor, deposit); err != nil { + if err := k.fetchDepositsToAccount(ctx, obj, deposits); err != nil { return err } - store.Set(key, k.cdc.MustMarshal(obj)) + key = BuildAccountsKey(obj.State.State, &id) + store.Set(key, k.cdc.MustMarshal(&obj.State)) return nil } -// fetchDepositToAccount fetches deposit amount from the depositor's account to the escrow -// account and accordingly updates the balance or funds. -func (k *keeper) fetchDepositToAccount(ctx sdk.Context, acc *types.Account, owner, depositor sdk.AccAddress, deposit sdk.Coin) error { - if err := k.bkeeper.SendCoinsFromAccountToModule(ctx, depositor, types.ModuleName, sdk.NewCoins(deposit)); err != nil { - return err +func (k *keeper) AuthorizeDeposits(sctx sdk.Context, msg sdk.Msg) ([]etypes.Depositor, error) { + depositors := make([]etypes.Depositor, 0, 1) + + hasDeposit, valid := msg.(deposit.HasDeposit) + if !valid { + return nil, fmt.Errorf("%w: message [%s] does not implement deposit.HasDeposit", module.ErrInvalidDeposit, reflect.TypeOf(msg).String()) } - if owner.Equals(depositor) { - acc.Balance = acc.Balance.Add(sdk.NewDecCoinFromCoin(deposit)) - } else { - acc.Funds = acc.Funds.Add(sdk.NewDecCoinFromCoin(deposit)) + lMsg, valid := msg.(sdk.LegacyMsg) + if !valid { + return nil, fmt.Errorf("%w: message [%s] does not implement sdk.LegacyMsg", module.ErrInvalidDeposit, reflect.TypeOf(msg).String()) } - return nil -} + signers := lMsg.GetSigners() + if len(signers) != 1 { + return nil, fmt.Errorf("%w: invalid signers", module.ErrInvalidDeposit) + } -func (k *keeper) GetAccountDepositor(ctx sdk.Context, id types.AccountID) (sdk.AccAddress, error) { - obj, err := k.GetAccount(ctx, id) - if err != nil { - return sdk.AccAddress{}, err + owner := signers[0] + + dep := hasDeposit.GetDeposit() + denom := dep.Amount.Denom + + remainder := sdkmath.NewInt(dep.Amount.Amount.Int64()) + + for _, source := range dep.Sources { + switch source { + case deposit.SourceBalance: + spendableAmount := k.bkeeper.SpendableCoin(sctx, owner, denom) + + if spendableAmount.Amount.IsPositive() { + requestedSpend := sdk.NewCoin(denom, remainder) + + if spendableAmount.IsLT(requestedSpend) { + requestedSpend = spendableAmount + } + depositors = append(depositors, etypes.Depositor{ + Owner: owner.String(), + Height: sctx.BlockHeight(), + Source: deposit.SourceBalance, + Balance: sdk.NewDecCoinFromCoin(requestedSpend), + }) + + remainder = remainder.Sub(requestedSpend.Amount) + } + case deposit.SourceGrant: + // find the DepositDeploymentAuthorization given to the owner by the depositor and check + // acceptance + msgTypeUrl := (&ev1.DepositAuthorization{}).MsgTypeURL() + + k.authzKeeper.GetGranteeGrantsByMsgType(sctx, owner, msgTypeUrl, func(ctx context.Context, granter sdk.AccAddress, authorization authz.Authorization, expiration *time.Time) bool { + depositAuthz, valid := authorization.(ev1.Authorization) + if !valid { + return false + } + + spendableAmount := depositAuthz.GetSpendLimit() + if spendableAmount.IsZero() { + return false + } + + requestedSpend := sdk.NewCoin(denom, remainder) + + // bc authz.Accepts take sdk.Msg as an argument, the deposit amount from incoming message + // has to be modified in place to correctly calculate what deposits to take from grants + switch mt := msg.(type) { + case *ev1.MsgAccountDeposit: + mt.Deposit.Amount = requestedSpend + case *dv1beta.MsgCreateDeployment: + mt.Deposit.Amount = requestedSpend + case *mv1beta.MsgCreateBid: + mt.Deposit.Amount = requestedSpend + } + + resp, err := depositAuthz.TryAccept(ctx, msg, true) + if err != nil { + return false + } + + if !resp.Accept { + return false + } + + // Delete is ignored here as not all fund may be used during deployment lifetime. + // also, there can be another deployment using same authorization and may return funds before deposit is fully used + err = k.authzKeeper.SaveGrant(ctx, owner, granter, resp.Updated, expiration) + if err != nil { + return false + } + + depositAuthz = resp.Updated.(ev1.Authorization) + + spendableAmount = spendableAmount.Sub(depositAuthz.GetSpendLimit()) + + depositors = append(depositors, etypes.Depositor{ + Owner: granter.String(), + Height: sctx.BlockHeight(), + Source: deposit.SourceGrant, + Balance: sdk.NewDecCoinFromCoin(spendableAmount), + }) + remainder = remainder.Sub(spendableAmount.Amount) + + return remainder.IsZero() + }) + } + + if remainder.IsZero() { + break + } } - depositor, err := sdk.AccAddressFromBech32(obj.Depositor) - if err != nil { - return sdk.AccAddress{}, err + if !remainder.IsZero() { + // the following check is for sanity. if value is negative, math above went horribly wrong + if remainder.IsNegative() { + return nil, fmt.Errorf("%w: deposit overflow", types.ErrInvalidDeposit) + } else { + return nil, fmt.Errorf("%w: insufficient balance", types.ErrInvalidDeposit) + } } - return depositor, nil + return depositors, nil } -func (k *keeper) AccountDeposit(ctx sdk.Context, id types.AccountID, depositor sdk.AccAddress, amount sdk.Coin) error { - store := ctx.KVStore(k.skey) - key := accountKey(id) - - obj, err := k.GetAccount(ctx, id) +func (k *keeper) AccountClose(ctx sdk.Context, id escrowid.Account) error { + acc, payments, od, err := k.accountSettle(ctx, id) if err != nil { return err } - if obj.State != types.AccountOpen { - return types.ErrAccountClosed + if od { + return nil } - owner, err := sdk.AccAddressFromBech32(obj.Owner) + acc.State.State = etypes.StateClosed + acc.dirty = true + + for idx := range payments { + payments[idx].State.State = etypes.StateClosed + payments[idx].dirty = true + + if err := k.paymentWithdraw(ctx, &payments[idx]); err != nil { + return err + } + } + + err = k.save(ctx, acc, payments) if err != nil { return err } - currDepositor, err := sdk.AccAddressFromBech32(obj.Depositor) + return nil +} + +func (k *keeper) AccountDeposit(ctx sdk.Context, id escrowid.Account, deposits []etypes.Depositor) error { + obj, err := k.getAccount(ctx, id) if err != nil { return err } - if !owner.Equals(depositor) { - if currDepositor.Equals(owner) { - obj.Depositor = depositor.String() - } else if !currDepositor.Equals(depositor) { - return types.ErrInvalidAccountDepositor - } + if obj.State.State != etypes.StateOpen { + return module.ErrAccountClosed } - if err = k.fetchDepositToAccount(ctx, &obj, owner, depositor, amount); err != nil { + if err := k.fetchDepositsToAccount(ctx, &obj, deposits); err != nil { return err } - store.Set(key, k.cdc.MustMarshal(&obj)) + if obj.dirty { + err = k.saveAccount(ctx, obj) + if err != nil { + return err + } + } return nil } -func (k *keeper) AccountSettle(ctx sdk.Context, id types.AccountID) (bool, error) { - _, _, od, err := k.doAccountSettle(ctx, id) +func (k *keeper) AccountSettle(ctx sdk.Context, id escrowid.Account) (bool, error) { + acc, payments, od, err := k.accountSettle(ctx, id) + if err != nil { + return false, err + } + + err = k.save(ctx, acc, payments) + if err != nil { + return false, err + } return od, err } -func (k *keeper) AccountClose(ctx sdk.Context, id types.AccountID) error { - // doAccountSettle checks if account is open - account, payments, od, err := k.doAccountSettle(ctx, id) +// fetchDepositToAccount fetches the deposit amount from the depositor's account to the escrow +// account and accordingly updates the balance or funds. +func (k *keeper) fetchDepositsToAccount(ctx sdk.Context, acc *account, deposits []etypes.Depositor) error { + if len(deposits) > 0 { + acc.dirty = true + } + + for _, d := range deposits { + depositor, err := sdk.AccAddressFromBech32(d.Owner) + if err != nil { + return err + } + + var funds *etypes.Balance + + for i := range acc.State.Funds { + if acc.State.Funds[i].Denom == d.Balance.Denom { + funds = &acc.State.Funds[i] + } + } + + if funds == nil { + return module.ErrInvalidDenomination + } + + if err := k.bkeeper.SendCoinsFromAccountToModule(ctx, depositor, module.ModuleName, sdk.NewCoins(sdk.NewCoin(d.Balance.Denom, d.Balance.Amount.TruncateInt()))); err != nil { + return err + } + + funds.Amount.AddMut(d.Balance.Amount) + } + + acc.State.Deposits = append(acc.State.Deposits, deposits...) + + return nil +} + +func (k *keeper) accountSettle(ctx sdk.Context, id escrowid.Account) (account, []payment, bool, error) { + acc, err := k.getAccount(ctx, id) if err != nil { - return err + return account{}, nil, false, err } - if od { - return nil + if acc.State.State != etypes.StateOpen { + return account{}, nil, false, module.ErrAccountClosed } - account.State = types.AccountClosed - if err := k.accountWithdraw(ctx, &account); err != nil { - return err + payments := k.accountOpenPayments(ctx, id) + + heightDelta := sdkmath.NewInt(ctx.BlockHeight() - acc.State.SettledAt) + if heightDelta.IsZero() { + return acc, nil, false, nil } - for idx := range payments { - payments[idx].State = types.PaymentClosed - if err := k.paymentWithdraw(ctx, &payments[idx]); err != nil { - return err - } + acc.State.SettledAt = ctx.BlockHeight() + acc.dirty = true + + if len(payments) == 0 { + return acc, nil, false, nil } - for _, hook := range k.hooks.onAccountClosed { - hook(ctx, account) + overdrawn := accountSettleFullBlocks(&acc, payments, heightDelta) + + // all payments made in full + if !overdrawn { + // return early + return acc, payments, false, nil } - for _, hook := range k.hooks.onPaymentClosed { - for idx := range payments { - hook(ctx, payments[idx]) + // + // overdrawn + // + acc.State.State = etypes.StateOverdrawn + + for idx := range payments { + payments[idx].State.State = etypes.StateOverdrawn + payments[idx].dirty = true + if err := k.paymentWithdraw(ctx, &payments[idx]); err != nil { + return acc, payments, overdrawn, err } } - return nil + return acc, payments, overdrawn, nil } -func (k *keeper) PaymentCreate(ctx sdk.Context, id types.AccountID, pid string, owner sdk.AccAddress, rate sdk.DecCoin) error { - account, _, od, err := k.doAccountSettle(ctx, id) +func (k *keeper) PaymentCreate(ctx sdk.Context, id escrowid.Payment, owner sdk.AccAddress, rate sdk.DecCoin) error { + acc, _, od, err := k.accountSettle(ctx, id.Account()) if err != nil { return err } if od { - return types.ErrAccountOverdrawn + return module.ErrAccountOverdrawn } - if rate.Denom != account.Balance.Denom { - return types.ErrInvalidDenomination + var funds *etypes.Balance + for i := range acc.State.Funds { + if rate.Denom == acc.State.Funds[i].Denom { + funds = &acc.State.Funds[i] + break + } } - if rate.IsZero() { - return types.ErrPaymentRateZero + if funds == nil { + return module.ErrInvalidDenomination } - store := ctx.KVStore(k.skey) - key := paymentKey(id, pid) + if rate.IsZero() { + return module.ErrPaymentRateZero + } - if store.Has(key) { - return types.ErrPaymentExists + key := k.findPayment(ctx, &id) + if len(key) != 0 { + return module.ErrPaymentExists } - obj := &types.FractionalPayment{ - AccountID: id, - PaymentID: pid, - Owner: owner.String(), - State: types.PaymentOpen, - Rate: rate, - Balance: sdk.NewDecCoin(rate.Denom, sdk.ZeroInt()), - Withdrawn: sdk.NewCoin(rate.Denom, sdk.ZeroInt()), + if acc.dirty { + err = k.saveAccount(ctx, acc) + if err != nil { + return err + } } - store.Set(key, k.cdc.MustMarshal(obj)) + k.savePayment(ctx, payment{ + Payment: etypes.Payment{ + ID: id, + State: etypes.PaymentState{ + Owner: owner.String(), + State: etypes.StateOpen, + Rate: rate, + Balance: sdk.NewDecCoin(rate.Denom, sdkmath.ZeroInt()), + Unsettled: sdk.NewDecCoin(rate.Denom, sdkmath.ZeroInt()), + Withdrawn: sdk.NewCoin(rate.Denom, sdkmath.ZeroInt()), + }}, + dirty: false, + prevState: etypes.StateOpen, + }) return nil } -func (k *keeper) PaymentWithdraw(ctx sdk.Context, id types.AccountID, pid string) error { - payment, err := k.GetPayment(ctx, id, pid) +func (k *keeper) PaymentWithdraw(ctx sdk.Context, id escrowid.Payment) error { + pmnt, err := k.getPayment(ctx, id) if err != nil { return err } - if payment.State != types.PaymentOpen { - return types.ErrPaymentClosed + if pmnt.State.State != etypes.StateOpen { + return module.ErrPaymentClosed } - od, err := k.AccountSettle(ctx, id) + acc, payments, od, err := k.accountSettle(ctx, id.Account()) if err != nil { return err } - if od { - return nil + if !od { + pmnt = nil + + for i, p := range payments { + if p.ID.Key() == id.Key() { + pmnt = &payments[i] + } + } + + if pmnt == nil { + panic(fmt.Sprintf("couldn't find payment %s", id.String())) + } + + err = k.paymentWithdraw(ctx, pmnt) + if err != nil { + return err + } } - payment, err = k.GetPayment(ctx, id, pid) + err = k.save(ctx, acc, payments) if err != nil { return err } - return k.paymentWithdraw(ctx, &payment) + return nil } -func (k *keeper) PaymentClose(ctx sdk.Context, id types.AccountID, pid string) error { - payment, err := k.GetPayment(ctx, id, pid) +func (k *keeper) PaymentClose(ctx sdk.Context, id escrowid.Payment) error { + pmnt, err := k.getPayment(ctx, id) if err != nil { return err } - if payment.State != types.PaymentOpen { - return types.ErrPaymentClosed + if pmnt.State.State != etypes.StateOpen { + return module.ErrPaymentClosed } - od, err := k.AccountSettle(ctx, id) + acc, payments, od, err := k.accountSettle(ctx, id.Account()) if err != nil { return err } - if od { return nil } - payment, err = k.GetPayment(ctx, id, pid) - if err != nil { - return err + pmnt = nil + + for i, p := range payments { + if p.ID.Key() == id.Key() { + pmnt = &payments[i] + } } - payment.State = types.PaymentClosed + if pmnt == nil { + panic(fmt.Sprintf("couldn't find payment %s", id.String())) + } - if err := k.paymentWithdraw(ctx, &payment); err != nil { + if err := k.paymentWithdraw(ctx, pmnt); err != nil { return err } - for _, hook := range k.hooks.onPaymentClosed { - hook(ctx, payment) + pmnt.State.State = etypes.StateClosed + pmnt.dirty = true + + err = k.save(ctx, acc, payments) + if err != nil { + return err } return nil @@ -325,291 +589,266 @@ func (k *keeper) AddOnPaymentClosedHook(hook PaymentHook) Keeper { return k } -func (k *keeper) GetAccount(ctx sdk.Context, id types.AccountID) (types.Account, error) { +func (k *keeper) GetAccount(ctx sdk.Context, id escrowid.Account) (etypes.Account, error) { + obj, err := k.getAccount(ctx, id) + if err != nil { + return etypes.Account{}, err + } + + return obj.Account, nil +} + +func (k *keeper) getAccount(ctx sdk.Context, id escrowid.Account) (account, error) { store := ctx.KVStore(k.skey) - key := accountKey(id) - if !store.Has(key) { - return types.Account{}, types.ErrAccountNotFound + key := k.findAccount(ctx, &id) + if len(key) == 0 { + return account{}, module.ErrAccountNotFound } buf := store.Get(key) - var obj types.Account + obj := account{ + Account: etypes.Account{ + ID: id, + }, + } - k.cdc.MustUnmarshal(buf, &obj) + k.cdc.MustUnmarshal(buf, &obj.State) + obj.prevState = obj.State.State return obj, nil } -func (k *keeper) GetPayment(ctx sdk.Context, id types.AccountID, pid string) (types.FractionalPayment, error) { +func (k *keeper) GetPayment(ctx sdk.Context, id escrowid.Payment) (etypes.Payment, error) { + obj, err := k.getPayment(ctx, id) + if err != nil { + return etypes.Payment{}, err + } + + return obj.Payment, nil +} + +func (k *keeper) getPayment(ctx sdk.Context, id escrowid.Payment) (*payment, error) { store := ctx.KVStore(k.skey) - key := paymentKey(id, pid) - if !store.Has(key) { - return types.FractionalPayment{}, types.ErrPaymentNotFound + key := k.findPayment(ctx, &id) + if len(key) == 0 { + return nil, module.ErrPaymentNotFound } buf := store.Get(key) - var obj types.FractionalPayment + obj := payment{ + Payment: etypes.Payment{ + ID: id, + }, + } - k.cdc.MustUnmarshal(buf, &obj) + k.cdc.MustUnmarshal(buf, &obj.State) + obj.prevState = obj.State.State - return obj, nil + return &obj, nil } -func (k *keeper) SaveAccount(ctx sdk.Context, obj types.Account) { - k.saveAccount(ctx, &obj) +func (k *keeper) SaveAccount(ctx sdk.Context, obj etypes.Account) error { + err := k.saveAccount(ctx, account{ + Account: obj, + prevState: obj.State.State, + }) + + if err != nil { + return err + } + + return nil } -func (k *keeper) SavePayment(ctx sdk.Context, obj types.FractionalPayment) { - k.savePayment(ctx, &obj) +func (k *keeper) SavePayment(ctx sdk.Context, obj etypes.Payment) { + k.savePayment(ctx, payment{ + Payment: obj, + prevState: obj.State.State, + }) } -func (k *keeper) WithAccounts(ctx sdk.Context, fn func(types.Account) bool) { +func (k *keeper) WithAccounts(ctx sdk.Context, fn func(etypes.Account) bool) { store := ctx.KVStore(k.skey) - iter := sdk.KVStorePrefixIterator(store, types.AccountKeyPrefix()) + iter := storetypes.KVStorePrefixIterator(store, AccountPrefix) defer func() { _ = iter.Close() }() for ; iter.Valid(); iter.Next() { - var val types.Account - k.cdc.MustUnmarshal(iter.Value(), &val) + id, _ := ParseAccountKey(iter.Key()) + val := etypes.Account{ + ID: id, + } + + k.cdc.MustUnmarshal(iter.Value(), &val.State) if stop := fn(val); stop { break } } } -func (k *keeper) WithPayments(ctx sdk.Context, fn func(types.FractionalPayment) bool) { +func (k *keeper) WithPayments(ctx sdk.Context, fn func(etypes.Payment) bool) { store := ctx.KVStore(k.skey) - iter := sdk.KVStorePrefixIterator(store, types.PaymentKeyPrefix()) + iter := storetypes.KVStorePrefixIterator(store, PaymentPrefix) defer func() { _ = iter.Close() }() for ; iter.Valid(); iter.Next() { - var val types.FractionalPayment - k.cdc.MustUnmarshal(iter.Value(), &val) + id, _ := ParsePaymentKey(iter.Key()) + val := etypes.Payment{ + ID: id, + } + k.cdc.MustUnmarshal(iter.Value(), &val.State) if stop := fn(val); stop { break } } } -func (k *keeper) doAccountSettle(ctx sdk.Context, id types.AccountID) (types.Account, []types.FractionalPayment, bool, error) { - account, err := k.GetAccount(ctx, id) - if err != nil { - return account, nil, false, err - } - - if account.State != types.AccountOpen { - return account, nil, false, types.ErrAccountClosed - } - - heightDelta := sdk.NewInt(ctx.BlockHeight() - account.SettledAt) - - if heightDelta.IsZero() { - return account, nil, false, nil - } - - account.SettledAt = ctx.BlockHeight() - - payments := k.accountOpenPayments(ctx, id) - - if len(payments) == 0 { - k.saveAccount(ctx, &account) - return account, nil, false, nil - } - - blockRate := sdk.NewDecCoin(account.Balance.Denom, sdk.ZeroInt()) - - for _, payment := range payments { - blockRate = blockRate.Add(payment.Rate) - } - - account, payments, overdrawn, amountRemaining := accountSettleFullBlocks(account, payments, heightDelta, blockRate) - - if account.Funds.Amount.IsPositive() { - owner := sdk.MustAccAddressFromBech32(account.Owner) - depositor := sdk.MustAccAddressFromBech32(account.Depositor) - - msg := &dtypes.MsgDepositDeployment{Amount: sdk.NewCoin(account.Balance.Denom, sdk.NewInt(0))} - - authz, _ := k.authzKeeper.GetCleanAuthorization(ctx, owner, depositor, sdk.MsgTypeURL(msg)) +func (k *keeper) saveAccount(ctx sdk.Context, obj account) error { + store := ctx.KVStore(k.skey) - // if authorization has been revoked or expired it cannot be used anymore - // send coins back to the owner - if authz == nil { - withdrawal := sdk.NewCoin(account.Balance.Denom, account.Funds.Amount.TruncateInt()) - if err := k.bkeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, depositor, sdk.NewCoins(withdrawal)); err != nil { - ctx.Logger().Error("account withdraw", "err", err, "id", account.ID) - return account, payments, overdrawn, err + var key []byte + if obj.State.State != obj.prevState { + key := BuildAccountsKey(obj.prevState, &obj.ID) + store.Delete(key) + } + + key = BuildAccountsKey(obj.State.State, &obj.ID) + + if obj.State.State == etypes.StateClosed || obj.State.State == etypes.StateOverdrawn { + for _, d := range obj.State.Deposits { + if d.Balance.IsPositive() { + depositor, err := sdk.AccAddressFromBech32(d.Owner) + if err != nil { + return err + } + + withdrawal := sdk.NewCoin(d.Balance.Denom, d.Balance.Amount.TruncateInt()) + + err = k.bkeeper.SendCoinsFromModuleToAccount(ctx, module.ModuleName, depositor, sdk.NewCoins(withdrawal)) + if err != nil { + return err + } + + // if depositor is not an owner then funds came from the grant. + if d.Source == deposit.SourceGrant { + owner, err := sdk.AccAddressFromBech32(obj.State.Owner) + if err != nil { + return err + } + + // if exists, increase allowed authz deposit by remainder in the Balance, it will allow owner to reuse active authz + // without asking for renew. + msgTypeUrl := (&ev1.DepositAuthorization{}).MsgTypeURL() + + authorization, expiration := k.authzKeeper.GetAuthorization(ctx, owner, depositor, msgTypeUrl) + dauthz, valid := authorization.(*ev1.DepositAuthorization) + if valid && authorization != nil { + dauthz.SpendLimit = dauthz.SpendLimit.Add(withdrawal) + err = k.authzKeeper.SaveGrant(ctx, owner, depositor, dauthz, expiration) + if err != nil { + return err + } + } + } + + obj.State.Funds[0].Amount.SubMut(sdkmath.LegacyNewDecFromInt(withdrawal.Amount)) } - - account.Funds.Amount = sdk.ZeroDec() } + + obj.State.Deposits = []etypes.Depositor{} } - // all payments made in full - if !overdrawn { - // save objects - k.saveAccount(ctx, &account) - for idx := range payments { - k.savePayment(ctx, &payments[idx]) - } + store.Set(key, k.cdc.MustMarshal(&obj.State)) - // return early - return account, payments, false, nil + if obj.State.State == etypes.StateClosed || obj.State.State == etypes.StateOverdrawn { + // call hooks + for _, hook := range k.hooks.onAccountClosed { + hook(ctx, obj.Account) + } } - // - // overdrawn - // + return nil +} - // distribute weighted by payment block rate - account, payments, amountRemaining = accountSettleDistributeWeighted(account, payments, blockRate, amountRemaining) +func (k *keeper) savePayment(ctx sdk.Context, obj payment) { + store := ctx.KVStore(k.skey) - if amountRemaining.Amount.GT(sdk.NewDec(1)) { - return account, payments, false, fmt.Errorf("%w: Invalid settlement: %v remains", types.ErrInvalidSettlement, amountRemaining) + var key []byte + if obj.State.State != obj.prevState { + key := BuildPaymentsKey(obj.prevState, &obj.ID) + store.Delete(key) } - // save objects - account.State = types.AccountOverdrawn - k.saveAccount(ctx, &account) - for idx := range payments { - payments[idx].State = types.PaymentOverdrawn - k.savePayment(ctx, &payments[idx]) - if err := k.paymentWithdraw(ctx, &payments[idx]); err != nil { - return account, payments, false, err + key = BuildPaymentsKey(obj.State.State, &obj.ID) + store.Set(key, k.cdc.MustMarshal(&obj.State)) + + if obj.State.State == etypes.StateClosed || obj.State.State == etypes.StateOverdrawn { + // call hooks + for _, hook := range k.hooks.onPaymentClosed { + hook(ctx, obj.Payment) } } +} - // call hooks - for _, hook := range k.hooks.onAccountClosed { - hook(ctx, account) +func (k *keeper) save(ctx sdk.Context, acc account, payments []payment) error { + if acc.dirty { + err := k.saveAccount(ctx, acc) + if err != nil { + return err + } } - for _, hook := range k.hooks.onPaymentClosed { - for _, payment := range payments { - hook(ctx, payment) + for _, pmnt := range payments { + if pmnt.dirty { + k.savePayment(ctx, pmnt) } } - return account, payments, true, nil -} - -func (k *keeper) saveAccount(ctx sdk.Context, obj *types.Account) { - store := ctx.KVStore(k.skey) - key := accountKey(obj.ID) - store.Set(key, k.cdc.MustMarshal(obj)) -} - -func (k *keeper) savePayment(ctx sdk.Context, obj *types.FractionalPayment) { - store := ctx.KVStore(k.skey) - key := paymentKey(obj.AccountID, obj.PaymentID) - store.Set(key, k.cdc.MustMarshal(obj)) + return nil } -func (k *keeper) accountPayments(ctx sdk.Context, id types.AccountID) []types.FractionalPayment { +func (k *keeper) accountOpenPayments(ctx sdk.Context, id escrowid.Account) []payment { store := ctx.KVStore(k.skey) - iter := sdk.KVStorePrefixIterator(store, accountPaymentsKey(id)) + prefix := BuildPaymentsKey(etypes.StateOpen, &id) + iter := storetypes.KVStorePrefixIterator(store, prefix) - var payments []types.FractionalPayment + var payments []payment defer func() { _ = iter.Close() }() for ; iter.Valid(); iter.Next() { - var val types.FractionalPayment - k.cdc.MustUnmarshal(iter.Value(), &val) - payments = append(payments, val) - } - - return payments -} - -func (k *keeper) accountOpenPayments(ctx sdk.Context, id types.AccountID) []types.FractionalPayment { - allPayments := k.accountPayments(ctx, id) - payments := make([]types.FractionalPayment, 0, len(allPayments)) - - for _, payment := range allPayments { - if payment.State != types.PaymentOpen { - continue + id, _ := ParsePaymentKey(iter.Key()) + val := etypes.Payment{ + ID: id, } - payments = append(payments, payment) + k.cdc.MustUnmarshal(iter.Value(), &val.State) + payments = append(payments, payment{ + Payment: val, + prevState: val.State.State, + }) } return payments } -func (k *keeper) accountWithdraw(ctx sdk.Context, obj *types.Account) error { - if obj.Balance.Amount.LT(sdk.NewDec(1)) && obj.Funds.Amount.LT(sdk.NewDec(1)) { - return nil - } - - owner, err := sdk.AccAddressFromBech32(obj.Owner) +func (k *keeper) paymentWithdraw(ctx sdk.Context, obj *payment) error { + owner, err := sdk.AccAddressFromBech32(obj.State.Owner) if err != nil { return err } - if !obj.Balance.Amount.LT(sdk.NewDec(1)) { - withdrawal := sdk.NewCoin(obj.Balance.Denom, obj.Balance.Amount.TruncateInt()) - if err = k.bkeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, owner, sdk.NewCoins(withdrawal)); err != nil { - ctx.Logger().Error("account withdraw", "err", err, "id", obj.ID) - return err - } - obj.Balance = obj.Balance.Sub(sdk.NewDecCoinFromCoin(withdrawal)) - } - - if obj.Funds.IsPositive() { - depositor, err := sdk.AccAddressFromBech32(obj.Depositor) - if err != nil { - return err - } - - withdrawal := sdk.NewCoin(obj.Balance.Denom, obj.Funds.Amount.TruncateInt()) - if err = k.bkeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, depositor, sdk.NewCoins(withdrawal)); err != nil { - ctx.Logger().Error("account withdraw", "err", err, "id", obj.ID) - return err - } - - obj.Funds = obj.Funds.Sub(sdk.NewDecCoinFromCoin(withdrawal)) - - msg := &dtypes.MsgDepositDeployment{Amount: sdk.NewCoin(obj.Balance.Denom, sdk.NewInt(0))} - - // Funds field is solely to track deposits via authz. - // check if there is active deployment authorization from given depositor - // if exists, increase allowed authz deposit by remainder in the Funds, it will allow owner to reuse active authz - // without asking for renew. - authorization, expiration := k.authzKeeper.GetCleanAuthorization(ctx, owner, depositor, sdk.MsgTypeURL(msg)) - dauthz, valid := authorization.(*dtypes.DepositDeploymentAuthorization) - if valid && authorization != nil { - dauthz.SpendLimit = dauthz.SpendLimit.Add(withdrawal) - err = k.authzKeeper.SaveGrant(ctx, owner, depositor, dauthz, expiration) - if err != nil { - return err - } - } - } - - k.saveAccount(ctx, obj) - - return nil -} - -func (k *keeper) paymentWithdraw(ctx sdk.Context, obj *types.FractionalPayment) error { - owner, err := sdk.AccAddressFromBech32(obj.Owner) - if err != nil { - return err - } - - rawEarnings := sdk.NewCoin(obj.Balance.Denom, obj.Balance.Amount.TruncateInt()) + rawEarnings := sdk.NewCoin(obj.State.Balance.Denom, obj.State.Balance.Amount.TruncateInt()) if rawEarnings.Amount.IsZero() { return nil @@ -621,23 +860,22 @@ func (k *keeper) paymentWithdraw(ctx sdk.Context, obj *types.FractionalPayment) } if err := k.sendFeeToCommunityPool(ctx, fee); err != nil { - ctx.Logger().Error("payment withdraw - fees", "err", err, "account", obj.AccountID, "payment", obj.PaymentID) + ctx.Logger().Error("payment withdraw - fees", "err", err, "id", obj.ID.Key()) return err } if !earnings.IsZero() { - if err := k.bkeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, owner, sdk.NewCoins(earnings)); err != nil { - ctx.Logger().Error("payment withdraw - earnings", "err", err, "account", obj.AccountID, "payment", obj.PaymentID) + if err := k.bkeeper.SendCoinsFromModuleToAccount(ctx, module.ModuleName, owner, sdk.NewCoins(earnings)); err != nil { + ctx.Logger().Error("payment withdraw - earnings", "err", err, "is", obj.ID.Key()) return err } } total := earnings.Add(fee) - obj.Withdrawn = obj.Withdrawn.Add(total) - obj.Balance = obj.Balance.Sub(sdk.NewDecCoinFromCoin(total)) - - k.savePayment(ctx, obj) + obj.State.Withdrawn = obj.State.Withdrawn.Add(total) + obj.State.Balance = obj.State.Balance.Sub(sdk.NewDecCoinFromCoin(total)) + obj.dirty = true return nil } @@ -648,101 +886,169 @@ func (k *keeper) sendFeeToCommunityPool(ctx sdk.Context, fee sdk.Coin) error { } // see https://github.com/cosmos/cosmos-sdk/blob/c2a07cea272a7878b5bc2ec160eb58ca83794214/x/distribution/keeper/keeper.go#L251-L263 - if err := k.bkeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, distrtypes.ModuleName, sdk.NewCoins(fee)); err != nil { + if err := k.bkeeper.SendCoinsFromModuleToModule(ctx, module.ModuleName, distrtypes.ModuleName, sdk.NewCoins(fee)); err != nil { return err } - pool := k.dkeeper.GetFeePool(ctx) + pool, err := k.feepool.Get(ctx) + if err != nil { + return err + } pool.CommunityPool = pool.CommunityPool.Add(sdk.NewDecCoinFromCoin(fee)) - k.dkeeper.SetFeePool(ctx, pool) + + err = k.feepool.Set(ctx, pool) + if err != nil { + return err + } return nil } -func accountSettleFullBlocks( - account types.Account, - payments []types.FractionalPayment, - heightDelta sdk.Int, - blockRate sdk.DecCoin, -) ( - types.Account, - []types.FractionalPayment, - bool, - sdk.DecCoin, -) { - numFullBlocks := account.TotalBalance().Amount.Quo(blockRate.Amount).TruncateInt() +func (acc *account) deductFromBalance(amount sdk.DecCoin) (sdk.DecCoin, bool) { + remaining := sdkmath.LegacyZeroDec() + remaining.AddMut(amount.Amount) + + withdrew := sdkmath.LegacyZeroDec() + + idx := 0 + + var funds *etypes.Balance + var transferred *sdk.DecCoin - if numFullBlocks.GT(heightDelta) { - numFullBlocks = heightDelta + for i := range acc.State.Funds { + if amount.Denom == acc.State.Funds[i].Denom { + funds = &acc.State.Funds[i] + } } - for idx := range payments { - p := payments[idx] - payments[idx].Balance = p.Balance.Add( - sdk.NewDecCoinFromDec(p.Rate.Denom, p.Rate.Amount.Mul(sdk.NewDecFromInt(numFullBlocks))), - ) + for i := range acc.State.Transferred { + if amount.Denom == acc.State.Transferred[i].Denom { + transferred = &acc.State.Transferred[i] + } } - transferred := sdk.NewDecCoinFromDec(blockRate.Denom, blockRate.Amount.Mul(sdk.NewDecFromInt(numFullBlocks))) + if funds == nil || transferred == nil { + panic(fmt.Sprintf("unknown denom \"%s\"", amount.Denom)) + } + + for i, d := range acc.State.Deposits { + toWithdraw := sdkmath.LegacyZeroDec() + + if d.Balance.Amount.LT(remaining) { + toWithdraw.AddMut(d.Balance.Amount) + } else { + toWithdraw.AddMut(remaining) + } + + funds.Amount.SubMut(toWithdraw) - account.Transferred = account.Transferred.Add(transferred) - // use funds before using balance - account.Funds.Amount = account.Funds.Amount.Sub(transferred.Amount) - if account.Funds.Amount.IsNegative() { - account.Balance.Amount = account.Balance.Amount.Sub(account.Funds.Amount.Abs()) - account.Funds.Amount = sdk.ZeroDec() + acc.State.Deposits[i].Balance.Amount.SubMut(toWithdraw) + if acc.State.Deposits[i].Balance.IsZero() { + idx++ + } + remaining.SubMut(toWithdraw) + withdrew.AddMut(toWithdraw) + transferred.Amount.AddMut(toWithdraw) + + if remaining.IsZero() { + break + } } - remaining := account.TotalBalance() - overdrawn := true - if numFullBlocks.Equal(heightDelta) { - remaining.Amount = sdk.ZeroDec() - overdrawn = false + if idx > 0 { + acc.State.Deposits = acc.State.Deposits[idx:] } - // only balance is used in later functions to do calculations, in case account is overdrawn - // finally, balance will always reach zero, so we are not doing any mis-management here. - if overdrawn { - account.Balance = remaining - account.Funds.Amount = sdk.ZeroDec() + res := sdk.NewDecCoinFromDec(amount.Denom, withdrew) + + if remaining.IsZero() { + return res, false } - return account, payments, overdrawn, remaining + funds.Amount.SubMut(remaining) + + return res, true } -func accountSettleDistributeWeighted( - account types.Account, - payments []types.FractionalPayment, - blockRate sdk.DecCoin, - amountRemaining sdk.DecCoin, -) ( - types.Account, - []types.FractionalPayment, - sdk.DecCoin, -) { - actualTransferred := sdk.ZeroDec() +func accountSettleFullBlocks(acc *account, payments []payment, heightDelta sdkmath.Int) bool { + funds := &acc.State.Funds[0] + + blockRate := sdk.NewDecCoin(funds.Denom, sdkmath.ZeroInt()) + paymentsTransfers := make([]sdk.DecCoin, 0, len(payments)) + + for _, pmnt := range payments { + blockRate = blockRate.Add(pmnt.State.Rate) + } + + for idx := range payments { + p := payments[idx] + paymentTransfer := sdk.NewDecCoinFromDec(p.State.Rate.Denom, p.State.Rate.Amount.Mul(sdkmath.LegacyNewDecFromInt(heightDelta))) + + paymentsTransfers = append(paymentsTransfers, paymentTransfer) + } - // distribute remaining balance weighted by rate + overdrawn := false for idx := range payments { - payment := payments[idx] - // amount := (rate / blockrate) * remaining - amount := amountRemaining.Amount. - Mul(payment.Rate.Amount). - Quo(blockRate.Amount) + unsettledAmount := paymentsTransfers[idx] + + settledAmount, od := acc.deductFromBalance(unsettledAmount) + unsettledAmount.Amount.SubMut(unsettledAmount.Amount) + + if settledAmount.IsPositive() { + payments[idx].State.Balance.Amount.AddMut(settledAmount.Amount) + } + + if od { + overdrawn = true + payments[idx].State.Unsettled.Amount.AddMut(unsettledAmount.Amount) + } + } + + acc.dirty = true + + return overdrawn +} + +func (k *keeper) findAccount(ctx sdk.Context, id escrowid.ID) []byte { + store := ctx.KVStore(k.skey) - payments[idx].Balance = payment.Balance.Add(sdk.NewDecCoinFromDec(payment.Balance.Denom, amount)) + okey := BuildAccountsKey(etypes.StateOpen, id) + ckey := BuildAccountsKey(etypes.StateClosed, id) + ovkey := BuildAccountsKey(etypes.StateOverdrawn, id) - actualTransferred = actualTransferred.Add(amount) + var key []byte + + //nolint: gocritic + if store.Has(okey) { + key = okey + } else if store.Has(ckey) { + key = ckey + } else if store.Has(ovkey) { + key = ovkey } - transferred := sdk.NewDecCoinFromDec(account.Balance.Denom, actualTransferred) + return key +} - account.Transferred = account.Transferred.Add(transferred) - account.Balance = account.Balance.Sub(transferred) +func (k *keeper) findPayment(ctx sdk.Context, id escrowid.ID) []byte { + store := ctx.KVStore(k.skey) + + okey := BuildPaymentsKey(etypes.StateOpen, id) + ckey := BuildPaymentsKey(etypes.StateClosed, id) + ovkey := BuildPaymentsKey(etypes.StateOverdrawn, id) - amountRemaining = amountRemaining.Sub(transferred) + var key []byte + + //nolint: gocritic + if store.Has(okey) { + key = okey + } else if store.Has(ckey) { + key = ckey + } else if store.Has(ovkey) { + key = ovkey + } - return account, payments, amountRemaining + return key } diff --git a/x/escrow/keeper/keeper_settle_test.go b/x/escrow/keeper/keeper_settle_test.go index 971ae88a9f..960fa781b8 100644 --- a/x/escrow/keeper/keeper_settle_test.go +++ b/x/escrow/keeper/keeper_settle_test.go @@ -3,10 +3,12 @@ package keeper import ( "testing" + sdkmath "cosmossdk.io/math" + etypes "pkg.akt.dev/go/node/escrow/types/v1" + "pkg.akt.dev/go/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" - - types "github.com/akash-network/akash-api/go/node/escrow/v1beta3" ) const denom = "uakt" @@ -23,9 +25,7 @@ func TestSettleFullBlocks(t *testing.T) { balanceStart: 100, rates: []int64{1, 2}, balanceEnd: 85, - transferred: []sdk.Dec{sdk.NewDec(5), sdk.NewDec(10)}, - remaining: 0, - overdrawn: false, + transferred: []sdkmath.LegacyDec{sdkmath.LegacyNewDec(5), sdkmath.LegacyNewDec(10)}, }, }, { @@ -35,9 +35,7 @@ func TestSettleFullBlocks(t *testing.T) { balanceStart: 100, rates: []int64{10, 10}, balanceEnd: 0, - transferred: []sdk.Dec{sdk.NewDec(50), sdk.NewDec(50)}, - remaining: 0, - overdrawn: false, + transferred: []sdkmath.LegacyDec{sdkmath.LegacyNewDec(50), sdkmath.LegacyNewDec(50)}, }, }, { @@ -46,191 +44,71 @@ func TestSettleFullBlocks(t *testing.T) { blocks: 6, balanceStart: 100, rates: []int64{10, 10}, - balanceEnd: 0, - transferred: []sdk.Dec{sdk.NewDec(50), sdk.NewDec(50)}, - remaining: 0, - overdrawn: true, - }, - }, - { - name: "some left", - cfg: distTestConfig{ - blocks: 6, - balanceStart: 90, - rates: []int64{10, 10}, - balanceEnd: 10, - transferred: []sdk.Dec{sdk.NewDec(40), sdk.NewDec(40)}, - remaining: 10, - overdrawn: true, + balanceEnd: -20, + transferred: []sdkmath.LegacyDec{sdkmath.LegacyNewDec(60), sdkmath.LegacyNewDec(40)}, }, }, { name: "plenty funds", cfg: distTestConfig{ blocks: 5, - balanceStart: 0, + balanceStart: 100, rates: []int64{1, 2}, - balanceEnd: 0, - fundsStart: 100, - fundsEnd: 85, - transferred: []sdk.Dec{sdk.NewDec(5), sdk.NewDec(10)}, - remaining: 0, - overdrawn: false, + balanceEnd: 85, + transferred: []sdkmath.LegacyDec{sdkmath.LegacyNewDec(5), sdkmath.LegacyNewDec(10)}, }, }, { name: "use all funds", cfg: distTestConfig{ blocks: 5, - balanceStart: 100, + balanceStart: 200, rates: []int64{10, 10}, balanceEnd: 100, - fundsStart: 100, - fundsEnd: 0, - transferred: []sdk.Dec{sdk.NewDec(50), sdk.NewDec(50)}, - remaining: 0, - overdrawn: false, + transferred: []sdkmath.LegacyDec{sdkmath.LegacyNewDec(50), sdkmath.LegacyNewDec(50)}, }, }, { name: "use all funds with some balance", cfg: distTestConfig{ blocks: 6, - balanceStart: 100, + balanceStart: 200, rates: []int64{10, 10}, balanceEnd: 80, - fundsStart: 100, - fundsEnd: 0, - transferred: []sdk.Dec{sdk.NewDec(60), sdk.NewDec(60)}, - remaining: 0, - overdrawn: false, + transferred: []sdkmath.LegacyDec{sdkmath.LegacyNewDec(60), sdkmath.LegacyNewDec(60)}, }, }, { name: "use all funds and balance", cfg: distTestConfig{ blocks: 10, - balanceStart: 100, + balanceStart: 200, rates: []int64{10, 10}, balanceEnd: 0, - fundsStart: 100, - fundsEnd: 0, - transferred: []sdk.Dec{sdk.NewDec(100), sdk.NewDec(100)}, - remaining: 0, - overdrawn: false, + transferred: []sdkmath.LegacyDec{sdkmath.LegacyNewDec(100), sdkmath.LegacyNewDec(100)}, }, }, { name: "overdrawn with all funds and balance used up", cfg: distTestConfig{ blocks: 11, - balanceStart: 100, + balanceStart: 200, rates: []int64{10, 10}, - balanceEnd: 0, - fundsStart: 100, - fundsEnd: 0, - transferred: []sdk.Dec{sdk.NewDec(100), sdk.NewDec(100)}, - remaining: 0, - overdrawn: true, - }, - }, - { - name: "overdrawn with all funds used and some balance left", - cfg: distTestConfig{ - blocks: 10, - balanceStart: 100, - rates: []int64{10, 10}, - balanceEnd: 10, - fundsStart: 90, - fundsEnd: 0, - transferred: []sdk.Dec{sdk.NewDec(90), sdk.NewDec(90)}, - remaining: 10, - overdrawn: true, - }, - }, - { - name: "overdrawn when only funds", - cfg: distTestConfig{ - blocks: 6, - balanceStart: 0, - rates: []int64{10, 10}, - balanceEnd: 10, - fundsStart: 90, - fundsEnd: 0, - transferred: []sdk.Dec{sdk.NewDec(40), sdk.NewDec(40)}, - remaining: 10, - overdrawn: true, + balanceEnd: -20, + transferred: []sdkmath.LegacyDec{sdkmath.LegacyNewDec(110), sdkmath.LegacyNewDec(90)}, }, }, } { - account, payments, blocks, blockRate := setupDistTest(tt.cfg) + account, payments, blocks := setupDistTest(t, tt.cfg) - account, payments, overdrawn, remaining := accountSettleFullBlocks( - account, payments, blocks, blockRate) + overdrawn := accountSettleFullBlocks(&account, payments, blocks) + assert.Equal(t, tt.cfg.balanceEnd < 0, overdrawn, tt.name) - assertCoinsEqual(t, sdk.NewInt64DecCoin(denom, tt.cfg.balanceEnd), account.Balance, tt.name) - assertCoinsEqual(t, sdk.NewInt64DecCoin(denom, tt.cfg.fundsEnd), account.Funds, tt.name) + assertAmountEqual(t, sdkmath.LegacyNewDec(tt.cfg.balanceEnd), account.State.Funds[0].Amount, tt.name) for idx := range payments { - assert.Equal(t, sdk.NewDecCoinFromDec(denom, tt.cfg.transferred[idx]), payments[idx].Balance, tt.name) + assert.Equal(t, sdk.NewDecCoinFromDec(denom, tt.cfg.transferred[idx]), payments[idx].State.Balance, tt.name) } - - assertCoinsEqual(t, sdk.NewInt64DecCoin(denom, tt.cfg.remaining), remaining, tt.name) - assert.Equal(t, tt.cfg.overdrawn, overdrawn, tt.name) - } -} - -func TestSettleDistributeWeighted(t *testing.T) { - for _, tt := range []struct { - name string - cfg distTestConfig - }{ - { - name: "all goes - unbalanced", - cfg: distTestConfig{ - balanceStart: 10, - rates: []int64{20, 30}, - balanceEnd: 0, - transferred: []sdk.Dec{sdk.NewDec(4), sdk.NewDec(6)}, - remaining: 0, - overdrawn: false, - }, - }, - { - name: "all goes - balanced", - cfg: distTestConfig{ - balanceStart: 10, - rates: []int64{30, 30}, - balanceEnd: 0, - transferred: []sdk.Dec{sdk.NewDec(5), sdk.NewDec(5)}, - remaining: 0, - overdrawn: false, - }, - }, - { - name: "all goes - unbalanced", - cfg: distTestConfig{ - balanceStart: 10, - rates: []int64{45, 55}, - balanceEnd: 0, - transferred: []sdk.Dec{sdk.MustNewDecFromStr("4.5"), sdk.MustNewDecFromStr("5.5")}, - remaining: 0, - overdrawn: false, - }, - }, - } { - account, payments, _, blockRate := setupDistTest(tt.cfg) - - account, payments, remaining := accountSettleDistributeWeighted( - account, payments, blockRate, account.Balance) - - assertCoinsEqual(t, sdk.NewInt64DecCoin(denom, tt.cfg.balanceEnd), account.Balance, tt.name) - - for idx := range payments { - assert.Equal(t, sdk.NewDecCoinFromDec(denom, tt.cfg.transferred[idx]), payments[idx].Balance, tt.name) - } - - assertCoinsEqual(t, sdk.NewInt64DecCoin(denom, tt.cfg.remaining), remaining, tt.name) } } @@ -239,36 +117,54 @@ type distTestConfig struct { balanceStart int64 rates []int64 balanceEnd int64 - fundsStart int64 - fundsEnd int64 - transferred []sdk.Dec - remaining int64 - overdrawn bool + transferred []sdkmath.LegacyDec } -func setupDistTest(cfg distTestConfig) (types.Account, []types.FractionalPayment, sdk.Int, sdk.DecCoin) { - account := types.Account{ - Balance: sdk.NewInt64DecCoin(denom, cfg.balanceStart), - Transferred: sdk.NewInt64DecCoin(denom, 0), - Funds: sdk.NewInt64DecCoin(denom, cfg.fundsStart), +func setupDistTest(t *testing.T, cfg distTestConfig) (account, []payment, sdkmath.Int) { + account := account{ + Account: etypes.Account{ + State: etypes.AccountState{ + Funds: []etypes.Balance{ + { + Denom: denom, + Amount: sdkmath.LegacyNewDec(cfg.balanceStart), + }, + }, + Transferred: sdk.DecCoins{ + sdk.NewInt64DecCoin(denom, 0), + }, + Deposits: []etypes.Depositor{ + { + Owner: testutil.AccAddress(t).String(), + Height: 0, + Balance: sdk.NewDecCoinFromCoin(sdk.NewInt64Coin(denom, cfg.balanceStart)), + }, + }, + }, + }, } - payments := make([]types.FractionalPayment, 0, len(cfg.rates)) + payments := make([]payment, 0, len(cfg.rates)) blockRate := int64(0) for _, rate := range cfg.rates { blockRate += rate - payments = append(payments, types.FractionalPayment{ - Rate: sdk.NewInt64DecCoin(denom, rate), - Balance: sdk.NewInt64DecCoin(denom, 0), + payments = append(payments, payment{ + Payment: etypes.Payment{ + State: etypes.PaymentState{ + Rate: sdk.NewInt64DecCoin(denom, rate), + Balance: sdk.NewInt64DecCoin(denom, 0), + Unsettled: sdk.NewInt64DecCoin(denom, 0), + }, + }, }) } - return account, payments, sdk.NewInt(cfg.blocks), sdk.NewInt64DecCoin(denom, blockRate) + return account, payments, sdkmath.NewInt(cfg.blocks) } -func assertCoinsEqual(t testing.TB, c1 sdk.DecCoin, c2 sdk.DecCoin, msg string) { +func assertAmountEqual(t testing.TB, c1 sdkmath.LegacyDec, c2 sdkmath.LegacyDec, msg string) { t.Helper() if c1.IsZero() { if !c2.IsZero() { @@ -276,5 +172,5 @@ func assertCoinsEqual(t testing.TB, c1 sdk.DecCoin, c2 sdk.DecCoin, msg string) } return } - assert.Equal(t, c1.Amount, c2.Amount, msg) + assert.Equal(t, c1, c2, msg) } diff --git a/x/escrow/keeper/keeper_test.go b/x/escrow/keeper/keeper_test.go index 4e91454823..427dfef6db 100644 --- a/x/escrow/keeper/keeper_test.go +++ b/x/escrow/keeper/keeper_test.go @@ -6,222 +6,261 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "pkg.akt.dev/go/node/escrow/module" + etypes "pkg.akt.dev/go/node/escrow/types/v1" + "pkg.akt.dev/go/testutil" - types "github.com/akash-network/akash-api/go/node/escrow/v1beta3" - - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/testutil/cosmos/mocks" - "github.com/akash-network/node/testutil/state" - "github.com/akash-network/node/x/escrow/keeper" + cmocks "pkg.akt.dev/node/testutil/cosmos/mocks" + "pkg.akt.dev/node/testutil/state" + "pkg.akt.dev/node/x/escrow/keeper" ) func Test_AccountCreate(t *testing.T) { ctx, keeper, bkeeper := setupKeeper(t) - id := genAccountID(t) + id := testutil.DeploymentID(t).ToEscrowAccountID() + owner := testutil.AccAddress(t) amt := testutil.AkashCoinRandom(t) amt2 := testutil.AkashCoinRandom(t) // create account bkeeper. - On("SendCoinsFromAccountToModule", ctx, owner, types.ModuleName, sdk.NewCoins(amt)). + On("SendCoinsFromAccountToModule", ctx, owner, module.ModuleName, sdk.NewCoins(amt)). Return(nil) - assert.NoError(t, keeper.AccountCreate(ctx, id, owner, owner, amt)) + assert.NoError(t, keeper.AccountCreate(ctx, id, owner, []etypes.Depositor{{ + Owner: owner.String(), + Height: ctx.BlockHeight(), + Balance: sdk.NewDecCoinFromCoin(amt), + }})) // deposit more tokens ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 10) bkeeper. - On("SendCoinsFromAccountToModule", ctx, owner, types.ModuleName, sdk.NewCoins(amt2)). + On("SendCoinsFromAccountToModule", ctx, owner, module.ModuleName, sdk.NewCoins(amt2)). Return(nil) - assert.NoError(t, keeper.AccountDeposit(ctx, id, owner, amt2)) + assert.NoError(t, keeper.AccountDeposit(ctx, id, []etypes.Depositor{{ + Owner: owner.String(), + Height: ctx.BlockHeight(), + Balance: sdk.NewDecCoinFromCoin(amt2), + }})) // close account ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 10) bkeeper. - On("SendCoinsFromModuleToAccount", ctx, types.ModuleName, owner, sdk.NewCoins(amt.Add(amt2))). + On("SendCoinsFromModuleToAccount", ctx, module.ModuleName, owner, sdk.NewCoins(amt.Add(amt2))). Return(nil) assert.NoError(t, keeper.AccountClose(ctx, id)) // no deposits after closed - assert.Error(t, keeper.AccountDeposit(ctx, id, owner, amt)) + assert.Error(t, keeper.AccountDeposit(ctx, id, []etypes.Depositor{{ + Owner: owner.String(), + Height: ctx.BlockHeight(), + Balance: sdk.NewDecCoinFromCoin(amt), + }})) // no re-creating account - assert.Error(t, keeper.AccountCreate(ctx, id, owner, owner, amt)) + assert.Error(t, keeper.AccountCreate(ctx, id, owner, []etypes.Depositor{{ + Owner: owner.String(), + Height: ctx.BlockHeight(), + Balance: sdk.NewDecCoinFromCoin(amt), + }})) } func Test_PaymentCreate(t *testing.T) { ctx, keeper, bkeeper := setupKeeper(t) - aid := genAccountID(t) + lid := testutil.LeaseID(t) + did := lid.DeploymentID() + + aid := did.ToEscrowAccountID() + pid := lid.ToEscrowPaymentID() + aowner := testutil.AccAddress(t) amt := testutil.AkashCoin(t, 1000) - pid := testutil.Name(t, "payment") powner := testutil.AccAddress(t) rate := testutil.AkashCoin(t, 10) // create account bkeeper. - On("SendCoinsFromAccountToModule", ctx, aowner, types.ModuleName, sdk.NewCoins(amt)). + On("SendCoinsFromAccountToModule", ctx, aowner, module.ModuleName, sdk.NewCoins(amt)). Return(nil) - assert.NoError(t, keeper.AccountCreate(ctx, aid, aowner, aowner, amt)) + assert.NoError(t, keeper.AccountCreate(ctx, aid, aowner, []etypes.Depositor{{ + Owner: aowner.String(), + Height: ctx.BlockHeight(), + Balance: sdk.NewDecCoinFromCoin(amt), + }})) { acct, err := keeper.GetAccount(ctx, aid) require.NoError(t, err) - require.Equal(t, ctx.BlockHeight(), acct.SettledAt) + require.Equal(t, ctx.BlockHeight(), acct.State.SettledAt) } // create payment - assert.NoError(t, keeper.PaymentCreate(ctx, aid, pid, powner, sdk.NewDecCoinFromCoin(rate))) + err := keeper.PaymentCreate(ctx, pid, powner, sdk.NewDecCoinFromCoin(rate)) + assert.NoError(t, err) // withdraw some funds blkdelta := int64(10) ctx = ctx.WithBlockHeight(ctx.BlockHeight() + blkdelta) bkeeper. - On("SendCoinsFromModuleToAccount", ctx, types.ModuleName, powner, sdk.NewCoins(testutil.AkashCoin(t, rate.Amount.Int64()*blkdelta))). + On("SendCoinsFromModuleToAccount", ctx, module.ModuleName, powner, sdk.NewCoins(testutil.AkashCoin(t, rate.Amount.Int64()*blkdelta))). Return(nil) - assert.NoError(t, keeper.PaymentWithdraw(ctx, aid, pid)) + err = keeper.PaymentWithdraw(ctx, pid) + assert.NoError(t, err) { acct, err := keeper.GetAccount(ctx, aid) require.NoError(t, err) - require.Equal(t, ctx.BlockHeight(), acct.SettledAt) + require.Equal(t, ctx.BlockHeight(), acct.State.SettledAt) - require.Equal(t, types.AccountOpen, acct.State) - require.Equal(t, testutil.AkashDecCoin(t, amt.Amount.Int64()-rate.Amount.Int64()*ctx.BlockHeight()), acct.Balance) - require.Equal(t, testutil.AkashDecCoin(t, rate.Amount.Int64()*ctx.BlockHeight()), acct.Transferred) + require.Equal(t, etypes.StateOpen, acct.State.State) + require.Equal(t, testutil.AkashDecCoin(t, amt.Amount.Int64()-rate.Amount.Int64()*ctx.BlockHeight()), sdk.NewDecCoinFromDec(acct.State.Funds[0].Denom, acct.State.Funds[0].Amount)) + require.Equal(t, testutil.AkashDecCoin(t, rate.Amount.Int64()*ctx.BlockHeight()), acct.State.Transferred[0]) - payment, err := keeper.GetPayment(ctx, aid, pid) + payment, err := keeper.GetPayment(ctx, pid) require.NoError(t, err) - require.Equal(t, types.PaymentOpen, payment.State) - require.Equal(t, testutil.AkashCoin(t, rate.Amount.Int64()*ctx.BlockHeight()), payment.Withdrawn) - require.Equal(t, testutil.AkashDecCoin(t, 0), payment.Balance) + require.Equal(t, etypes.StateOpen, payment.State.State) + require.Equal(t, testutil.AkashCoin(t, rate.Amount.Int64()*ctx.BlockHeight()), payment.State.Withdrawn) + require.Equal(t, testutil.AkashDecCoin(t, 0), payment.State.Balance) } // close payment blkdelta = 20 ctx = ctx.WithBlockHeight(ctx.BlockHeight() + blkdelta) bkeeper. - On("SendCoinsFromModuleToAccount", ctx, types.ModuleName, powner, sdk.NewCoins(testutil.AkashCoin(t, rate.Amount.Int64()*blkdelta))). + On("SendCoinsFromModuleToAccount", ctx, module.ModuleName, powner, sdk.NewCoins(testutil.AkashCoin(t, rate.Amount.Int64()*blkdelta))). Return(nil) - assert.NoError(t, keeper.PaymentClose(ctx, aid, pid)) + assert.NoError(t, keeper.PaymentClose(ctx, pid)) { acct, err := keeper.GetAccount(ctx, aid) require.NoError(t, err) - require.Equal(t, ctx.BlockHeight(), acct.SettledAt) + require.Equal(t, ctx.BlockHeight(), acct.State.SettledAt) - require.Equal(t, types.AccountOpen, acct.State) - require.Equal(t, testutil.AkashDecCoin(t, amt.Amount.Int64()-rate.Amount.Int64()*ctx.BlockHeight()), acct.Balance) - require.Equal(t, testutil.AkashDecCoin(t, rate.Amount.Int64()*ctx.BlockHeight()), acct.Transferred) + require.Equal(t, etypes.StateOpen, acct.State.State) + require.Equal(t, testutil.AkashDecCoin(t, amt.Amount.Int64()-rate.Amount.Int64()*ctx.BlockHeight()), sdk.NewDecCoinFromDec(acct.State.Funds[0].Denom, acct.State.Funds[0].Amount)) + require.Equal(t, testutil.AkashDecCoin(t, rate.Amount.Int64()*ctx.BlockHeight()), acct.State.Transferred[0]) - payment, err := keeper.GetPayment(ctx, aid, pid) + payment, err := keeper.GetPayment(ctx, pid) require.NoError(t, err) - require.Equal(t, types.PaymentClosed, payment.State) - require.Equal(t, testutil.AkashCoin(t, rate.Amount.Int64()*ctx.BlockHeight()), payment.Withdrawn) - require.Equal(t, testutil.AkashDecCoin(t, 0), payment.Balance) + require.Equal(t, etypes.StateClosed, payment.State.State) + require.Equal(t, testutil.AkashCoin(t, rate.Amount.Int64()*ctx.BlockHeight()), payment.State.Withdrawn) + require.Equal(t, testutil.AkashDecCoin(t, 0), payment.State.Balance) } ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 30) // can't withdraw from a closed payment - assert.Error(t, keeper.PaymentWithdraw(ctx, aid, pid)) + assert.Error(t, keeper.PaymentWithdraw(ctx, pid)) // can't re-created a closed payment - assert.Error(t, keeper.PaymentCreate(ctx, aid, pid, powner, sdk.NewDecCoinFromCoin(rate))) + assert.Error(t, keeper.PaymentCreate(ctx, pid, powner, sdk.NewDecCoinFromCoin(rate))) // closing the account transfers all remaining funds bkeeper. - On("SendCoinsFromModuleToAccount", ctx, types.ModuleName, aowner, sdk.NewCoins(testutil.AkashCoin(t, amt.Amount.Int64()-rate.Amount.Int64()*30))). + On("SendCoinsFromModuleToAccount", ctx, module.ModuleName, aowner, sdk.NewCoins(testutil.AkashCoin(t, amt.Amount.Int64()-rate.Amount.Int64()*30))). Return(nil) assert.NoError(t, keeper.AccountClose(ctx, aid)) } func Test_Payment_Overdraw(t *testing.T) { ctx, keeper, bkeeper := setupKeeper(t) - aid := genAccountID(t) + lid := testutil.LeaseID(t) + did := lid.DeploymentID() + + aid := did.ToEscrowAccountID() + pid := lid.ToEscrowPaymentID() + aowner := testutil.AccAddress(t) amt := testutil.AkashCoin(t, 1000) - pid := testutil.Name(t, "payment") powner := testutil.AccAddress(t) rate := testutil.AkashCoin(t, 10) // create account bkeeper. - On("SendCoinsFromAccountToModule", ctx, aowner, types.ModuleName, sdk.NewCoins(amt)). + On("SendCoinsFromAccountToModule", ctx, aowner, module.ModuleName, sdk.NewCoins(amt)). Return(nil) - assert.NoError(t, keeper.AccountCreate(ctx, aid, aowner, aowner, amt)) + err := keeper.AccountCreate(ctx, aid, aowner, []etypes.Depositor{{ + Owner: aowner.String(), + Height: ctx.BlockHeight(), + Balance: sdk.NewDecCoinFromCoin(amt), + }}) + + require.NoError(t, err) // create payment - assert.NoError(t, keeper.PaymentCreate(ctx, aid, pid, powner, sdk.NewDecCoinFromCoin(rate))) + err = keeper.PaymentCreate(ctx, pid, powner, sdk.NewDecCoinFromCoin(rate)) + require.NoError(t, err) // withdraw some funds - blkdelta := int64(1000/10 + 1) + blkdelta := int64(1000/10 + 5) ctx = ctx.WithBlockHeight(ctx.BlockHeight() + blkdelta) bkeeper. - On("SendCoinsFromModuleToAccount", ctx, types.ModuleName, powner, sdk.NewCoins(testutil.AkashCoin(t, 1000))). + On("SendCoinsFromModuleToAccount", ctx, module.ModuleName, powner, sdk.NewCoins(testutil.AkashCoin(t, 1000))). Return(nil) - assert.NoError(t, keeper.PaymentWithdraw(ctx, aid, pid)) + + err = keeper.PaymentWithdraw(ctx, pid) + require.NoError(t, err) { acct, err := keeper.GetAccount(ctx, aid) require.NoError(t, err) - assert.Equal(t, ctx.BlockHeight(), acct.SettledAt) + require.Equal(t, ctx.BlockHeight(), acct.State.SettledAt) - assert.Equal(t, types.AccountOverdrawn, acct.State) - assert.Equal(t, testutil.AkashDecCoin(t, 0), acct.Balance) - assert.Equal(t, sdk.NewDecCoinFromCoin(amt), acct.Transferred) + require.Equal(t, etypes.StateOverdrawn, acct.State.State) + require.True(t, acct.State.Funds[0].Amount.IsNegative()) + require.Equal(t, sdk.NewDecCoins(sdk.NewDecCoinFromCoin(amt)), acct.State.Transferred) - payment, err := keeper.GetPayment(ctx, aid, pid) - assert.NoError(t, err) + payment, err := keeper.GetPayment(ctx, pid) + require.NoError(t, err) - assert.Equal(t, types.PaymentOverdrawn, payment.State) - assert.Equal(t, amt, payment.Withdrawn) - assert.Equal(t, testutil.AkashDecCoin(t, 0), payment.Balance) + require.Equal(t, etypes.StateOverdrawn, payment.State.State) + require.Equal(t, amt, payment.State.Withdrawn) + require.Equal(t, testutil.AkashDecCoin(t, 0), payment.State.Balance) } - } func Test_PaymentCreate_later(t *testing.T) { ctx, keeper, bkeeper := setupKeeper(t) - aid := genAccountID(t) + lid := testutil.LeaseID(t) + did := lid.DeploymentID() + + aid := did.ToEscrowAccountID() + pid := lid.ToEscrowPaymentID() + aowner := testutil.AccAddress(t) amt := testutil.AkashCoin(t, 1000) - pid := testutil.Name(t, "payment") powner := testutil.AccAddress(t) rate := testutil.AkashCoin(t, 10) // create account bkeeper. - On("SendCoinsFromAccountToModule", ctx, aowner, types.ModuleName, sdk.NewCoins(amt)). + On("SendCoinsFromAccountToModule", ctx, aowner, module.ModuleName, sdk.NewCoins(amt)). Return(nil) - assert.NoError(t, keeper.AccountCreate(ctx, aid, aowner, aowner, amt)) + assert.NoError(t, keeper.AccountCreate(ctx, aid, aowner, []etypes.Depositor{{ + Owner: aowner.String(), + Height: ctx.BlockHeight(), + Balance: sdk.NewDecCoinFromCoin(amt), + }})) blkdelta := int64(10) ctx = ctx.WithBlockHeight(ctx.BlockHeight() + blkdelta) // create payment - assert.NoError(t, keeper.PaymentCreate(ctx, aid, pid, powner, sdk.NewDecCoinFromCoin(rate))) + assert.NoError(t, keeper.PaymentCreate(ctx, pid, powner, sdk.NewDecCoinFromCoin(rate))) { acct, err := keeper.GetAccount(ctx, aid) require.NoError(t, err) - require.Equal(t, ctx.BlockHeight(), acct.SettledAt) - } -} - -func genAccountID(t testing.TB) types.AccountID { - t.Helper() - return types.AccountID{ - Scope: "test", - XID: testutil.Name(t, "acct"), + require.Equal(t, ctx.BlockHeight(), acct.State.SettledAt) } } -func setupKeeper(t testing.TB) (sdk.Context, keeper.Keeper, *mocks.BankKeeper) { +func setupKeeper(t testing.TB) (sdk.Context, keeper.Keeper, *cmocks.BankKeeper) { t.Helper() ssuite := state.SetupTestSuite(t) return ssuite.Context(), ssuite.EscrowKeeper(), ssuite.BankKeeper() diff --git a/x/escrow/keeper/key.go b/x/escrow/keeper/key.go index a6c573ab0f..efa61b43ec 100644 --- a/x/escrow/keeper/key.go +++ b/x/escrow/keeper/key.go @@ -2,42 +2,191 @@ package keeper import ( "bytes" + "fmt" + "strings" - types "github.com/akash-network/akash-api/go/node/escrow/v1beta3" + escrowid "pkg.akt.dev/go/node/escrow/id/v1" + etypes "pkg.akt.dev/go/node/escrow/types/v1" + "pkg.akt.dev/go/node/escrow/v1beta3" ) -func accountKey(id types.AccountID) []byte { - // TODO: validate scope, xid - buf := bytes.Buffer{} - buf.Write(types.AccountKeyPrefix()) - buf.WriteRune('/') - buf.WriteString(id.Scope) +const ( + StateOpenPrefixID = byte(0x01) + StateClosedPrefixID = byte(0x02) + StateOverdrawnPrefixID = byte(0x03) +) + +var ( + AccountPrefix = []byte{0x11, 0x00} + PaymentPrefix = []byte{0x12, 0x00} + StateOpenPrefix = []byte{StateOpenPrefixID} + StateClosedPrefix = []byte{StateClosedPrefixID} + StateOverdrawnPrefix = []byte{StateOverdrawnPrefixID} +) + +func BuildAccountsKey(state etypes.State, id escrowid.ID) []byte { + buf := &bytes.Buffer{} + buf.Write(AccountPrefix) + writeKey(buf, state, id) + + return buf.Bytes() +} + +func writeKey(buf *bytes.Buffer, state etypes.State, id escrowid.ID) { + if state != etypes.StateInvalid { + buf.Write(stateToPrefix(state)) + + if id != nil { + writeId(buf, id) + } + } +} + +func writeId(buf *bytes.Buffer, id escrowid.ID) { buf.WriteRune('/') - buf.WriteString(id.XID) + buf.WriteString(id.Key()) +} + +func BuildPaymentsKey(state etypes.State, id escrowid.ID) []byte { + buf := &bytes.Buffer{} + buf.Write(PaymentPrefix) + writeKey(buf, state, id) + return buf.Bytes() } -func accountPaymentsKey(id types.AccountID) []byte { - // TODO: validate scope, xid, pid - buf := bytes.Buffer{} - buf.Write(types.PaymentKeyPrefix()) +func stateToPrefix(state etypes.State) []byte { + switch state { + case etypes.StateOpen: + return StateOpenPrefix + case etypes.StateClosed: + return StateClosedPrefix + case etypes.StateOverdrawn: + return StateOverdrawnPrefix + default: + panic(fmt.Sprintf("invalid state %d", state)) + } +} + +func ParseAccountKey(key []byte) (escrowid.Account, etypes.State) { + if len(key) < len(AccountPrefix)+2 { + panic("malformed account key") + } + + if !bytes.HasPrefix(key, AccountPrefix) { + panic("malformed account prefix") + } + + key = key[len(AccountPrefix):] + state := etypes.State(key[0]) + + key = key[1:] + + if key[0] != '/' { + panic("malformed account separator") + } + + key = key[1:] + + parts := strings.Split(string(key), "/") + if len(parts) < 3 { + panic(fmt.Sprintf("malformed account key \"%s\"", string(key))) + } + + scopeVal, valid := escrowid.Scope_value[parts[0]] + if !valid { + panic(fmt.Sprintf("invalid account scope \"%s\"", parts[0])) + } + + parts = parts[1:] + + scope := escrowid.Scope(scopeVal) + + switch scope { + case escrowid.ScopeDeployment: + if len(parts) != 2 { + panic(fmt.Sprintf("malformed account key \"%s\"", string(key))) + } + case escrowid.ScopeBid: + if len(parts) != 5 { + panic(fmt.Sprintf("malformed account key \"%s\"", string(key))) + } + } + + return escrowid.Account{ + Scope: scope, + XID: strings.Join(parts, "/"), + }, state +} + +func ParsePaymentKey(key []byte) (escrowid.Payment, etypes.State) { + if len(key) < len(PaymentPrefix)+1 { + panic("malformed payment key") + } + + if !bytes.HasPrefix(key, PaymentPrefix) { + panic("malformed payment prefix") + } + + key = key[len(PaymentPrefix):] + state := etypes.State(key[0]) + + key = key[1:] + + if key[0] != '/' { + panic("malformed payment separator") + } + + key = key[1:] + + parts := strings.Split(string(key), "/") + + if len(parts) != 6 { + panic(fmt.Sprintf("malformed payment key \"%s\"", string(key))) + } + + scope, valid := escrowid.Scope_value[parts[0]] + if !valid { + panic(fmt.Sprintf("invalid payment scope \"%s\"", parts[0])) + } + + return escrowid.Payment{ + AID: escrowid.Account{ + Scope: escrowid.Scope(scope), + XID: strings.Join(parts[1:3], "/"), + }, + XID: strings.Join(parts[3:], "/"), + }, state +} + +func LegacyAccountKey(id v1beta3.AccountID) []byte { + // TODO: validate scope, xid + buf := &bytes.Buffer{} + + buf.Write(v1beta3.AccountKeyPrefix()) buf.WriteRune('/') buf.WriteString(id.Scope) buf.WriteRune('/') buf.WriteString(id.XID) - buf.WriteRune('/') + return buf.Bytes() } -func paymentKey(id types.AccountID, pid string) []byte { - // TODO: validate scope, xid, pid - buf := bytes.Buffer{} - buf.Write(types.PaymentKeyPrefix()) +func keyWritePaymentPrefix(buf *bytes.Buffer, id v1beta3.AccountID) { + buf.Write(v1beta3.PaymentKeyPrefix()) buf.WriteRune('/') buf.WriteString(id.Scope) buf.WriteRune('/') buf.WriteString(id.XID) buf.WriteRune('/') +} + +func LegacyPaymentKey(id v1beta3.AccountID, pid string) []byte { + // TODO: validate scope, xid, pid + buf := &bytes.Buffer{} + + keyWritePaymentPrefix(buf, id) buf.WriteString(pid) + return buf.Bytes() } diff --git a/x/escrow/keeper/querier.go b/x/escrow/keeper/querier.go index 670f23ce55..e57e511c3f 100644 --- a/x/escrow/keeper/querier.go +++ b/x/escrow/keeper/querier.go @@ -1,9 +1,9 @@ package keeper import ( - types "github.com/akash-network/akash-api/go/node/escrow/v1beta3" + types "pkg.akt.dev/go/node/escrow/v1" ) -func NewQuerier(k Keeper) types.QueryServer { +func NewQuerier(_ Keeper) types.QueryServer { return nil } diff --git a/x/escrow/module.go b/x/escrow/module.go index 8a2486e014..92ffd660d1 100644 --- a/x/escrow/module.go +++ b/x/escrow/module.go @@ -4,36 +4,37 @@ import ( "context" "encoding/json" "fmt" - "math/rand" - "github.com/gogo/protobuf/grpc" + "cosmossdk.io/core/appmodule" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/gogoproto/grpc" "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" - - abci "github.com/tendermint/tendermint/abci/types" + emodule "pkg.akt.dev/go/node/escrow/module" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - sim "github.com/cosmos/cosmos-sdk/types/simulation" - - v1beta1types "github.com/akash-network/akash-api/go/node/escrow/v1beta1" - v1beta2types "github.com/akash-network/akash-api/go/node/escrow/v1beta2" - types "github.com/akash-network/akash-api/go/node/escrow/v1beta3" + v1 "pkg.akt.dev/go/node/escrow/v1" - "github.com/akash-network/node/x/escrow/client/cli" - "github.com/akash-network/node/x/escrow/client/rest" - "github.com/akash-network/node/x/escrow/keeper" - "github.com/akash-network/node/x/escrow/query" + "pkg.akt.dev/node/x/escrow/client/rest" + "pkg.akt.dev/node/x/escrow/handler" + "pkg.akt.dev/node/x/escrow/keeper" ) var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} - _ module.AppModuleSimulation = AppModuleSimulation{} + _ module.AppModuleBasic = AppModuleBasic{} + _ module.HasGenesisBasics = AppModuleBasic{} + + _ appmodule.AppModule = AppModule{} + _ module.HasConsensusVersion = AppModule{} + _ module.HasGenesis = AppModule{} + _ module.HasServices = AppModule{} + + _ module.AppModuleSimulation = AppModule{} ) // AppModuleBasic defines the basic application module used by the provider module. @@ -43,19 +44,17 @@ type AppModuleBasic struct { // Name returns provider module's name func (AppModuleBasic) Name() string { - return types.ModuleName + return emodule.ModuleName } // RegisterLegacyAminoCodec registers the provider module's types for the given codec. func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { - types.RegisterLegacyAminoCodec(cdc) + v1.RegisterLegacyAminoCodec(cdc) } // RegisterInterfaces registers the module's interface types func (b AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) { - types.RegisterInterfaces(registry) - v1beta2types.RegisterInterfaces(registry) - v1beta1types.RegisterInterfaces(registry) + v1.RegisterInterfaces(registry) } // DefaultGenesis returns default genesis state as raw bytes for the provider @@ -70,11 +69,11 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingCo return nil } - var data types.GenesisState + var data v1.GenesisState err := cdc.UnmarshalJSON(bz, &data) if err != nil { - return fmt.Errorf("failed to unmarshal %s genesis state: %v", types.ModuleName, err) + return fmt.Errorf("failed to unmarshal %s genesis state: %v", emodule.ModuleName, err) } return ValidateGenesis(&data) @@ -82,105 +81,99 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingCo // RegisterRESTRoutes registers rest routes for this module func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { - rest.RegisterRoutes(clientCtx, rtr, types.StoreKey) + rest.RegisterRoutes(clientCtx, rtr, emodule.StoreKey) } // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the provider module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + err := v1.RegisterQueryHandlerClient(context.Background(), mux, v1.NewQueryClient(clientCtx)) if err != nil { panic(fmt.Sprintf("couldn't register provider grpc routes: %s", err.Error())) } } -// RegisterGRPCRoutes registers the gRPC Gateway routes for the provider module. -func (AppModuleBasic) RegisterGRPCRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) - if err != nil { - panic(fmt.Sprintf("couldn't register audit grpc routes: %s", err.Error())) - } -} - // GetQueryCmd returns the root query command of this module func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.GetQueryCmd() + panic("akash modules do not export cli commands via cosmos interface") } // GetTxCmd returns the transaction commands for this module func (AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.GetTxCmd() + panic("akash modules do not export cli commands via cosmos interface") } // GetQueryClient returns a new query client for this module -func (AppModuleBasic) GetQueryClient(clientCtx client.Context) types.QueryClient { - return types.NewQueryClient(clientCtx) +func (AppModuleBasic) GetQueryClient(clientCtx client.Context) v1.QueryClient { + return v1.NewQueryClient(clientCtx) } // AppModule implements an application module for the audit module. type AppModule struct { AppModuleBasic - keeper keeper.Keeper + keeper keeper.Keeper + authzKeeper keeper.AuthzKeeper + bankKeeper keeper.BankKeeper } // NewAppModule creates a new AppModule object -func NewAppModule(cdc codec.Codec, k keeper.Keeper) AppModule { +func NewAppModule(cdc codec.Codec, k keeper.Keeper, authzKeeper keeper.AuthzKeeper, bankKeeper keeper.BankKeeper) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{cdc: cdc}, keeper: k, + authzKeeper: authzKeeper, + bankKeeper: bankKeeper, } } // Name returns the provider module name func (AppModule) Name() string { - return types.ModuleName + return emodule.ModuleName } -// RegisterInvariants registers module invariants -func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (am AppModule) IsOnePerModuleType() {} -// Route returns the message routing key for the audit module. -func (am AppModule) Route() sdk.Route { - return sdk.NewRoute(types.RouterKey, nil) -} +// IsAppModule implements the appmodule.AppModule interface. +func (am AppModule) IsAppModule() {} // QuerierRoute returns the audit module's querier route name. func (am AppModule) QuerierRoute() string { - return types.ModuleName + return emodule.ModuleName } -// LegacyQuerierHandler returns the sdk.Querier for audit module -func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { - return query.NewQuerier(am.keeper, legacyQuerierCdc) -} - -// RegisterServices registers the module's servicess +// RegisterServices registers the module's services func (am AppModule) RegisterServices(cfg module.Configurator) { - querier := keeper.NewQuerier(am.keeper) - types.RegisterQueryServer(cfg.QueryServer(), querier) + v1.RegisterMsgServer(cfg.MsgServer(), handler.NewServer(am.keeper, am.authzKeeper, am.bankKeeper)) + + querier := am.keeper.NewQuerier() + + v1.RegisterQueryServer(cfg.QueryServer(), querier) } // RegisterQueryService registers a GRPC query service to respond to the // module-specific GRPC queries. func (am AppModule) RegisterQueryService(server grpc.Server) { querier := keeper.NewQuerier(am.keeper) - types.RegisterQueryServer(server, querier) + v1.RegisterQueryServer(server, querier) } // BeginBlock performs no-op -func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} +func (am AppModule) BeginBlock(_ context.Context) error { + return nil +} -// EndBlock returns the end blocker for the audit module. It returns no auditor +// EndBlock returns the end blocker for the deployment module. It returns no validator // updates. -func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - return []abci.ValidatorUpdate{} +func (am AppModule) EndBlock(_ context.Context) error { + return nil } -// InitGenesis performs genesis initialization for the audit module. It returns +// InitGenesis performs genesis initialization for the escrow module. It returns // no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { - var genesisState types.GenesisState +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) { + var genesisState v1.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) - return InitGenesis(ctx, am.keeper, &genesisState) + InitGenesis(ctx, am.keeper, &genesisState) } // ExportGenesis returns the exported genesis state as raw bytes for the audit @@ -192,11 +185,23 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw // ConsensusVersion implements module.AppModule#ConsensusVersion func (am AppModule) ConsensusVersion() uint64 { - return 2 + return 3 } // ____________________________________________________________________________ +// RegisterStoreDecoder registers a decoder for take module's types. +func (am AppModule) RegisterStoreDecoder(_ simtypes.StoreDecoderRegistry) {} + +// WeightedOperations doesn't return any take module operation. +func (am AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { + return []simtypes.WeightedOperation{} +} + +// GenerateGenesisState creates a randomized GenState of the staking module. +func (AppModule) GenerateGenesisState(_ *module.SimulationState) { +} + // AppModuleSimulation implements an application simulation module for the audit module. type AppModuleSimulation struct { keeper keeper.Keeper @@ -209,28 +214,28 @@ func NewAppModuleSimulation(k keeper.Keeper) AppModuleSimulation { } } -// AppModuleSimulation functions -// GenerateGenesisState creates a randomized GenState of the staking module. -func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) { - // simulation.RandomizedGenState(simState) -} - -// ProposalContents doesn't return any content functions for governance proposals. -func (AppModuleSimulation) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent { - return nil -} - -// RandomizedParams creates randomized staking param changes for the simulator. -func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange { - return nil -} - -// RegisterStoreDecoder registers a decoder for staking module's types -func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { - -} - -// WeightedOperations returns the all the staking module operations with their respective weights. -func (am AppModuleSimulation) WeightedOperations(simState module.SimulationState) []sim.WeightedOperation { - return nil -} +// // AppModuleSimulation functions +// // GenerateGenesisState creates a randomized GenState of the staking module. +// func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) { +// // simulation.RandomizedGenState(simState) +// } +// +// // ProposalContents doesn't return any content functions for governance proposals. +// func (AppModuleSimulation) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent { +// return nil +// } +// +// // RandomizedParams creates randomized staking param changes for the simulator. +// func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange { +// return nil +// } +// +// // RegisterStoreDecoder registers a decoder for staking module's types +// func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { +// +// } +// +// // WeightedOperations returns the all the staking module operations with their respective weights. +// func (am AppModuleSimulation) WeightedOperations(simState module.SimulationState) []sim.WeightedOperation { +// return nil +// } diff --git a/x/escrow/query/querier.go b/x/escrow/query/querier.go index 7824bb2651..8e8e47f68f 100644 --- a/x/escrow/query/querier.go +++ b/x/escrow/query/querier.go @@ -1,12 +1,12 @@ package query -import ( - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/akash-network/node/x/escrow/keeper" -) - -func NewQuerier(keeper keeper.Keeper, cdc *codec.LegacyAmino) sdk.Querier { - return nil -} +// import ( +// "github.com/cosmos/cosmos-sdk/codec" +// sdk "github.com/cosmos/cosmos-sdk/types" +// +// "pkg.akt.dev/node/x/escrow/keeper" +// ) +// +// func NewQuerier(keeper keeper.Keeper, cdc *codec.LegacyAmino) sdk.Querier { +// return nil +// } diff --git a/x/gov/alias.go b/x/gov/alias.go deleted file mode 100644 index c30bd8fdef..0000000000 --- a/x/gov/alias.go +++ /dev/null @@ -1,24 +0,0 @@ -package provider - -import ( - types "github.com/akash-network/akash-api/go/node/gov/v1beta3" - - "github.com/akash-network/node/x/gov/keeper" -) - -const ( - // StoreKey represents storekey of provider module - StoreKey = types.StoreKey - // ModuleName represents current module name - ModuleName = types.ModuleName -) - -type ( - // Keeper defines keeper of provider module - Keeper = keeper.Keeper -) - -var ( - // NewKeeper creates new keeper instance of provider module - NewKeeper = keeper.NewKeeper -) diff --git a/x/gov/genesis.go b/x/gov/genesis.go deleted file mode 100644 index 2b7b7638c7..0000000000 --- a/x/gov/genesis.go +++ /dev/null @@ -1,54 +0,0 @@ -package provider - -import ( - "encoding/json" - - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" - - types "github.com/akash-network/akash-api/go/node/gov/v1beta3" - - "github.com/akash-network/node/x/gov/keeper" -) - -// ValidateGenesis does validation check of the Genesis and returns error in case of failure -func ValidateGenesis(data *types.GenesisState) error { - return data.DepositParams.Validate() -} - -// DefaultGenesisState returns default genesis state as raw bytes for the provider -// module. -func DefaultGenesisState() *types.GenesisState { - return &types.GenesisState{ - DepositParams: types.DefaultDepositParams(), - } -} - -// InitGenesis initiate genesis state and return updated validator details -func InitGenesis(ctx sdk.Context, keeper keeper.IKeeper, data *types.GenesisState) []abci.ValidatorUpdate { - if err := keeper.SetDepositParams(ctx, data.DepositParams); err != nil { - panic(err) - } - - return []abci.ValidatorUpdate{} -} - -// ExportGenesis returns genesis state as raw bytes for the provider module -func ExportGenesis(ctx sdk.Context, k keeper.IKeeper) *types.GenesisState { - return &types.GenesisState{ - DepositParams: k.GetDepositParams(ctx), - } -} - -// GetGenesisStateFromAppState returns x/gov GenesisState given raw application -// genesis state. -func GetGenesisStateFromAppState(cdc codec.JSONCodec, appState map[string]json.RawMessage) *types.GenesisState { - var genesisState types.GenesisState - - if appState[ModuleName] != nil { - cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState) - } - - return &genesisState -} diff --git a/x/gov/keeper/keeper.go b/x/gov/keeper/keeper.go deleted file mode 100644 index 001f4a96c7..0000000000 --- a/x/gov/keeper/keeper.go +++ /dev/null @@ -1,60 +0,0 @@ -package keeper - -import ( - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - - types "github.com/akash-network/akash-api/go/node/gov/v1beta3" -) - -type IKeeper interface { - Codec() codec.BinaryCodec - StoreKey() sdk.StoreKey - SetDepositParams(ctx sdk.Context, params types.DepositParams) error - GetDepositParams(ctx sdk.Context) (params types.DepositParams) -} - -// Keeper of the provider store -type Keeper struct { - skey sdk.StoreKey - cdc codec.BinaryCodec - pspace paramtypes.Subspace -} - -// NewKeeper creates and returns an instance for Provider keeper -func NewKeeper(cdc codec.BinaryCodec, skey sdk.StoreKey, pspace paramtypes.Subspace) IKeeper { - if !pspace.HasKeyTable() { - pspace = pspace.WithKeyTable(types.ParamKeyTable()) - } - - return Keeper{ - skey: skey, - cdc: cdc, - pspace: pspace, - } -} - -// Codec returns keeper codec -func (k Keeper) Codec() codec.BinaryCodec { - return k.cdc -} - -func (k Keeper) StoreKey() sdk.StoreKey { - return k.skey -} - -// SetDepositParams sets the deployment parameters to the paramspace. -func (k Keeper) SetDepositParams(ctx sdk.Context, params types.DepositParams) error { - k.pspace.Set(ctx, types.KeyDepositParams, ¶ms) - - return nil -} - -// GetDepositParams returns the total set of x/gov parameters. -func (k Keeper) GetDepositParams(ctx sdk.Context) types.DepositParams { - var params types.DepositParams - - k.pspace.Get(ctx, types.KeyDepositParams, ¶ms) - return params -} diff --git a/x/gov/module.go b/x/gov/module.go deleted file mode 100644 index f2d87fb1fa..0000000000 --- a/x/gov/module.go +++ /dev/null @@ -1,195 +0,0 @@ -package provider - -import ( - "encoding/json" - "fmt" - "math/rand" - - "github.com/gorilla/mux" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" - - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - cdctypes "github.com/cosmos/cosmos-sdk/codec/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - sim "github.com/cosmos/cosmos-sdk/types/simulation" - - types "github.com/akash-network/akash-api/go/node/gov/v1beta3" - - "github.com/akash-network/node/x/gov/keeper" - "github.com/akash-network/node/x/gov/simulation" -) - -var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} - _ module.AppModuleSimulation = AppModuleSimulation{} -) - -// AppModuleBasic defines the basic application module used by the provider module. -type AppModuleBasic struct { - cdc codec.Codec -} - -// Name returns provider module's name -func (AppModuleBasic) Name() string { - return types.ModuleName -} - -// RegisterLegacyAminoCodec registers the provider module's types for the given codec. -func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { - -} - -// RegisterInterfaces registers the module's interface types -func (b AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) { -} - -// DefaultGenesis returns default genesis state as raw bytes for the provider -// module. -func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { - return cdc.MustMarshalJSON(DefaultGenesisState()) -} - -// ValidateGenesis validation check of the Genesis -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { - var data types.GenesisState - err := cdc.UnmarshalJSON(bz, &data) - if err != nil { - return fmt.Errorf("failed to unmarshal %s genesis state: %v", types.ModuleName, err) - } - return ValidateGenesis(&data) -} - -// RegisterRESTRoutes registers rest routes for this module -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { -} - -// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the provider module. -func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { -} - -// GetQueryCmd returns the root query command of this module -func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return nil -} - -// GetTxCmd returns the transaction commands for this module -func (AppModuleBasic) GetTxCmd() *cobra.Command { - return nil -} - -// AppModule implements an application module for the provider module. -type AppModule struct { - AppModuleBasic - keeper keeper.IKeeper -} - -// NewAppModule creates a new AppModule object -func NewAppModule(cdc codec.Codec, k keeper.IKeeper) AppModule { - return AppModule{ - AppModuleBasic: AppModuleBasic{cdc: cdc}, - keeper: k, - } -} - -// Name returns the provider module name -func (AppModule) Name() string { - return types.ModuleName -} - -// RegisterInvariants registers module invariants -func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} - -// Route returns the message routing key for the provider module. -func (am AppModule) Route() sdk.Route { - return sdk.Route{} -} - -// QuerierRoute returns the provider module's querier route name. -func (am AppModule) QuerierRoute() string { - return "" -} - -// LegacyQuerierHandler returns the sdk.Querier for provider module -func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { - return nil -} - -// RegisterServices registers the module's services -func (am AppModule) RegisterServices(_ module.Configurator) { -} - -// BeginBlock performs no-op -func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} - -// EndBlock returns the end blocker for the provider module. It returns no validator -// updates. -func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - return []abci.ValidatorUpdate{} -} - -// InitGenesis performs genesis initialization for the provider module. It returns -// no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { - var genesisState types.GenesisState - cdc.MustUnmarshalJSON(data, &genesisState) - return InitGenesis(ctx, am.keeper, &genesisState) -} - -// ExportGenesis returns the exported genesis state as raw bytes for the provider -// module. -func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { - gs := ExportGenesis(ctx, am.keeper) - return cdc.MustMarshalJSON(gs) -} - -// ConsensusVersion implements module.AppModule#ConsensusVersion -func (am AppModule) ConsensusVersion() uint64 { - return 1 -} - -// ____________________________________________________________________________ - -// AppModuleSimulation implements an application simulation module for the provider module. -type AppModuleSimulation struct { - keeper keeper.IKeeper -} - -// NewAppModuleSimulation creates a new AppModuleSimulation instance -func NewAppModuleSimulation(k keeper.IKeeper) AppModuleSimulation { - return AppModuleSimulation{ - keeper: k, - } -} - -// AppModuleSimulation functions - -// GenerateGenesisState creates a randomized GenState of the staking module. -func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) { - simulation.RandomizedGenState(simState) -} - -// ProposalContents doesn't return any content functions for governance proposals. -func (AppModuleSimulation) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent { - return nil -} - -// RandomizedParams creates randomized staking param changes for the simulator. -func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange { - return nil -} - -// RegisterStoreDecoder registers a decoder for staking module's types -func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { - // sdr[StoreKey] = simulation.DecodeStore -} - -// WeightedOperations returns the all the staking module operations with their respective weights. -func (am AppModuleSimulation) WeightedOperations(simState module.SimulationState) []sim.WeightedOperation { - return simulation.WeightedOperations(simState.AppParams, simState.Cdc, am.keeper) -} diff --git a/x/gov/simulation/genesis.go b/x/gov/simulation/genesis.go deleted file mode 100644 index 673784f54c..0000000000 --- a/x/gov/simulation/genesis.go +++ /dev/null @@ -1,14 +0,0 @@ -package simulation - -import ( - "github.com/cosmos/cosmos-sdk/types/module" - - types "github.com/akash-network/akash-api/go/node/gov/v1beta3" -) - -// RandomizedGenState generates a random GenesisState for supply -func RandomizedGenState(simState *module.SimulationState) { - providerGenesis := &types.GenesisState{} - - simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(providerGenesis) -} diff --git a/x/gov/simulation/operations.go b/x/gov/simulation/operations.go deleted file mode 100644 index 2d71a519bf..0000000000 --- a/x/gov/simulation/operations.go +++ /dev/null @@ -1,42 +0,0 @@ -package simulation - -import ( - "github.com/cosmos/cosmos-sdk/codec" - simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/cosmos/cosmos-sdk/x/simulation" - - "github.com/akash-network/node/x/gov/keeper" -) - -// WeightedOperations returns all the operations from the module with their respective weights -func WeightedOperations( - appParams simtypes.AppParams, cdc codec.JSONCodec, k keeper.IKeeper) simulation.WeightedOperations { - return nil - // var ( - // weightMsgCreate int - // weightMsgUpdate int - // ) - // - // appParams.GetOrGenerate( - // cdc, OpWeightMsgCreate, &weightMsgCreate, nil, func(r *rand.Rand) { - // weightMsgCreate = appparams.DefaultWeightMsgCreateProvider - // }, - // ) - // - // appParams.GetOrGenerate( - // cdc, OpWeightMsgUpdate, &weightMsgUpdate, nil, func(r *rand.Rand) { - // weightMsgUpdate = appparams.DefaultWeightMsgUpdateProvider - // }, - // ) - // - // return simulation.WeightedOperations{ - // simulation.NewWeightedOperation( - // weightMsgCreate, - // // SimulateMsgCreate(ak, bk, k), - // ), - // simulation.NewWeightedOperation( - // weightMsgUpdate, - // SimulateMsgUpdate(ak, bk, k), - // ), - // } -} diff --git a/x/inflation/alias.go b/x/inflation/alias.go deleted file mode 100644 index 048570023a..0000000000 --- a/x/inflation/alias.go +++ /dev/null @@ -1,24 +0,0 @@ -package inflation - -import ( - types "github.com/akash-network/akash-api/go/node/inflation/v1beta3" - - "github.com/akash-network/node/x/inflation/keeper" -) - -const ( - // StoreKey represents storekey of inflation module - StoreKey = types.StoreKey - // ModuleName represents current module name - ModuleName = types.ModuleName -) - -type ( - // Keeper defines keeper of inflation module - Keeper = keeper.IKeeper -) - -var ( - // NewKeeper creates new keeper instance of inflation module - NewKeeper = keeper.NewKeeper -) diff --git a/x/inflation/genesis.go b/x/inflation/genesis.go deleted file mode 100644 index 1743dcd882..0000000000 --- a/x/inflation/genesis.go +++ /dev/null @@ -1,53 +0,0 @@ -package inflation - -import ( - "encoding/json" - - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - - abci "github.com/tendermint/tendermint/abci/types" - - types "github.com/akash-network/akash-api/go/node/inflation/v1beta3" - - "github.com/akash-network/node/x/inflation/keeper" -) - -// ValidateGenesis does validation check of the Genesis and return error in case of failure -func ValidateGenesis(data *types.GenesisState) error { - return data.Params.Validate() -} - -// DefaultGenesisState returns default genesis state as raw bytes for the deployment -// module. -func DefaultGenesisState() *types.GenesisState { - return &types.GenesisState{ - Params: types.DefaultParams(), - } -} - -// InitGenesis initiate genesis state and return updated validator details -func InitGenesis(ctx sdk.Context, keeper keeper.IKeeper, data *types.GenesisState) []abci.ValidatorUpdate { - keeper.SetParams(ctx, data.Params) - return []abci.ValidatorUpdate{} -} - -// ExportGenesis returns genesis state for the deployment module -func ExportGenesis(ctx sdk.Context, k keeper.IKeeper) *types.GenesisState { - params := k.GetParams(ctx) - return &types.GenesisState{ - Params: params, - } -} - -// GetGenesisStateFromAppState returns x/inflation GenesisState given raw application -// genesis state. -func GetGenesisStateFromAppState(cdc codec.JSONCodec, appState map[string]json.RawMessage) *types.GenesisState { - var genesisState types.GenesisState - - if appState[ModuleName] != nil { - cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState) - } - - return &genesisState -} diff --git a/x/inflation/keeper/keeper.go b/x/inflation/keeper/keeper.go deleted file mode 100644 index dc55f6d6eb..0000000000 --- a/x/inflation/keeper/keeper.go +++ /dev/null @@ -1,57 +0,0 @@ -package keeper - -import ( - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - - types "github.com/akash-network/akash-api/go/node/inflation/v1beta3" -) - -type IKeeper interface { - Codec() codec.BinaryCodec - StoreKey() sdk.StoreKey - GetParams(ctx sdk.Context) (params types.Params) - SetParams(ctx sdk.Context, params types.Params) -} - -// Keeper of the deployment store -type Keeper struct { - skey sdk.StoreKey - cdc codec.BinaryCodec - pspace paramtypes.Subspace -} - -// NewKeeper creates and returns an instance for deployment keeper -func NewKeeper(cdc codec.BinaryCodec, skey sdk.StoreKey, pspace paramtypes.Subspace) IKeeper { - if !pspace.HasKeyTable() { - pspace = pspace.WithKeyTable(types.ParamKeyTable()) - } - - return Keeper{ - skey: skey, - cdc: cdc, - pspace: pspace, - } -} - -// Codec returns keeper codec -func (k Keeper) Codec() codec.BinaryCodec { - return k.cdc -} - -func (k Keeper) StoreKey() sdk.StoreKey { - return k.skey -} - -// GetParams returns the total set of deployment parameters. -func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { - k.pspace.GetParamSet(ctx, ¶ms) - return params -} - -// SetParams sets the deployment parameters to the paramspace. -func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { - k.pspace.SetParamSet(ctx, ¶ms) -} diff --git a/x/inflation/module.go b/x/inflation/module.go deleted file mode 100644 index ae4414cf47..0000000000 --- a/x/inflation/module.go +++ /dev/null @@ -1,191 +0,0 @@ -package inflation - -import ( - "encoding/json" - "fmt" - "math/rand" - - "github.com/gorilla/mux" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" - - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - cdctypes "github.com/cosmos/cosmos-sdk/codec/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - sim "github.com/cosmos/cosmos-sdk/types/simulation" - - types "github.com/akash-network/akash-api/go/node/inflation/v1beta3" - - "github.com/akash-network/node/x/inflation/keeper" - "github.com/akash-network/node/x/inflation/simulation" -) - -// type check to ensure the interface is properly implemented -var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} - _ module.AppModuleSimulation = AppModuleSimulation{} -) - -// AppModuleBasic defines the basic application module used by the deployment module. -type AppModuleBasic struct { - cdc codec.Codec -} - -// Name returns deployment module's name -func (AppModuleBasic) Name() string { - return types.ModuleName -} - -// RegisterLegacyAminoCodec registers the deployment module's types for the given codec. -func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {} - -// RegisterInterfaces registers the module's interface types -func (b AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) { - -} - -// DefaultGenesis returns default genesis state as raw bytes for the inflation -// module. -func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { - return cdc.MustMarshalJSON(DefaultGenesisState()) -} - -// ValidateGenesis does validation check of the Genesis and returns error incase of failure -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { - var data types.GenesisState - err := cdc.UnmarshalJSON(bz, &data) - if err != nil { - return fmt.Errorf("failed to unmarshal %s genesis state: %v", types.ModuleName, err) - } - return ValidateGenesis(&data) -} - -// RegisterRESTRoutes registers rest routes for this module -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) {} - -// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the deployment module. -func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {} - -// GetQueryCmd get the root query command of this module -func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return nil -} - -// GetTxCmd get the root tx command of this module -func (AppModuleBasic) GetTxCmd() *cobra.Command { - return nil -} - -// AppModule implements an application module for the deployment module. -type AppModule struct { - AppModuleBasic - keeper keeper.IKeeper -} - -// NewAppModule creates a new AppModule Object -func NewAppModule(cdc codec.Codec, k keeper.IKeeper) AppModule { - return AppModule{ - AppModuleBasic: AppModuleBasic{cdc: cdc}, - keeper: k, - } -} - -// Name returns the deployment module name -func (AppModule) Name() string { - return types.ModuleName -} - -// RegisterInvariants registers module invariants -func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} - -// Route returns the message routing key for the deployment module -func (am AppModule) Route() sdk.Route { - return sdk.NewRoute(types.RouterKey, nil) -} - -// QuerierRoute returns the module's querier route name. -func (am AppModule) QuerierRoute() string { - return "" -} - -// LegacyQuerierHandler returns the sdk.Querier for deployment module -func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { - return nil -} - -// RegisterServices registers the module's services -func (am AppModule) RegisterServices(_ module.Configurator) { -} - -// BeginBlock performs no-op -func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} - -// EndBlock returns the end blocker for the module. It returns no validator -// updates. -func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - return []abci.ValidatorUpdate{} -} - -// InitGenesis performs genesis initialization for the module. It returns -// no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { - var genesisState types.GenesisState - cdc.MustUnmarshalJSON(data, &genesisState) - return InitGenesis(ctx, am.keeper, &genesisState) -} - -// ExportGenesis returns the exported genesis state as raw bytes for the inflation -// module. -func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { - gs := ExportGenesis(ctx, am.keeper) - return cdc.MustMarshalJSON(gs) -} - -// ConsensusVersion implements module.AppModule#ConsensusVersion -func (am AppModule) ConsensusVersion() uint64 { - return 1 -} - -// AppModuleSimulation implements an application simulation module for the deployment module. -type AppModuleSimulation struct { - keeper keeper.IKeeper -} - -// NewAppModuleSimulation creates a new AppModuleSimulation instance -func NewAppModuleSimulation(k keeper.IKeeper) AppModuleSimulation { - return AppModuleSimulation{ - keeper: k, - } -} - -// AppModuleSimulation functions - -// GenerateGenesisState creates a randomized GenState of the staking module. -func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) { - simulation.RandomizedGenState(simState) -} - -// ProposalContents doesn't return any content functions for governance proposals. -func (AppModuleSimulation) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent { - return nil -} - -// RandomizedParams creates randomized staking param changes for the simulator. -func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange { - return nil -} - -// RegisterStoreDecoder registers a decoder for staking module's types -func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { - // sdr[StoreKey] = simulation.DecodeStore -} - -// WeightedOperations returns the all the staking module operations with their respective weights. -func (am AppModuleSimulation) WeightedOperations(simState module.SimulationState) []sim.WeightedOperation { - return nil -} diff --git a/x/inflation/simulation/genesis.go b/x/inflation/simulation/genesis.go deleted file mode 100644 index 4ae77027de..0000000000 --- a/x/inflation/simulation/genesis.go +++ /dev/null @@ -1,21 +0,0 @@ -package simulation - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - - types "github.com/akash-network/akash-api/go/node/inflation/v1beta3" -) - -// RandomizedGenState generates a random GenesisState for supply -func RandomizedGenState(simState *module.SimulationState) { - deploymentGenesis := &types.GenesisState{ - Params: types.Params{ - InflationDecayFactor: types.DefaultInflationDecayFactor(), - InitialInflation: sdk.NewDec(100), - Variance: sdk.MustNewDecFromStr("0.05"), - }, - } - - simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(deploymentGenesis) -} diff --git a/x/market/alias.go b/x/market/alias.go index 322a46ab0b..330e4913e5 100644 --- a/x/market/alias.go +++ b/x/market/alias.go @@ -1,16 +1,16 @@ package market import ( - types "github.com/akash-network/akash-api/go/node/market/v1beta4" + v1 "pkg.akt.dev/go/node/market/v1" - "github.com/akash-network/node/x/market/keeper" + "pkg.akt.dev/node/x/market/keeper" ) const ( // StoreKey represents storekey of market module - StoreKey = types.StoreKey + StoreKey = v1.StoreKey // ModuleName represents current module name - ModuleName = types.ModuleName + ModuleName = v1.ModuleName ) type ( diff --git a/x/market/client/cli/bid.go b/x/market/client/cli/bid.go deleted file mode 100644 index 2236065855..0000000000 --- a/x/market/client/cli/bid.go +++ /dev/null @@ -1,99 +0,0 @@ -package cli - -import ( - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/spf13/cobra" - - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - - aclient "github.com/akash-network/node/client" - clientutils "github.com/akash-network/node/client" -) - -func cmdGetBids() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "Query for all bids", - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientQueryContext(cmd) - if err != nil { - return err - } - - qq, err := aclient.DiscoverQueryClient(ctx, cctx) - if err != nil { - return err - } - - bfilters, err := BidFiltersFromFlags(cmd.Flags()) - if err != nil { - return err - } - - pageReq, err := clientutils.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - params := &types.QueryBidsRequest{ - Filters: bfilters, - Pagination: pageReq, - } - - res, err := qq.Bids(cmd.Context(), params) - if err != nil { - return err - } - - return qq.ClientContext().PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "bids") - AddBidFilterFlags(cmd.Flags()) - - return cmd -} - -func cmdGetBid() *cobra.Command { - cmd := &cobra.Command{ - Use: "get", - Short: "Query order", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientQueryContext(cmd) - if err != nil { - return err - } - - qq, err := aclient.DiscoverQueryClient(ctx, cctx) - if err != nil { - return err - } - - bidID, err := BidIDFromFlags(cmd.Flags()) - if err != nil { - return err - } - - res, err := qq.Bid(cmd.Context(), &types.QueryBidRequest{ID: bidID}) - if err != nil { - return err - } - - return qq.ClientContext().PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - AddQueryBidIDFlags(cmd.Flags()) - MarkReqBidIDFlags(cmd) - - return cmd -} diff --git a/x/market/client/cli/cli_test.go b/x/market/client/cli/cli_test.go deleted file mode 100644 index d93046861b..0000000000 --- a/x/market/client/cli/cli_test.go +++ /dev/null @@ -1,411 +0,0 @@ -package cli_test - -import ( - "context" - "fmt" - "path/filepath" - "testing" - - "github.com/stretchr/testify/suite" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - sdk "github.com/cosmos/cosmos-sdk/types" - bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - ptypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" - - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/testutil/network" - ccli "github.com/akash-network/node/x/cert/client/cli" - dcli "github.com/akash-network/node/x/deployment/client/cli" - "github.com/akash-network/node/x/market/client/cli" - pcli "github.com/akash-network/node/x/provider/client/cli" -) - -type IntegrationTestSuite struct { - suite.Suite - - cfg network.Config - network *network.Network -} - -func (s *IntegrationTestSuite) SetupSuite() { - s.T().Log("setting up integration test suite") - - cfg := testutil.DefaultConfig() - cfg.NumValidators = 1 - cfg.EnableLogging = true - - s.cfg = cfg - s.network = network.New(s.T(), cfg) - - kb := s.network.Validators[0].ClientCtx.Keyring - _, _, err := kb.NewMnemonic("keyBar", keyring.English, sdk.FullFundraiserPath, "", hd.Secp256k1) - s.Require().NoError(err) - - _, err = s.network.WaitForHeight(1) - s.Require().NoError(err) - - val := s.network.Validators[0] - - // Generate client certificate - _, err = ccli.TxGenerateClientExec( - context.Background(), - val.ClientCtx, - val.Address, - ) - s.Require().NoError(err) - - // Publish client certificate - _, err = ccli.TxPublishClientExec( - context.Background(), - val.ClientCtx, - val.Address, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) -} - -func (s *IntegrationTestSuite) TearDownSuite() { - s.T().Log("tearing down integration test suite") - s.network.Cleanup() -} - -// Naming as Test{number} just to run all tests sequentially -func (s *IntegrationTestSuite) Test1QueryOrders() { - val := s.network.Validators[0] - - deploymentPath, err := filepath.Abs("../../../deployment/testdata/deployment.yaml") - s.Require().NoError(err) - - // create deployment - _, err = dcli.TxCreateDeploymentExec( - val.ClientCtx, - val.Address, - deploymentPath, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - fmt.Sprintf("--deposit=%s", dcli.DefaultDeposit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - // test query deployments - resp, err := dcli.QueryDeploymentsExec(val.ClientCtx.WithOutputFormat("json")) - s.Require().NoError(err) - - out := &dtypes.QueryDeploymentsResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), out) - s.Require().NoError(err) - s.Require().Len(out.Deployments, 1) - s.Require().Equal(val.Address.String(), out.Deployments[0].Deployment.DeploymentID.Owner) - - // test query orders - resp, err = cli.QueryOrdersExec(val.ClientCtx.WithOutputFormat("json")) - s.Require().NoError(err) - - result := &types.QueryOrdersResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), result) - s.Require().NoError(err) - s.Require().Len(result.Orders, 1) - orders := result.Orders - s.Require().Equal(val.Address.String(), orders[0].OrderID.Owner) - - // test query order - createdOrder := orders[0] - resp, err = cli.QueryOrderExec(val.ClientCtx.WithOutputFormat("json"), createdOrder.OrderID) - s.Require().NoError(err) - - var order types.Order - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &order) - s.Require().NoError(err) - s.Require().Equal(createdOrder, order) - - // test query orders with filters - resp, err = cli.QueryOrdersExec( - val.ClientCtx.WithOutputFormat("json"), - fmt.Sprintf("--owner=%s", val.Address.String()), - "--state=open", - ) - s.Require().NoError(err) - - result = &types.QueryOrdersResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), result) - s.Require().NoError(err) - s.Require().Len(result.Orders, 1) - s.Require().Equal(createdOrder, result.Orders[0]) - - // test query orders with wrong owner value - _, err = cli.QueryOrdersExec( - val.ClientCtx.WithOutputFormat("json"), - "--owner=cosmos102ruvpv2srmunfffxavttxnhezln6fnc3pf7tt", - ) - s.Require().Error(err) - - // test query orders with wrong state value - _, err = cli.QueryOrdersExec( - val.ClientCtx.WithOutputFormat("json"), - "--state=hello", - ) - s.Require().Error(err) -} - -// Naming as Test{number} just to run all tests sequentially -func (s *IntegrationTestSuite) Test2CreateBid() { - val := s.network.Validators[0] - - providerPath, err := filepath.Abs("../../../provider/testdata/provider.yaml") - s.Require().NoError(err) - - keyBar, err := val.ClientCtx.Keyring.Key("keyBar") - s.Require().NoError(err) - - // Send coins from validator to keyBar - sendTokens := sdk.NewCoin(s.cfg.BondDenom, cli.DefaultDeposit.Amount.MulRaw(2)) - _, err = bankcli.MsgSendExec( - val.ClientCtx, - val.Address, - keyBar.GetAddress(), - sdk.NewCoins(sendTokens), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - resp, err := bankcli.QueryBalancesExec(val.ClientCtx.WithOutputFormat("json"), keyBar.GetAddress()) - s.Require().NoError(err) - - var balRes banktypes.QueryAllBalancesResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &balRes) - s.Require().NoError(err) - s.Require().Equal(sendTokens.Amount, balRes.Balances.AmountOf(s.cfg.BondDenom)) - - // create provider - _, err = pcli.TxCreateProviderExec( - val.ClientCtx, - keyBar.GetAddress(), - providerPath, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - // test query providers - resp, err = pcli.QueryProvidersExec(val.ClientCtx.WithOutputFormat("json")) - s.Require().NoError(err) - - out := &ptypes.QueryProvidersResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), out) - s.Require().NoError(err) - s.Require().Len(out.Providers, 1, "Provider Creation Failed in TestCreateBid") - s.Require().Equal(keyBar.GetAddress().String(), out.Providers[0].Owner) - - // fetch orders - resp, err = cli.QueryOrdersExec(val.ClientCtx.WithOutputFormat("json")) - s.Require().NoError(err) - - result := &types.QueryOrdersResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), result) - s.Require().NoError(err) - s.Require().Len(result.Orders, 1) - - createdOrder := result.Orders[0] - - // create bid - _, err = cli.TxCreateBidExec( - val.ClientCtx, - createdOrder.OrderID, - sdk.NewDecCoinFromDec(testutil.CoinDenom, sdk.MustNewDecFromStr("1.1")), - keyBar.GetAddress(), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - fmt.Sprintf("--deposit=%s", cli.DefaultDeposit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - // test query bids - resp, err = cli.QueryBidsExec(val.ClientCtx.WithOutputFormat("json")) - s.Require().NoError(err) - - bidRes := &types.QueryBidsResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), bidRes) - s.Require().NoError(err) - s.Require().Len(bidRes.Bids, 1) - bids := bidRes.Bids - s.Require().Equal(keyBar.GetAddress().String(), bids[0].Bid.BidID.Provider) - - // test query bid - createdBid := bids[0].Bid - resp, err = cli.QueryBidExec(val.ClientCtx.WithOutputFormat("json"), createdBid.BidID) - s.Require().NoError(err) - - var bid types.QueryBidResponse - s.T().Logf("query response: %v", resp.String()) - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &bid) - s.Require().NoError(err) - s.Require().Equal(createdBid, bid.Bid) - - // test query bids with filters - resp, err = cli.QueryBidsExec( - val.ClientCtx.WithOutputFormat("json"), - fmt.Sprintf("--provider=%s", keyBar.GetAddress().String()), - fmt.Sprintf("--state=%s", bid.Bid.State.String()), - ) - s.Require().NoError(err) - - bidRes = &types.QueryBidsResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), bidRes) - s.Require().NoError(err) - s.Require().Len(bidRes.Bids, 1) - s.Require().Equal(createdBid, bidRes.Bids[0].Bid) - - // test query bids with wrong owner value - _, err = cli.QueryBidsExec( - val.ClientCtx.WithOutputFormat("json"), - "--owner=cosmos102ruvpv2srmunfffxavttxnhezln6fnc3pf7tt", - ) - s.Require().Error(err) - - // test query bids with wrong state value - _, err = cli.QueryBidsExec( - val.ClientCtx.WithOutputFormat("json"), - "--state=hello", - ) - s.Require().Error(err) - - // create lease - _, err = cli.TxCreateLeaseExec( - val.ClientCtx, - bid.Bid.BidID, - val.Address, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) -} - -// Naming as Test{number} just to run all tests sequentially -func (s *IntegrationTestSuite) Test3QueryLeasesAndCloseBid() { - val := s.network.Validators[0] - - keyBar, err := val.ClientCtx.Keyring.Key("keyBar") - s.Require().NoError(err) - - // test query leases - resp, err := cli.QueryLeasesExec(val.ClientCtx.WithOutputFormat("json")) - s.Require().NoError(err) - - leaseRes := &types.QueryLeasesResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), leaseRes) - s.Require().NoError(err) - s.Require().Len(leaseRes.Leases, 1) - leases := leaseRes.Leases - s.Require().Equal(keyBar.GetAddress().String(), leases[0].Lease.LeaseID.Provider) - - // test query lease - createdLease := leases[0].Lease - resp, err = cli.QueryLeaseExec(val.ClientCtx.WithOutputFormat("json"), createdLease.LeaseID) - s.Require().NoError(err) - - var lease types.QueryLeaseResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &lease) - s.Require().NoError(err) - s.Require().Equal(createdLease, lease.Lease) - - // create bid - _, err = cli.TxCloseBidExec( - val.ClientCtx, - lease.Lease.LeaseID.OrderID(), - keyBar.GetAddress(), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - "--gas=auto", - "--gas-adjustment=1.5", - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // test query closed bids - resp, err = cli.QueryBidsExec(val.ClientCtx.WithOutputFormat("json"), "--state=closed") - s.Require().NoError(err) - - bidRes := &types.QueryBidsResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), bidRes) - s.Require().NoError(err) - s.Require().Len(bidRes.Bids, 1) - s.Require().Equal(keyBar.GetAddress().String(), bidRes.Bids[0].Bid.BidID.Provider) - - // test query leases with state value filter - resp, err = cli.QueryLeasesExec(val.ClientCtx.WithOutputFormat("json"), "--state=closed") - s.Require().NoError(err) - - leaseRes = &types.QueryLeasesResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), leaseRes) - s.Require().NoError(err) - s.Require().Len(leaseRes.Leases, 1) - - // test query leases with wrong owner value - _, err = cli.QueryLeasesExec( - val.ClientCtx.WithOutputFormat("json"), - "--provider=cosmos102ruvpv2srmunfffxavttxnhezln6fnc3pf7tt", - ) - s.Require().Error(err) - - // test query leases with wrong state value - _, err = cli.QueryLeasesExec( - val.ClientCtx.WithOutputFormat("json"), - "--state=hello", - ) - s.Require().Error(err) -} - -// Naming as Test{number} just to run all tests sequentially -func (s *IntegrationTestSuite) Test4CloseOrder() { - val := s.network.Validators[0] - - // fetch open orders - resp, err := cli.QueryOrdersExec( - val.ClientCtx.WithOutputFormat("json"), - "--state=open", - ) - s.Require().NoError(err) - - result := &types.QueryOrdersResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), result) - s.Require().NoError(err) - openedOrders := result.Orders - s.Require().Len(openedOrders, 0) -} - -func TestIntegrationTestSuite(t *testing.T) { - suite.Run(t, new(IntegrationTestSuite)) -} diff --git a/x/market/client/cli/flags.go b/x/market/client/cli/flags.go deleted file mode 100644 index 1e4e8489dd..0000000000 --- a/x/market/client/cli/flags.go +++ /dev/null @@ -1,210 +0,0 @@ -package cli - -import ( - "errors" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - - dcli "github.com/akash-network/node/x/deployment/client/cli" -) - -var ( - ErrStateValue = errors.New("query: invalid state value") - DefaultDeposit = types.DefaultBidMinDeposit -) - -// AddOrderIDFlags add flags for order -func AddOrderIDFlags(flags *pflag.FlagSet, opts ...dcli.DeploymentIDOption) { - dcli.AddGroupIDFlags(flags, opts...) - flags.Uint32("oseq", 1, "Order Sequence") -} - -// MarkReqOrderIDFlags marks flags required for order -func MarkReqOrderIDFlags(cmd *cobra.Command, opts ...dcli.DeploymentIDOption) { - dcli.MarkReqGroupIDFlags(cmd, opts...) -} - -// AddProviderFlag add provider flag to command flags set -func AddProviderFlag(flags *pflag.FlagSet) { - flags.String("provider", "", "Provider") -} - -// MarkReqProviderFlag marks provider flag as required -func MarkReqProviderFlag(cmd *cobra.Command) { - _ = cmd.MarkFlagRequired("provider") -} - -// OrderIDFromFlags returns OrderID with given flags and error if occurred -func OrderIDFromFlags(flags *pflag.FlagSet, opts ...dcli.MarketOption) (types.OrderID, error) { - prev, err := dcli.GroupIDFromFlags(flags, opts...) - if err != nil { - return types.OrderID{}, err - } - val, err := flags.GetUint32("oseq") - if err != nil { - return types.OrderID{}, err - } - return types.MakeOrderID(prev, val), nil -} - -// AddBidIDFlags add flags for bid -func AddBidIDFlags(flags *pflag.FlagSet, opts ...dcli.DeploymentIDOption) { - AddOrderIDFlags(flags, opts...) - AddProviderFlag(flags) -} - -// AddQueryBidIDFlags add flags for bid in query commands -func AddQueryBidIDFlags(flags *pflag.FlagSet) { - AddBidIDFlags(flags) -} - -// MarkReqBidIDFlags marks flags required for bid -// Used in get bid query command -func MarkReqBidIDFlags(cmd *cobra.Command, opts ...dcli.DeploymentIDOption) { - MarkReqOrderIDFlags(cmd, opts...) - MarkReqProviderFlag(cmd) -} - -// BidIDFromFlags returns BidID with given flags and error if occurred -// Here provider value is taken from flags -func BidIDFromFlags(flags *pflag.FlagSet, opts ...dcli.MarketOption) (types.BidID, error) { - prev, err := OrderIDFromFlags(flags, opts...) - if err != nil { - return types.BidID{}, err - } - - opt := &dcli.MarketOptions{} - - for _, o := range opts { - o(opt) - } - - if opt.Provider.Empty() { - provider, err := flags.GetString("provider") - if err != nil { - return types.BidID{}, err - } - - if opt.Provider, err = sdk.AccAddressFromBech32(provider); err != nil { - return types.BidID{}, err - } - } - - return types.MakeBidID(prev, opt.Provider), nil -} - -func AddLeaseIDFlags(flags *pflag.FlagSet, opts ...dcli.DeploymentIDOption) { - AddBidIDFlags(flags, opts...) -} - -// MarkReqLeaseIDFlags marks flags required for bid -// Used in get bid query command -func MarkReqLeaseIDFlags(cmd *cobra.Command, opts ...dcli.DeploymentIDOption) { - MarkReqBidIDFlags(cmd, opts...) -} - -// LeaseIDFromFlags returns LeaseID with given flags and error if occurred -// Here provider value is taken from flags -func LeaseIDFromFlags(flags *pflag.FlagSet, opts ...dcli.MarketOption) (types.LeaseID, error) { - bid, err := BidIDFromFlags(flags, opts...) - if err != nil { - return types.LeaseID{}, err - } - - return bid.LeaseID(), nil -} - -// AddOrderFilterFlags add flags to filter for order list -func AddOrderFilterFlags(flags *pflag.FlagSet) { - flags.String("owner", "", "order owner address to filter") - flags.String("state", "", "order state to filter (open,matched,closed)") - flags.Uint64("dseq", 0, "deployment sequence to filter") - flags.Uint32("gseq", 1, "group sequence to filter") - flags.Uint32("oseq", 1, "order sequence to filter") -} - -// OrderFiltersFromFlags returns OrderFilters with given flags and error if occurred -func OrderFiltersFromFlags(flags *pflag.FlagSet) (types.OrderFilters, error) { - dfilters, err := dcli.DepFiltersFromFlags(flags) - if err != nil { - return types.OrderFilters{}, err - } - ofilters := types.OrderFilters{ - Owner: dfilters.Owner, - DSeq: dfilters.DSeq, - State: dfilters.State, - } - - if ofilters.GSeq, err = flags.GetUint32("gseq"); err != nil { - return ofilters, err - } - - if ofilters.OSeq, err = flags.GetUint32("oseq"); err != nil { - return ofilters, err - } - - return ofilters, nil -} - -// AddBidFilterFlags add flags to filter for bid list -func AddBidFilterFlags(flags *pflag.FlagSet) { - flags.String("owner", "", "bid owner address to filter") - flags.String("state", "", "bid state to filter (open,matched,lost,closed)") - flags.Uint64("dseq", 0, "deployment sequence to filter") - flags.Uint32("gseq", 1, "group sequence to filter") - flags.Uint32("oseq", 1, "order sequence to filter") - flags.String("provider", "", "bid provider address to filter") -} - -// BidFiltersFromFlags returns BidFilters with given flags and error if occurred -func BidFiltersFromFlags(flags *pflag.FlagSet) (types.BidFilters, error) { - ofilters, err := OrderFiltersFromFlags(flags) - if err != nil { - return types.BidFilters{}, err - } - bfilters := types.BidFilters{ - Owner: ofilters.Owner, - DSeq: ofilters.DSeq, - GSeq: ofilters.OSeq, - OSeq: ofilters.OSeq, - State: ofilters.State, - } - - provider, err := flags.GetString("provider") - if err != nil { - return bfilters, err - } - - if provider != "" { - _, err = sdk.AccAddressFromBech32(provider) - if err != nil { - return bfilters, err - } - } - bfilters.Provider = provider - - return bfilters, nil -} - -// AddLeaseFilterFlags add flags to filter for lease list -func AddLeaseFilterFlags(flags *pflag.FlagSet) { - flags.String("owner", "", "lease owner address to filter") - flags.String("state", "", "lease state to filter (active,insufficient_funds,closed)") - flags.Uint64("dseq", 0, "deployment sequence to filter") - flags.Uint32("gseq", 1, "group sequence to filter") - flags.Uint32("oseq", 1, "order sequence to filter") - flags.String("provider", "", "bid provider address to filter") -} - -// LeaseFiltersFromFlags returns LeaseFilters with given flags and error if occurred -func LeaseFiltersFromFlags(flags *pflag.FlagSet) (types.LeaseFilters, error) { - bfilters, err := BidFiltersFromFlags(flags) - if err != nil { - return types.LeaseFilters{}, err - } - return types.LeaseFilters(bfilters), nil -} diff --git a/x/market/client/cli/grpc_rest_test.go b/x/market/client/cli/grpc_rest_test.go deleted file mode 100644 index e0ab1b5dab..0000000000 --- a/x/market/client/cli/grpc_rest_test.go +++ /dev/null @@ -1,627 +0,0 @@ -package cli_test - -import ( - "context" - "fmt" - "path/filepath" - "testing" - - "github.com/stretchr/testify/suite" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkrest "github.com/cosmos/cosmos-sdk/types/rest" - bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil" - - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/testutil/network" - ccli "github.com/akash-network/node/x/cert/client/cli" - dcli "github.com/akash-network/node/x/deployment/client/cli" - "github.com/akash-network/node/x/market/client/cli" - pcli "github.com/akash-network/node/x/provider/client/cli" -) - -type GRPCRestTestSuite struct { - suite.Suite - - cfg network.Config - network *network.Network - order types.Order - bid types.Bid - lease types.Lease -} - -func (s *GRPCRestTestSuite) SetupSuite() { - s.T().Log("setting up integration test suite") - - cfg := testutil.DefaultConfig() - cfg.NumValidators = 1 - - s.cfg = cfg - s.network = network.New(s.T(), cfg) - - kb := s.network.Validators[0].ClientCtx.Keyring - keyBar, _, err := kb.NewMnemonic("keyBar", keyring.English, sdk.FullFundraiserPath, "", - hd.Secp256k1) - s.Require().NoError(err) - - _, err = s.network.WaitForHeight(1) - s.Require().NoError(err) - - val := s.network.Validators[0] - - // Generate client certificate - _, err = ccli.TxGenerateClientExec( - context.Background(), - val.ClientCtx, - val.Address, - ) - s.Require().NoError(err) - - // Publish client certificate - _, err = ccli.TxPublishClientExec( - context.Background(), - val.ClientCtx, - val.Address, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - deploymentPath, err := filepath.Abs("./../../../deployment/testdata/deployment.yaml") - s.Require().NoError(err) - - providerPath, err := filepath.Abs("./../../../provider/testdata/provider.yaml") - s.Require().NoError(err) - - // create deployment - _, err = dcli.TxCreateDeploymentExec( - val.ClientCtx, - val.Address, - deploymentPath, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - fmt.Sprintf("--deposit=%s", dcli.DefaultDeposit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - // test query orders - resp, err := cli.QueryOrdersExec(val.ClientCtx.WithOutputFormat("json")) - s.Require().NoError(err) - - result := &types.QueryOrdersResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), result) - s.Require().NoError(err) - s.Require().Len(result.Orders, 1) - orders := result.Orders - s.Require().Equal(val.Address.String(), orders[0].OrderID.Owner) - - // test query order - s.order = orders[0] - - // Send coins from validator to keyBar - sendTokens := cli.DefaultDeposit.Add(cli.DefaultDeposit) - _, err = bankcli.MsgSendExec( - val.ClientCtx, - val.Address, - keyBar.GetAddress(), - sdk.NewCoins(sendTokens), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - // create provider - _, err = pcli.TxCreateProviderExec( - val.ClientCtx, - keyBar.GetAddress(), - providerPath, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - _, err = cli.TxCreateBidExec( - val.ClientCtx, - s.order.OrderID, - sdk.NewDecCoinFromDec(testutil.CoinDenom, sdk.MustNewDecFromStr("1.1")), - keyBar.GetAddress(), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - fmt.Sprintf("--deposit=%s", cli.DefaultDeposit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - // get bid - resp, err = cli.QueryBidsExec(val.ClientCtx.WithOutputFormat("json")) - s.Require().NoError(err) - - bidRes := &types.QueryBidsResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), bidRes) - s.Require().NoError(err) - s.Require().Len(bidRes.Bids, 1) - bids := bidRes.Bids - s.Require().Equal(keyBar.GetAddress().String(), bids[0].Bid.BidID.Provider) - - s.bid = bids[0].Bid - - // create lease - _, err = cli.TxCreateLeaseExec( - val.ClientCtx, - s.bid.BidID, - val.Address, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - // test query leases - resp, err = cli.QueryLeasesExec(val.ClientCtx.WithOutputFormat("json")) - s.Require().NoError(err) - - leaseRes := &types.QueryLeasesResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), leaseRes) - s.Require().NoError(err) - s.Require().Len(leaseRes.Leases, 1) - leases := leaseRes.Leases - s.Require().Equal(keyBar.GetAddress().String(), leases[0].Lease.LeaseID.Provider) - - s.order.State = types.OrderActive - s.bid.State = types.BidActive - - // test query lease - s.lease = leases[0].Lease -} - -func (s *GRPCRestTestSuite) TestGetOrders() { - val := s.network.Validators[0] - order := s.order - - testCases := []struct { - name string - url string - expErr bool - expResp types.Order - expLen int - }{ - { - "get orders without filters", - fmt.Sprintf("%s/akash/market/%s/orders/list", val.APIAddress, types.APIVersion), - false, - order, - 1, - }, - { - "get orders with filters", - fmt.Sprintf("%s/akash/market/%s/orders/list?filters.owner=%s", val.APIAddress, - types.APIVersion, - order.OrderID.Owner), - false, - order, - 1, - }, - { - "get orders with wrong state filter", - fmt.Sprintf("%s/akash/market/%s/orders/list?filters.state=%s", val.APIAddress, - types.APIVersion, - types.OrderStateInvalid.String()), - true, - types.Order{}, - 0, - }, - { - "get orders with two filters", - fmt.Sprintf("%s/akash/market/%s/orders/list?filters.state=%s&filters.oseq=%d", - val.APIAddress, types.APIVersion, order.State.String(), order.OrderID.OSeq), - false, - order, - 1, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := sdkrest.GetRequest(tc.url) - s.Require().NoError(err) - - var orders types.QueryOrdersResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp, &orders) - - if tc.expErr { - s.Require().NotNil(err) - s.Require().Empty(orders.Orders) - } else { - s.Require().NoError(err) - s.Require().Len(orders.Orders, tc.expLen) - s.Require().Equal(tc.expResp, orders.Orders[0]) - } - }) - } -} - -func (s *GRPCRestTestSuite) TestGetOrder() { - val := s.network.Validators[0] - order := s.order - - testCases := []struct { - name string - url string - expErr bool - expResp types.Order - }{ - { - "get order with empty input", - fmt.Sprintf("%s/akash/market/%s/orders/info", val.APIAddress, types.APIVersion), - true, - types.Order{}, - }, - { - "get order with invalid input", - fmt.Sprintf("%s/akash/market/%s/orders/info?id.owner=%s", val.APIAddress, - types.APIVersion, - order.OrderID.Owner), - true, - types.Order{}, - }, - { - "order not found", - fmt.Sprintf("%s/akash/market/%s/orders/info?id.owner=%s&id.dseq=%d&id.gseq=%d&id.oseq=%d", - val.APIAddress, - types.APIVersion, - order.OrderID.Owner, 249, 32, 235), - true, - types.Order{}, - }, - { - "valid get order request", - fmt.Sprintf("%s/akash/market/%s/orders/info?id.owner=%s&id.dseq=%d&id.gseq=%d&id.oseq=%d", - val.APIAddress, - types.APIVersion, - order.OrderID.Owner, - order.OrderID.DSeq, - order.OrderID.GSeq, - order.OrderID.OSeq), - false, - order, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := sdkrest.GetRequest(tc.url) - s.Require().NoError(err) - - var out types.QueryOrderResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp, &out) - - if tc.expErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().Equal(tc.expResp, out.Order) - } - }) - } -} - -func (s *GRPCRestTestSuite) TestGetBids() { - val := s.network.Validators[0] - bid := s.bid - - testCases := []struct { - name string - url string - expErr bool - expResp types.Bid - expLen int - }{ - { - "get bids without filters", - fmt.Sprintf("%s/akash/market/%s/bids/list", val.APIAddress, types.APIVersion), - false, - bid, - 1, - }, - { - "get bids with filters", - fmt.Sprintf("%s/akash/market/%s/bids/list?filters.owner=%s", - val.APIAddress, - types.APIVersion, - bid.BidID.Owner), - false, - bid, - 1, - }, - { - "get bids with wrong state filter", - fmt.Sprintf("%s/akash/market/%s/bids/list?filters.state=%s", - val.APIAddress, - types.APIVersion, - types.BidStateInvalid.String()), - true, - types.Bid{}, - 0, - }, - { - "get bids with more filters", - fmt.Sprintf("%s/akash/market/%s/bids/list?filters.state=%s&filters.oseq=%d&filters.provider=%s", - val.APIAddress, - types.APIVersion, - bid.State.String(), - bid.BidID.OSeq, - bid.BidID.Provider), - false, - bid, - 1, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := sdkrest.GetRequest(tc.url) - s.Require().NoError(err) - - var bids types.QueryBidsResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp, &bids) - - if tc.expErr { - s.Require().NotNil(err) - s.Require().Empty(bids.Bids) - } else { - s.Require().NoError(err) - s.Require().Len(bids.Bids, tc.expLen) - s.Require().Equal(tc.expResp, bids.Bids[0].Bid) - } - }) - } -} - -func (s *GRPCRestTestSuite) TestGetBid() { - val := s.network.Validators[0] - bid := s.bid - - testCases := []struct { - name string - url string - expErr bool - expResp types.Bid - }{ - { - "get bid with empty input", - fmt.Sprintf("%s/akash/market/%s/bids/info", val.APIAddress, types.APIVersion), - true, - types.Bid{}, - }, - { - "get bid with invalid input", - fmt.Sprintf("%s/akash/market/%s/bids/info?id.owner=%s", - val.APIAddress, - types.APIVersion, - bid.BidID.Owner), - true, - types.Bid{}, - }, - { - "bid not found", - fmt.Sprintf("%s/akash/market/%s/bids/info?id.owner=%s&id.dseq=%d&id.gseq=%d&id.oseq=%d&id.provider=%s", - val.APIAddress, - types.APIVersion, - bid.BidID.Provider, - 249, - 32, - 235, - bid.BidID.Owner), - true, - types.Bid{}, - }, - { - "valid get bid request", - fmt.Sprintf("%s/akash/market/%s/bids/info?id.owner=%s&id.dseq=%d&id.gseq=%d&id.oseq=%d&id.provider=%s", - val.APIAddress, - types.APIVersion, - bid.BidID.Owner, - bid.BidID.DSeq, - bid.BidID.GSeq, - bid.BidID.OSeq, - bid.BidID.Provider), - false, - bid, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := sdkrest.GetRequest(tc.url) - s.Require().NoError(err) - - var out types.QueryBidResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp, &out) - - if tc.expErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().Equal(tc.expResp, out.Bid) - } - }) - } -} - -func (s *GRPCRestTestSuite) TestGetLeases() { - val := s.network.Validators[0] - lease := s.lease - - testCases := []struct { - name string - url string - expErr bool - expResp types.Lease - expLen int - }{ - { - "get leases without filters", - fmt.Sprintf("%s/akash/market/%s/leases/list", val.APIAddress, types.APIVersion), - false, - lease, - 1, - }, - { - "get leases with filters", - fmt.Sprintf("%s/akash/market/%s/leases/list?filters.owner=%s", - val.APIAddress, - types.APIVersion, - lease.LeaseID.Owner), - false, - lease, - 1, - }, - { - "get leases with wrong state filter", - fmt.Sprintf("%s/akash/market/%s/leases/list?filters.state=%s", - val.APIAddress, - types.APIVersion, - types.LeaseStateInvalid.String()), - true, - types.Lease{}, - 0, - }, - { - "get leases with more filters", - fmt.Sprintf("%s/akash/market/%s/leases/list?filters.state=%s&filters.oseq=%d&filters.provider=%s", - val.APIAddress, - types.APIVersion, - lease.State.String(), - lease.LeaseID.OSeq, - lease.LeaseID.Provider), - false, - lease, - 1, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := sdkrest.GetRequest(tc.url) - s.Require().NoError(err) - - var leases types.QueryLeasesResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp, &leases) - - if tc.expErr { - s.Require().NotNil(err) - s.Require().Empty(leases.Leases) - } else { - s.Require().NoError(err) - s.Require().Len(leases.Leases, tc.expLen) - s.Require().Equal(tc.expResp, leases.Leases[0].Lease) - } - }) - } -} - -func (s *GRPCRestTestSuite) TestGetLease() { - val := s.network.Validators[0] - lease := s.lease - - testCases := []struct { - name string - url string - expErr bool - expResp types.Lease - }{ - { - "get lease with empty input", - fmt.Sprintf("%s/akash/market/%s/leases/info", val.APIAddress, types.APIVersion), - true, - types.Lease{}, - }, - { - "get lease with invalid input", - fmt.Sprintf("%s/akash/market/%s/leases/info?id.owner=%s", - val.APIAddress, - types.APIVersion, - lease.LeaseID.Owner), - true, - types.Lease{}, - }, - { - "lease not found", - fmt.Sprintf("%s/akash/market/%s/leases/info?id.owner=%s&id.dseq=%d&id.gseq=%d&id.oseq=%d&id.provider=%s", - val.APIAddress, - types.APIVersion, - lease.LeaseID.Provider, - 249, - 32, - 235, - lease.LeaseID.Owner), - true, - types.Lease{}, - }, - { - "valid get lease request", - fmt.Sprintf("%s/akash/market/%s/leases/info?id.owner=%s&id.dseq=%d&id.gseq=%d&id.oseq=%d&id.provider=%s", - val.APIAddress, - types.APIVersion, - lease.LeaseID.Owner, - lease.LeaseID.DSeq, - lease.LeaseID.GSeq, - lease.LeaseID.OSeq, - lease.LeaseID.Provider), - false, - lease, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := sdkrest.GetRequest(tc.url) - s.Require().NoError(err) - - var out types.QueryLeaseResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp, &out) - - if tc.expErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().Equal(tc.expResp, out.Lease) - } - }) - } -} - -func (s *GRPCRestTestSuite) TearDownSuite() { - s.T().Log("tearing down integration test suite") - s.network.Cleanup() -} - -func TestGRPCRestTestSuite(t *testing.T) { - suite.Run(t, new(GRPCRestTestSuite)) -} diff --git a/x/market/client/cli/lease.go b/x/market/client/cli/lease.go deleted file mode 100644 index eec20b153e..0000000000 --- a/x/market/client/cli/lease.go +++ /dev/null @@ -1,99 +0,0 @@ -package cli - -import ( - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/spf13/cobra" - - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - - aclient "github.com/akash-network/node/client" - clientutils "github.com/akash-network/node/client" -) - -func cmdGetLeases() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "Query for all leases", - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientQueryContext(cmd) - if err != nil { - return err - } - - qq, err := aclient.DiscoverQueryClient(ctx, cctx) - if err != nil { - return err - } - - lfilters, err := LeaseFiltersFromFlags(cmd.Flags()) - if err != nil { - return err - } - - pageReq, err := clientutils.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - params := &types.QueryLeasesRequest{ - Filters: lfilters, - Pagination: pageReq, - } - - res, err := qq.Leases(cmd.Context(), params) - if err != nil { - return err - } - - return qq.ClientContext().PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "leases") - AddLeaseFilterFlags(cmd.Flags()) - - return cmd -} - -func cmdGetLease() *cobra.Command { - cmd := &cobra.Command{ - Use: "get", - Short: "Query order", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientQueryContext(cmd) - if err != nil { - return err - } - - qq, err := aclient.DiscoverQueryClient(ctx, cctx) - if err != nil { - return err - } - - bidID, err := BidIDFromFlags(cmd.Flags()) - if err != nil { - return err - } - - res, err := qq.Lease(cmd.Context(), &types.QueryLeaseRequest{ID: types.MakeLeaseID(bidID)}) - if err != nil { - return err - } - - return qq.ClientContext().PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - AddQueryBidIDFlags(cmd.Flags()) - MarkReqBidIDFlags(cmd) - - return cmd -} diff --git a/x/market/client/cli/order.go b/x/market/client/cli/order.go deleted file mode 100644 index e8388c26ca..0000000000 --- a/x/market/client/cli/order.go +++ /dev/null @@ -1,98 +0,0 @@ -package cli - -import ( - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/spf13/cobra" - - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - - aclient "github.com/akash-network/node/client" - clientutils "github.com/akash-network/node/client" -) - -func cmdGetOrders() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "Query for all orders", - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientQueryContext(cmd) - if err != nil { - return err - } - - qq, err := aclient.DiscoverQueryClient(ctx, cctx) - if err != nil { - return err - } - - ofilters, err := OrderFiltersFromFlags(cmd.Flags()) - if err != nil { - return err - } - - pageReq, err := clientutils.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - params := &types.QueryOrdersRequest{ - Filters: ofilters, - Pagination: pageReq, - } - - res, err := qq.Orders(cmd.Context(), params) - if err != nil { - return err - } - - return qq.ClientContext().PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "orders") - AddOrderFilterFlags(cmd.Flags()) - return cmd -} - -func cmdGetOrder() *cobra.Command { - cmd := &cobra.Command{ - Use: "get", - Short: "Query order", - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientQueryContext(cmd) - if err != nil { - return err - } - - qq, err := aclient.DiscoverQueryClient(ctx, cctx) - if err != nil { - return err - } - - id, err := OrderIDFromFlags(cmd.Flags()) - if err != nil { - return err - } - - res, err := qq.Order(cmd.Context(), &types.QueryOrderRequest{ID: id}) - if err != nil { - return err - } - - return qq.ClientContext().PrintProto(&res.Order) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - AddOrderIDFlags(cmd.Flags()) - MarkReqOrderIDFlags(cmd) - - return cmd -} diff --git a/x/market/client/cli/query.go b/x/market/client/cli/query.go deleted file mode 100644 index bd6f984fab..0000000000 --- a/x/market/client/cli/query.go +++ /dev/null @@ -1,75 +0,0 @@ -package cli - -import ( - "github.com/cosmos/cosmos-sdk/client" - "github.com/spf13/cobra" - - types "github.com/akash-network/akash-api/go/node/market/v1beta4" -) - -// GetQueryCmd returns the transaction commands for the market module -func GetQueryCmd() *cobra.Command { - - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: "Market query commands", - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - - cmd.AddCommand( - getOrderCmd(), - getBidCmd(), - getLeaseCmd(), - ) - - return cmd -} - -func getOrderCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "order", - Short: "Order query commands", - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - - cmd.AddCommand( - cmdGetOrders(), - cmdGetOrder(), - ) - - return cmd -} - -func getBidCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "bid", - Short: "Bid query commands", - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - - cmd.AddCommand( - cmdGetBids(), - cmdGetBid(), - ) - - return cmd -} - -func getLeaseCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "lease", - Short: "Lease query commands", - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - - cmd.AddCommand( - cmdGetLeases(), - cmdGetLease(), - ) - - return cmd -} diff --git a/x/market/client/cli/test_helpers.go b/x/market/client/cli/test_helpers.go deleted file mode 100644 index ac87c1615e..0000000000 --- a/x/market/client/cli/test_helpers.go +++ /dev/null @@ -1,139 +0,0 @@ -package cli - -import ( - "fmt" - - "github.com/cosmos/cosmos-sdk/client" - sdktest "github.com/cosmos/cosmos-sdk/testutil" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - - types "github.com/akash-network/akash-api/go/node/market/v1beta4" -) - -// XXX: WHY TF DON'T THESE RETURN OBJECTS - -const key string = types.StoreKey - -// TxCreateBidExec is used for testing create bid tx -func TxCreateBidExec(clientCtx client.Context, orderID types.OrderID, price, from fmt.Stringer, - extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--from=%s", from.String()), - fmt.Sprintf("--owner=%s", orderID.Owner), - fmt.Sprintf("--dseq=%v", orderID.DSeq), - fmt.Sprintf("--gseq=%v", orderID.GSeq), - fmt.Sprintf("--oseq=%v", orderID.OSeq), - fmt.Sprintf("--price=%s", price.String()), - } - - args = append(args, extraArgs...) - - return clitestutil.ExecTestCLICmd(clientCtx, cmdBidCreate(key), args) -} - -// TxCloseBidExec is used for testing close bid tx -func TxCloseBidExec(clientCtx client.Context, orderID types.OrderID, from fmt.Stringer, - extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--from=%s", from.String()), - fmt.Sprintf("--owner=%v", orderID.Owner), - fmt.Sprintf("--dseq=%v", orderID.DSeq), - fmt.Sprintf("--gseq=%v", orderID.GSeq), - fmt.Sprintf("--oseq=%v", orderID.OSeq), - } - - args = append(args, extraArgs...) - - return clitestutil.ExecTestCLICmd(clientCtx, cmdBidClose(key), args) -} - -// TxCreateLeaseExec is used for creating a lease -func TxCreateLeaseExec(clientCtx client.Context, bid types.BidID, from fmt.Stringer, - extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--from=%s", from.String()), - fmt.Sprintf("--dseq=%v", bid.DSeq), - fmt.Sprintf("--gseq=%v", bid.GSeq), - fmt.Sprintf("--oseq=%v", bid.OSeq), - fmt.Sprintf("--provider=%s", bid.Provider), - } - - args = append(args, extraArgs...) - - return clitestutil.ExecTestCLICmd(clientCtx, cmdLeaseCreate(key), args) -} - -// TxCloseLeaseExec is used for testing close order tx -func TxCloseLeaseExec(clientCtx client.Context, orderID types.OrderID, from fmt.Stringer, - extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--from=%s", from.String()), - fmt.Sprintf("--owner=%s", orderID.Owner), - fmt.Sprintf("--dseq=%v", orderID.DSeq), - fmt.Sprintf("--gseq=%v", orderID.GSeq), - fmt.Sprintf("--oseq=%v", orderID.OSeq), - } - - args = append(args, extraArgs...) - - return clitestutil.ExecTestCLICmd(clientCtx, cmdLeaseClose(key), args) -} - -// QueryOrdersExec is used for testing orders query -func QueryOrdersExec(clientCtx client.Context, args ...string) (sdktest.BufferWriter, error) { - return clitestutil.ExecTestCLICmd(clientCtx, cmdGetOrders(), args) -} - -// QueryOrderExec is used for testing order query -func QueryOrderExec(clientCtx client.Context, orderID types.OrderID, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--owner=%s", orderID.Owner), - fmt.Sprintf("--dseq=%v", orderID.DSeq), - fmt.Sprintf("--gseq=%v", orderID.GSeq), - fmt.Sprintf("--oseq=%v", orderID.OSeq), - } - - args = append(args, extraArgs...) - - return clitestutil.ExecTestCLICmd(clientCtx, cmdGetOrder(), args) -} - -// QueryBidsExec is used for testing bids query -func QueryBidsExec(clientCtx client.Context, args ...string) (sdktest.BufferWriter, error) { - return clitestutil.ExecTestCLICmd(clientCtx, cmdGetBids(), args) -} - -// QueryBidExec is used for testing bid query -func QueryBidExec(clientCtx client.Context, bidID types.BidID, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--owner=%s", bidID.Owner), - fmt.Sprintf("--dseq=%v", bidID.DSeq), - fmt.Sprintf("--gseq=%v", bidID.GSeq), - fmt.Sprintf("--oseq=%v", bidID.OSeq), - fmt.Sprintf("--provider=%v", bidID.Provider), - } - - args = append(args, extraArgs...) - - return clitestutil.ExecTestCLICmd(clientCtx, cmdGetBid(), args) -} - -// QueryLeasesExec is used for testing leases query -func QueryLeasesExec(clientCtx client.Context, args ...string) (sdktest.BufferWriter, error) { - return clitestutil.ExecTestCLICmd(clientCtx, cmdGetLeases(), args) -} - -// QueryLeaseExec is used for testing lease query -func QueryLeaseExec(clientCtx client.Context, leaseID types.LeaseID, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--owner=%s", leaseID.Owner), - fmt.Sprintf("--dseq=%v", leaseID.DSeq), - fmt.Sprintf("--gseq=%v", leaseID.GSeq), - fmt.Sprintf("--oseq=%v", leaseID.OSeq), - fmt.Sprintf("--provider=%v", leaseID.Provider), - } - - args = append(args, extraArgs...) - - return clitestutil.ExecTestCLICmd(clientCtx, cmdGetLease(), args) -} diff --git a/x/market/client/cli/tx.go b/x/market/client/cli/tx.go deleted file mode 100644 index 97aa8b5707..0000000000 --- a/x/market/client/cli/tx.go +++ /dev/null @@ -1,339 +0,0 @@ -package cli - -import ( - "fmt" - - cltypes "github.com/akash-network/akash-api/go/node/client/types" - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - - aclient "github.com/akash-network/node/client" - "github.com/akash-network/node/cmd/common" - dcli "github.com/akash-network/node/x/deployment/client/cli" -) - -// GetTxCmd returns the transaction commands for market module -func GetTxCmd(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: "Transaction subcommands", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - cmd.AddCommand( - cmdBid(key), - cmdLease(key), - ) - return cmd -} - -func cmdBid(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: "bid", - Short: "Bid subcommands", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - cmd.AddCommand( - cmdBidCreate(key), - cmdBidClose(key), - ) - return cmd -} - -func cmdBidCreate(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: "create", - Short: fmt.Sprintf("Create a %s bid", key), - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - price, err := cmd.Flags().GetString("price") - if err != nil { - return err - } - - coin, err := sdk.ParseDecCoin(price) - if err != nil { - return err - } - - id, err := OrderIDFromFlags(cmd.Flags(), dcli.WithProvider(cctx.FromAddress)) - if err != nil { - return err - } - - deposit, err := common.DetectDeposit(ctx, cmd.Flags(), cl.Query(), "market", "BidMinDeposit") - if err != nil { - return err - } - - msg := &types.MsgCreateBid{ - Order: id, - Provider: cctx.GetFromAddress().String(), - Price: coin, - Deposit: deposit, - } - - if err := msg.ValidateBasic(); err != nil { - return err - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - AddOrderIDFlags(cmd.Flags()) - cmd.Flags().String("price", "", "Bid Price") - common.AddDepositFlags(cmd.Flags()) - - return cmd -} - -func cmdBidClose(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: "close", - Short: fmt.Sprintf("Close a %s bid", key), - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - id, err := BidIDFromFlags(cmd.Flags(), dcli.WithProvider(cctx.FromAddress)) - if err != nil { - return err - } - - msg := &types.MsgCloseBid{ - BidID: id, - } - - if err := msg.ValidateBasic(); err != nil { - return err - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - AddBidIDFlags(cmd.Flags()) - - return cmd -} - -func cmdLease(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: "lease", - Short: "Lease subcommands", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - cmd.AddCommand( - cmdLeaseCreate(key), - cmdLeaseWithdraw(key), - cmdLeaseClose(key), - ) - return cmd -} - -func cmdLeaseCreate(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: "create", - Short: fmt.Sprintf("Create a %s lease", key), - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - id, err := LeaseIDFromFlags(cmd.Flags(), dcli.WithOwner(cctx.FromAddress)) - if err != nil { - return err - } - - msg := &types.MsgCreateLease{ - BidID: id.BidID(), - } - - if err := msg.ValidateBasic(); err != nil { - return err - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - AddLeaseIDFlags(cmd.Flags()) - MarkReqLeaseIDFlags(cmd, dcli.DeploymentIDOptionNoOwner(true)) - - return cmd -} - -func cmdLeaseWithdraw(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: "withdraw", - Short: fmt.Sprintf("Settle and withdraw available funds from %s order escrow account", key), - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - id, err := LeaseIDFromFlags(cmd.Flags(), dcli.WithOwner(cctx.FromAddress)) - if err != nil { - return err - } - - msg := &types.MsgWithdrawLease{ - LeaseID: id, - } - - if err := msg.ValidateBasic(); err != nil { - return err - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - AddLeaseIDFlags(cmd.Flags()) - MarkReqLeaseIDFlags(cmd, dcli.DeploymentIDOptionNoOwner(true)) - - return cmd -} - -func cmdLeaseClose(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: "close", - Short: fmt.Sprintf("Close a %s order", key), - Args: cobra.ExactArgs(0), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - id, err := LeaseIDFromFlags(cmd.Flags(), dcli.WithOwner(cctx.FromAddress)) - if err != nil { - return err - } - - msg := &types.MsgCloseLease{ - LeaseID: id, - } - - if err := msg.ValidateBasic(); err != nil { - return err - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - AddLeaseIDFlags(cmd.Flags()) - MarkReqLeaseIDFlags(cmd, dcli.DeploymentIDOptionNoOwner(true)) - - return cmd -} diff --git a/x/market/client/rest/params.go b/x/market/client/rest/params.go index c737e10a82..a51bb5fe78 100644 --- a/x/market/client/rest/params.go +++ b/x/market/client/rest/params.go @@ -1,110 +1,109 @@ package rest -import ( - "net/http" - "strconv" - - sdk "github.com/cosmos/cosmos-sdk/types" - - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - - drest "github.com/akash-network/node/x/deployment/client/rest" - "github.com/akash-network/node/x/market/query" -) - -// OrderIDFromRequest returns OrderID from parsing request -func OrderIDFromRequest(r *http.Request) (types.OrderID, string) { - gID, errMsg := drest.GroupIDFromRequest(r) - if len(errMsg) != 0 { - return types.OrderID{}, errMsg - } - oseqNo := r.URL.Query().Get("oseq") - - var oseq uint32 - - if len(oseqNo) != 0 { - num, err := strconv.ParseUint(oseqNo, 10, 32) - if err != nil { - return types.OrderID{}, err.Error() - } - oseq = uint32(num) - } else { - return types.OrderID{}, "Missing oseq query param" - } - return types.MakeOrderID(gID, oseq), "" -} - -// OrderFiltersFromRequest returns OrderFilters with given params in request -func OrderFiltersFromRequest(r *http.Request) (query.OrderFilters, string) { - gfilters, errMsg := drest.GroupFiltersFromRequest(r) - if len(errMsg) != 0 { - return query.OrderFilters{}, errMsg - } - - ofilters := query.OrderFilters{ - Owner: gfilters.Owner, - StateFlagVal: gfilters.StateFlagVal, - } - return ofilters, "" -} - -// BidIDFromRequest returns BidID from parsing request -func BidIDFromRequest(r *http.Request) (types.BidID, string) { - oID, errMsg := OrderIDFromRequest(r) - if len(errMsg) != 0 { - return types.BidID{}, errMsg - } - providerAddr := r.URL.Query().Get("provider") - - var provider sdk.AccAddress - - if len(providerAddr) != 0 { - addr, err := sdk.AccAddressFromBech32(providerAddr) - if err != nil { - return types.BidID{}, err.Error() - } - provider = addr - } else { - return types.BidID{}, "Missing provider query param" - } - - return types.MakeBidID(oID, provider), "" -} - -// BidFiltersFromRequest returns BidFilters with given params in request -func BidFiltersFromRequest(r *http.Request) (query.BidFilters, string) { - ofilters, errMsg := drest.GroupFiltersFromRequest(r) - if len(errMsg) != 0 { - return query.BidFilters{}, errMsg - } - - bfilters := query.BidFilters{ - Owner: ofilters.Owner, - StateFlagVal: ofilters.StateFlagVal, - } - return bfilters, "" -} - -// LeaseIDFromRequest returns LeaseID from parsing request -func LeaseIDFromRequest(r *http.Request) (types.LeaseID, string) { - bID, errMsg := BidIDFromRequest(r) - if len(errMsg) != 0 { - return types.LeaseID{}, errMsg - } - - return types.MakeLeaseID(bID), "" -} - -// LeaseFiltersFromRequest returns LeaseFilters with given params in request -func LeaseFiltersFromRequest(r *http.Request) (query.LeaseFilters, string) { - bfilters, errMsg := drest.GroupFiltersFromRequest(r) - if len(errMsg) != 0 { - return query.LeaseFilters{}, errMsg - } - - lfilters := query.LeaseFilters{ - Owner: bfilters.Owner, - StateFlagVal: bfilters.StateFlagVal, - } - return lfilters, "" -} +// import ( +// "net/http" +// "strconv" +// +// sdk "github.com/cosmos/cosmos-sdk/types" +// "pkg.akt.dev/go/node/market/v1" +// "pkg.akt.dev/go/node/market/v1beta5" +// +// drest "pkg.akt.dev/node/x/deployment/client/rest" +// ) +// +// // OrderIDFromRequest returns OrderID from parsing request +// func OrderIDFromRequest(r *http.Request) (v1.OrderID, string) { +// gID, errMsg := drest.GroupIDFromRequest(r) +// if len(errMsg) != 0 { +// return v1.OrderID{}, errMsg +// } +// oseqNo := r.URL.Query().Get("oseq") +// +// var oseq uint32 +// +// if len(oseqNo) != 0 { +// num, err := strconv.ParseUint(oseqNo, 10, 32) +// if err != nil { +// return v1.OrderID{}, err.Error() +// } +// oseq = uint32(num) +// } else { +// return v1.OrderID{}, "Missing oseq query param" +// } +// return v1.MakeOrderID(gID, oseq), "" +// } +// +// // OrderFiltersFromRequest returns OrderFilters with given params in request +// func OrderFiltersFromRequest(r *http.Request) (v1beta5.OrderFilters, string) { +// gfilters, errMsg := drest.GroupFiltersFromRequest(r) +// if len(errMsg) != 0 { +// return v1beta5.OrderFilters{}, errMsg +// } +// +// ofilters := v1beta5.OrderFilters{ +// Owner: gfilters.Owner, +// State: gfilters.State, +// } +// return ofilters, "" +// } +// +// // BidIDFromRequest returns BidID from parsing request +// func BidIDFromRequest(r *http.Request) (v1.BidID, string) { +// oID, errMsg := OrderIDFromRequest(r) +// if len(errMsg) != 0 { +// return v1.BidID{}, errMsg +// } +// providerAddr := r.URL.Query().Get("provider") +// +// var provider sdk.AccAddress +// +// if len(providerAddr) != 0 { +// addr, err := sdk.AccAddressFromBech32(providerAddr) +// if err != nil { +// return v1.BidID{}, err.Error() +// } +// provider = addr +// } else { +// return v1.BidID{}, "Missing provider query param" +// } +// +// return v1.MakeBidID(oID, provider), "" +// } +// +// // BidFiltersFromRequest returns BidFilters with given params in request +// func BidFiltersFromRequest(r *http.Request) (v1beta5.BidFilters, string) { +// ofilters, errMsg := drest.GroupFiltersFromRequest(r) +// if len(errMsg) != 0 { +// return v1beta5.BidFilters{}, errMsg +// } +// +// bfilters := v1beta5.BidFilters{ +// Owner: ofilters.Owner, +// State: ofilters.State, +// } +// return bfilters, "" +// } +// +// // LeaseIDFromRequest returns LeaseID from parsing request +// func LeaseIDFromRequest(r *http.Request) (v1.LeaseID, string) { +// bID, errMsg := BidIDFromRequest(r) +// if len(errMsg) != 0 { +// return v1.LeaseID{}, errMsg +// } +// +// return v1.MakeLeaseID(bID), "" +// } +// +// // LeaseFiltersFromRequest returns LeaseFilters with given params in request +// func LeaseFiltersFromRequest(r *http.Request) (v1.LeaseFilters, string) { +// bfilters, errMsg := drest.GroupFiltersFromRequest(r) +// if len(errMsg) != 0 { +// return v1.LeaseFilters{}, errMsg +// } +// +// lfilters := v1.LeaseFilters{ +// Owner: bfilters.Owner, +// State: bfilters.State, +// } +// return lfilters, "" +// } diff --git a/x/market/client/rest/rest.go b/x/market/client/rest/rest.go index 1c5ec8527c..3cadc1c21a 100644 --- a/x/market/client/rest/rest.go +++ b/x/market/client/rest/rest.go @@ -5,10 +5,8 @@ import ( "net/http" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/types/rest" "github.com/gorilla/mux" - - "github.com/akash-network/node/x/market/query" + // "pkg.akt.dev/node/x/market/query" ) // RegisterRoutes registers all query routes @@ -32,112 +30,109 @@ func RegisterRoutes(ctx client.Context, r *mux.Router, ns string) { r.HandleFunc(fmt.Sprintf("/%s/lease/info", ns), getLeaseHandler(ctx, ns)).Methods("GET") } -func listOrdersHandler(ctx client.Context, ns string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - ofilters, errMsg := OrderFiltersFromRequest(r) - - if len(errMsg) != 0 { - rest.WriteErrorResponse(w, http.StatusBadRequest, errMsg) - return - } - - res, err := query.NewRawClient(ctx, ns).Orders(ofilters) - if err != nil { - rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") - return - } - rest.PostProcessResponse(w, ctx, res) +func listOrdersHandler(_ client.Context, _ string) http.HandlerFunc { + return func(_ http.ResponseWriter, _ *http.Request) { + // ofilters, errMsg := OrderFiltersFromRequest(r) + // + // if len(errMsg) != 0 { + // rest.WriteErrorResponse(w, http.StatusBadRequest, errMsg) + // return + // } + // + // res, err := query.NewRawClient(ctx, ns).Orders(ofilters) + // if err != nil { + // rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") + // return + // } + // rest.PostProcessResponse(w, ctx, res) } } -func listBidsHandler(ctx client.Context, ns string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - bfilters, errMsg := BidFiltersFromRequest(r) - - if len(errMsg) != 0 { - rest.WriteErrorResponse(w, http.StatusBadRequest, errMsg) - return - } - - res, err := query.NewRawClient(ctx, ns).Bids(bfilters) - if err != nil { - rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") - return - } - rest.PostProcessResponse(w, ctx, res) +func listBidsHandler(_ client.Context, _ string) http.HandlerFunc { + return func(_ http.ResponseWriter, _ *http.Request) { + // bfilters, errMsg := BidFiltersFromRequest(r) + // + // if len(errMsg) != 0 { + // rest.WriteErrorResponse(w, http.StatusBadRequest, errMsg) + // return + // } + // + // res, err := query.NewRawClient(ctx, ns).Bids(bfilters) + // if err != nil { + // rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") + // return + // } + // rest.PostProcessResponse(w, ctx, res) } } -func listLeasesHandler(ctx client.Context, ns string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - lfilters, errMsg := LeaseFiltersFromRequest(r) - - if len(errMsg) != 0 { - rest.WriteErrorResponse(w, http.StatusBadRequest, errMsg) - return - } - res, err := query.NewRawClient(ctx, ns).Leases(lfilters) - if err != nil { - rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") - return - } - rest.PostProcessResponse(w, ctx, res) +func listLeasesHandler(_ client.Context, _ string) http.HandlerFunc { + return func(_ http.ResponseWriter, _ *http.Request) { + // lfilters, errMsg := LeaseFiltersFromRequest(r) + // + // if len(errMsg) != 0 { + // rest.WriteErrorResponse(w, http.StatusBadRequest, errMsg) + // return + // } + // res, err := query.NewRawClient(ctx, ns).Leases(lfilters) + // if err != nil { + // rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") + // return + // } + // rest.PostProcessResponse(w, ctx, res) } } -func getOrderHandler(ctx client.Context, ns string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - id, errMsg := OrderIDFromRequest(r) - - if len(errMsg) != 0 { - rest.WriteErrorResponse(w, http.StatusBadRequest, errMsg) - return - } - - res, err := query.NewRawClient(ctx, ns).Order(id) - if err != nil { - rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") - return - } - rest.PostProcessResponse(w, ctx, res) +func getOrderHandler(_ client.Context, _ string) http.HandlerFunc { + return func(_ http.ResponseWriter, _ *http.Request) { + // id, errMsg := OrderIDFromRequest(r) + // + // if len(errMsg) != 0 { + // rest.WriteErrorResponse(w, http.StatusBadRequest, errMsg) + // return + // } + // + // res, err := query.NewRawClient(ctx, ns).Order(id) + // if err != nil { + // rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") + // return + // } + // rest.PostProcessResponse(w, ctx, res) } } -func getBidHandler(ctx client.Context, ns string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - id, errMsg := BidIDFromRequest(r) - - if len(errMsg) != 0 { - rest.WriteErrorResponse(w, http.StatusBadRequest, errMsg) - return - } - - res, err := query.NewRawClient(ctx, ns).Bid(id) - if err != nil { - rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") - return - } - rest.PostProcessResponse(w, ctx, res) +func getBidHandler(_ client.Context, _ string) http.HandlerFunc { + return func(_ http.ResponseWriter, _ *http.Request) { + // id, errMsg := BidIDFromRequest(r) + // + // if len(errMsg) != 0 { + // rest.WriteErrorResponse(w, http.StatusBadRequest, errMsg) + // return + // } + // + // res, err := query.NewRawClient(ctx, ns).Bid(id) + // if err != nil { + // rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") + // return + // } + // rest.PostProcessResponse(w, ctx, res) } } -func getLeaseHandler(ctx client.Context, ns string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - id, errMsg := LeaseIDFromRequest(r) - - if len(errMsg) != 0 { - rest.WriteErrorResponse(w, http.StatusBadRequest, errMsg) - return - } - - res, err := query.NewRawClient(ctx, ns).Lease(id) - if err != nil { - rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") - return - } - rest.PostProcessResponse(w, ctx, res) +func getLeaseHandler(_ client.Context, _ string) http.HandlerFunc { + return func(_ http.ResponseWriter, _ *http.Request) { + // id, errMsg := LeaseIDFromRequest(r) + // + // if len(errMsg) != 0 { + // rest.WriteErrorResponse(w, http.StatusBadRequest, errMsg) + // return + // } + // + // res, err := query.NewRawClient(ctx, ns).Lease(id) + // if err != nil { + // rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") + // return + // } + // rest.PostProcessResponse(w, ctx, res) } } diff --git a/x/market/genesis.go b/x/market/genesis.go index 7f3fb95f9f..99485cd201 100644 --- a/x/market/genesis.go +++ b/x/market/genesis.go @@ -6,16 +6,16 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" + "pkg.akt.dev/go/node/market/v1" + "pkg.akt.dev/go/node/market/v1beta5" - "github.com/akash-network/node/x/market/keeper" - keys "github.com/akash-network/node/x/market/keeper/keys/v1beta4" + "pkg.akt.dev/node/x/market/keeper" + "pkg.akt.dev/node/x/market/keeper/keys" ) // ValidateGenesis does validation check of the Genesis -func ValidateGenesis(data *types.GenesisState) error { +func ValidateGenesis(data *v1beta5.GenesisState) error { if err := data.Params.Validate(); err != nil { return err } @@ -25,36 +25,36 @@ func ValidateGenesis(data *types.GenesisState) error { // DefaultGenesisState returns default genesis state as raw bytes for the market // module. -func DefaultGenesisState() *types.GenesisState { - return &types.GenesisState{ - Params: types.DefaultParams(), +func DefaultGenesisState() *v1beta5.GenesisState { + return &v1beta5.GenesisState{ + Params: v1beta5.DefaultParams(), } } // InitGenesis initiate genesis state and return updated validator details -func InitGenesis(ctx sdk.Context, kpr keeper.IKeeper, data *types.GenesisState) []abci.ValidatorUpdate { +func InitGenesis(ctx sdk.Context, kpr keeper.IKeeper, data *v1beta5.GenesisState) { store := ctx.KVStore(kpr.StoreKey()) cdc := kpr.Codec() for _, record := range data.Orders { - key := keys.MustOrderKey(keys.OrderStateToPrefix(record.State), record.ID()) + key := keys.MustOrderKey(keys.OrderStateToPrefix(record.State), record.ID) if store.Has(key) { - panic(fmt.Errorf("market genesis orders init. order id %s: %w", record.ID(), types.ErrOrderExists)) + panic(fmt.Errorf("market genesis orders init. order id %s: %w", record.ID, v1.ErrOrderExists)) } store.Set(key, cdc.MustMarshal(&record)) } for _, record := range data.Bids { - key := keys.MustBidKey(keys.BidStateToPrefix(record.State), record.ID()) - revKey := keys.MustBidReverseKey(keys.BidStateToPrefix(record.State), record.ID()) + key := keys.MustBidKey(keys.BidStateToPrefix(record.State), record.ID) + revKey := keys.MustBidReverseKey(keys.BidStateToPrefix(record.State), record.ID) if store.Has(key) { - panic(fmt.Errorf("market genesis bids init. bid id %s: %w", record.ID(), types.ErrBidExists)) + panic(fmt.Errorf("market genesis bids init. bid id %s: %w", record.ID, v1.ErrBidExists)) } if store.Has(revKey) { - panic(fmt.Errorf("market genesis bids init. reverse key for bid id %s: %w", record.ID(), types.ErrBidExists)) + panic(fmt.Errorf("market genesis bids init. reverse key for bid id %s: %w", record.ID, v1.ErrBidExists)) } data := cdc.MustMarshal(&record) @@ -63,15 +63,15 @@ func InitGenesis(ctx sdk.Context, kpr keeper.IKeeper, data *types.GenesisState) } for _, record := range data.Leases { - key := keys.MustLeaseKey(keys.LeaseStateToPrefix(record.State), record.ID()) - revKey := keys.MustLeaseReverseKey(keys.LeaseStateToPrefix(record.State), record.ID()) + key := keys.MustLeaseKey(keys.LeaseStateToPrefix(record.State), record.ID) + revKey := keys.MustLeaseReverseKey(keys.LeaseStateToPrefix(record.State), record.ID) if store.Has(key) { - panic(fmt.Errorf("market genesis leases init. lease id %s: lease exists", record.ID())) + panic(fmt.Errorf("market genesis leases init. lease id %s: lease exists", record.ID)) } if store.Has(revKey) { - panic(fmt.Errorf("market genesis leases init. reverse key for lease id %s: lease exists", record.ID())) + panic(fmt.Errorf("market genesis leases init. reverse key for lease id %s: lease exists", record.ID)) } data := cdc.MustMarshal(&record) @@ -79,35 +79,36 @@ func InitGenesis(ctx sdk.Context, kpr keeper.IKeeper, data *types.GenesisState) store.Set(revKey, data) } - kpr.SetParams(ctx, data.Params) - - return []abci.ValidatorUpdate{} + err := kpr.SetParams(ctx, data.Params) + if err != nil { + panic(err) + } } // ExportGenesis returns genesis state as raw bytes for the market module -func ExportGenesis(ctx sdk.Context, k keeper.IKeeper) *types.GenesisState { +func ExportGenesis(ctx sdk.Context, k keeper.IKeeper) *v1beta5.GenesisState { params := k.GetParams(ctx) - var bids []types.Bid - var leases []types.Lease - var orders []types.Order + var bids v1beta5.Bids + var leases v1.Leases + var orders v1beta5.Orders - k.WithLeases(ctx, func(lease types.Lease) bool { + k.WithLeases(ctx, func(lease v1.Lease) bool { leases = append(leases, lease) return false }) - k.WithOrders(ctx, func(order types.Order) bool { + k.WithOrders(ctx, func(order v1beta5.Order) bool { orders = append(orders, order) return false }) - k.WithBids(ctx, func(bid types.Bid) bool { + k.WithBids(ctx, func(bid v1beta5.Bid) bool { bids = append(bids, bid) return false }) - return &types.GenesisState{ + return &v1beta5.GenesisState{ Params: params, Orders: orders, Leases: leases, @@ -117,8 +118,8 @@ func ExportGenesis(ctx sdk.Context, k keeper.IKeeper) *types.GenesisState { // GetGenesisStateFromAppState returns x/market GenesisState given raw application // genesis state. -func GetGenesisStateFromAppState(cdc codec.JSONCodec, appState map[string]json.RawMessage) *types.GenesisState { - var genesisState types.GenesisState +func GetGenesisStateFromAppState(cdc codec.JSONCodec, appState map[string]json.RawMessage) *v1beta5.GenesisState { + var genesisState v1beta5.GenesisState if appState[ModuleName] != nil { cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState) diff --git a/x/market/handler/handler.go b/x/market/handler/handler.go index 8681a0cc5f..bb04494fd5 100644 --- a/x/market/handler/handler.go +++ b/x/market/handler/handler.go @@ -1,38 +1,34 @@ package handler import ( + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" + types "pkg.akt.dev/go/node/market/v1beta5" ) // NewHandler returns a handler for "market" type messages -func NewHandler(keepers Keepers) sdk.Handler { +func NewHandler(keepers Keepers) baseapp.MsgServiceHandler { ms := NewServer(keepers) return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { switch msg := msg.(type) { case *types.MsgCreateBid: - res, err := ms.CreateBid(sdk.WrapSDKContext(ctx), msg) + res, err := ms.CreateBid(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) - case *types.MsgCloseBid: - res, err := ms.CloseBid(sdk.WrapSDKContext(ctx), msg) + res, err := ms.CloseBid(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) - case *types.MsgWithdrawLease: - res, err := ms.WithdrawLease(sdk.WrapSDKContext(ctx), msg) + res, err := ms.WithdrawLease(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) - case *types.MsgCreateLease: - res, err := ms.CreateLease(sdk.WrapSDKContext(ctx), msg) + res, err := ms.CreateLease(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) - case *types.MsgCloseLease: - res, err := ms.CloseLease(sdk.WrapSDKContext(ctx), msg) + res, err := ms.CloseLease(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) - default: return nil, sdkerrors.ErrUnknownRequest } diff --git a/x/market/handler/handler_test.go b/x/market/handler/handler_test.go index cb78c5769d..8285dece1a 100644 --- a/x/market/handler/handler_test.go +++ b/x/market/handler/handler_test.go @@ -8,24 +8,29 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/cometbft/cometbft/libs/rand" + + sdkmath "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/baseapp" sdktestdata "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/tendermint/tendermint/libs/rand" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - ptypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" - akashtypes "github.com/akash-network/akash-api/go/node/types/v1beta3" + dtypes "pkg.akt.dev/go/node/deployment/v1beta4" + v1 "pkg.akt.dev/go/node/market/v1" + types "pkg.akt.dev/go/node/market/v1beta5" + ptypes "pkg.akt.dev/go/node/provider/v1beta4" + attr "pkg.akt.dev/go/node/types/attributes/v1" + deposit "pkg.akt.dev/go/node/types/deposit/v1" + "pkg.akt.dev/go/testutil" - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/testutil/state" - "github.com/akash-network/node/x/market/handler" + "pkg.akt.dev/node/testutil/state" + "pkg.akt.dev/node/x/market/handler" ) type testSuite struct { *state.TestSuite - handler sdk.Handler + handler baseapp.MsgServiceHandler t testing.TB } @@ -40,8 +45,7 @@ func setupTestSuite(t *testing.T) *testSuite { Market: ssuite.MarketKeeper(), Deployment: ssuite.DeploymentKeeper(), Provider: ssuite.ProviderKeeper(), - // unused? - // Bank: ssuite.BankKeeper(), + Bank: ssuite.BankKeeper(), }), } @@ -63,29 +67,31 @@ func TestCreateBidValid(t *testing.T) { order, gspec := suite.createOrder(testutil.Resources(t)) provider := suite.createProvider(gspec.Requirements.Attributes).Owner + providerAddr, err := sdk.AccAddressFromBech32(provider) + require.NoError(t, err) msg := &types.MsgCreateBid{ - Order: order.ID(), - Provider: provider, - Price: sdk.NewDecCoin(testutil.CoinDenom, sdk.NewInt(1)), - Deposit: types.DefaultBidMinDeposit, + ID: v1.MakeBidID(order.ID, providerAddr), + Price: sdk.NewDecCoin(testutil.CoinDenom, sdkmath.NewInt(1)), + Deposit: deposit.Deposit{ + Amount: types.DefaultBidMinDeposit, + Sources: deposit.Sources{deposit.SourceBalance}, + }, } res, err := suite.handler(suite.Context(), msg) require.NotNil(t, res) require.NoError(t, err) - providerAddr, err := sdk.AccAddressFromBech32(provider) - require.NoError(t, err) - - bid := types.MakeBidID(order.ID(), providerAddr) + bid := v1.MakeBidID(order.ID, providerAddr) t.Run("ensure event created", func(t *testing.T) { - t.Skip("EVENTS TESTING") - iev := testutil.ParseMarketEvent(t, res.Events[2:]) - require.IsType(t, types.EventBidCreated{}, iev) + iev, err := sdk.ParseTypedEvent(res.Events[3]) + require.NoError(t, err) + + require.IsType(t, &v1.EventBidCreated{}, iev) - dev := iev.(types.EventBidCreated) + dev := iev.(*v1.EventBidCreated) require.Equal(t, bid, dev.ID) }) @@ -100,39 +106,36 @@ func TestCreateBidInvalidPrice(t *testing.T) { order, gspec := suite.createOrder(nil) provider := suite.createProvider(gspec.Requirements.Attributes).Owner + providerAddr, err := sdk.AccAddressFromBech32(provider) + require.NoError(t, err) msg := &types.MsgCreateBid{ - Order: order.ID(), - Provider: provider, - Price: sdk.DecCoin{}, + ID: v1.MakeBidID(order.ID, providerAddr), + Price: sdk.DecCoin{}, } res, err := suite.handler(suite.Context(), msg) require.Nil(t, res) require.Error(t, err) - providerAddr, err := sdk.AccAddressFromBech32(provider) - require.NoError(t, err) - - _, found := suite.MarketKeeper().GetBid(suite.Context(), types.MakeBidID(order.ID(), providerAddr)) + _, found := suite.MarketKeeper().GetBid(suite.Context(), v1.MakeBidID(order.ID, providerAddr)) require.False(t, found) } func TestCreateBidNonExistingOrder(t *testing.T) { suite := setupTestSuite(t) + orderID := v1.OrderID{Owner: testutil.AccAddress(t).String()} + providerAddr := testutil.AccAddress(t) msg := &types.MsgCreateBid{ - Order: types.OrderID{Owner: testutil.AccAddress(t).String()}, - Provider: testutil.AccAddress(t).String(), - Price: testutil.AkashDecCoinRandom(t), + ID: v1.MakeBidID(orderID, providerAddr), + Price: testutil.AkashDecCoinRandom(t), } res, err := suite.handler(suite.Context(), msg) require.Nil(t, res) require.Error(t, err) - providerAddr, _ := sdk.AccAddressFromBech32(msg.Provider) - - _, found := suite.MarketKeeper().GetBid(suite.Context(), types.MakeBidID(msg.Order, providerAddr)) + _, found := suite.MarketKeeper().GetBid(suite.Context(), v1.MakeBidID(orderID, providerAddr)) require.False(t, found) } @@ -140,13 +143,16 @@ func TestCreateBidClosedOrder(t *testing.T) { suite := setupTestSuite(t) order, gspec := suite.createOrder(nil) + provider := suite.createProvider(gspec.Requirements.Attributes).Owner + providerAddr, err := sdk.AccAddressFromBech32(provider) - suite.MarketKeeper().OnOrderClosed(suite.Context(), order) + require.NoError(t, err) + + _ = suite.MarketKeeper().OnOrderClosed(suite.Context(), order) msg := &types.MsgCreateBid{ - Order: order.ID(), - Provider: suite.createProvider(gspec.Requirements.Attributes).Owner, - Price: sdk.NewDecCoin(testutil.CoinDenom, sdk.NewInt(math.MaxInt64)), + ID: v1.MakeBidID(order.ID, providerAddr), + Price: sdk.NewDecCoin(testutil.CoinDenom, sdkmath.NewInt(math.MaxInt64)), } res, err := suite.handler(suite.Context(), msg) @@ -159,15 +165,17 @@ func TestCreateBidOverprice(t *testing.T) { resources := dtypes.ResourceUnits{ { - Price: sdk.NewDecCoin(testutil.CoinDenom, sdk.NewInt(1)), + Price: sdk.NewDecCoin(testutil.CoinDenom, sdkmath.NewInt(1)), }, } order, gspec := suite.createOrder(resources) + providerAddr, err := sdk.AccAddressFromBech32(suite.createProvider(gspec.Requirements.Attributes).Owner) + require.NoError(t, err) + msg := &types.MsgCreateBid{ - Order: order.ID(), - Provider: suite.createProvider(gspec.Requirements.Attributes).Owner, - Price: sdk.NewDecCoin(testutil.CoinDenom, sdk.NewInt(math.MaxInt64)), + ID: v1.MakeBidID(order.ID, providerAddr), + Price: sdk.NewDecCoin(testutil.CoinDenom, sdkmath.NewInt(math.MaxInt64)), } res, err := suite.handler(suite.Context(), msg) @@ -181,9 +189,8 @@ func TestCreateBidInvalidProvider(t *testing.T) { order, _ := suite.createOrder(testutil.Resources(t)) msg := &types.MsgCreateBid{ - Order: order.ID(), - Provider: "", - Price: sdk.NewDecCoin(testutil.CoinDenom, sdk.NewInt(1)), + ID: v1.MakeBidID(order.ID, sdk.AccAddress{}), + Price: sdk.NewDecCoin(testutil.CoinDenom, sdkmath.NewInt(1)), } res, err := suite.handler(suite.Context(), msg) @@ -195,11 +202,12 @@ func TestCreateBidInvalidAttributes(t *testing.T) { suite := setupTestSuite(t) order, _ := suite.createOrder(testutil.Resources(t)) + providerAddr, err := sdk.AccAddressFromBech32(suite.createProvider(nil).Owner) + require.NoError(t, err) msg := &types.MsgCreateBid{ - Order: order.ID(), - Provider: suite.createProvider(testutil.Attributes(t)).Owner, - Price: sdk.NewDecCoin(testutil.CoinDenom, sdk.NewInt(1)), + ID: v1.MakeBidID(order.ID, providerAddr), + Price: sdk.NewDecCoin(testutil.CoinDenom, sdkmath.NewInt(1)), } res, err := suite.handler(suite.Context(), msg) @@ -211,12 +219,17 @@ func TestCreateBidAlreadyExists(t *testing.T) { suite := setupTestSuite(t) order, gspec := suite.createOrder(testutil.Resources(t)) + provider := suite.createProvider(gspec.Requirements.Attributes).Owner + providerAddr, err := sdk.AccAddressFromBech32(provider) + require.NoError(t, err) msg := &types.MsgCreateBid{ - Order: order.ID(), - Provider: suite.createProvider(gspec.Requirements.Attributes).Owner, - Price: sdk.NewDecCoin(testutil.CoinDenom, sdk.NewInt(1)), - Deposit: types.DefaultBidMinDeposit, + ID: v1.MakeBidID(order.ID, providerAddr), + Price: sdk.NewDecCoin(testutil.CoinDenom, sdkmath.NewInt(1)), + Deposit: deposit.Deposit{ + Amount: types.DefaultBidMinDeposit, + Sources: deposit.Sources{deposit.SourceBalance}, + }, } res, err := suite.handler(suite.Context(), msg) @@ -292,7 +305,7 @@ func TestCloseBidNonExisting(t *testing.T) { require.NoError(t, err) msg := &types.MsgCloseBid{ - BidID: types.MakeBidID(order.ID(), providerAddr), + ID: v1.MakeBidID(order.ID, providerAddr), } res, err := suite.handler(suite.Context(), msg) @@ -308,7 +321,7 @@ func TestCloseBidUnknownLease(t *testing.T) { suite.MarketKeeper().OnBidMatched(suite.Context(), bid) msg := &types.MsgCloseBid{ - BidID: bid.ID(), + ID: bid.ID, } res, err := suite.handler(suite.Context(), msg) @@ -322,7 +335,7 @@ func TestCloseBidValid(t *testing.T) { _, bid, _ := suite.createLease() msg := &types.MsgCloseBid{ - BidID: bid.ID(), + ID: bid.ID, } res, err := suite.handler(suite.Context(), msg) @@ -330,13 +343,15 @@ func TestCloseBidValid(t *testing.T) { require.NoError(t, err) t.Run("ensure event created", func(t *testing.T) { - t.Skip("EVENTS TESTING") - iev := testutil.ParseMarketEvent(t, res.Events[3:4]) - require.IsType(t, types.EventBidClosed{}, iev) + iev, err := sdk.ParseTypedEvent(res.Events[6]) + require.NoError(t, err) + + // iev := testutil.ParseMarketEvent(t, res.Events[3:4]) + require.IsType(t, &v1.EventBidClosed{}, iev) - dev := iev.(types.EventBidClosed) + dev := iev.(*v1.EventBidClosed) - require.Equal(t, msg.BidID, dev.ID) + require.Equal(t, msg.ID, dev.ID) }) } @@ -346,7 +361,7 @@ func TestCloseBidWithStateOpen(t *testing.T) { bid, _ := suite.createBid() msg := &types.MsgCloseBid{ - BidID: bid.ID(), + ID: bid.ID, } res, err := suite.handler(suite.Context(), msg) @@ -354,13 +369,15 @@ func TestCloseBidWithStateOpen(t *testing.T) { require.NoError(t, err) t.Run("ensure event created", func(t *testing.T) { - t.Skip("EVENTS TESTING") - iev := testutil.ParseMarketEvent(t, res.Events[2:]) - require.IsType(t, types.EventBidClosed{}, iev) + iev, err := sdk.ParseTypedEvent(res.Events[3]) + require.NoError(t, err) - dev := iev.(types.EventBidClosed) + // iev := testutil.ParseMarketEvent(t, res.Events[2:]) + require.IsType(t, &v1.EventBidClosed{}, iev) - require.Equal(t, msg.BidID, dev.ID) + dev := iev.(*v1.EventBidClosed) + + require.Equal(t, msg.ID, dev.ID) }) } @@ -386,18 +403,20 @@ func TestCloseBidUnknownOrder(t *testing.T) { suite := setupTestSuite(t) group := testutil.DeploymentGroup(t, testutil.DeploymentID(t), 0) - orderID := types.MakeOrderID(group.ID(), 1) + orderID := v1.MakeOrderID(group.ID, 1) provider := testutil.AccAddress(t) - price := sdk.NewDecCoin(testutil.CoinDenom, sdk.NewInt(int64(rand.Uint16()))) + price := sdk.NewDecCoin(testutil.CoinDenom, sdkmath.NewInt(int64(rand.Uint16()))) roffer := types.ResourceOfferFromRU(group.GroupSpec.Resources) - bid, err := suite.MarketKeeper().CreateBid(suite.Context(), orderID, provider, price, roffer) + bidID := v1.MakeBidID(orderID, provider) + bid, err := suite.MarketKeeper().CreateBid(suite.Context(), bidID, price, roffer) require.NoError(t, err) - suite.MarketKeeper().CreateLease(suite.Context(), bid) + err = suite.MarketKeeper().CreateLease(suite.Context(), bid) + require.NoError(t, err) msg := &types.MsgCloseBid{ - BidID: bid.ID(), + ID: bid.ID, } res, err := suite.handler(suite.Context(), msg) @@ -405,15 +424,17 @@ func TestCloseBidUnknownOrder(t *testing.T) { require.Error(t, err) } -func (st *testSuite) createLease() (types.LeaseID, types.Bid, types.Order) { +func (st *testSuite) createLease() (v1.LeaseID, types.Bid, types.Order) { st.t.Helper() bid, order := st.createBid() - st.MarketKeeper().CreateLease(st.Context(), bid) + err := st.MarketKeeper().CreateLease(st.Context(), bid) + require.NoError(st.t, err) + st.MarketKeeper().OnBidMatched(st.Context(), bid) st.MarketKeeper().OnOrderMatched(st.Context(), order) - lid := types.MakeLeaseID(bid.ID()) + lid := v1.MakeLeaseID(bid.ID) return lid, bid, order } @@ -421,14 +442,16 @@ func (st *testSuite) createBid() (types.Bid, types.Order) { st.t.Helper() order, gspec := st.createOrder(testutil.Resources(st.t)) provider := testutil.AccAddress(st.t) - price := sdk.NewDecCoin(testutil.CoinDenom, sdk.NewInt(int64(rand.Uint16()))) + price := sdk.NewDecCoin(testutil.CoinDenom, sdkmath.NewInt(int64(rand.Uint16()))) roffer := types.ResourceOfferFromRU(gspec.Resources) - bid, err := st.MarketKeeper().CreateBid(st.Context(), order.ID(), provider, price, roffer) + bidID := v1.MakeBidID(order.ID, provider) + + bid, err := st.MarketKeeper().CreateBid(st.Context(), bidID, price, roffer) require.NoError(st.t, err) - require.Equal(st.t, order.ID(), bid.ID().OrderID()) + require.Equal(st.t, order.ID, bid.ID.OrderID()) require.Equal(st.t, price, bid.Price) - require.Equal(st.t, provider.String(), bid.ID().Provider) + require.Equal(st.t, provider.String(), bid.ID.Provider) return bid, order } @@ -436,22 +459,22 @@ func (st *testSuite) createOrder(resources dtypes.ResourceUnits) (types.Order, d st.t.Helper() deployment := testutil.Deployment(st.t) - group := testutil.DeploymentGroup(st.t, deployment.ID(), 0) + group := testutil.DeploymentGroup(st.t, deployment.ID, 0) group.GroupSpec.Resources = resources err := st.DeploymentKeeper().Create(st.Context(), deployment, []dtypes.Group{group}) require.NoError(st.t, err) - order, err := st.MarketKeeper().CreateOrder(st.Context(), group.ID(), group.GroupSpec) + order, err := st.MarketKeeper().CreateOrder(st.Context(), group.ID, group.GroupSpec) require.NoError(st.t, err) - require.Equal(st.t, group.ID(), order.ID().GroupID()) - require.Equal(st.t, uint32(1), order.ID().OSeq) + require.Equal(st.t, group.ID, order.ID.GroupID()) + require.Equal(st.t, uint32(1), order.ID.OSeq) require.Equal(st.t, types.OrderOpen, order.State) return order, group.GroupSpec } -func (st *testSuite) createProvider(attr []akashtypes.Attribute) ptypes.Provider { +func (st *testSuite) createProvider(attr attr.Attributes) ptypes.Provider { st.t.Helper() prov := ptypes.Provider{ diff --git a/x/market/handler/keepers.go b/x/market/handler/keepers.go index 9a08f139bd..c9a3ca3423 100644 --- a/x/market/handler/keepers.go +++ b/x/market/handler/keepers.go @@ -1,24 +1,32 @@ package handler import ( + "context" + "time" + sdk "github.com/cosmos/cosmos-sdk/types" - bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + "github.com/cosmos/cosmos-sdk/x/authz" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - atypes "github.com/akash-network/akash-api/go/node/audit/v1beta3" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - etypes "github.com/akash-network/akash-api/go/node/escrow/v1beta3" - ptypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" + atypes "pkg.akt.dev/go/node/audit/v1" + dtypes "pkg.akt.dev/go/node/deployment/v1" + dbeta "pkg.akt.dev/go/node/deployment/v1beta4" + escrowid "pkg.akt.dev/go/node/escrow/id/v1" + etypes "pkg.akt.dev/go/node/escrow/types/v1" + ptypes "pkg.akt.dev/go/node/provider/v1beta4" - "github.com/akash-network/node/x/market/keeper" + "pkg.akt.dev/node/x/market/keeper" ) type EscrowKeeper interface { - AccountCreate(ctx sdk.Context, id etypes.AccountID, owner, depositor sdk.AccAddress, deposit sdk.Coin) error - AccountDeposit(ctx sdk.Context, id etypes.AccountID, depositor sdk.AccAddress, amount sdk.Coin) error - AccountClose(ctx sdk.Context, id etypes.AccountID) error - PaymentCreate(ctx sdk.Context, id etypes.AccountID, pid string, owner sdk.AccAddress, rate sdk.DecCoin) error - PaymentWithdraw(ctx sdk.Context, id etypes.AccountID, pid string) error - PaymentClose(ctx sdk.Context, id etypes.AccountID, pid string) error + AccountCreate(ctx sdk.Context, id escrowid.Account, owner sdk.AccAddress, deposits []etypes.Depositor) error + AccountDeposit(ctx sdk.Context, id escrowid.Account, deposits []etypes.Depositor) error + AccountClose(ctx sdk.Context, id escrowid.Account) error + PaymentCreate(ctx sdk.Context, id escrowid.Payment, provider sdk.AccAddress, rate sdk.DecCoin) error + PaymentWithdraw(ctx sdk.Context, id escrowid.Payment) error + PaymentClose(ctx sdk.Context, id escrowid.Payment) error + AuthorizeDeposits(sctx sdk.Context, msg sdk.Msg) ([]etypes.Depositor, error) } // ProviderKeeper Interface includes provider methods @@ -28,14 +36,26 @@ type ProviderKeeper interface { } type AuditKeeper interface { - GetProviderAttributes(ctx sdk.Context, id sdk.Address) (atypes.Providers, bool) + GetProviderAttributes(ctx sdk.Context, id sdk.Address) (atypes.AuditedProviders, bool) } // DeploymentKeeper Interface includes deployment methods type DeploymentKeeper interface { - GetGroup(ctx sdk.Context, id dtypes.GroupID) (dtypes.Group, bool) + GetGroup(ctx sdk.Context, id dtypes.GroupID) (dbeta.Group, bool) OnBidClosed(ctx sdk.Context, id dtypes.GroupID) error - OnLeaseClosed(ctx sdk.Context, id dtypes.GroupID) (dtypes.Group, error) + OnLeaseClosed(ctx sdk.Context, id dtypes.GroupID) (dbeta.Group, error) +} + +type AuthzKeeper interface { + DeleteGrant(ctx context.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) error + GetAuthorization(ctx context.Context, grantee sdk.AccAddress, granter sdk.AccAddress, msgType string) (authz.Authorization, *time.Time) + SaveGrant(ctx context.Context, grantee sdk.AccAddress, granter sdk.AccAddress, authorization authz.Authorization, expiration *time.Time) error + GetGranteeGrantsByMsgType(ctx context.Context, grantee sdk.AccAddress, msgType string, onGrant authzkeeper.OnGrantFn) +} + +type BankKeeper interface { + SpendableCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins + SpendableCoin(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin } // Keepers include all modules keepers @@ -45,5 +65,7 @@ type Keepers struct { Deployment DeploymentKeeper Provider ProviderKeeper Audit AuditKeeper - Bank bankkeeper.Keeper + Account govtypes.AccountKeeper + Authz AuthzKeeper + Bank BankKeeper } diff --git a/x/market/handler/server.go b/x/market/handler/server.go index e81adabe71..3943512e8b 100644 --- a/x/market/handler/server.go +++ b/x/market/handler/server.go @@ -6,11 +6,13 @@ import ( "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - atypes "github.com/akash-network/akash-api/go/node/audit/v1beta3" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - ptypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" + atypes "pkg.akt.dev/go/node/audit/v1" + dbeta "pkg.akt.dev/go/node/deployment/v1beta4" + v1 "pkg.akt.dev/go/node/market/v1" + types "pkg.akt.dev/go/node/market/v1beta5" + ptypes "pkg.akt.dev/go/node/provider/v1beta4" ) type msgServer struct { @@ -31,20 +33,24 @@ func (ms msgServer) CreateBid(goCtx context.Context, msg *types.MsgCreateBid) (* params := ms.keepers.Market.GetParams(ctx) minDeposit := params.BidMinDeposit - if msg.Deposit.Denom != minDeposit.Denom { - return nil, fmt.Errorf("%w: mininum:%v received:%v", types.ErrInvalidDeposit, minDeposit, msg.Deposit) + if msg.Deposit.Amount.Denom != minDeposit.Denom { + return nil, fmt.Errorf("%w: mininum:%v received:%v", v1.ErrInvalidDeposit, minDeposit, msg.Deposit) } - if minDeposit.Amount.GT(msg.Deposit.Amount) { - return nil, fmt.Errorf("%w: mininum:%v received:%v", types.ErrInvalidDeposit, minDeposit, msg.Deposit) + if minDeposit.Amount.GT(msg.Deposit.Amount.Amount) { + return nil, fmt.Errorf("%w: mininum:%v received:%v", v1.ErrInvalidDeposit, minDeposit, msg.Deposit) } - if ms.keepers.Market.BidCountForOrder(ctx, msg.Order) > params.OrderMaxBids { - return nil, fmt.Errorf("%w: too many existing bids (%v)", types.ErrInvalidBid, params.OrderMaxBids) + if ms.keepers.Market.BidCountForOrder(ctx, msg.ID.OrderID()) > params.OrderMaxBids { + return nil, fmt.Errorf("%w: too many existing bids (%v)", v1.ErrInvalidBid, params.OrderMaxBids) } - order, found := ms.keepers.Market.GetOrder(ctx, msg.Order) + if msg.ID.BSeq != 0 { + return nil, v1.ErrInvalidBid + } + + order, found := ms.keepers.Market.GetOrder(ctx, msg.ID.OrderID()) if !found { - return nil, types.ErrOrderNotFound + return nil, v1.ErrOrderNotFound } if err := order.ValidateCanBid(); err != nil { @@ -52,53 +58,55 @@ func (ms msgServer) CreateBid(goCtx context.Context, msg *types.MsgCreateBid) (* } if !msg.Price.IsValid() { - return nil, types.ErrBidInvalidPrice + return nil, v1.ErrBidInvalidPrice } if order.Price().IsLT(msg.Price) { - return nil, types.ErrBidOverOrder + return nil, v1.ErrBidOverOrder } if !msg.ResourcesOffer.MatchGSpec(order.Spec) { - return nil, types.ErrCapabilitiesMismatch + return nil, v1.ErrCapabilitiesMismatch } - provider, err := sdk.AccAddressFromBech32(msg.Provider) + provider, err := sdk.AccAddressFromBech32(msg.ID.Provider) if err != nil { - return nil, types.ErrEmptyProvider + return nil, v1.ErrEmptyProvider } var prov ptypes.Provider if prov, found = ms.keepers.Provider.Get(ctx, provider); !found { - return nil, types.ErrUnknownProvider + return nil, v1.ErrUnknownProvider } provAttr, _ := ms.keepers.Audit.GetProviderAttributes(ctx, provider) - provAttr = append([]atypes.Provider{{ - Owner: msg.Provider, + provAttr = append([]atypes.AuditedProvider{{ + Owner: msg.ID.Provider, Attributes: prov.Attributes, }}, provAttr...) if !order.MatchRequirements(provAttr) { - return nil, types.ErrAttributeMismatch + return nil, v1.ErrAttributeMismatch } if !order.MatchResourcesRequirements(prov.Attributes) { - return nil, types.ErrCapabilitiesMismatch + return nil, v1.ErrCapabilitiesMismatch + } + + deposits, err := ms.keepers.Escrow.AuthorizeDeposits(ctx, msg) + if err != nil { + return nil, err } - bid, err := ms.keepers.Market.CreateBid(ctx, msg.Order, provider, msg.Price, msg.ResourcesOffer) + bid, err := ms.keepers.Market.CreateBid(ctx, msg.ID, msg.Price, msg.ResourcesOffer) if err != nil { return nil, err } - // create escrow account for this bid - if err := ms.keepers.Escrow.AccountCreate(ctx, - types.EscrowAccountForBid(bid.ID()), - provider, - provider, // bids currently don't support deposits by non-owners - msg.Deposit); err != nil { + // create an escrow account for this bid + err = ms.keepers.Escrow.AccountCreate(ctx, bid.ID.ToEscrowAccountID(), provider, deposits) + if err != nil { return &types.MsgCreateBidResponse{}, err } @@ -109,45 +117,43 @@ func (ms msgServer) CreateBid(goCtx context.Context, msg *types.MsgCreateBid) (* func (ms msgServer) CloseBid(goCtx context.Context, msg *types.MsgCloseBid) (*types.MsgCloseBidResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - bid, found := ms.keepers.Market.GetBid(ctx, msg.BidID) + bid, found := ms.keepers.Market.GetBid(ctx, msg.ID) if !found { - return nil, types.ErrUnknownBid + return nil, v1.ErrUnknownBid } - order, found := ms.keepers.Market.GetOrder(ctx, msg.BidID.OrderID()) + order, found := ms.keepers.Market.GetOrder(ctx, msg.ID.OrderID()) if !found { - return nil, types.ErrUnknownOrderForBid + return nil, v1.ErrUnknownOrderForBid } if bid.State == types.BidOpen { - ms.keepers.Market.OnBidClosed(ctx, bid) + _ = ms.keepers.Market.OnBidClosed(ctx, bid) return &types.MsgCloseBidResponse{}, nil } - lease, found := ms.keepers.Market.GetLease(ctx, types.LeaseID(msg.BidID)) + lease, found := ms.keepers.Market.GetLease(ctx, v1.LeaseID(msg.ID)) if !found { - return nil, types.ErrUnknownLeaseForBid + return nil, v1.ErrUnknownLeaseForBid } - if lease.State != types.LeaseActive { - return nil, types.ErrLeaseNotActive + if lease.State != v1.LeaseActive { + return nil, v1.ErrLeaseNotActive } if bid.State != types.BidActive { - return nil, types.ErrBidNotActive + return nil, v1.ErrBidNotActive } - if err := ms.keepers.Deployment.OnBidClosed(ctx, order.ID().GroupID()); err != nil { + if err := ms.keepers.Deployment.OnBidClosed(ctx, order.ID.GroupID()); err != nil { return nil, err } - ms.keepers.Market.OnLeaseClosed(ctx, lease, types.LeaseClosed) - ms.keepers.Market.OnBidClosed(ctx, bid) - ms.keepers.Market.OnOrderClosed(ctx, order) + _ = ms.keepers.Market.OnLeaseClosed(ctx, lease, v1.LeaseClosed, msg.Reason) + _ = ms.keepers.Market.OnBidClosed(ctx, bid) + _ = ms.keepers.Market.OnOrderClosed(ctx, order) - _ = ms.keepers.Escrow.PaymentClose(ctx, - dtypes.EscrowAccountForDeployment(lease.ID().DeploymentID()), - types.EscrowPaymentForLease(lease.ID())) + _ = ms.keepers.Escrow.PaymentClose(ctx, lease.ID.ToEscrowPaymentID()) telemetry.IncrCounter(1.0, "akash.order_closed") @@ -157,15 +163,12 @@ func (ms msgServer) CloseBid(goCtx context.Context, msg *types.MsgCloseBid) (*ty func (ms msgServer) WithdrawLease(goCtx context.Context, msg *types.MsgWithdrawLease) (*types.MsgWithdrawLeaseResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - _, found := ms.keepers.Market.GetLease(ctx, msg.LeaseID) + _, found := ms.keepers.Market.GetLease(ctx, msg.ID) if !found { - return nil, types.ErrUnknownLease + return nil, v1.ErrUnknownLease } - if err := ms.keepers.Escrow.PaymentWithdraw(ctx, - dtypes.EscrowAccountForDeployment(msg.LeaseID.DeploymentID()), - types.EscrowPaymentForLease(msg.LeaseID), - ); err != nil { + if err := ms.keepers.Escrow.PaymentWithdraw(ctx, msg.ID.ToEscrowPaymentID()); err != nil { return &types.MsgWithdrawLeaseResponse{}, err } @@ -177,117 +180,124 @@ func (ms msgServer) CreateLease(goCtx context.Context, msg *types.MsgCreateLease bid, found := ms.keepers.Market.GetBid(ctx, msg.BidID) if !found { - return &types.MsgCreateLeaseResponse{}, types.ErrBidNotFound + return &types.MsgCreateLeaseResponse{}, v1.ErrBidNotFound } if bid.State != types.BidOpen { - return &types.MsgCreateLeaseResponse{}, types.ErrBidNotOpen + return &types.MsgCreateLeaseResponse{}, v1.ErrBidNotOpen } order, found := ms.keepers.Market.GetOrder(ctx, msg.BidID.OrderID()) if !found { - return &types.MsgCreateLeaseResponse{}, types.ErrOrderNotFound + return &types.MsgCreateLeaseResponse{}, v1.ErrOrderNotFound } if order.State != types.OrderOpen { - return &types.MsgCreateLeaseResponse{}, types.ErrOrderNotOpen + return &types.MsgCreateLeaseResponse{}, v1.ErrOrderNotOpen } - group, found := ms.keepers.Deployment.GetGroup(ctx, order.ID().GroupID()) + group, found := ms.keepers.Deployment.GetGroup(ctx, order.ID.GroupID()) if !found { - return &types.MsgCreateLeaseResponse{}, types.ErrGroupNotFound + return &types.MsgCreateLeaseResponse{}, v1.ErrGroupNotFound } - if group.State != dtypes.GroupOpen { - return &types.MsgCreateLeaseResponse{}, types.ErrGroupNotOpen + if group.State != dbeta.GroupOpen { + return &types.MsgCreateLeaseResponse{}, v1.ErrGroupNotOpen } - owner, err := sdk.AccAddressFromBech32(msg.BidID.Provider) + provider, err := sdk.AccAddressFromBech32(msg.BidID.Provider) if err != nil { return &types.MsgCreateLeaseResponse{}, err } - if err := ms.keepers.Escrow.PaymentCreate(ctx, - dtypes.EscrowAccountForDeployment(msg.BidID.DeploymentID()), - types.EscrowPaymentForLease(msg.BidID.LeaseID()), - owner, - bid.Price); err != nil { + err = ms.keepers.Escrow.PaymentCreate(ctx, msg.BidID.LeaseID().ToEscrowPaymentID(), provider, bid.Price) + if err != nil { + return &types.MsgCreateLeaseResponse{}, err + } + + err = ms.keepers.Market.CreateLease(ctx, bid) + if err != nil { return &types.MsgCreateLeaseResponse{}, err } - ms.keepers.Market.CreateLease(ctx, bid) ms.keepers.Market.OnOrderMatched(ctx, order) ms.keepers.Market.OnBidMatched(ctx, bid) // close losing bids - ms.keepers.Market.WithBidsForOrder(ctx, msg.BidID.OrderID(), types.BidOpen, func(bid types.Bid) bool { - ms.keepers.Market.OnBidLost(ctx, bid) + ms.keepers.Market.WithBidsForOrder(ctx, msg.BidID.OrderID(), types.BidOpen, func(cbid types.Bid) bool { + ms.keepers.Market.OnBidLost(ctx, cbid) - if err = ms.keepers.Escrow.AccountClose(ctx, - types.EscrowAccountForBid(bid.ID())); err != nil { + if err = ms.keepers.Escrow.AccountClose(ctx, cbid.ID.ToEscrowAccountID()); err != nil { return true } - return false }) - if err != nil { - return &types.MsgCreateLeaseResponse{}, err - } - return &types.MsgCreateLeaseResponse{}, nil } func (ms msgServer) CloseLease(goCtx context.Context, msg *types.MsgCloseLease) (*types.MsgCloseLeaseResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - order, found := ms.keepers.Market.GetOrder(ctx, msg.LeaseID.OrderID()) + order, found := ms.keepers.Market.GetOrder(ctx, msg.ID.OrderID()) if !found { - return nil, types.ErrOrderNotFound + return nil, v1.ErrOrderNotFound } if order.State != types.OrderActive { - return &types.MsgCloseLeaseResponse{}, types.ErrOrderClosed + return &types.MsgCloseLeaseResponse{}, v1.ErrOrderClosed } - bid, found := ms.keepers.Market.GetBid(ctx, msg.LeaseID.BidID()) + bid, found := ms.keepers.Market.GetBid(ctx, msg.ID.BidID()) if !found { - return &types.MsgCloseLeaseResponse{}, types.ErrBidNotFound + return &types.MsgCloseLeaseResponse{}, v1.ErrBidNotFound } if bid.State != types.BidActive { - return &types.MsgCloseLeaseResponse{}, types.ErrBidNotActive + return &types.MsgCloseLeaseResponse{}, v1.ErrBidNotActive } - lease, found := ms.keepers.Market.GetLease(ctx, msg.LeaseID) + lease, found := ms.keepers.Market.GetLease(ctx, msg.ID) if !found { - return &types.MsgCloseLeaseResponse{}, types.ErrLeaseNotFound + return &types.MsgCloseLeaseResponse{}, v1.ErrLeaseNotFound } - if lease.State != types.LeaseActive { - return &types.MsgCloseLeaseResponse{}, types.ErrOrderClosed + if lease.State != v1.LeaseActive { + return &types.MsgCloseLeaseResponse{}, v1.ErrOrderClosed } - ms.keepers.Market.OnLeaseClosed(ctx, lease, types.LeaseClosed) - ms.keepers.Market.OnBidClosed(ctx, bid) - ms.keepers.Market.OnOrderClosed(ctx, order) + _ = ms.keepers.Market.OnLeaseClosed(ctx, lease, v1.LeaseClosed, v1.LeaseClosedReasonOwner) + _ = ms.keepers.Market.OnBidClosed(ctx, bid) + _ = ms.keepers.Market.OnOrderClosed(ctx, order) - if err := ms.keepers.Escrow.PaymentClose(ctx, - dtypes.EscrowAccountForDeployment(lease.ID().DeploymentID()), - types.EscrowPaymentForLease(lease.ID()), - ); err != nil { + err := ms.keepers.Escrow.PaymentClose(ctx, lease.ID.ToEscrowPaymentID()) + if err != nil { return &types.MsgCloseLeaseResponse{}, err } - group, err := ms.keepers.Deployment.OnLeaseClosed(ctx, msg.LeaseID.GroupID()) + group, err := ms.keepers.Deployment.OnLeaseClosed(ctx, msg.ID.GroupID()) if err != nil { return &types.MsgCloseLeaseResponse{}, err } - if group.State != dtypes.GroupOpen { + if group.State != dbeta.GroupOpen { return &types.MsgCloseLeaseResponse{}, nil } - if _, err := ms.keepers.Market.CreateOrder(ctx, group.ID(), group.GroupSpec); err != nil { + + if _, err := ms.keepers.Market.CreateOrder(ctx, group.ID, group.GroupSpec); err != nil { return &types.MsgCloseLeaseResponse{}, err } + return &types.MsgCloseLeaseResponse{}, nil +} + +func (ms msgServer) UpdateParams(goCtx context.Context, req *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + if ms.keepers.Market.GetAuthority() != req.Authority { + return nil, govtypes.ErrInvalidSigner.Wrapf("invalid authority; expected %s, got %s", ms.keepers.Market.GetAuthority(), req.Authority) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + if err := ms.keepers.Market.SetParams(ctx, req.Params); err != nil { + return nil, err + } + return &types.MsgUpdateParamsResponse{}, nil } diff --git a/x/market/hooks/external.go b/x/market/hooks/external.go index 5ccdabf728..bcc227eb37 100644 --- a/x/market/hooks/external.go +++ b/x/market/hooks/external.go @@ -3,23 +3,25 @@ package hooks import ( sdk "github.com/cosmos/cosmos-sdk/types" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - mtypes "github.com/akash-network/akash-api/go/node/market/v1beta4" + dv1 "pkg.akt.dev/go/node/deployment/v1" + dtypes "pkg.akt.dev/go/node/deployment/v1beta4" + mv1 "pkg.akt.dev/go/node/market/v1" + mtypes "pkg.akt.dev/go/node/market/v1beta5" ) type DeploymentKeeper interface { - GetDeployment(ctx sdk.Context, id dtypes.DeploymentID) (dtypes.Deployment, bool) - GetGroups(ctx sdk.Context, id dtypes.DeploymentID) []dtypes.Group - CloseDeployment(ctx sdk.Context, deployment dtypes.Deployment) + GetDeployment(ctx sdk.Context, id dv1.DeploymentID) (dv1.Deployment, bool) + GetGroups(ctx sdk.Context, id dv1.DeploymentID) dtypes.Groups + CloseDeployment(ctx sdk.Context, deployment dv1.Deployment) error OnCloseGroup(ctx sdk.Context, group dtypes.Group, state dtypes.Group_State) error } type MarketKeeper interface { - GetOrder(ctx sdk.Context, id mtypes.OrderID) (mtypes.Order, bool) - GetBid(ctx sdk.Context, id mtypes.BidID) (mtypes.Bid, bool) - GetLease(ctx sdk.Context, id mtypes.LeaseID) (mtypes.Lease, bool) - OnGroupClosed(ctx sdk.Context, id dtypes.GroupID) - OnOrderClosed(ctx sdk.Context, order mtypes.Order) - OnBidClosed(ctx sdk.Context, bid mtypes.Bid) - OnLeaseClosed(ctx sdk.Context, lease mtypes.Lease, state mtypes.Lease_State) + GetOrder(ctx sdk.Context, id mv1.OrderID) (mtypes.Order, bool) + GetBid(ctx sdk.Context, id mv1.BidID) (mtypes.Bid, bool) + GetLease(ctx sdk.Context, id mv1.LeaseID) (mv1.Lease, bool) + OnGroupClosed(ctx sdk.Context, id dv1.GroupID) error + OnOrderClosed(ctx sdk.Context, order mtypes.Order) error + OnBidClosed(ctx sdk.Context, bid mtypes.Bid) error + OnLeaseClosed(ctx sdk.Context, lease mv1.Lease, state mv1.Lease_State, reason mv1.LeaseClosedReason) error } diff --git a/x/market/hooks/hooks.go b/x/market/hooks/hooks.go index b4ea5eec68..212880f30a 100644 --- a/x/market/hooks/hooks.go +++ b/x/market/hooks/hooks.go @@ -3,15 +3,16 @@ package hooks import ( sdk "github.com/cosmos/cosmos-sdk/types" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - etypes "github.com/akash-network/akash-api/go/node/escrow/v1beta3" - - mtypes "github.com/akash-network/akash-api/go/node/market/v1beta4" + dv1 "pkg.akt.dev/go/node/deployment/v1" + dtypes "pkg.akt.dev/go/node/deployment/v1beta4" + etypes "pkg.akt.dev/go/node/escrow/types/v1" + mv1 "pkg.akt.dev/go/node/market/v1" + mtypes "pkg.akt.dev/go/node/market/v1beta5" ) type Hooks interface { OnEscrowAccountClosed(ctx sdk.Context, obj etypes.Account) - OnEscrowPaymentClosed(ctx sdk.Context, obj etypes.FractionalPayment) + OnEscrowPaymentClosed(ctx sdk.Context, obj etypes.Payment) } type hooks struct { @@ -27,8 +28,8 @@ func New(dkeeper DeploymentKeeper, mkeeper MarketKeeper) Hooks { } func (h *hooks) OnEscrowAccountClosed(ctx sdk.Context, obj etypes.Account) { - id, found := dtypes.DeploymentIDFromEscrowAccount(obj.ID) - if !found { + id, err := dv1.DeploymentIDFromEscrowID(obj.ID) + if err != nil { return } @@ -37,27 +38,27 @@ func (h *hooks) OnEscrowAccountClosed(ctx sdk.Context, obj etypes.Account) { return } - if deployment.State != dtypes.DeploymentActive { + if deployment.State != dv1.DeploymentActive { return } - h.dkeeper.CloseDeployment(ctx, deployment) + _ = h.dkeeper.CloseDeployment(ctx, deployment) gstate := dtypes.GroupClosed - if obj.State == etypes.AccountOverdrawn { + if obj.State.State == etypes.StateOverdrawn { gstate = dtypes.GroupInsufficientFunds } - for _, group := range h.dkeeper.GetGroups(ctx, deployment.ID()) { + for _, group := range h.dkeeper.GetGroups(ctx, deployment.ID) { if group.ValidateClosable() == nil { _ = h.dkeeper.OnCloseGroup(ctx, group, gstate) - h.mkeeper.OnGroupClosed(ctx, group.ID()) + _ = h.mkeeper.OnGroupClosed(ctx, group.ID) } } } -func (h *hooks) OnEscrowPaymentClosed(ctx sdk.Context, obj etypes.FractionalPayment) { - id, ok := mtypes.LeaseIDFromEscrowAccount(obj.AccountID, obj.PaymentID) - if !ok { +func (h *hooks) OnEscrowPaymentClosed(ctx sdk.Context, obj etypes.Payment) { + id, err := mv1.LeaseIDFromPaymentID(obj.ID) + if err != nil { return } @@ -80,12 +81,12 @@ func (h *hooks) OnEscrowPaymentClosed(ctx sdk.Context, obj etypes.FractionalPaym return } - h.mkeeper.OnOrderClosed(ctx, order) - h.mkeeper.OnBidClosed(ctx, bid) + _ = h.mkeeper.OnOrderClosed(ctx, order) + _ = h.mkeeper.OnBidClosed(ctx, bid) - if obj.State == etypes.PaymentOverdrawn { - h.mkeeper.OnLeaseClosed(ctx, lease, mtypes.LeaseInsufficientFunds) + if obj.State.State == etypes.StateOverdrawn { + _ = h.mkeeper.OnLeaseClosed(ctx, lease, mv1.LeaseInsufficientFunds, mv1.LeaseClosedReasonInsufficientFunds) } else { - h.mkeeper.OnLeaseClosed(ctx, lease, mtypes.LeaseClosed) + _ = h.mkeeper.OnLeaseClosed(ctx, lease, mv1.LeaseClosed, mv1.LeaseClosedReasonUnspecified) } } diff --git a/x/market/keeper/external.go b/x/market/keeper/external.go index 033b6d96f6..33bf766228 100644 --- a/x/market/keeper/external.go +++ b/x/market/keeper/external.go @@ -2,13 +2,13 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - - etypes "github.com/akash-network/akash-api/go/node/escrow/v1beta3" + escrowid "pkg.akt.dev/go/node/escrow/id/v1" + etypes "pkg.akt.dev/go/node/escrow/types/v1" ) type EscrowKeeper interface { - GetAccount(ctx sdk.Context, id etypes.AccountID) (etypes.Account, error) - GetPayment(ctx sdk.Context, id etypes.AccountID, pid string) (etypes.FractionalPayment, error) - AccountClose(ctx sdk.Context, id etypes.AccountID) error - PaymentClose(ctx sdk.Context, id etypes.AccountID, pid string) error + GetAccount(ctx sdk.Context, id escrowid.Account) (etypes.Account, error) + GetPayment(ctx sdk.Context, id escrowid.Payment) (etypes.Payment, error) + AccountClose(ctx sdk.Context, id escrowid.Account) error + PaymentClose(ctx sdk.Context, id escrowid.Payment) error } diff --git a/x/market/keeper/grpc_query.go b/x/market/keeper/grpc_query.go index 9080a73a80..4eb06ac8ff 100644 --- a/x/market/keeper/grpc_query.go +++ b/x/market/keeper/grpc_query.go @@ -6,15 +6,15 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/cosmos/cosmos-sdk/store/prefix" + "cosmossdk.io/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" sdkquery "github.com/cosmos/cosmos-sdk/types/query" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" + "pkg.akt.dev/go/node/market/v1" + types "pkg.akt.dev/go/node/market/v1beta5" - "github.com/akash-network/node/util/query" - keys "github.com/akash-network/node/x/market/keeper/keys/v1beta4" + "pkg.akt.dev/node/util/query" + "pkg.akt.dev/node/x/market/keeper/keys" ) // Querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over keeper @@ -67,10 +67,8 @@ func (k Querier) Orders(c context.Context, req *types.QueryOrdersRequest) (*type states = append(states, byte(stateVal)) } else { - // request does not have pagination set. Start from open store - states = append(states, byte(types.OrderOpen)) - states = append(states, byte(types.OrderActive)) - states = append(states, byte(types.OrderClosed)) + // request does not have a pagination set. Start from an open store + states = append(states, []byte{byte(types.OrderOpen), byte(types.OrderActive), byte(types.OrderClosed)}...) } var orders types.Orders @@ -102,7 +100,7 @@ func (k Querier) Orders(c context.Context, req *types.QueryOrdersRequest) (*type count := uint64(0) - pageRes, err = sdkquery.FilteredPaginate(searchStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) { + pageRes, err = sdkquery.FilteredPaginate(searchStore, req.Pagination, func(_ []byte, value []byte, accumulate bool) (bool, error) { var order types.Order err := k.cdc.Unmarshal(value, &order) @@ -140,6 +138,7 @@ func (k Querier) Orders(c context.Context, req *types.QueryOrdersRequest) (*type if len(pageRes.NextKey) > 0 { pageRes.NextKey, err = query.EncodePaginationKey(states[idx:], searchPrefix, pageRes.NextKey, nil) if err != nil { + pageRes.Total = total return &types.QueryOrdersResponse{ Orders: orders, Pagination: pageRes, @@ -204,7 +203,7 @@ func (k Querier) Bids(c context.Context, req *types.QueryBidsRequest) (*types.Qu states = append(states, byte(stateVal)) } else { - // request does not have pagination set. Start from open store + // request does not have a pagination set. Start from an open store states = append(states, byte(types.BidOpen), byte(types.BidActive), byte(types.BidLost), byte(types.BidClosed)) } @@ -241,7 +240,7 @@ func (k Querier) Bids(c context.Context, req *types.QueryBidsRequest) (*types.Qu count := uint64(0) searchStore := prefix.NewStore(ctx.KVStore(k.skey), searchPrefix) - pageRes, err = sdkquery.FilteredPaginate(searchStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) { + pageRes, err = sdkquery.FilteredPaginate(searchStore, req.Pagination, func(_ []byte, value []byte, accumulate bool) (bool, error) { var bid types.Bid err := k.cdc.Unmarshal(value, &bid) @@ -252,7 +251,7 @@ func (k Querier) Bids(c context.Context, req *types.QueryBidsRequest) (*types.Qu // filter bids with provided filters if req.Filters.Accept(bid, state) { if accumulate { - acct, err := k.ekeeper.GetAccount(ctx, types.EscrowAccountForBid(bid.BidID)) + acct, err := k.ekeeper.GetAccount(ctx, bid.ID.ToEscrowAccountID()) if err != nil { return true, err } @@ -284,6 +283,7 @@ func (k Querier) Bids(c context.Context, req *types.QueryBidsRequest) (*types.Qu if pageRes != nil { pageRes.Total = total + if len(pageRes.NextKey) > 0 { unsolicited := make([]byte, 1) unsolicited[0] = 0 @@ -351,16 +351,16 @@ func (k Querier) Leases(c context.Context, req *types.QueryLeasesRequest) (*type } else if req.Filters.State != "" { reverseSearch = (req.Filters.Owner == "") && (req.Filters.Provider != "") - stateVal := types.Lease_State(types.Lease_State_value[req.Filters.State]) + stateVal := v1.Lease_State(v1.Lease_State_value[req.Filters.State]) - if req.Filters.State != "" && stateVal == types.LeaseStateInvalid { + if req.Filters.State != "" && stateVal == v1.LeaseStateInvalid { return nil, status.Error(codes.InvalidArgument, "invalid state value") } states = append(states, byte(stateVal)) } else { - // request does not have pagination set. Start from open store - states = append(states, byte(types.LeaseActive), byte(types.LeaseInsufficientFunds), byte(types.LeaseClosed)) + // request does not have a pagination set. Start from an open store + states = append(states, byte(v1.LeaseActive), byte(v1.LeaseInsufficientFunds), byte(v1.LeaseClosed)) } var leases []types.QueryLeaseResponse @@ -371,8 +371,9 @@ func (k Querier) Leases(c context.Context, req *types.QueryLeasesRequest) (*type var idx int var err error + for idx = range states { - state := types.Lease_State(states[idx]) + state := v1.Lease_State(states[idx]) if idx > 0 { req.Pagination.Key = nil @@ -396,8 +397,8 @@ func (k Querier) Leases(c context.Context, req *types.QueryLeasesRequest) (*type count := uint64(0) - pageRes, err = sdkquery.FilteredPaginate(searchedStore, req.Pagination, func(key []byte, value []byte, accumulate bool) (bool, error) { - var lease types.Lease + pageRes, err = sdkquery.FilteredPaginate(searchedStore, req.Pagination, func(_ []byte, value []byte, accumulate bool) (bool, error) { + var lease v1.Lease err := k.cdc.Unmarshal(value, &lease) if err != nil { @@ -407,9 +408,7 @@ func (k Querier) Leases(c context.Context, req *types.QueryLeasesRequest) (*type // filter leases with provided filters if req.Filters.Accept(lease, state) { if accumulate { - payment, err := k.ekeeper.GetPayment(ctx, - dtypes.EscrowAccountForDeployment(lease.ID().DeploymentID()), - types.EscrowPaymentForLease(lease.ID())) + payment, err := k.ekeeper.GetPayment(ctx, lease.ID.ToEscrowPaymentID()) if err != nil { return true, err } @@ -480,7 +479,7 @@ func (k Querier) Order(c context.Context, req *types.QueryOrderRequest) (*types. order, found := k.GetOrder(ctx, req.ID) if !found { - return nil, types.ErrOrderNotFound + return nil, v1.ErrOrderNotFound } return &types.QueryOrderResponse{Order: order}, nil @@ -504,10 +503,10 @@ func (k Querier) Bid(c context.Context, req *types.QueryBidRequest) (*types.Quer bid, found := k.GetBid(ctx, req.ID) if !found { - return nil, types.ErrBidNotFound + return nil, v1.ErrBidNotFound } - acct, err := k.ekeeper.GetAccount(ctx, types.EscrowAccountForBid(bid.ID())) + acct, err := k.ekeeper.GetAccount(ctx, bid.ID.ToEscrowAccountID()) if err != nil { return nil, err } @@ -536,12 +535,10 @@ func (k Querier) Lease(c context.Context, req *types.QueryLeaseRequest) (*types. lease, found := k.GetLease(ctx, req.ID) if !found { - return nil, types.ErrLeaseNotFound + return nil, v1.ErrLeaseNotFound } - payment, err := k.ekeeper.GetPayment(ctx, - dtypes.EscrowAccountForDeployment(lease.ID().DeploymentID()), - types.EscrowPaymentForLease(lease.ID())) + payment, err := k.ekeeper.GetPayment(ctx, lease.ID.ToEscrowPaymentID()) if err != nil { return nil, err } @@ -551,3 +548,14 @@ func (k Querier) Lease(c context.Context, req *types.QueryLeaseRequest) (*types. EscrowPayment: payment, }, nil } + +func (k Querier) Params(ctx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { + if req == nil { + return nil, status.Errorf(codes.InvalidArgument, "empty request") + } + + sdkCtx := sdk.UnwrapSDKContext(ctx) + params := k.GetParams(sdkCtx) + + return &types.QueryParamsResponse{Params: params}, nil +} diff --git a/x/market/keeper/grpc_query_test.go b/x/market/keeper/grpc_query_test.go index 676f84865e..3b1bfa08a2 100644 --- a/x/market/keeper/grpc_query_test.go +++ b/x/market/keeper/grpc_query_test.go @@ -12,11 +12,12 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkquery "github.com/cosmos/cosmos-sdk/types/query" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" + types "pkg.akt.dev/go/node/market/v1" + "pkg.akt.dev/go/node/market/v1beta5" + "pkg.akt.dev/go/testutil" - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/testutil/state" - "github.com/akash-network/node/x/market/keeper" + "pkg.akt.dev/node/testutil/state" + "pkg.akt.dev/node/x/market/keeper" ) type grpcTestSuite struct { @@ -25,7 +26,7 @@ type grpcTestSuite struct { ctx sdk.Context keeper keeper.IKeeper - queryClient types.QueryClient + queryClient v1beta5.QueryClient } func setupTest(t *testing.T) *grpcTestSuite { @@ -41,8 +42,8 @@ func setupTest(t *testing.T) *grpcTestSuite { querier := suite.keeper.NewQuerier() queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.App().InterfaceRegistry()) - types.RegisterQueryServer(queryHelper, querier) - suite.queryClient = types.NewQueryClient(queryHelper) + v1beta5.RegisterQueryServer(queryHelper, querier) + suite.queryClient = v1beta5.NewQueryClient(queryHelper) return suite } @@ -54,8 +55,8 @@ func TestGRPCQueryOrder(t *testing.T) { order, _ := createOrder(t, suite.ctx, suite.keeper) var ( - req *types.QueryOrderRequest - expOrder types.Order + req *v1beta5.QueryOrderRequest + expOrder v1beta5.Order ) testCases := []struct { @@ -66,21 +67,21 @@ func TestGRPCQueryOrder(t *testing.T) { { "empty request", func() { - req = &types.QueryOrderRequest{} + req = &v1beta5.QueryOrderRequest{} }, false, }, { "invalid request", func() { - req = &types.QueryOrderRequest{ID: types.OrderID{}} + req = &v1beta5.QueryOrderRequest{ID: types.OrderID{}} }, false, }, { "order not found", func() { - req = &types.QueryOrderRequest{ID: types.OrderID{ + req = &v1beta5.QueryOrderRequest{ID: types.OrderID{ Owner: testutil.AccAddress(t).String(), DSeq: 32, GSeq: 43, @@ -92,7 +93,7 @@ func TestGRPCQueryOrder(t *testing.T) { { "success", func() { - req = &types.QueryOrderRequest{ID: order.OrderID} + req = &v1beta5.QueryOrderRequest{ID: order.ID} expOrder = order }, true, @@ -102,7 +103,7 @@ func TestGRPCQueryOrder(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { tc.malleate() - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx res, err := suite.queryClient.Order(ctx, req) @@ -127,7 +128,7 @@ func TestGRPCQueryOrders(t *testing.T) { order2, _ := createOrder(t, suite.ctx, suite.keeper) suite.keeper.OnOrderMatched(suite.ctx, order2) - var req *types.QueryOrdersRequest + var req *v1beta5.QueryOrdersRequest testCases := []struct { msg string @@ -137,17 +138,17 @@ func TestGRPCQueryOrders(t *testing.T) { { "query orders without any filters and pagination", func() { - req = &types.QueryOrdersRequest{} + req = &v1beta5.QueryOrdersRequest{} }, 2, }, { "query orders with filters having non existent data", func() { - req = &types.QueryOrdersRequest{ - Filters: types.OrderFilters{ + req = &v1beta5.QueryOrdersRequest{ + Filters: v1beta5.OrderFilters{ OSeq: 37, - State: types.OrderActive.String(), + State: v1beta5.OrderActive.String(), }} }, 0, @@ -155,14 +156,14 @@ func TestGRPCQueryOrders(t *testing.T) { { "query orders with state filter", func() { - req = &types.QueryOrdersRequest{Filters: types.OrderFilters{State: types.OrderActive.String()}} + req = &v1beta5.QueryOrdersRequest{Filters: v1beta5.OrderFilters{State: v1beta5.OrderActive.String()}} }, 1, }, { "query orders with pagination", func() { - req = &types.QueryOrdersRequest{Pagination: &sdkquery.PageRequest{Limit: 1}} + req = &v1beta5.QueryOrdersRequest{Pagination: &sdkquery.PageRequest{Limit: 1}} }, 1, }, @@ -171,7 +172,7 @@ func TestGRPCQueryOrders(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { tc.malleate() - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx res, err := suite.queryClient.Orders(ctx, req) @@ -184,13 +185,13 @@ func TestGRPCQueryOrders(t *testing.T) { type orderFilterModifier struct { fieldName string - f func(orderID types.OrderID, filter types.OrderFilters) types.OrderFilters + f func(orderID types.OrderID, filter v1beta5.OrderFilters) v1beta5.OrderFilters getField func(orderID types.OrderID) interface{} } type bidFilterModifier struct { fieldName string - f func(bidID types.BidID, filter types.BidFilters) types.BidFilters + f func(bidID types.BidID, filter v1beta5.BidFilters) v1beta5.BidFilters getField func(bidID types.BidID) interface{} } @@ -209,15 +210,15 @@ func TestGRPCQueryOrdersWithFilter(t *testing.T) { orderC, _ := createOrder(t, suite.ctx, suite.keeper) orders := []types.OrderID{ - orderA.GetOrderID(), - orderB.GetOrderID(), - orderC.GetOrderID(), + orderA.ID, + orderB.ID, + orderC.ID, } modifiers := []orderFilterModifier{ { "owner", - func(orderID types.OrderID, filter types.OrderFilters) types.OrderFilters { + func(orderID types.OrderID, filter v1beta5.OrderFilters) v1beta5.OrderFilters { filter.Owner = orderID.GetOwner() return filter }, @@ -227,7 +228,7 @@ func TestGRPCQueryOrdersWithFilter(t *testing.T) { }, { "dseq", - func(orderID types.OrderID, filter types.OrderFilters) types.OrderFilters { + func(orderID types.OrderID, filter v1beta5.OrderFilters) v1beta5.OrderFilters { filter.DSeq = orderID.DSeq return filter }, @@ -237,7 +238,7 @@ func TestGRPCQueryOrdersWithFilter(t *testing.T) { }, { "gseq", - func(orderID types.OrderID, filter types.OrderFilters) types.OrderFilters { + func(orderID types.OrderID, filter v1beta5.OrderFilters) v1beta5.OrderFilters { filter.GSeq = orderID.GSeq return filter }, @@ -247,7 +248,7 @@ func TestGRPCQueryOrdersWithFilter(t *testing.T) { }, { "oseq", - func(orderID types.OrderID, filter types.OrderFilters) types.OrderFilters { + func(orderID types.OrderID, filter v1beta5.OrderFilters) v1beta5.OrderFilters { filter.OSeq = orderID.OSeq return filter }, @@ -257,12 +258,12 @@ func TestGRPCQueryOrdersWithFilter(t *testing.T) { }, } - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx for _, orderID := range orders { for _, m := range modifiers { - req := &types.QueryOrdersRequest{ - Filters: m.f(orderID, types.OrderFilters{}), + req := &v1beta5.QueryOrdersRequest{ + Filters: m.f(orderID, v1beta5.OrderFilters{}), } res, err := suite.queryClient.Orders(ctx, req) @@ -273,7 +274,7 @@ func TestGRPCQueryOrdersWithFilter(t *testing.T) { require.GreaterOrEqual(t, len(res.Orders), 1, "testing %v", m.fieldName) for _, order := range res.Orders { - resultOrderID := order.GetOrderID() + resultOrderID := order.ID require.Equal(t, m.getField(orderID), m.getField(resultOrderID), "testing %v", m.fieldName) } } @@ -297,7 +298,7 @@ func TestGRPCQueryOrdersWithFilter(t *testing.T) { } for _, orderID := range orders { - filter := types.OrderFilters{} + filter := v1beta5.OrderFilters{} msg := strings.Builder{} msg.WriteString("testing filtering on: ") for k, useModifier := range modifiersToUse { @@ -310,7 +311,7 @@ func TestGRPCQueryOrdersWithFilter(t *testing.T) { msg.WriteString(", ") } - req := &types.QueryOrdersRequest{ + req := &v1beta5.QueryOrdersRequest{ Filters: filter, } @@ -322,7 +323,7 @@ func TestGRPCQueryOrdersWithFilter(t *testing.T) { require.GreaterOrEqual(t, len(res.Orders), 1, msg.String()) for _, order := range res.Orders { - resultOrderID := order.GetOrderID() + resultOrderID := order.ID for k, useModifier := range modifiersToUse { if !useModifier { continue @@ -333,7 +334,7 @@ func TestGRPCQueryOrdersWithFilter(t *testing.T) { } } - filter := types.OrderFilters{} + filter := v1beta5.OrderFilters{} msg := strings.Builder{} msg.WriteString("testing filtering on (using non matching ID): ") for k, useModifier := range modifiersToUse { @@ -346,7 +347,7 @@ func TestGRPCQueryOrdersWithFilter(t *testing.T) { msg.WriteString(", ") } - req := &types.QueryOrdersRequest{ + req := &v1beta5.QueryOrdersRequest{ Filters: filter, } @@ -363,8 +364,8 @@ func TestGRPCQueryOrdersWithFilter(t *testing.T) { for _, orderID := range orders { // Query by owner - req := &types.QueryOrdersRequest{ - Filters: types.OrderFilters{ + req := &v1beta5.QueryOrdersRequest{ + Filters: v1beta5.OrderFilters{ Owner: orderID.Owner, }, } @@ -376,11 +377,11 @@ func TestGRPCQueryOrdersWithFilter(t *testing.T) { // Just 1 result require.Len(t, res.Orders, 1) orderResult := res.Orders[0] - require.Equal(t, orderID, orderResult.GetOrderID()) + require.Equal(t, orderID, orderResult.ID) // Query with valid DSeq - req = &types.QueryOrdersRequest{ - Filters: types.OrderFilters{ + req = &v1beta5.QueryOrdersRequest{ + Filters: v1beta5.OrderFilters{ Owner: orderID.Owner, DSeq: orderID.DSeq, }, @@ -393,11 +394,11 @@ func TestGRPCQueryOrdersWithFilter(t *testing.T) { require.NotNil(t, res) require.Len(t, res.Orders, 1) orderResult = res.Orders[0] - require.Equal(t, orderID, orderResult.GetOrderID()) + require.Equal(t, orderID, orderResult.ID) // Query with a bogus DSeq - req = &types.QueryOrdersRequest{ - Filters: types.OrderFilters{ + req = &v1beta5.QueryOrdersRequest{ + Filters: v1beta5.OrderFilters{ Owner: orderID.Owner, DSeq: orderID.DSeq + 1, }, @@ -421,15 +422,15 @@ func TestGRPCQueryBidsWithFilter(t *testing.T) { bidC, _ := createBid(t, suite.TestSuite) bids := []types.BidID{ - bidA.GetBidID(), - bidB.GetBidID(), - bidC.GetBidID(), + bidA.ID, + bidB.ID, + bidC.ID, } modifiers := []bidFilterModifier{ { "owner", - func(bidID types.BidID, filter types.BidFilters) types.BidFilters { + func(bidID types.BidID, filter v1beta5.BidFilters) v1beta5.BidFilters { filter.Owner = bidID.GetOwner() return filter }, @@ -439,7 +440,7 @@ func TestGRPCQueryBidsWithFilter(t *testing.T) { }, { "dseq", - func(bidID types.BidID, filter types.BidFilters) types.BidFilters { + func(bidID types.BidID, filter v1beta5.BidFilters) v1beta5.BidFilters { filter.DSeq = bidID.DSeq return filter }, @@ -449,7 +450,7 @@ func TestGRPCQueryBidsWithFilter(t *testing.T) { }, { "gseq", - func(bidID types.BidID, filter types.BidFilters) types.BidFilters { + func(bidID types.BidID, filter v1beta5.BidFilters) v1beta5.BidFilters { filter.GSeq = bidID.GSeq return filter }, @@ -459,7 +460,7 @@ func TestGRPCQueryBidsWithFilter(t *testing.T) { }, { "oseq", - func(bidID types.BidID, filter types.BidFilters) types.BidFilters { + func(bidID types.BidID, filter v1beta5.BidFilters) v1beta5.BidFilters { filter.OSeq = bidID.OSeq return filter }, @@ -469,7 +470,7 @@ func TestGRPCQueryBidsWithFilter(t *testing.T) { }, { "provider", - func(bidID types.BidID, filter types.BidFilters) types.BidFilters { + func(bidID types.BidID, filter v1beta5.BidFilters) v1beta5.BidFilters { filter.Provider = bidID.Provider return filter }, @@ -479,12 +480,12 @@ func TestGRPCQueryBidsWithFilter(t *testing.T) { }, } - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx for _, bidID := range bids { for _, m := range modifiers { - req := &types.QueryBidsRequest{ - Filters: m.f(bidID, types.BidFilters{}), + req := &v1beta5.QueryBidsRequest{ + Filters: m.f(bidID, v1beta5.BidFilters{}), } res, err := suite.queryClient.Bids(ctx, req) @@ -495,7 +496,7 @@ func TestGRPCQueryBidsWithFilter(t *testing.T) { require.GreaterOrEqual(t, len(res.Bids), 1, "testing %v", m.fieldName) for _, bid := range res.Bids { - resultBidID := bid.GetBid().BidID + resultBidID := bid.GetBid().ID require.Equal(t, m.getField(bidID), m.getField(resultBidID), "testing %v", m.fieldName) } } @@ -520,7 +521,7 @@ func TestGRPCQueryBidsWithFilter(t *testing.T) { } for _, bidID := range bids { - filter := types.BidFilters{} + filter := v1beta5.BidFilters{} msg := strings.Builder{} msg.WriteString("testing filtering on: ") for k, useModifier := range modifiersToUse { @@ -533,7 +534,7 @@ func TestGRPCQueryBidsWithFilter(t *testing.T) { msg.WriteString(", ") } - req := &types.QueryBidsRequest{ + req := &v1beta5.QueryBidsRequest{ Filters: filter, } @@ -545,7 +546,7 @@ func TestGRPCQueryBidsWithFilter(t *testing.T) { require.GreaterOrEqual(t, len(res.Bids), 1, msg.String()) for _, bid := range res.Bids { - resultBidID := bid.GetBid().BidID + resultBidID := bid.GetBid().ID for k, useModifier := range modifiersToUse { if !useModifier { continue @@ -556,7 +557,7 @@ func TestGRPCQueryBidsWithFilter(t *testing.T) { } } - filter := types.BidFilters{} + filter := v1beta5.BidFilters{} msg := strings.Builder{} msg.WriteString("testing filtering on (using non matching ID): ") for k, useModifier := range modifiersToUse { @@ -569,7 +570,7 @@ func TestGRPCQueryBidsWithFilter(t *testing.T) { msg.WriteString(", ") } - req := &types.QueryBidsRequest{ + req := &v1beta5.QueryBidsRequest{ Filters: filter, } @@ -586,8 +587,8 @@ func TestGRPCQueryBidsWithFilter(t *testing.T) { for _, bidID := range bids { // Query by owner - req := &types.QueryBidsRequest{ - Filters: types.BidFilters{ + req := &v1beta5.QueryBidsRequest{ + Filters: v1beta5.BidFilters{ Owner: bidID.Owner, }, } @@ -599,11 +600,11 @@ func TestGRPCQueryBidsWithFilter(t *testing.T) { // Just 1 result require.Len(t, res.Bids, 1) bidResult := res.Bids[0] - require.Equal(t, bidID, bidResult.GetBid().BidID) + require.Equal(t, bidID, bidResult.GetBid().ID) // Query with valid DSeq - req = &types.QueryBidsRequest{ - Filters: types.BidFilters{ + req = &v1beta5.QueryBidsRequest{ + Filters: v1beta5.BidFilters{ Owner: bidID.Owner, DSeq: bidID.DSeq, }, @@ -616,11 +617,11 @@ func TestGRPCQueryBidsWithFilter(t *testing.T) { require.NotNil(t, res) require.Len(t, res.Bids, 1) bidResult = res.Bids[0] - require.Equal(t, bidID, bidResult.GetBid().BidID) + require.Equal(t, bidID, bidResult.GetBid().ID) // Query with a bogus DSeq - req = &types.QueryBidsRequest{ - Filters: types.BidFilters{ + req = &v1beta5.QueryBidsRequest{ + Filters: v1beta5.BidFilters{ Owner: bidID.Owner, DSeq: bidID.DSeq + 1, }, @@ -702,11 +703,11 @@ func TestGRPCQueryLeasesWithFilter(t *testing.T) { }, } - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx for _, leaseID := range leases { for _, m := range modifiers { - req := &types.QueryLeasesRequest{ + req := &v1beta5.QueryLeasesRequest{ Filters: m.f(leaseID, types.LeaseFilters{}), } @@ -718,7 +719,7 @@ func TestGRPCQueryLeasesWithFilter(t *testing.T) { require.GreaterOrEqual(t, len(res.Leases), 1, "testing %v", m.fieldName) for _, lease := range res.Leases { - resultLeaseID := lease.Lease.GetLeaseID() + resultLeaseID := lease.Lease.ID require.Equal(t, m.getField(leaseID), m.getField(resultLeaseID), "testing %v", m.fieldName) } } @@ -756,7 +757,7 @@ func TestGRPCQueryLeasesWithFilter(t *testing.T) { msg.WriteString(", ") } - req := &types.QueryLeasesRequest{ + req := &v1beta5.QueryLeasesRequest{ Filters: filter, } @@ -768,7 +769,7 @@ func TestGRPCQueryLeasesWithFilter(t *testing.T) { require.GreaterOrEqual(t, len(res.Leases), 1, msg.String()) for _, lease := range res.Leases { - resultLeaseID := lease.GetLease().LeaseID + resultLeaseID := lease.GetLease().ID for k, useModifier := range modifiersToUse { if !useModifier { continue @@ -792,7 +793,7 @@ func TestGRPCQueryLeasesWithFilter(t *testing.T) { msg.WriteString(", ") } - req := &types.QueryLeasesRequest{ + req := &v1beta5.QueryLeasesRequest{ Filters: filter, } @@ -809,7 +810,7 @@ func TestGRPCQueryLeasesWithFilter(t *testing.T) { for _, leaseID := range leases { // Query by owner - req := &types.QueryLeasesRequest{ + req := &v1beta5.QueryLeasesRequest{ Filters: types.LeaseFilters{ Owner: leaseID.Owner, }, @@ -822,10 +823,10 @@ func TestGRPCQueryLeasesWithFilter(t *testing.T) { // Just 1 result require.Len(t, res.Leases, 1) leaseResult := res.Leases[0] - require.Equal(t, leaseID, leaseResult.GetLease().LeaseID) + require.Equal(t, leaseID, leaseResult.GetLease().ID) // Query with valid DSeq - req = &types.QueryLeasesRequest{ + req = &v1beta5.QueryLeasesRequest{ Filters: types.LeaseFilters{ Owner: leaseID.Owner, DSeq: leaseID.DSeq, @@ -839,10 +840,10 @@ func TestGRPCQueryLeasesWithFilter(t *testing.T) { require.NotNil(t, res) require.Len(t, res.Leases, 1) leaseResult = res.Leases[0] - require.Equal(t, leaseID, leaseResult.GetLease().LeaseID) + require.Equal(t, leaseID, leaseResult.GetLease().ID) // Query with a bogus DSeq - req = &types.QueryLeasesRequest{ + req = &v1beta5.QueryLeasesRequest{ Filters: types.LeaseFilters{ Owner: leaseID.Owner, DSeq: leaseID.DSeq + 1, @@ -865,8 +866,8 @@ func TestGRPCQueryBid(t *testing.T) { bid, _ := createBid(t, suite.TestSuite) var ( - req *types.QueryBidRequest - expBid types.Bid + req *v1beta5.QueryBidRequest + expBid v1beta5.Bid ) testCases := []struct { @@ -877,21 +878,21 @@ func TestGRPCQueryBid(t *testing.T) { { "empty request", func() { - req = &types.QueryBidRequest{} + req = &v1beta5.QueryBidRequest{} }, false, }, { "invalid request", func() { - req = &types.QueryBidRequest{ID: types.BidID{}} + req = &v1beta5.QueryBidRequest{ID: types.BidID{}} }, false, }, { "bid not found", func() { - req = &types.QueryBidRequest{ID: types.BidID{ + req = &v1beta5.QueryBidRequest{ID: types.BidID{ Owner: testutil.AccAddress(t).String(), DSeq: 32, GSeq: 43, @@ -904,7 +905,7 @@ func TestGRPCQueryBid(t *testing.T) { { "success", func() { - req = &types.QueryBidRequest{ID: bid.BidID} + req = &v1beta5.QueryBidRequest{ID: bid.ID} expBid = bid }, true, @@ -914,7 +915,7 @@ func TestGRPCQueryBid(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { tc.malleate() - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx res, err := suite.queryClient.Bid(ctx, req) @@ -939,7 +940,7 @@ func TestGRPCQueryBids(t *testing.T) { bid2, _ := createBid(t, suite.TestSuite) suite.keeper.OnBidLost(suite.ctx, bid2) - var req *types.QueryBidsRequest + var req *v1beta5.QueryBidsRequest testCases := []struct { msg string @@ -949,17 +950,17 @@ func TestGRPCQueryBids(t *testing.T) { { "query bids without any filters and pagination", func() { - req = &types.QueryBidsRequest{} + req = &v1beta5.QueryBidsRequest{} }, 2, }, { "query bids with filters having non existent data", func() { - req = &types.QueryBidsRequest{ - Filters: types.BidFilters{ + req = &v1beta5.QueryBidsRequest{ + Filters: v1beta5.BidFilters{ OSeq: 37, - State: types.BidLost.String(), + State: v1beta5.BidLost.String(), Provider: testutil.AccAddress(t).String(), }} }, @@ -968,14 +969,14 @@ func TestGRPCQueryBids(t *testing.T) { { "query bids with state filter", func() { - req = &types.QueryBidsRequest{Filters: types.BidFilters{State: types.BidLost.String()}} + req = &v1beta5.QueryBidsRequest{Filters: v1beta5.BidFilters{State: v1beta5.BidLost.String()}} }, 1, }, { "query bids with pagination", func() { - req = &types.QueryBidsRequest{Pagination: &sdkquery.PageRequest{Limit: 1}} + req = &v1beta5.QueryBidsRequest{Pagination: &sdkquery.PageRequest{Limit: 1}} }, 1, }, @@ -984,7 +985,7 @@ func TestGRPCQueryBids(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { tc.malleate() - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx res, err := suite.queryClient.Bids(ctx, req) @@ -1004,7 +1005,7 @@ func TestGRPCQueryLease(t *testing.T) { require.True(t, ok) var ( - req *types.QueryLeaseRequest + req *v1beta5.QueryLeaseRequest expLease types.Lease ) @@ -1016,21 +1017,21 @@ func TestGRPCQueryLease(t *testing.T) { { "empty request", func() { - req = &types.QueryLeaseRequest{} + req = &v1beta5.QueryLeaseRequest{} }, false, }, { "invalid request", func() { - req = &types.QueryLeaseRequest{ID: types.LeaseID{}} + req = &v1beta5.QueryLeaseRequest{ID: types.LeaseID{}} }, false, }, { "lease not found", func() { - req = &types.QueryLeaseRequest{ID: types.LeaseID{ + req = &v1beta5.QueryLeaseRequest{ID: types.LeaseID{ Owner: testutil.AccAddress(t).String(), DSeq: 32, GSeq: 43, @@ -1043,7 +1044,7 @@ func TestGRPCQueryLease(t *testing.T) { { "success", func() { - req = &types.QueryLeaseRequest{ID: lease.LeaseID} + req = &v1beta5.QueryLeaseRequest{ID: lease.ID} expLease = lease }, true, @@ -1053,7 +1054,7 @@ func TestGRPCQueryLease(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { tc.malleate() - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx res, err := suite.queryClient.Lease(ctx, req) @@ -1081,9 +1082,10 @@ func TestGRPCQueryLeases(t *testing.T) { leaseID2 := createLease(t, suite.TestSuite) lease2, ok := suite.keeper.GetLease(suite.ctx, leaseID2) require.True(t, ok) - suite.keeper.OnLeaseClosed(suite.ctx, lease2, types.LeaseClosed) + err := suite.keeper.OnLeaseClosed(suite.ctx, lease2, types.LeaseClosed, types.LeaseClosedReasonUnspecified) + require.NoError(t, err) - var req *types.QueryLeasesRequest + var req *v1beta5.QueryLeasesRequest testCases := []struct { msg string @@ -1093,14 +1095,14 @@ func TestGRPCQueryLeases(t *testing.T) { { "query leases without any filters and pagination", func() { - req = &types.QueryLeasesRequest{} + req = &v1beta5.QueryLeasesRequest{} }, 2, }, { "query leases with filters having non existent data", func() { - req = &types.QueryLeasesRequest{ + req = &v1beta5.QueryLeasesRequest{ Filters: types.LeaseFilters{ OSeq: 37, State: types.LeaseClosed.String(), @@ -1112,14 +1114,14 @@ func TestGRPCQueryLeases(t *testing.T) { { "query leases with state filter", func() { - req = &types.QueryLeasesRequest{Filters: types.LeaseFilters{State: types.LeaseClosed.String()}} + req = &v1beta5.QueryLeasesRequest{Filters: types.LeaseFilters{State: types.LeaseClosed.String()}} }, 1, }, { "query leases with pagination", func() { - req = &types.QueryLeasesRequest{Pagination: &sdkquery.PageRequest{Limit: 1}} + req = &v1beta5.QueryLeasesRequest{Pagination: &sdkquery.PageRequest{Limit: 1}} }, 1, }, @@ -1128,7 +1130,7 @@ func TestGRPCQueryLeases(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { tc.malleate() - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx res, err := suite.queryClient.Leases(ctx, req) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index a53c43a7d5..107f983046 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -3,62 +3,64 @@ package keeper import ( "fmt" + storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" + dtypes "pkg.akt.dev/go/node/deployment/v1" + dtypesBeta "pkg.akt.dev/go/node/deployment/v1beta4" + mv1 "pkg.akt.dev/go/node/market/v1" + types "pkg.akt.dev/go/node/market/v1beta5" - keys "github.com/akash-network/node/x/market/keeper/keys/v1beta4" + "pkg.akt.dev/node/x/market/keeper/keys" ) -// TODO: use interface for all keepers, queriers type IKeeper interface { NewQuerier() Querier Codec() codec.BinaryCodec - StoreKey() sdk.StoreKey - CreateOrder(ctx sdk.Context, gid dtypes.GroupID, spec dtypes.GroupSpec) (types.Order, error) - CreateBid(ctx sdk.Context, oid types.OrderID, provider sdk.AccAddress, price sdk.DecCoin, roffer types.ResourcesOffer) (types.Bid, error) - CreateLease(ctx sdk.Context, bid types.Bid) + StoreKey() storetypes.StoreKey + CreateOrder(ctx sdk.Context, gid dtypes.GroupID, spec dtypesBeta.GroupSpec) (types.Order, error) + CreateBid(ctx sdk.Context, id mv1.BidID, price sdk.DecCoin, roffer types.ResourcesOffer) (types.Bid, error) + CreateLease(ctx sdk.Context, bid types.Bid) error OnOrderMatched(ctx sdk.Context, order types.Order) OnBidMatched(ctx sdk.Context, bid types.Bid) OnBidLost(ctx sdk.Context, bid types.Bid) - OnBidClosed(ctx sdk.Context, bid types.Bid) - OnOrderClosed(ctx sdk.Context, order types.Order) - OnLeaseClosed(ctx sdk.Context, lease types.Lease, state types.Lease_State) - OnGroupClosed(ctx sdk.Context, id dtypes.GroupID) - GetOrder(ctx sdk.Context, id types.OrderID) (types.Order, bool) - GetBid(ctx sdk.Context, id types.BidID) (types.Bid, bool) - GetLease(ctx sdk.Context, id types.LeaseID) (types.Lease, bool) + OnBidClosed(ctx sdk.Context, bid types.Bid) error + OnOrderClosed(ctx sdk.Context, order types.Order) error + OnLeaseClosed(ctx sdk.Context, lease mv1.Lease, state mv1.Lease_State, reason mv1.LeaseClosedReason) error + OnGroupClosed(ctx sdk.Context, id dtypes.GroupID) error + GetOrder(ctx sdk.Context, id mv1.OrderID) (types.Order, bool) + GetBid(ctx sdk.Context, id mv1.BidID) (types.Bid, bool) + GetLease(ctx sdk.Context, id mv1.LeaseID) (mv1.Lease, bool) + LeaseForOrder(ctx sdk.Context, bs types.Bid_State, oid mv1.OrderID) (mv1.Lease, bool) WithOrders(ctx sdk.Context, fn func(types.Order) bool) WithBids(ctx sdk.Context, fn func(types.Bid) bool) - WithLeases(ctx sdk.Context, fn func(types.Lease) bool) - WithBidsForOrder(ctx sdk.Context, id types.OrderID, state types.Bid_State, fn func(types.Bid) bool) - BidCountForOrder(ctx sdk.Context, id types.OrderID) uint32 + WithBidsForOrder(ctx sdk.Context, id mv1.OrderID, state types.Bid_State, fn func(types.Bid) bool) + WithLeases(ctx sdk.Context, fn func(mv1.Lease) bool) + WithOrdersForGroup(ctx sdk.Context, id dtypes.GroupID, state types.Order_State, fn func(types.Order) bool) + BidCountForOrder(ctx sdk.Context, id mv1.OrderID) uint32 GetParams(ctx sdk.Context) (params types.Params) - SetParams(ctx sdk.Context, params types.Params) + SetParams(ctx sdk.Context, params types.Params) error + GetAuthority() string } // Keeper of the market store type Keeper struct { cdc codec.BinaryCodec - skey sdk.StoreKey - pspace paramtypes.Subspace + skey storetypes.StoreKey ekeeper EscrowKeeper + // The address capable of executing a MsgUpdateParams message. + // This should be the x/gov module account. + authority string } // NewKeeper creates and returns an instance for Market keeper -func NewKeeper(cdc codec.BinaryCodec, skey sdk.StoreKey, pspace paramtypes.Subspace, ekeeper EscrowKeeper) IKeeper { - if !pspace.HasKeyTable() { - pspace = pspace.WithKeyTable(types.ParamKeyTable()) - } - +func NewKeeper(cdc codec.BinaryCodec, skey storetypes.StoreKey, ekeeper EscrowKeeper, authority string) IKeeper { return Keeper{ - skey: skey, - cdc: cdc, - pspace: pspace, - ekeeper: ekeeper, + skey: skey, + cdc: cdc, + ekeeper: ekeeper, + authority: authority, } } @@ -72,28 +74,58 @@ func (k Keeper) Codec() codec.BinaryCodec { } // StoreKey returns store key -func (k Keeper) StoreKey() sdk.StoreKey { +func (k Keeper) StoreKey() storetypes.StoreKey { return k.skey } +// GetAuthority returns the x/mint module's authority. +func (k Keeper) GetAuthority() string { + return k.authority +} + +// SetParams sets the x/market module parameters. +func (k Keeper) SetParams(ctx sdk.Context, p types.Params) error { + if err := p.Validate(); err != nil { + return err + } + + store := ctx.KVStore(k.skey) + bz := k.cdc.MustMarshal(&p) + store.Set(mv1.ParamsPrefix(), bz) + + return nil +} + +// GetParams returns the current x/market module parameters. +func (k Keeper) GetParams(ctx sdk.Context) (p types.Params) { + store := ctx.KVStore(k.skey) + bz := store.Get(mv1.ParamsPrefix()) + if bz == nil { + return p + } + + k.cdc.MustUnmarshal(bz, &p) + return p +} + // CreateOrder creates a new order with given group id and specifications. It returns created order -func (k Keeper) CreateOrder(ctx sdk.Context, gid dtypes.GroupID, spec dtypes.GroupSpec) (types.Order, error) { +func (k Keeper) CreateOrder(ctx sdk.Context, gid dtypes.GroupID, spec dtypesBeta.GroupSpec) (types.Order, error) { store := ctx.KVStore(k.skey) oseq := uint32(1) var err error - k.WithOrdersForGroup(ctx, gid, types.OrderActive, func(order types.Order) bool { - err = types.ErrOrderActive + k.WithOrdersForGroup(ctx, gid, types.OrderActive, func(_ types.Order) bool { + err = mv1.ErrOrderActive return true }) - k.WithOrdersForGroup(ctx, gid, types.OrderOpen, func(order types.Order) bool { - err = types.ErrOrderActive + k.WithOrdersForGroup(ctx, gid, types.OrderOpen, func(_ types.Order) bool { + err = mv1.ErrOrderActive return true }) - k.WithOrdersForGroup(ctx, gid, types.OrderClosed, func(order types.Order) bool { + k.WithOrdersForGroup(ctx, gid, types.OrderClosed, func(_ types.Order) bool { oseq++ return false }) @@ -102,44 +134,44 @@ func (k Keeper) CreateOrder(ctx sdk.Context, gid dtypes.GroupID, spec dtypes.Gro return types.Order{}, fmt.Errorf("%w: create order: active order exists", err) } - orderID := types.MakeOrderID(gid, oseq) + orderID := mv1.MakeOrderID(gid, oseq) if res := k.findOrder(ctx, orderID); len(res) > 0 { - return types.Order{}, types.ErrOrderExists + return types.Order{}, mv1.ErrOrderExists } order := types.Order{ - OrderID: types.MakeOrderID(gid, oseq), + ID: mv1.MakeOrderID(gid, oseq), Spec: spec, State: types.OrderOpen, CreatedAt: ctx.BlockHeight(), } - key := keys.MustOrderKey(keys.OrderStateOpenPrefix, order.ID()) - + key := keys.MustOrderKey(keys.OrderStateOpenPrefix, order.ID) store.Set(key, k.cdc.MustMarshal(&order)) - ctx.Logger().Info("created order", "order", order.ID()) + ctx.Logger().Info("created order", "order", order.ID) - ctx.EventManager().EmitEvent( - types.NewEventOrderCreated(order.ID()). - ToSDKEvent(), + err = ctx.EventManager().EmitTypedEvent( + &mv1.EventOrderCreated{ID: order.ID}, ) + if err != nil { + return types.Order{}, err + } + return order, nil } // CreateBid creates a bid for a order with given orderID, price for bid and provider -func (k Keeper) CreateBid(ctx sdk.Context, oid types.OrderID, provider sdk.AccAddress, price sdk.DecCoin, roffer types.ResourcesOffer) (types.Bid, error) { +func (k Keeper) CreateBid(ctx sdk.Context, id mv1.BidID, price sdk.DecCoin, roffer types.ResourcesOffer) (types.Bid, error) { store := ctx.KVStore(k.skey) - bidID := types.MakeBidID(oid, provider) - - if key := k.findBid(ctx, bidID); len(key) > 0 { - return types.Bid{}, types.ErrBidExists + if key := k.findBid(ctx, id); len(key) > 0 { + return types.Bid{}, mv1.ErrBidExists } bid := types.Bid{ - BidID: bidID, + ID: id, State: types.BidOpen, Price: price, CreatedAt: ctx.BlockHeight(), @@ -148,8 +180,8 @@ func (k Keeper) CreateBid(ctx sdk.Context, oid types.OrderID, provider sdk.AccAd data := k.cdc.MustMarshal(&bid) - key := keys.MustBidKey(keys.BidStateToPrefix(bid.State), bidID) - revKey := keys.MustBidStateRevereKey(bid.State, bidID) + key := keys.MustBidKey(keys.BidStateToPrefix(bid.State), id) + revKey := keys.MustBidStateRevereKey(bid.State, id) store.Set(key, data) @@ -157,22 +189,27 @@ func (k Keeper) CreateBid(ctx sdk.Context, oid types.OrderID, provider sdk.AccAd store.Set(revKey, data) } - ctx.EventManager().EmitEvent( - types.NewEventBidCreated(bid.ID(), price). - ToSDKEvent(), + err := ctx.EventManager().EmitTypedEvent( + &mv1.EventBidCreated{ + ID: bid.ID, + Price: price, + }, ) + if err != nil { + return types.Bid{}, err + } return bid, nil } // CreateLease creates lease for bid with given bidID. // Should only be called by the EndBlock handler or unit tests. -func (k Keeper) CreateLease(ctx sdk.Context, bid types.Bid) { +func (k Keeper) CreateLease(ctx sdk.Context, bid types.Bid) error { store := ctx.KVStore(k.skey) - lease := types.Lease{ - LeaseID: types.LeaseID(bid.ID()), - State: types.LeaseActive, + lease := mv1.Lease{ + ID: mv1.LeaseID(bid.ID), + State: mv1.LeaseActive, Price: bid.Price, CreatedAt: ctx.BlockHeight(), } @@ -180,19 +217,25 @@ func (k Keeper) CreateLease(ctx sdk.Context, bid types.Bid) { data := k.cdc.MustMarshal(&lease) // create (active) lease in store - key := keys.MustLeaseKey(keys.LeaseStateToPrefix(lease.State), lease.ID()) - revKey := keys.MustLeaseStateReverseKey(lease.State, lease.LeaseID) + key := keys.MustLeaseKey(keys.LeaseStateToPrefix(lease.State), lease.ID) + revKey := keys.MustLeaseStateReverseKey(lease.State, lease.ID) store.Set(key, data) if len(revKey) > 0 { store.Set(revKey, data) } - ctx.Logger().Info("created lease", "lease", lease.ID()) - ctx.EventManager().EmitEvent( - types.NewEventLeaseCreated(lease.ID(), lease.Price). - ToSDKEvent(), + err := ctx.EventManager().EmitTypedEvent( + &mv1.EventLeaseCreated{ + ID: lease.ID, + Price: lease.Price, + }, ) + if err != nil { + return err + } + + return nil } // OnOrderMatched updates order state to matched @@ -217,106 +260,148 @@ func (k Keeper) OnBidLost(ctx sdk.Context, bid types.Bid) { } // OnBidClosed updates bid state to closed -func (k Keeper) OnBidClosed(ctx sdk.Context, bid types.Bid) { +func (k Keeper) OnBidClosed(ctx sdk.Context, bid types.Bid) error { switch bid.State { case types.BidClosed, types.BidLost: - return + return nil } currState := bid.State bid.State = types.BidClosed k.updateBid(ctx, bid, currState) - _ = k.ekeeper.AccountClose(ctx, types.EscrowAccountForBid(bid.ID())) + _ = k.ekeeper.AccountClose(ctx, bid.ID.ToEscrowAccountID()) - ctx.EventManager().EmitEvent( - types.NewEventBidClosed(bid.ID(), bid.Price). - ToSDKEvent(), + err := ctx.EventManager().EmitTypedEvent( + &mv1.EventBidClosed{ + ID: bid.ID, + }, ) + if err != nil { + return err + } + + return nil } // OnOrderClosed updates order state to closed -func (k Keeper) OnOrderClosed(ctx sdk.Context, order types.Order) { +func (k Keeper) OnOrderClosed(ctx sdk.Context, order types.Order) error { if order.State == types.OrderClosed { - return + return nil } currState := order.State order.State = types.OrderClosed + k.updateOrder(ctx, order, currState) - ctx.EventManager().EmitEvent( - types.NewEventOrderClosed(order.ID()). - ToSDKEvent(), + err := ctx.EventManager().EmitTypedEvent( + &mv1.EventOrderClosed{ + ID: order.ID, + }, ) + if err != nil { + return err + } + + return nil } // OnLeaseClosed updates lease state to closed -func (k Keeper) OnLeaseClosed(ctx sdk.Context, lease types.Lease, state types.Lease_State) { +func (k Keeper) OnLeaseClosed(ctx sdk.Context, lease mv1.Lease, state mv1.Lease_State, reason mv1.LeaseClosedReason) error { switch lease.State { - case types.LeaseClosed, types.LeaseInsufficientFunds: - return + case mv1.LeaseClosed, mv1.LeaseInsufficientFunds: + return nil } currState := lease.State + lease.State = state lease.ClosedOn = ctx.BlockHeight() store := ctx.KVStore(k.skey) - key := keys.MustLeaseKey(keys.LeaseStateToPrefix(currState), lease.ID()) - revKey := keys.MustLeaseStateReverseKey(currState, lease.LeaseID) + key := keys.MustLeaseKey(keys.LeaseStateToPrefix(currState), lease.ID) + revKey := keys.MustLeaseStateReverseKey(currState, lease.ID) store.Delete(key) if len(revKey) > 0 { store.Delete(revKey) } - key = keys.MustLeaseKey(keys.LeaseStateToPrefix(lease.State), lease.ID()) + key = keys.MustLeaseKey(keys.LeaseStateToPrefix(lease.State), lease.ID) store.Set(key, k.cdc.MustMarshal(&lease)) - ctx.EventManager().EmitEvent( - types.NewEventLeaseClosed(lease.ID(), lease.Price). - ToSDKEvent(), + err := ctx.EventManager().EmitTypedEvent( + &mv1.EventLeaseClosed{ + ID: lease.ID, + Reason: reason, + }, ) + if err != nil { + return err + } + + return nil } // OnGroupClosed updates state of all orders, bids and leases in group to closed -func (k Keeper) OnGroupClosed(ctx sdk.Context, id dtypes.GroupID) { - processClose := func(ctx sdk.Context, bid types.Bid) { - k.OnBidClosed(ctx, bid) - if lease, ok := k.GetLease(ctx, bid.ID().LeaseID()); ok { - k.OnLeaseClosed(ctx, lease, types.LeaseClosed) - - if err := k.ekeeper.PaymentClose(ctx, - dtypes.EscrowAccountForDeployment(id.DeploymentID()), - types.EscrowPaymentForLease(lease.ID())); err != nil { +func (k Keeper) OnGroupClosed(ctx sdk.Context, id dtypes.GroupID) error { + processClose := func(ctx sdk.Context, bid types.Bid) error { + err := k.OnBidClosed(ctx, bid) + if err != nil { + return err + } + + if lease, ok := k.GetLease(ctx, bid.ID.LeaseID()); ok { + // OnGroupClosed is callable by x/deployment only so only reason is owner + err = k.OnLeaseClosed(ctx, lease, mv1.LeaseClosed, mv1.LeaseClosedReasonOwner) + if err := k.ekeeper.PaymentClose(ctx, lease.ID.ToEscrowPaymentID()); err != nil { ctx.Logger().With("err", err).Info("error closing payment") } - + if err != nil { + return err + } } + + return nil } + var err error k.WithOrdersForGroup(ctx, id, types.OrderActive, func(order types.Order) bool { - k.OnOrderClosed(ctx, order) + err = k.OnOrderClosed(ctx, order) + if err != nil { + return true + } - k.WithBidsForOrder(ctx, order.ID(), types.BidOpen, func(bid types.Bid) bool { - processClose(ctx, bid) - return false + k.WithBidsForOrder(ctx, order.ID, types.BidOpen, func(bid types.Bid) bool { + err = processClose(ctx, bid) + return err != nil }) - k.WithBidsForOrder(ctx, order.ID(), types.BidActive, func(bid types.Bid) bool { - processClose(ctx, bid) - return false + if err != nil { + return true + } + + k.WithBidsForOrder(ctx, order.ID, types.BidActive, func(bid types.Bid) bool { + err = processClose(ctx, bid) + return err != nil }) - return false + return err != nil }) + + if err != nil { + return err + } + + return nil } -func (k Keeper) findOrder(ctx sdk.Context, id types.OrderID) []byte { +func (k Keeper) findOrder(ctx sdk.Context, id mv1.OrderID) []byte { store := ctx.KVStore(k.skey) + aKey := keys.MustOrderKey(keys.OrderStateActivePrefix, id) oKey := keys.MustOrderKey(keys.OrderStateOpenPrefix, id) cKey := keys.MustOrderKey(keys.OrderStateClosedPrefix, id) @@ -336,7 +421,7 @@ func (k Keeper) findOrder(ctx sdk.Context, id types.OrderID) []byte { } // GetOrder returns order with given orderID from market store -func (k Keeper) GetOrder(ctx sdk.Context, id types.OrderID) (types.Order, bool) { +func (k Keeper) GetOrder(ctx sdk.Context, id mv1.OrderID) (types.Order, bool) { key := k.findOrder(ctx, id) if len(key) == 0 { @@ -353,7 +438,7 @@ func (k Keeper) GetOrder(ctx sdk.Context, id types.OrderID) (types.Order, bool) return val, true } -func (k Keeper) findBid(ctx sdk.Context, id types.BidID) []byte { +func (k Keeper) findBid(ctx sdk.Context, id mv1.BidID) []byte { store := ctx.KVStore(k.skey) aKey := keys.MustBidKey(keys.BidStateActivePrefix, id) @@ -378,7 +463,7 @@ func (k Keeper) findBid(ctx sdk.Context, id types.BidID) []byte { } // GetBid returns bid with given bidID from market store -func (k Keeper) GetBid(ctx sdk.Context, id types.BidID) (types.Bid, bool) { +func (k Keeper) GetBid(ctx sdk.Context, id mv1.BidID) (types.Bid, bool) { store := ctx.KVStore(k.skey) key := k.findBid(ctx, id) @@ -395,7 +480,7 @@ func (k Keeper) GetBid(ctx sdk.Context, id types.BidID) (types.Bid, bool) { return val, true } -func (k Keeper) findLease(ctx sdk.Context, id types.LeaseID) []byte { +func (k Keeper) findLease(ctx sdk.Context, id mv1.LeaseID) []byte { store := ctx.KVStore(k.skey) aKey := keys.MustLeaseKey(keys.LeaseStateActivePrefix, id) @@ -417,26 +502,39 @@ func (k Keeper) findLease(ctx sdk.Context, id types.LeaseID) []byte { } // GetLease returns lease with given leaseID from market store -func (k Keeper) GetLease(ctx sdk.Context, id types.LeaseID) (types.Lease, bool) { +func (k Keeper) GetLease(ctx sdk.Context, id mv1.LeaseID) (mv1.Lease, bool) { store := ctx.KVStore(k.skey) - key := k.findLease(ctx, id) if len(key) == 0 { - return types.Lease{}, false + return mv1.Lease{}, false } buf := store.Get(key) - var val types.Lease + var val mv1.Lease k.cdc.MustUnmarshal(buf, &val) + return val, true } +// LeaseForOrder returns lease for order with given ID and lease found status +func (k Keeper) LeaseForOrder(ctx sdk.Context, bs types.Bid_State, oid mv1.OrderID) (mv1.Lease, bool) { + var value mv1.Lease + var found bool + + k.WithBidsForOrder(ctx, oid, bs, func(item types.Bid) bool { + value, found = k.GetLease(ctx, mv1.LeaseID(item.ID)) + return true + }) + + return value, found +} + // WithOrders iterates all orders in market func (k Keeper) WithOrders(ctx sdk.Context, fn func(types.Order) bool) { store := ctx.KVStore(k.skey) - iter := sdk.KVStorePrefixIterator(store, keys.OrderPrefix) + iter := storetypes.KVStorePrefixIterator(store, keys.OrderPrefix) defer func() { _ = iter.Close() }() @@ -453,7 +551,11 @@ func (k Keeper) WithOrders(ctx sdk.Context, fn func(types.Order) bool) { // WithBids iterates all bids in market func (k Keeper) WithBids(ctx sdk.Context, fn func(types.Bid) bool) { store := ctx.KVStore(k.skey) - iter := sdk.KVStorePrefixIterator(store, keys.BidPrefix) + iter := storetypes.KVStorePrefixIterator(store, keys.BidPrefix) + + defer func() { + _ = iter.Close() + }() defer func() { _ = iter.Close() @@ -469,16 +571,16 @@ func (k Keeper) WithBids(ctx sdk.Context, fn func(types.Bid) bool) { } // WithLeases iterates all leases in market -func (k Keeper) WithLeases(ctx sdk.Context, fn func(types.Lease) bool) { +func (k Keeper) WithLeases(ctx sdk.Context, fn func(mv1.Lease) bool) { store := ctx.KVStore(k.skey) - iter := sdk.KVStorePrefixIterator(store, keys.LeasePrefix) + iter := storetypes.KVStorePrefixIterator(store, keys.LeasePrefix) defer func() { _ = iter.Close() }() for ; iter.Valid(); iter.Next() { - var val types.Lease + var val mv1.Lease k.cdc.MustUnmarshal(iter.Value(), &val) if stop := fn(val); stop { break @@ -489,7 +591,7 @@ func (k Keeper) WithLeases(ctx sdk.Context, fn func(types.Lease) bool) { // WithOrdersForGroup iterates all orders of a group in market with given GroupID func (k Keeper) WithOrdersForGroup(ctx sdk.Context, id dtypes.GroupID, state types.Order_State, fn func(types.Order) bool) { store := ctx.KVStore(k.skey) - iter := sdk.KVStorePrefixIterator(store, keys.OrdersForGroupPrefix(keys.OrderStateToPrefix(state), id)) + iter := storetypes.KVStorePrefixIterator(store, keys.OrdersForGroupPrefix(keys.OrderStateToPrefix(state), id)) defer func() { _ = iter.Close() @@ -504,10 +606,10 @@ func (k Keeper) WithOrdersForGroup(ctx sdk.Context, id dtypes.GroupID, state typ } } -// WithBidsForOrder iterates all bids of a order in market with given OrderID -func (k Keeper) WithBidsForOrder(ctx sdk.Context, id types.OrderID, state types.Bid_State, fn func(types.Bid) bool) { +// WithBidsForOrder iterates all bids of an order in market with given OrderID +func (k Keeper) WithBidsForOrder(ctx sdk.Context, id mv1.OrderID, state types.Bid_State, fn func(types.Bid) bool) { store := ctx.KVStore(k.skey) - iter := sdk.KVStorePrefixIterator(store, keys.BidsForOrderPrefix(keys.BidStateToPrefix(state), id)) + iter := storetypes.KVStorePrefixIterator(store, keys.BidsForOrderPrefix(keys.BidStateToPrefix(state), id)) defer func() { _ = iter.Close() @@ -522,11 +624,11 @@ func (k Keeper) WithBidsForOrder(ctx sdk.Context, id types.OrderID, state types. } } -func (k Keeper) BidCountForOrder(ctx sdk.Context, id types.OrderID) uint32 { +func (k Keeper) BidCountForOrder(ctx sdk.Context, id mv1.OrderID) uint32 { store := ctx.KVStore(k.skey) - oiter := sdk.KVStorePrefixIterator(store, keys.BidsForOrderPrefix(keys.BidStateOpenPrefix, id)) - aiter := sdk.KVStorePrefixIterator(store, keys.BidsForOrderPrefix(keys.BidStateActivePrefix, id)) - citer := sdk.KVStorePrefixIterator(store, keys.BidsForOrderPrefix(keys.BidStateClosedPrefix, id)) + oiter := storetypes.KVStorePrefixIterator(store, keys.BidsForOrderPrefix(keys.BidStateOpenPrefix, id)) + aiter := storetypes.KVStorePrefixIterator(store, keys.BidsForOrderPrefix(keys.BidStateActivePrefix, id)) + citer := storetypes.KVStorePrefixIterator(store, keys.BidsForOrderPrefix(keys.BidStateClosedPrefix, id)) defer func() { _ = oiter.Close() @@ -550,17 +652,6 @@ func (k Keeper) BidCountForOrder(ctx sdk.Context, id types.OrderID) uint32 { return count } -// GetParams returns the total set of deployment parameters. -func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { - k.pspace.GetParamSet(ctx, ¶ms) - return params -} - -// SetParams sets the deployment parameters to the paramspace. -func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { - k.pspace.SetParamSet(ctx, ¶ms) -} - func (k Keeper) updateOrder(ctx sdk.Context, order types.Order, currState types.Order_State) { store := ctx.KVStore(k.skey) @@ -571,7 +662,7 @@ func (k Keeper) updateOrder(ctx sdk.Context, order types.Order, currState types. panic(fmt.Sprintf("unexpected current state of the order: %d", currState)) } - key := keys.MustOrderKey(keys.OrderStateToPrefix(currState), order.ID()) + key := keys.MustOrderKey(keys.OrderStateToPrefix(currState), order.ID) store.Delete(key) switch order.State { @@ -583,7 +674,7 @@ func (k Keeper) updateOrder(ctx sdk.Context, order types.Order, currState types. data := k.cdc.MustMarshal(&order) - key = keys.MustOrderKey(keys.OrderStateToPrefix(order.State), order.ID()) + key = keys.MustOrderKey(keys.OrderStateToPrefix(order.State), order.ID) store.Set(key, data) } @@ -597,8 +688,8 @@ func (k Keeper) updateBid(ctx sdk.Context, bid types.Bid, currState types.Bid_St panic(fmt.Sprintf("unexpected current state of the bid: %d", currState)) } - key := keys.MustBidKey(keys.BidStateToPrefix(currState), bid.ID()) - revKey := keys.MustBidStateRevereKey(currState, bid.ID()) + key := keys.MustBidKey(keys.BidStateToPrefix(currState), bid.ID) + revKey := keys.MustBidStateRevereKey(currState, bid.ID) store.Delete(key) if revKey != nil { store.Delete(revKey) @@ -614,8 +705,8 @@ func (k Keeper) updateBid(ctx sdk.Context, bid types.Bid, currState types.Bid_St data := k.cdc.MustMarshal(&bid) - key = keys.MustBidKey(keys.BidStateToPrefix(bid.State), bid.ID()) - revKey = keys.MustBidStateRevereKey(bid.State, bid.ID()) + key = keys.MustBidKey(keys.BidStateToPrefix(bid.State), bid.ID) + revKey = keys.MustBidStateRevereKey(bid.State, bid.ID) store.Set(key, data) if len(revKey) > 0 { diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index e46ccb4dd6..09ae00e538 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -8,12 +8,14 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/testutil/state" - "github.com/akash-network/node/x/market/keeper" + dtypes "pkg.akt.dev/go/node/deployment/v1beta4" + "pkg.akt.dev/go/node/market/v1" + types "pkg.akt.dev/go/node/market/v1beta5" + deposit "pkg.akt.dev/go/node/types/deposit/v1" + "pkg.akt.dev/go/testutil" + + "pkg.akt.dev/node/testutil/state" + "pkg.akt.dev/node/x/market/keeper" ) func Test_CreateOrder(t *testing.T) { @@ -21,14 +23,14 @@ func Test_CreateOrder(t *testing.T) { order, gspec := createOrder(t, ctx, keeper) // assert one active for group - _, err := keeper.CreateOrder(ctx, order.ID().GroupID(), gspec) + _, err := keeper.CreateOrder(ctx, order.ID.GroupID(), gspec) require.Error(t, err) } func Test_GetOrder(t *testing.T) { ctx, keeper, _ := setupKeeper(t) order, _ := createOrder(t, ctx, keeper) - result, ok := keeper.GetOrder(ctx, order.ID()) + result, ok := keeper.GetOrder(ctx, order.ID) require.True(t, ok) require.Equal(t, order, result) @@ -45,7 +47,7 @@ func Test_WithOrders(t *testing.T) { count := 0 keeper.WithOrders(ctx, func(result types.Order) bool { - if assert.Equal(t, order.ID(), result.ID()) { + if assert.Equal(t, order.ID, result.ID) { count++ } return false @@ -54,23 +56,23 @@ func Test_WithOrders(t *testing.T) { assert.Equal(t, 1, count) } -// func Test_WithOrdersForGroup(t *testing.T) { -// ctx, keeper, _ := setupKeeper(t) -// order, _ := createOrder(t, ctx, keeper) -// -// // create extra orders -// createOrder(t, ctx, keeper) -// -// count := 0 -// keeper.WithOrdersForGroup(ctx, order.ID().GroupID(), func(result types.Order) bool { -// if assert.Equal(t, order.ID(), result.ID()) { -// count++ -// } -// return false -// }) -// -// assert.Equal(t, 1, count) -// } +func Test_WithOrdersForGroup(t *testing.T) { + ctx, keeper, _ := setupKeeper(t) + order, _ := createOrder(t, ctx, keeper) + + // create extra orders + createOrder(t, ctx, keeper) + + count := 0 + keeper.WithOrdersForGroup(ctx, order.ID.GroupID(), types.OrderOpen, func(result types.Order) bool { + if assert.Equal(t, order.ID, result.ID) { + count++ + } + return false + }) + + assert.Equal(t, 1, count) +} func Test_CreateBid(t *testing.T) { _, _, suite := setupKeeper(t) @@ -83,7 +85,7 @@ func Test_GetBid(t *testing.T) { keeper := suite.MarketKeeper() - result, ok := keeper.GetBid(ctx, bid.ID()) + result, ok := keeper.GetBid(ctx, bid.ID) require.True(t, ok) assert.Equal(t, bid, result) @@ -99,7 +101,7 @@ func Test_WithBids(t *testing.T) { bid, _ := createBid(t, suite) count := 0 keeper.WithBids(ctx, func(result types.Bid) bool { - if assert.Equal(t, bid.ID(), result.ID()) { + if assert.Equal(t, bid.ID, result.ID) { count++ } return false @@ -116,8 +118,9 @@ func Test_WithBidsForOrder(t *testing.T) { createBid(t, suite) count := 0 - keeper.WithBidsForOrder(ctx, bid.ID().OrderID(), types.BidOpen, func(result types.Bid) bool { - if assert.Equal(t, bid.ID(), result.ID()) { + + keeper.WithBidsForOrder(ctx, bid.ID.OrderID(), types.BidOpen, func(result types.Bid) bool { + if assert.Equal(t, bid.ID, result.ID) { count++ } return false @@ -131,7 +134,7 @@ func Test_GetLease(t *testing.T) { lease, ok := keeper.GetLease(ctx, id) assert.True(t, ok) - assert.Equal(t, id, lease.ID()) + assert.Equal(t, id, lease.ID) // non-existent { @@ -145,8 +148,8 @@ func Test_WithLeases(t *testing.T) { id := createLease(t, suite) count := 0 - keeper.WithLeases(ctx, func(result types.Lease) bool { - if assert.Equal(t, id, result.ID()) { + keeper.WithLeases(ctx, func(result v1.Lease) bool { + if assert.Equal(t, id, result.ID) { count++ } return false @@ -154,26 +157,26 @@ func Test_WithLeases(t *testing.T) { assert.Equal(t, 1, count) } -// func Test_LeaseForOrder(t *testing.T) { -// ctx, keeper, suite := setupKeeper(t) -// id := createLease(t, suite) -// -// // extra leases -// createLease(t, suite) -// createLease(t, suite) -// -// result, ok := keeper.LeaseForOrder(ctx, id.OrderID()) -// assert.True(t, ok) -// -// assert.Equal(t, id, result.ID()) -// -// // no match -// { -// bid, _ := createBid(t, suite) -// _, ok := keeper.LeaseForOrder(ctx, bid.ID().OrderID()) -// assert.False(t, ok) -// } -// } +func Test_LeaseForOrder(t *testing.T) { + ctx, keeper, suite := setupKeeper(t) + id := createLease(t, suite) + + // extra leases + createLease(t, suite) + createLease(t, suite) + + result, ok := keeper.LeaseForOrder(ctx, types.BidActive, id.OrderID()) + assert.True(t, ok) + + assert.Equal(t, id, result.ID) + + // no match + { + bid, _ := createBid(t, suite) + _, ok := keeper.LeaseForOrder(ctx, types.BidActive, bid.ID.OrderID()) + assert.False(t, ok) + } +} func Test_OnOrderMatched(t *testing.T) { ctx, keeper, suite := setupKeeper(t) @@ -198,7 +201,7 @@ func Test_OnBidLost(t *testing.T) { bid, _ := createBid(t, suite) keeper.OnBidLost(ctx, bid) - result, ok := keeper.GetBid(ctx, bid.ID()) + result, ok := keeper.GetBid(ctx, bid.ID) require.True(t, ok) assert.Equal(t, types.BidLost, result.State) } @@ -207,9 +210,10 @@ func Test_OnOrderClosed(t *testing.T) { ctx, keeper, _ := setupKeeper(t) order, _ := createOrder(t, ctx, keeper) - keeper.OnOrderClosed(ctx, order) + err := keeper.OnOrderClosed(ctx, order) + require.NoError(t, err) - result, ok := keeper.GetOrder(ctx, order.ID()) + result, ok := keeper.GetOrder(ctx, order.ID) require.True(t, ok) assert.Equal(t, types.OrderClosed, result.State) } @@ -226,12 +230,13 @@ func Test_OnLeaseClosed(t *testing.T) { const testBlockHeight = 1337 suite.SetBlockHeight(testBlockHeight) - require.Equal(t, types.LeaseActive, lease.State) - keeper.OnLeaseClosed(suite.Context(), lease, types.LeaseClosed) + require.Equal(t, v1.LeaseActive, lease.State) + err := keeper.OnLeaseClosed(suite.Context(), lease, v1.LeaseClosed, v1.LeaseClosedReasonUnspecified) + require.NoError(t, err) result, ok := keeper.GetLease(suite.Context(), id) require.True(t, ok) - assert.Equal(t, types.LeaseClosed, result.State) + assert.Equal(t, v1.LeaseClosed, result.State) assert.Equal(t, int64(testBlockHeight), result.ClosedOn) } @@ -241,11 +246,12 @@ func Test_OnGroupClosed(t *testing.T) { const testBlockHeight = 133 suite.SetBlockHeight(testBlockHeight) - keeper.OnGroupClosed(suite.Context(), id.BidID().GroupID()) + err := keeper.OnGroupClosed(suite.Context(), id.BidID().GroupID()) + require.NoError(t, err) lease, ok := keeper.GetLease(suite.Context(), id) require.True(t, ok) - assert.Equal(t, types.LeaseClosed, lease.State) + assert.Equal(t, v1.LeaseClosed, lease.State) assert.Equal(t, int64(testBlockHeight), lease.ClosedOn) bid, ok := keeper.GetBid(suite.Context(), id.BidID()) @@ -257,43 +263,54 @@ func Test_OnGroupClosed(t *testing.T) { assert.Equal(t, types.OrderClosed, order.State) } -func createLease(t testing.TB, suite *state.TestSuite) types.LeaseID { +func createLease(t testing.TB, suite *state.TestSuite) v1.LeaseID { t.Helper() ctx := suite.Context() bid, order := createBid(t, suite) keeper := suite.MarketKeeper() - keeper.CreateLease(ctx, bid) + + err := keeper.CreateLease(ctx, bid) + require.NoError(t, err) + keeper.OnBidMatched(ctx, bid) keeper.OnOrderMatched(ctx, order) - owner, err := sdk.AccAddressFromBech32(bid.ID().Owner) + owner, err := sdk.AccAddressFromBech32(bid.ID.Owner) require.NoError(t, err) defaultDeposit, err := dtypes.DefaultParams().MinDepositFor("uakt") require.NoError(t, err) + msg := &dtypes.MsgCreateDeployment{ + ID: order.ID.GroupID().DeploymentID(), + Deposit: deposit.Deposit{ + Amount: defaultDeposit, + Sources: deposit.Sources{deposit.SourceBalance}, + }} + + deposits, err := suite.EscrowKeeper().AuthorizeDeposits(ctx, msg) + require.NoError(t, err) + err = suite.EscrowKeeper().AccountCreate( ctx, - dtypes.EscrowAccountForDeployment(bid.ID().DeploymentID()), + bid.ID.DeploymentID().ToEscrowAccountID(), owner, - owner, - defaultDeposit, + deposits, ) require.NoError(t, err) - provider, err := sdk.AccAddressFromBech32(bid.ID().Provider) + provider, err := sdk.AccAddressFromBech32(bid.ID.Provider) require.NoError(t, err) err = suite.EscrowKeeper().PaymentCreate( ctx, - dtypes.EscrowAccountForDeployment(bid.ID().DeploymentID()), - types.EscrowPaymentForLease(bid.ID().LeaseID()), + bid.ID.LeaseID().ToEscrowPaymentID(), provider, bid.Price, ) require.NoError(t, err) - return bid.ID().LeaseID() + return bid.ID.LeaseID() } func createBid(t testing.TB, suite *state.TestSuite) (types.Bid, types.Order) { @@ -304,18 +321,29 @@ func createBid(t testing.TB, suite *state.TestSuite) (types.Bid, types.Order) { price := testutil.AkashDecCoinRandom(t) roffer := types.ResourceOfferFromRU(gspec.Resources) - bid, err := suite.MarketKeeper().CreateBid(ctx, order.ID(), provider, price, roffer) + bidID := v1.MakeBidID(order.ID, provider) + + bid, err := suite.MarketKeeper().CreateBid(ctx, bidID, price, roffer) require.NoError(t, err) - assert.Equal(t, order.ID(), bid.ID().OrderID()) + assert.Equal(t, order.ID, bid.ID.OrderID()) assert.Equal(t, price, bid.Price) - assert.Equal(t, provider.String(), bid.ID().Provider) + assert.Equal(t, provider.String(), bid.ID.Provider) + + msg := &types.MsgCreateBid{ + ID: bidID, + Deposit: deposit.Deposit{ + Amount: types.DefaultBidMinDeposit, + Sources: deposit.Sources{deposit.SourceBalance}, + }} + + deposits, err := suite.EscrowKeeper().AuthorizeDeposits(ctx, msg) + require.NoError(t, err) err = suite.EscrowKeeper().AccountCreate( ctx, - types.EscrowAccountForBid(bid.ID()), - provider, + bid.ID.ToEscrowAccountID(), provider, - types.DefaultBidMinDeposit, + deposits, ) require.NoError(t, err) @@ -326,11 +354,11 @@ func createOrder(t testing.TB, ctx sdk.Context, keeper keeper.IKeeper) (types.Or t.Helper() group := testutil.DeploymentGroup(t, testutil.DeploymentID(t), 0) - order, err := keeper.CreateOrder(ctx, group.ID(), group.GroupSpec) + order, err := keeper.CreateOrder(ctx, group.ID, group.GroupSpec) require.NoError(t, err) - require.Equal(t, group.ID(), order.ID().GroupID()) - require.Equal(t, uint32(1), order.ID().OSeq) + require.Equal(t, group.ID, order.ID.GroupID()) + require.Equal(t, uint32(1), order.ID.OSeq) require.Equal(t, types.OrderOpen, order.State) return order, group.GroupSpec } diff --git a/x/market/keeper/keys/v1beta4/key.go b/x/market/keeper/keys/key.go similarity index 84% rename from x/market/keeper/keys/v1beta4/key.go rename to x/market/keeper/keys/key.go index 93769f27d1..038a0387da 100644 --- a/x/market/keeper/keys/v1beta4/key.go +++ b/x/market/keeper/keys/key.go @@ -1,4 +1,4 @@ -package v1beta4 +package keys import ( "bytes" @@ -6,10 +6,12 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" + mv1beta4 "pkg.akt.dev/go/node/market/v1beta4" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - "github.com/akash-network/akash-api/go/sdkutil" + dtypes "pkg.akt.dev/go/node/deployment/v1" + types "pkg.akt.dev/go/node/market/v1" + mv1beta "pkg.akt.dev/go/node/market/v1beta5" + "pkg.akt.dev/go/sdkutil" ) const ( @@ -116,6 +118,10 @@ func BidKey(statePrefix []byte, id types.BidID) ([]byte, error) { buf.Write(lenPrefixedProvider) + if err := binary.Write(buf, binary.BigEndian, id.BSeq); err != nil { + return nil, err + } + return buf.Bytes(), nil } @@ -153,6 +159,10 @@ func BidReverseKey(statePrefix []byte, id types.BidID) ([]byte, error) { buf.Write(statePrefix) buf.Write(lenPrefixedProvider) + if err := binary.Write(buf, binary.BigEndian, id.BSeq); err != nil { + return nil, err + } + if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { return nil, err } @@ -176,8 +186,8 @@ func MustBidReverseKey(statePrefix []byte, id types.BidID) []byte { return key } -func BidStateReverseKey(state types.Bid_State, id types.BidID) ([]byte, error) { - if state != types.BidActive && state != types.BidOpen { +func BidStateReverseKey(state mv1beta.Bid_State, id types.BidID) ([]byte, error) { + if state != mv1beta.BidActive && state != mv1beta.BidOpen { return nil, nil } @@ -190,7 +200,7 @@ func BidStateReverseKey(state types.Bid_State, id types.BidID) ([]byte, error) { return key, nil } -func MustBidStateRevereKey(state types.Bid_State, id types.BidID) []byte { +func MustBidStateRevereKey(state mv1beta.Bid_State, id types.BidID) []byte { key, err := BidStateReverseKey(state, id) if err != nil { panic(err) @@ -236,6 +246,10 @@ func LeaseKey(statePrefix []byte, id types.LeaseID) ([]byte, error) { buf.Write(lenPrefixedProvider) + if err := binary.Write(buf, binary.BigEndian, id.BSeq); err != nil { + return nil, err + } + return buf.Bytes(), nil } @@ -271,6 +285,9 @@ func LeaseReverseKey(statePrefix []byte, id types.LeaseID) ([]byte, error) { buf := bytes.NewBuffer(LeasePrefixReverse) buf.Write(statePrefix) buf.Write(lenPrefixedProvider) + if err := binary.Write(buf, binary.BigEndian, id.BSeq); err != nil { + return nil, err + } if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { return nil, err @@ -349,32 +366,32 @@ func BidsForOrderPrefix(statePrefix []byte, id types.OrderID) []byte { return buf.Bytes() } -func OrderStateToPrefix(state types.Order_State) []byte { +func OrderStateToPrefix(state mv1beta.Order_State) []byte { var res []byte switch state { - case types.OrderOpen: + case mv1beta.OrderOpen: res = OrderStateOpenPrefix - case types.OrderActive: + case mv1beta.OrderActive: res = OrderStateActivePrefix - case types.OrderClosed: + case mv1beta.OrderClosed: res = OrderStateClosedPrefix } return res } -func BidStateToPrefix(state types.Bid_State) []byte { +func BidStateToPrefix(state mv1beta.Bid_State) []byte { var res []byte switch state { - case types.BidOpen: + case mv1beta.BidOpen: res = BidStateOpenPrefix - case types.BidActive: + case mv1beta.BidActive: res = BidStateActivePrefix - case types.BidLost: + case mv1beta.BidLost: res = BidStateLostPrefix - case types.BidClosed: + case mv1beta.BidClosed: res = BidStateClosedPrefix } @@ -396,7 +413,7 @@ func LeaseStateToPrefix(state types.Lease_State) []byte { return res } -func filterToPrefix(prefix []byte, owner string, dseq uint64, gseq, oseq uint32, provider string) ([]byte, error) { +func filterToPrefix(prefix []byte, owner string, dseq uint64, gseq, oseq uint32, provider string, bseq uint32) ([]byte, error) { buf := bytes.NewBuffer(prefix) if len(owner) == 0 { @@ -436,11 +453,18 @@ func filterToPrefix(prefix []byte, owner string, dseq uint64, gseq, oseq uint32, return nil, err } + if bseq == 0 { + return buf.Bytes(), nil + } + if err := binary.Write(buf, binary.BigEndian, bseq); err != nil { + return nil, err + } + return buf.Bytes(), nil } // nolint: unused -func reverseFilterToPrefix(prefix []byte, provider string, dseq uint64, gseq, oseq uint32, owner string) ([]byte, error) { +func reverseFilterToPrefix(prefix []byte, provider string, bseq uint32, dseq uint64, gseq, oseq uint32, owner string) ([]byte, error) { buf := bytes.NewBuffer(prefix) if len(provider) == 0 { @@ -451,6 +475,13 @@ func reverseFilterToPrefix(prefix []byte, provider string, dseq uint64, gseq, os return nil, err } + if bseq == 0 { + return buf.Bytes(), nil + } + if err := binary.Write(buf, binary.BigEndian, bseq); err != nil { + return nil, err + } + if dseq == 0 { return buf.Bytes(), nil } @@ -483,14 +514,14 @@ func reverseFilterToPrefix(prefix []byte, provider string, dseq uint64, gseq, os return buf.Bytes(), nil } -func OrderPrefixFromFilter(f types.OrderFilters) ([]byte, error) { +func OrderPrefixFromFilter(f mv1beta.OrderFilters) ([]byte, error) { var idx []byte switch f.State { - case types.OrderOpen.String(): + case mv1beta.OrderOpen.String(): idx = OrderStateOpenPrefix - case types.OrderActive.String(): + case mv1beta.OrderActive.String(): idx = OrderStateActivePrefix - case types.OrderClosed.String(): + case mv1beta.OrderClosed.String(): idx = OrderStateClosedPrefix } @@ -498,7 +529,7 @@ func OrderPrefixFromFilter(f types.OrderFilters) ([]byte, error) { prefix = append(prefix, OrderPrefix...) prefix = append(prefix, idx...) - return filterToPrefix(prefix, f.Owner, f.DSeq, f.GSeq, f.OSeq, "") + return filterToPrefix(prefix, f.Owner, f.DSeq, f.GSeq, f.OSeq, "", 0) } func buildLeasePrefix(prefix []byte, state string) []byte { @@ -522,13 +553,13 @@ func buildLeasePrefix(prefix []byte, state string) []byte { func buildBidPrefix(prefix []byte, state string) []byte { var idx []byte switch state { - case types.BidActive.String(): + case mv1beta.BidActive.String(): idx = BidStateActivePrefix - case types.BidOpen.String(): + case mv1beta.BidOpen.String(): idx = BidStateOpenPrefix - case types.BidLost.String(): + case mv1beta.BidLost.String(): idx = BidStateLostPrefix - case types.BidClosed.String(): + case mv1beta.BidClosed.String(): idx = BidStateClosedPrefix } @@ -539,27 +570,27 @@ func buildBidPrefix(prefix []byte, state string) []byte { return res } -func BidPrefixFromFilter(f types.BidFilters) ([]byte, error) { - return filterToPrefix(buildBidPrefix(BidPrefix, f.State), f.Owner, f.DSeq, f.GSeq, f.OSeq, f.Provider) +func BidPrefixFromFilter(f mv1beta.BidFilters) ([]byte, error) { + return filterToPrefix(buildBidPrefix(BidPrefix, f.State), f.Owner, f.DSeq, f.GSeq, f.OSeq, f.Provider, f.BSeq) } -func BidReversePrefixFromFilter(f types.BidFilters) ([]byte, error) { - prefix, err := filterToPrefix(buildBidPrefix(BidPrefixReverse, f.State), f.Provider, f.DSeq, f.GSeq, f.OSeq, f.Owner) +func BidReversePrefixFromFilter(f mv1beta.BidFilters) ([]byte, error) { + prefix, err := reverseFilterToPrefix(buildBidPrefix(BidPrefixReverse, f.State), f.Provider, f.BSeq, f.DSeq, f.GSeq, f.OSeq, f.Owner) return prefix, err } func LeasePrefixFromFilter(f types.LeaseFilters) ([]byte, error) { - prefix, err := filterToPrefix(buildLeasePrefix(LeasePrefix, f.State), f.Owner, f.DSeq, f.GSeq, f.OSeq, f.Provider) + prefix, err := filterToPrefix(buildLeasePrefix(LeasePrefix, f.State), f.Owner, f.DSeq, f.GSeq, f.OSeq, f.Provider, f.BSeq) return prefix, err } func LeaseReversePrefixFromFilter(f types.LeaseFilters) ([]byte, error) { - prefix, err := filterToPrefix(buildLeasePrefix(LeasePrefixReverse, f.State), f.Provider, f.DSeq, f.GSeq, f.OSeq, f.Owner) + prefix, err := reverseFilterToPrefix(buildLeasePrefix(LeasePrefixReverse, f.State), f.Provider, f.BSeq, f.DSeq, f.GSeq, f.OSeq, f.Owner) return prefix, err } func OrderKeyLegacy(id types.OrderID) []byte { - buf := bytes.NewBuffer(types.OrderPrefix()) + buf := bytes.NewBuffer(mv1beta4.OrderPrefix()) buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { panic(err) @@ -574,7 +605,7 @@ func OrderKeyLegacy(id types.OrderID) []byte { } func BidKeyLegacy(id types.BidID) []byte { - buf := bytes.NewBuffer(types.BidPrefix()) + buf := bytes.NewBuffer(mv1beta4.BidPrefix()) buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { panic(err) @@ -590,7 +621,7 @@ func BidKeyLegacy(id types.BidID) []byte { } func LeaseKeyLegacy(id types.LeaseID) []byte { - buf := bytes.NewBuffer(types.LeasePrefix()) + buf := bytes.NewBuffer(mv1beta4.LeasePrefix()) buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { panic(err) @@ -606,7 +637,7 @@ func LeaseKeyLegacy(id types.LeaseID) []byte { } func SecondaryLeaseKeyByProviderLegacy(id types.LeaseID) []byte { - buf := bytes.NewBuffer(types.SecondaryLeasePrefix()) + buf := bytes.NewBuffer(mv1beta4.SecondaryLeasePrefix()) buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Provider))) buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { @@ -628,7 +659,7 @@ func SecondaryKeysForLeaseLegacy(id types.LeaseID) [][]byte { } func OrdersForGroupPrefixLegacy(id dtypes.GroupID) []byte { - buf := bytes.NewBuffer(types.OrderPrefix()) + buf := bytes.NewBuffer(mv1beta4.OrderPrefix()) buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { panic(err) @@ -640,7 +671,7 @@ func OrdersForGroupPrefixLegacy(id dtypes.GroupID) []byte { } func BidsForOrderPrefixLegacy(id types.OrderID) []byte { - buf := bytes.NewBuffer(types.BidPrefix()) + buf := bytes.NewBuffer(mv1beta4.BidPrefix()) buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { panic(err) diff --git a/x/market/keeper/keys/v1beta1/key.go b/x/market/keeper/keys/v1beta1/key.go deleted file mode 100644 index e76fdbab41..0000000000 --- a/x/market/keeper/keys/v1beta1/key.go +++ /dev/null @@ -1,92 +0,0 @@ -package v1beta1 - -import ( - "bytes" - "encoding/binary" - - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta1" - types "github.com/akash-network/akash-api/go/node/market/v1beta1" -) - -var ( - orderPrefix = []byte{0x01, 0x00} - bidPrefix = []byte{0x02, 0x00} - leasePrefix = []byte{0x03, 0x00} // nolint: unused -) - -// nolint: unused -func orderKey(id types.OrderID) []byte { - buf := bytes.NewBuffer(orderPrefix) - buf.Write([]byte(id.Owner)) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.OSeq); err != nil { - panic(err) - } - return buf.Bytes() -} - -// nolint: unused -func bidKey(id types.BidID) []byte { - buf := bytes.NewBuffer(bidPrefix) - buf.Write([]byte(id.Owner)) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.OSeq); err != nil { - panic(err) - } - buf.Write([]byte(id.Provider)) - return buf.Bytes() -} - -// nolint: unused -func leaseKey(id types.LeaseID) []byte { - buf := bytes.NewBuffer(leasePrefix) - buf.Write([]byte(id.Owner)) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.OSeq); err != nil { - panic(err) - } - buf.Write([]byte(id.Provider)) - return buf.Bytes() -} - -func OrdersForGroupPrefix(id dtypes.GroupID) []byte { - buf := bytes.NewBuffer(orderPrefix) - buf.Write([]byte(id.Owner)) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - return buf.Bytes() -} - -func BidsForOrderPrefix(id types.OrderID) []byte { - buf := bytes.NewBuffer(bidPrefix) - buf.Write([]byte(id.Owner)) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.OSeq); err != nil { - panic(err) - } - return buf.Bytes() -} diff --git a/x/market/keeper/keys/v1beta2/key.go b/x/market/keeper/keys/v1beta2/key.go deleted file mode 100644 index 991206c6e5..0000000000 --- a/x/market/keeper/keys/v1beta2/key.go +++ /dev/null @@ -1,164 +0,0 @@ -package v1beta2 - -import ( - "bytes" - "encoding/binary" - - "github.com/cosmos/cosmos-sdk/types/address" - - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta2" - types "github.com/akash-network/akash-api/go/node/market/v1beta2" - "github.com/akash-network/akash-api/go/sdkutil" -) - -func filterToPrefix(prefix []byte, owner string, dseq uint64, gseq, oseq uint32, provider string) ([]byte, error) { - buf := bytes.NewBuffer(prefix) - - if len(owner) == 0 { - return buf.Bytes(), nil - } - - if _, err := buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(owner))); err != nil { - return nil, err - } - - if dseq == 0 { - return buf.Bytes(), nil - } - if err := binary.Write(buf, binary.BigEndian, dseq); err != nil { - return nil, err - } - - if gseq == 0 { - return buf.Bytes(), nil - } - if err := binary.Write(buf, binary.BigEndian, gseq); err != nil { - return nil, err - } - - if oseq == 0 { - return buf.Bytes(), nil - } - if err := binary.Write(buf, binary.BigEndian, oseq); err != nil { - return nil, err - } - - if len(provider) == 0 { - return buf.Bytes(), nil - } - - if _, err := buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(provider))); err != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -func OrderPrefixFromFilter(f types.OrderFilters) ([]byte, error) { - return filterToPrefix(types.OrderPrefix(), f.Owner, f.DSeq, f.GSeq, f.OSeq, "") -} - -func LeasePrefixFromFilter(f types.LeaseFilters) ([]byte, bool, error) { - prefix, err := filterToPrefix(types.LeasePrefix(), f.Owner, f.DSeq, f.GSeq, f.OSeq, f.Provider) - return prefix, false, err -} - -func BidPrefixFromFilter(f types.BidFilters) ([]byte, error) { - return filterToPrefix(types.BidPrefix(), f.Owner, f.DSeq, f.GSeq, f.OSeq, f.Provider) -} - -func OrderKey(id types.OrderID) []byte { - buf := bytes.NewBuffer(types.OrderPrefix()) - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.OSeq); err != nil { - panic(err) - } - return buf.Bytes() -} - -func BidKey(id types.BidID) []byte { - buf := bytes.NewBuffer(types.BidPrefix()) - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.OSeq); err != nil { - panic(err) - } - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Provider))) - return buf.Bytes() -} - -func LeaseKey(id types.LeaseID) []byte { - buf := bytes.NewBuffer(types.LeasePrefix()) - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.OSeq); err != nil { - panic(err) - } - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Provider))) - return buf.Bytes() -} - -func secondaryLeaseKeyByProvider(id types.LeaseID) []byte { - buf := bytes.NewBuffer(types.SecondaryLeasePrefix()) - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Provider))) - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.OSeq); err != nil { - panic(err) - } - return buf.Bytes() -} - -func SecondaryKeysForLease(id types.LeaseID) [][]byte { - return [][]byte{ - secondaryLeaseKeyByProvider(id), - } -} - -func OrdersForGroupPrefix(id dtypes.GroupID) []byte { - buf := bytes.NewBuffer(types.OrderPrefix()) - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - return buf.Bytes() -} - -func BidsForOrderPrefix(id types.OrderID) []byte { - buf := bytes.NewBuffer(types.BidPrefix()) - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.OSeq); err != nil { - panic(err) - } - return buf.Bytes() -} diff --git a/x/market/keeper/keys/v1beta2/key_test.go b/x/market/keeper/keys/v1beta2/key_test.go deleted file mode 100644 index 82636a734f..0000000000 --- a/x/market/keeper/keys/v1beta2/key_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package v1beta2_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - types "github.com/akash-network/akash-api/go/node/market/v1beta2" - - _ "github.com/akash-network/node/testutil" - keys "github.com/akash-network/node/x/market/keeper/keys/v1beta2" -) - -func TestKeysAndSecondaryKeysFilter(t *testing.T) { - filter := types.LeaseFilters{ - Owner: "akash104fq56d9attl4m709h7mgx9lwqklnh05fhy5nu", - DSeq: 1, - GSeq: 2, - OSeq: 3, - Provider: "akash1vlaa09ytnl0hvu04wgs0d6zw5n6anjc3allk49", - State: types.LeaseClosed.String(), - } - - prefix, isSecondary, err := keys.LeasePrefixFromFilter(filter) - require.NoError(t, err) - require.False(t, isSecondary) - require.Equal(t, types.LeasePrefix(), prefix[0:2]) - - filter.Owner = "" - prefix, isSecondary, err = keys.LeasePrefixFromFilter(filter) - require.NoError(t, err) - require.False(t, isSecondary) - require.Equal(t, types.LeasePrefix(), prefix[0:2]) -} diff --git a/x/market/keeper/keys/v1beta3/key.go b/x/market/keeper/keys/v1beta3/key.go deleted file mode 100644 index 78ace686be..0000000000 --- a/x/market/keeper/keys/v1beta3/key.go +++ /dev/null @@ -1,164 +0,0 @@ -package v1beta3 - -import ( - "bytes" - "encoding/binary" - - "github.com/cosmos/cosmos-sdk/types/address" - - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/market/v1beta3" - "github.com/akash-network/akash-api/go/sdkutil" -) - -func filterToPrefix(prefix []byte, owner string, dseq uint64, gseq, oseq uint32, provider string) ([]byte, error) { - buf := bytes.NewBuffer(prefix) - - if len(owner) == 0 { - return buf.Bytes(), nil - } - - if _, err := buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(owner))); err != nil { - return nil, err - } - - if dseq == 0 { - return buf.Bytes(), nil - } - if err := binary.Write(buf, binary.BigEndian, dseq); err != nil { - return nil, err - } - - if gseq == 0 { - return buf.Bytes(), nil - } - if err := binary.Write(buf, binary.BigEndian, gseq); err != nil { - return nil, err - } - - if oseq == 0 { - return buf.Bytes(), nil - } - if err := binary.Write(buf, binary.BigEndian, oseq); err != nil { - return nil, err - } - - if len(provider) == 0 { - return buf.Bytes(), nil - } - - if _, err := buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(provider))); err != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -func OrderPrefixFromFilter(f types.OrderFilters) ([]byte, error) { - return filterToPrefix(types.OrderPrefix(), f.Owner, f.DSeq, f.GSeq, f.OSeq, "") -} - -func LeasePrefixFromFilter(f types.LeaseFilters) ([]byte, bool, error) { - prefix, err := filterToPrefix(types.LeasePrefix(), f.Owner, f.DSeq, f.GSeq, f.OSeq, f.Provider) - return prefix, false, err -} - -func BidPrefixFromFilter(f types.BidFilters) ([]byte, error) { - return filterToPrefix(types.BidPrefix(), f.Owner, f.DSeq, f.GSeq, f.OSeq, f.Provider) -} - -func OrderKey(id types.OrderID) []byte { - buf := bytes.NewBuffer(types.OrderPrefix()) - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.OSeq); err != nil { - panic(err) - } - return buf.Bytes() -} - -func BidKey(id types.BidID) []byte { - buf := bytes.NewBuffer(types.BidPrefix()) - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.OSeq); err != nil { - panic(err) - } - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Provider))) - return buf.Bytes() -} - -func LeaseKey(id types.LeaseID) []byte { - buf := bytes.NewBuffer(types.LeasePrefix()) - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.OSeq); err != nil { - panic(err) - } - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Provider))) - return buf.Bytes() -} - -func secondaryLeaseKeyByProvider(id types.LeaseID) []byte { - buf := bytes.NewBuffer(types.SecondaryLeasePrefix()) - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Provider))) - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.OSeq); err != nil { - panic(err) - } - return buf.Bytes() -} - -func SecondaryKeysForLease(id types.LeaseID) [][]byte { - return [][]byte{ - secondaryLeaseKeyByProvider(id), - } -} - -func OrdersForGroupPrefix(id dtypes.GroupID) []byte { - buf := bytes.NewBuffer(types.OrderPrefix()) - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - return buf.Bytes() -} - -func BidsForOrderPrefix(id types.OrderID) []byte { - buf := bytes.NewBuffer(types.BidPrefix()) - buf.Write(address.MustLengthPrefix(sdkutil.MustAccAddressFromBech32(id.Owner))) - if err := binary.Write(buf, binary.BigEndian, id.DSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.GSeq); err != nil { - panic(err) - } - if err := binary.Write(buf, binary.BigEndian, id.OSeq); err != nil { - panic(err) - } - return buf.Bytes() -} diff --git a/x/market/keeper/keys/v1beta3/key_test.go b/x/market/keeper/keys/v1beta3/key_test.go deleted file mode 100644 index ecac8320ec..0000000000 --- a/x/market/keeper/keys/v1beta3/key_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package v1beta3_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - types "github.com/akash-network/akash-api/go/node/market/v1beta3" - - _ "github.com/akash-network/node/testutil" - keys "github.com/akash-network/node/x/market/keeper/keys/v1beta3" -) - -func TestKeysAndSecondaryKeysFilter(t *testing.T) { - filter := types.LeaseFilters{ - Owner: "akash104fq56d9attl4m709h7mgx9lwqklnh05fhy5nu", - DSeq: 1, - GSeq: 2, - OSeq: 3, - Provider: "akash1vlaa09ytnl0hvu04wgs0d6zw5n6anjc3allk49", - State: types.LeaseClosed.String(), - } - - prefix, isSecondary, err := keys.LeasePrefixFromFilter(filter) - require.NoError(t, err) - require.False(t, isSecondary) - require.Equal(t, types.LeasePrefix(), prefix[0:2]) - - filter.Owner = "" - prefix, isSecondary, err = keys.LeasePrefixFromFilter(filter) - require.NoError(t, err) - require.False(t, isSecondary) - require.Equal(t, types.LeasePrefix(), prefix[0:2]) -} diff --git a/x/market/keeper/keys/v1beta4/key_test.go b/x/market/keeper/keys/v1beta4/key_test.go deleted file mode 100644 index 4fb4b25b98..0000000000 --- a/x/market/keeper/keys/v1beta4/key_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package v1beta4_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - _ "github.com/akash-network/node/testutil" - - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - - keys "github.com/akash-network/node/x/market/keeper/keys/v1beta4" -) - -func TestKeysAndSecondaryKeysFilter(t *testing.T) { - filter := types.LeaseFilters{ - Owner: "akash104fq56d9attl4m709h7mgx9lwqklnh05fhy5nu", - DSeq: 1, - GSeq: 2, - OSeq: 3, - Provider: "akash1vlaa09ytnl0hvu04wgs0d6zw5n6anjc3allk49", - State: types.LeaseClosed.String(), - } - - prefix, err := keys.LeasePrefixFromFilter(filter) - require.NoError(t, err) - // require.False(t, isSecondary) - require.Equal(t, keys.LeasePrefix, prefix[0:2]) - - filter.Owner = "" - prefix, err = keys.LeasePrefixFromFilter(filter) - require.NoError(t, err) - // require.False(t, isSecondary) - require.Equal(t, keys.LeasePrefix, prefix[0:2]) -} diff --git a/x/market/module.go b/x/market/module.go index 8b7813fcfd..cad5c0f872 100644 --- a/x/market/module.go +++ b/x/market/module.go @@ -4,41 +4,41 @@ import ( "context" "encoding/json" "fmt" - "math/rand" - "github.com/gorilla/mux" + "cosmossdk.io/core/appmodule" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" - - abci "github.com/tendermint/tendermint/abci/types" + v1 "pkg.akt.dev/go/node/market/v1" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - simtypes "github.com/cosmos/cosmos-sdk/types/simulation" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + types "pkg.akt.dev/go/node/market/v1beta5" - v1beta1types "github.com/akash-network/akash-api/go/node/market/v1beta1" - v1beta2types "github.com/akash-network/akash-api/go/node/market/v1beta2" - v1beta3types "github.com/akash-network/akash-api/go/node/market/v1beta3" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - - akeeper "github.com/akash-network/node/x/audit/keeper" - ekeeper "github.com/akash-network/node/x/escrow/keeper" - "github.com/akash-network/node/x/market/client/cli" - "github.com/akash-network/node/x/market/client/rest" - "github.com/akash-network/node/x/market/handler" - "github.com/akash-network/node/x/market/keeper" - "github.com/akash-network/node/x/market/simulation" + akeeper "pkg.akt.dev/node/x/audit/keeper" + ekeeper "pkg.akt.dev/node/x/escrow/keeper" + "pkg.akt.dev/node/x/market/handler" + "pkg.akt.dev/node/x/market/keeper" + "pkg.akt.dev/node/x/market/simulation" ) +// type check to ensure the interface is properly implemented var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} - _ module.AppModuleSimulation = AppModuleSimulation{} + _ module.AppModuleBasic = AppModuleBasic{} + _ module.HasGenesisBasics = AppModuleBasic{} + + _ appmodule.AppModule = AppModule{} + _ module.HasConsensusVersion = AppModule{} + _ module.HasGenesis = AppModule{} + _ module.HasServices = AppModule{} + + _ module.AppModuleSimulation = AppModule{} ) // AppModuleBasic defines the basic application module used by the market module. @@ -46,22 +46,25 @@ type AppModuleBasic struct { cdc codec.Codec } +// AppModule implements an application module for the market module. +type AppModule struct { + AppModuleBasic + keepers handler.Keepers +} + // Name returns market module's name func (AppModuleBasic) Name() string { - return types.ModuleName + return v1.ModuleName } // RegisterLegacyAminoCodec registers the market module's types for the given codec. func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { - types.RegisterLegacyAminoCodec(cdc) + types.RegisterLegacyAminoCodec(cdc) // nolint staticcheck } // RegisterInterfaces registers the module's interface types func (b AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) { types.RegisterInterfaces(registry) - v1beta3types.RegisterInterfaces(registry) - v1beta2types.RegisterInterfaces(registry) - v1beta1types.RegisterInterfaces(registry) } // DefaultGenesis returns default genesis state as raw bytes for the market @@ -75,16 +78,11 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingCo var data types.GenesisState err := cdc.UnmarshalJSON(bz, &data) if err != nil { - return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + return fmt.Errorf("failed to unmarshal %s genesis state: %w", v1.ModuleName, err) } return ValidateGenesis(&data) } -// RegisterRESTRoutes registers rest routes for this module -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { - rest.RegisterRoutes(clientCtx, rtr, StoreKey) -} - // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the market module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) @@ -95,12 +93,12 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *r // GetQueryCmd returns the root query command of this module func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.GetQueryCmd() + panic("akash modules do not export cli commands via cosmos interface") } // GetTxCmd returns the root tx command of this module func (AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.GetTxCmd(StoreKey) + panic("akash modules do not export cli commands via cosmos interface") } // GetQueryClient returns a new query client for this module @@ -108,12 +106,6 @@ func (AppModuleBasic) GetQueryClient(clientCtx client.Context) types.QueryClient return types.NewQueryClient(clientCtx) } -// AppModule implements an application module for the market module. -type AppModule struct { - AppModuleBasic - keepers handler.Keepers -} - // NewAppModule creates a new AppModule object func NewAppModule( cdc codec.Codec, @@ -122,16 +114,20 @@ func NewAppModule( akeeper akeeper.Keeper, dkeeper handler.DeploymentKeeper, pkeeper handler.ProviderKeeper, + acckeeper govtypes.AccountKeeper, + authzkeeper authzkeeper.Keeper, bkeeper bankkeeper.Keeper, ) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{cdc: cdc}, keepers: handler.Keepers{ + Account: acckeeper, Escrow: ekeeper, Audit: akeeper, Market: keeper, Deployment: dkeeper, Provider: pkeeper, + Authz: authzkeeper, Bank: bkeeper, }, } @@ -139,26 +135,14 @@ func NewAppModule( // Name returns the market module name func (AppModule) Name() string { - return types.ModuleName + return v1.ModuleName } -// RegisterInvariants registers module invariants -func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} - -// Route returns the message routing key for the market module. -func (am AppModule) Route() sdk.Route { - return sdk.NewRoute(types.RouterKey, handler.NewHandler(am.keepers)) -} +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (am AppModule) IsOnePerModuleType() {} -// QuerierRoute returns the market module's querier route name. -func (am AppModule) QuerierRoute() string { - return "" -} - -// LegacyQuerierHandler returns the sdk.Querier for market module -func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { - return nil -} +// IsAppModule implements the appmodule.AppModule interface. +func (am AppModule) IsAppModule() {} // RegisterServices registers the module's services func (am AppModule) RegisterServices(cfg module.Configurator) { @@ -168,20 +152,22 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { } // BeginBlock performs no-op -func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} +func (am AppModule) BeginBlock(_ context.Context) error { + return nil +} -// EndBlock returns the end blocker for the market module. It returns no validator +// EndBlock returns the end blocker for the deployment module. It returns no validator // updates. -func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - return []abci.ValidatorUpdate{} +func (am AppModule) EndBlock(_ context.Context) error { + return nil } // InitGenesis performs genesis initialization for the market module. It returns // no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) { var genesisState types.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) - return InitGenesis(ctx, am.keepers.Market, &genesisState) + InitGenesis(ctx, am.keepers.Market, &genesisState) } // ExportGenesis returns the exported genesis state as raw bytes for the market @@ -193,58 +179,25 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw // ConsensusVersion implements module.AppModule#ConsensusVersion func (am AppModule) ConsensusVersion() uint64 { - return 6 -} - -// AppModuleSimulation implements an application simulation module for the market module. -type AppModuleSimulation struct { - keepers handler.Keepers - akeeper govtypes.AccountKeeper -} - -// NewAppModuleSimulation creates a new AppModuleSimulation instance -func NewAppModuleSimulation( - keeper keeper.IKeeper, - akeeper govtypes.AccountKeeper, - dkeeper handler.DeploymentKeeper, - pkeeper handler.ProviderKeeper, - bkeeper bankkeeper.Keeper, -) AppModuleSimulation { - return AppModuleSimulation{ - keepers: handler.Keepers{ - Market: keeper, - Deployment: dkeeper, - Provider: pkeeper, - Bank: bkeeper, - }, - akeeper: akeeper, - } + return 7 } // AppModuleSimulation functions // GenerateGenesisState creates a randomized GenState of the staking module. -func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) { +func (AppModule) GenerateGenesisState(simState *module.SimulationState) { simulation.RandomizedGenState(simState) } -// ProposalContents doesn't return any content functions for governance proposals. -func (AppModuleSimulation) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { - return nil -} - -// RandomizedParams creates randomized staking param changes for the simulator. -func (AppModuleSimulation) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { - return nil +// ProposalMsgs returns msgs used for governance proposals for simulations. +func (AppModule) ProposalMsgs(_ module.SimulationState) []simtypes.WeightedProposalMsg { + return simulation.ProposalMsgs() } -// RegisterStoreDecoder registers a decoder for staking module's types -func (AppModuleSimulation) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) { - // sdr[StoreKey] = simulation.DecodeStore -} +// RegisterStoreDecoder registers a decoder for take module's types. +func (am AppModule) RegisterStoreDecoder(_ simtypes.StoreDecoderRegistry) {} -// WeightedOperations returns the all the staking module operations with their respective weights. -func (am AppModuleSimulation) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { - return simulation.WeightedOperations(simState.AppParams, simState.Cdc, - am.akeeper, am.keepers) +// WeightedOperations doesn't return any take module operation. +func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { + return simulation.WeightedOperations(simState.AppParams, simState.Cdc, am.keepers) } diff --git a/x/market/query/client.go b/x/market/query/client.go index 189c67c719..e5dbc82ab5 100644 --- a/x/market/query/client.go +++ b/x/market/query/client.go @@ -1,15 +1,15 @@ package query import ( - types "github.com/akash-network/akash-api/go/node/market/v1beta4" + "pkg.akt.dev/go/node/market/v1" ) // Client interface type Client interface { Orders(filters OrderFilters) (Orders, error) - Order(id types.OrderID) (Order, error) + Order(id v1.OrderID) (Order, error) Bids(filters BidFilters) (Bids, error) - Bid(id types.BidID) (Bid, error) + Bid(id v1.BidID) (Bid, error) Leases(filters LeaseFilters) (Leases, error) - Lease(id types.LeaseID) (Lease, error) + Lease(id v1.LeaseID) (Lease, error) } diff --git a/x/market/query/path.go b/x/market/query/path.go index d4dd876049..f686237048 100644 --- a/x/market/query/path.go +++ b/x/market/query/path.go @@ -6,10 +6,9 @@ import ( "strconv" sdk "github.com/cosmos/cosmos-sdk/types" + v1 "pkg.akt.dev/go/node/market/v1" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" - - dpath "github.com/akash-network/node/x/deployment/query" + dpath "pkg.akt.dev/node/x/deployment/query" ) const ( @@ -33,7 +32,7 @@ func getOrdersPath(ofilters OrderFilters) string { } // OrderPath return order path of given order id for queries -func OrderPath(id types.OrderID) string { +func OrderPath(id v1.OrderID) string { return fmt.Sprintf("%s/%s", orderPath, orderParts(id)) } @@ -43,7 +42,7 @@ func getBidsPath(bfilters BidFilters) string { } // getBidPath return bid path of given bid id for queries -func getBidPath(id types.BidID) string { +func getBidPath(id v1.BidID) string { return fmt.Sprintf("%s/%s/%s", bidPath, orderParts(id.OrderID()), id.Provider) } @@ -53,61 +52,61 @@ func getLeasesPath(lfilters LeaseFilters) string { } // LeasePath return lease path of given lease id for queries -func LeasePath(id types.LeaseID) string { +func LeasePath(id v1.LeaseID) string { return fmt.Sprintf("%s/%s/%s", leasePath, orderParts(id.OrderID()), id.Provider) } -func orderParts(id types.OrderID) string { +func orderParts(id v1.OrderID) string { return fmt.Sprintf("%s/%v/%v/%v", id.Owner, id.DSeq, id.GSeq, id.OSeq) } // parseOrderPath returns orderID details with provided queries, and return // error if occurred due to wrong query -func parseOrderPath(parts []string) (types.OrderID, error) { +func parseOrderPath(parts []string) (v1.OrderID, error) { if len(parts) < 4 { - return types.OrderID{}, ErrInvalidPath + return v1.OrderID{}, ErrInvalidPath } did, err := dpath.ParseGroupPath(parts[0:3]) if err != nil { - return types.OrderID{}, err + return v1.OrderID{}, err } oseq, err := strconv.ParseUint(parts[3], 10, 32) if err != nil { - return types.OrderID{}, err + return v1.OrderID{}, err } - return types.MakeOrderID(did, uint32(oseq)), nil + return v1.MakeOrderID(did, uint32(oseq)), nil } // parseBidPath returns bidID details with provided queries, and return // error if occurred due to wrong query -func parseBidPath(parts []string) (types.BidID, error) { +func parseBidPath(parts []string) (v1.BidID, error) { if len(parts) < 5 { - return types.BidID{}, ErrInvalidPath + return v1.BidID{}, ErrInvalidPath } oid, err := parseOrderPath(parts[0:4]) if err != nil { - return types.BidID{}, err + return v1.BidID{}, err } provider, err := sdk.AccAddressFromBech32(parts[4]) if err != nil { - return types.BidID{}, err + return v1.BidID{}, err } - return types.MakeBidID(oid, provider), nil + return v1.MakeBidID(oid, provider), nil } // ParseLeasePath returns leaseID details with provided queries, and return // error if occurred due to wrong query -func ParseLeasePath(parts []string) (types.LeaseID, error) { +func ParseLeasePath(parts []string) (v1.LeaseID, error) { bid, err := parseBidPath(parts) if err != nil { - return types.LeaseID{}, err + return v1.LeaseID{}, err } - return types.MakeLeaseID(bid), nil + return v1.MakeLeaseID(bid), nil } diff --git a/x/market/query/rawclient.go b/x/market/query/rawclient.go index da2e6c713b..7857abf59e 100644 --- a/x/market/query/rawclient.go +++ b/x/market/query/rawclient.go @@ -4,18 +4,17 @@ import ( "fmt" sdkclient "github.com/cosmos/cosmos-sdk/client" - - types "github.com/akash-network/akash-api/go/node/market/v1beta4" + v1 "pkg.akt.dev/go/node/market/v1" ) // RawClient interface type RawClient interface { Orders(filters OrderFilters) ([]byte, error) - Order(id types.OrderID) ([]byte, error) + Order(id v1.OrderID) ([]byte, error) Bids(filters BidFilters) ([]byte, error) - Bid(id types.BidID) ([]byte, error) + Bid(id v1.BidID) ([]byte, error) Leases(filters LeaseFilters) ([]byte, error) - Lease(id types.LeaseID) ([]byte, error) + Lease(id v1.LeaseID) ([]byte, error) } // NewRawClient creates a raw client instance with provided context and key @@ -36,7 +35,7 @@ func (c *rawclient) Orders(ofilters OrderFilters) ([]byte, error) { return buf, nil } -func (c *rawclient) Order(id types.OrderID) ([]byte, error) { +func (c *rawclient) Order(id v1.OrderID) ([]byte, error) { buf, _, err := c.ctx.QueryWithData(fmt.Sprintf("custom/%s/%s", c.key, OrderPath(id)), nil) if err != nil { return []byte{}, err @@ -52,7 +51,7 @@ func (c *rawclient) Bids(bfilters BidFilters) ([]byte, error) { return buf, nil } -func (c *rawclient) Bid(id types.BidID) ([]byte, error) { +func (c *rawclient) Bid(id v1.BidID) ([]byte, error) { buf, _, err := c.ctx.QueryWithData(fmt.Sprintf("custom/%s/%s", c.key, getBidPath(id)), nil) if err != nil { return []byte{}, err @@ -68,7 +67,7 @@ func (c *rawclient) Leases(lfilters LeaseFilters) ([]byte, error) { return buf, nil } -func (c *rawclient) Lease(id types.LeaseID) ([]byte, error) { +func (c *rawclient) Lease(id v1.LeaseID) ([]byte, error) { buf, _, err := c.ctx.QueryWithData(fmt.Sprintf("custom/%s/%s", c.key, LeasePath(id)), nil) if err != nil { return []byte{}, err diff --git a/x/market/query/types.go b/x/market/query/types.go index 2087a20ec8..b1acb06027 100644 --- a/x/market/query/types.go +++ b/x/market/query/types.go @@ -3,22 +3,23 @@ package query import ( sdk "github.com/cosmos/cosmos-sdk/types" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" + "pkg.akt.dev/go/node/market/v1" + "pkg.akt.dev/go/node/market/v1beta5" ) type ( // Order type - Order types.Order + Order v1beta5.Order // Orders - Slice of Order Struct Orders []Order // Bid type - Bid types.Bid + Bid v1beta5.Bid // Bids - Slice of Bid Struct Bids []Bid // Lease type - Lease types.Lease + Lease v1.Lease // Leases - Slice of Lease Struct Leases []Lease ) @@ -33,7 +34,7 @@ type OrderFilters struct { // State flag value given StateFlagVal string // Actual state value decoded from Order_State_value - State types.Order_State + State v1beta5.Order_State } // BidFilters defines flags for bid list filter @@ -42,7 +43,7 @@ type BidFilters struct { // State flag value given StateFlagVal string // Actual state value decoded from Bid_State_value - State types.Bid_State + State v1beta5.Bid_State } // LeaseFilters defines flags for lease list filter @@ -51,15 +52,15 @@ type LeaseFilters struct { // State flag value given StateFlagVal string // Actual state value decoded from Lease_State_value - State types.Lease_State + State v1.Lease_State } // Accept returns true if object matches filter requirements -func (f OrderFilters) Accept(obj types.Order, isValidState bool) bool { +func (f OrderFilters) Accept(obj v1beta5.Order, isValidState bool) bool { if (f.Owner.Empty() && !isValidState) || (f.Owner.Empty() && (obj.State == f.State)) || - (!isValidState && obj.OrderID.Owner == f.Owner.String()) || - (obj.OrderID.Owner == f.Owner.String() && obj.State == f.State) { + (!isValidState && obj.ID.Owner == f.Owner.String()) || + (obj.ID.Owner == f.Owner.String() && obj.State == f.State) { return true } @@ -67,11 +68,11 @@ func (f OrderFilters) Accept(obj types.Order, isValidState bool) bool { } // Accept returns true if object matches filter requirements -func (f BidFilters) Accept(obj types.Bid, isValidState bool) bool { +func (f BidFilters) Accept(obj v1beta5.Bid, isValidState bool) bool { if (f.Owner.Empty() && !isValidState) || (f.Owner.Empty() && (obj.State == f.State)) || - (!isValidState && obj.BidID.Owner == f.Owner.String()) || - (obj.BidID.Owner == f.Owner.String() && obj.State == f.State) { + (!isValidState && obj.ID.Owner == f.Owner.String()) || + (obj.ID.Owner == f.Owner.String() && obj.State == f.State) { return true } @@ -79,11 +80,11 @@ func (f BidFilters) Accept(obj types.Bid, isValidState bool) bool { } // Accept returns true if object matches filter requirements -func (f LeaseFilters) Accept(obj types.Lease, isValidState bool) bool { +func (f LeaseFilters) Accept(obj v1.Lease, isValidState bool) bool { if (f.Owner.Empty() && !isValidState) || (f.Owner.Empty() && (obj.State == f.State)) || - (!isValidState && (obj.LeaseID.Owner == f.Owner.String())) || - (obj.LeaseID.Owner == f.Owner.String() && obj.State == f.State) { + (!isValidState && (obj.ID.Owner == f.Owner.String())) || + (obj.ID.Owner == f.Owner.String() && obj.State == f.State) { return true } return false diff --git a/x/market/simulation/genesis.go b/x/market/simulation/genesis.go index f6cf09d027..8da59d0452 100644 --- a/x/market/simulation/genesis.go +++ b/x/market/simulation/genesis.go @@ -2,9 +2,10 @@ package simulation import ( "github.com/cosmos/cosmos-sdk/types/module" + mv1 "pkg.akt.dev/go/node/market/v1" - dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" + dtypes "pkg.akt.dev/go/node/deployment/v1beta4" + types "pkg.akt.dev/go/node/market/v1beta5" ) var minDeposit, _ = dtypes.DefaultParams().MinDepositFor("uakt") @@ -18,5 +19,5 @@ func RandomizedGenState(simState *module.SimulationState) { }, } - simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(marketGenesis) + simState.GenState[mv1.ModuleName] = simState.Cdc.MustMarshalJSON(marketGenesis) } diff --git a/x/market/simulation/operations.go b/x/market/simulation/operations.go index 7fec0fd7ae..7ee5552472 100644 --- a/x/market/simulation/operations.go +++ b/x/market/simulation/operations.go @@ -7,19 +7,19 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/simapp/helpers" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - "github.com/cosmos/cosmos-sdk/x/simulation" - - simappparams "github.com/cosmos/cosmos-sdk/simapp/params" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/simulation" + deposit "pkg.akt.dev/go/node/types/deposit/v1" + "pkg.akt.dev/go/sdkutil" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" + "pkg.akt.dev/go/node/market/v1" + types "pkg.akt.dev/go/node/market/v1beta5" - appparams "github.com/akash-network/node/app/params" - testsim "github.com/akash-network/node/testutil/sim" - keepers "github.com/akash-network/node/x/market/handler" + appparams "pkg.akt.dev/node/app/params" + testsim "pkg.akt.dev/node/testutil/sim" + keepers "pkg.akt.dev/node/x/market/handler" ) // Simulation operation weights constants @@ -31,8 +31,7 @@ const ( // WeightedOperations returns all the operations from the module with their respective weights func WeightedOperations( - appParams simtypes.AppParams, cdc codec.JSONCodec, ak govtypes.AccountKeeper, - ks keepers.Keepers) simulation.WeightedOperations { + appParams simtypes.AppParams, _ codec.JSONCodec, ks keepers.Keepers) simulation.WeightedOperations { var ( weightMsgCreateBid int weightMsgCloseBid int @@ -40,19 +39,19 @@ func WeightedOperations( ) appParams.GetOrGenerate( - cdc, OpWeightMsgCreateBid, &weightMsgCreateBid, nil, func(r *rand.Rand) { + OpWeightMsgCreateBid, &weightMsgCreateBid, nil, func(_ *rand.Rand) { weightMsgCreateBid = appparams.DefaultWeightMsgCreateBid }, ) appParams.GetOrGenerate( - cdc, OpWeightMsgCloseBid, &weightMsgCloseBid, nil, func(r *rand.Rand) { + OpWeightMsgCloseBid, &weightMsgCloseBid, nil, func(_ *rand.Rand) { weightMsgCloseBid = appparams.DefaultWeightMsgCloseBid }, ) appParams.GetOrGenerate( - cdc, OpWeightMsgCloseLease, &weightMsgCloseLease, nil, func(r *rand.Rand) { + OpWeightMsgCloseLease, &weightMsgCloseLease, nil, func(_ *rand.Rand) { weightMsgCloseLease = appparams.DefaultWeightMsgCloseLease }, ) @@ -60,26 +59,25 @@ func WeightedOperations( return simulation.WeightedOperations{ simulation.NewWeightedOperation( weightMsgCreateBid, - SimulateMsgCreateBid(ak, ks), + SimulateMsgCreateBid(ks), ), simulation.NewWeightedOperation( weightMsgCloseBid, - SimulateMsgCloseBid(ak, ks), + SimulateMsgCloseBid(ks), ), simulation.NewWeightedOperation( weightMsgCloseLease, - SimulateMsgCloseLease(ak, ks), + SimulateMsgCloseLease(ks), ), } } // SimulateMsgCreateBid generates a MsgCreateBid with random values -func SimulateMsgCreateBid(ak govtypes.AccountKeeper, ks keepers.Keepers) simtypes.Operation { - return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accounts []simtypes.Account, - chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { +func SimulateMsgCreateBid(ks keepers.Keepers) simtypes.Operation { + return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { orders := getOrdersWithState(ctx, ks, types.OrderOpen) if len(orders) == 0 { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateBid, "no open orders found"), nil, nil + return simtypes.NoOpMsg(v1.ModuleName, (&types.MsgCreateBid{}).Type(), "no open orders found"), nil, nil } // Get random order @@ -88,7 +86,7 @@ func SimulateMsgCreateBid(ak govtypes.AccountKeeper, ks keepers.Keepers) simtype providers := getProviders(ctx, ks) if len(providers) == 0 { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateBid, "no providers found"), nil, nil + return simtypes.NoOpMsg(v1.ModuleName, (&types.MsgCreateBid{}).Type(), "no providers found"), nil, nil } // Get random deployment @@ -96,73 +94,77 @@ func SimulateMsgCreateBid(ak govtypes.AccountKeeper, ks keepers.Keepers) simtype ownerAddr, convertErr := sdk.AccAddressFromBech32(provider.Owner) if convertErr != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateBid, "error while converting address"), nil, convertErr + return simtypes.NoOpMsg(v1.ModuleName, (&types.MsgCreateBid{}).Type(), "error while converting address"), nil, convertErr } simAccount, found := simtypes.FindAccount(accounts, ownerAddr) if !found { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateBid, "unable to find provider"), + return simtypes.NoOpMsg(v1.ModuleName, (&types.MsgCreateBid{}).Type(), "unable to find provider"), nil, fmt.Errorf("provider with %s not found", provider.Owner) } - if provider.Owner == order.ID().Owner { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateBid, "provider and order owner cannot be same"), + if provider.Owner == order.ID.Owner { + return simtypes.NoOpMsg(v1.ModuleName, (&types.MsgCreateBid{}).Type(), "provider and order owner cannot be same"), nil, nil } depositAmount := minDeposit - account := ak.GetAccount(ctx, simAccount.Address) + account := ks.Account.GetAccount(ctx, simAccount.Address) spendable := ks.Bank.SpendableCoins(ctx, account.GetAddress()) if spendable.AmountOf(depositAmount.Denom).LT(depositAmount.Amount.MulRaw(2)) { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateBid, "out of money"), nil, nil + return simtypes.NoOpMsg(v1.ModuleName, (&types.MsgCreateBid{}).Type(), "out of money"), nil, nil } - spendable = spendable.Sub(sdk.NewCoins(depositAmount)) + spendable = spendable.Sub(depositAmount) fees, err := simtypes.RandomFees(r, ctx, spendable) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateBid, "unable to generate fees"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, (&types.MsgCreateBid{}).Type(), "unable to generate fees"), nil, err } - msg := types.NewMsgCreateBid(order.OrderID, simAccount.Address, order.Price(), depositAmount, nil) + msg := types.NewMsgCreateBid(v1.MakeBidID(order.ID, simAccount.Address), order.Price(), deposit.Deposit{ + Amount: depositAmount, + Sources: deposit.Sources{deposit.SourceBalance}, + }, nil) - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( + txGen := sdkutil.MakeEncodingConfig().TxConfig + tx, err := simtestutil.GenSignedMockTx( + r, txGen, []sdk.Msg{msg}, fees, - helpers.DefaultGenTxGas, + simtestutil.DefaultGenTxGas, chainID, []uint64{account.GetAccountNumber()}, []uint64{account.GetSequence()}, simAccount.PrivKey, ) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err } - _, _, err = app.Deliver(txGen.TxEncoder(), tx) + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) switch { case err == nil: - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil - case errors.Is(err, types.ErrBidExists): - return simtypes.NewOperationMsg(msg, false, "", nil), nil, nil + return simtypes.NewOperationMsg(msg, true, ""), nil, nil + case errors.Is(err, v1.ErrBidExists): + return simtypes.NewOperationMsg(msg, false, ""), nil, nil default: - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver mock tx"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, msg.Type(), "unable to deliver mock tx"), nil, err } } } // SimulateMsgCloseBid generates a MsgCloseBid with random values -func SimulateMsgCloseBid(ak govtypes.AccountKeeper, ks keepers.Keepers) simtypes.Operation { +func SimulateMsgCloseBid(ks keepers.Keepers) simtypes.Operation { return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accounts []simtypes.Account, chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { var bids []types.Bid ks.Market.WithBids(ctx, func(bid types.Bid) bool { if bid.State == types.BidActive { - lease, ok := ks.Market.GetLease(ctx, types.LeaseID(bid.BidID)) - if ok && lease.State == types.LeaseActive { + lease, ok := ks.Market.GetLease(ctx, v1.LeaseID(bid.ID)) + if ok && lease.State == v1.LeaseActive { bids = append(bids, bid) } } @@ -171,96 +173,106 @@ func SimulateMsgCloseBid(ak govtypes.AccountKeeper, ks keepers.Keepers) simtypes }) if len(bids) == 0 { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseBid, "no matched bids found"), nil, nil + return simtypes.NoOpMsg(v1.ModuleName, (&types.MsgCloseBid{}).Type(), "no matched bids found"), nil, nil } // Get random bid bid := bids[testsim.RandIdx(r, len(bids)-1)] - providerAddr, convertErr := sdk.AccAddressFromBech32(bid.ID().Provider) + providerAddr, convertErr := sdk.AccAddressFromBech32(bid.ID.Provider) if convertErr != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseBid, "error while converting address"), nil, convertErr + return simtypes.NoOpMsg(v1.ModuleName, (&types.MsgCloseBid{}).Type(), "error while converting address"), nil, convertErr } simAccount, found := simtypes.FindAccount(accounts, providerAddr) if !found { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseBid, "unable to find bid with provider"), - nil, fmt.Errorf("bid with %s not found", bid.ID().Provider) + return simtypes.NoOpMsg(v1.ModuleName, (&types.MsgCloseBid{}).Type(), "unable to find bid with provider"), + nil, fmt.Errorf("bid with %s not found", bid.ID.Provider) } - account := ak.GetAccount(ctx, simAccount.Address) + account := ks.Account.GetAccount(ctx, simAccount.Address) spendable := ks.Bank.SpendableCoins(ctx, account.GetAddress()) fees, err := simtypes.RandomFees(r, ctx, spendable) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseBid, "unable to generate fees"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, (&types.MsgCloseBid{}).Type(), "unable to generate fees"), nil, err } - msg := types.NewMsgCloseBid(bid.BidID) + msg := types.NewMsgCloseBid(bid.ID, v1.LeaseClosedReasonUnspecified) - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( + txGen := sdkutil.MakeEncodingConfig().TxConfig + tx, err := simtestutil.GenSignedMockTx( + r, txGen, []sdk.Msg{msg}, fees, - helpers.DefaultGenTxGas, + simtestutil.DefaultGenTxGas, chainID, []uint64{account.GetAccountNumber()}, []uint64{account.GetSequence()}, simAccount.PrivKey, ) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err } - _, _, err = app.Deliver(txGen.TxEncoder(), tx) + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err + return simtypes.NoOpMsg(v1.ModuleName, msg.Type(), "unable to deliver tx"), nil, err } - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + return simtypes.NewOperationMsg(msg, true, ""), nil, nil } } // SimulateMsgCloseLease generates a MsgCloseLease with random values -func SimulateMsgCloseLease(ak govtypes.AccountKeeper, ks keepers.Keepers) simtypes.Operation { - return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accounts []simtypes.Account, - chainID string) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { - // orders := getOrdersWithState(ctx, ks, types.OrderActive) - // if len(orders) == 0 { - // return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseLease, "no orders with state matched found"), nil, nil +func SimulateMsgCloseLease(_ keepers.Keepers) simtypes.Operation { + return func( + r *rand.Rand, // nolint revive + app *baseapp.BaseApp, // nolint revive + ctx sdk.Context, // nolint revive + accounts []simtypes.Account, // nolint revive + chainID string, // nolint revive + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + // leases := getLeasesWithState(ctx, ks, v1.LeaseActive) + // if len(leases) == 0 { + // return simtypes.NoOpMsg(types.ModuleName, (&types.MsgCloseLease{}).Type(), "no orders with state matched found"), nil, nil // } - + // // // Get random order - // order := orders[testsim.RandIdx(r, len(orders) - 1)] - - // ownerAddr, convertErr := sdk.AccAddressFromBech32(order.ID().Owner) + // lease := leases[testsim.RandIdx(r, len(leases)-1)] + // + // ownerAddr, convertErr := sdk.AccAddressFromBech32(lease.ID.Owner) // if convertErr != nil { - // return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseLease, "error while converting address"), nil, convertErr + // return simtypes.NoOpMsg(types.ModuleName, (&types.MsgCloseLease{}).Type(), "error while converting address"), nil, convertErr // } - + // // simAccount, found := simtypes.FindAccount(accounts, ownerAddr) // if !found { - // return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseLease, "unable to find order"), - // nil, errors.Errorf("order with %s not found", order.ID().Owner) + // return simtypes.NoOpMsg(types.ModuleName, (&types.MsgCloseLease{}).Type(), "unable to find lease"), + // nil, fmt.Errorf("lease with %s not found", lease.ID.Owner) // } - - // account := ak.GetAccount(ctx, simAccount.Address) + // + // account := ks.Account.GetAccount(ctx, simAccount.Address) // spendable := ks.Bank.SpendableCoins(ctx, account.GetAddress()) - + // // fees, err := simtypes.RandomFees(r, ctx, spendable) // if err != nil { - // return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseBid, "unable to generate fees"), nil, err + // return simtypes.NoOpMsg(types.ModuleName, (&types.MsgCloseLease{}).Type(), "unable to generate fees"), nil, err // } - - // msg := types.NewMsgCloseLease(order.OrderID) - - // txGen := simappparams.MakeTestEncodingConfig().TxConfig - // tx, err := helpers.GenTx( + // + // lease.ID.Provider = "3425q" + // + // msg := types.NewMsgCloseLease(lease.ID) + // + // txGen := moduletestutil.MakeTestEncodingConfig().TxConfig + // + // tx, err := simtestutil.GenSignedMockTx( + // r, // txGen, // []sdk.Msg{msg}, // fees, - // helpers.DefaultGenTxGas, + // simtestutil.DefaultGenTxGas, // chainID, // []uint64{account.GetAccountNumber()}, // []uint64{account.GetSequence()}, @@ -269,12 +281,14 @@ func SimulateMsgCloseLease(ak govtypes.AccountKeeper, ks keepers.Keepers) simtyp // if err != nil { // return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err // } - - // _, _, err = app.Deliver(txGen.TxEncoder(), tx) + // + // _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) // if err != nil { // return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, err // } + // + // return simtypes.NoOpMsg(types.ModuleName, (&types.MsgCloseLease{}).Type(), "skipping"), nil, nil - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCloseLease, "skipping"), nil, nil + return simtypes.NoOpMsg(v1.ModuleName, (&types.MsgCloseLease{}).Type(), "skipping"), nil, nil } } diff --git a/x/market/simulation/proposals.go b/x/market/simulation/proposals.go new file mode 100644 index 0000000000..0afcbd3c5c --- /dev/null +++ b/x/market/simulation/proposals.go @@ -0,0 +1,44 @@ +package simulation + +import ( + "math/rand" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/simulation" + + types "pkg.akt.dev/go/node/market/v1beta5" +) + +// Simulation operation weights constants +const ( + DefaultWeightMsgUpdateParams int = 100 + + OpWeightMsgUpdateParams = "op_weight_msg_update_params" //nolint:gosec +) + +// ProposalMsgs defines the module weighted proposals' contents +func ProposalMsgs() []simtypes.WeightedProposalMsg { + return []simtypes.WeightedProposalMsg{ + simulation.NewWeightedProposalMsg( + OpWeightMsgUpdateParams, + DefaultWeightMsgUpdateParams, + SimulateMsgUpdateParams, + ), + } +} + +func SimulateMsgUpdateParams(r *rand.Rand, _ sdk.Context, _ []simtypes.Account) sdk.Msg { + // use the default gov module account address as authority + var authority sdk.AccAddress = address.Module("gov") + + params := types.DefaultParams() + params.BidMinDeposit = sdk.NewInt64Coin("uakt", int64(simtypes.RandIntBetween(r, 500000, 50000000))) + params.OrderMaxBids = uint32(simtypes.RandIntBetween(r, 20, 500)) // nolint gosec + + return &types.MsgUpdateParams{ + Authority: authority.String(), + Params: params, + } +} diff --git a/x/market/simulation/utils.go b/x/market/simulation/utils.go index 5a9f60be88..2b15153407 100644 --- a/x/market/simulation/utils.go +++ b/x/market/simulation/utils.go @@ -2,18 +2,17 @@ package simulation import ( sdk "github.com/cosmos/cosmos-sdk/types" + "pkg.akt.dev/go/node/market/v1beta5" - types "github.com/akash-network/akash-api/go/node/market/v1beta4" + ptypes "pkg.akt.dev/go/node/provider/v1beta4" - ptypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" - - keepers "github.com/akash-network/node/x/market/handler" + keepers "pkg.akt.dev/node/x/market/handler" ) -func getOrdersWithState(ctx sdk.Context, ks keepers.Keepers, state types.Order_State) []types.Order { - var orders []types.Order +func getOrdersWithState(ctx sdk.Context, ks keepers.Keepers, state v1beta5.Order_State) v1beta5.Orders { + var orders v1beta5.Orders - ks.Market.WithOrders(ctx, func(order types.Order) bool { + ks.Market.WithOrders(ctx, func(order v1beta5.Order) bool { if order.State == state { orders = append(orders, order) } diff --git a/x/provider/alias.go b/x/provider/alias.go index e67402a720..90407bcba8 100644 --- a/x/provider/alias.go +++ b/x/provider/alias.go @@ -1,9 +1,9 @@ package provider import ( - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" + types "pkg.akt.dev/go/node/provider/v1beta4" - "github.com/akash-network/node/x/provider/keeper" + "pkg.akt.dev/node/x/provider/keeper" ) const ( diff --git a/x/provider/client/cli/cli_test.go b/x/provider/client/cli/cli_test.go deleted file mode 100644 index a6e8ceffab..0000000000 --- a/x/provider/client/cli/cli_test.go +++ /dev/null @@ -1,114 +0,0 @@ -package cli_test - -import ( - "fmt" - "path/filepath" - "testing" - - "github.com/stretchr/testify/suite" - - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" - - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/testutil/network" - "github.com/akash-network/node/x/provider/client/cli" -) - -type IntegrationTestSuite struct { - suite.Suite - - cfg network.Config - network *network.Network -} - -func (s *IntegrationTestSuite) SetupSuite() { - s.T().Log("setting up integration test suite") - - cfg := testutil.DefaultConfig() - cfg.NumValidators = 1 - - s.cfg = cfg - s.network = network.New(s.T(), cfg) - - _, err := s.network.WaitForHeight(1) - s.Require().NoError(err) -} - -func (s *IntegrationTestSuite) TearDownSuite() { - s.T().Log("tearing down integration test suite") - s.network.Cleanup() -} - -func (s *IntegrationTestSuite) TestProvider() { - val := s.network.Validators[0] - - providerPath, err := filepath.Abs("../../testdata/provider.yaml") - s.Require().NoError(err) - - providerPath2, err := filepath.Abs("../../testdata/provider2.yaml") - s.Require().NoError(err) - - // create deployment - _, err = cli.TxCreateProviderExec( - val.ClientCtx, - val.Address, - providerPath, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - // test query providers - resp, err := cli.QueryProvidersExec(val.ClientCtx.WithOutputFormat("json")) - s.Require().NoError(err) - - out := &types.QueryProvidersResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), out) - s.Require().NoError(err) - s.Require().Len(out.Providers, 1, "Provider Creation Failed") - providers := out.Providers - s.Require().Equal(val.Address.String(), providers[0].Owner) - - // test query provider - createdProvider := providers[0] - resp, err = cli.QueryProviderExec(val.ClientCtx.WithOutputFormat("json"), createdProvider.Owner) - s.Require().NoError(err) - - var provider types.Provider - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &provider) - s.Require().NoError(err) - s.Require().Equal(createdProvider, provider) - - // test updating provider - _, err = cli.TxUpdateProviderExec( - val.ClientCtx, - val.Address, - providerPath2, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - resp, err = cli.QueryProviderExec(val.ClientCtx.WithOutputFormat("json"), createdProvider.Owner) - s.Require().NoError(err) - - var providerV2 types.Provider - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), &providerV2) - s.Require().NoError(err) - s.Require().NotEqual(provider.HostURI, providerV2.HostURI) -} - -func TestIntegrationTestSuite(t *testing.T) { - suite.Run(t, new(IntegrationTestSuite)) -} diff --git a/x/provider/client/cli/grpc_rest_test.go b/x/provider/client/cli/grpc_rest_test.go deleted file mode 100644 index a7f3397f16..0000000000 --- a/x/provider/client/cli/grpc_rest_test.go +++ /dev/null @@ -1,170 +0,0 @@ -package cli_test - -import ( - "fmt" - "path/filepath" - "testing" - - "github.com/stretchr/testify/suite" - - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkrest "github.com/cosmos/cosmos-sdk/types/rest" - - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" - - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/testutil/network" - "github.com/akash-network/node/x/provider/client/cli" -) - -type GRPCRestTestSuite struct { - suite.Suite - - cfg network.Config - network *network.Network - provider types.Provider -} - -func (s *GRPCRestTestSuite) SetupSuite() { - s.T().Log("setting up integration test suite") - - cfg := testutil.DefaultConfig() - cfg.NumValidators = 1 - - s.cfg = cfg - s.network = network.New(s.T(), cfg) - - _, err := s.network.WaitForHeight(1) - s.Require().NoError(err) - - val := s.network.Validators[0] - - providerPath, err := filepath.Abs("../../testdata/provider.yaml") - s.Require().NoError(err) - - // create deployment - _, err = cli.TxCreateProviderExec( - val.ClientCtx, - val.Address, - providerPath, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - ) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - // get provider - resp, err := cli.QueryProvidersExec(val.ClientCtx.WithOutputFormat("json")) - s.Require().NoError(err) - - out := &types.QueryProvidersResponse{} - err = val.ClientCtx.Codec.UnmarshalJSON(resp.Bytes(), out) - s.Require().NoError(err) - s.Require().Len(out.Providers, 1, "Provider Creation Failed") - providers := out.Providers - s.Require().Equal(val.Address.String(), providers[0].Owner) - - s.provider = providers[0] -} - -func (s *GRPCRestTestSuite) TestGetProviders() { - val := s.network.Validators[0] - provider := s.provider - - testCases := []struct { - name string - url string - expResp types.Provider - expLen int - }{ - { - "get providers without pagination", - fmt.Sprintf("%s/akash/provider/v1beta3/providers", val.APIAddress), - provider, - 1, - }, - { - "get providers with pagination", - fmt.Sprintf("%s/akash/provider/v1beta3/providers?pagination.offset=2", val.APIAddress), - types.Provider{}, - 0, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := sdkrest.GetRequest(tc.url) - s.Require().NoError(err) - - var providers types.QueryProvidersResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp, &providers) - - s.Require().NoError(err) - s.Require().Len(providers.Providers, tc.expLen) - if tc.expLen != 0 { - s.Require().Equal(tc.expResp, providers.Providers[0]) - } - }) - } -} - -func (s *GRPCRestTestSuite) TestGetProvider() { - val := s.network.Validators[0] - provider := s.provider - - testCases := []struct { - name string - url string - expErr bool - expResp types.Provider - }{ - { - "get group with empty input", - fmt.Sprintf("%s/akash/provider/v1beta3/providers/%s", val.APIAddress, ""), - true, - types.Provider{}, - }, - { - "get provider with invalid input", - fmt.Sprintf("%s/akash/provider/v1beta3/providers/%s", val.APIAddress, "hellohai"), - true, - types.Provider{}, - }, - { - "valid get provider request", - fmt.Sprintf("%s/akash/provider/v1beta3/providers/%s", val.APIAddress, provider.Owner), - false, - provider, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := sdkrest.GetRequest(tc.url) - s.Require().NoError(err) - - var out types.QueryProviderResponse - err = val.ClientCtx.Codec.UnmarshalJSON(resp, &out) - - if tc.expErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().Equal(tc.expResp, out.Provider) - } - }) - } -} - -func (s *GRPCRestTestSuite) TearDownSuite() { - s.T().Log("tearing down integration test suite") - s.network.Cleanup() -} - -func TestGRPCRestTestSuite(t *testing.T) { - suite.Run(t, new(GRPCRestTestSuite)) -} diff --git a/x/provider/client/cli/query.go b/x/provider/client/cli/query.go deleted file mode 100644 index 1109fcf978..0000000000 --- a/x/provider/client/cli/query.go +++ /dev/null @@ -1,108 +0,0 @@ -package cli - -import ( - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" - - aclient "github.com/akash-network/node/client" - clientutils "github.com/akash-network/node/client" -) - -// GetQueryCmd returns the transaction commands for the provider module -func GetQueryCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: "Provider query commands", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - - cmd.AddCommand( - cmdGetProviders(), - cmdGetProvider(), - ) - - return cmd -} - -func cmdGetProviders() *cobra.Command { - cmd := &cobra.Command{ - Use: "list", - Short: "Query for all providers", - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientQueryContext(cmd) - if err != nil { - return err - } - - qq, err := aclient.DiscoverQueryClient(ctx, cctx) - if err != nil { - return err - } - - pageReq, err := clientutils.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - params := &types.QueryProvidersRequest{ - Pagination: pageReq, - } - - res, err := qq.Providers(cmd.Context(), params) - if err != nil { - return err - } - - return qq.ClientContext().PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "providers") - - return cmd -} - -func cmdGetProvider() *cobra.Command { - cmd := &cobra.Command{ - Use: "get [address]", - Short: "Query provider", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientQueryContext(cmd) - if err != nil { - return err - } - - qq, err := aclient.DiscoverQueryClient(ctx, cctx) - if err != nil { - return err - } - - owner, err := sdk.AccAddressFromBech32(args[0]) - if err != nil { - return err - } - - res, err := qq.Provider(cmd.Context(), &types.QueryProviderRequest{Owner: owner.String()}) - if err != nil { - return err - } - - return qq.ClientContext().PrintProto(&res.Provider) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} diff --git a/x/provider/client/cli/test_helpers.go b/x/provider/client/cli/test_helpers.go deleted file mode 100644 index b26de8e018..0000000000 --- a/x/provider/client/cli/test_helpers.go +++ /dev/null @@ -1,53 +0,0 @@ -package cli - -import ( - "fmt" - - "github.com/cosmos/cosmos-sdk/client" - sdktest "github.com/cosmos/cosmos-sdk/testutil" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" -) - -const key string = types.StoreKey - -// TxCreateProviderExec is used for testing create provider tx -func TxCreateProviderExec(clientCtx client.Context, from fmt.Stringer, filepath string, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--from=%s", from.String()), - filepath, - } - - args = append(args, extraArgs...) - - return clitestutil.ExecTestCLICmd(clientCtx, cmdCreate(key), args) -} - -// TxUpdateProviderExec is used for testing update provider tx -func TxUpdateProviderExec(clientCtx client.Context, from fmt.Stringer, filepath string, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - fmt.Sprintf("--from=%s", from.String()), - filepath, - } - - args = append(args, extraArgs...) - - return clitestutil.ExecTestCLICmd(clientCtx, cmdUpdate(key), args) -} - -// QueryProvidersExec is used for testing providers query -func QueryProvidersExec(clientCtx client.Context, args ...string) (sdktest.BufferWriter, error) { - return clitestutil.ExecTestCLICmd(clientCtx, cmdGetProviders(), args) -} - -// QueryProviderExec is used for testing provider query -func QueryProviderExec(clientCtx client.Context, owner string, extraArgs ...string) (sdktest.BufferWriter, error) { - args := []string{ - owner, - } - - args = append(args, extraArgs...) - - return clitestutil.ExecTestCLICmd(clientCtx, cmdGetProvider(), args) -} diff --git a/x/provider/client/cli/tx.go b/x/provider/client/cli/tx.go deleted file mode 100644 index d1a327d1ab..0000000000 --- a/x/provider/client/cli/tx.go +++ /dev/null @@ -1,139 +0,0 @@ -package cli - -import ( - "fmt" - - cltypes "github.com/akash-network/akash-api/go/node/client/types" - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/spf13/cobra" - - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" - - aclient "github.com/akash-network/node/client" - "github.com/akash-network/node/x/provider/config" -) - -// GetTxCmd returns the transaction commands for provider module -func GetTxCmd(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: types.ModuleName, - Short: "Provider transaction subcommands", - SuggestionsMinimumDistance: 2, - RunE: sdkclient.ValidateCmd, - } - cmd.AddCommand( - cmdCreate(key), - cmdUpdate(key), - ) - return cmd -} - -func cmdCreate(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: "create [config-file]", - Short: fmt.Sprintf("Create a %s", key), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - // TODO: enable reading files with non-local URIs - cfg, err := config.ReadConfigPath(args[0]) - if err != nil { - err = fmt.Errorf("%w: ReadConfigPath err: %q", err, args[0]) - return err - } - - msg := &types.MsgCreateProvider{ - Owner: cctx.GetFromAddress().String(), - HostURI: cfg.Host, - Info: cfg.Info, - Attributes: cfg.GetAttributes(), - } - - if err := msg.ValidateBasic(); err != nil { - return err - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - - return cmd -} - -func cmdUpdate(key string) *cobra.Command { - cmd := &cobra.Command{ - Use: "update [config-file]", - Short: fmt.Sprintf("Update %s", key), - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := cmd.Context() - - cctx, err := sdkclient.GetClientTxContext(cmd) - if err != nil { - return err - } - - opts, err := cltypes.ClientOptionsFromFlags(cmd.Flags()) - if err != nil { - return err - } - - cl, err := aclient.DiscoverClient(ctx, cctx, opts...) - if err != nil { - return err - } - - cfg, err := config.ReadConfigPath(args[0]) - if err != nil { - return err - } - - msg := &types.MsgUpdateProvider{ - Owner: cctx.GetFromAddress().String(), - HostURI: cfg.Host, - Info: cfg.Info, - Attributes: cfg.GetAttributes(), - } - - if err := msg.ValidateBasic(); err != nil { - return err - } - - resp, err := cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) - if err != nil { - return err - } - - return cl.PrintMessage(resp) - }, - } - - flags.AddTxFlagsToCmd(cmd) - - return cmd -} diff --git a/x/provider/client/rest/rest.go b/x/provider/client/rest/rest.go index e6cbc185ac..5acfa353fb 100644 --- a/x/provider/client/rest/rest.go +++ b/x/provider/client/rest/rest.go @@ -4,10 +4,7 @@ import ( "fmt" "net/http" - "github.com/akash-network/node/x/provider/query" "github.com/cosmos/cosmos-sdk/client" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/rest" "github.com/gorilla/mux" ) @@ -20,31 +17,31 @@ func RegisterRoutes(ctx client.Context, r *mux.Router, ns string) { r.HandleFunc(fmt.Sprintf("/%s/info/{providerOwner}", ns), getProviderHandler(ctx, ns)).Methods("GET") } -func listProvidersHandler(ctx client.Context, ns string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - res, err := query.NewRawClient(ctx, ns).Providers() - if err != nil { - rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") - return - } - rest.PostProcessResponse(w, ctx, res) +func listProvidersHandler(_ client.Context, _ string) http.HandlerFunc { + return func(_ http.ResponseWriter, _ *http.Request) { + // res, err := query.NewRawClient(ctx, ns).Providers() + // if err != nil { + // rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") + // return + // } + // rest.PostProcessResponse(w, ctx, res) } } -func getProviderHandler(ctx client.Context, ns string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - bech32Addr := mux.Vars(r)["providerOwner"] - - id, err := sdk.AccAddressFromBech32(bech32Addr) - if err != nil { - rest.WriteErrorResponse(w, http.StatusBadRequest, "Invalid address") - return - } - res, err := query.NewRawClient(ctx, ns).Provider(id) - if err != nil { - rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") - return - } - rest.PostProcessResponse(w, ctx, res) +func getProviderHandler(_ client.Context, _ string) http.HandlerFunc { + return func(_ http.ResponseWriter, _ *http.Request) { + // bech32Addr := mux.Vars(r)["providerOwner"] + // + // id, err := sdk.AccAddressFromBech32(bech32Addr) + // if err != nil { + // rest.WriteErrorResponse(w, http.StatusBadRequest, "Invalid address") + // return + // } + // res, err := query.NewRawClient(ctx, ns).Provider(id) + // if err != nil { + // rest.WriteErrorResponse(w, http.StatusNotFound, "Not Found") + // return + // } + // rest.PostProcessResponse(w, ctx, res) } } diff --git a/x/provider/config/config.go b/x/provider/config/config.go index 97328c3ede..34fea4a1ea 100644 --- a/x/provider/config/config.go +++ b/x/provider/config/config.go @@ -7,9 +7,8 @@ import ( "gopkg.in/yaml.v3" - ptypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" - - types "github.com/akash-network/akash-api/go/node/types/v1beta3" + ptypes "pkg.akt.dev/go/node/provider/v1beta4" + tattr "pkg.akt.dev/go/node/types/attributes/v1" ) var ( @@ -18,19 +17,19 @@ var ( // Config is the struct that stores provider config type Config struct { - Host string `json:"host" yaml:"host"` - Info ptypes.ProviderInfo `json:"info" yaml:"info"` - Attributes types.Attributes `json:"attributes" yaml:"attributes"` + Host string `json:"host" yaml:"host"` + Info ptypes.Info `json:"info" yaml:"info"` + Attributes tattr.Attributes `json:"attributes" yaml:"attributes"` } // GetAttributes returns config attributes into key value pairs -func (c Config) GetAttributes() types.Attributes { +func (c Config) GetAttributes() tattr.Attributes { return c.Attributes } // ReadConfigPath reads and parses file func ReadConfigPath(path string) (Config, error) { - buf, err := os.ReadFile(path) + buf, err := os.ReadFile(path) //nolint: gosec if err != nil { return Config{}, err } diff --git a/x/provider/genesis.go b/x/provider/genesis.go index 5756c4c27c..3e1c7ac179 100644 --- a/x/provider/genesis.go +++ b/x/provider/genesis.go @@ -6,17 +6,17 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" + types "pkg.akt.dev/go/node/provider/v1beta4" - "github.com/akash-network/node/x/provider/keeper" + "pkg.akt.dev/node/x/provider/keeper" ) // ValidateGenesis does validation check of the Genesis and returns error in case of failure + func ValidateGenesis(data *types.GenesisState) error { for _, record := range data.Providers { - msg := types.MsgCreateProvider{ + msg := &types.MsgCreateProvider{ Owner: record.Owner, HostURI: record.HostURI, Attributes: record.Attributes, @@ -28,11 +28,12 @@ func ValidateGenesis(data *types.GenesisState) error { } } + return nil } // InitGenesis initiate genesis state and return updated validator details -func InitGenesis(ctx sdk.Context, kpr keeper.IKeeper, data *types.GenesisState) []abci.ValidatorUpdate { +func InitGenesis(ctx sdk.Context, kpr keeper.IKeeper, data *types.GenesisState) { store := ctx.KVStore(kpr.StoreKey()) cdc := kpr.Codec() @@ -50,8 +51,6 @@ func InitGenesis(ctx sdk.Context, kpr keeper.IKeeper, data *types.GenesisState) store.Set(key, cdc.MustMarshal(&record)) } - - return []abci.ValidatorUpdate{} } // ExportGenesis returns genesis state as raw bytes for the provider module diff --git a/x/provider/handler/handler.go b/x/provider/handler/handler.go index a9d97e16b5..4d2e742c0f 100644 --- a/x/provider/handler/handler.go +++ b/x/provider/handler/handler.go @@ -1,35 +1,36 @@ package handler import ( + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" + types "pkg.akt.dev/go/node/provider/v1beta4" - mkeeper "github.com/akash-network/node/x/market/keeper" - "github.com/akash-network/node/x/provider/keeper" + mkeeper "pkg.akt.dev/node/x/market/keeper" + "pkg.akt.dev/node/x/provider/keeper" ) // NewHandler returns a handler for "provider" type messages. -func NewHandler(keeper keeper.IKeeper, mkeeper mkeeper.IKeeper) sdk.Handler { +func NewHandler(keeper keeper.IKeeper, mkeeper mkeeper.IKeeper) baseapp.MsgServiceHandler { ms := NewMsgServerImpl(keeper, mkeeper) return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { switch msg := msg.(type) { case *types.MsgCreateProvider: - res, err := ms.CreateProvider(sdk.WrapSDKContext(ctx), msg) + res, err := ms.CreateProvider(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) case *types.MsgUpdateProvider: - res, err := ms.UpdateProvider(sdk.WrapSDKContext(ctx), msg) + res, err := ms.UpdateProvider(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) case *types.MsgDeleteProvider: - res, err := ms.DeleteProvider(sdk.WrapSDKContext(ctx), msg) + res, err := ms.DeleteProvider(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) default: - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized bank message type: %T", msg) + return nil, sdkerrors.ErrUnknownRequest.Wrapf("unrecognized bank message type: %T", msg) } } } diff --git a/x/provider/handler/handler_test.go b/x/provider/handler/handler_test.go index b7d65e8ddd..bd13daff5c 100644 --- a/x/provider/handler/handler_test.go +++ b/x/provider/handler/handler_test.go @@ -4,20 +4,21 @@ import ( "errors" "testing" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/baseapp" sdktestdata "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/stretchr/testify/require" - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" + types "pkg.akt.dev/go/node/provider/v1beta4" + akashtypes "pkg.akt.dev/go/node/types/attributes/v1" + "pkg.akt.dev/go/testutil" - akashtypes "github.com/akash-network/akash-api/go/node/types/v1beta3" - - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/testutil/state" - mkeeper "github.com/akash-network/node/x/market/keeper" - "github.com/akash-network/node/x/provider/handler" - "github.com/akash-network/node/x/provider/keeper" + "pkg.akt.dev/node/testutil/state" + mkeeper "pkg.akt.dev/node/x/market/keeper" + "pkg.akt.dev/node/x/provider/handler" + "pkg.akt.dev/node/x/provider/keeper" ) const ( @@ -29,7 +30,7 @@ type testSuite struct { ctx sdk.Context keeper keeper.IKeeper mkeeper mkeeper.IKeeper - handler sdk.Handler + handler baseapp.MsgServiceHandler } func setupTestSuite(t *testing.T) *testSuite { @@ -67,13 +68,14 @@ func TestProviderCreate(t *testing.T) { require.NoError(t, err) t.Run("ensure event created", func(t *testing.T) { + ev, err := sdk.ParseTypedEvent(res.Events[0]) + require.NoError(t, err) - iev := testutil.ParseProviderEvent(t, res.Events) - require.IsType(t, types.EventProviderCreated{}, iev) + require.IsType(t, &types.EventProviderCreated{}, ev) - dev := iev.(types.EventProviderCreated) + dev := ev.(*types.EventProviderCreated) - require.Equal(t, msg.Owner, dev.Owner.String()) + require.Equal(t, msg.Owner, dev.Owner) }) res, err = suite.handler(suite.ctx, msg) @@ -88,7 +90,7 @@ func TestProviderCreateWithInfo(t *testing.T) { msg := &types.MsgCreateProvider{ Owner: testutil.AccAddress(t).String(), HostURI: testutil.ProviderHostname(t), - Info: types.ProviderInfo{ + Info: types.Info{ EMail: emailValid, Website: testutil.Hostname(t), }, @@ -99,13 +101,14 @@ func TestProviderCreateWithInfo(t *testing.T) { require.NoError(t, err) t.Run("ensure event created", func(t *testing.T) { + ev, err := sdk.ParseTypedEvent(res.Events[0]) + require.NoError(t, err) - iev := testutil.ParseProviderEvent(t, res.Events) - require.IsType(t, types.EventProviderCreated{}, iev) + require.IsType(t, &types.EventProviderCreated{}, ev) - dev := iev.(types.EventProviderCreated) + dev := ev.(*types.EventProviderCreated) - require.Equal(t, msg.Owner, dev.Owner.String()) + require.Equal(t, msg.Owner, dev.Owner) }) res, err = suite.handler(suite.ctx, msg) @@ -178,12 +181,14 @@ func TestProviderUpdateExisting(t *testing.T) { res, err := suite.handler(suite.ctx, updateMsg) t.Run("ensure event created", func(t *testing.T) { - iev := testutil.ParseProviderEvent(t, res.Events[1:]) - require.IsType(t, types.EventProviderUpdated{}, iev) + ev, err := sdk.ParseTypedEvent(res.Events[1]) + require.NoError(t, err) + + require.IsType(t, &types.EventProviderUpdated{}, ev) - dev := iev.(types.EventProviderUpdated) + dev := ev.(*types.EventProviderUpdated) - require.Equal(t, updateMsg.Owner, dev.Owner.String()) + require.Equal(t, updateMsg.Owner, dev.Owner) }) require.NoError(t, err) @@ -251,7 +256,7 @@ func TestProviderDeleteExisting(t *testing.T) { require.EqualError(t, err, "NOTIMPLEMENTED: "+handler.ErrInternal.Error()) require.True(t, errors.Is(err, handler.ErrInternal)) - t.Run("ensure event created", func(t *testing.T) { + t.Run("ensure event created", func(_ *testing.T) { // TODO: this should emit a ProviderDelete }) } diff --git a/x/provider/handler/server.go b/x/provider/handler/server.go index 21cd71fe06..d353df7fd2 100644 --- a/x/provider/handler/server.go +++ b/x/provider/handler/server.go @@ -2,20 +2,19 @@ package handler import ( "context" - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" + sdk "github.com/cosmos/cosmos-sdk/types" + types "pkg.akt.dev/go/node/provider/v1beta4" - mkeeper "github.com/akash-network/node/x/market/keeper" - "github.com/akash-network/node/x/provider/keeper" + mkeeper "pkg.akt.dev/node/x/market/keeper" + "pkg.akt.dev/node/x/provider/keeper" ) var ( // ErrInternal defines registered error code for internal error - ErrInternal = sdkerrors.Register(types.ModuleName, 10, "internal error") + ErrInternal = errorsmod.Register(types.ModuleName, 10, "internal error") ) type msgServer struct { @@ -41,11 +40,11 @@ func (ms msgServer) CreateProvider(goCtx context.Context, msg *types.MsgCreatePr owner, _ := sdk.AccAddressFromBech32(msg.Owner) if _, ok := ms.provider.Get(ctx, owner); ok { - return nil, fmt.Errorf("%w: id: %s", types.ErrProviderExists, msg.Owner) + return nil, types.ErrProviderExists.Wrapf("id: %s", msg.Owner) } if err := ms.provider.Create(ctx, types.Provider(*msg)); err != nil { - return nil, sdkerrors.Wrapf(ErrInternal, "err: %v", err) + return nil, ErrInternal.Wrapf("err: %v", err) } return &types.MsgCreateProviderResponse{}, nil @@ -62,11 +61,11 @@ func (ms msgServer) UpdateProvider(goCtx context.Context, msg *types.MsgUpdatePr owner, _ := sdk.AccAddressFromBech32(msg.Owner) _, found := ms.provider.Get(ctx, owner) if !found { - return nil, fmt.Errorf("%w: id: %s", types.ErrProviderNotFound, msg.Owner) + return nil, types.ErrProviderNotFound.Wrapf("id: %s", msg.Owner) } if err := ms.provider.Update(ctx, types.Provider(*msg)); err != nil { - return nil, sdkerrors.Wrapf(ErrInternal, "err: %v", err) + return nil, errorsmod.Wrapf(ErrInternal, "err: %v", err) } return &types.MsgUpdateProviderResponse{}, nil @@ -85,5 +84,5 @@ func (ms msgServer) DeleteProvider(goCtx context.Context, msg *types.MsgDeletePr } // TODO: cancel leases - return nil, sdkerrors.Wrapf(ErrInternal, "NOTIMPLEMENTED") + return nil, ErrInternal.Wrap("NOTIMPLEMENTED") } diff --git a/x/provider/keeper/grpc_query.go b/x/provider/keeper/grpc_query.go index cd4825e1f4..75238c1c76 100644 --- a/x/provider/keeper/grpc_query.go +++ b/x/provider/keeper/grpc_query.go @@ -9,7 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkquery "github.com/cosmos/cosmos-sdk/types/query" - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" + types "pkg.akt.dev/go/node/provider/v1beta4" ) // Querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over keeper @@ -30,7 +30,7 @@ func (k Querier) Providers(c context.Context, req *types.QueryProvidersRequest) store := ctx.KVStore(k.skey) - pageRes, err := sdkquery.Paginate(store, req.Pagination, func(key []byte, value []byte) error { + pageRes, err := sdkquery.Paginate(store, req.Pagination, func(_ []byte, value []byte) error { var provider types.Provider err := k.cdc.Unmarshal(value, &provider) diff --git a/x/provider/keeper/grpc_query_test.go b/x/provider/keeper/grpc_query_test.go index 617e1fac0c..06891f9c16 100644 --- a/x/provider/keeper/grpc_query_test.go +++ b/x/provider/keeper/grpc_query_test.go @@ -10,12 +10,12 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkquery "github.com/cosmos/cosmos-sdk/types/query" - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" + types "pkg.akt.dev/go/node/provider/v1beta4" + "pkg.akt.dev/go/testutil" - "github.com/akash-network/node/app" - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/testutil/state" - "github.com/akash-network/node/x/provider/keeper" + "pkg.akt.dev/node/app" + "pkg.akt.dev/node/testutil/state" + "pkg.akt.dev/node/x/provider/keeper" ) type grpcTestSuite struct { @@ -89,7 +89,7 @@ func TestGRPCQueryProvider(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { tc.malleate() - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx res, err := suite.queryClient.Provider(ctx, req) @@ -144,7 +144,7 @@ func TestGRPCQueryProviders(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.msg), func(t *testing.T) { tc.malleate() - ctx := sdk.WrapSDKContext(suite.ctx) + ctx := suite.ctx res, err := suite.queryClient.Providers(ctx, req) diff --git a/x/provider/keeper/keeper.go b/x/provider/keeper/keeper.go index 9a25bfa81c..79d03e70af 100644 --- a/x/provider/keeper/keeper.go +++ b/x/provider/keeper/keeper.go @@ -1,15 +1,17 @@ package keeper import ( + "cosmossdk.io/store/prefix" + storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" + types "pkg.akt.dev/go/node/provider/v1beta4" ) type IKeeper interface { Codec() codec.BinaryCodec - StoreKey() sdk.StoreKey + StoreKey() storetypes.StoreKey Get(ctx sdk.Context, id sdk.Address) (types.Provider, bool) Create(ctx sdk.Context, provider types.Provider) error WithProviders(ctx sdk.Context, fn func(types.Provider) bool) @@ -20,12 +22,12 @@ type IKeeper interface { // Keeper of the provider store type Keeper struct { - skey sdk.StoreKey + skey storetypes.StoreKey cdc codec.BinaryCodec } // NewKeeper creates and returns an instance for Provider keeper -func NewKeeper(cdc codec.BinaryCodec, skey sdk.StoreKey) IKeeper { +func NewKeeper(cdc codec.BinaryCodec, skey storetypes.StoreKey) IKeeper { return Keeper{ skey: skey, cdc: cdc, @@ -42,7 +44,7 @@ func (k Keeper) Codec() codec.BinaryCodec { } // StoreKey returns store key -func (k Keeper) StoreKey() sdk.StoreKey { +func (k Keeper) StoreKey() storetypes.StoreKey { return k.skey } @@ -77,18 +79,27 @@ func (k Keeper) Create(ctx sdk.Context, provider types.Provider) error { store.Set(key, k.cdc.MustMarshal(&provider)) - ctx.EventManager().EmitEvent( - types.EventProviderCreated{Owner: owner}.ToSDKEvent(), + err = ctx.EventManager().EmitTypedEvent( + &types.EventProviderCreated{ + Owner: owner.String(), + }, ) + if err != nil { + return err + } + return nil } // WithProviders iterates all providers func (k Keeper) WithProviders(ctx sdk.Context, fn func(types.Provider) bool) { - store := ctx.KVStore(k.skey) + store := prefix.NewStore(ctx.KVStore(k.skey), types.ProviderPrefix()) + iter := store.Iterator(nil, nil) - defer iter.Close() + defer func() { + _ = iter.Close() + }() for ; iter.Valid(); iter.Next() { var val types.Provider k.cdc.MustUnmarshal(iter.Value(), &val) @@ -113,14 +124,20 @@ func (k Keeper) Update(ctx sdk.Context, provider types.Provider) error { } store.Set(key, k.cdc.MustMarshal(&provider)) - ctx.EventManager().EmitEvent( - types.EventProviderUpdated{Owner: owner}.ToSDKEvent(), + err = ctx.EventManager().EmitTypedEvent( + &types.EventProviderUpdated{ + Owner: owner.String(), + }, ) + if err != nil { + return err + } + return nil } // Delete delete a provider -func (k Keeper) Delete(ctx sdk.Context, id sdk.Address) { +func (k Keeper) Delete(_ sdk.Context, _ sdk.Address) { panic("TODO") } diff --git a/x/provider/keeper/keeper_test.go b/x/provider/keeper/keeper_test.go index 57ba051c94..a65852bfaf 100644 --- a/x/provider/keeper/keeper_test.go +++ b/x/provider/keeper/keeper_test.go @@ -7,11 +7,11 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" + types "pkg.akt.dev/go/node/provider/v1beta4" + "pkg.akt.dev/go/testutil" - "github.com/akash-network/node/testutil" - "github.com/akash-network/node/testutil/state" - "github.com/akash-network/node/x/provider/keeper" + "pkg.akt.dev/node/testutil/state" + "pkg.akt.dev/node/x/provider/keeper" ) func TestProviderCreate(t *testing.T) { diff --git a/x/provider/keeper/key.go b/x/provider/keeper/key.go index 04a87a4ea3..4333843d4d 100644 --- a/x/provider/keeper/key.go +++ b/x/provider/keeper/key.go @@ -1,10 +1,16 @@ package keeper import ( + "bytes" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" + types "pkg.akt.dev/go/node/provider/v1beta4" ) func ProviderKey(id sdk.Address) []byte { - return address.MustLengthPrefix(id.Bytes()) + buf := bytes.NewBuffer(types.ProviderPrefix()) + buf.Write(address.MustLengthPrefix(id.Bytes())) + + return buf.Bytes() } diff --git a/x/provider/module.go b/x/provider/module.go index bd28bd7c88..4123e310c1 100644 --- a/x/provider/module.go +++ b/x/provider/module.go @@ -4,39 +4,39 @@ import ( "context" "encoding/json" "fmt" - "math/rand" - "github.com/gorilla/mux" + "cosmossdk.io/core/appmodule" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - sim "github.com/cosmos/cosmos-sdk/types/simulation" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - v1beta1types "github.com/akash-network/akash-api/go/node/provider/v1beta1" - v1beta2types "github.com/akash-network/akash-api/go/node/provider/v1beta2" - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" + types "pkg.akt.dev/go/node/provider/v1beta4" - mkeeper "github.com/akash-network/node/x/market/keeper" - "github.com/akash-network/node/x/provider/client/cli" - "github.com/akash-network/node/x/provider/client/rest" - "github.com/akash-network/node/x/provider/handler" - "github.com/akash-network/node/x/provider/keeper" - "github.com/akash-network/node/x/provider/simulation" + mkeeper "pkg.akt.dev/node/x/market/keeper" + "pkg.akt.dev/node/x/provider/handler" + "pkg.akt.dev/node/x/provider/keeper" + "pkg.akt.dev/node/x/provider/simulation" ) +// type check to ensure the interface is properly implemented var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} - _ module.AppModuleSimulation = AppModuleSimulation{} + _ module.AppModuleBasic = AppModuleBasic{} + _ module.HasGenesisBasics = AppModuleBasic{} + + _ appmodule.AppModule = AppModule{} + _ module.HasConsensusVersion = AppModule{} + _ module.HasGenesis = AppModule{} + _ module.HasServices = AppModule{} + + _ module.AppModuleSimulation = AppModule{} ) // AppModuleBasic defines the basic application module used by the provider module. @@ -44,6 +44,16 @@ type AppModuleBasic struct { cdc codec.Codec } +// AppModule implements an application module for the provider module. +type AppModule struct { + AppModuleBasic + + keeper keeper.IKeeper + acckeeper govtypes.AccountKeeper + bkeeper bankkeeper.Keeper + mkeeper mkeeper.IKeeper +} + // Name returns provider module's name func (AppModuleBasic) Name() string { return types.ModuleName @@ -51,14 +61,12 @@ func (AppModuleBasic) Name() string { // RegisterLegacyAminoCodec registers the provider module's types for the given codec. func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { - types.RegisterLegacyAminoCodec(cdc) + types.RegisterLegacyAminoCodec(cdc) // nolint staticcheck } // RegisterInterfaces registers the module's interface types func (b AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) { types.RegisterInterfaces(registry) - v1beta2types.RegisterInterfaces(registry) - v1beta1types.RegisterInterfaces(registry) } // DefaultGenesis returns default genesis state as raw bytes for the provider @@ -68,7 +76,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { } // ValidateGenesis validation check of the Genesis -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { var data types.GenesisState err := cdc.UnmarshalJSON(bz, &data) if err != nil { @@ -77,11 +85,6 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncod return ValidateGenesis(&data) } -// RegisterRESTRoutes registers rest routes for this module -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { - rest.RegisterRoutes(clientCtx, rtr, StoreKey) -} - // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the provider module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) @@ -92,33 +95,26 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *r // GetQueryCmd returns the root query command of this module func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.GetQueryCmd() + panic("akash modules do not export cli commands via cosmos interface") } // GetTxCmd returns the transaction commands for this module func (AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.GetTxCmd(StoreKey) -} - -// GetQueryClient returns a new query client for this module -func (AppModuleBasic) GetQueryClient(clientCtx client.Context) types.QueryClient { - return types.NewQueryClient(clientCtx) -} - -// AppModule implements an application module for the provider module. -type AppModule struct { - AppModuleBasic - keeper keeper.IKeeper - bkeeper bankkeeper.Keeper - mkeeper mkeeper.IKeeper + panic("akash modules do not export cli commands via cosmos interface") } // NewAppModule creates a new AppModule object -func NewAppModule(cdc codec.Codec, k keeper.IKeeper, bkeeper bankkeeper.Keeper, - mkeeper mkeeper.IKeeper) AppModule { +func NewAppModule( + cdc codec.Codec, + k keeper.IKeeper, + acckeeper govtypes.AccountKeeper, + bkeeper bankkeeper.Keeper, + mkeeper mkeeper.IKeeper, +) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{cdc: cdc}, keeper: k, + acckeeper: acckeeper, bkeeper: bkeeper, mkeeper: mkeeper, } @@ -129,23 +125,11 @@ func (AppModule) Name() string { return types.ModuleName } -// RegisterInvariants registers module invariants -func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (am AppModule) IsOnePerModuleType() {} -// Route returns the message routing key for the provider module. -func (am AppModule) Route() sdk.Route { - return sdk.NewRoute(types.RouterKey, handler.NewHandler(am.keeper, am.mkeeper)) -} - -// QuerierRoute returns the provider module's querier route name. -func (am AppModule) QuerierRoute() string { - return "" -} - -// LegacyQuerierHandler returns the sdk.Querier for provider module -func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { - return nil -} +// IsAppModule implements the appmodule.AppModule interface. +func (am AppModule) IsAppModule() {} // RegisterServices registers the module's services func (am AppModule) RegisterServices(cfg module.Configurator) { @@ -155,20 +139,22 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { } // BeginBlock performs no-op -func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} +func (am AppModule) BeginBlock(_ context.Context) error { + return nil +} -// EndBlock returns the end blocker for the provider module. It returns no validator +// EndBlock returns the end blocker for the deployment module. It returns no validator // updates. -func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - return []abci.ValidatorUpdate{} +func (am AppModule) EndBlock(_ context.Context) error { + return nil } // InitGenesis performs genesis initialization for the provider module. It returns // no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) { var genesisState types.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) - return InitGenesis(ctx, am.keeper, &genesisState) + InitGenesis(ctx, am.keeper, &genesisState) } // ExportGenesis returns the exported genesis state as raw bytes for the provider @@ -180,51 +166,25 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw // ConsensusVersion implements module.AppModule#ConsensusVersion func (am AppModule) ConsensusVersion() uint64 { - return 2 -} - -// ____________________________________________________________________________ - -// AppModuleSimulation implements an application simulation module for the provider module. -type AppModuleSimulation struct { - keeper keeper.IKeeper - akeeper govtypes.AccountKeeper - bkeeper bankkeeper.Keeper -} - -// NewAppModuleSimulation creates a new AppModuleSimulation instance -func NewAppModuleSimulation(k keeper.IKeeper, akeeper govtypes.AccountKeeper, bkeeper bankkeeper.Keeper) AppModuleSimulation { - return AppModuleSimulation{ - keeper: k, - akeeper: akeeper, - bkeeper: bkeeper, - } + return 3 } // AppModuleSimulation functions // GenerateGenesisState creates a randomized GenState of the staking module. -func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) { +func (AppModule) GenerateGenesisState(simState *module.SimulationState) { simulation.RandomizedGenState(simState) } -// ProposalContents doesn't return any content functions for governance proposals. -func (AppModuleSimulation) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent { +// ProposalMsgs returns msgs used for governance proposals for simulations. +func (AppModule) ProposalMsgs(_ module.SimulationState) []simtypes.WeightedProposalMsg { return nil } -// RandomizedParams creates randomized staking param changes for the simulator. -func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange { - return nil -} - -// RegisterStoreDecoder registers a decoder for staking module's types -func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { - // sdr[StoreKey] = simulation.DecodeStore -} +// RegisterStoreDecoder registers a decoder for take module's types. +func (am AppModule) RegisterStoreDecoder(_ simtypes.StoreDecoderRegistry) {} -// WeightedOperations returns the all the staking module operations with their respective weights. -func (am AppModuleSimulation) WeightedOperations(simState module.SimulationState) []sim.WeightedOperation { - return simulation.WeightedOperations(simState.AppParams, simState.Cdc, - am.akeeper, am.bkeeper, am.keeper) +// WeightedOperations doesn't return any mint module operation. +func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { + return simulation.WeightedOperations(simState.AppParams, simState.Cdc, am.acckeeper, am.bkeeper, am.keeper) } diff --git a/x/provider/query/types.go b/x/provider/query/types.go index e4331cc4e6..6a5a7be594 100644 --- a/x/provider/query/types.go +++ b/x/provider/query/types.go @@ -6,7 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" + types "pkg.akt.dev/go/node/provider/v1beta4" ) type ( diff --git a/x/provider/simulation/genesis.go b/x/provider/simulation/genesis.go index 705e14eb65..7a466746b4 100644 --- a/x/provider/simulation/genesis.go +++ b/x/provider/simulation/genesis.go @@ -3,7 +3,7 @@ package simulation import ( "github.com/cosmos/cosmos-sdk/types/module" - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" + types "pkg.akt.dev/go/node/provider/v1beta4" ) // RandomizedGenState generates a random GenesisState for supply diff --git a/x/provider/simulation/operations.go b/x/provider/simulation/operations.go index de6c66fd7a..7eb0286518 100644 --- a/x/provider/simulation/operations.go +++ b/x/provider/simulation/operations.go @@ -4,22 +4,25 @@ import ( "fmt" "math/rand" + cerrors "cosmossdk.io/errors" + "pkg.akt.dev/go/sdkutil" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/simapp/helpers" - simappparams "github.com/cosmos/cosmos-sdk/simapp/params" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/cosmos-sdk/x/simulation" - types "github.com/akash-network/akash-api/go/node/provider/v1beta3" + types "pkg.akt.dev/go/node/provider/v1beta4" - appparams "github.com/akash-network/node/app/params" - testsim "github.com/akash-network/node/testutil/sim" - "github.com/akash-network/node/x/provider/config" - "github.com/akash-network/node/x/provider/keeper" + appparams "pkg.akt.dev/node/app/params" + testsim "pkg.akt.dev/node/testutil/sim" + "pkg.akt.dev/node/x/provider/config" + "pkg.akt.dev/node/x/provider/keeper" ) // Simulation operation weights constants @@ -30,21 +33,25 @@ const ( // WeightedOperations returns all the operations from the module with their respective weights func WeightedOperations( - appParams simtypes.AppParams, cdc codec.JSONCodec, ak govtypes.AccountKeeper, - bk bankkeeper.Keeper, k keeper.IKeeper) simulation.WeightedOperations { + appParams simtypes.AppParams, + _ codec.JSONCodec, + ak govtypes.AccountKeeper, + bk bankkeeper.Keeper, + k keeper.IKeeper, +) simulation.WeightedOperations { var ( weightMsgCreate int weightMsgUpdate int ) appParams.GetOrGenerate( - cdc, OpWeightMsgCreate, &weightMsgCreate, nil, func(r *rand.Rand) { + OpWeightMsgCreate, &weightMsgCreate, nil, func(_ *rand.Rand) { weightMsgCreate = appparams.DefaultWeightMsgCreateProvider }, ) appParams.GetOrGenerate( - cdc, OpWeightMsgUpdate, &weightMsgUpdate, nil, func(r *rand.Rand) { + OpWeightMsgUpdate, &weightMsgUpdate, nil, func(_ *rand.Rand) { weightMsgUpdate = appparams.DefaultWeightMsgUpdateProvider }, ) @@ -71,46 +78,20 @@ func SimulateMsgCreate(ak govtypes.AccountKeeper, bk bankkeeper.Keeper, k keeper // ensure the provider doesn't exist already _, found := k.Get(ctx, simAccount.Address) if found { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateProvider, "provider already exists"), nil, nil + return simtypes.NoOpMsg(types.ModuleName, (&types.MsgCreateProvider{}).Type(), "provider already exists"), nil, nil } cfg, readError := config.ReadConfigPath("../x/provider/testdata/provider.yaml") if readError != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateProvider, "unable to read config file"), nil, readError + return simtypes.NoOpMsg(types.ModuleName, (&types.MsgCreateProvider{}).Type(), "unable to read config file"), nil, readError } account := ak.GetAccount(ctx, simAccount.Address) spendable := bk.SpendableCoins(ctx, account.GetAddress()) - fees, err := simtypes.RandomFees(r, ctx, spendable) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeCreateProvider, "unable to generate fees"), nil, err - } - msg := types.NewMsgCreateProvider(simAccount.Address, cfg.Host, cfg.GetAttributes()) - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - simAccount.PrivKey, - ) - - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err - } - - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver mock tx"), nil, err - } - - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + return deliverMockTx(r, app, ctx, msg, account, spendable, chainID, simAccount.PrivKey) } } @@ -128,7 +109,7 @@ func SimulateMsgUpdate(ak govtypes.AccountKeeper, bk bankkeeper.Keeper, k keeper }) if len(providers) == 0 { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeUpdateProvider, "no providers found"), nil, nil + return simtypes.NoOpMsg(types.ModuleName, (&types.MsgUpdateProvider{}).Type(), "no providers found"), nil, nil } // Get random deployment @@ -136,50 +117,73 @@ func SimulateMsgUpdate(ak govtypes.AccountKeeper, bk bankkeeper.Keeper, k keeper owner, convertErr := sdk.AccAddressFromBech32(provider.Owner) if convertErr != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeUpdateProvider, "error while converting address"), + return simtypes.NoOpMsg(types.ModuleName, (&types.MsgUpdateProvider{}).Type(), "error while converting address"), nil, convertErr } simAccount, found := simtypes.FindAccount(accounts, owner) if !found { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeUpdateProvider, "provider not found"), + return simtypes.NoOpMsg(types.ModuleName, (&types.MsgUpdateProvider{}).Type(), "provider not found"), nil, fmt.Errorf("provider with %s not found", provider.Owner) } account := ak.GetAccount(ctx, simAccount.Address) spendable := bk.SpendableCoins(ctx, account.GetAddress()) - fees, err := simtypes.RandomFees(r, ctx, spendable) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, types.MsgTypeUpdateProvider, "unable to generate fees"), nil, err - } - msg := &types.MsgUpdateProvider{ Owner: simAccount.Address.String(), HostURI: provider.HostURI, } - txGen := simappparams.MakeTestEncodingConfig().TxConfig - tx, err := helpers.GenTx( - txGen, - []sdk.Msg{msg}, - fees, - helpers.DefaultGenTxGas, - chainID, - []uint64{account.GetAccountNumber()}, - []uint64{account.GetSequence()}, - simAccount.PrivKey, - ) - - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err - } + return deliverMockTx(r, app, ctx, msg, account, spendable, chainID, simAccount.PrivKey) + } +} - _, _, err = app.Deliver(txGen.TxEncoder(), tx) - if err != nil { - return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver mock tx"), nil, err - } +type typer interface { + Type() string +} + +func deliverMockTx( + r *rand.Rand, + app *baseapp.BaseApp, + sdkctx sdk.Context, + msg sdk.Msg, + acc sdk.AccountI, + spendable sdk.Coins, + chainID string, + privKey cryptotypes.PrivKey, +) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + mtype, valid := msg.(typer) + if !valid { + return simtypes.NoOpMsg(types.ModuleName, "", "unable to determine message type. Does not implement Type interface"), nil, cerrors.ErrPanic + } - return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil + fees, err := simtypes.RandomFees(r, sdkctx, spendable) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, mtype.Type(), "unable to generate fees"), nil, err } + + txGen := sdkutil.MakeEncodingConfig().TxConfig + tx, err := simtestutil.GenSignedMockTx( + r, + txGen, + []sdk.Msg{msg}, + fees, + simtestutil.DefaultGenTxGas, + chainID, + []uint64{acc.GetAccountNumber()}, + []uint64{acc.GetSequence()}, + privKey, + ) + + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, mtype.Type(), "unable to generate mock tx"), nil, err + } + + _, _, err = app.SimDeliver(txGen.TxEncoder(), tx) + if err != nil { + return simtypes.NoOpMsg(types.ModuleName, mtype.Type(), "unable to deliver mock tx"), nil, err + } + + return simtypes.NewOperationMsg(msg, true, mtype.Type()), nil, nil } diff --git a/x/staking/alias.go b/x/staking/alias.go deleted file mode 100644 index bd338c800e..0000000000 --- a/x/staking/alias.go +++ /dev/null @@ -1,24 +0,0 @@ -package provider - -import ( - types "github.com/akash-network/akash-api/go/node/staking/v1beta3" - - "github.com/akash-network/node/x/staking/keeper" -) - -const ( - // StoreKey represents storekey of provider module - StoreKey = types.StoreKey - // ModuleName represents current module name - ModuleName = types.ModuleName -) - -type ( - // Keeper defines keeper of provider module - Keeper = keeper.Keeper -) - -var ( - // NewKeeper creates new keeper instance of provider module - NewKeeper = keeper.NewKeeper -) diff --git a/x/staking/genesis.go b/x/staking/genesis.go deleted file mode 100644 index ff8385b988..0000000000 --- a/x/staking/genesis.go +++ /dev/null @@ -1,39 +0,0 @@ -package provider - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" - - types "github.com/akash-network/akash-api/go/node/staking/v1beta3" - - "github.com/akash-network/node/x/staking/keeper" -) - -// ValidateGenesis does validation check of the Genesis and returns error in case of failure -func ValidateGenesis(data *types.GenesisState) error { - return data.Params.Validate() -} - -// DefaultGenesisState returns default genesis state as raw bytes for the provider -// module. -func DefaultGenesisState() *types.GenesisState { - return &types.GenesisState{ - Params: types.DefaultParams(), - } -} - -// InitGenesis initiate genesis state and return updated validator details -func InitGenesis(ctx sdk.Context, keeper keeper.IKeeper, data *types.GenesisState) []abci.ValidatorUpdate { - if err := keeper.SetParams(ctx, data.Params); err != nil { - panic(err) - } - - return []abci.ValidatorUpdate{} -} - -// ExportGenesis returns genesis state as raw bytes for the provider module -func ExportGenesis(ctx sdk.Context, k keeper.IKeeper) *types.GenesisState { - return &types.GenesisState{ - Params: k.GetParams(ctx), - } -} diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go deleted file mode 100644 index 5b2a5677f3..0000000000 --- a/x/staking/keeper/keeper.go +++ /dev/null @@ -1,65 +0,0 @@ -package keeper - -import ( - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - - types "github.com/akash-network/akash-api/go/node/staking/v1beta3" -) - -type IKeeper interface { - Codec() codec.BinaryCodec - StoreKey() sdk.StoreKey - SetParams(ctx sdk.Context, params types.Params) error - GetParams(ctx sdk.Context) (params types.Params) - MinCommissionRate(ctx sdk.Context) sdk.Dec -} - -// Keeper of the provider store -type Keeper struct { - skey sdk.StoreKey - cdc codec.BinaryCodec - pspace paramtypes.Subspace -} - -// NewKeeper creates and returns an instance for Provider keeper -func NewKeeper(cdc codec.BinaryCodec, skey sdk.StoreKey, pspace paramtypes.Subspace) IKeeper { - if !pspace.HasKeyTable() { - pspace = pspace.WithKeyTable(types.ParamKeyTable()) - } - - return Keeper{ - skey: skey, - cdc: cdc, - pspace: pspace, - } -} - -// Codec returns keeper codec -func (k Keeper) Codec() codec.BinaryCodec { - return k.cdc -} - -func (k Keeper) StoreKey() sdk.StoreKey { - return k.skey -} - -func (k Keeper) MinCommissionRate(ctx sdk.Context) sdk.Dec { - res := sdk.NewDec(0) - k.pspace.Get(ctx, types.KeyMinCommissionRate, &res) - return res -} - -// SetParams sets the deployment parameters to the paramspace. -func (k Keeper) SetParams(ctx sdk.Context, params types.Params) error { - k.pspace.SetParamSet(ctx, ¶ms) - return nil -} - -// GetParams returns the total set of deployment parameters. -func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { - return types.NewParams( - k.MinCommissionRate(ctx), - ) -} diff --git a/x/staking/module.go b/x/staking/module.go deleted file mode 100644 index 6058fe01a2..0000000000 --- a/x/staking/module.go +++ /dev/null @@ -1,194 +0,0 @@ -package provider - -import ( - "encoding/json" - "fmt" - "math/rand" - - "github.com/gorilla/mux" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" - - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - cdctypes "github.com/cosmos/cosmos-sdk/codec/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - sim "github.com/cosmos/cosmos-sdk/types/simulation" - - types "github.com/akash-network/akash-api/go/node/staking/v1beta3" - - "github.com/akash-network/node/x/staking/keeper" - "github.com/akash-network/node/x/staking/simulation" -) - -var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} - _ module.AppModuleSimulation = AppModuleSimulation{} -) - -// AppModuleBasic defines the basic application module used by the provider module. -type AppModuleBasic struct { - cdc codec.Codec -} - -// Name returns provider module's name -func (AppModuleBasic) Name() string { - return types.ModuleName -} - -// RegisterLegacyAminoCodec registers the provider module's types for the given codec. -func (AppModuleBasic) RegisterLegacyAminoCodec(_ *codec.LegacyAmino) { -} - -// RegisterInterfaces registers the module's interface types -func (b AppModuleBasic) RegisterInterfaces(_ cdctypes.InterfaceRegistry) { -} - -// DefaultGenesis returns default genesis state as raw bytes for the provider -// module. -func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { - return cdc.MustMarshalJSON(DefaultGenesisState()) -} - -// ValidateGenesis validation check of the Genesis -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { - var data types.GenesisState - err := cdc.UnmarshalJSON(bz, &data) - if err != nil { - return fmt.Errorf("failed to unmarshal %s genesis state: %v", types.ModuleName, err) - } - return ValidateGenesis(&data) -} - -// RegisterRESTRoutes registers rest routes for this module -func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) { -} - -// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the provider module. -func (AppModuleBasic) RegisterGRPCGatewayRoutes(_ client.Context, _ *runtime.ServeMux) { -} - -// GetQueryCmd returns the root query command of this module -func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return nil -} - -// GetTxCmd returns the transaction commands for this module -func (AppModuleBasic) GetTxCmd() *cobra.Command { - return nil -} - -// AppModule implements an application module for the provider module. -type AppModule struct { - AppModuleBasic - keeper keeper.IKeeper -} - -// NewAppModule creates a new AppModule object -func NewAppModule(cdc codec.Codec, k keeper.IKeeper) AppModule { - return AppModule{ - AppModuleBasic: AppModuleBasic{cdc: cdc}, - keeper: k, - } -} - -// Name returns the provider module name -func (AppModule) Name() string { - return types.ModuleName -} - -// RegisterInvariants registers module invariants -func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} - -// Route returns the message routing key for the provider module. -func (am AppModule) Route() sdk.Route { - return sdk.Route{} -} - -// QuerierRoute returns the provider module's querier route name. -func (am AppModule) QuerierRoute() string { - return "" -} - -// LegacyQuerierHandler returns the sdk.Querier for provider module -func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { - return nil -} - -// RegisterServices registers the module's services -func (am AppModule) RegisterServices(_ module.Configurator) { -} - -// BeginBlock performs no-op -func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} - -// EndBlock returns the end blocker for the provider module. It returns no validator -// updates. -func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - return []abci.ValidatorUpdate{} -} - -// InitGenesis performs genesis initialization for the provider module. It returns -// no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { - var genesisState types.GenesisState - cdc.MustUnmarshalJSON(data, &genesisState) - return InitGenesis(ctx, am.keeper, &genesisState) -} - -// ExportGenesis returns the exported genesis state as raw bytes for the provider -// module. -func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { - gs := ExportGenesis(ctx, am.keeper) - return cdc.MustMarshalJSON(gs) -} - -// ConsensusVersion implements module.AppModule#ConsensusVersion -func (am AppModule) ConsensusVersion() uint64 { - return 1 -} - -// ____________________________________________________________________________ - -// AppModuleSimulation implements an application simulation module for the provider module. -type AppModuleSimulation struct { - keeper keeper.IKeeper -} - -// NewAppModuleSimulation creates a new AppModuleSimulation instance -func NewAppModuleSimulation(k keeper.IKeeper) AppModuleSimulation { - return AppModuleSimulation{ - keeper: k, - } -} - -// AppModuleSimulation functions - -// GenerateGenesisState creates a randomized GenState of the staking module. -func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) { - simulation.RandomizedGenState(simState) -} - -// ProposalContents doesn't return any content functions for governance proposals. -func (AppModuleSimulation) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent { - return nil -} - -// RandomizedParams creates randomized staking param changes for the simulator. -func (AppModuleSimulation) RandomizedParams(_ *rand.Rand) []sim.ParamChange { - return nil -} - -// RegisterStoreDecoder registers a decoder for staking module's types -func (AppModuleSimulation) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) { - // sdr[StoreKey] = simulation.DecodeStore -} - -// WeightedOperations returns the all the staking module operations with their respective weights. -func (am AppModuleSimulation) WeightedOperations(simState module.SimulationState) []sim.WeightedOperation { - return simulation.WeightedOperations(simState.AppParams, simState.Cdc, am.keeper) -} diff --git a/x/staking/simulation/genesis.go b/x/staking/simulation/genesis.go deleted file mode 100644 index 214a7e2187..0000000000 --- a/x/staking/simulation/genesis.go +++ /dev/null @@ -1,14 +0,0 @@ -package simulation - -import ( - "github.com/cosmos/cosmos-sdk/types/module" - - types "github.com/akash-network/akash-api/go/node/staking/v1beta3" -) - -// RandomizedGenState generates a random GenesisState for supply -func RandomizedGenState(simState *module.SimulationState) { - providerGenesis := &types.GenesisState{} - - simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(providerGenesis) -} diff --git a/x/staking/simulation/operations.go b/x/staking/simulation/operations.go deleted file mode 100644 index 4f41281156..0000000000 --- a/x/staking/simulation/operations.go +++ /dev/null @@ -1,42 +0,0 @@ -package simulation - -import ( - "github.com/cosmos/cosmos-sdk/codec" - simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/cosmos/cosmos-sdk/x/simulation" - - "github.com/akash-network/node/x/staking/keeper" -) - -// WeightedOperations returns all the operations from the module with their respective weights -func WeightedOperations( - appParams simtypes.AppParams, cdc codec.JSONCodec, k keeper.IKeeper) simulation.WeightedOperations { - return nil - // var ( - // weightMsgCreate int - // weightMsgUpdate int - // ) - // - // appParams.GetOrGenerate( - // cdc, OpWeightMsgCreate, &weightMsgCreate, nil, func(r *rand.Rand) { - // weightMsgCreate = appparams.DefaultWeightMsgCreateProvider - // }, - // ) - // - // appParams.GetOrGenerate( - // cdc, OpWeightMsgUpdate, &weightMsgUpdate, nil, func(r *rand.Rand) { - // weightMsgUpdate = appparams.DefaultWeightMsgUpdateProvider - // }, - // ) - // - // return simulation.WeightedOperations{ - // simulation.NewWeightedOperation( - // weightMsgCreate, - // // SimulateMsgCreate(ak, bk, k), - // ), - // simulation.NewWeightedOperation( - // weightMsgUpdate, - // SimulateMsgUpdate(ak, bk, k), - // ), - // } -} diff --git a/x/take/alias.go b/x/take/alias.go index eaacc2e318..fe7d111266 100644 --- a/x/take/alias.go +++ b/x/take/alias.go @@ -1,7 +1,7 @@ package take import ( - types "github.com/akash-network/akash-api/go/node/take/v1beta3" + types "pkg.akt.dev/go/node/take/v1" ) const ( diff --git a/x/take/genesis.go b/x/take/genesis.go index 56fe694907..7391ab625b 100644 --- a/x/take/genesis.go +++ b/x/take/genesis.go @@ -3,11 +3,9 @@ package take import ( sdk "github.com/cosmos/cosmos-sdk/types" - abci "github.com/tendermint/tendermint/abci/types" + types "pkg.akt.dev/go/node/take/v1" - types "github.com/akash-network/akash-api/go/node/take/v1beta3" - - "github.com/akash-network/node/x/take/keeper" + "pkg.akt.dev/node/x/take/keeper" ) // ValidateGenesis does validation check of the Genesis and return error incase of failure @@ -24,9 +22,11 @@ func DefaultGenesisState() *types.GenesisState { } // InitGenesis initiate genesis state and return updated validator details -func InitGenesis(ctx sdk.Context, keeper keeper.IKeeper, data *types.GenesisState) []abci.ValidatorUpdate { - keeper.SetParams(ctx, data.Params) - return []abci.ValidatorUpdate{} +func InitGenesis(ctx sdk.Context, keeper keeper.IKeeper, data *types.GenesisState) { + err := keeper.SetParams(ctx, data.Params) + if err != nil { + panic(err.Error()) + } } // ExportGenesis returns genesis state for the deployment module diff --git a/x/take/handler/server.go b/x/take/handler/server.go new file mode 100644 index 0000000000..1dcdb75acf --- /dev/null +++ b/x/take/handler/server.go @@ -0,0 +1,39 @@ +package handler + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + types "pkg.akt.dev/go/node/take/v1" + + "pkg.akt.dev/node/x/take/keeper" +) + +var _ types.MsgServer = msgServer{} + +type msgServer struct { + keeper keeper.IKeeper +} + +// NewMsgServerImpl returns an implementation of the akash staking MsgServer interface +// for the provided Keeper. +func NewMsgServerImpl(k keeper.IKeeper) types.MsgServer { + return &msgServer{ + keeper: k, + } +} + +func (ms msgServer) UpdateParams(goCtx context.Context, req *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + if ms.keeper.GetAuthority() != req.Authority { + return nil, govtypes.ErrInvalidSigner.Wrapf("invalid authority; expected %s, got %s", ms.keeper.GetAuthority(), req.Authority) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + if err := ms.keeper.SetParams(ctx, req.Params); err != nil { + return nil, err + } + + return &types.MsgUpdateParamsResponse{}, nil +} diff --git a/x/take/keeper/grpc_query.go b/x/take/keeper/grpc_query.go new file mode 100644 index 0000000000..a5c9c46a40 --- /dev/null +++ b/x/take/keeper/grpc_query.go @@ -0,0 +1,29 @@ +package keeper + +import ( + "context" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + sdk "github.com/cosmos/cosmos-sdk/types" + types "pkg.akt.dev/go/node/take/v1" +) + +// Querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over keeper +type Querier struct { + Keeper +} + +var _ types.QueryServer = Querier{} + +func (k Querier) Params(ctx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { + if req == nil { + return nil, status.Errorf(codes.InvalidArgument, "empty request") + } + + sdkCtx := sdk.UnwrapSDKContext(ctx) + params := k.GetParams(sdkCtx) + + return &types.QueryParamsResponse{Params: params}, nil +} diff --git a/x/take/keeper/keeper.go b/x/take/keeper/keeper.go index db67cbaabd..30d83eec79 100644 --- a/x/take/keeper/keeper.go +++ b/x/take/keeper/keeper.go @@ -1,39 +1,40 @@ package keeper import ( + sdkmath "cosmossdk.io/math" + storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - - types "github.com/akash-network/akash-api/go/node/take/v1beta3" + types "pkg.akt.dev/go/node/take/v1" ) type IKeeper interface { - StoreKey() sdk.StoreKey + StoreKey() storetypes.StoreKey Codec() codec.BinaryCodec GetParams(ctx sdk.Context) (params types.Params) - SetParams(ctx sdk.Context, params types.Params) + SetParams(ctx sdk.Context, params types.Params) error SubtractFees(ctx sdk.Context, amt sdk.Coin) (sdk.Coin, sdk.Coin, error) + + NewQuerier() Querier + GetAuthority() string } // Keeper of the deployment store type Keeper struct { - skey sdk.StoreKey - cdc codec.BinaryCodec - pspace paramtypes.Subspace + skey storetypes.StoreKey + cdc codec.BinaryCodec + // The address capable of executing a MsgUpdateParams message. + // This should be the x/gov module account. + authority string } -// NewKeeper creates and returns an instance for deployment keeper -func NewKeeper(cdc codec.BinaryCodec, skey sdk.StoreKey, pspace paramtypes.Subspace) IKeeper { - if !pspace.HasKeyTable() { - pspace = pspace.WithKeyTable(types.ParamKeyTable()) - } - +// NewKeeper creates and returns an instance of take keeper +func NewKeeper(cdc codec.BinaryCodec, skey storetypes.StoreKey, authority string) IKeeper { return Keeper{ - skey: skey, - cdc: cdc, - pspace: pspace, + skey: skey, + cdc: cdc, + authority: authority, } } @@ -42,20 +43,42 @@ func (k Keeper) Codec() codec.BinaryCodec { return k.cdc } -func (k Keeper) StoreKey() sdk.StoreKey { +func (k Keeper) StoreKey() storetypes.StoreKey { return k.skey } -// GetParams returns the total set of deployment parameters. -func (k Keeper) GetParams(ctx sdk.Context) types.Params { - var params types.Params - k.pspace.GetParamSet(ctx, ¶ms) - return params +func (k Keeper) NewQuerier() Querier { + return Querier{k} } -// SetParams sets the deployment parameters to the paramspace. -func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { - k.pspace.SetParamSet(ctx, ¶ms) +// GetAuthority returns the x/mint module's authority. +func (k Keeper) GetAuthority() string { + return k.authority +} + +// SetParams sets the x/take module parameters. +func (k Keeper) SetParams(ctx sdk.Context, p types.Params) error { + if err := p.Validate(); err != nil { + return err + } + + store := ctx.KVStore(k.skey) + bz := k.cdc.MustMarshal(&p) + store.Set(types.ParamsPrefix(), bz) + + return nil +} + +// GetParams returns the current x/take module parameters. +func (k Keeper) GetParams(ctx sdk.Context) (p types.Params) { + store := ctx.KVStore(k.skey) + bz := store.Get(types.ParamsPrefix()) + if bz == nil { + return p + } + + k.cdc.MustUnmarshal(bz, &p) + return p } func (k Keeper) SubtractFees(ctx sdk.Context, amt sdk.Coin) (sdk.Coin, sdk.Coin, error) { @@ -70,7 +93,7 @@ func (k Keeper) SubtractFees(ctx sdk.Context, amt sdk.Coin) (sdk.Coin, sdk.Coin, return earnings, sdk.NewCoin(amt.GetDenom(), fees), nil } -func (k Keeper) findRate(ctx sdk.Context, denom string) sdk.Dec { +func (k Keeper) findRate(ctx sdk.Context, denom string) sdkmath.LegacyDec { params := k.GetParams(ctx) rate := params.DefaultTakeRate @@ -83,5 +106,5 @@ func (k Keeper) findRate(ctx sdk.Context, denom string) sdk.Dec { } // return percentage. - return sdk.NewDecFromInt(sdk.NewIntFromUint64(uint64(rate))).Quo(sdk.NewDec(100)) + return sdkmath.LegacyNewDecFromInt(sdkmath.NewIntFromUint64(uint64(rate))).Quo(sdkmath.LegacyNewDec(100)) } diff --git a/x/take/module.go b/x/take/module.go index 0d8bfef9e6..fb16f4ea61 100644 --- a/x/take/module.go +++ b/x/take/module.go @@ -1,34 +1,37 @@ package take import ( + "context" "encoding/json" - "math/rand" + "fmt" - "github.com/cosmos/cosmos-sdk/client" - sdk "github.com/cosmos/cosmos-sdk/types" - sim "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/spf13/cobra" - - "github.com/gorilla/mux" + "cosmossdk.io/core/appmodule" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/grpc-ecosystem/grpc-gateway/runtime" - abci "github.com/tendermint/tendermint/abci/types" + "github.com/spf13/cobra" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - "github.com/gogo/protobuf/grpc" - "github.com/pkg/errors" + types "pkg.akt.dev/go/node/take/v1" - "github.com/akash-network/node/x/take/keeper" - "github.com/akash-network/node/x/take/simulation" - - types "github.com/akash-network/akash-api/go/node/take/v1beta3" + "pkg.akt.dev/node/x/take/handler" + "pkg.akt.dev/node/x/take/keeper" + "pkg.akt.dev/node/x/take/simulation" ) var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} - _ module.AppModuleSimulation = AppModuleSimulation{} + _ module.AppModuleBasic = AppModuleBasic{} + _ module.HasGenesisBasics = AppModuleBasic{} + + _ appmodule.AppModule = AppModule{} + _ module.HasConsensusVersion = AppModule{} + _ module.HasGenesis = AppModule{} + _ module.HasServices = AppModule{} + + _ module.AppModuleSimulation = AppModule{} ) // AppModuleBasic defines the basic application module used by the provider module. @@ -36,6 +39,12 @@ type AppModuleBasic struct { cdc codec.Codec } +// AppModule implements an application module for the take module. +type AppModule struct { + AppModuleBasic + keeper keeper.IKeeper +} + // Name returns provider module's name func (AppModuleBasic) Name() string { return types.ModuleName @@ -43,7 +52,7 @@ func (AppModuleBasic) Name() string { // RegisterLegacyAminoCodec registers the provider module's types for the given codec. func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { - types.RegisterLegacyAminoCodec(cdc) + types.RegisterLegacyAminoCodec(cdc) // nolint staticcheck } // RegisterInterfaces registers the module's interface types @@ -67,22 +76,17 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingCo err := cdc.UnmarshalJSON(bz, &data) if err != nil { - return errors.Errorf("failed to unmarshal %s genesis state: %v", types.ModuleName, err) + return fmt.Errorf("failed to unmarshal %s genesis state: %v", types.ModuleName, err) } return ValidateGenesis(&data) } -// RegisterRESTRoutes registers rest routes for this module -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { -} - // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the provider module. -func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { -} - -// RegisterGRPCRoutes registers the gRPC Gateway routes for the provider module. -func (AppModuleBasic) RegisterGRPCRoutes(clientCtx client.Context, mux *runtime.ServeMux) { +func (AppModuleBasic) RegisterGRPCGatewayRoutes(cctx client.Context, mux *runtime.ServeMux) { + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(cctx)); err != nil { + panic(err) + } } // GetQueryCmd returns the root query command of this module @@ -95,17 +99,6 @@ func (AppModuleBasic) GetTxCmd() *cobra.Command { return nil } -// GetQueryClient returns a new query client for this module -func (AppModuleBasic) GetQueryClient(clientCtx client.Context) types.QueryClient { - return nil -} - -// AppModule implements an application module for the take module. -type AppModule struct { - AppModuleBasic - keeper keeper.IKeeper -} - // NewAppModule creates a new AppModule object func NewAppModule(cdc codec.Codec, k keeper.IKeeper) AppModule { return AppModule{ @@ -119,48 +112,41 @@ func (AppModule) Name() string { return types.ModuleName } -// RegisterInvariants registers module invariants -func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (am AppModule) IsOnePerModuleType() {} -// Route returns the message routing key for the take module. -func (am AppModule) Route() sdk.Route { - return sdk.NewRoute(types.RouterKey, nil) -} +// IsAppModule implements the appmodule.AppModule interface. +func (am AppModule) IsAppModule() {} // QuerierRoute returns the take module's querier route name. func (am AppModule) QuerierRoute() string { return types.ModuleName } -// LegacyQuerierHandler returns the sdk.Querier for take module -func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { - return nil -} - -// RegisterServices registers the module's servicess -func (am AppModule) RegisterServices(_ module.Configurator) { -} - -// RegisterQueryService registers a GRPC query service to respond to the -// module-specific GRPC queries. -func (am AppModule) RegisterQueryService(server grpc.Server) { +// RegisterServices registers the module's services +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), handler.NewMsgServerImpl(am.keeper)) + querier := am.keeper.NewQuerier() + types.RegisterQueryServer(cfg.QueryServer(), querier) } // BeginBlock performs no-op -func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} +func (am AppModule) BeginBlock(_ context.Context) error { + return nil +} -// EndBlock returns the end blocker for the take module. It returns no takeor +// EndBlock returns the end blocker for the deployment module. It returns no validator // updates. -func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - return []abci.ValidatorUpdate{} +func (am AppModule) EndBlock(_ context.Context) error { + return nil } // InitGenesis performs genesis initialization for the take module. It returns // no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) { var genesisState types.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) - return InitGenesis(ctx, am.keeper, &genesisState) + InitGenesis(ctx, am.keeper, &genesisState) } // ExportGenesis returns the exported genesis state as raw bytes for the take @@ -172,46 +158,25 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw // ConsensusVersion implements module.AppModule#ConsensusVersion func (am AppModule) ConsensusVersion() uint64 { - return 2 -} - -// ____________________________________________________________________________ - -// AppModuleSimulation implements an application simulation module for the take module. -type AppModuleSimulation struct { - keeper keeper.IKeeper -} - -// NewAppModuleSimulation creates a new AppModuleSimulation instance -func NewAppModuleSimulation(k keeper.IKeeper) AppModuleSimulation { - return AppModuleSimulation{ - keeper: k, - } + return 3 } // AppModuleSimulation functions // GenerateGenesisState creates a randomized GenState of the staking module. -func (AppModuleSimulation) GenerateGenesisState(simState *module.SimulationState) { +func (AppModule) GenerateGenesisState(simState *module.SimulationState) { simulation.RandomizedGenState(simState) } -// ProposalContents doesn't return any content functions for governance proposals. -func (AppModuleSimulation) ProposalContents(_ module.SimulationState) []sim.WeightedProposalContent { - return nil -} - -// RandomizedParams creates randomized staking param changes for the simulator. -func (AppModuleSimulation) RandomizedParams(r *rand.Rand) []sim.ParamChange { - return nil +// ProposalMsgs returns msgs used for governance proposals for simulations. +func (AppModule) ProposalMsgs(_ module.SimulationState) []simtypes.WeightedProposalMsg { + return simulation.ProposalMsgs() } -// RegisterStoreDecoder registers a decoder for staking module's types -func (AppModuleSimulation) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { - -} +// RegisterStoreDecoder registers a decoder for take module's types. +func (am AppModule) RegisterStoreDecoder(_ simtypes.StoreDecoderRegistry) {} -// WeightedOperations returns the all the staking module operations with their respective weights. -func (am AppModuleSimulation) WeightedOperations(simState module.SimulationState) []sim.WeightedOperation { +// WeightedOperations doesn't return any take module operation. +func (am AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { return nil } diff --git a/x/take/simulation/decoder.go b/x/take/simulation/decoder.go new file mode 100644 index 0000000000..c1be5a2b23 --- /dev/null +++ b/x/take/simulation/decoder.go @@ -0,0 +1,17 @@ +package simulation + +// NewDecodeStore returns a decoder function closure that unmarshals the KVPair's +// Value to the corresponding mint type. +// func NewDecodeStore(_ codec.Codec) func(kvA, kvB kv.Pair) string { +// return func(kvA, kvB kv.Pair) string { +// switch { +// case bytes.Equal(kvA.Key, types.MinterKey): +// var minterA, minterB types.Minter +// cdc.MustUnmarshal(kvA.Value, &minterA) +// cdc.MustUnmarshal(kvB.Value, &minterB) +// return fmt.Sprintf("%v\n%v", minterA, minterB) +// default: +// panic(fmt.Sprintf("invalid mint key %X", kvA.Key)) +// } +// } +// } diff --git a/x/take/simulation/genesis.go b/x/take/simulation/genesis.go index ef389922a5..28a40f7e6f 100644 --- a/x/take/simulation/genesis.go +++ b/x/take/simulation/genesis.go @@ -1,8 +1,9 @@ package simulation import ( - types "github.com/akash-network/akash-api/go/node/take/v1beta3" "github.com/cosmos/cosmos-sdk/types/module" + + types "pkg.akt.dev/go/node/take/v1" ) // RandomizedGenState generates a random GenesisState for supply diff --git a/x/take/simulation/proposals.go b/x/take/simulation/proposals.go new file mode 100644 index 0000000000..5894d75c36 --- /dev/null +++ b/x/take/simulation/proposals.go @@ -0,0 +1,65 @@ +package simulation + +import ( + "math/rand" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/simulation" + + types "pkg.akt.dev/go/node/take/v1" +) + +// Simulation operation weights constants +const ( + DefaultWeightMsgUpdateParams int = 100 + + OpWeightMsgUpdateParams = "op_weight_msg_update_params" //nolint:gosec +) + +// ProposalMsgs defines the module weighted proposals' contents +func ProposalMsgs() []simtypes.WeightedProposalMsg { + return []simtypes.WeightedProposalMsg{ + simulation.NewWeightedProposalMsg( + OpWeightMsgUpdateParams, + DefaultWeightMsgUpdateParams, + SimulateMsgUpdateParams, + ), + } +} + +func SimulateMsgUpdateParams(r *rand.Rand, _ sdk.Context, _ []simtypes.Account) sdk.Msg { + // use the default gov module account address as authority + var authority sdk.AccAddress = address.Module("gov") + + params := types.DefaultParams() + + coins := simtypes.RandSubsetCoins(r, sdk.Coins{ + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D84", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D85", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D86", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D87", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D88", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D89", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D8A", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + sdk.NewInt64Coin("ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D8B", int64(simtypes.RandIntBetween(r, 500000, 50000000))), + }) + + // uakt must always be present + coins = append(coins, sdk.NewInt64Coin("uakt", int64(simtypes.RandIntBetween(r, 500000, 50000000)))) + + params.DenomTakeRates = make(types.DenomTakeRates, 0, len(coins)) + + for _, coin := range coins { + params.DenomTakeRates = append(params.DenomTakeRates, types.DenomTakeRate{ + Denom: coin.Denom, + Rate: uint32(simtypes.RandIntBetween(r, 0, 100)), // nolint gosec + }) + } + + return &types.MsgUpdateParams{ + Authority: authority.String(), + Params: params, + } +}