From c6b2a0928e9ead38abcb5e5e97e9ede46202d017 Mon Sep 17 00:00:00 2001 From: Daniel Olshansky Date: Thu, 21 Nov 2024 13:02:52 -0800 Subject: [PATCH 01/21] [Docs] Update documentation on installing the `poktrolld` CLI (#949) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updating the following page for details on how to install the `poktrolld` CLI using homebrew: https://dev.poktroll.com/operate/user_guide/install ![Screenshot 2024-11-21 at 12 58 19β€―PM](https://github.com/user-attachments/assets/cee0c036-cc6e-486f-8c8e-4db5fa25c4b5) --- docusaurus/docs/operate/user_guide/install.md | 68 ++++++++++++------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/docusaurus/docs/operate/user_guide/install.md b/docusaurus/docs/operate/user_guide/install.md index ffa17875c..b19473f01 100644 --- a/docusaurus/docs/operate/user_guide/install.md +++ b/docusaurus/docs/operate/user_guide/install.md @@ -3,41 +3,47 @@ title: CLI Installation sidebar_position: 0 --- -- [Release binaries](#release-binaries) -- [Installing from source](#installing-from-source) - - [Prerequisites](#prerequisites) -- [Homebrew and pkgx](#homebrew-and-pkgx) +- [MacOS \& Linux Users](#macos--linux-users) + - [Using Homebrew](#using-homebrew) + - [From Source](#from-source) + - [Using release binaries](#using-release-binaries) - [Windows Users](#windows-users) -## Release binaries +## MacOS & Linux Users -Pre-built binaries are available on our [releases page](https://github.com/pokt-network/poktroll/releases). +### Using Homebrew -The following snippet downloads/upgrades the binary to the latest released version (Linux and macOS only): +:::tip +See the [homebrew-poktroll](https://github.com/pokt-network/homebrew-poktroll/) +repository for details on how to install homebrew or other details to install +or debug the CLI. +::: -```bash -# Download the correct binary based on the OS and architecture -curl -LO "https://github.com/pokt-network/poktroll/releases/latest/download/poktroll_$(uname | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" +Ensure you have [Homebrew](https://brew.sh/) installed. -# Extract the downloaded tarball to /usr/local/bin -sudo tar -zxf "poktroll_$(uname | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" -C /usr/local/bin +Then run the following commands: -# Make the binary executable -sudo chmod +x /usr/local/bin/poktrolld +```bash +brew tap pokt-network/poktroll +brew install poktrolld +``` -# Check version +And verify it worked by running: + +```bash poktrolld version +poktrolld --help ``` -## Installing from source - -### Prerequisites +### From Source Ensure you have the following installed: - [Go](https://go.dev/doc/install) (version 1.18 or later) - [Ignite CLI](https://docs.ignite.com/welcome/install) +Then run the following commands: + ```bash git clone https://github.com/pokt-network/poktroll.git cd poktroll @@ -45,20 +51,32 @@ make go_develop make ignite_poktrolld_build ``` -Verify it worked by running: +And verify it worked by running: ```bash +poktrolld version poktrolld --help ``` -## Homebrew and pkgx +### Using release binaries -:::tip -We have an [open GitHub issue](https://github.com/pokt-network/poktroll/issues/535) -to introduce `poktrolld` to [brew](https://brew.sh/) and [pkgx](https://github.com/pkgxdev/pkgx). +Pre-built binaries are available on our [releases page](https://github.com/pokt-network/poktroll/releases). -Please reach out to us in the ticket if you want to pick this ticket! -::: +The following snippet downloads/upgrades the binary to the latest released version: + +```bash +# Download the correct binary based on the OS and architecture +curl -LO "https://github.com/pokt-network/poktroll/releases/latest/download/poktroll_$(uname | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" + +# Extract the downloaded tarball to /usr/local/bin +sudo tar -zxf "poktroll_$(uname | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" -C /usr/local/bin + +# Make the binary executable +sudo chmod +x /usr/local/bin/poktrolld + +# Check version +poktrolld version +``` ## Windows Users From 59ec254f58895cb0a7209d07cd86d59f84e9ae7e Mon Sep 17 00:00:00 2001 From: Daniel Olshansky Date: Thu, 21 Nov 2024 13:37:57 -0800 Subject: [PATCH 02/21] [Docs] Update links to RPC & explorers (#950) Update links to RPC endpoints, faucet & explorers --- docusaurus/docs/explore/rpc.md | 13 ++++++------- docusaurus/docs/explore/tools.md | 14 ++++++++------ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/docusaurus/docs/explore/rpc.md b/docusaurus/docs/explore/rpc.md index a87c5e1a2..5a407e2ce 100644 --- a/docusaurus/docs/explore/rpc.md +++ b/docusaurus/docs/explore/rpc.md @@ -13,7 +13,6 @@ sidebar_position: 3 ## Types of RPC Endpoints - You can review the difference between them in the [Cosmos SDK docs](https://docs.cosmos.network/main/learn/advanced/grpc_rest#comparison-table). ## Beta TestNet @@ -22,9 +21,9 @@ You can review the difference between them in the [Cosmos SDK docs](https://docs We provide `gRPC`, `JSON-RPC` and `REST` endpoints, which are available here: -- **RPC**: `https://shannon-testnet-grove-seed-rpc.beta.poktroll.com` -- **gRPC**: `https://shannon-testnet-grove-seed-grpc.beta.poktroll.com` -- **REST**: `https://shannon-testnet-grove-seed-api.beta.poktroll.com` +- **RPC**: `https://shannon-testnet-grove-rpc.beta.poktroll.com` +- **gRPC**: `https://shannon-testnet-grove-grpc.beta.poktroll.com` +- **REST**: `https://shannon-testnet-grove-api.beta.poktroll.com` ### Beta JSON-RPC Example @@ -46,9 +45,9 @@ poktrolld query block --type=height 0 --node https://shannon-testnet-grove-seed- We provide `gRPC`, `JSON-RPC` and `REST` endpoints, which are available here: -- **RPC**: `https://shannon-testnet-grove-seed-rpc.alpha.poktroll.com` -- **gRPC**: `https://shannon-testnet-grove-seed-grpc.alpha.poktroll.com` -- **REST**: `https://shannon-testnet-grove-seed-api.alpha.poktroll.com` +- **RPC**: `https://shannon-testnet-grove-rpc.alpha.poktroll.com` +- **gRPC**: `https://shannon-testnet-grove-grpc.alpha.poktroll.com` +- **REST**: `https://shannon-testnet-grove-api.alpha.poktroll.com` ### Alpha JSON-RPC Example diff --git a/docusaurus/docs/explore/tools.md b/docusaurus/docs/explore/tools.md index 1034d1565..9e46f4f64 100644 --- a/docusaurus/docs/explore/tools.md +++ b/docusaurus/docs/explore/tools.md @@ -9,15 +9,17 @@ sidebar_position: 1 ## Beta TestNet -- πŸͺ™ [Shannon Beta Token Faucet](https://faucet.beta.testnet.pokt.network/) -- πŸ—ΊοΈ [Shannon Beta Explorer](https://shannon.beta.testnet.pokt.network) -- πŸ—ΊοΈ [PoktScan's Shannon Beta Explorer](https://shannon.beta.poktscan.com/) +- πŸͺ™ [Token Faucet](https://faucet.beta.testnet.pokt.network/) +- πŸ—ΊοΈ [Explorer](https://shannon.beta.testnet.pokt.network) +- πŸ—ΊοΈ [POKTScan's Explorer](https://shannon-beta.poktscan.com/) +- πŸ‘¨β€πŸ’» [POKTScan's GraphQL Playground](https://shannon-beta-api.poktscan.com/) ## Alpha TestNet -- πŸͺ™ [Shannon Alpha Token Faucet](https://faucet.alpha.testnet.pokt.network/) -- πŸ—ΊοΈ [Shannon Alpha Explorer](https://shannon.alpha.testnet.pokt.network) -- πŸ—ΊοΈ [PoktScan's Shannon Alpha Explorer](https://shannon.alpha.poktscan.com/) +- πŸͺ™ [Token Faucet](https://faucet.alpha.testnet.pokt.network/) +- πŸ—ΊοΈ [Explorer](https://shannon.alpha.testnet.pokt.network) +- πŸ—ΊοΈ [POKTScan's Explorer](https://shannon-alpha.poktscan.com/) +- πŸ‘¨β€πŸ’» [POKTScan's GraphQL Playground](https://shannon-alpha-api.poktscan.com/) ## πŸ› οΈ Tools & References From 4ad2c9152668797382947e899e3eaaab4851abb0 Mon Sep 17 00:00:00 2001 From: Bryan White Date: Mon, 25 Nov 2024 20:40:58 +0100 Subject: [PATCH 03/21] [Docs] adding params - fix gRPC status error code (#958) ## Summary ```diff func (k msgServer) UpdateParam(ctx context.Context, msg *examplemodtypes.MsgUpdateParam) (*examplemodtypes.MsgUpdateParamResponse, error) { // ... if k.GetAuthority() != msg.Authority { return nil, status.Error( - codes.InvalidArgument, + codes.PermissionDenied, examplemodtypes.ErrExamplemodInvalidSigner.Wrapf( "invalid authority; expected %s, got %s", k.GetAuthority(), msg.Authority, ).Error(), ) } // ... } ``` ## Issue - N/A ## Type of change Select one or more from the following: - [ ] New feature, functionality or library - [ ] Consensus breaking; add the `consensus-breaking` label if so. See #791 for details - [ ] Bug fix - [ ] Code health or cleanup - [x] Documentation - [ ] Other (specify) ## Testing - [ ] **Documentation**: `make docusaurus_start`; only needed if you make doc changes - [ ] **Unit Tests**: `make go_develop_and_test` - [ ] **LocalNet E2E Tests**: `make test_e2e` - [ ] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR. ## Sanity Checklist - [ ] I have tested my changes using the available tooling - [ ] I have commented my code - [ ] I have performed a self-review of my own code; both comments & source code - [ ] I create and reference any new tickets, if applicable - [ ] I have left TODOs throughout the codebase, if applicable --- docusaurus/docs/develop/developer_guide/adding_params.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/develop/developer_guide/adding_params.md b/docusaurus/docs/develop/developer_guide/adding_params.md index 48de66434..df8bf2c7d 100644 --- a/docusaurus/docs/develop/developer_guide/adding_params.md +++ b/docusaurus/docs/develop/developer_guide/adding_params.md @@ -243,7 +243,7 @@ Prepare `x/examplemod/keeper/msg_server_update_param.go` to handle parameter upd + + if k.GetAuthority() != msg.Authority { + return nil, status.Error( -+ codes.InvalidArgument, ++ codes.PermissionDenied, + examplemodtypes.ErrExamplemodInvalidSigner.Wrapf( + "invalid authority; expected %s, got %s", + k.GetAuthority(), msg.Authority, From f46dd4fa9e9717d594ecd2899189aa540bbc5b42 Mon Sep 17 00:00:00 2001 From: Daniel Olshansky Date: Mon, 25 Nov 2024 13:38:06 -0800 Subject: [PATCH 04/21] Commit outdated proto files --- api/poktroll/application/event.pulsar.go | 2 +- api/poktroll/application/types.pulsar.go | 2 +- api/poktroll/supplier/event.pulsar.go | 2 +- api/poktroll/supplier/tx.pulsar.go | 2 +- api/poktroll/tokenomics/event.pulsar.go | 2 +- api/poktroll/tokenomics/types.pulsar.go | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/api/poktroll/application/event.pulsar.go b/api/poktroll/application/event.pulsar.go index 292a46750..09bac55c2 100644 --- a/api/poktroll/application/event.pulsar.go +++ b/api/poktroll/application/event.pulsar.go @@ -3,11 +3,11 @@ package application import ( _ "cosmossdk.io/api/cosmos/base/v1beta1" + _ "github.com/pokt-network/poktroll/api/poktroll/shared" fmt "fmt" _ "github.com/cosmos/cosmos-proto" runtime "github.com/cosmos/cosmos-proto/runtime" _ "github.com/cosmos/gogoproto/gogoproto" - _ "github.com/pokt-network/poktroll/api/poktroll/shared" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoiface "google.golang.org/protobuf/runtime/protoiface" protoimpl "google.golang.org/protobuf/runtime/protoimpl" diff --git a/api/poktroll/application/types.pulsar.go b/api/poktroll/application/types.pulsar.go index ca032ba67..f482e77bb 100644 --- a/api/poktroll/application/types.pulsar.go +++ b/api/poktroll/application/types.pulsar.go @@ -3,11 +3,11 @@ package application import ( v1beta1 "cosmossdk.io/api/cosmos/base/v1beta1" + shared "github.com/pokt-network/poktroll/api/poktroll/shared" fmt "fmt" _ "github.com/cosmos/cosmos-proto" runtime "github.com/cosmos/cosmos-proto/runtime" _ "github.com/cosmos/gogoproto/gogoproto" - shared "github.com/pokt-network/poktroll/api/poktroll/shared" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoiface "google.golang.org/protobuf/runtime/protoiface" protoimpl "google.golang.org/protobuf/runtime/protoimpl" diff --git a/api/poktroll/supplier/event.pulsar.go b/api/poktroll/supplier/event.pulsar.go index 8558365eb..22dcc4989 100644 --- a/api/poktroll/supplier/event.pulsar.go +++ b/api/poktroll/supplier/event.pulsar.go @@ -3,11 +3,11 @@ package supplier import ( _ "cosmossdk.io/api/cosmos/base/v1beta1" + shared "github.com/pokt-network/poktroll/api/poktroll/shared" fmt "fmt" _ "github.com/cosmos/cosmos-proto" runtime "github.com/cosmos/cosmos-proto/runtime" _ "github.com/cosmos/gogoproto/gogoproto" - shared "github.com/pokt-network/poktroll/api/poktroll/shared" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoiface "google.golang.org/protobuf/runtime/protoiface" protoimpl "google.golang.org/protobuf/runtime/protoimpl" diff --git a/api/poktroll/supplier/tx.pulsar.go b/api/poktroll/supplier/tx.pulsar.go index 7a709f7f0..1d2057b01 100644 --- a/api/poktroll/supplier/tx.pulsar.go +++ b/api/poktroll/supplier/tx.pulsar.go @@ -5,11 +5,11 @@ import ( _ "cosmossdk.io/api/amino" v1beta1 "cosmossdk.io/api/cosmos/base/v1beta1" _ "cosmossdk.io/api/cosmos/msg/v1" + shared "github.com/pokt-network/poktroll/api/poktroll/shared" fmt "fmt" _ "github.com/cosmos/cosmos-proto" runtime "github.com/cosmos/cosmos-proto/runtime" _ "github.com/cosmos/gogoproto/gogoproto" - shared "github.com/pokt-network/poktroll/api/poktroll/shared" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoiface "google.golang.org/protobuf/runtime/protoiface" protoimpl "google.golang.org/protobuf/runtime/protoimpl" diff --git a/api/poktroll/tokenomics/event.pulsar.go b/api/poktroll/tokenomics/event.pulsar.go index e62c41344..af0c412dc 100644 --- a/api/poktroll/tokenomics/event.pulsar.go +++ b/api/poktroll/tokenomics/event.pulsar.go @@ -3,10 +3,10 @@ package tokenomics import ( v1beta1 "cosmossdk.io/api/cosmos/base/v1beta1" + proof "github.com/pokt-network/poktroll/api/poktroll/proof" fmt "fmt" runtime "github.com/cosmos/cosmos-proto/runtime" _ "github.com/cosmos/gogoproto/gogoproto" - proof "github.com/pokt-network/poktroll/api/poktroll/proof" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoiface "google.golang.org/protobuf/runtime/protoiface" protoimpl "google.golang.org/protobuf/runtime/protoimpl" diff --git a/api/poktroll/tokenomics/types.pulsar.go b/api/poktroll/tokenomics/types.pulsar.go index 9ca1a54f9..e48600e95 100644 --- a/api/poktroll/tokenomics/types.pulsar.go +++ b/api/poktroll/tokenomics/types.pulsar.go @@ -3,11 +3,11 @@ package tokenomics import ( v1beta1 "cosmossdk.io/api/cosmos/base/v1beta1" + proof "github.com/pokt-network/poktroll/api/poktroll/proof" fmt "fmt" _ "github.com/cosmos/cosmos-proto" runtime "github.com/cosmos/cosmos-proto/runtime" _ "github.com/cosmos/gogoproto/gogoproto" - proof "github.com/pokt-network/poktroll/api/poktroll/proof" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoiface "google.golang.org/protobuf/runtime/protoiface" protoimpl "google.golang.org/protobuf/runtime/protoimpl" From afa7c8646c011884d227ee679f69f54cf6ba8d95 Mon Sep 17 00:00:00 2001 From: Daniel Olshansky Date: Tue, 26 Nov 2024 12:57:05 -0800 Subject: [PATCH 05/21] [Docs] Beta TestNet - Service Cheatsheet (#965) Cheatsheet to add a new onchain `Service` plus a few other improvements. - Add a service quickstart - Update `.gitignore` w/ a few config files - Add `tl;dr` to `CLI installation` and use account setup` - Add instructions on creating a new Debian user --- Co-authored-by: Redouane Lakrache Co-authored-by: Dima K. --- .gitignore | 7 +- .../docker_compose_debian_cheatsheet.md | 13 ++- .../quickstart/docker_compose_walkthrough.md | 38 +++++++- .../operate/quickstart/service_cheatsheet.md | 90 ++++++++++++++++++- .../operate/quickstart/supplier_cheatsheet.md | 14 --- .../operate/user_guide/create-new-wallet.md | 23 ++++- docusaurus/docs/operate/user_guide/install.md | 23 +++-- 7 files changed, 178 insertions(+), 30 deletions(-) delete mode 100644 docusaurus/docs/operate/quickstart/supplier_cheatsheet.md diff --git a/.gitignore b/.gitignore index f444c077b..862f41be0 100644 --- a/.gitignore +++ b/.gitignore @@ -100,4 +100,9 @@ cmd/poktrolld/*debug_bin* job.yaml # tmp directory for locally produced artifacts -tmp/* \ No newline at end of file +tmp/* + +# Common testing configurations +relayminer_config.yaml +gateway_config.yaml +path_config.yaml diff --git a/docusaurus/docs/operate/quickstart/docker_compose_debian_cheatsheet.md b/docusaurus/docs/operate/quickstart/docker_compose_debian_cheatsheet.md index 6493b012e..ad7d2b632 100644 --- a/docusaurus/docs/operate/quickstart/docker_compose_debian_cheatsheet.md +++ b/docusaurus/docs/operate/quickstart/docker_compose_debian_cheatsheet.md @@ -26,7 +26,6 @@ import ReactPlayer from "react-player"; - [Faucet is not ready and you need to fund the accounts manually](#faucet-is-not-ready-and-you-need-to-fund-the-accounts-manually) - [Start the RelayMiner](#start-the-relayminer) - [Start the AppGate Server](#start-the-appgate-server) - - [Re-stake the gateway](#re-stake-the-gateway) ## Results @@ -85,6 +84,16 @@ And then install docker: sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin ``` +### [Optional] Create a new user + +You can optionally create a new user and give it sudo permissions instead of using `root`. + +```bash +export USERNAME=olshansky +sudo adduser $USERNAME +sudo usermod -aG sudo $USERNAME +``` + ## Retrieve the source code Then pull the github repo @@ -320,5 +329,3 @@ docker compose up -d appgate # View docker logs -f --tail 100 appgate ``` - -### Re-stake the gateway diff --git a/docusaurus/docs/operate/quickstart/docker_compose_walkthrough.md b/docusaurus/docs/operate/quickstart/docker_compose_walkthrough.md index ca58321bc..1d0518d7f 100644 --- a/docusaurus/docs/operate/quickstart/docker_compose_walkthrough.md +++ b/docusaurus/docs/operate/quickstart/docker_compose_walkthrough.md @@ -115,7 +115,7 @@ flowchart TB _Note: the system must be capable of exposing ports to the internet for peer-to-peer communication._ -### 0. Software & Tooling +### Software & Tooling Ensure the following software is installed on your system: @@ -152,6 +152,42 @@ Update `NODE_HOSTNAME` in `.env` to the IP address or hostname of your node. For sed -i -e s/NODE_HOSTNAME=/NODE_HOSTNAME=69.42.690.420/g .env ``` +### [Optional] Create a new user + +:::note + +Make sure to replace `olshansky` with your username. + +::: + +You can generally do everything as the `root` user, but it's recommended to +create a new user and give it sudo permissions. + +This is necessary, in particular, if you want to use [homebrew](https://brew.sh/) [to install `poktrolld`](../user_guide/install.md). + +```bash +# Create a new user and give sudo permissions +export USERNAME=olshansky +sudo adduser $USERNAME +sudo usermod -aG sudo $USERNAME +``` + +Then, switch to the new user: + +```bash +su - olshansky +``` + +You can also avoid needing to pass in the password each time by running the following: + +```bash +# Optionally avoid needing to provide a password +sudo vi /etc/sudoers + +# Add the following line to the end of the file +olshansky ALL=(ALL) NOPASSWD:ALL +``` + ## A. Deploying a Full Node ### Launch the Node diff --git a/docusaurus/docs/operate/quickstart/service_cheatsheet.md b/docusaurus/docs/operate/quickstart/service_cheatsheet.md index e7a99290c..c1cfa6bf0 100644 --- a/docusaurus/docs/operate/quickstart/service_cheatsheet.md +++ b/docusaurus/docs/operate/quickstart/service_cheatsheet.md @@ -5,4 +5,92 @@ title: Service Cheat Sheet ## Service Cheat Sheet -TODO_BETA(@olshansk): Document how to add a service onchain. +- [Pre-Requisites](#pre-requisites) +- [How do I query for all existing onchain Services?](#how-do-i-query-for-all-existing-onchain-services) +- [How do I create a new service?](#how-do-i-create-a-new-service) +- [How do I learn more about interacting with Services?](#how-do-i-learn-more-about-interacting-with-services) + - [Service Transactions](#service-transactions) + - [Service Queries](#service-queries) + +### Pre-Requisites + +1. Make sure to [install the `poktrolld` CLI](../user_guide/install.md). +2. Make sure you know how to [create and fund a new account](../user_guide/create-new-wallet.md). + +### How do I query for all existing onchain Services? + +You can query for all services like so: + +```bash +poktrolld query service all-services --node https://shannon-testnet-grove-rpc.beta.poktroll.com --output json | jq +``` + +Here is an example of the output on Beta TestNet as of writing this document: + +```json +{ + "service": [ + { + "id": "svc_8ymf38", + "name": "name for svc_8ymf38", + "compute_units_per_relay": "7", + "owner_address": "pokt1aqsr8ejvwwnjwx3ppp234l586kl06cvas7ag6w" + }, + { + "id": "svc_drce83", + "name": "name for svc_drce83", + "compute_units_per_relay": "7", + "owner_address": "pokt1mgtf9k4k3pze57gwp3qsne88jmvqkc37t7vd9g" + }, + { + "id": "svc_jk07qh", + "name": "name for svc_jk07qh", + "compute_units_per_relay": "7", + "owner_address": "pokt1mwynfsnzesc38f98zrk08pttjn48tu7crc2p09" + } + ], + "pagination": { + "total": "3" + } +} +``` + +### How do I create a new service? + +You can use the `add-service` command to create a new service like so: + +```bash +poktrolld tx service add-service ${SERVICE_ID} "${SERVICE_NAME_OR_DESCRIPTION}" ${COMPUTE_UNITS_PER_RELAY} --from ${SERVICE_OWNER} +``` + +Here is a concrete copy-pasta assuming you have created and funded a new account called `$USER`: + +```bash +poktrolld tx service add-service "svc-$USER" "service description for $USER" 69 \ + --node https://shannon-testnet-grove-rpc.beta.poktroll.com \ + --fees 1upokt --from $USER --chain-id pocket-beta +``` + +Optionally, you can add some more flags to be ultra-verbose about your local environment: + +```bash +poktrolld tx service add-service "svc-$USER" "service description for $USER" 69 \ + --node https://shannon-testnet-grove-rpc.beta.poktroll.com \ + --fees 1upokt --from $USER --chain-id pocket-beta \ + --home ~/.poktroll --keyring-backend test \ + --yes --output json +``` + +### How do I learn more about interacting with Services? + +#### Service Transactions + +```bash +poktrolld tx service -h +``` + +#### Service Queries + +```bash +poktrolld query service -h +``` diff --git a/docusaurus/docs/operate/quickstart/supplier_cheatsheet.md b/docusaurus/docs/operate/quickstart/supplier_cheatsheet.md deleted file mode 100644 index 5e991ed70..000000000 --- a/docusaurus/docs/operate/quickstart/supplier_cheatsheet.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -sidebar_position: 4 -title: Supplier Cheat Sheet ---- - -## Supplier Cheat Sheet - -:::tip - -See the [Supplier Walkthrough](./../run_a_node/supplier_walkthrough.md) for an in-depth guide on setting up a Supplier. - -::: - -TODO_BETA(@olshansk): Finish this page. diff --git a/docusaurus/docs/operate/user_guide/create-new-wallet.md b/docusaurus/docs/operate/user_guide/create-new-wallet.md index 6a2af0e61..8df204d14 100644 --- a/docusaurus/docs/operate/user_guide/create-new-wallet.md +++ b/docusaurus/docs/operate/user_guide/create-new-wallet.md @@ -5,11 +5,18 @@ sidebar_position: 1 # Create a New Wallet -:::warning Security Notice +:::warning -**ALWAYS back up your key and/or mnemonic**. Store it in a secure -location accessible only to you, such as a password manager, or written down -in a safe place. Under your πŸ›οΈ does not count! +tl;dr IFF you know what you're doing. + +```bash +# Add a new wallet +poktrolld keys add $USER +# Retrieve the address +poktrolld keys show $USER -a +``` + +Use the `address` and go to the [Beta TestNet Faucet](https://faucet.beta.testnet.pokt.network/) to fund your account. ::: @@ -20,6 +27,14 @@ This guide will walk you through creating a new wallet on the Pocket Network. - [Step 2: Creating the Wallet](#step-2-creating-the-wallet) - [Step 3: Backing Up Your Wallet](#step-3-backing-up-your-wallet) +:::warning Security Notice + +**ALWAYS back up your key and/or mnemonic**. Store it in a secure +location accessible only to you, such as a password manager, or written down +in a safe place. Under your πŸ›οΈ does not count! + +::: + ## What is a keyring backend? Before proceeding, it's critical to understand the implications of keyring backends diff --git a/docusaurus/docs/operate/user_guide/install.md b/docusaurus/docs/operate/user_guide/install.md index b19473f01..4c20f0824 100644 --- a/docusaurus/docs/operate/user_guide/install.md +++ b/docusaurus/docs/operate/user_guide/install.md @@ -3,6 +3,17 @@ title: CLI Installation sidebar_position: 0 --- +:::warning + +tl;dr IFF you know what you're doing. + +```bash +brew tap pokt-network/poktroll +brew install poktrolld +``` + +::: + - [MacOS \& Linux Users](#macos--linux-users) - [Using Homebrew](#using-homebrew) - [From Source](#from-source) @@ -13,12 +24,6 @@ sidebar_position: 0 ### Using Homebrew -:::tip -See the [homebrew-poktroll](https://github.com/pokt-network/homebrew-poktroll/) -repository for details on how to install homebrew or other details to install -or debug the CLI. -::: - Ensure you have [Homebrew](https://brew.sh/) installed. Then run the following commands: @@ -35,6 +40,12 @@ poktrolld version poktrolld --help ``` +:::tip +See the [homebrew-poktroll](https://github.com/pokt-network/homebrew-poktroll/) +repository for details on how to install homebrew or other details to install +or debug the CLI. +::: + ### From Source Ensure you have the following installed: From 9ae1129b38c718cdfd79414b674f30885c57316a Mon Sep 17 00:00:00 2001 From: Bryan White Date: Wed, 27 Nov 2024 16:13:54 +0100 Subject: [PATCH 06/21] [Service] refactor: `TargetNumRelays` var usage to param usage (#943) ## Summary Replace usage of `servicekeeper.TargetNumRelays` with the new param and delete it. ## Issue - `TODO_BETA` ## Type of change Select one or more from the following: - [ ] New feature, functionality or library - [ ] Consensus breaking; add the `consensus-breaking` label if so. See #791 for details - [ ] Bug fix - [x] Code health or cleanup - [ ] Documentation - [ ] Other (specify) ## Testing - [ ] **Documentation**: `make docusaurus_start`; only needed if you make doc changes - [x] **Unit Tests**: `make go_develop_and_test` - [ ] **LocalNet E2E Tests**: `make test_e2e` - [x] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR. ## Sanity Checklist - [x] I have tested my changes using the available tooling - [ ] I have commented my code - [x] I have performed a self-review of my own code; both comments & source code - [ ] I create and reference any new tickets, if applicable - [ ] I have left TODOs throughout the codebase, if applicable --- .../integration/application/min_stake_test.go | 5 +++- .../relay_mining_integration_test.go | 23 +++++++++---------- testutil/keeper/tokenomics.go | 9 +++++++- .../keeper/msg_server_create_claim_test.go | 10 ++++++-- .../keeper/msg_server_submit_proof_test.go | 10 ++++++-- x/proof/keeper/proof_validation_test.go | 9 +++++++- x/proof/types/expected_keepers.go | 1 + x/service/keeper/relay_mining_difficulty.go | 11 +++++++-- .../keeper/update_relay_mining_difficulty.go | 23 +++++++++---------- .../update_relay_mining_difficulty_test.go | 16 ++++++------- .../keeper_settle_pending_claims_test.go | 9 +++++++- x/tokenomics/keeper/settle_pending_claims.go | 9 +++++++- x/tokenomics/keeper/token_logic_modules.go | 9 +++++++- x/tokenomics/types/expected_keepers.go | 2 ++ 14 files changed, 102 insertions(+), 44 deletions(-) diff --git a/tests/integration/application/min_stake_test.go b/tests/integration/application/min_stake_test.go index 5a0ea2128..b8211d6ec 100644 --- a/tests/integration/application/min_stake_test.go +++ b/tests/integration/application/min_stake_test.go @@ -255,11 +255,14 @@ func (s *applicationMinStakeTestSuite) getExpectedApp(claim *prooftypes.Claim) * func (s *applicationMinStakeTestSuite) newRelayminingDifficulty() servicetypes.RelayMiningDifficulty { s.T().Helper() + targetNumRelays := s.keepers.ServiceKeeper.GetParams(s.ctx).TargetNumRelays + return servicekeeper.NewDefaultRelayMiningDifficulty( s.ctx, cosmoslog.NewNopLogger(), s.serviceId, - servicekeeper.TargetNumRelays, + targetNumRelays, + targetNumRelays, ) } diff --git a/tests/integration/tokenomics/relay_mining_integration_test.go b/tests/integration/tokenomics/relay_mining_integration_test.go index 5014c7275..0b6ea4a9f 100644 --- a/tests/integration/tokenomics/relay_mining_integration_test.go +++ b/tests/integration/tokenomics/relay_mining_integration_test.go @@ -17,7 +17,6 @@ import ( "github.com/pokt-network/poktroll/testutil/testrelayer" apptypes "github.com/pokt-network/poktroll/x/application/types" prooftypes "github.com/pokt-network/poktroll/x/proof/types" - servicekeeper "github.com/pokt-network/poktroll/x/service/keeper" servicetypes "github.com/pokt-network/poktroll/x/service/types" sessiontypes "github.com/pokt-network/poktroll/x/session/types" sharedtypes "github.com/pokt-network/poktroll/x/shared/types" @@ -30,15 +29,6 @@ const ( ) func TestComputeNewDifficultyHash_RewardsReflectWorkCompleted(t *testing.T) { - // Update the target number of relays to a value that suits the test. - // A too high number would make the difficulty stay at BaseRelayDifficultyHash - initialTargetRelays := servicekeeper.TargetNumRelays - servicekeeper.TargetNumRelays = 1000 - t.Cleanup(func() { - // Reset the target number of relays to its initial value. - servicekeeper.TargetNumRelays = initialTargetRelays - }) - // Prepare the test service. service := sharedtypes.Service{ Id: "svc1", @@ -89,10 +79,17 @@ func TestComputeNewDifficultyHash_RewardsReflectWorkCompleted(t *testing.T) { sdkCtx := sdk.UnwrapSDKContext(ctx) sdkCtx = sdkCtx.WithBlockHeight(1) + // Update the target number of relays to a value that suits the test. + // A too high number would make the difficulty stay at BaseRelayDifficultyHash + serviceParams := keepers.ServiceKeeper.GetParams(ctx) + serviceParams.TargetNumRelays = 1000 + err := keepers.ServiceKeeper.SetParams(ctx, serviceParams) + require.NoError(t, err) + // Set the CUTTM to 1 to simplify the math sharedParams := keepers.SharedKeeper.GetParams(sdkCtx) sharedParams.ComputeUnitsToTokensMultiplier = uint64(1) - err := keepers.SharedKeeper.SetParams(sdkCtx, sharedParams) + err = keepers.SharedKeeper.SetParams(sdkCtx, sharedParams) require.NoError(t, err) // Update the relay mining difficulty so there's always a difficulty to retrieve @@ -159,10 +156,12 @@ func TestComputeNewDifficultyHash_RewardsReflectWorkCompleted(t *testing.T) { updatedRelayMiningDifficulty, ok := keepers.ServiceKeeper.GetRelayMiningDifficulty(sdkCtx, service.Id) require.True(t, ok) + targetNumRelays := keepers.ServiceKeeper.GetParams(ctx).TargetNumRelays + // Compute the new difficulty hash based on the updated relay mining difficulty. newDifficultyHash := protocol.ComputeNewDifficultyTargetHash( protocol.BaseRelayDifficultyHashBz, - servicekeeper.TargetNumRelays, + targetNumRelays, updatedRelayMiningDifficulty.NumRelaysEma, ) diff --git a/testutil/keeper/tokenomics.go b/testutil/keeper/tokenomics.go index ff5729376..e4cef7328 100644 --- a/testutil/keeper/tokenomics.go +++ b/testutil/keeper/tokenomics.go @@ -251,7 +251,14 @@ func TokenomicsKeeperWithActorAddrs(t testing.TB) ( Return(sharedtypes.Service{}, false). AnyTimes() - relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty(sdkCtx, log.NewNopLogger(), service.Id, servicekeeper.TargetNumRelays) + targetNumRelays := servicetypes.DefaultTargetNumRelays + relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty( + sdkCtx, + log.NewNopLogger(), + service.Id, + targetNumRelays, + targetNumRelays, + ) mockServiceKeeper.EXPECT(). GetRelayMiningDifficulty(gomock.Any(), gomock.Any()). Return(relayMiningDifficulty, true). diff --git a/x/proof/keeper/msg_server_create_claim_test.go b/x/proof/keeper/msg_server_create_claim_test.go index b48973b1c..f97982cfd 100644 --- a/x/proof/keeper/msg_server_create_claim_test.go +++ b/x/proof/keeper/msg_server_create_claim_test.go @@ -174,8 +174,14 @@ func TestMsgServer_CreateClaim_Success(t *testing.T) { claimCreatedEvents := testutilevents.FilterEvents[*prooftypes.EventClaimCreated](t, events) require.Len(t, claimCreatedEvents, 1) - targetNumRelays := servicekeeper.TargetNumRelays - relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty(ctx, keepers.Logger(), service.Id, targetNumRelays) + targetNumRelays := keepers.ServiceKeeper.GetParams(ctx).TargetNumRelays + relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty( + ctx, + keepers.Logger(), + service.Id, + targetNumRelays, + targetNumRelays, + ) numEstimatedComputUnits, err := claim.GetNumEstimatedComputeUnits(relayMiningDifficulty) require.NoError(t, err) diff --git a/x/proof/keeper/msg_server_submit_proof_test.go b/x/proof/keeper/msg_server_submit_proof_test.go index cca419533..35185f798 100644 --- a/x/proof/keeper/msg_server_submit_proof_test.go +++ b/x/proof/keeper/msg_server_submit_proof_test.go @@ -235,8 +235,14 @@ func TestMsgServer_SubmitProof_Success(t *testing.T) { proofSubmittedEvent := proofSubmittedEvents[0] - targetNumRelays := servicekeeper.TargetNumRelays - relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty(ctx, keepers.Logger(), service.Id, targetNumRelays) + targetNumRelays := keepers.ServiceKeeper.GetParams(ctx).TargetNumRelays + relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty( + ctx, + keepers.Logger(), + service.Id, + targetNumRelays, + targetNumRelays, + ) numEstimatedComputUnits, err := claim.GetNumEstimatedComputeUnits(relayMiningDifficulty) require.NoError(t, err) diff --git a/x/proof/keeper/proof_validation_test.go b/x/proof/keeper/proof_validation_test.go index f00022d2a..d3389f103 100644 --- a/x/proof/keeper/proof_validation_test.go +++ b/x/proof/keeper/proof_validation_test.go @@ -782,7 +782,14 @@ func setRelayMiningDifficultyHash( targetHash []byte, logger log.Logger, ) { - relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty(ctx, logger, serviceId, servicekeeper.TargetNumRelays) + targetNumRelays := serviceKeeper.GetParams(ctx).TargetNumRelays + relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty( + ctx, + logger, + serviceId, + targetNumRelays, + targetNumRelays, + ) relayMiningDifficulty.TargetHash = targetHash serviceKeeper.SetRelayMiningDifficulty(ctx, relayMiningDifficulty) } diff --git a/x/proof/types/expected_keepers.go b/x/proof/types/expected_keepers.go index 66103d2b8..9d1fd765e 100644 --- a/x/proof/types/expected_keepers.go +++ b/x/proof/types/expected_keepers.go @@ -63,4 +63,5 @@ type ServiceKeeper interface { // Only used for testing & simulation SetService(ctx context.Context, service sharedtypes.Service) SetRelayMiningDifficulty(ctx context.Context, relayMiningDifficulty servicetypes.RelayMiningDifficulty) + GetParams(ctx context.Context) servicetypes.Params } diff --git a/x/service/keeper/relay_mining_difficulty.go b/x/service/keeper/relay_mining_difficulty.go index eae318f91..05ac62a36 100644 --- a/x/service/keeper/relay_mining_difficulty.go +++ b/x/service/keeper/relay_mining_difficulty.go @@ -31,11 +31,18 @@ func (k Keeper) GetRelayMiningDifficulty( difficultyBz := store.Get(types.RelayMiningDifficultyKey(serviceId)) if difficultyBz == nil { + targetNumRelays := k.GetParams(ctx).TargetNumRelays k.Logger().Warn(fmt.Sprintf( "relayMiningDifficulty not found for service: %s, defaulting to base difficulty with protocol TargetNumRelays (%d)", - serviceId, TargetNumRelays, + serviceId, targetNumRelays, )) - difficulty = NewDefaultRelayMiningDifficulty(ctx, k.logger, serviceId, TargetNumRelays) + difficulty = NewDefaultRelayMiningDifficulty( + ctx, + k.logger, + serviceId, + targetNumRelays, + targetNumRelays, + ) return difficulty, false } diff --git a/x/service/keeper/update_relay_mining_difficulty.go b/x/service/keeper/update_relay_mining_difficulty.go index 0a3ac6fc8..b73e79131 100644 --- a/x/service/keeper/update_relay_mining_difficulty.go +++ b/x/service/keeper/update_relay_mining_difficulty.go @@ -16,15 +16,6 @@ import ( ) var ( - // TargetNumRelays is the target number of relays we want the network to mine for - // a specific service across all applications & suppliers per session. - // This number determines the total number of leafs to be created across in - // the off-chain SMTs, across all suppliers, for each service. - // It indirectly drives the off-chain resource requirements of the network - // in additional to playing a critical role in Relay Mining. - // TODO_MAINNET(#542): Make this a governance parameter and figure out the correct value. - TargetNumRelays = uint64(10e4) - // Exponential moving average (ema) smoothing factor, commonly known as alpha. // Usually, alpha = 2 / (N+1), where N is the number of periods. // Large alpha -> more weight on recent data; less smoothing and fast response. @@ -53,12 +44,19 @@ func (k Keeper) UpdateRelayMiningDifficulty( // Iterate over the relaysPerServiceMap deterministically by sorting the keys. // This ensures that the order of the keys is consistent across different nodes. // See comment: https://github.com/pokt-network/poktroll/pull/840#discussion_r1796663285 + targetNumRelays := k.GetParams(ctx).TargetNumRelays sortedRelayPerServiceMapKeys := getSortedMapKeys(relaysPerServiceMap) for _, serviceId := range sortedRelayPerServiceMapKeys { numRelays := relaysPerServiceMap[serviceId] prevDifficulty, found := k.GetRelayMiningDifficulty(ctx, serviceId) if !found { - prevDifficulty = NewDefaultRelayMiningDifficulty(ctx, logger, serviceId, numRelays) + prevDifficulty = NewDefaultRelayMiningDifficulty( + ctx, + logger, + serviceId, + numRelays, + targetNumRelays, + ) } // TODO_MAINNET(@Olshansk): We could potentially compute the smoothing factor @@ -83,7 +81,7 @@ func (k Keeper) UpdateRelayMiningDifficulty( // We kept scaling down even though numRelaysEma was decreasing. // To avoid continuing to increase the difficulty (i.e. scaling down), the // relative starting difficulty has to be kept constant. - difficultyHash := protocol.ComputeNewDifficultyTargetHash(protocol.BaseRelayDifficultyHashBz, TargetNumRelays, newRelaysEma) + difficultyHash := protocol.ComputeNewDifficultyTargetHash(protocol.BaseRelayDifficultyHashBz, targetNumRelays, newRelaysEma) newDifficulty := types.RelayMiningDifficulty{ ServiceId: serviceId, BlockHeight: sdkCtx.BlockHeight(), @@ -152,11 +150,12 @@ func NewDefaultRelayMiningDifficulty( logger log.Logger, serviceId string, numRelays uint64, + targetNumRelays uint64, ) types.RelayMiningDifficulty { logger = logger.With("helper", "NewDefaultRelayMiningDifficulty") // Compute the target hash based on the number of relays seen for the first time. - newDifficultyHash := protocol.ComputeNewDifficultyTargetHash(protocol.BaseRelayDifficultyHashBz, TargetNumRelays, numRelays) + newDifficultyHash := protocol.ComputeNewDifficultyTargetHash(protocol.BaseRelayDifficultyHashBz, targetNumRelays, numRelays) logger.Warn(types.ErrServiceMissingRelayMiningDifficulty.Wrapf( "No previous relay mining difficulty found for service %s.\n"+ diff --git a/x/service/keeper/update_relay_mining_difficulty_test.go b/x/service/keeper/update_relay_mining_difficulty_test.go index ed46c2ac2..87380e2c8 100644 --- a/x/service/keeper/update_relay_mining_difficulty_test.go +++ b/x/service/keeper/update_relay_mining_difficulty_test.go @@ -10,7 +10,6 @@ import ( "github.com/pokt-network/poktroll/pkg/crypto/protocol" testutilevents "github.com/pokt-network/poktroll/testutil/events" keepertest "github.com/pokt-network/poktroll/testutil/keeper" - servicekeeper "github.com/pokt-network/poktroll/x/service/keeper" servicetypes "github.com/pokt-network/poktroll/x/service/types" ) @@ -150,7 +149,8 @@ func TestUpdateRelayMiningDifficulty_Base(t *testing.T) { require.True(t, found) require.Less(t, difficultySvc22.NumRelaysEma, difficultySvc21.NumRelaysEma) // Since the relays EMA is lower than the target, the difficulty hash is all 1s - require.Less(t, difficultySvc22.NumRelaysEma, servicekeeper.TargetNumRelays) + targetNumRelays := keeper.GetParams(ctx).TargetNumRelays + require.Less(t, difficultySvc22.NumRelaysEma, targetNumRelays) require.Equal(t, difficultySvc22.TargetHash, makeBytesFullOfOnes(32)) // svc3 is new so the relay ema is equal to the first value provided @@ -172,29 +172,29 @@ func TestUpdateRelayMiningDifficulty_FirstDifficulty(t *testing.T) { }{ { desc: "First Difficulty way below target", - numRelays: servicekeeper.TargetNumRelays / 1e3, + numRelays: servicetypes.DefaultTargetNumRelays / 1e3, expectedRelayMiningDifficulty: servicetypes.RelayMiningDifficulty{ ServiceId: "svc1", BlockHeight: 1, - NumRelaysEma: servicekeeper.TargetNumRelays / 1e3, + NumRelaysEma: servicetypes.DefaultTargetNumRelays / 1e3, TargetHash: defaultDifficulty(), // default difficulty without any leading 0 bits }, }, { desc: "First Difficulty equal to target", - numRelays: servicekeeper.TargetNumRelays, + numRelays: servicetypes.DefaultTargetNumRelays, expectedRelayMiningDifficulty: servicetypes.RelayMiningDifficulty{ ServiceId: "svc1", BlockHeight: 1, - NumRelaysEma: servicekeeper.TargetNumRelays, + NumRelaysEma: servicetypes.DefaultTargetNumRelays, TargetHash: defaultDifficulty(), // default difficulty without any leading 0 bits }, }, { desc: "First Difficulty way above target", - numRelays: servicekeeper.TargetNumRelays * 1e3, + numRelays: servicetypes.DefaultTargetNumRelays * 1e3, expectedRelayMiningDifficulty: servicetypes.RelayMiningDifficulty{ ServiceId: "svc1", BlockHeight: 1, - NumRelaysEma: servicekeeper.TargetNumRelays * 1e3, + NumRelaysEma: servicetypes.DefaultTargetNumRelays * 1e3, TargetHash: append( []byte{0b00000000}, // at least 8 leading 0 bits makeBytesFullOfOnes(31)..., diff --git a/x/tokenomics/keeper/keeper_settle_pending_claims_test.go b/x/tokenomics/keeper/keeper_settle_pending_claims_test.go index 09a18c1b0..f40d66890 100644 --- a/x/tokenomics/keeper/keeper_settle_pending_claims_test.go +++ b/x/tokenomics/keeper/keeper_settle_pending_claims_test.go @@ -167,7 +167,14 @@ func (s *TestSuite) SetupTest() { // Calculate the number of claimed compute units. s.numClaimedComputeUnits = s.numRelays * service.ComputeUnitsPerRelay - s.relayMiningDifficulty = servicekeeper.NewDefaultRelayMiningDifficulty(sdkCtx, s.keepers.Logger(), testServiceId, servicekeeper.TargetNumRelays) + targetNumRelays := s.keepers.ServiceKeeper.GetParams(sdkCtx).TargetNumRelays + s.relayMiningDifficulty = servicekeeper.NewDefaultRelayMiningDifficulty( + sdkCtx, + s.keepers.Logger(), + testServiceId, + targetNumRelays, + targetNumRelays, + ) // Calculate the number of estimated compute units. s.numEstimatedComputeUnits = getEstimatedComputeUnits(s.numClaimedComputeUnits, s.relayMiningDifficulty) diff --git a/x/tokenomics/keeper/settle_pending_claims.go b/x/tokenomics/keeper/settle_pending_claims.go index 249971f00..fa1995de2 100644 --- a/x/tokenomics/keeper/settle_pending_claims.go +++ b/x/tokenomics/keeper/settle_pending_claims.go @@ -86,7 +86,14 @@ func (k Keeper) SettlePendingClaims(ctx cosmostypes.Context) ( serviceId := claim.GetSessionHeader().GetServiceId() relayMiningDifficulty, found := k.serviceKeeper.GetRelayMiningDifficulty(ctx, serviceId) if !found { - relayMiningDifficulty = servicekeeper.NewDefaultRelayMiningDifficulty(ctx, logger, serviceId, servicekeeper.TargetNumRelays) + targetNumRelays := k.serviceKeeper.GetParams(ctx).TargetNumRelays + relayMiningDifficulty = servicekeeper.NewDefaultRelayMiningDifficulty( + ctx, + logger, + serviceId, + targetNumRelays, + targetNumRelays, + ) } // numEstimatedComputeUnits is the probabilistic estimation of the off-chain // work done by the relay miner in this session. It is derived from the claimed diff --git a/x/tokenomics/keeper/token_logic_modules.go b/x/tokenomics/keeper/token_logic_modules.go index 05ab91f00..fbf95db66 100644 --- a/x/tokenomics/keeper/token_logic_modules.go +++ b/x/tokenomics/keeper/token_logic_modules.go @@ -150,7 +150,14 @@ func (k Keeper) ProcessTokenLogicModules( // Retrieving the relay mining difficulty for service. relayMiningDifficulty, found := k.serviceKeeper.GetRelayMiningDifficulty(ctx, service.Id) if !found { - relayMiningDifficulty = servicekeeper.NewDefaultRelayMiningDifficulty(ctx, logger, service.Id, servicekeeper.TargetNumRelays) + targetNumRelays := k.serviceKeeper.GetParams(ctx).TargetNumRelays + relayMiningDifficulty = servicekeeper.NewDefaultRelayMiningDifficulty( + ctx, + logger, + service.Id, + targetNumRelays, + targetNumRelays, + ) } sharedParams := k.sharedKeeper.GetParams(ctx) diff --git a/x/tokenomics/types/expected_keepers.go b/x/tokenomics/types/expected_keepers.go index cac324d16..c7c0de0c5 100644 --- a/x/tokenomics/types/expected_keepers.go +++ b/x/tokenomics/types/expected_keepers.go @@ -94,4 +94,6 @@ type ServiceKeeper interface { UpdateRelayMiningDifficulty(ctx context.Context, relaysPerServiceMap map[string]uint64) (map[string]servicetypes.RelayMiningDifficulty, error) // Only used for testing & simulation SetService(ctx context.Context, service sharedtypes.Service) + GetParams(ctx context.Context) servicetypes.Params + SetParams(ctx context.Context, params servicetypes.Params) error } From fa86fe8716101dedfbdd98b3e5a2e3a68bd85bb5 Mon Sep 17 00:00:00 2001 From: "Dima K." Date: Wed, 27 Nov 2024 15:13:37 -0800 Subject: [PATCH 07/21] [Docs] Upgrade list (#928) ## Summary Add recent Alpha TestNet upgrades ## Type of change Select one or more from the following: - [ ] New feature, functionality or library - [ ] Consensus breaking; add the `consensus-breaking` label if so. See #791 for details - [ ] Bug fix - [ ] Code health or cleanup - [x] Documentation - [ ] Other (specify) ## Testing - [x] **Documentation**: `make docusaurus_start`; only needed if you make doc changes - [ ] **Unit Tests**: `make go_develop_and_test` - [ ] **LocalNet E2E Tests**: `make test_e2e` - [ ] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR. ## Sanity Checklist - [x] I have tested my changes using the available tooling - [ ] I have commented my code - [x] I have performed a self-review of my own code; both comments & source code - [ ] I create and reference any new tickets, if applicable - [x] I have left TODOs throughout the codebase, if applicable --------- Co-authored-by: Daniel Olshansky --- .../docker_compose_debian_cheatsheet.md | 7 ++++ .../quickstart/docker_compose_walkthrough.md | 5 +++ .../docs/protocol/upgrades/upgrade_list.md | 35 ++++++++++++------- tools/scripts/tx_jsons/staking_params.json | 18 ++++++++++ .../scripts/tx_jsons/staking_validator2.json | 16 +++++++++ .../scripts/tx_jsons/staking_validator3.json | 16 +++++++++ 6 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 tools/scripts/tx_jsons/staking_params.json create mode 100644 tools/scripts/tx_jsons/staking_validator2.json create mode 100644 tools/scripts/tx_jsons/staking_validator3.json diff --git a/docusaurus/docs/operate/quickstart/docker_compose_debian_cheatsheet.md b/docusaurus/docs/operate/quickstart/docker_compose_debian_cheatsheet.md index ad7d2b632..c75358cb1 100644 --- a/docusaurus/docs/operate/quickstart/docker_compose_debian_cheatsheet.md +++ b/docusaurus/docs/operate/quickstart/docker_compose_debian_cheatsheet.md @@ -119,6 +119,13 @@ source ~/.bashrc ## Start up the full node + +:::warning +The Alpha TestNet currently requires manual steps to sync the node to the latest block. Please find the affected block(s) +in [this document](../../protocol/upgrades/upgrade_list.md), which leads to the manual upgrade instructions. +::: + + ```bash docker compose up -d full-node # Optional: watch the block height sync up & logs diff --git a/docusaurus/docs/operate/quickstart/docker_compose_walkthrough.md b/docusaurus/docs/operate/quickstart/docker_compose_walkthrough.md index 1d0518d7f..e2a83d340 100644 --- a/docusaurus/docs/operate/quickstart/docker_compose_walkthrough.md +++ b/docusaurus/docs/operate/quickstart/docker_compose_walkthrough.md @@ -192,6 +192,11 @@ olshansky ALL=(ALL) NOPASSWD:ALL ### Launch the Node +:::warning +The Alpha TestNet currently requires manual steps to sync the node to the latest block. Please find the affected block(s) +in [this document](../../protocol/upgrades/upgrade_list.md), which leads to the manual upgrade instructions. +::: + _Note: You may need to replace `docker-compose` with `docker compose` if you are running a newer version of Docker where `docker-compose` is integrated into `docker` itself._ diff --git a/docusaurus/docs/protocol/upgrades/upgrade_list.md b/docusaurus/docs/protocol/upgrades/upgrade_list.md index f4b2c8d19..6480086c3 100644 --- a/docusaurus/docs/protocol/upgrades/upgrade_list.md +++ b/docusaurus/docs/protocol/upgrades/upgrade_list.md @@ -8,8 +8,10 @@ sidebar_position: 1 The tables below provide a list of past and upcoming protocol upgrades. For more detailed information about what upgrades are, how they work, and what changes they bring to the protocol, please refer to our [upgrade overview page](./protocol_upgrades.md). - [Legend](#legend) -- [TestNet](#testnet) - [MainNet](#mainnet) +- [Beta TestNet](#beta-testnet) +- [Alpha TestNet](#alpha-testnet) + - [Syncing from genesis - manual steps](#syncing-from-genesis---manual-steps) ## Legend @@ -18,21 +20,30 @@ The tables below provide a list of past and upcoming protocol upgrades. For more - ❓ - Unknown/To Be Determined - ⚠️ - Warning/Caution Required -## TestNet +## MainNet +Coming... + +## Beta TestNet +| Version | Planned | Breaking | Requires Manual Intervention | Upgrade Height | +| -------------------------------------------------------------------------------- | :-----: | :------: | :--------------------------: | -------------- | +| [`v0.0.11-rc`](https://github.com/pokt-network/poktroll/releases/tag/v0.0.11-rc) | N/A | N/A | ❌ genesis version | N/A | + +## Alpha TestNet :::warning -This table is currently incomplete and does not include all protocol upgrades. Our recent TestNet upgrades, which were performed via a regenesis, are not listed here. +Some manual steps are currently required to sync to the latest block. Please follow instructions below. ::: - + -| Version | Planned | Breaking | Requires Manual Intervention | Upgrade Height | -| ------------------------------------------------------------------------ | :-----: | :------: | :---------------------------------: | -------------- | -| [`v0.0.7`](https://github.com/pokt-network/poktroll/releases/tag/v0.0.7) | ❓ | ❓ | βœ… (Alpha TestNet Participants Only) | ❓ | -| [`v0.0.6`](https://github.com/pokt-network/poktroll/releases/tag/v0.0.6) | ❓ | ❓ | βœ… (Alpha TestNet Participants Only) | ❓ | -| [`v0.0.5`](https://github.com/pokt-network/poktroll/releases/tag/v0.0.5) | ❓ | ❓ | βœ… (Alpha TestNet Participants Only) | ❓ | -| [`v0.0.4`](https://github.com/pokt-network/poktroll/releases/tag/v0.0.4) | ❓ | ❓ | βœ… (Alpha TestNet Participants Only) | ❓ | +| Version | Planned | Breaking | Requires Manual Intervention | Upgrade Height | +| ---------------------------------------------------------------------------- | :-----: | :------: | :--------------------------------------------------------------------------------------------------------------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------- | +| [`v0.0.10`](https://github.com/pokt-network/poktroll/releases/tag/v0.0.10) | βœ… | βœ… | ❌ (automatic upgrade) | [56860](https://shannon.alpha.testnet.pokt.network/poktroll/tx/4E201E5C397AB881F417266154C907D38404BE00BE9A443DE28E44A2B09C5CFB) | +| [`v0.0.9-4`](https://github.com/pokt-network/poktroll/releases/tag/v0.0.9-4) | ❌ | βœ… | ⚠️ [follow manual upgrade instructions](https://github.com/pokt-network/poktroll/releases/tag/v0.0.9-4) ⚠️ | `46329` | +| [`v0.0.9-3`](https://github.com/pokt-network/poktroll/releases/tag/v0.0.9-3) | ❌ | βœ… | ❌ Active Alpha TestNet Participants Only: [follow manual upgrade instructions](https://github.com/pokt-network/poktroll/releases/tag/v0.0.9-3) | `17102` | +| [`v0.0.9`](https://github.com/pokt-network/poktroll/releases/tag/v0.0.9) | N/A | N/A | ❌ genesis version | N/A | -## MainNet +### Syncing from genesis - manual steps + -Coming... +When syncing Alpha TestNet from the first block, the node will fail at height `46329`. Some manual steps are required in order for it to continue. Please [follow manual upgrade instructions](https://github.com/pokt-network/poktroll/releases/tag/v0.0.9-4). diff --git a/tools/scripts/tx_jsons/staking_params.json b/tools/scripts/tx_jsons/staking_params.json new file mode 100644 index 000000000..fc5074a44 --- /dev/null +++ b/tools/scripts/tx_jsons/staking_params.json @@ -0,0 +1,18 @@ +{ + "body": { + "messages": [ + { + "@type": "/cosmos.staking.v1beta1.MsgUpdateParams", + "authority": "pokt10d07y265gmmuvt4z0w9aw880jnsr700j8yv32t", + "params": { + "bond_denom": "upokt", + "historical_entries": 10000, + "max_entries": 7, + "max_validators": 3, + "min_commission_rate": "0", + "unbonding_time": "504h0m0s" + } + } + ] + } +} \ No newline at end of file diff --git a/tools/scripts/tx_jsons/staking_validator2.json b/tools/scripts/tx_jsons/staking_validator2.json new file mode 100644 index 000000000..d64e2db42 --- /dev/null +++ b/tools/scripts/tx_jsons/staking_validator2.json @@ -0,0 +1,16 @@ +{ + "pubkey": { + "@type": "/cosmos.crypto.ed25519.PubKey", + "key": "ojUaD7c/Ssmor53eOMl0BNczr4u1VdgVnUL+IQFcC/g=" + }, + "amount": "900000000upokt", + "moniker": "validator2", + "identity": "", + "website": "", + "security": "", + "details": "", + "commission-rate": "0.100000000000000000", + "commission-max-rate": "0.200000000000000000", + "commission-max-change-rate": "0.01000000000000000", + "min-self-delegation": "1" +} \ No newline at end of file diff --git a/tools/scripts/tx_jsons/staking_validator3.json b/tools/scripts/tx_jsons/staking_validator3.json new file mode 100644 index 000000000..86c76a7a1 --- /dev/null +++ b/tools/scripts/tx_jsons/staking_validator3.json @@ -0,0 +1,16 @@ +{ + "pubkey": { + "@type": "/cosmos.crypto.ed25519.PubKey", + "key": "U+Qi//fZhYtbr25PsWqFQZpxft3erzyrg2cWbLOj6+A=" + }, + "amount": "900000000upokt", + "moniker": "validator3", + "identity": "", + "website": "", + "security": "", + "details": "", + "commission-rate": "0.100000000000000000", + "commission-max-rate": "0.200000000000000000", + "commission-max-change-rate": "0.01000000000000000", + "min-self-delegation": "1" +} \ No newline at end of file From 76d131c07540581a2541de27536f1c7cdd738f35 Mon Sep 17 00:00:00 2001 From: "Dima K." Date: Wed, 27 Nov 2024 15:25:41 -0800 Subject: [PATCH 08/21] [Docs/Tools] Validator: support multiple networks + cheat sheet (#941) ## Summary Allows to support multiple networks in the installation script. ## Issue - https://github.com/pokt-network/pocket-network-genesis/pull/9 --- .../docker_compose_debian_cheatsheet.md | 21 +- .../quickstart/full_node_cheatsheet.md | 145 ++++++++++ .../quickstart/validator_cheatsheet.md | 14 - .../run_a_node/full_node_cosmovisor.md | 108 -------- .../run_a_node/full_node_walkthrough.md | 252 ++++++++++++++++++ .../run_a_node/validator_walkthrough.md | 8 - .../protocol/upgrades/protocol_upgrades.md | 2 +- .../protocol/upgrades/upgrade_procedure.md | 4 +- tools/installer/full-node.sh | 147 ++++++++-- 9 files changed, 544 insertions(+), 157 deletions(-) create mode 100644 docusaurus/docs/operate/quickstart/full_node_cheatsheet.md delete mode 100644 docusaurus/docs/operate/quickstart/validator_cheatsheet.md delete mode 100644 docusaurus/docs/operate/run_a_node/full_node_cosmovisor.md create mode 100644 docusaurus/docs/operate/run_a_node/full_node_walkthrough.md delete mode 100644 docusaurus/docs/operate/run_a_node/validator_walkthrough.md diff --git a/docusaurus/docs/operate/quickstart/docker_compose_debian_cheatsheet.md b/docusaurus/docs/operate/quickstart/docker_compose_debian_cheatsheet.md index c75358cb1..7a1157639 100644 --- a/docusaurus/docs/operate/quickstart/docker_compose_debian_cheatsheet.md +++ b/docusaurus/docs/operate/quickstart/docker_compose_debian_cheatsheet.md @@ -72,7 +72,7 @@ sudo apt-get update if command -v ufw > /dev/null 2>&1; then sudo ufw allow from 172.16.0.0/12 sudo ufw allow from 192.168.0.0/16 - echo "UFW rules added for Docker networks" + echo "UFW rules added for Docker networks and validator endpoint" else echo "UFW is not installed, skipping firewall configuration" fi @@ -106,9 +106,18 @@ cd poktroll-docker-compose-example ## Update your environment +First, copy the sample environment file: ```bash cp .env.sample .env +``` + +By default, the `.env` file uses `testnet-beta`. If you want to use a different network, update the `NETWORK_NAME` in your `.env` file to one of: +- `testnet-alpha` - Unstable testnet +- `testnet-beta` - Stable testnet (default) +- `mainnet` - Production network +Then set your external IP and source the environment: +```bash EXTERNAL_IP=$(curl -4 ifconfig.me/ip) sed -i -e s/NODE_HOSTNAME=/NODE_HOSTNAME=$EXTERNAL_IP/g .env @@ -169,15 +178,19 @@ FINALLY, `source .env` to update the environment variables. ## Fund your accounts -Run the following: +Run the following to see your addresses: ```bash show_actor_addresses ``` -For each one, fund the accounts using the [faucet](https://faucet.testnet.pokt.network/) +Get the faucet URL for your network: + +```bash +show_faucet_url +``` -Next, run this helper (it's part of `helpers.sh`) to find each of them on the explorer: +Fund each address using the faucet URL shown above. Then run this helper to find each account on the explorer: ```bash show_explorer_urls diff --git a/docusaurus/docs/operate/quickstart/full_node_cheatsheet.md b/docusaurus/docs/operate/quickstart/full_node_cheatsheet.md new file mode 100644 index 000000000..d2986bb30 --- /dev/null +++ b/docusaurus/docs/operate/quickstart/full_node_cheatsheet.md @@ -0,0 +1,145 @@ +--- +sidebar_position: 3 +title: Full Node Cheat Sheet +--- + +This cheat sheet provides quick instructions for installing a Full Node using an automated script. + +- [Pre-Requisites](#pre-requisites) +- [Install a Full Node using Cosmovisor](#install-a-full-node-using-cosmovisor) +- [What Gets Installed](#what-gets-installed) +- [Useful Commands](#useful-commands) + - [Check the status of your node](#check-the-status-of-your-node) + - [View the logs](#view-the-logs) + - [Stop the node](#stop-the-node) + - [Start the node](#start-the-node) + - [Restart the node](#restart-the-node) + - [Advanced Operations](#advanced-operations) +- [Automatic Upgrades](#automatic-upgrades) + +### Pre-Requisites + +1. **Linux-based System**: Ensure you have a Debian-based Linux distribution (other distributions may work but are not fully supported). +2. **Root or Sudo Access**: You need administrative privileges to run the installation script. +3. **Dedicated Server or Virtual Machine**: Any provider should work (Vultr and Hetzner have been tested). + +### Install a Full Node using Cosmovisor + +To install and set up a Full Node, follow these steps: + +1. **Download the Installation Script**: + + ```bash + curl -O https://raw.githubusercontent.com/pokt-network/poktroll/main/tools/installer/full-node.sh + ``` + +2. **Run the Script with Sudo Privileges**: + + ```bash + sudo bash full-node.sh + ``` + +3. **Follow the Prompts**: + + - **Choose the Network**: Select `testnet-alpha`, `testnet-beta`, or `mainnet`. + - **Set Username**: Input the desired username to run `poktrolld` (default: `poktroll`). + - **Set Node Moniker**: Input the node moniker (default: your hostname). + - **Confirm Seeds and Genesis File**: The script fetches seeds and the genesis file automatically. + - **External IP Address**: The script detects your external IP address. Confirm or input manually if incorrect. + +The script will handle the installation of dependencies, user creation, environment variable setup, and configuration of Cosmovisor and `poktrolld`. + +### What Gets Installed + +When you run the installation script, the following components are set up: + +1. **System User**: A dedicated user (default: `poktroll`) is created to run the node securely. + +2. **Cosmovisor**: A binary manager that handles chain upgrades automatically: + - Location: `/home/poktroll/bin/cosmovisor` + - Purpose: Manages different versions of `poktrolld` and handles chain upgrades + - Configuration: Set up to automatically download and switch to new binaries during upgrades + +3. **Poktrolld**: The core node software: + - Location: `/home/poktroll/.poktroll/cosmovisor/genesis/bin/poktrolld` + - Configuration: `/home/poktroll/.poktroll/config/` + - Data: `/home/poktroll/.poktroll/data/` + +4. **Systemd Service**: A service that manages the node: + - Name: `cosmovisor.service` + - Status: Enabled and started automatically + - Configured for automatic restarts and upgrades + +### Useful Commands + +After installation, you can manage your node using the following commands: + +#### Check the status of your node + +```bash +sudo systemctl status cosmovisor.service +``` + +#### View the logs + +```bash +sudo journalctl -u cosmovisor.service -f +``` + +#### Stop the node + +```bash +sudo systemctl stop cosmovisor.service +``` + +#### Start the node + +```bash +sudo systemctl start cosmovisor.service +``` + +#### Restart the node + +```bash +sudo systemctl restart cosmovisor.service +``` + +#### Advanced Operations + +Check the current version: +```bash +sudo -u poktroll poktrolld version +``` + +View the Cosmovisor directory structure: +```bash +ls -la /home/poktroll/.poktroll/cosmovisor/ +``` + +Check if an upgrade is available: +```bash +ls -la /home/poktroll/.poktroll/cosmovisor/upgrades/ +``` + +View node configuration: +```bash +cat /home/poktroll/.poktroll/config/config.toml +``` + +### Automatic Upgrades + +Your node is configured to handle chain upgrades automatically through Cosmovisor. When a chain upgrade is proposed and approved: + +1. Cosmovisor will download the new binary +2. The node will stop at the designated upgrade height +3. Cosmovisor will switch to the new binary +4. The node will restart automatically + +No manual intervention is required for standard upgrades. + + diff --git a/docusaurus/docs/operate/quickstart/validator_cheatsheet.md b/docusaurus/docs/operate/quickstart/validator_cheatsheet.md deleted file mode 100644 index d09097e4b..000000000 --- a/docusaurus/docs/operate/quickstart/validator_cheatsheet.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -sidebar_position: 3 -title: Validator Cheat Sheet ---- - -## Validator Cheat Sheet - -:::tip - -See the [Validator Walkthrough](./../run_a_node/validator_walkthrough.md) for an in-depth guide on setting up a Validator Node. - -::: - -TODO_BETA(@okdas): Finish this page. diff --git a/docusaurus/docs/operate/run_a_node/full_node_cosmovisor.md b/docusaurus/docs/operate/run_a_node/full_node_cosmovisor.md deleted file mode 100644 index e8bb2ee3b..000000000 --- a/docusaurus/docs/operate/run_a_node/full_node_cosmovisor.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: Full Node (Cosmovisor) -sidebar_position: 2 ---- - -## Run a Full Node using Cosmovisor - -This document provides instructions on using the official Cosmos SDK [Cosmosvisor](https://docs.cosmos.network/v0.45/run-node/cosmovisor.html) to run a full Pocket Network node. - -- [What is a Full Node](#what-is-a-full-node) -- [What is Cosmovisor](#what-is-cosmovisor) -- [Installation Instructions](#installation-instructions) - - [Prerequisites](#prerequisites) - - [Installation Steps](#installation-steps) -- [Useful Command Cheat Sheet](#useful-command-cheat-sheet) - - [Check the status of your node](#check-the-status-of-your-node) - - [View the logs](#view-the-logs) - - [Stop the node](#stop-the-node) - - [Start the node](#start-the-node) - - [Restart the node](#restart-the-node) - -### What is a Full Node - -In blockchain networks, a full node retains continuous synchs and updates the latest copy of the ledger. It may either be a pruned full node (the latest data only) or an archival full node (including complete and historical data). - -You can visit the [Cosmos SDK documentation](https://docs.cosmos.network/main/user/run-node/run-node) for more information on Full Nodes. - -### What is Cosmovisor - -[Cosmovisor](https://docs.cosmos.network/main/build/tooling/cosmovisor) is a tool that automates the version management for our blockchain. It allows operators to automatically upgrade their full nodes and validators without downtime and reduce maintenance overhead. - -### Installation Instructions - -To install and set up a Poktroll Full Node using Cosmovisor, we provide a comprehensive installation script. This script will handle all the necessary steps, including user creation, dependency installation, Cosmovisor and Poktrolld setup, and system configuration. - -#### Prerequisites - -- A Linux-based system (Debian-based distributions are fully supported, others may work as well) -- Root or sudo access -- A dedicated server or a virtual machine (any provider should work, Vultr and Hetzner have been tested) - -#### Installation Steps - -1. Download the installation script: - - ```bash - curl -O https://raw.githubusercontent.com/pokt-network/poktroll/main/tools/installer/full-node.sh - ``` - -2. Make the script executable: - - ```bash - chmod +x full-node.sh - ``` - -3. Run the script with sudo privileges: - - ```bash - sudo ./full-node.sh - ``` - -4. Follow the prompts to provide the necessary information: - - Desired username to run poktrolld (`default: poktroll`) - - Node moniker (`default: hostname`) - - Seeds (`default: fetched` [from the official source](https://github.com/pokt-network/pocket-network-genesis/tree/master/shannon/alpha)) - - Chain ID (`default: poktroll-testnet`) - -The script will then proceed with the installation and setup process. - -### Useful Command Cheat Sheet - -After the installation is complete, your Poktroll Full Node should be up and running. - -:::tip -Remember to keep your system updated and monitor your node regularly to ensure its proper functioning and security. -::: - -Here are some useful commands for managing your node: - -#### Check the status of your node - -```bash - sudo systemctl status cosmovisor.service -``` - -#### View the logs - -```bash -sudo journalctl -u cosmovisor.service -f -``` - -#### Stop the node - -```bash -sudo systemctl stop cosmovisor.service -``` - -#### Start the node - -```bash -sudo systemctl start cosmovisor.service -``` - -#### Restart the node - -```bash -sudo systemctl restart cosmovisor.service -``` diff --git a/docusaurus/docs/operate/run_a_node/full_node_walkthrough.md b/docusaurus/docs/operate/run_a_node/full_node_walkthrough.md new file mode 100644 index 000000000..d0adb768c --- /dev/null +++ b/docusaurus/docs/operate/run_a_node/full_node_walkthrough.md @@ -0,0 +1,252 @@ +--- +title: Full Node (systemd) +sidebar_position: 2 +--- + +## Run a Validator + +This walkthrough provides step-by-step instructions to manually install and configure a Full Node from scratch. + +- [Introduction](#introduction) +- [Pre-Requisites](#pre-requisites) +- [Step 1: Create a New User](#step-1-create-a-new-user) +- [Step 2: Install Dependencies](#step-2-install-dependencies) +- [Step 3: Set Up Environment Variables](#step-3-set-up-environment-variables) +- [Step 4: Install Cosmovisor](#step-4-install-cosmovisor) +- [Step 5: Install `poktrolld`](#step-5-install-poktrolld) +- [Step 6: Configure `poktrolld`](#step-6-configure-poktrolld) +- [Step 7: Set Up `systemd` Service](#step-7-set-up-systemd-service) +- [Step 8: Open Firewall Ports](#step-8-open-firewall-ports) +- [Next Steps](#next-steps) + +### Introduction + +This guide will help you install a Full Node for Pocket Network manually, giving you control over each step of the process. Running a Full Node is the first step toward becoming a Validator. + +**TL;DR**: If you're comfortable using an automated script, check out the [Full Node Cheat Sheet](../quickstart/full_node_cheatsheet.md) for quick setup instructions. + +### Pre-Requisites + +- **Linux-based System**: Preferably Debian-based distributions. +- **Root or Sudo Access**: Administrative privileges are required. +- **Dedicated Server or Virtual Machine**: Any provider is acceptable. + +### Step 1: Create a New User + +Create a dedicated user to run `poktrolld`: + +```bash +sudo adduser poktroll +``` + +Set a password when prompted, and add the user to the sudo group: + +```bash +sudo usermod -aG sudo poktroll +``` + +### Step 2: Install Dependencies + +Update your package list and install necessary dependencies: + +```bash +sudo apt-get update +sudo apt-get install -y curl tar wget jq +``` + +### Step 3: Set Up Environment Variables + +Switch to the `poktroll` user and set environment variables required for Cosmovisor: + +```bash +sudo su - poktroll +``` + +Add the following to your `.profile`: + +```bash +echo "export DAEMON_NAME=poktrolld" >> ~/.profile +echo "export DAEMON_HOME=\$HOME/.poktroll" >> ~/.profile +echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.profile +echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.profile +echo "export UNSAFE_SKIP_BACKUP=false" >> ~/.profile +source ~/.profile +``` + +### Step 4: Install Cosmovisor + +Download and install Cosmovisor: + +:::info +Alternatively, you can follow the [official cosmovisor installation instructions](https://docs.cosmos.network/main/build/tooling/cosmovisor#installation). +::: + +```bash +mkdir -p $HOME/.local/bin +COSMOVISOR_VERSION="v1.6.0" +ARCH=$(uname -m) +if [ "$ARCH" = "x86_64" ]; then + ARCH="amd64" +elif [ "$ARCH" = "aarch64" ]; then + ARCH="arm64" +fi + +curl -L "https://github.com/cosmos/cosmos-sdk/releases/download/cosmovisor%2F${COSMOVISOR_VERSION}/cosmovisor-${COSMOVISOR_VERSION}-linux-${ARCH}.tar.gz" | tar -zxvf - -C $HOME/.local/bin +echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.profile +source ~/.profile +``` + + +### Step 5: Install `poktrolld` + +Download and install `poktrolld`: + +1. **Download Genesis and Extract Version**: + + ```bash + # Select network (testnet-alpha, testnet-beta, or mainnet) + NETWORK="testnet-beta" # Change this to your desired network + + # Create config directory if it doesn't exist + mkdir -p $HOME/.poktroll/config + + # Download genesis file + GENESIS_URL="https://raw.githubusercontent.com/pokt-network/pocket-network-genesis/master/shannon/${NETWORK}/genesis.json" + curl -s -o $HOME/.poktroll/config/genesis.json "$GENESIS_URL" + + # Extract version and set architecture + POKTROLLD_VERSION=$(jq -r '.app_version' < $HOME/.poktroll/config/genesis.json) + ARCH=$(uname -m) + if [ "$ARCH" = "x86_64" ]; then ARCH="amd64" + elif [ "$ARCH" = "aarch64" ]; then ARCH="arm64" + fi + ``` + +2. **Download and Install the Binary**: + + Create the cosmovisor genesis directory and download the binary. + ```bash + mkdir -p $HOME/.poktroll/cosmovisor/genesis/bin + curl -L "https://github.com/pokt-network/poktroll/releases/download/v${POKTROLLD_VERSION}/poktroll_linux_${ARCH}.tar.gz" | tar -zxvf - -C $HOME/.poktroll/cosmovisor/genesis/bin + chmod +x $HOME/.poktroll/cosmovisor/genesis/bin/poktrolld + ln -sf $HOME/.poktroll/cosmovisor/genesis/bin/poktrolld $HOME/.local/bin/poktrolld + ``` + +### Step 6: Configure `poktrolld` + +Initialize configuration files and set up the node: + +1. **Extract Chain ID and Initialize Node**: + + ```bash + # Extract chain-id from existing genesis + CHAIN_ID=$(jq -r '.chain_id' < $HOME/.poktroll/config/genesis.json) + + # Initialize the node + poktrolld init "YourNodeMoniker" --chain-id="$CHAIN_ID" --home=$HOME/.poktroll + ``` + + :::note + You may see a message saying `genesis.json file already exists`. This is expected since we downloaded the genesis file in Step 5. The initialization will still complete successfully and set up the required configuration files. + ::: + +2. **Set Seeds**: + + ```bash + SEEDS_URL="https://raw.githubusercontent.com/pokt-network/pocket-network-genesis/master/shannon/${NETWORK}/seeds" + SEEDS=$(curl -s "$SEEDS_URL") + sed -i -e "s|^seeds *=.*|seeds = \"$SEEDS\"|" $HOME/.poktroll/config/config.toml + ``` + +3. **Set External Address**: + + ```bash + EXTERNAL_IP=$(curl -s https://api.ipify.org) + sed -i -e "s|^external_address *=.*|external_address = \"${EXTERNAL_IP}:26656\"|" $HOME/.poktroll/config/config.toml + ``` + +### Step 7: Set Up `systemd` Service + +Create a `systemd` service file to manage the node: + +```bash +sudo tee /etc/systemd/system/cosmovisor.service > /dev/null < diff --git a/docusaurus/docs/operate/run_a_node/validator_walkthrough.md b/docusaurus/docs/operate/run_a_node/validator_walkthrough.md deleted file mode 100644 index 49fabfb3a..000000000 --- a/docusaurus/docs/operate/run_a_node/validator_walkthrough.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: Validator Walkthrough -sidebar_position: 6 ---- - -# Run a Validator - -TODO_BETA(@okdas): Update this page with all the details. diff --git a/docusaurus/docs/protocol/upgrades/protocol_upgrades.md b/docusaurus/docs/protocol/upgrades/protocol_upgrades.md index 61b86e29e..684bc8e7a 100644 --- a/docusaurus/docs/protocol/upgrades/protocol_upgrades.md +++ b/docusaurus/docs/protocol/upgrades/protocol_upgrades.md @@ -5,7 +5,7 @@ sidebar_position: 1 # Protocol Upgrades -Pocket Network is continuously evolving through regular protocol upgrades. We implement software upgrades via a DAO process, allowing validator nodes to incorporate consensus-breaking changes. These upgrades can be automatically applied when using [Cosmovisor](../../operate/run_a_node/full_node_cosmovisor.md), or manually if not using `cosmovisor`. +Pocket Network is continuously evolving through regular protocol upgrades. We implement software upgrades via a DAO process, allowing validator nodes to incorporate consensus-breaking changes. These upgrades can be automatically applied when using [Cosmovisor](../../operate/run_a_node/full_node_walkthrough.md), or manually if not using `cosmovisor`. - [What is a Protocol Upgrade?](#what-is-a-protocol-upgrade) - [List of Upgrades](#list-of-upgrades) diff --git a/docusaurus/docs/protocol/upgrades/upgrade_procedure.md b/docusaurus/docs/protocol/upgrades/upgrade_procedure.md index b1098f509..2e0998251 100644 --- a/docusaurus/docs/protocol/upgrades/upgrade_procedure.md +++ b/docusaurus/docs/protocol/upgrades/upgrade_procedure.md @@ -27,7 +27,7 @@ When a consensus-breaking change is made to the protocol, we must carefully eval 2. **Implementation**: The proposed changes are implemented in the codebase. 3. **Testing**: Thorough testing of the proposed changes is conducted in devnet and testnet environments before mainnet deployment. 4. **Announcement**: Upon successful testing, we announce the upgrade through our social media channels and community forums. -5. **Deployment**: An upgrade transaction is sent to the network, allowing node operators using [Cosmovisor](../../operate/run_a_node/full_node_cosmovisor.md) to automatically upgrade their nodes at the specified block height. +5. **Deployment**: An upgrade transaction is sent to the network, allowing node operators using [Cosmovisor](../../operate/run_a_node/full_node_walkthrough.md) to automatically upgrade their nodes at the specified block height. 6. **Monitoring**: Post-deployment, we closely monitor the network to ensure everything functions as expected. ## When is an Upgrade Warranted? @@ -112,7 +112,7 @@ We use Kubernetes to manage software versions, including validators. Introducing ### TestNet -We currently deploy TestNet validators using Kubernetes with helm charts, which prevents us from managing the validator with `cosmovisor`. We do not control what other TestNet participants are running. However, if participants have deployed their nodes using the [cosmovisor guide](../../operate/run_a_node/full_node_cosmovisor.md), their nodes will upgrade automatically. +We currently deploy TestNet validators using Kubernetes with helm charts, which prevents us from managing the validator with `cosmovisor`. We do not control what other TestNet participants are running. However, if participants have deployed their nodes using the [cosmovisor guide](../../operate/run_a_node/full_node_walkthrough.md), their nodes will upgrade automatically. Until we transition to [cosmos-operator](https://github.com/strangelove-ventures/cosmos-operator), which supports scheduled upgrades (although not fully automatic like `cosmovisor`), we need to manually manage the process: diff --git a/tools/installer/full-node.sh b/tools/installer/full-node.sh index 0804bc278..1274933de 100644 --- a/tools/installer/full-node.sh +++ b/tools/installer/full-node.sh @@ -8,6 +8,9 @@ GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color +# DEV_NOTE: For testing purposes, you can change the branch name before merging to master. +POCKET_NETWORK_GENESIS_BRANCH="master" + # Function to print colored output print_color() { COLOR=$1 @@ -23,19 +26,72 @@ check_root() { fi } +# Function to install jq if not installed +install_jq() { + if ! command -v jq &> /dev/null; then + print_color $YELLOW "Installing jq..." + if [ -f /etc/debian_version ]; then + apt-get update + apt-get install -y jq + elif [ -f /etc/redhat-release ]; then + yum update -y + yum install -y jq + else + print_color $RED "Unsupported distribution. Please install jq manually." + exit 1 + fi + print_color $GREEN "jq installed successfully." + else + print_color $YELLOW "jq is already installed." + fi +} + # Function to get user input get_user_input() { + # Ask user which network to install + echo "Which network would you like to install?" + echo "1) testnet-alpha" + echo "2) testnet-beta" + echo "3) mainnet" + read -p "Enter your choice (1-3): " network_choice + + case $network_choice in + 1) NETWORK="testnet-alpha" ;; + 2) NETWORK="testnet-beta" ;; + 3) NETWORK="mainnet" ;; + *) print_color $RED "Invalid network choice. Exiting."; exit 1 ;; + esac + + print_color $GREEN "Installing the $NETWORK network." + read -p "Enter the desired username to run poktrolld (default: poktroll): " POKTROLL_USER POKTROLL_USER=${POKTROLL_USER:-poktroll} read -p "Enter the node moniker (default: $(hostname)): " NODE_MONIKER NODE_MONIKER=${NODE_MONIKER:-$(hostname)} - read -p "Enter the chain-id (default: poktroll): " CHAIN_ID - CHAIN_ID=${CHAIN_ID:-"poktroll"} + # Update URLs to use the branch constant + BASE_URL="https://raw.githubusercontent.com/pokt-network/pocket-network-genesis/${POCKET_NETWORK_GENESIS_BRANCH}/shannon/$NETWORK" + SEEDS_URL="$BASE_URL/seeds" + GENESIS_URL="$BASE_URL/genesis.json" + + # Download genesis.json and store it + GENESIS_FILE="/tmp/genesis.json" + curl -s -o "$GENESIS_FILE" "$GENESIS_URL" + if [ $? -ne 0 ]; then + print_color $RED "Failed to download genesis file. Please check your internet connection and try again." + exit 1 + fi + + # Extract chain_id from genesis.json + CHAIN_ID=$(jq -r '.chain_id' < "$GENESIS_FILE") + if [ -z "$CHAIN_ID" ]; then + print_color $RED "Failed to extract chain_id from genesis file." + exit 1 + fi + print_color $GREEN "Using chain_id: $CHAIN_ID from genesis file" # Fetch seeds from the provided URL - SEEDS_URL="https://raw.githubusercontent.com/pokt-network/pocket-network-genesis/master/shannon/alpha/testnet-validated.seeds" SEEDS=$(curl -s "$SEEDS_URL") if [ -z "$SEEDS" ]; then print_color $RED "Failed to fetch seeds from $SEEDS_URL. Please check your internet connection and try again." @@ -125,6 +181,7 @@ EOF print_color $GREEN "Cosmovisor set up successfully." } + # Function to download and set up Poktrolld setup_poktrolld() { print_color $YELLOW "Setting up Poktrolld..." @@ -138,20 +195,38 @@ setup_poktrolld() { exit 1 fi - # Get the version genesis started from. We can't just use `latest` as the new binary won't sync from genesis. - # We need to start syncing from scratch using the version that was used when the network started. - POKTROLLD_VERSION=$(curl -s https://raw.githubusercontent.com/pokt-network/pocket-network-genesis/master/shannon/alpha/testnet-validated.init-version) + # Extract the version from genesis.json using jq + POKTROLLD_VERSION=$(jq -r '.app_version' < "$GENESIS_FILE") + print_color $YELLOW "Detected version from genesis: $POKTROLLD_VERSION" + + if [ -z "$POKTROLLD_VERSION" ]; then + print_color $RED "Failed to extract version information from genesis file." + exit 1 + fi - # Use the direct download link for the correct release - RELEASE_URL="https://github.com/pokt-network/poktroll/releases/download/${POKTROLLD_VERSION}/poktroll_linux_${ARCH}.tar.gz" + # Construct the release URL with proper version format + RELEASE_URL="https://github.com/pokt-network/poktroll/releases/download/v${POKTROLLD_VERSION}/poktroll_linux_${ARCH}.tar.gz" + print_color $YELLOW "Attempting to download from: $RELEASE_URL" + # Download and extract directly as the POKTROLL_USER sudo -u "$POKTROLL_USER" bash << EOF mkdir -p \$HOME/.poktroll/cosmovisor/genesis/bin + mkdir -p \$HOME/.local/bin curl -L "$RELEASE_URL" | tar -zxvf - -C \$HOME/.poktroll/cosmovisor/genesis/bin + if [ \$? -ne 0 ]; then + echo "Failed to download or extract binary" + exit 1 + fi chmod +x \$HOME/.poktroll/cosmovisor/genesis/bin/poktrolld - ln -sf \$HOME/.poktroll/cosmovisor/genesis/bin/poktrolld \$HOME/bin/poktrolld + ln -sf \$HOME/.poktroll/cosmovisor/genesis/bin/poktrolld \$HOME/.local/bin/poktrolld source \$HOME/.profile EOF + + if [ $? -ne 0 ]; then + print_color $RED "Failed to set up Poktrolld" + exit 1 + fi + print_color $GREEN "Poktrolld set up successfully." } @@ -159,16 +234,24 @@ EOF configure_poktrolld() { print_color $YELLOW "Configuring Poktrolld..." - # Ask for confirmation to download the genesis file - GENESIS_URL="https://raw.githubusercontent.com/pokt-network/pocket-network-genesis/master/shannon/alpha/testnet-validated.json" - print_color $YELLOW "The script will download the genesis file from:" + # Ask for confirmation to use the downloaded genesis file + print_color $YELLOW "The script has downloaded the genesis file from:" print_color $YELLOW "$GENESIS_URL" - read -p "Are you OK with downloading and using this genesis file? (y/N): " confirm_genesis + read -p "Are you OK with using this genesis file? (y/N): " confirm_genesis if [[ ! $confirm_genesis =~ ^[Yy] ]]; then - print_color $RED "Genesis file download cancelled. Exiting." + print_color $RED "Genesis file usage cancelled. Exiting." exit 1 fi + # Detect external IP address + EXTERNAL_IP=$(curl -s https://api.ipify.org) + print_color $YELLOW "Detected external IP address: $EXTERNAL_IP" + read -p "Is this your correct external IP address? (Y/n): " confirm_ip + if [[ $confirm_ip =~ ^[Nn] ]]; then + read -p "Please enter your external IP address: " custom_ip + EXTERNAL_IP=${custom_ip:-$EXTERNAL_IP} + fi + sudo -u "$POKTROLL_USER" bash << EOF source \$HOME/.profile @@ -177,12 +260,9 @@ configure_poktrolld() { echo "Poktrolld version: \$POKTROLLD_VERSION" poktrolld init "$NODE_MONIKER" --chain-id="$CHAIN_ID" --home=\$HOME/.poktroll - curl -o \$HOME/.poktroll/config/genesis.json $GENESIS_URL - if [ \$? -ne 0 ]; then - echo "Failed to download genesis file. Please check your internet connection and try again." - exit 1 - fi + cp "$GENESIS_FILE" \$HOME/.poktroll/config/genesis.json sed -i -e "s|^seeds *=.*|seeds = \"$SEEDS\"|" \$HOME/.poktroll/config/config.toml + sed -i -e "s|^external_address *=.*|external_address = \"$EXTERNAL_IP:26656\"|" \$HOME/.poktroll/config/config.toml EOF if [ $? -eq 0 ]; then print_color $GREEN "Poktrolld configured successfully." @@ -223,10 +303,36 @@ EOF print_color $GREEN "Systemd service set up and started successfully." } +# Function to check if ufw is installed and open port 26656. We need to open the port to keep the network healthy. +# By default, at least on Debian vultr, this port is not open to the internet. +configure_ufw() { + if command -v ufw &> /dev/null; then + print_color $YELLOW "ufw is installed." + + # Check if rule already exists + if ufw status | grep -q "26656"; then + print_color $YELLOW "Port 26656 is already allowed in ufw rules." + return + fi + + read -p "Do you want to open port 26656 for p2p communication? (Y/n): " open_port + if [[ $open_port =~ ^[Yy] ]]; then + ufw allow 26656 + print_color $GREEN "Port 26656 opened successfully." + print_color $YELLOW "To remove this rule later, run: sudo ufw delete allow 26656" + else + print_color $YELLOW "No firewall rules modified." + fi + else + print_color $YELLOW "ufw is not installed. Skipping firewall configuration." + fi +} + # Main function main() { print_color $GREEN "Welcome to the Poktroll Full Node Install Script!" check_root + install_jq get_user_input create_user install_dependencies @@ -235,7 +341,8 @@ main() { setup_poktrolld configure_poktrolld setup_systemd - print_color $GREEN "Poktroll Full Node installation completed successfully!" + configure_ufw + print_color $GREEN "Poktroll Full Node installation for $NETWORK completed successfully!" print_color $YELLOW "You can check the status of your node with: sudo systemctl status cosmovisor.service" print_color $YELLOW "View logs with: sudo journalctl -u cosmovisor.service -f" } From 256d001a759d98c51b6bef1bc51d5ffb0ce24a99 Mon Sep 17 00:00:00 2001 From: Bryan White Date: Mon, 2 Dec 2024 08:54:41 +0100 Subject: [PATCH 09/21] chore: review feedback improvements Co-authored-by: red-0ne --- x/service/types/message_update_param.go | 2 +- x/tokenomics/types/message_update_param.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x/service/types/message_update_param.go b/x/service/types/message_update_param.go index ccef3422a..d6ec1b1eb 100644 --- a/x/service/types/message_update_param.go +++ b/x/service/types/message_update_param.go @@ -55,7 +55,7 @@ func (msg *MsgUpdateParam) ValidateBasic() error { } } -// genericTypeIsCoin checks if the parameter type is T, returning an error if not. +// genericParamTypeIs checks if the parameter type is T, returning an error if not. func genericParamTypeIs[T any](msg *MsgUpdateParam) error { if _, ok := msg.AsType.(T); !ok { return ErrServiceParamInvalid.Wrapf( diff --git a/x/tokenomics/types/message_update_param.go b/x/tokenomics/types/message_update_param.go index 0875f40cf..719ec842a 100644 --- a/x/tokenomics/types/message_update_param.go +++ b/x/tokenomics/types/message_update_param.go @@ -66,7 +66,7 @@ func (msg *MsgUpdateParam) paramTypeIsString() error { return genericParamTypeIs[*MsgUpdateParam_AsString](msg) } -// genericTypeIsCoin checks if the parameter type is T, returning an error if not. +// genericParamTypeIs checks if the parameter type is T, returning an error if not. func genericParamTypeIs[T any](msg *MsgUpdateParam) error { if _, ok := msg.AsType.(T); !ok { return ErrTokenomicsParamInvalid.Wrapf( From 9efa98c3670dd30ec1c0d878a3b35d8dded890d3 Mon Sep 17 00:00:00 2001 From: Bryan White Date: Mon, 2 Dec 2024 09:15:58 +0100 Subject: [PATCH 10/21] chore: review feedback improvements Co-authored-by: red-0ne --- x/supplier/keeper/params_test.go | 7 +++++++ x/supplier/types/message_update_param.go | 1 + x/supplier/types/params.go | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/x/supplier/keeper/params_test.go b/x/supplier/keeper/params_test.go index 7b3cc0770..8ac48c13f 100644 --- a/x/supplier/keeper/params_test.go +++ b/x/supplier/keeper/params_test.go @@ -94,6 +94,13 @@ func TestParams_ValidateStakingFee(t *testing.T) { volatile.DenomuPOKT, ), }, + { + desc: "zero SupplierStakingFee", + minStake: &cosmostypes.Coin{ + Denom: volatile.DenomuPOKT, + Amount: math.NewInt(0), + }, + }, { desc: "valid SupplierStakingFee", minStake: &suppliertypes.DefaultStakingFee, diff --git a/x/supplier/types/message_update_param.go b/x/supplier/types/message_update_param.go index 0f7925988..e1ce28298 100644 --- a/x/supplier/types/message_update_param.go +++ b/x/supplier/types/message_update_param.go @@ -59,6 +59,7 @@ func (msg *MsgUpdateParam) ValidateBasic() error { } } +// genericParamTypeIs checks if the parameter type is T, returning an error if not. func genericParamTypeIs[T any](msg *MsgUpdateParam) error { if _, ok := msg.AsType.(T); !ok { return ErrSupplierParamInvalid.Wrapf( diff --git a/x/supplier/types/params.go b/x/supplier/types/params.go index 788bc3a9b..7fe2e081a 100644 --- a/x/supplier/types/params.go +++ b/x/supplier/types/params.go @@ -96,7 +96,8 @@ func ValidateStakingFee(stakingFeeAny any) error { return nil } -// TODO_IN_THIS_COMMOT: godoc... +// paramAsPositiveuPOKT checks that paramAny is a *cosmostypes.Coin and that its +// amount is positive, returning an error if either is not the case. func paramAsPositiveuPOKT(paramAny any, paramName string) (*cosmostypes.Coin, error) { paramCoin, ok := paramAny.(*cosmostypes.Coin) if !ok { From 496ac35b165a18c0da94e69f26de4a1b5c2de1a5 Mon Sep 17 00:00:00 2001 From: Bryan White Date: Mon, 2 Dec 2024 09:57:55 +0100 Subject: [PATCH 11/21] [Tokenomics] feat: add `target_num_relays` param to service module (#930) ## Summary Add `target_num_relay` param to the tokenomics module. ## Issue - `TODO_BETA` ## Type of change Select one or more from the following: - [x] New feature, functionality or library - [ ] Consensus breaking; add the `consensus-breaking` label if so. See #791 for details - [ ] Bug fix - [ ] Code health or cleanup - [ ] Documentation - [ ] Other (specify) ## Testing - [ ] **Documentation**: `make docusaurus_start`; only needed if you make doc changes - [ ] **Unit Tests**: `make go_develop_and_test` - [ ] **LocalNet E2E Tests**: `make test_e2e` - [ ] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR. ## Sanity Checklist - [ ] I have tested my changes using the available tooling - [ ] I have commented my code - [ ] I have performed a self-review of my own code; both comments & source code - [ ] I create and reference any new tickets, if applicable - [ ] I have left TODOs throughout the codebase, if applicable --------- Co-authored-by: red-0ne --- api/poktroll/service/params.pulsar.go | 99 +++++++-- api/poktroll/service/tx.pulsar.go | 188 +++++++++++++----- config.yml | 1 + makefiles/params.mk | 4 + proto/poktroll/service/params.proto | 4 + proto/poktroll/service/tx.proto | 3 +- .../integration/application/min_stake_test.go | 5 +- .../relay_mining_integration_test.go | 23 +-- testutil/integration/suites/param_configs.go | 6 +- testutil/keeper/tokenomics.go | 9 +- tools/scripts/params/service_all.json | 3 +- .../params/service_target_num_relays.json | 12 ++ x/application/types/message_update_param.go | 22 +- .../keeper/msg_server_create_claim_test.go | 10 +- .../keeper/msg_server_submit_proof_test.go | 10 +- x/proof/keeper/proof_validation_test.go | 9 +- x/proof/types/expected_keepers.go | 1 + x/service/keeper/msg_server_update_param.go | 17 +- .../keeper/msg_server_update_param_test.go | 27 +++ x/service/keeper/msg_update_params_test.go | 14 +- x/service/keeper/params_test.go | 35 ++++ x/service/keeper/relay_mining_difficulty.go | 11 +- .../keeper/update_relay_mining_difficulty.go | 23 +-- .../update_relay_mining_difficulty_test.go | 16 +- x/service/types/message_update_param.go | 26 ++- x/service/types/message_update_param_test.go | 6 +- x/service/types/params.go | 44 +++- x/service/types/params.pb.go | 81 ++++++-- x/service/types/tx.pb.go | 138 +++++++++---- .../keeper_settle_pending_claims_test.go | 9 +- x/tokenomics/keeper/settle_pending_claims.go | 9 +- x/tokenomics/keeper/token_logic_modules.go | 9 +- x/tokenomics/types/expected_keepers.go | 2 + x/tokenomics/types/message_update_param.go | 5 +- 34 files changed, 648 insertions(+), 233 deletions(-) create mode 100644 tools/scripts/params/service_target_num_relays.json diff --git a/api/poktroll/service/params.pulsar.go b/api/poktroll/service/params.pulsar.go index 981c7d4a5..6b180a66a 100644 --- a/api/poktroll/service/params.pulsar.go +++ b/api/poktroll/service/params.pulsar.go @@ -16,14 +16,16 @@ import ( ) var ( - md_Params protoreflect.MessageDescriptor - fd_Params_add_service_fee protoreflect.FieldDescriptor + md_Params protoreflect.MessageDescriptor + fd_Params_add_service_fee protoreflect.FieldDescriptor + fd_Params_target_num_relays protoreflect.FieldDescriptor ) func init() { file_poktroll_service_params_proto_init() md_Params = File_poktroll_service_params_proto.Messages().ByName("Params") fd_Params_add_service_fee = md_Params.Fields().ByName("add_service_fee") + fd_Params_target_num_relays = md_Params.Fields().ByName("target_num_relays") } var _ protoreflect.Message = (*fastReflection_Params)(nil) @@ -97,6 +99,12 @@ func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, proto return } } + if x.TargetNumRelays != uint64(0) { + value := protoreflect.ValueOfUint64(x.TargetNumRelays) + if !f(fd_Params_target_num_relays, value) { + return + } + } } // Has reports whether a field is populated. @@ -114,6 +122,8 @@ func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { case "poktroll.service.Params.add_service_fee": return x.AddServiceFee != nil + case "poktroll.service.Params.target_num_relays": + return x.TargetNumRelays != uint64(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.service.Params")) @@ -132,6 +142,8 @@ func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { case "poktroll.service.Params.add_service_fee": x.AddServiceFee = nil + case "poktroll.service.Params.target_num_relays": + x.TargetNumRelays = uint64(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.service.Params")) @@ -151,6 +163,9 @@ func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) pro case "poktroll.service.Params.add_service_fee": value := x.AddServiceFee return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "poktroll.service.Params.target_num_relays": + value := x.TargetNumRelays + return protoreflect.ValueOfUint64(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.service.Params")) @@ -173,6 +188,8 @@ func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value proto switch fd.FullName() { case "poktroll.service.Params.add_service_fee": x.AddServiceFee = value.Message().Interface().(*v1beta1.Coin) + case "poktroll.service.Params.target_num_relays": + x.TargetNumRelays = value.Uint() default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.service.Params")) @@ -198,6 +215,8 @@ func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protore x.AddServiceFee = new(v1beta1.Coin) } return protoreflect.ValueOfMessage(x.AddServiceFee.ProtoReflect()) + case "poktroll.service.Params.target_num_relays": + panic(fmt.Errorf("field target_num_relays of message poktroll.service.Params is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.service.Params")) @@ -214,6 +233,8 @@ func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protor case "poktroll.service.Params.add_service_fee": m := new(v1beta1.Coin) return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "poktroll.service.Params.target_num_relays": + return protoreflect.ValueOfUint64(uint64(0)) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.service.Params")) @@ -287,6 +308,9 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { l = options.Size(x.AddServiceFee) n += 1 + l + runtime.Sov(uint64(l)) } + if x.TargetNumRelays != 0 { + n += 1 + runtime.Sov(uint64(x.TargetNumRelays)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -316,6 +340,11 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if x.TargetNumRelays != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.TargetNumRelays)) + i-- + dAtA[i] = 0x10 + } if x.AddServiceFee != nil { encoded, err := options.Marshal(x.AddServiceFee) if err != nil { @@ -415,6 +444,25 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err } iNdEx = postIndex + case 2: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field TargetNumRelays", wireType) + } + x.TargetNumRelays = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.TargetNumRelays |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -473,6 +521,9 @@ type Params struct { // This will be deducted from the signer's account balance, // and transferred to the pocket network foundation. AddServiceFee *v1beta1.Coin `protobuf:"bytes,1,opt,name=add_service_fee,json=addServiceFee,proto3" json:"add_service_fee,omitempty"` + // target_num_relays is the target for the EMA of the number of relays per session. + // Per service, on-chain relay mining difficulty will be adjusted to maintain this target. + TargetNumRelays uint64 `protobuf:"varint,2,opt,name=target_num_relays,json=targetNumRelays,proto3" json:"target_num_relays,omitempty"` } func (x *Params) Reset() { @@ -502,6 +553,13 @@ func (x *Params) GetAddServiceFee() *v1beta1.Coin { return nil } +func (x *Params) GetTargetNumRelays() uint64 { + if x != nil { + return x.TargetNumRelays + } + return 0 +} + var File_poktroll_service_params_proto protoreflect.FileDescriptor var file_poktroll_service_params_proto_rawDesc = []byte{ @@ -512,7 +570,7 @@ var file_poktroll_service_params_proto_rawDesc = []byte{ 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, - 0x63, 0x6f, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9e, 0x01, 0x0a, 0x06, 0x50, + 0x63, 0x6f, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfd, 0x01, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x70, 0x0a, 0x0f, 0x61, 0x64, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x66, 0x65, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, @@ -520,21 +578,26 @@ var file_poktroll_service_params_proto_rawDesc = []byte{ 0x64, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x66, 0x65, 0x65, 0xf2, 0xde, 0x1f, 0x16, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x61, 0x64, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x66, 0x65, 0x65, 0x22, 0x52, 0x0d, 0x61, 0x64, 0x64, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x46, 0x65, 0x65, 0x3a, 0x22, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, - 0x2a, 0x19, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x78, 0x2f, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0xab, 0x01, 0xd8, 0xe2, - 0x1e, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x0b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x21, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, - 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, - 0x6c, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xa2, 0x02, 0x03, 0x50, 0x53, 0x58, - 0xaa, 0x02, 0x10, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0xca, 0x02, 0x10, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xe2, 0x02, 0x1c, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, - 0x6c, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x11, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x3a, 0x3a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x76, 0x69, 0x63, 0x65, 0x46, 0x65, 0x65, 0x12, 0x5d, 0x0a, 0x11, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x42, 0x31, 0xea, 0xde, 0x1f, 0x11, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6e, + 0x75, 0x6d, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x73, 0xf2, 0xde, 0x1f, 0x18, 0x79, 0x61, 0x6d, + 0x6c, 0x3a, 0x22, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x65, + 0x6c, 0x61, 0x79, 0x73, 0x22, 0x52, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4e, 0x75, 0x6d, + 0x52, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x3a, 0x22, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, + 0x19, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x78, 0x2f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x2f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0xab, 0x01, 0xd8, 0xe2, 0x1e, + 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x0b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x21, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, + 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, + 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xa2, 0x02, 0x03, 0x50, 0x53, 0x58, 0xaa, + 0x02, 0x10, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0xca, 0x02, 0x10, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0xe2, 0x02, 0x1c, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, + 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x11, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x3a, + 0x3a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/poktroll/service/tx.pulsar.go b/api/poktroll/service/tx.pulsar.go index ae03ea849..3b140dce5 100644 --- a/api/poktroll/service/tx.pulsar.go +++ b/api/poktroll/service/tx.pulsar.go @@ -5,11 +5,11 @@ import ( _ "cosmossdk.io/api/amino" v1beta1 "cosmossdk.io/api/cosmos/base/v1beta1" _ "cosmossdk.io/api/cosmos/msg/v1" - shared "github.com/pokt-network/poktroll/api/poktroll/shared" fmt "fmt" _ "github.com/cosmos/cosmos-proto" runtime "github.com/cosmos/cosmos-proto/runtime" _ "github.com/cosmos/gogoproto/gogoproto" + shared "github.com/pokt-network/poktroll/api/poktroll/shared" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoiface "google.golang.org/protobuf/runtime/protoiface" protoimpl "google.golang.org/protobuf/runtime/protoimpl" @@ -878,6 +878,7 @@ var ( fd_MsgUpdateParam_authority protoreflect.FieldDescriptor fd_MsgUpdateParam_name protoreflect.FieldDescriptor fd_MsgUpdateParam_as_coin protoreflect.FieldDescriptor + fd_MsgUpdateParam_as_uint64 protoreflect.FieldDescriptor ) func init() { @@ -886,6 +887,7 @@ func init() { fd_MsgUpdateParam_authority = md_MsgUpdateParam.Fields().ByName("authority") fd_MsgUpdateParam_name = md_MsgUpdateParam.Fields().ByName("name") fd_MsgUpdateParam_as_coin = md_MsgUpdateParam.Fields().ByName("as_coin") + fd_MsgUpdateParam_as_uint64 = md_MsgUpdateParam.Fields().ByName("as_uint64") } var _ protoreflect.Message = (*fastReflection_MsgUpdateParam)(nil) @@ -973,6 +975,12 @@ func (x *fastReflection_MsgUpdateParam) Range(f func(protoreflect.FieldDescripto if !f(fd_MsgUpdateParam_as_coin, value) { return } + case *MsgUpdateParam_AsUint64: + v := o.AsUint64 + value := protoreflect.ValueOfUint64(v) + if !f(fd_MsgUpdateParam_as_uint64, value) { + return + } } } } @@ -1002,6 +1010,14 @@ func (x *fastReflection_MsgUpdateParam) Has(fd protoreflect.FieldDescriptor) boo } else { return false } + case "poktroll.service.MsgUpdateParam.as_uint64": + if x.AsType == nil { + return false + } else if _, ok := x.AsType.(*MsgUpdateParam_AsUint64); ok { + return true + } else { + return false + } default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.service.MsgUpdateParam")) @@ -1024,6 +1040,8 @@ func (x *fastReflection_MsgUpdateParam) Clear(fd protoreflect.FieldDescriptor) { x.Name = "" case "poktroll.service.MsgUpdateParam.as_coin": x.AsType = nil + case "poktroll.service.MsgUpdateParam.as_uint64": + x.AsType = nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.service.MsgUpdateParam")) @@ -1054,6 +1072,14 @@ func (x *fastReflection_MsgUpdateParam) Get(descriptor protoreflect.FieldDescrip } else { return protoreflect.ValueOfMessage((*v1beta1.Coin)(nil).ProtoReflect()) } + case "poktroll.service.MsgUpdateParam.as_uint64": + if x.AsType == nil { + return protoreflect.ValueOfUint64(uint64(0)) + } else if v, ok := x.AsType.(*MsgUpdateParam_AsUint64); ok { + return protoreflect.ValueOfUint64(v.AsUint64) + } else { + return protoreflect.ValueOfUint64(uint64(0)) + } default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.service.MsgUpdateParam")) @@ -1081,6 +1107,9 @@ func (x *fastReflection_MsgUpdateParam) Set(fd protoreflect.FieldDescriptor, val case "poktroll.service.MsgUpdateParam.as_coin": cv := value.Message().Interface().(*v1beta1.Coin) x.AsType = &MsgUpdateParam_AsCoin{AsCoin: cv} + case "poktroll.service.MsgUpdateParam.as_uint64": + cv := value.Uint() + x.AsType = &MsgUpdateParam_AsUint64{AsUint64: cv} default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.service.MsgUpdateParam")) @@ -1121,6 +1150,8 @@ func (x *fastReflection_MsgUpdateParam) Mutable(fd protoreflect.FieldDescriptor) panic(fmt.Errorf("field authority of message poktroll.service.MsgUpdateParam is not mutable")) case "poktroll.service.MsgUpdateParam.name": panic(fmt.Errorf("field name of message poktroll.service.MsgUpdateParam is not mutable")) + case "poktroll.service.MsgUpdateParam.as_uint64": + panic(fmt.Errorf("field as_uint64 of message poktroll.service.MsgUpdateParam is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.service.MsgUpdateParam")) @@ -1141,6 +1172,8 @@ func (x *fastReflection_MsgUpdateParam) NewField(fd protoreflect.FieldDescriptor case "poktroll.service.MsgUpdateParam.as_coin": value := &v1beta1.Coin{} return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "poktroll.service.MsgUpdateParam.as_uint64": + return protoreflect.ValueOfUint64(uint64(0)) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.service.MsgUpdateParam")) @@ -1161,6 +1194,8 @@ func (x *fastReflection_MsgUpdateParam) WhichOneof(d protoreflect.OneofDescripto switch x.AsType.(type) { case *MsgUpdateParam_AsCoin: return x.Descriptor().Fields().ByName("as_coin") + case *MsgUpdateParam_AsUint64: + return x.Descriptor().Fields().ByName("as_uint64") } default: panic(fmt.Errorf("%s is not a oneof field in poktroll.service.MsgUpdateParam", d.FullName())) @@ -1233,6 +1268,11 @@ func (x *fastReflection_MsgUpdateParam) ProtoMethods() *protoiface.Methods { } l = options.Size(x.AsCoin) n += 1 + l + runtime.Sov(uint64(l)) + case *MsgUpdateParam_AsUint64: + if x == nil { + break + } + n += 1 + runtime.Sov(uint64(x.AsUint64)) } if x.unknownFields != nil { n += len(x.unknownFields) @@ -1276,7 +1316,11 @@ func (x *fastReflection_MsgUpdateParam) ProtoMethods() *protoiface.Methods { copy(dAtA[i:], encoded) i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) i-- - dAtA[i] = 0x4a + dAtA[i] = 0x1a + case *MsgUpdateParam_AsUint64: + i = runtime.EncodeVarint(dAtA, i, uint64(x.AsUint64)) + i-- + dAtA[i] = 0x20 } if len(x.Name) > 0 { i -= len(x.Name) @@ -1405,7 +1449,7 @@ func (x *fastReflection_MsgUpdateParam) ProtoMethods() *protoiface.Methods { } x.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 9: + case 3: if wireType != 2 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field AsCoin", wireType) } @@ -1440,6 +1484,26 @@ func (x *fastReflection_MsgUpdateParam) ProtoMethods() *protoiface.Methods { } x.AsType = &MsgUpdateParam_AsCoin{v} iNdEx = postIndex + case 4: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field AsUint64", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + x.AsType = &MsgUpdateParam_AsUint64{v} default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -2867,6 +2931,7 @@ type MsgUpdateParam struct { // Types that are assignable to AsType: // // *MsgUpdateParam_AsCoin + // *MsgUpdateParam_AsUint64 AsType isMsgUpdateParam_AsType `protobuf_oneof:"as_type"` } @@ -2918,16 +2983,29 @@ func (x *MsgUpdateParam) GetAsCoin() *v1beta1.Coin { return nil } +func (x *MsgUpdateParam) GetAsUint64() uint64 { + if x, ok := x.GetAsType().(*MsgUpdateParam_AsUint64); ok { + return x.AsUint64 + } + return 0 +} + type isMsgUpdateParam_AsType interface { isMsgUpdateParam_AsType() } type MsgUpdateParam_AsCoin struct { - AsCoin *v1beta1.Coin `protobuf:"bytes,9,opt,name=as_coin,json=asCoin,proto3,oneof"` + AsCoin *v1beta1.Coin `protobuf:"bytes,3,opt,name=as_coin,json=asCoin,proto3,oneof"` +} + +type MsgUpdateParam_AsUint64 struct { + AsUint64 uint64 `protobuf:"varint,4,opt,name=as_uint64,json=asUint64,proto3,oneof"` } func (*MsgUpdateParam_AsCoin) isMsgUpdateParam_AsType() {} +func (*MsgUpdateParam_AsUint64) isMsgUpdateParam_AsType() {} + // MsgUpdateParamResponse defines the response structure for executing a // MsgUpdateParam message after a single param update. type MsgUpdateParamResponse struct { @@ -3068,64 +3146,67 @@ var file_poktroll_service_tx_proto_rawDesc = []byte{ 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0xba, 0x01, 0x0a, 0x0e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x6e, 0x73, 0x65, 0x22, 0xe8, 0x01, 0x0a, 0x0e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x61, 0x73, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x18, 0x09, 0x20, + 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x61, 0x73, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x0b, 0xea, 0xde, 0x1f, 0x07, 0x61, 0x73, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x48, 0x00, 0x52, 0x06, 0x61, - 0x73, 0x43, 0x6f, 0x69, 0x6e, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x42, 0x09, 0x0a, 0x07, 0x61, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x22, 0x4a, 0x0a, 0x16, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x06, 0x70, 0x61, - 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x6f, 0x6b, - 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x9c, 0x01, 0x0a, - 0x0d, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3d, - 0x0a, 0x0d, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, - 0x0c, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x38, 0x0a, - 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, - 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, - 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x07, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x12, 0x82, 0xe7, 0xb0, 0x2a, 0x0d, 0x6f, 0x77, - 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x17, 0x0a, 0x15, 0x4d, - 0x73, 0x67, 0x41, 0x64, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x9d, 0x02, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x5c, 0x0a, 0x0c, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x21, 0x2e, 0x70, - 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, - 0x29, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x0b, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x20, 0x2e, 0x70, 0x6f, 0x6b, 0x74, + 0x73, 0x43, 0x6f, 0x69, 0x6e, 0x12, 0x2c, 0x0a, 0x09, 0x61, 0x73, 0x5f, 0x75, 0x69, 0x6e, 0x74, + 0x36, 0x34, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0d, 0xea, 0xde, 0x1f, 0x09, 0x61, 0x73, + 0x5f, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x48, 0x00, 0x52, 0x08, 0x61, 0x73, 0x55, 0x69, 0x6e, + 0x74, 0x36, 0x34, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x42, 0x09, 0x0a, 0x07, 0x61, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x4a, + 0x0a, 0x16, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x9c, 0x01, 0x0a, 0x0d, 0x4d, + 0x73, 0x67, 0x41, 0x64, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3d, 0x0a, 0x0d, + 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x6f, + 0x77, 0x6e, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x38, 0x0a, 0x07, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, + 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x07, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x12, 0x82, 0xe7, 0xb0, 0x2a, 0x0d, 0x6f, 0x77, 0x6e, 0x65, + 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x17, 0x0a, 0x15, 0x4d, 0x73, 0x67, + 0x41, 0x64, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x32, 0x9d, 0x02, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x5c, 0x0a, 0x0c, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x21, 0x2e, 0x70, 0x6f, 0x6b, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x73, + 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x29, 0x2e, + 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x20, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, + 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x1a, 0x28, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x73, 0x67, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x1a, 0x28, 0x2e, 0x70, 0x6f, - 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, - 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x1f, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x1a, 0x27, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, - 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0xa7, 0x01, 0xd8, 0xe2, 0x1e, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, - 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x21, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, - 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xa2, - 0x02, 0x03, 0x50, 0x53, 0x58, 0xaa, 0x02, 0x10, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xca, 0x02, 0x10, 0x50, 0x6f, 0x6b, 0x74, 0x72, - 0x6f, 0x6c, 0x6c, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xe2, 0x02, 0x1c, 0x50, 0x6f, - 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x11, 0x50, 0x6f, 0x6b, - 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x3a, 0x3a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x1f, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x1a, 0x27, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, + 0x2a, 0x01, 0x42, 0xa7, 0x01, 0xd8, 0xe2, 0x1e, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x70, + 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, + 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x21, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x6f, 0x6b, + 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xa2, 0x02, 0x03, + 0x50, 0x53, 0x58, 0xaa, 0x02, 0x10, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xca, 0x02, 0x10, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, + 0x6c, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0xe2, 0x02, 0x1c, 0x50, 0x6f, 0x6b, 0x74, + 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x47, 0x50, 0x42, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x11, 0x50, 0x6f, 0x6b, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x3a, 0x3a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3252,6 +3333,7 @@ func file_poktroll_service_tx_proto_init() { } file_poktroll_service_tx_proto_msgTypes[2].OneofWrappers = []interface{}{ (*MsgUpdateParam_AsCoin)(nil), + (*MsgUpdateParam_AsUint64)(nil), } type x struct{} out := protoimpl.TypeBuilder{ diff --git a/config.yml b/config.yml index d3c593976..f6bec72d1 100644 --- a/config.yml +++ b/config.yml @@ -251,6 +251,7 @@ genesis: add_service_fee: amount: "1000000000" denom: upokt + target_num_relays: 100000 serviceList: - id: anvil name: "anvil" diff --git a/makefiles/params.mk b/makefiles/params.mk index 823f0ecbc..bbe99698a 100644 --- a/makefiles/params.mk +++ b/makefiles/params.mk @@ -31,6 +31,10 @@ params_update_service_all: ## Update the service module params params_update_service_add_service_fee: ## Update the service module add_service_fee param poktrolld tx authz exec ./tools/scripts/params/service_add_service_fee.json $(PARAM_FLAGS) +.PHONY: params_update_service_target_num_relays +params_update_service_target_num_relays: ## Update the service module target_num_relays param + poktrolld tx authz exec ./tools/scripts/params/service_target_num_relays.json $(PARAM_FLAGS) + ### Proof Module Params ### .PHONY: params_get_proof params_get_proof: ## Get the proof module params diff --git a/proto/poktroll/service/params.proto b/proto/poktroll/service/params.proto index 66677c9b3..78c5da623 100644 --- a/proto/poktroll/service/params.proto +++ b/proto/poktroll/service/params.proto @@ -18,4 +18,8 @@ message Params { // This will be deducted from the signer's account balance, // and transferred to the pocket network foundation. cosmos.base.v1beta1.Coin add_service_fee = 1 [(gogoproto.jsontag) = "add_service_fee", (gogoproto.moretags) = "yaml:\"add_service_fee\""]; + + // target_num_relays is the target for the EMA of the number of relays per session. + // Per service, on-chain relay mining difficulty will be adjusted to maintain this target. + uint64 target_num_relays = 2 [(gogoproto.jsontag) = "target_num_relays", (gogoproto.moretags) = "yaml:\"target_num_relays\""]; } diff --git a/proto/poktroll/service/tx.proto b/proto/poktroll/service/tx.proto index 44bc0c988..b80a5d5d2 100644 --- a/proto/poktroll/service/tx.proto +++ b/proto/poktroll/service/tx.proto @@ -53,7 +53,8 @@ message MsgUpdateParam { // specified in the `Params` message in `proof/params.proto.` string name = 2; oneof as_type { - cosmos.base.v1beta1.Coin as_coin = 9 [(gogoproto.jsontag) = "as_coin"]; + cosmos.base.v1beta1.Coin as_coin = 3 [(gogoproto.jsontag) = "as_coin"]; + uint64 as_uint64 = 4 [(gogoproto.jsontag) = "as_uint64"]; } } diff --git a/tests/integration/application/min_stake_test.go b/tests/integration/application/min_stake_test.go index 5a0ea2128..b8211d6ec 100644 --- a/tests/integration/application/min_stake_test.go +++ b/tests/integration/application/min_stake_test.go @@ -255,11 +255,14 @@ func (s *applicationMinStakeTestSuite) getExpectedApp(claim *prooftypes.Claim) * func (s *applicationMinStakeTestSuite) newRelayminingDifficulty() servicetypes.RelayMiningDifficulty { s.T().Helper() + targetNumRelays := s.keepers.ServiceKeeper.GetParams(s.ctx).TargetNumRelays + return servicekeeper.NewDefaultRelayMiningDifficulty( s.ctx, cosmoslog.NewNopLogger(), s.serviceId, - servicekeeper.TargetNumRelays, + targetNumRelays, + targetNumRelays, ) } diff --git a/tests/integration/tokenomics/relay_mining_integration_test.go b/tests/integration/tokenomics/relay_mining_integration_test.go index 5014c7275..0b6ea4a9f 100644 --- a/tests/integration/tokenomics/relay_mining_integration_test.go +++ b/tests/integration/tokenomics/relay_mining_integration_test.go @@ -17,7 +17,6 @@ import ( "github.com/pokt-network/poktroll/testutil/testrelayer" apptypes "github.com/pokt-network/poktroll/x/application/types" prooftypes "github.com/pokt-network/poktroll/x/proof/types" - servicekeeper "github.com/pokt-network/poktroll/x/service/keeper" servicetypes "github.com/pokt-network/poktroll/x/service/types" sessiontypes "github.com/pokt-network/poktroll/x/session/types" sharedtypes "github.com/pokt-network/poktroll/x/shared/types" @@ -30,15 +29,6 @@ const ( ) func TestComputeNewDifficultyHash_RewardsReflectWorkCompleted(t *testing.T) { - // Update the target number of relays to a value that suits the test. - // A too high number would make the difficulty stay at BaseRelayDifficultyHash - initialTargetRelays := servicekeeper.TargetNumRelays - servicekeeper.TargetNumRelays = 1000 - t.Cleanup(func() { - // Reset the target number of relays to its initial value. - servicekeeper.TargetNumRelays = initialTargetRelays - }) - // Prepare the test service. service := sharedtypes.Service{ Id: "svc1", @@ -89,10 +79,17 @@ func TestComputeNewDifficultyHash_RewardsReflectWorkCompleted(t *testing.T) { sdkCtx := sdk.UnwrapSDKContext(ctx) sdkCtx = sdkCtx.WithBlockHeight(1) + // Update the target number of relays to a value that suits the test. + // A too high number would make the difficulty stay at BaseRelayDifficultyHash + serviceParams := keepers.ServiceKeeper.GetParams(ctx) + serviceParams.TargetNumRelays = 1000 + err := keepers.ServiceKeeper.SetParams(ctx, serviceParams) + require.NoError(t, err) + // Set the CUTTM to 1 to simplify the math sharedParams := keepers.SharedKeeper.GetParams(sdkCtx) sharedParams.ComputeUnitsToTokensMultiplier = uint64(1) - err := keepers.SharedKeeper.SetParams(sdkCtx, sharedParams) + err = keepers.SharedKeeper.SetParams(sdkCtx, sharedParams) require.NoError(t, err) // Update the relay mining difficulty so there's always a difficulty to retrieve @@ -159,10 +156,12 @@ func TestComputeNewDifficultyHash_RewardsReflectWorkCompleted(t *testing.T) { updatedRelayMiningDifficulty, ok := keepers.ServiceKeeper.GetRelayMiningDifficulty(sdkCtx, service.Id) require.True(t, ok) + targetNumRelays := keepers.ServiceKeeper.GetParams(ctx).TargetNumRelays + // Compute the new difficulty hash based on the updated relay mining difficulty. newDifficultyHash := protocol.ComputeNewDifficultyTargetHash( protocol.BaseRelayDifficultyHashBz, - servicekeeper.TargetNumRelays, + targetNumRelays, updatedRelayMiningDifficulty.NumRelaysEma, ) diff --git a/testutil/integration/suites/param_configs.go b/testutil/integration/suites/param_configs.go index 9a509587e..1e3a52e9e 100644 --- a/testutil/integration/suites/param_configs.go +++ b/testutil/integration/suites/param_configs.go @@ -131,10 +131,12 @@ var ( QueryParamsResponse: servicetypes.QueryParamsResponse{}, }, ValidParams: servicetypes.Params{ - AddServiceFee: &ValidAddServiceFeeCoin, + AddServiceFee: &ValidAddServiceFeeCoin, + TargetNumRelays: servicetypes.DefaultTargetNumRelays, }, ParamTypes: map[ParamType]any{ - ParamTypeCoin: servicetypes.MsgUpdateParam_AsCoin{}, + ParamTypeCoin: servicetypes.MsgUpdateParam_AsCoin{}, + ParamTypeUint64: servicetypes.MsgUpdateParam_AsUint64{}, }, DefaultParams: servicetypes.DefaultParams(), NewParamClientFn: servicetypes.NewQueryClient, diff --git a/testutil/keeper/tokenomics.go b/testutil/keeper/tokenomics.go index ff5729376..e4cef7328 100644 --- a/testutil/keeper/tokenomics.go +++ b/testutil/keeper/tokenomics.go @@ -251,7 +251,14 @@ func TokenomicsKeeperWithActorAddrs(t testing.TB) ( Return(sharedtypes.Service{}, false). AnyTimes() - relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty(sdkCtx, log.NewNopLogger(), service.Id, servicekeeper.TargetNumRelays) + targetNumRelays := servicetypes.DefaultTargetNumRelays + relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty( + sdkCtx, + log.NewNopLogger(), + service.Id, + targetNumRelays, + targetNumRelays, + ) mockServiceKeeper.EXPECT(). GetRelayMiningDifficulty(gomock.Any(), gomock.Any()). Return(relayMiningDifficulty, true). diff --git a/tools/scripts/params/service_all.json b/tools/scripts/params/service_all.json index 9a1f3f682..8296fc869 100644 --- a/tools/scripts/params/service_all.json +++ b/tools/scripts/params/service_all.json @@ -8,7 +8,8 @@ "add_service_fee": { "denom": "upokt", "amount": "1000000000" - } + }, + "target_num_relays": 100000 } } ] diff --git a/tools/scripts/params/service_target_num_relays.json b/tools/scripts/params/service_target_num_relays.json new file mode 100644 index 000000000..6c84324e3 --- /dev/null +++ b/tools/scripts/params/service_target_num_relays.json @@ -0,0 +1,12 @@ +{ + "body": { + "messages": [ + { + "@type": "/poktroll.service.MsgUpdateParam", + "authority": "pokt10d07y265gmmuvt4z0w9aw880jnsr700j8yv32t", + "name": "target_num_relays", + "as_uint64": 100000 + } + ] + } +} diff --git a/x/application/types/message_update_param.go b/x/application/types/message_update_param.go index ed66a4ee4..251ab6a4b 100644 --- a/x/application/types/message_update_param.go +++ b/x/application/types/message_update_param.go @@ -43,12 +43,12 @@ func (msg *MsgUpdateParam) ValidateBasic() error { // Parameter name MUST be supported by this module. switch msg.Name { case ParamMaxDelegatedGateways: - if err := msg.paramTypeIsUint64(); err != nil { + if err := genericParamTypeIs[*MsgUpdateParam_AsUint64](msg); err != nil { return err } return ValidateMaxDelegatedGateways(msg.GetAsUint64()) case ParamMinStake: - if err := msg.paramTypeIsCoin(); err != nil { + if err := genericParamTypeIs[*MsgUpdateParam_AsCoin](msg); err != nil { return err } return ValidateMinStake(msg.GetAsCoin()) @@ -57,22 +57,14 @@ func (msg *MsgUpdateParam) ValidateBasic() error { } } -func (msg *MsgUpdateParam) paramTypeIsUint64() error { - if _, ok := msg.AsType.(*MsgUpdateParam_AsUint64); !ok { - return ErrAppParamInvalid.Wrapf(""+ +// genericTypeIsCoin checks if the parameter type is T, returning an error if not. +func genericParamTypeIs[T any](msg *MsgUpdateParam) error { + if _, ok := msg.AsType.(T); !ok { + return ErrAppParamInvalid.Wrapf( "invalid type for param %q; expected %T, got %T", - msg.Name, &MsgUpdateParam_AsUint64{}, msg.AsType, + msg.Name, *new(T), msg.AsType, ) } - return nil -} -func (msg *MsgUpdateParam) paramTypeIsCoin() error { - if _, ok := msg.AsType.(*MsgUpdateParam_AsCoin); !ok { - return ErrAppParamInvalid.Wrapf(""+ - "invalid type for param %q; expected %T, got %T", - msg.Name, &MsgUpdateParam_AsCoin{}, msg.AsType, - ) - } return nil } diff --git a/x/proof/keeper/msg_server_create_claim_test.go b/x/proof/keeper/msg_server_create_claim_test.go index b48973b1c..f97982cfd 100644 --- a/x/proof/keeper/msg_server_create_claim_test.go +++ b/x/proof/keeper/msg_server_create_claim_test.go @@ -174,8 +174,14 @@ func TestMsgServer_CreateClaim_Success(t *testing.T) { claimCreatedEvents := testutilevents.FilterEvents[*prooftypes.EventClaimCreated](t, events) require.Len(t, claimCreatedEvents, 1) - targetNumRelays := servicekeeper.TargetNumRelays - relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty(ctx, keepers.Logger(), service.Id, targetNumRelays) + targetNumRelays := keepers.ServiceKeeper.GetParams(ctx).TargetNumRelays + relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty( + ctx, + keepers.Logger(), + service.Id, + targetNumRelays, + targetNumRelays, + ) numEstimatedComputUnits, err := claim.GetNumEstimatedComputeUnits(relayMiningDifficulty) require.NoError(t, err) diff --git a/x/proof/keeper/msg_server_submit_proof_test.go b/x/proof/keeper/msg_server_submit_proof_test.go index cca419533..35185f798 100644 --- a/x/proof/keeper/msg_server_submit_proof_test.go +++ b/x/proof/keeper/msg_server_submit_proof_test.go @@ -235,8 +235,14 @@ func TestMsgServer_SubmitProof_Success(t *testing.T) { proofSubmittedEvent := proofSubmittedEvents[0] - targetNumRelays := servicekeeper.TargetNumRelays - relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty(ctx, keepers.Logger(), service.Id, targetNumRelays) + targetNumRelays := keepers.ServiceKeeper.GetParams(ctx).TargetNumRelays + relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty( + ctx, + keepers.Logger(), + service.Id, + targetNumRelays, + targetNumRelays, + ) numEstimatedComputUnits, err := claim.GetNumEstimatedComputeUnits(relayMiningDifficulty) require.NoError(t, err) diff --git a/x/proof/keeper/proof_validation_test.go b/x/proof/keeper/proof_validation_test.go index f00022d2a..d3389f103 100644 --- a/x/proof/keeper/proof_validation_test.go +++ b/x/proof/keeper/proof_validation_test.go @@ -782,7 +782,14 @@ func setRelayMiningDifficultyHash( targetHash []byte, logger log.Logger, ) { - relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty(ctx, logger, serviceId, servicekeeper.TargetNumRelays) + targetNumRelays := serviceKeeper.GetParams(ctx).TargetNumRelays + relayMiningDifficulty := servicekeeper.NewDefaultRelayMiningDifficulty( + ctx, + logger, + serviceId, + targetNumRelays, + targetNumRelays, + ) relayMiningDifficulty.TargetHash = targetHash serviceKeeper.SetRelayMiningDifficulty(ctx, relayMiningDifficulty) } diff --git a/x/proof/types/expected_keepers.go b/x/proof/types/expected_keepers.go index 66103d2b8..9d1fd765e 100644 --- a/x/proof/types/expected_keepers.go +++ b/x/proof/types/expected_keepers.go @@ -63,4 +63,5 @@ type ServiceKeeper interface { // Only used for testing & simulation SetService(ctx context.Context, service sharedtypes.Service) SetRelayMiningDifficulty(ctx context.Context, relayMiningDifficulty servicetypes.RelayMiningDifficulty) + GetParams(ctx context.Context) servicetypes.Params } diff --git a/x/service/keeper/msg_server_update_param.go b/x/service/keeper/msg_server_update_param.go index ac1ea6a6c..bcbe2cb39 100644 --- a/x/service/keeper/msg_server_update_param.go +++ b/x/service/keeper/msg_server_update_param.go @@ -6,15 +6,15 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/pokt-network/poktroll/x/service/types" + servicetypes "github.com/pokt-network/poktroll/x/service/types" ) // UpdateParam updates a single parameter in the service module and returns // all active parameters. func (k msgServer) UpdateParam( ctx context.Context, - msg *types.MsgUpdateParam, -) (*types.MsgUpdateParamResponse, error) { + msg *servicetypes.MsgUpdateParam, +) (*servicetypes.MsgUpdateParamResponse, error) { logger := k.logger.With( "method", "UpdateParam", "param_name", msg.Name, @@ -27,7 +27,7 @@ func (k msgServer) UpdateParam( if k.GetAuthority() != msg.Authority { return nil, status.Error( codes.InvalidArgument, - types.ErrServiceInvalidSigner.Wrapf( + servicetypes.ErrServiceInvalidSigner.Wrapf( "invalid authority; expected %s, got %s", k.GetAuthority(), msg.Authority, ).Error(), @@ -37,13 +37,16 @@ func (k msgServer) UpdateParam( params := k.GetParams(ctx) switch msg.Name { - case types.ParamAddServiceFee: + case servicetypes.ParamAddServiceFee: logger = logger.With("param_value", msg.GetAsCoin()) params.AddServiceFee = msg.GetAsCoin() + case servicetypes.ParamTargetNumRelays: + logger = logger.With("param_value", msg.GetAsUint64()) + params.TargetNumRelays = msg.GetAsUint64() default: return nil, status.Error( codes.InvalidArgument, - types.ErrServiceParamInvalid.Wrapf("unsupported param %q", msg.Name).Error(), + servicetypes.ErrServiceParamInvalid.Wrapf("unsupported param %q", msg.Name).Error(), ) } @@ -60,7 +63,7 @@ func (k msgServer) UpdateParam( updatedParams := k.GetParams(ctx) - return &types.MsgUpdateParamResponse{ + return &servicetypes.MsgUpdateParamResponse{ Params: &updatedParams, }, nil } diff --git a/x/service/keeper/msg_server_update_param_test.go b/x/service/keeper/msg_server_update_param_test.go index 67c2eb979..d6d774872 100644 --- a/x/service/keeper/msg_server_update_param_test.go +++ b/x/service/keeper/msg_server_update_param_test.go @@ -40,3 +40,30 @@ func TestMsgUpdateParam_UpdateAddServiceFeeOnly(t *testing.T) { // Ensure the other parameters are unchanged testkeeper.AssertDefaultParamsEqualExceptFields(t, &defaultParams, res.Params, "AddServiceFee") } + +func TestMsgUpdateParam_UpdateTargetNumRelaysOnly(t *testing.T) { + expectedTargetNumRelays := uint64(9001) + + // Set the parameters to their default values + k, msgSrv, ctx := setupMsgServer(t) + defaultParams := servicetypes.DefaultParams() + require.NoError(t, k.SetParams(ctx, defaultParams)) + + // Ensure the default values are different from the new values we want to set + require.NotEqual(t, expectedTargetNumRelays, defaultParams.TargetNumRelays) + + // Update the add service fee parameter + updateParamMsg := &servicetypes.MsgUpdateParam{ + Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Name: servicetypes.ParamTargetNumRelays, + AsType: &servicetypes.MsgUpdateParam_AsUint64{AsUint64: expectedTargetNumRelays}, + } + res, err := msgSrv.UpdateParam(ctx, updateParamMsg) + require.NoError(t, err) + + require.NotEqual(t, defaultParams.TargetNumRelays, res.Params.TargetNumRelays) + require.Equal(t, expectedTargetNumRelays, res.Params.TargetNumRelays) + + // Ensure the other parameters are unchanged + testkeeper.AssertDefaultParamsEqualExceptFields(t, &defaultParams, res.Params, "TargetNumRelays") +} diff --git a/x/service/keeper/msg_update_params_test.go b/x/service/keeper/msg_update_params_test.go index e473aab7d..f8500e860 100644 --- a/x/service/keeper/msg_update_params_test.go +++ b/x/service/keeper/msg_update_params_test.go @@ -5,24 +5,24 @@ import ( "github.com/stretchr/testify/require" - "github.com/pokt-network/poktroll/x/service/types" + servicetypes "github.com/pokt-network/poktroll/x/service/types" ) func TestMsgUpdateParams(t *testing.T) { k, ms, ctx := setupMsgServer(t) - params := types.DefaultParams() + params := servicetypes.DefaultParams() require.NoError(t, k.SetParams(ctx, params)) // default params tests := []struct { desc string - input *types.MsgUpdateParams + input *servicetypes.MsgUpdateParams shouldError bool expectedErrMsg string }{ { desc: "invalid: authority address invalid", - input: &types.MsgUpdateParams{ + input: &servicetypes.MsgUpdateParams{ Authority: "invalid", Params: params, }, @@ -31,16 +31,16 @@ func TestMsgUpdateParams(t *testing.T) { }, { desc: "invalid: send empty params", - input: &types.MsgUpdateParams{ + input: &servicetypes.MsgUpdateParams{ Authority: k.GetAuthority(), - Params: types.Params{}, + Params: servicetypes.Params{}, }, shouldError: true, expectedErrMsg: "missing add_service_fee", }, { desc: "valid: send default params", - input: &types.MsgUpdateParams{ + input: &servicetypes.MsgUpdateParams{ Authority: k.GetAuthority(), Params: params, }, diff --git a/x/service/keeper/params_test.go b/x/service/keeper/params_test.go index 556f1de0f..fa00efcc4 100644 --- a/x/service/keeper/params_test.go +++ b/x/service/keeper/params_test.go @@ -46,3 +46,38 @@ func TestParams_ValidateAddServiceFee(t *testing.T) { }) } } + +func TestParams_ValidateTargetNumRelays(t *testing.T) { + tests := []struct { + desc string + targetNumRelays any + expectedErr error + }{ + { + desc: "invalid type", + targetNumRelays: "999", + expectedErr: servicetypes.ErrServiceParamInvalid, + }, + { + desc: "invalid value", + targetNumRelays: 0, + expectedErr: servicetypes.ErrServiceParamInvalid, + }, + { + desc: "valid TargetNumRelays", + targetNumRelays: uint64(999), + }, + } + + for _, test := range tests { + t.Run(test.desc, func(t *testing.T) { + err := servicetypes.ValidateTargetNumRelays(test.targetNumRelays) + if test.expectedErr != nil { + require.Error(t, err) + require.Contains(t, err.Error(), test.expectedErr.Error()) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/x/service/keeper/relay_mining_difficulty.go b/x/service/keeper/relay_mining_difficulty.go index eae318f91..05ac62a36 100644 --- a/x/service/keeper/relay_mining_difficulty.go +++ b/x/service/keeper/relay_mining_difficulty.go @@ -31,11 +31,18 @@ func (k Keeper) GetRelayMiningDifficulty( difficultyBz := store.Get(types.RelayMiningDifficultyKey(serviceId)) if difficultyBz == nil { + targetNumRelays := k.GetParams(ctx).TargetNumRelays k.Logger().Warn(fmt.Sprintf( "relayMiningDifficulty not found for service: %s, defaulting to base difficulty with protocol TargetNumRelays (%d)", - serviceId, TargetNumRelays, + serviceId, targetNumRelays, )) - difficulty = NewDefaultRelayMiningDifficulty(ctx, k.logger, serviceId, TargetNumRelays) + difficulty = NewDefaultRelayMiningDifficulty( + ctx, + k.logger, + serviceId, + targetNumRelays, + targetNumRelays, + ) return difficulty, false } diff --git a/x/service/keeper/update_relay_mining_difficulty.go b/x/service/keeper/update_relay_mining_difficulty.go index 0a3ac6fc8..b73e79131 100644 --- a/x/service/keeper/update_relay_mining_difficulty.go +++ b/x/service/keeper/update_relay_mining_difficulty.go @@ -16,15 +16,6 @@ import ( ) var ( - // TargetNumRelays is the target number of relays we want the network to mine for - // a specific service across all applications & suppliers per session. - // This number determines the total number of leafs to be created across in - // the off-chain SMTs, across all suppliers, for each service. - // It indirectly drives the off-chain resource requirements of the network - // in additional to playing a critical role in Relay Mining. - // TODO_MAINNET(#542): Make this a governance parameter and figure out the correct value. - TargetNumRelays = uint64(10e4) - // Exponential moving average (ema) smoothing factor, commonly known as alpha. // Usually, alpha = 2 / (N+1), where N is the number of periods. // Large alpha -> more weight on recent data; less smoothing and fast response. @@ -53,12 +44,19 @@ func (k Keeper) UpdateRelayMiningDifficulty( // Iterate over the relaysPerServiceMap deterministically by sorting the keys. // This ensures that the order of the keys is consistent across different nodes. // See comment: https://github.com/pokt-network/poktroll/pull/840#discussion_r1796663285 + targetNumRelays := k.GetParams(ctx).TargetNumRelays sortedRelayPerServiceMapKeys := getSortedMapKeys(relaysPerServiceMap) for _, serviceId := range sortedRelayPerServiceMapKeys { numRelays := relaysPerServiceMap[serviceId] prevDifficulty, found := k.GetRelayMiningDifficulty(ctx, serviceId) if !found { - prevDifficulty = NewDefaultRelayMiningDifficulty(ctx, logger, serviceId, numRelays) + prevDifficulty = NewDefaultRelayMiningDifficulty( + ctx, + logger, + serviceId, + numRelays, + targetNumRelays, + ) } // TODO_MAINNET(@Olshansk): We could potentially compute the smoothing factor @@ -83,7 +81,7 @@ func (k Keeper) UpdateRelayMiningDifficulty( // We kept scaling down even though numRelaysEma was decreasing. // To avoid continuing to increase the difficulty (i.e. scaling down), the // relative starting difficulty has to be kept constant. - difficultyHash := protocol.ComputeNewDifficultyTargetHash(protocol.BaseRelayDifficultyHashBz, TargetNumRelays, newRelaysEma) + difficultyHash := protocol.ComputeNewDifficultyTargetHash(protocol.BaseRelayDifficultyHashBz, targetNumRelays, newRelaysEma) newDifficulty := types.RelayMiningDifficulty{ ServiceId: serviceId, BlockHeight: sdkCtx.BlockHeight(), @@ -152,11 +150,12 @@ func NewDefaultRelayMiningDifficulty( logger log.Logger, serviceId string, numRelays uint64, + targetNumRelays uint64, ) types.RelayMiningDifficulty { logger = logger.With("helper", "NewDefaultRelayMiningDifficulty") // Compute the target hash based on the number of relays seen for the first time. - newDifficultyHash := protocol.ComputeNewDifficultyTargetHash(protocol.BaseRelayDifficultyHashBz, TargetNumRelays, numRelays) + newDifficultyHash := protocol.ComputeNewDifficultyTargetHash(protocol.BaseRelayDifficultyHashBz, targetNumRelays, numRelays) logger.Warn(types.ErrServiceMissingRelayMiningDifficulty.Wrapf( "No previous relay mining difficulty found for service %s.\n"+ diff --git a/x/service/keeper/update_relay_mining_difficulty_test.go b/x/service/keeper/update_relay_mining_difficulty_test.go index ed46c2ac2..87380e2c8 100644 --- a/x/service/keeper/update_relay_mining_difficulty_test.go +++ b/x/service/keeper/update_relay_mining_difficulty_test.go @@ -10,7 +10,6 @@ import ( "github.com/pokt-network/poktroll/pkg/crypto/protocol" testutilevents "github.com/pokt-network/poktroll/testutil/events" keepertest "github.com/pokt-network/poktroll/testutil/keeper" - servicekeeper "github.com/pokt-network/poktroll/x/service/keeper" servicetypes "github.com/pokt-network/poktroll/x/service/types" ) @@ -150,7 +149,8 @@ func TestUpdateRelayMiningDifficulty_Base(t *testing.T) { require.True(t, found) require.Less(t, difficultySvc22.NumRelaysEma, difficultySvc21.NumRelaysEma) // Since the relays EMA is lower than the target, the difficulty hash is all 1s - require.Less(t, difficultySvc22.NumRelaysEma, servicekeeper.TargetNumRelays) + targetNumRelays := keeper.GetParams(ctx).TargetNumRelays + require.Less(t, difficultySvc22.NumRelaysEma, targetNumRelays) require.Equal(t, difficultySvc22.TargetHash, makeBytesFullOfOnes(32)) // svc3 is new so the relay ema is equal to the first value provided @@ -172,29 +172,29 @@ func TestUpdateRelayMiningDifficulty_FirstDifficulty(t *testing.T) { }{ { desc: "First Difficulty way below target", - numRelays: servicekeeper.TargetNumRelays / 1e3, + numRelays: servicetypes.DefaultTargetNumRelays / 1e3, expectedRelayMiningDifficulty: servicetypes.RelayMiningDifficulty{ ServiceId: "svc1", BlockHeight: 1, - NumRelaysEma: servicekeeper.TargetNumRelays / 1e3, + NumRelaysEma: servicetypes.DefaultTargetNumRelays / 1e3, TargetHash: defaultDifficulty(), // default difficulty without any leading 0 bits }, }, { desc: "First Difficulty equal to target", - numRelays: servicekeeper.TargetNumRelays, + numRelays: servicetypes.DefaultTargetNumRelays, expectedRelayMiningDifficulty: servicetypes.RelayMiningDifficulty{ ServiceId: "svc1", BlockHeight: 1, - NumRelaysEma: servicekeeper.TargetNumRelays, + NumRelaysEma: servicetypes.DefaultTargetNumRelays, TargetHash: defaultDifficulty(), // default difficulty without any leading 0 bits }, }, { desc: "First Difficulty way above target", - numRelays: servicekeeper.TargetNumRelays * 1e3, + numRelays: servicetypes.DefaultTargetNumRelays * 1e3, expectedRelayMiningDifficulty: servicetypes.RelayMiningDifficulty{ ServiceId: "svc1", BlockHeight: 1, - NumRelaysEma: servicekeeper.TargetNumRelays * 1e3, + NumRelaysEma: servicetypes.DefaultTargetNumRelays * 1e3, TargetHash: append( []byte{0b00000000}, // at least 8 leading 0 bits makeBytesFullOfOnes(31)..., diff --git a/x/service/types/message_update_param.go b/x/service/types/message_update_param.go index 7d3ad2c15..d6ec1b1eb 100644 --- a/x/service/types/message_update_param.go +++ b/x/service/types/message_update_param.go @@ -1,10 +1,10 @@ package types import ( - sdk "github.com/cosmos/cosmos-sdk/types" + cosmostypes "github.com/cosmos/cosmos-sdk/types" ) -var _ sdk.Msg = (*MsgUpdateParam)(nil) +var _ cosmostypes.Msg = (*MsgUpdateParam)(nil) // NewMsgUpdateParam creates a new MsgUpdateParam instance for a single // governance parameter update. @@ -12,8 +12,10 @@ func NewMsgUpdateParam(authority string, name string, asType any) (*MsgUpdatePar var asTypeIface isMsgUpdateParam_AsType switch t := asType.(type) { - case *sdk.Coin: + case *cosmostypes.Coin: asTypeIface = &MsgUpdateParam_AsCoin{AsCoin: t} + case uint64: + asTypeIface = &MsgUpdateParam_AsUint64{AsUint64: t} default: return nil, ErrServiceParamInvalid.Wrapf("unexpected param value type: %T", asType) } @@ -30,7 +32,7 @@ func NewMsgUpdateParam(authority string, name string, asType any) (*MsgUpdatePar // a given parameter name. func (msg *MsgUpdateParam) ValidateBasic() error { // Validate the address - if _, err := sdk.AccAddressFromBech32(msg.Authority); err != nil { + if _, err := cosmostypes.AccAddressFromBech32(msg.Authority); err != nil { return ErrServiceInvalidAddress.Wrapf("invalid authority address %s; (%v)", msg.Authority, err) } @@ -42,23 +44,25 @@ func (msg *MsgUpdateParam) ValidateBasic() error { // Parameter name MUST be supported by this module. switch msg.Name { case ParamAddServiceFee: - if err := msg.paramTypeIsCoin(); err != nil { + if err := genericParamTypeIs[*MsgUpdateParam_AsCoin](msg); err != nil { return err } return ValidateAddServiceFee(msg.GetAsCoin()) + case ParamTargetNumRelays: + return ValidateTargetNumRelays(msg.GetAsUint64()) default: return ErrServiceParamInvalid.Wrapf("unsupported param %q", msg.Name) } } -// paramTypeIsCoin checks if the parameter type is *cosmostypes.Coin, returning an error if not. -func (msg *MsgUpdateParam) paramTypeIsCoin() error { - if _, ok := msg.AsType.(*MsgUpdateParam_AsCoin); !ok { +// genericParamTypeIs checks if the parameter type is T, returning an error if not. +func genericParamTypeIs[T any](msg *MsgUpdateParam) error { + if _, ok := msg.AsType.(T); !ok { return ErrServiceParamInvalid.Wrapf( - "invalid type for param %q expected %T, got %T", - msg.Name, &MsgUpdateParam_AsCoin{}, - msg.AsType, + "invalid type for param %q; expected %T, got %T", + msg.Name, *new(T), msg.AsType, ) } + return nil } diff --git a/x/service/types/message_update_param_test.go b/x/service/types/message_update_param_test.go index 75a45c41a..3bfb599d1 100644 --- a/x/service/types/message_update_param_test.go +++ b/x/service/types/message_update_param_test.go @@ -25,7 +25,8 @@ func TestMsgUpdateParam_ValidateBasic(t *testing.T) { AsType: &MsgUpdateParam_AsCoin{AsCoin: nil}, }, expectedErr: sdkerrors.ErrInvalidAddress, - }, { + }, + { desc: "invalid: param name incorrect (non-existent)", msg: MsgUpdateParam{ Authority: sample.AccAddress(), @@ -33,7 +34,8 @@ func TestMsgUpdateParam_ValidateBasic(t *testing.T) { AsType: &MsgUpdateParam_AsCoin{AsCoin: &MinAddServiceFee}, }, expectedErr: ErrServiceParamInvalid, - }, { + }, + { name: "valid address", desc: "valid: correct address, param name, and type", msg: MsgUpdateParam{ diff --git a/x/service/types/params.go b/x/service/types/params.go index b9bc3026b..2903dee89 100644 --- a/x/service/types/params.go +++ b/x/service/types/params.go @@ -14,11 +14,14 @@ import ( var ( _ paramtypes.ParamSet = (*Params)(nil) - KeyAddServiceFee = []byte("AddServiceFee") - ParamAddServiceFee = "add_service_fee" - // TODO_TECHDEBT: Determine a sensible default/min value for the add service fee. - // MinAddServiceFee is the default and minimum fee for adding a new service. - MinAddServiceFee = cosmostypes.NewCoin(volatile.DenomuPOKT, math.NewInt(1000000000)) + // TODO_MAINNET: Determine a sensible default/min values. + + KeyAddServiceFee = []byte("AddServiceFee") + ParamAddServiceFee = "add_service_fee" + MinAddServiceFee = cosmostypes.NewCoin(volatile.DenomuPOKT, math.NewInt(1000000000)) + KeyTargetNumRelays = []byte("TargetNumRelays") + ParamTargetNumRelays = "target_num_relays" + DefaultTargetNumRelays = uint64(10e4) ) // ParamKeyTable the param key table for launch module @@ -27,9 +30,13 @@ func ParamKeyTable() paramtypes.KeyTable { } // NewParams creates a new Params instance -func NewParams(addServiceFee *cosmostypes.Coin) Params { +func NewParams( + addServiceFee *cosmostypes.Coin, + targetNumRelays uint64, +) Params { return Params{ - AddServiceFee: addServiceFee, + AddServiceFee: addServiceFee, + TargetNumRelays: targetNumRelays, } } @@ -37,6 +44,7 @@ func NewParams(addServiceFee *cosmostypes.Coin) Params { func DefaultParams() Params { return NewParams( &MinAddServiceFee, + DefaultTargetNumRelays, ) } @@ -44,6 +52,7 @@ func DefaultParams() Params { func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{ paramtypes.NewParamSetPair(KeyAddServiceFee, &p.AddServiceFee, ValidateAddServiceFee), + paramtypes.NewParamSetPair(KeyTargetNumRelays, &p.AddServiceFee, ValidateTargetNumRelays), } } @@ -52,10 +61,15 @@ func (p Params) ValidateBasic() error { if err := ValidateAddServiceFee(p.AddServiceFee); err != nil { return err } + + if err := ValidateTargetNumRelays(p.TargetNumRelays); err != nil { + return err + } + return nil } -// validateAddServiceFee validates the AddServiceFee param +// ValidateAddServiceFee validates the AddServiceFee param func ValidateAddServiceFee(addServiceFeeAny any) error { addServiceFee, ok := addServiceFeeAny.(*cosmostypes.Coin) if !ok { @@ -81,3 +95,17 @@ func ValidateAddServiceFee(addServiceFeeAny any) error { return nil } + +// ValidateTargetNumRelays validates the TargetNumRelays param +func ValidateTargetNumRelays(targetNumRelaysAny any) error { + targetNumRelays, ok := targetNumRelaysAny.(uint64) + if !ok { + return ErrServiceParamInvalid.Wrapf("invalid parameter type: %T", targetNumRelaysAny) + } + + if targetNumRelays < 1 { + return ErrServiceParamInvalid.Wrapf("target_num_relays must be greater than 0: got %d", targetNumRelays) + } + + return nil +} diff --git a/x/service/types/params.pb.go b/x/service/types/params.pb.go index 8a12bc9f0..3fd9295e8 100644 --- a/x/service/types/params.pb.go +++ b/x/service/types/params.pb.go @@ -31,6 +31,9 @@ type Params struct { // This will be deducted from the signer's account balance, // and transferred to the pocket network foundation. AddServiceFee *types.Coin `protobuf:"bytes,1,opt,name=add_service_fee,json=addServiceFee,proto3" json:"add_service_fee" yaml:"add_service_fee"` + // target_num_relays is the target for the EMA of the number of relays per session. + // Per service, on-chain relay mining difficulty will be adjusted to maintain this target. + TargetNumRelays uint64 `protobuf:"varint,2,opt,name=target_num_relays,json=targetNumRelays,proto3" json:"target_num_relays" yaml:"target_num_relays"` } func (m *Params) Reset() { *m = Params{} } @@ -69,6 +72,13 @@ func (m *Params) GetAddServiceFee() *types.Coin { return nil } +func (m *Params) GetTargetNumRelays() uint64 { + if m != nil { + return m.TargetNumRelays + } + return 0 +} + func init() { proto.RegisterType((*Params)(nil), "poktroll.service.Params") } @@ -76,25 +86,28 @@ func init() { func init() { proto.RegisterFile("poktroll/service/params.proto", fileDescriptor_69b5d0104478b383) } var fileDescriptor_69b5d0104478b383 = []byte{ - // 277 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2d, 0xc8, 0xcf, 0x2e, - 0x29, 0xca, 0xcf, 0xc9, 0xd1, 0x2f, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0xd5, 0x2f, 0x48, 0x2c, - 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x80, 0x49, 0xeb, 0x41, 0xa5, - 0xa5, 0x04, 0x13, 0x73, 0x33, 0xf3, 0xf2, 0xf5, 0xc1, 0x24, 0x44, 0x91, 0x94, 0x48, 0x7a, 0x7e, - 0x7a, 0x3e, 0x98, 0xa9, 0x0f, 0x62, 0x41, 0x45, 0xe5, 0x92, 0xf3, 0x8b, 0x73, 0xf3, 0x8b, 0xf5, - 0x93, 0x12, 0x8b, 0x53, 0xf5, 0xcb, 0x0c, 0x93, 0x52, 0x4b, 0x12, 0x0d, 0xf5, 0x93, 0xf3, 0x33, - 0xf3, 0x20, 0xf2, 0x4a, 0xf3, 0x18, 0xb9, 0xd8, 0x02, 0xc0, 0x76, 0x09, 0x15, 0x70, 0xf1, 0x27, - 0xa6, 0xa4, 0xc4, 0x43, 0xad, 0x88, 0x4f, 0x4b, 0x4d, 0x95, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x36, - 0x92, 0xd4, 0x83, 0x18, 0xa2, 0x07, 0x32, 0x44, 0x0f, 0x6a, 0x88, 0x9e, 0x73, 0x7e, 0x66, 0x9e, - 0x93, 0xee, 0xab, 0x7b, 0xf2, 0xe8, 0xba, 0x3e, 0xdd, 0x93, 0x17, 0xab, 0x4c, 0xcc, 0xcd, 0xb1, - 0x52, 0x42, 0x93, 0x50, 0x0a, 0xe2, 0x4d, 0x4c, 0x49, 0x09, 0x86, 0x08, 0xb8, 0xa5, 0xa6, 0x5a, - 0x29, 0xbd, 0x58, 0x20, 0xcf, 0xd8, 0xf5, 0x7c, 0x83, 0x96, 0x24, 0xdc, 0xff, 0x15, 0xf0, 0x10, - 0x80, 0xb8, 0xca, 0xc9, 0xef, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x6f, 0x3c, 0x92, - 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, - 0x96, 0x63, 0x88, 0x32, 0x48, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x07, - 0x99, 0xa1, 0x9b, 0x97, 0x5a, 0x52, 0x9e, 0x5f, 0x94, 0xad, 0x8f, 0xc5, 0xc0, 0x92, 0xca, 0x82, - 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0xbf, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x60, 0xd1, - 0x42, 0x73, 0x01, 0x00, 0x00, + // 330 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xb1, 0x4a, 0xc3, 0x40, + 0x18, 0xc7, 0x7b, 0x22, 0x1d, 0x22, 0x52, 0x5b, 0x44, 0xda, 0x82, 0x97, 0x92, 0xa9, 0x08, 0xcd, + 0x59, 0xdd, 0x3a, 0x56, 0x70, 0x2c, 0x52, 0x37, 0x41, 0xc2, 0x25, 0x39, 0x63, 0x68, 0x2e, 0x5f, + 0xb8, 0xbb, 0x56, 0xfb, 0x0a, 0x4e, 0x3e, 0x82, 0x8f, 0xe0, 0x63, 0x38, 0x76, 0xec, 0x14, 0x24, + 0x1d, 0x94, 0x8e, 0xdd, 0x05, 0x69, 0x2e, 0x76, 0x68, 0x5d, 0x8e, 0x8f, 0xff, 0xef, 0xee, 0xf7, + 0x71, 0x7f, 0xe3, 0x34, 0x81, 0x91, 0x12, 0x10, 0x45, 0x44, 0x32, 0x31, 0x09, 0x3d, 0x46, 0x12, + 0x2a, 0x28, 0x97, 0x76, 0x22, 0x40, 0x41, 0xed, 0xe8, 0x0f, 0xdb, 0x05, 0x6e, 0x56, 0x29, 0x0f, + 0x63, 0x20, 0xf9, 0xa9, 0x2f, 0x35, 0x8f, 0x03, 0x08, 0x20, 0x1f, 0xc9, 0x7a, 0x2a, 0x52, 0xec, + 0x81, 0xe4, 0x20, 0x89, 0x4b, 0x25, 0x23, 0x93, 0xae, 0xcb, 0x14, 0xed, 0x12, 0x0f, 0xc2, 0x58, + 0x73, 0xeb, 0x07, 0x19, 0xe5, 0x9b, 0x7c, 0x57, 0x2d, 0x31, 0x2a, 0xd4, 0xf7, 0x9d, 0x62, 0x85, + 0xf3, 0xc0, 0x58, 0x1d, 0xb5, 0x50, 0xfb, 0xe0, 0xa2, 0x61, 0x6b, 0x89, 0xbd, 0x96, 0xd8, 0x85, + 0xc4, 0xbe, 0x82, 0x30, 0xee, 0x77, 0x96, 0xa9, 0xb9, 0xfd, 0x6a, 0x95, 0x9a, 0x27, 0x53, 0xca, + 0xa3, 0x9e, 0xb5, 0x05, 0xac, 0xe1, 0x21, 0xf5, 0xfd, 0x5b, 0x1d, 0x5c, 0x33, 0x56, 0xbb, 0x37, + 0xaa, 0x8a, 0x8a, 0x80, 0x29, 0x27, 0x1e, 0x73, 0x47, 0xb0, 0x88, 0x4e, 0x65, 0x7d, 0xaf, 0x85, + 0xda, 0xfb, 0xfd, 0xee, 0x32, 0x35, 0x77, 0xe1, 0x2a, 0x35, 0xeb, 0x5a, 0xbd, 0x83, 0xac, 0x61, + 0x45, 0x67, 0x83, 0x31, 0x1f, 0xe6, 0x49, 0xcf, 0xfa, 0x7e, 0x33, 0xd1, 0xcb, 0xd7, 0xfb, 0x59, + 0x63, 0x53, 0xef, 0xf3, 0xa6, 0x60, 0xfd, 0xe9, 0xfe, 0xe0, 0x23, 0xc3, 0x68, 0x96, 0x61, 0x34, + 0xcf, 0x30, 0xfa, 0xcc, 0x30, 0x7a, 0x5d, 0xe0, 0xd2, 0x6c, 0x81, 0x4b, 0xf3, 0x05, 0x2e, 0xdd, + 0x9d, 0x07, 0xa1, 0x7a, 0x1c, 0xbb, 0xb6, 0x07, 0x9c, 0xac, 0x1d, 0x9d, 0x98, 0xa9, 0x27, 0x10, + 0x23, 0xf2, 0x8f, 0x50, 0x4d, 0x13, 0x26, 0xdd, 0x72, 0x5e, 0xeb, 0xe5, 0x6f, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xcf, 0xf3, 0x1c, 0x51, 0xd2, 0x01, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { @@ -119,6 +132,9 @@ func (this *Params) Equal(that interface{}) bool { if !this.AddServiceFee.Equal(that1.AddServiceFee) { return false } + if this.TargetNumRelays != that1.TargetNumRelays { + return false + } return true } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -141,6 +157,11 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.TargetNumRelays != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.TargetNumRelays)) + i-- + dAtA[i] = 0x10 + } if m.AddServiceFee != nil { { size, err := m.AddServiceFee.MarshalToSizedBuffer(dAtA[:i]) @@ -177,6 +198,9 @@ func (m *Params) Size() (n int) { l = m.AddServiceFee.Size() n += 1 + l + sovParams(uint64(l)) } + if m.TargetNumRelays != 0 { + n += 1 + sovParams(uint64(m.TargetNumRelays)) + } return n } @@ -251,6 +275,25 @@ func (m *Params) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TargetNumRelays", wireType) + } + m.TargetNumRelays = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TargetNumRelays |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) diff --git a/x/service/types/tx.pb.go b/x/service/types/tx.pb.go index 098020211..c6c9e1259 100644 --- a/x/service/types/tx.pb.go +++ b/x/service/types/tx.pb.go @@ -128,6 +128,7 @@ type MsgUpdateParam struct { Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // Types that are valid to be assigned to AsType: // *MsgUpdateParam_AsCoin + // *MsgUpdateParam_AsUint64 AsType isMsgUpdateParam_AsType `protobuf_oneof:"as_type"` } @@ -167,10 +168,14 @@ type isMsgUpdateParam_AsType interface { } type MsgUpdateParam_AsCoin struct { - AsCoin *types.Coin `protobuf:"bytes,9,opt,name=as_coin,json=asCoin,proto3,oneof" json:"as_coin"` + AsCoin *types.Coin `protobuf:"bytes,3,opt,name=as_coin,json=asCoin,proto3,oneof" json:"as_coin"` +} +type MsgUpdateParam_AsUint64 struct { + AsUint64 uint64 `protobuf:"varint,4,opt,name=as_uint64,json=asUint64,proto3,oneof" json:"as_uint64"` } -func (*MsgUpdateParam_AsCoin) isMsgUpdateParam_AsType() {} +func (*MsgUpdateParam_AsCoin) isMsgUpdateParam_AsType() {} +func (*MsgUpdateParam_AsUint64) isMsgUpdateParam_AsType() {} func (m *MsgUpdateParam) GetAsType() isMsgUpdateParam_AsType { if m != nil { @@ -200,10 +205,18 @@ func (m *MsgUpdateParam) GetAsCoin() *types.Coin { return nil } +func (m *MsgUpdateParam) GetAsUint64() uint64 { + if x, ok := m.GetAsType().(*MsgUpdateParam_AsUint64); ok { + return x.AsUint64 + } + return 0 +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*MsgUpdateParam) XXX_OneofWrappers() []interface{} { return []interface{}{ (*MsgUpdateParam_AsCoin)(nil), + (*MsgUpdateParam_AsUint64)(nil), } } @@ -344,43 +357,45 @@ func init() { func init() { proto.RegisterFile("poktroll/service/tx.proto", fileDescriptor_31ba9559706e649e) } var fileDescriptor_31ba9559706e649e = []byte{ - // 575 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0xbf, 0x6f, 0xd3, 0x40, - 0x14, 0xce, 0x95, 0x92, 0xca, 0x97, 0xb6, 0x80, 0x55, 0x48, 0x62, 0x09, 0x27, 0x78, 0x21, 0x44, - 0xaa, 0xdd, 0x14, 0x81, 0x50, 0x10, 0x43, 0xcc, 0x82, 0x90, 0x82, 0x90, 0x2b, 0x90, 0x40, 0x48, - 0xd1, 0x25, 0x3e, 0x39, 0x56, 0x6b, 0x9f, 0xe5, 0xbb, 0xa6, 0xed, 0x86, 0x18, 0x99, 0xf8, 0x03, - 0x60, 0x67, 0xcc, 0xc0, 0x84, 0xc4, 0xde, 0xb1, 0x62, 0xea, 0x54, 0xa1, 0x64, 0x88, 0xc4, 0x5f, - 0x81, 0x7c, 0x3e, 0x27, 0x75, 0x12, 0x61, 0xa9, 0x4b, 0x72, 0xf7, 0xbe, 0xef, 0xfd, 0xf8, 0xde, - 0x7b, 0x67, 0x58, 0x0e, 0xc8, 0x3e, 0x0b, 0xc9, 0xc1, 0x81, 0x41, 0x71, 0x38, 0x70, 0x7b, 0xd8, - 0x60, 0xc7, 0x7a, 0x10, 0x12, 0x46, 0xe4, 0x9b, 0x09, 0xa4, 0x0b, 0x48, 0xb9, 0x85, 0x3c, 0xd7, - 0x27, 0x06, 0xff, 0x8d, 0x49, 0x8a, 0xda, 0x23, 0xd4, 0x23, 0xd4, 0xe8, 0x22, 0x8a, 0x8d, 0x41, - 0xa3, 0x8b, 0x19, 0x6a, 0x18, 0x3d, 0xe2, 0xfa, 0x02, 0x2f, 0x0a, 0xdc, 0xa3, 0x8e, 0x31, 0x68, - 0x44, 0x7f, 0x02, 0x28, 0xc7, 0x40, 0x87, 0xdf, 0x8c, 0xf8, 0x22, 0xa0, 0x2d, 0x87, 0x38, 0x24, - 0xb6, 0x47, 0x27, 0x61, 0xbd, 0xbb, 0x50, 0x69, 0x80, 0x42, 0xe4, 0xd1, 0x45, 0xb8, 0x8f, 0x42, - 0x6c, 0x27, 0xac, 0x18, 0xd6, 0x7e, 0x01, 0x78, 0xa3, 0x4d, 0x9d, 0x37, 0x81, 0x8d, 0x18, 0x7e, - 0xcd, 0x1d, 0xe5, 0xc7, 0x50, 0x42, 0x87, 0xac, 0x4f, 0x42, 0x97, 0x9d, 0x94, 0x40, 0x15, 0xd4, - 0x24, 0xb3, 0xf4, 0xfb, 0xc7, 0xf6, 0x96, 0x28, 0xa6, 0x65, 0xdb, 0x21, 0xa6, 0x74, 0x8f, 0x85, - 0xae, 0xef, 0x58, 0x33, 0xaa, 0xfc, 0x14, 0xe6, 0xe3, 0xd4, 0xa5, 0x95, 0x2a, 0xa8, 0x15, 0x76, - 0x4b, 0xfa, 0x7c, 0xa7, 0xf4, 0x38, 0x83, 0x29, 0x9d, 0x5e, 0x54, 0x72, 0xdf, 0x27, 0xc3, 0x3a, - 0xb0, 0x84, 0x4b, 0xf3, 0xd1, 0xa7, 0xc9, 0xb0, 0x3e, 0x0b, 0xf6, 0x79, 0x32, 0xac, 0x6b, 0xd3, - 0xd2, 0x8f, 0xa7, 0xda, 0xe6, 0x6a, 0xd5, 0xca, 0xb0, 0x38, 0x67, 0xb2, 0x30, 0x0d, 0x88, 0x4f, - 0xb1, 0xf6, 0x13, 0xc0, 0xcd, 0x34, 0x76, 0x65, 0x65, 0x32, 0x5c, 0xf5, 0x91, 0x87, 0xb9, 0x2e, - 0xc9, 0xe2, 0x67, 0xb9, 0x05, 0xd7, 0x10, 0xed, 0x44, 0x23, 0x2d, 0x49, 0x5c, 0x6e, 0x59, 0x17, - 0x61, 0xa2, 0x99, 0xeb, 0x62, 0xe6, 0xfa, 0x73, 0xe2, 0xfa, 0x66, 0xe1, 0xef, 0x45, 0x25, 0x61, - 0xbf, 0xc8, 0x59, 0x79, 0x44, 0x23, 0x73, 0x73, 0x33, 0xad, 0xd9, 0x94, 0x78, 0x48, 0x76, 0x12, - 0x60, 0xed, 0x25, 0xbc, 0x93, 0xae, 0x3d, 0x91, 0x25, 0xef, 0x4c, 0xbb, 0x0c, 0xfe, 0xdf, 0xe5, - 0xa4, 0xb5, 0xda, 0x57, 0x00, 0x37, 0xda, 0xd4, 0x69, 0xd9, 0xf6, 0x5e, 0x4c, 0x90, 0x9f, 0xc1, - 0x0d, 0x72, 0xe4, 0xe3, 0xb0, 0x83, 0x62, 0xc5, 0x99, 0xbd, 0x58, 0xe7, 0x74, 0x61, 0x93, 0x9f, - 0xc0, 0x35, 0x91, 0x6a, 0xc9, 0xa4, 0xf9, 0x96, 0xe9, 0x22, 0x93, 0xb9, 0x1a, 0x4d, 0xda, 0x4a, - 0xe8, 0x4d, 0x39, 0x52, 0x9c, 0xce, 0xad, 0x15, 0xe1, 0xed, 0x54, 0x75, 0x89, 0xd2, 0xdd, 0x6f, - 0x2b, 0xf0, 0x5a, 0x9b, 0x3a, 0xf2, 0x07, 0xb8, 0x9e, 0xda, 0xcf, 0x7b, 0x8b, 0x8a, 0xe7, 0x76, - 0x40, 0x79, 0x90, 0x49, 0x99, 0xf6, 0xf3, 0x1d, 0x2c, 0x5c, 0x5e, 0x91, 0x6a, 0x96, 0xa7, 0x52, - 0xcb, 0x62, 0x4c, 0x43, 0xbf, 0x85, 0xf0, 0x52, 0xd3, 0x2b, 0x4b, 0xfd, 0x66, 0x04, 0xe5, 0x7e, - 0x06, 0x21, 0x89, 0xab, 0x5c, 0xff, 0x18, 0x3d, 0x1d, 0xf3, 0xd5, 0xe9, 0x48, 0x05, 0x67, 0x23, - 0x15, 0x9c, 0x8f, 0x54, 0xf0, 0x67, 0xa4, 0x82, 0x2f, 0x63, 0x35, 0x77, 0x36, 0x56, 0x73, 0xe7, - 0x63, 0x35, 0xf7, 0x7e, 0xc7, 0x71, 0x59, 0xff, 0xb0, 0xab, 0xf7, 0x88, 0x67, 0x44, 0x71, 0xb7, - 0x7d, 0xcc, 0x8e, 0x48, 0xb8, 0x6f, 0x2c, 0x79, 0x55, 0xd1, 0xca, 0xd1, 0x6e, 0x9e, 0x7f, 0x12, - 0x1e, 0xfe, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x9f, 0xce, 0x8f, 0xce, 0xfc, 0x04, 0x00, 0x00, + // 607 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0xbf, 0x6f, 0xd3, 0x4e, + 0x14, 0xf7, 0xb5, 0xf9, 0xb6, 0x5f, 0x5f, 0x7f, 0x00, 0x56, 0xa1, 0x8e, 0x25, 0x9c, 0xe0, 0x85, + 0x50, 0x51, 0xbb, 0x29, 0x50, 0xa1, 0x20, 0x86, 0x98, 0xa5, 0x42, 0x0a, 0x42, 0xae, 0x8a, 0x04, + 0x42, 0x8a, 0x2e, 0xf1, 0xc9, 0xb1, 0x5a, 0xfb, 0x2c, 0xdf, 0x25, 0x6d, 0x37, 0xc4, 0xc8, 0xc4, + 0x1f, 0x00, 0x3b, 0x63, 0x06, 0x56, 0xf6, 0x8e, 0x15, 0x53, 0xa7, 0x08, 0x25, 0x43, 0x50, 0xff, + 0x0a, 0x64, 0xfb, 0x9c, 0xd4, 0x49, 0x44, 0x24, 0x96, 0xe4, 0xee, 0x7d, 0x3e, 0xef, 0xc7, 0xe7, + 0xbd, 0x77, 0x86, 0xf9, 0x80, 0x1c, 0xb1, 0x90, 0x1c, 0x1f, 0x1b, 0x14, 0x87, 0x1d, 0xb7, 0x89, + 0x0d, 0x76, 0xaa, 0x07, 0x21, 0x61, 0x44, 0xba, 0x99, 0x42, 0x3a, 0x87, 0x94, 0x5b, 0xc8, 0x73, + 0x7d, 0x62, 0xc4, 0xbf, 0x09, 0x49, 0x51, 0x9b, 0x84, 0x7a, 0x84, 0x1a, 0x0d, 0x44, 0xb1, 0xd1, + 0x29, 0x37, 0x30, 0x43, 0x65, 0xa3, 0x49, 0x5c, 0x9f, 0xe3, 0x9b, 0x1c, 0xf7, 0xa8, 0x63, 0x74, + 0xca, 0xd1, 0x1f, 0x07, 0xf2, 0x09, 0x50, 0x8f, 0x6f, 0x46, 0x72, 0xe1, 0xd0, 0x86, 0x43, 0x1c, + 0x92, 0xd8, 0xa3, 0x13, 0xb7, 0xde, 0x9d, 0xaa, 0x34, 0x40, 0x21, 0xf2, 0xe8, 0x34, 0xdc, 0x42, + 0x21, 0xb6, 0x53, 0x56, 0x02, 0x6b, 0x3f, 0x00, 0xbc, 0x51, 0xa3, 0xce, 0x61, 0x60, 0x23, 0x86, + 0x5f, 0xc7, 0x8e, 0xd2, 0x1e, 0x14, 0x51, 0x9b, 0xb5, 0x48, 0xe8, 0xb2, 0x33, 0x19, 0x14, 0x41, + 0x49, 0x34, 0xe5, 0x9f, 0xdf, 0xb7, 0x37, 0x78, 0x31, 0x55, 0xdb, 0x0e, 0x31, 0xa5, 0x07, 0x2c, + 0x74, 0x7d, 0xc7, 0x1a, 0x53, 0xa5, 0x67, 0x70, 0x29, 0x49, 0x2d, 0x2f, 0x14, 0x41, 0x69, 0x65, + 0x57, 0xd6, 0x27, 0x3b, 0xa5, 0x27, 0x19, 0x4c, 0xf1, 0xbc, 0x57, 0x10, 0xbe, 0x0d, 0xbb, 0x5b, + 0xc0, 0xe2, 0x2e, 0x95, 0x27, 0x1f, 0x87, 0xdd, 0xad, 0x71, 0xb0, 0x4f, 0xc3, 0xee, 0x96, 0x36, + 0x2a, 0xfd, 0x74, 0xa4, 0x6d, 0xa2, 0x56, 0x2d, 0x0f, 0x37, 0x27, 0x4c, 0x16, 0xa6, 0x01, 0xf1, + 0x29, 0xd6, 0x7e, 0x03, 0xb8, 0x9e, 0xc5, 0xfe, 0x59, 0x99, 0x04, 0x73, 0x3e, 0xf2, 0x70, 0xac, + 0x4b, 0xb4, 0xe2, 0xb3, 0x54, 0x85, 0xcb, 0x88, 0xd6, 0xa3, 0x91, 0xca, 0x8b, 0xb1, 0xdc, 0xbc, + 0xce, 0xc3, 0x44, 0x33, 0xd7, 0xf9, 0xcc, 0xf5, 0x17, 0xc4, 0xf5, 0xcd, 0x95, 0xab, 0x5e, 0x21, + 0x65, 0xef, 0x0b, 0xd6, 0x12, 0xa2, 0x91, 0x59, 0x7a, 0x08, 0x45, 0x44, 0xeb, 0x6d, 0xd7, 0x67, + 0x7b, 0x8f, 0xe5, 0x5c, 0x11, 0x94, 0x72, 0xe6, 0xda, 0x55, 0xaf, 0x30, 0x36, 0xee, 0x0b, 0xd6, + 0xff, 0x88, 0x1e, 0xc6, 0xe7, 0xca, 0x7a, 0xb6, 0x43, 0xa6, 0x18, 0x17, 0xc0, 0xce, 0x02, 0xac, + 0xbd, 0x84, 0x77, 0xb2, 0x4a, 0xd3, 0x26, 0x48, 0x3b, 0xa3, 0x99, 0x80, 0xbf, 0xcf, 0x24, 0x1d, + 0x84, 0xf6, 0x05, 0xc0, 0xb5, 0x1a, 0x75, 0xaa, 0xb6, 0x7d, 0x90, 0x10, 0xa4, 0xe7, 0x70, 0x8d, + 0x9c, 0xf8, 0x38, 0xac, 0xa3, 0xa4, 0x3f, 0x73, 0x3b, 0xb7, 0x1a, 0xd3, 0xb9, 0x4d, 0x7a, 0x0a, + 0x97, 0x79, 0xaa, 0x19, 0x7b, 0x11, 0xef, 0xa4, 0xce, 0x33, 0x99, 0xb9, 0x68, 0x2f, 0xac, 0x94, + 0x5e, 0x91, 0x22, 0xc5, 0xd9, 0xdc, 0xda, 0x26, 0xbc, 0x9d, 0xa9, 0x2e, 0x55, 0xba, 0xfb, 0x75, + 0x01, 0x2e, 0xd6, 0xa8, 0x23, 0xbd, 0x87, 0xab, 0x99, 0x6d, 0xbe, 0x37, 0xad, 0x78, 0x62, 0x63, + 0x94, 0x07, 0x73, 0x29, 0xa3, 0x7e, 0xbe, 0x85, 0x2b, 0xd7, 0x17, 0xaa, 0x38, 0xcf, 0x53, 0x29, + 0xcd, 0x63, 0x8c, 0x42, 0xbf, 0x81, 0xf0, 0x5a, 0xd3, 0x0b, 0x33, 0xfd, 0xc6, 0x04, 0xe5, 0xfe, + 0x1c, 0x42, 0x1a, 0x57, 0xf9, 0xef, 0x43, 0xf4, 0xd0, 0xcc, 0x57, 0xe7, 0x7d, 0x15, 0x5c, 0xf4, + 0x55, 0x70, 0xd9, 0x57, 0xc1, 0xaf, 0xbe, 0x0a, 0x3e, 0x0f, 0x54, 0xe1, 0x62, 0xa0, 0x0a, 0x97, + 0x03, 0x55, 0x78, 0xb7, 0xe3, 0xb8, 0xac, 0xd5, 0x6e, 0xe8, 0x4d, 0xe2, 0x19, 0x51, 0xdc, 0x6d, + 0x1f, 0xb3, 0x13, 0x12, 0x1e, 0x19, 0x33, 0xde, 0x60, 0xb4, 0x72, 0xb4, 0xb1, 0x14, 0x7f, 0x40, + 0x1e, 0xfd, 0x09, 0x00, 0x00, 0xff, 0xff, 0xb4, 0xe3, 0x94, 0x22, 0x2a, 0x05, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -665,10 +680,22 @@ func (m *MsgUpdateParam_AsCoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x4a + dAtA[i] = 0x1a } return len(dAtA) - i, nil } +func (m *MsgUpdateParam_AsUint64) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParam_AsUint64) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + i = encodeVarintTx(dAtA, i, uint64(m.AsUint64)) + i-- + dAtA[i] = 0x20 + return len(dAtA) - i, nil +} func (m *MsgUpdateParamResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -834,6 +861,15 @@ func (m *MsgUpdateParam_AsCoin) Size() (n int) { } return n } +func (m *MsgUpdateParam_AsUint64) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovTx(uint64(m.AsUint64)) + return n +} func (m *MsgUpdateParamResponse) Size() (n int) { if m == nil { return 0 @@ -1135,7 +1171,7 @@ func (m *MsgUpdateParam) Unmarshal(dAtA []byte) error { } m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 9: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field AsCoin", wireType) } @@ -1170,6 +1206,26 @@ func (m *MsgUpdateParam) Unmarshal(dAtA []byte) error { } m.AsType = &MsgUpdateParam_AsCoin{v} iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AsUint64", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.AsType = &MsgUpdateParam_AsUint64{v} default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/x/tokenomics/keeper/keeper_settle_pending_claims_test.go b/x/tokenomics/keeper/keeper_settle_pending_claims_test.go index 09a18c1b0..f40d66890 100644 --- a/x/tokenomics/keeper/keeper_settle_pending_claims_test.go +++ b/x/tokenomics/keeper/keeper_settle_pending_claims_test.go @@ -167,7 +167,14 @@ func (s *TestSuite) SetupTest() { // Calculate the number of claimed compute units. s.numClaimedComputeUnits = s.numRelays * service.ComputeUnitsPerRelay - s.relayMiningDifficulty = servicekeeper.NewDefaultRelayMiningDifficulty(sdkCtx, s.keepers.Logger(), testServiceId, servicekeeper.TargetNumRelays) + targetNumRelays := s.keepers.ServiceKeeper.GetParams(sdkCtx).TargetNumRelays + s.relayMiningDifficulty = servicekeeper.NewDefaultRelayMiningDifficulty( + sdkCtx, + s.keepers.Logger(), + testServiceId, + targetNumRelays, + targetNumRelays, + ) // Calculate the number of estimated compute units. s.numEstimatedComputeUnits = getEstimatedComputeUnits(s.numClaimedComputeUnits, s.relayMiningDifficulty) diff --git a/x/tokenomics/keeper/settle_pending_claims.go b/x/tokenomics/keeper/settle_pending_claims.go index 249971f00..fa1995de2 100644 --- a/x/tokenomics/keeper/settle_pending_claims.go +++ b/x/tokenomics/keeper/settle_pending_claims.go @@ -86,7 +86,14 @@ func (k Keeper) SettlePendingClaims(ctx cosmostypes.Context) ( serviceId := claim.GetSessionHeader().GetServiceId() relayMiningDifficulty, found := k.serviceKeeper.GetRelayMiningDifficulty(ctx, serviceId) if !found { - relayMiningDifficulty = servicekeeper.NewDefaultRelayMiningDifficulty(ctx, logger, serviceId, servicekeeper.TargetNumRelays) + targetNumRelays := k.serviceKeeper.GetParams(ctx).TargetNumRelays + relayMiningDifficulty = servicekeeper.NewDefaultRelayMiningDifficulty( + ctx, + logger, + serviceId, + targetNumRelays, + targetNumRelays, + ) } // numEstimatedComputeUnits is the probabilistic estimation of the off-chain // work done by the relay miner in this session. It is derived from the claimed diff --git a/x/tokenomics/keeper/token_logic_modules.go b/x/tokenomics/keeper/token_logic_modules.go index 05ab91f00..fbf95db66 100644 --- a/x/tokenomics/keeper/token_logic_modules.go +++ b/x/tokenomics/keeper/token_logic_modules.go @@ -150,7 +150,14 @@ func (k Keeper) ProcessTokenLogicModules( // Retrieving the relay mining difficulty for service. relayMiningDifficulty, found := k.serviceKeeper.GetRelayMiningDifficulty(ctx, service.Id) if !found { - relayMiningDifficulty = servicekeeper.NewDefaultRelayMiningDifficulty(ctx, logger, service.Id, servicekeeper.TargetNumRelays) + targetNumRelays := k.serviceKeeper.GetParams(ctx).TargetNumRelays + relayMiningDifficulty = servicekeeper.NewDefaultRelayMiningDifficulty( + ctx, + logger, + service.Id, + targetNumRelays, + targetNumRelays, + ) } sharedParams := k.sharedKeeper.GetParams(ctx) diff --git a/x/tokenomics/types/expected_keepers.go b/x/tokenomics/types/expected_keepers.go index cac324d16..c7c0de0c5 100644 --- a/x/tokenomics/types/expected_keepers.go +++ b/x/tokenomics/types/expected_keepers.go @@ -94,4 +94,6 @@ type ServiceKeeper interface { UpdateRelayMiningDifficulty(ctx context.Context, relaysPerServiceMap map[string]uint64) (map[string]servicetypes.RelayMiningDifficulty, error) // Only used for testing & simulation SetService(ctx context.Context, service sharedtypes.Service) + GetParams(ctx context.Context) servicetypes.Params + SetParams(ctx context.Context, params servicetypes.Params) error } diff --git a/x/tokenomics/types/message_update_param.go b/x/tokenomics/types/message_update_param.go index 735b390aa..719ec842a 100644 --- a/x/tokenomics/types/message_update_param.go +++ b/x/tokenomics/types/message_update_param.go @@ -66,10 +66,7 @@ func (msg *MsgUpdateParam) paramTypeIsString() error { return genericParamTypeIs[*MsgUpdateParam_AsString](msg) } -// TODO_TECHDEBT(@bryanchriswhite): -// 1. Move this to a shared package. -// 2. Refactor other module message_update_param.go files to use this. -// 3. Update "adding on-chain module params" docs. +// genericParamTypeIs checks if the parameter type is T, returning an error if not. func genericParamTypeIs[T any](msg *MsgUpdateParam) error { if _, ok := msg.AsType.(T); !ok { return ErrTokenomicsParamInvalid.Wrapf( From 09702d6688ad1ec34f668700690092e20018c0f6 Mon Sep 17 00:00:00 2001 From: Bryan White Date: Mon, 2 Dec 2024 10:14:48 +0100 Subject: [PATCH 12/21] [Code Health] fix: gateway module gRPC status error returns (#955) ## Summary Ensure all gateway message and query handlers return gRPC status errors. ## Issue - #954 ## Type of change Select one or more from the following: - [ ] New feature, functionality or library - [x] Consensus breaking; add the `consensus-breaking` label if so. See #791 for details - [ ] Bug fix - [x] Code health or cleanup - [ ] Documentation - [ ] Other (specify) ## Testing - [ ] **Documentation**: `make docusaurus_start`; only needed if you make doc changes - [x] **Unit Tests**: `make go_develop_and_test` - [ ] **LocalNet E2E Tests**: `make test_e2e` - [x] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR. ## Sanity Checklist - [x] I have tested my changes using the available tooling - [ ] I have commented my code - [x] I have performed a self-review of my own code; both comments & source code - [ ] I create and reference any new tickets, if applicable - [ ] I have left TODOs throughout the codebase, if applicable --- x/gateway/keeper/msg_server_stake_gateway.go | 2 +- x/gateway/keeper/msg_server_unstake_gateway.go | 18 ++++++++++++------ .../keeper/msg_server_unstake_gateway_test.go | 2 +- x/gateway/keeper/msg_update_params.go | 18 +++++++++++++++--- x/gateway/keeper/query_gateway.go | 5 ++++- 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/x/gateway/keeper/msg_server_stake_gateway.go b/x/gateway/keeper/msg_server_stake_gateway.go index 8a6ce25ab..3f3f1cc14 100644 --- a/x/gateway/keeper/msg_server_stake_gateway.go +++ b/x/gateway/keeper/msg_server_stake_gateway.go @@ -90,7 +90,7 @@ func (k msgServer) StakeGateway( if err != nil { // TODO_TECHDEBT(#384): determine whether to continue using cosmos logger for debug level. logger.Error(fmt.Sprintf("could not escrowed %v coins from %q to %q module account due to %v", coinsToEscrow, gatewayAddress, types.ModuleName, err)) - return nil, err + return nil, status.Error(codes.Internal, err.Error()) } // Update the Gateway in the store diff --git a/x/gateway/keeper/msg_server_unstake_gateway.go b/x/gateway/keeper/msg_server_unstake_gateway.go index 2e09bec19..d8c757713 100644 --- a/x/gateway/keeper/msg_server_unstake_gateway.go +++ b/x/gateway/keeper/msg_server_unstake_gateway.go @@ -30,7 +30,7 @@ func (k msgServer) UnstakeGateway( logger.Info(fmt.Sprintf("About to unstake gateway with msg: %v", msg)) if err := msg.ValidateBasic(); err != nil { - return nil, err + return nil, status.Error(codes.InvalidArgument, err.Error()) } // Check if the gateway already exists or not @@ -38,22 +38,28 @@ func (k msgServer) UnstakeGateway( gateway, isGatewayFound := k.GetGateway(ctx, msg.Address) if !isGatewayFound { logger.Info(fmt.Sprintf("Gateway not found. Cannot unstake address %s", msg.Address)) - return nil, types.ErrGatewayNotFound + return nil, status.Error( + codes.NotFound, + types.ErrGatewayNotFound.Wrapf( + "gateway with address %s", msg.Address, + ).Error(), + ) } logger.Info(fmt.Sprintf("Gateway found. Unstaking gateway for address %s", msg.Address)) // Retrieve the address of the gateway gatewayAddress, err := sdk.AccAddressFromBech32(msg.Address) if err != nil { - logger.Error(fmt.Sprintf("could not parse address %s", msg.Address)) - return nil, err + logger.Info(fmt.Sprintf("could not parse address %s", msg.Address)) + return nil, status.Error(codes.InvalidArgument, err.Error()) } // Send the coins from the gateway pool back to the gateway err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, gatewayAddress, []sdk.Coin{*gateway.Stake}) if err != nil { - logger.Error(fmt.Sprintf("could not send %v coins from %s module to %s account due to %v", gateway.Stake, gatewayAddress, types.ModuleName, err)) - return nil, err + err = fmt.Errorf("could not send %v coins from %s module to %s account due to %v", gateway.Stake, gatewayAddress, types.ModuleName, err) + logger.Error(err.Error()) + return nil, status.Error(codes.Internal, err.Error()) } // Update the Gateway in the store diff --git a/x/gateway/keeper/msg_server_unstake_gateway_test.go b/x/gateway/keeper/msg_server_unstake_gateway_test.go index 4c977ef3c..64ad5cadf 100644 --- a/x/gateway/keeper/msg_server_unstake_gateway_test.go +++ b/x/gateway/keeper/msg_server_unstake_gateway_test.go @@ -66,7 +66,7 @@ func TestMsgServer_UnstakeGateway_FailIfNotStaked(t *testing.T) { unstakeMsg := &types.MsgUnstakeGateway{Address: addr} _, err := srv.UnstakeGateway(ctx, unstakeMsg) require.Error(t, err) - require.ErrorIs(t, err, types.ErrGatewayNotFound) + require.ErrorContains(t, err, types.ErrGatewayNotFound.Error()) _, isGatewayFound = k.GetGateway(ctx, addr) require.False(t, isGatewayFound) diff --git a/x/gateway/keeper/msg_update_params.go b/x/gateway/keeper/msg_update_params.go index d8039b896..9b13b4d17 100644 --- a/x/gateway/keeper/msg_update_params.go +++ b/x/gateway/keeper/msg_update_params.go @@ -2,8 +2,11 @@ package keeper import ( "context" + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "github.com/pokt-network/poktroll/x/gateway/types" ) @@ -12,17 +15,26 @@ func (k msgServer) UpdateParams( goCtx context.Context, req *types.MsgUpdateParams, ) (*types.MsgUpdateParamsResponse, error) { + logger := k.Logger().With("method", "UpdateParams") + if err := req.ValidateBasic(); err != nil { - return nil, err + return nil, status.Error(codes.InvalidArgument, err.Error()) } if k.GetAuthority() != req.Authority { - return nil, types.ErrGatewayInvalidSigner.Wrapf("invalid authority; expected %s, got %s", k.GetAuthority(), req.Authority) + return nil, status.Error( + codes.PermissionDenied, + types.ErrGatewayInvalidSigner.Wrapf( + "invalid authority; expected %s, got %s", k.GetAuthority(), req.Authority, + ).Error(), + ) } ctx := sdk.UnwrapSDKContext(goCtx) // NOTE(#322): Omitted parameters will be set to their zero value. if err := k.SetParams(ctx, req.Params); err != nil { - return nil, err + err = fmt.Errorf("unable to set params: %w", err) + logger.Error(err.Error()) + return nil, status.Error(codes.Internal, err.Error()) } return &types.MsgUpdateParamsResponse{}, nil diff --git a/x/gateway/keeper/query_gateway.go b/x/gateway/keeper/query_gateway.go index 0b6d2ab2a..8420bde17 100644 --- a/x/gateway/keeper/query_gateway.go +++ b/x/gateway/keeper/query_gateway.go @@ -14,6 +14,8 @@ import ( ) func (k Keeper) AllGateways(ctx context.Context, req *types.QueryAllGatewaysRequest) (*types.QueryAllGatewaysResponse, error) { + logger := k.Logger().With("method", "AllGateways") + if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -26,7 +28,8 @@ func (k Keeper) AllGateways(ctx context.Context, req *types.QueryAllGatewaysRequ pageRes, err := query.Paginate(gatewayStore, req.Pagination, func(key []byte, value []byte) error { var gateway types.Gateway if err := k.cdc.Unmarshal(value, &gateway); err != nil { - return err + logger.Error(fmt.Sprintf("unmarshaling gateway with key (hex): %x: %+v", key, err)) + return status.Error(codes.Internal, err.Error()) } gateways = append(gateways, gateway) From be817c2eabd5ca1d44629c45e474d71d935e9db9 Mon Sep 17 00:00:00 2001 From: Bryan White Date: Mon, 2 Dec 2024 10:15:14 +0100 Subject: [PATCH 13/21] [Code Health] fix: proof module gRPC status error returns (#956) ## Summary Ensure all proof module message and query handlers return gRPC status errors. ## Issue - #954 ## Type of change Select one or more from the following: - [ ] New feature, functionality or library - [x] Consensus breaking; add the `consensus-breaking` label if so. See #791 for details - [ ] Bug fix - [x] Code health or cleanup - [ ] Documentation - [ ] Other (specify) ## Testing - [ ] **Documentation**: `make docusaurus_start`; only needed if you make doc changes - [x] **Unit Tests**: `make go_develop_and_test` - [ ] **LocalNet E2E Tests**: `make test_e2e` - [x] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR. ## Sanity Checklist - [x] I have tested my changes using the available tooling - [ ] I have commented my code - [x] I have performed a self-review of my own code; both comments & source code - [ ] I create and reference any new tickets, if applicable - [ ] I have left TODOs throughout the codebase, if applicable --- x/proof/keeper/msg_server_create_claim.go | 2 +- x/proof/keeper/msg_update_params.go | 19 ++++++++++++++++--- x/proof/keeper/query_claim.go | 7 ++++++- x/proof/keeper/query_proof.go | 6 +++++- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/x/proof/keeper/msg_server_create_claim.go b/x/proof/keeper/msg_server_create_claim.go index d9c4a32d3..f9e06055c 100644 --- a/x/proof/keeper/msg_server_create_claim.go +++ b/x/proof/keeper/msg_server_create_claim.go @@ -33,7 +33,7 @@ func (k msgServer) CreateClaim( // Basic validation of the CreateClaim message. if err = msg.ValidateBasic(); err != nil { - return nil, err + return nil, status.Error(codes.InvalidArgument, err.Error()) } logger.Info("validated the createClaim message") diff --git a/x/proof/keeper/msg_update_params.go b/x/proof/keeper/msg_update_params.go index 392f9333f..8b95781b2 100644 --- a/x/proof/keeper/msg_update_params.go +++ b/x/proof/keeper/msg_update_params.go @@ -2,20 +2,33 @@ package keeper import ( "context" + "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "github.com/pokt-network/poktroll/x/proof/types" ) func (k msgServer) UpdateParams(ctx context.Context, req *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + logger := k.Logger().With("method", "UpdateParams") + if err := req.ValidateBasic(); err != nil { - return nil, err + return nil, status.Error(codes.InvalidArgument, err.Error()) } if k.GetAuthority() != req.Authority { - return nil, types.ErrProofInvalidSigner.Wrapf("invalid authority; expected %s, got %s", k.GetAuthority(), req.Authority) + return nil, status.Error( + codes.PermissionDenied, + types.ErrProofInvalidSigner.Wrapf( + "invalid authority; expected %s, got %s", k.GetAuthority(), req.Authority, + ).Error(), + ) } if err := k.SetParams(ctx, req.Params); err != nil { - return nil, err + err = fmt.Errorf("unable to set params: %w", err) + logger.Error(err.Error()) + return nil, status.Error(codes.Internal, err.Error()) } return &types.MsgUpdateParamsResponse{}, nil diff --git a/x/proof/keeper/query_claim.go b/x/proof/keeper/query_claim.go index 520aa4b0c..399cf3f27 100644 --- a/x/proof/keeper/query_claim.go +++ b/x/proof/keeper/query_claim.go @@ -3,6 +3,7 @@ package keeper import ( "context" "encoding/binary" + "fmt" "cosmossdk.io/store/prefix" "github.com/cosmos/cosmos-sdk/runtime" @@ -14,6 +15,8 @@ import ( ) func (k Keeper) AllClaims(ctx context.Context, req *types.QueryAllClaimsRequest) (*types.QueryAllClaimsResponse, error) { + logger := k.Logger().With("method", "AllClaims") + if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -65,7 +68,9 @@ func (k Keeper) AllClaims(ctx context.Context, req *types.QueryAllClaimsRequest) // The value is the encoded claim. var claim types.Claim if err := k.cdc.Unmarshal(value, &claim); err != nil { - return err + err = fmt.Errorf("unable to unmarshal claim with key (hex): %x: %+v", key, err) + logger.Error(err.Error()) + return status.Error(codes.Internal, err.Error()) } claims = append(claims, claim) } diff --git a/x/proof/keeper/query_proof.go b/x/proof/keeper/query_proof.go index 12eae432c..f2a84ba42 100644 --- a/x/proof/keeper/query_proof.go +++ b/x/proof/keeper/query_proof.go @@ -14,6 +14,8 @@ import ( ) func (k Keeper) AllProofs(ctx context.Context, req *types.QueryAllProofsRequest) (*types.QueryAllProofsResponse, error) { + logger := k.Logger().With("method", "AllProofs") + if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -63,7 +65,9 @@ func (k Keeper) AllProofs(ctx context.Context, req *types.QueryAllProofsRequest) // The value is the encoded proof. var proof types.Proof if err := k.cdc.Unmarshal(value, &proof); err != nil { - return err + err = fmt.Errorf("unable to unmarshal proof with key (hex): %x: %+v", key, err) + logger.Error(err.Error()) + return status.Error(codes.Internal, err.Error()) } proofs = append(proofs, proof) From 1c490ce2577991b21188b6a8625d8421d7c8ba16 Mon Sep 17 00:00:00 2001 From: Bryan White Date: Mon, 2 Dec 2024 10:15:31 +0100 Subject: [PATCH 14/21] [Code Health] fix: service module gRPC status error returns (#959) ## Summary Ensure all service module message and query handlers return gRPC status errors. ## Issue - #860 ## Type of change Select one or more from the following: - [ ] New feature, functionality or library - [x] Consensus breaking; add the `consensus-breaking` label if so. See #791 for details - [ ] Bug fix - [x] Code health or cleanup - [ ] Documentation - [ ] Other (specify) ## Testing - [ ] **Documentation**: `make docusaurus_start`; only needed if you make doc changes - [x] **Unit Tests**: `make go_develop_and_test` - [ ] **LocalNet E2E Tests**: `make test_e2e` - [x] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR. ## Sanity Checklist - [x] I have tested my changes using the available tooling - [ ] I have commented my code - [x] I have performed a self-review of my own code; both comments & source code - [ ] I create and reference any new tickets, if applicable - [ ] I have left TODOs throughout the codebase, if applicable --- x/service/keeper/msg_server_add_service.go | 58 ++++++++++++------- x/service/keeper/msg_update_params.go | 19 +++++- .../keeper/query_relay_mining_difficulty.go | 7 ++- x/service/keeper/query_service.go | 7 ++- 4 files changed, 65 insertions(+), 26 deletions(-) diff --git a/x/service/keeper/msg_server_add_service.go b/x/service/keeper/msg_server_add_service.go index 52fe8365e..2d3dd69c0 100644 --- a/x/service/keeper/msg_server_add_service.go +++ b/x/service/keeper/msg_server_add_service.go @@ -5,6 +5,8 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "github.com/pokt-network/poktroll/telemetry" "github.com/pokt-network/poktroll/x/service/types" @@ -33,39 +35,48 @@ func (k msgServer) AddService( // Validate the message. if err := msg.ValidateBasic(); err != nil { logger.Error(fmt.Sprintf("Adding service failed basic validation: %v", err)) - return nil, err + return nil, status.Error(codes.InvalidArgument, err.Error()) } // Check if the service already exists or not. foundService, found := k.GetService(ctx, msg.Service.Id) if found { if foundService.OwnerAddress != msg.Service.OwnerAddress { - logger.Error(fmt.Sprintf("Owner address of existing service (%q) does not match the owner address %q", foundService.OwnerAddress, msg.OwnerAddress)) - return nil, types.ErrServiceInvalidOwnerAddress.Wrapf( - "existing owner address %q does not match the new owner address %q", - foundService.OwnerAddress, msg.Service.OwnerAddress, + return nil, status.Error( + codes.InvalidArgument, + types.ErrServiceInvalidOwnerAddress.Wrapf( + "existing owner address %q does not match the new owner address %q", + foundService.OwnerAddress, msg.Service.OwnerAddress, + ).Error(), ) } - return nil, types.ErrServiceAlreadyExists.Wrapf( - "TODO_MAINNET(@red-0ne): This is an ephemeral state of the code. Once we s/AddService/UpdateService/g, add the business logic here for updates here.", + return nil, status.Error( + codes.FailedPrecondition, + types.ErrServiceAlreadyExists.Wrapf( + "TODO_MAINNET(@red-0ne): This is an ephemeral state of the code. Once we s/AddService/UpdateService/g, add the business logic here for updates here.", + ).Error(), ) } // Retrieve the address of the actor adding the service; the owner of the service. serviceOwnerAddr, err := sdk.AccAddressFromBech32(msg.OwnerAddress) if err != nil { - logger.Error(fmt.Sprintf("could not parse address %s", msg.OwnerAddress)) - return nil, types.ErrServiceInvalidAddress.Wrapf( - "%s is not in Bech32 format", msg.OwnerAddress, + return nil, status.Error( + codes.InvalidArgument, + types.ErrServiceInvalidAddress.Wrapf( + "%s is not in Bech32 format", msg.OwnerAddress, + ).Error(), ) } // Check the actor has sufficient funds to pay for the add service fee. accCoins := k.bankKeeper.SpendableCoins(ctx, serviceOwnerAddr) if accCoins.Len() == 0 { - logger.Error(fmt.Sprintf("%s doesn't have any funds to add service: %v", serviceOwnerAddr, err)) - return nil, types.ErrServiceNotEnoughFunds.Wrapf( - "account has no spendable coins", + return nil, status.Error( + codes.FailedPrecondition, + types.ErrServiceNotEnoughFunds.Wrapf( + "account has no spendable coins", + ).Error(), ) } @@ -73,10 +84,12 @@ func (k msgServer) AddService( accBalance := accCoins.AmountOf("upokt") addServiceFee := k.GetParams(ctx).AddServiceFee if accBalance.LTE(addServiceFee.Amount) { - logger.Error(fmt.Sprintf("%s doesn't have enough funds to add service: %v", serviceOwnerAddr, err)) - return nil, types.ErrServiceNotEnoughFunds.Wrapf( - "account has %s, but the service fee is %s", - accBalance, k.GetParams(ctx).AddServiceFee, + return nil, status.Error( + codes.FailedPrecondition, + types.ErrServiceNotEnoughFunds.Wrapf( + "account has %s, but the service fee is %s", + accBalance, k.GetParams(ctx).AddServiceFee, + ).Error(), ) } @@ -84,10 +97,13 @@ func (k msgServer) AddService( serviceFee := sdk.NewCoins(*addServiceFee) err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, serviceOwnerAddr, types.ModuleName, serviceFee) if err != nil { - logger.Error(fmt.Sprintf("Failed to deduct service fee from actor's balance: %v", err)) - return nil, types.ErrServiceFailedToDeductFee.Wrapf( - "account has %s, failed to deduct %s", - accBalance, k.GetParams(ctx).AddServiceFee, + logger.Error(fmt.Sprintf("Failed to deduct service fee from actor's balance: %+v", err)) + return nil, status.Error( + codes.Internal, + types.ErrServiceFailedToDeductFee.Wrapf( + "account has %s, failed to deduct %s", + accBalance, k.GetParams(ctx).AddServiceFee, + ).Error(), ) } diff --git a/x/service/keeper/msg_update_params.go b/x/service/keeper/msg_update_params.go index 964d1db26..d8317c864 100644 --- a/x/service/keeper/msg_update_params.go +++ b/x/service/keeper/msg_update_params.go @@ -2,20 +2,33 @@ package keeper import ( "context" + "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "github.com/pokt-network/poktroll/x/service/types" ) func (k msgServer) UpdateParams(ctx context.Context, req *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + logger := k.Logger().With("method", "UpdateParams") + if err := req.ValidateBasic(); err != nil { - return nil, err + return nil, status.Error(codes.InvalidArgument, err.Error()) } if k.GetAuthority() != req.Authority { - return nil, types.ErrServiceInvalidSigner.Wrapf("invalid authority; expected %s, got %s", k.GetAuthority(), req.Authority) + return nil, status.Error( + codes.PermissionDenied, + types.ErrServiceInvalidSigner.Wrapf( + "invalid authority; expected %s, got %s", k.GetAuthority(), req.Authority, + ).Error(), + ) } if err := k.SetParams(ctx, req.Params); err != nil { - return nil, err + err = fmt.Errorf("unable to set params: %w", err) + logger.Error(err.Error()) + return nil, status.Error(codes.Internal, err.Error()) } return &types.MsgUpdateParamsResponse{}, nil diff --git a/x/service/keeper/query_relay_mining_difficulty.go b/x/service/keeper/query_relay_mining_difficulty.go index 17cef487a..82403fd0a 100644 --- a/x/service/keeper/query_relay_mining_difficulty.go +++ b/x/service/keeper/query_relay_mining_difficulty.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "fmt" "cosmossdk.io/store/prefix" "github.com/cosmos/cosmos-sdk/runtime" @@ -13,6 +14,8 @@ import ( ) func (k Keeper) RelayMiningDifficultyAll(ctx context.Context, req *types.QueryAllRelayMiningDifficultyRequest) (*types.QueryAllRelayMiningDifficultyResponse, error) { + logger := k.Logger().With("method", "RelayMiningDifficultyAll") + if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -25,7 +28,9 @@ func (k Keeper) RelayMiningDifficultyAll(ctx context.Context, req *types.QueryAl pageRes, err := query.Paginate(relayMiningDifficultyStore, req.Pagination, func(key []byte, value []byte) error { var relayMiningDifficulty types.RelayMiningDifficulty if err := k.cdc.Unmarshal(value, &relayMiningDifficulty); err != nil { - return err + err = fmt.Errorf("unable to unmarshal relayMiningDifficulty with key (hex): %x: %w", key, err) + logger.Error(err.Error()) + return status.Error(codes.Internal, err.Error()) } relayMiningDifficulties = append(relayMiningDifficulties, relayMiningDifficulty) diff --git a/x/service/keeper/query_service.go b/x/service/keeper/query_service.go index 0792fa688..73f420edc 100644 --- a/x/service/keeper/query_service.go +++ b/x/service/keeper/query_service.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "fmt" "cosmossdk.io/store/prefix" "github.com/cosmos/cosmos-sdk/runtime" @@ -15,6 +16,8 @@ import ( // AllServices queries all services. func (k Keeper) AllServices(ctx context.Context, req *types.QueryAllServicesRequest) (*types.QueryAllServicesResponse, error) { + logger := k.Logger().With("method", "AllServices") + if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -27,7 +30,9 @@ func (k Keeper) AllServices(ctx context.Context, req *types.QueryAllServicesRequ pageRes, err := query.Paginate(serviceStore, req.Pagination, func(key []byte, value []byte) error { var service sharedtypes.Service if err := k.cdc.Unmarshal(value, &service); err != nil { - return err + err = fmt.Errorf("unable to unmarshal service with key (hex): %x: %w", key, err) + logger.Error(err.Error()) + return status.Error(codes.Internal, err.Error()) } services = append(services, service) From 41a373bdce36982f90452eb833e8072aeb8124ff Mon Sep 17 00:00:00 2001 From: Bryan White Date: Mon, 2 Dec 2024 10:15:47 +0100 Subject: [PATCH 15/21] [Code Health] fix: session module gRPC status return errors (#960) ## Summary Ensure all session message and query handlers return gRPC status errors. ## Issue - #860 ## Type of change Select one or more from the following: - [ ] New feature, functionality or library - [x] Consensus breaking; add the `consensus-breaking` label if so. See #791 for details - [ ] Bug fix - [x] Code health or cleanup - [ ] Documentation - [ ] Other (specify) ## Testing - [ ] **Documentation**: `make docusaurus_start`; only needed if you make doc changes - [x] **Unit Tests**: `make go_develop_and_test` - [ ] **LocalNet E2E Tests**: `make test_e2e` - [x] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR. ## Sanity Checklist - [x] I have tested my changes using the available tooling - [ ] I have commented my code - [x] I have performed a self-review of my own code; both comments & source code - [ ] I create and reference any new tickets, if applicable - [ ] I have left TODOs throughout the codebase, if applicable --- x/proof/keeper/session.go | 4 ++++ x/session/keeper/msg_update_params.go | 19 ++++++++++++++++--- x/session/keeper/query_get_session.go | 7 +++++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/x/proof/keeper/session.go b/x/proof/keeper/session.go index 9d33d76c6..68a72cf10 100644 --- a/x/proof/keeper/session.go +++ b/x/proof/keeper/session.go @@ -2,8 +2,10 @@ package keeper import ( "context" + "fmt" cosmostypes "github.com/cosmos/cosmos-sdk/types" + "google.golang.org/grpc/status" "github.com/pokt-network/poktroll/x/proof/types" sessiontypes "github.com/pokt-network/poktroll/x/session/types" @@ -30,6 +32,8 @@ func (k Keeper) queryAndValidateSessionHeader( // session header is to be validated. sessionRes, err := k.sessionKeeper.GetSession(ctx, sessionReq) if err != nil { + // NB: Strip internal error status from error. An appropriate status will be associated by the caller. + err = fmt.Errorf("%s", status.Convert(err).Message()) return nil, err } onChainSession := sessionRes.GetSession() diff --git a/x/session/keeper/msg_update_params.go b/x/session/keeper/msg_update_params.go index 84a5debfa..57564b921 100644 --- a/x/session/keeper/msg_update_params.go +++ b/x/session/keeper/msg_update_params.go @@ -2,21 +2,34 @@ package keeper import ( "context" + "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "github.com/pokt-network/poktroll/x/session/types" ) func (k msgServer) UpdateParams(ctx context.Context, req *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + logger := k.Logger().With("method", "UpdateParams") + if err := req.ValidateBasic(); err != nil { - return nil, err + return nil, status.Error(codes.InvalidArgument, err.Error()) } if k.GetAuthority() != req.Authority { - return nil, types.ErrSessionInvalidSigner.Wrapf("invalid authority; expected %s, got %s", k.GetAuthority(), req.Authority) + return nil, status.Error( + codes.PermissionDenied, + types.ErrSessionInvalidSigner.Wrapf( + "invalid authority; expected %s, got %s", k.GetAuthority(), req.Authority, + ).Error(), + ) } if err := k.SetParams(ctx, req.Params); err != nil { - return nil, err + err = fmt.Errorf("unable to set params: %w", err) + logger.Error(err.Error()) + return nil, status.Error(codes.Internal, err.Error()) } return &types.MsgUpdateParamsResponse{}, nil diff --git a/x/session/keeper/query_get_session.go b/x/session/keeper/query_get_session.go index bc25fff0e..412d77c45 100644 --- a/x/session/keeper/query_get_session.go +++ b/x/session/keeper/query_get_session.go @@ -14,6 +14,8 @@ import ( // GetSession should be deterministic and always return the same session for // the same block height. func (k Keeper) GetSession(ctx context.Context, req *types.QueryGetSessionRequest) (*types.QueryGetSessionResponse, error) { + logger := k.Logger().With("method", "GetSession") + if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -36,12 +38,13 @@ func (k Keeper) GetSession(ctx context.Context, req *types.QueryGetSessionReques blockHeight = req.BlockHeight } - k.Logger().Debug(fmt.Sprintf("Getting session for height: %d", blockHeight)) + logger.Debug(fmt.Sprintf("Getting session for height: %d", blockHeight)) sessionHydrator := NewSessionHydrator(req.ApplicationAddress, req.ServiceId, blockHeight) session, err := k.HydrateSession(ctx, sessionHydrator) if err != nil { - return nil, err + logger.Error(err.Error()) + return nil, status.Error(codes.Internal, err.Error()) } res := &types.QueryGetSessionResponse{ From 9678997e62c6a8cd73ab4f0c155ad0592f7e6f36 Mon Sep 17 00:00:00 2001 From: Bryan White Date: Mon, 2 Dec 2024 10:16:05 +0100 Subject: [PATCH 16/21] [Code Health] fix: shared module gRPC return errors (#961) ## Summary Ensure all shared message and query handlers return gRPC status errors. ## Issue - #860 ## Type of change Select one or more from the following: - [ ] New feature, functionality or library - [x] Consensus breaking; add the `consensus-breaking` label if so. See #791 for details - [ ] Bug fix - [x] Code health or cleanup - [ ] Documentation - [ ] Other (specify) ## Testing - [ ] **Documentation**: `make docusaurus_start`; only needed if you make doc changes - [x] **Unit Tests**: `make go_develop_and_test` - [ ] **LocalNet E2E Tests**: `make test_e2e` - [x] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR. ## Sanity Checklist - [x] I have tested my changes using the available tooling - [ ] I have commented my code - [x] I have performed a self-review of my own code; both comments & source code - [ ] I create and reference any new tickets, if applicable - [ ] I have left TODOs throughout the codebase, if applicable --- x/shared/keeper/msg_update_params.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/x/shared/keeper/msg_update_params.go b/x/shared/keeper/msg_update_params.go index 9df191361..c313387f6 100644 --- a/x/shared/keeper/msg_update_params.go +++ b/x/shared/keeper/msg_update_params.go @@ -3,23 +3,34 @@ package keeper import ( "context" - sdkerrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "github.com/pokt-network/poktroll/x/shared/types" ) func (k msgServer) UpdateParams(goCtx context.Context, req *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + logger := k.Logger().With("method", "UpdateParams") + if err := req.ValidateBasic(); err != nil { - return nil, err + return nil, status.Error(codes.InvalidArgument, err.Error()) } if k.GetAuthority() != req.Authority { - return nil, sdkerrors.Wrapf(types.ErrSharedInvalidSigner, "invalid authority; expected %s, got %s", k.GetAuthority(), req.Authority) + return nil, status.Error( + codes.PermissionDenied, + types.ErrSharedInvalidSigner.Wrapf( + "invalid authority; expected %s, got %s", + k.GetAuthority(), req.Authority, + ).Error(), + ) } ctx := sdk.UnwrapSDKContext(goCtx) if err := k.SetParams(ctx, req.Params); err != nil { - return nil, err + err = types.ErrSharedParamInvalid.Wrapf("unable to set params: %v", err) + logger.Error(err.Error()) + return nil, status.Error(codes.Internal, err.Error()) } return &types.MsgUpdateParamsResponse{}, nil From f35e87943124ddc2965fc1ffa4c2bba4ce4139ee Mon Sep 17 00:00:00 2001 From: Bryan White Date: Mon, 2 Dec 2024 10:16:18 +0100 Subject: [PATCH 17/21] [Code Health] fix: application module gRPC status error returns (#954) ## Summary Ensure all application message and query handlers return gRPC status errors. ## Issue - #860 ## Type of change Select one or more from the following: - [ ] New feature, functionality or library - [x] Consensus breaking; add the `consensus-breaking` label if so. See #791 for details - [ ] Bug fix - [x] Code health or cleanup - [ ] Documentation - [ ] Other (specify) ## Testing - [ ] **Documentation**: `make docusaurus_start`; only needed if you make doc changes - [x] **Unit Tests**: `make go_develop_and_test` - [ ] **LocalNet E2E Tests**: `make test_e2e` - [x] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR. ## Sanity Checklist - [x] I have tested my changes using the available tooling - [ ] I have commented my code - [x] I have performed a self-review of my own code; both comments & source code - [ ] I create and reference any new tickets, if applicable - [ ] I have left TODOs throughout the codebase, if applicable --- .../keeper/msg_server_delegate_to_gateway.go | 55 ++++++++++++++----- .../msg_server_delegate_to_gateway_test.go | 6 +- .../msg_server_undelegate_from_gateway.go | 40 +++++++++----- ...msg_server_undelegate_from_gateway_test.go | 4 +- .../keeper/msg_server_unstake_application.go | 29 +++++++--- .../msg_server_unstake_application_test.go | 4 +- .../keeper/msg_server_update_param.go | 18 ++++-- x/application/keeper/msg_update_params.go | 20 ++++++- x/application/keeper/query_application.go | 6 +- 9 files changed, 132 insertions(+), 50 deletions(-) diff --git a/x/application/keeper/msg_server_delegate_to_gateway.go b/x/application/keeper/msg_server_delegate_to_gateway.go index f109d0ce3..395346d88 100644 --- a/x/application/keeper/msg_server_delegate_to_gateway.go +++ b/x/application/keeper/msg_server_delegate_to_gateway.go @@ -5,6 +5,8 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "github.com/pokt-network/poktroll/telemetry" apptypes "github.com/pokt-network/poktroll/x/application/types" @@ -20,44 +22,66 @@ func (k msgServer) DelegateToGateway(ctx context.Context, msg *apptypes.MsgDeleg ) logger := k.Logger().With("method", "DelegateToGateway") - logger.Info(fmt.Sprintf("About to delegate application to gateway with msg: %v", msg)) + logger.Info(fmt.Sprintf("About to delegate application to gateway with msg: %+v", msg)) if err := msg.ValidateBasic(); err != nil { - logger.Error(fmt.Sprintf("Delegation Message failed basic validation: %v", err)) - return nil, err + logger.Info(fmt.Sprintf("Delegation Message failed basic validation: %s", err)) + return nil, status.Error(codes.InvalidArgument, err.Error()) } // Retrieve the application from the store - app, found := k.GetApplication(ctx, msg.AppAddress) + app, found := k.GetApplication(ctx, msg.GetAppAddress()) if !found { logger.Info(fmt.Sprintf("Application not found with address [%s]", msg.AppAddress)) - return nil, apptypes.ErrAppNotFound.Wrapf("application not found with address: %s", msg.AppAddress) + return nil, status.Error( + codes.NotFound, + apptypes.ErrAppNotFound.Wrapf( + "application with address: %s", msg.GetAppAddress(), + ).Error(), + ) } logger.Info(fmt.Sprintf("Application found with address [%s]", msg.AppAddress)) // Check if the gateway is staked - if _, found := k.gatewayKeeper.GetGateway(ctx, msg.GatewayAddress); !found { - logger.Info(fmt.Sprintf("Gateway not found with address [%s]", msg.GatewayAddress)) - return nil, apptypes.ErrAppGatewayNotFound.Wrapf("gateway not found with address: %s", msg.GatewayAddress) + if _, found := k.gatewayKeeper.GetGateway(ctx, msg.GetGatewayAddress()); !found { + logger.Info(fmt.Sprintf("Gateway not found with address [%s]", msg.GetGatewayAddress())) + return nil, status.Error( + codes.NotFound, + apptypes.ErrAppGatewayNotFound.Wrapf( + "gateway with address: %q", msg.GetGatewayAddress(), + ).Error(), + ) } // Ensure the application is not already delegated to the maximum number of gateways maxDelegatedParam := k.GetParams(ctx).MaxDelegatedGateways if uint64(len(app.DelegateeGatewayAddresses)) >= maxDelegatedParam { logger.Info(fmt.Sprintf("Application already delegated to maximum number of gateways: %d", maxDelegatedParam)) - return nil, apptypes.ErrAppMaxDelegatedGateways.Wrapf("application already delegated to %d gateways", maxDelegatedParam) + return nil, status.Error( + codes.FailedPrecondition, + apptypes.ErrAppMaxDelegatedGateways.Wrapf( + "application with address %q already delegated to %d (max) gateways", + msg.GetAppAddress(), maxDelegatedParam, + ).Error(), + ) } // Check if the application is already delegated to the gateway for _, gatewayAddr := range app.DelegateeGatewayAddresses { - if gatewayAddr == msg.GatewayAddress { + if gatewayAddr == msg.GetGatewayAddress() { logger.Info(fmt.Sprintf("Application already delegated to gateway with address [%s]", msg.GatewayAddress)) - return nil, apptypes.ErrAppAlreadyDelegated.Wrapf("application already delegated to gateway with address: %s", msg.GatewayAddress) + return nil, status.Error( + codes.AlreadyExists, + apptypes.ErrAppAlreadyDelegated.Wrapf( + "application with address %q already delegated to gateway with address: %q", + msg.GetAppAddress(), msg.GetGatewayAddress(), + ).Error(), + ) } } // Update the application with the new delegatee public key - app.DelegateeGatewayAddresses = append(app.DelegateeGatewayAddresses, msg.GatewayAddress) + app.DelegateeGatewayAddresses = append(app.DelegateeGatewayAddresses, msg.GetGatewayAddress()) logger.Info("Successfully added delegatee public key to application") // Update the application store with the new delegation @@ -72,12 +96,13 @@ func (k msgServer) DelegateToGateway(ctx context.Context, msg *apptypes.MsgDeleg Application: &app, SessionEndHeight: sessionEndHeight, } - logger.Info(fmt.Sprintf("Emitting application redelegation event %v", event)) + logger.Info(fmt.Sprintf("Emitting application redelegation event %+v", event)) sdkCtx := sdk.UnwrapSDKContext(ctx) if err := sdkCtx.EventManager().EmitTypedEvent(event); err != nil { - logger.Error(fmt.Sprintf("Failed to emit application redelegation event: %v", err)) - return nil, err + err = fmt.Errorf("failed to emit application redelegation event: %w", err) + logger.Error(err.Error()) + return nil, status.Error(codes.Internal, err.Error()) } isSuccessful = true diff --git a/x/application/keeper/msg_server_delegate_to_gateway_test.go b/x/application/keeper/msg_server_delegate_to_gateway_test.go index 18525fa4f..873817d8b 100644 --- a/x/application/keeper/msg_server_delegate_to_gateway_test.go +++ b/x/application/keeper/msg_server_delegate_to_gateway_test.go @@ -182,7 +182,7 @@ func TestMsgServer_DelegateToGateway_FailDuplicate(t *testing.T) { // Attempt to delegate the application to the gateway again _, err = srv.DelegateToGateway(ctx, delegateMsg2) - require.ErrorIs(t, err, apptypes.ErrAppAlreadyDelegated) + require.ErrorContains(t, err, apptypes.ErrAppAlreadyDelegated.Error()) events = sdkCtx.EventManager().Events() require.Equal(t, 0, len(events)) @@ -221,7 +221,7 @@ func TestMsgServer_DelegateToGateway_FailGatewayNotStaked(t *testing.T) { // Attempt to delegate the application to the unstaked gateway _, err = srv.DelegateToGateway(ctx, delegateMsg) - require.ErrorIs(t, err, apptypes.ErrAppGatewayNotFound) + require.ErrorContains(t, err, apptypes.ErrAppGatewayNotFound.Error()) foundApp, isAppFound := k.GetApplication(ctx, appAddr) require.True(t, isAppFound) require.Equal(t, 0, len(foundApp.DelegateeGatewayAddresses)) @@ -312,7 +312,7 @@ func TestMsgServer_DelegateToGateway_FailMaxReached(t *testing.T) { // Attempt to delegate the application when the max is already reached _, err = srv.DelegateToGateway(ctx, delegateMsg) - require.ErrorIs(t, err, apptypes.ErrAppMaxDelegatedGateways) + require.ErrorContains(t, err, apptypes.ErrAppMaxDelegatedGateways.Error()) events = sdkCtx.EventManager().Events() filteredEvents = testevents.FilterEvents[*apptypes.EventRedelegation](t, events) diff --git a/x/application/keeper/msg_server_undelegate_from_gateway.go b/x/application/keeper/msg_server_undelegate_from_gateway.go index 8af02752d..9fd7b1258 100644 --- a/x/application/keeper/msg_server_undelegate_from_gateway.go +++ b/x/application/keeper/msg_server_undelegate_from_gateway.go @@ -6,6 +6,8 @@ import ( "slices" sdk "github.com/cosmos/cosmos-sdk/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "github.com/pokt-network/poktroll/telemetry" apptypes "github.com/pokt-network/poktroll/x/application/types" @@ -20,32 +22,43 @@ func (k msgServer) UndelegateFromGateway(ctx context.Context, msg *apptypes.MsgU ) logger := k.Logger().With("method", "UndelegateFromGateway") - logger.Info(fmt.Sprintf("About to undelegate application from gateway with msg: %v", msg)) + logger.Info(fmt.Sprintf("About to undelegate application from gateway with msg: %+v", msg)) // Basic validation of the message if err := msg.ValidateBasic(); err != nil { - logger.Error(fmt.Sprintf("Undelegation Message failed basic validation: %v", err)) - return nil, err + logger.Info(fmt.Sprintf("Undelegation Message failed basic validation: %s", err)) + return nil, status.Error(codes.InvalidArgument, err.Error()) } // Retrieve the application from the store - foundApp, isAppFound := k.GetApplication(ctx, msg.AppAddress) + foundApp, isAppFound := k.GetApplication(ctx, msg.GetAppAddress()) if !isAppFound { - logger.Info(fmt.Sprintf("Application not found with address [%s]", msg.AppAddress)) - return nil, apptypes.ErrAppNotFound.Wrapf("application not found with address: %s", msg.AppAddress) + logger.Info(fmt.Sprintf("Application not found with address [%s]", msg.GetAppAddress())) + return nil, status.Error( + codes.NotFound, + apptypes.ErrAppNotFound.Wrapf( + "application with address: %q", msg.GetAppAddress(), + ).Error(), + ) } - logger.Info(fmt.Sprintf("Application found with address [%s]", msg.AppAddress)) + logger.Info(fmt.Sprintf("Application found with address [%s]", msg.GetAppAddress())) // Check if the application is already delegated to the gateway foundIdx := -1 for i, gatewayAddr := range foundApp.DelegateeGatewayAddresses { - if gatewayAddr == msg.GatewayAddress { + if gatewayAddr == msg.GetGatewayAddress() { foundIdx = i } } if foundIdx == -1 { - logger.Info(fmt.Sprintf("Application not delegated to gateway with address [%s]", msg.GatewayAddress)) - return nil, apptypes.ErrAppNotDelegated.Wrapf("application not delegated to gateway with address: %s", msg.GatewayAddress) + logger.Info(fmt.Sprintf("Application not delegated to gateway with address [%s]", msg.GetGatewayAddress())) + return nil, status.Error( + codes.FailedPrecondition, + apptypes.ErrAppNotDelegated.Wrapf( + "application with address %q not delegated to gateway with address: %q", + msg.GetAppAddress(), msg.GetGatewayAddress(), + ).Error(), + ) } // Remove the gateway from the application's delegatee gateway public keys @@ -55,7 +68,7 @@ func (k msgServer) UndelegateFromGateway(ctx context.Context, msg *apptypes.MsgU currentHeight := sdkCtx.BlockHeight() sessionEndHeight := k.sharedKeeper.GetSessionEndHeight(ctx, currentHeight) - k.recordPendingUndelegation(ctx, &foundApp, msg.GatewayAddress, currentHeight) + k.recordPendingUndelegation(ctx, &foundApp, msg.GetGatewayAddress(), currentHeight) // Update the application store with the new delegation k.SetApplication(ctx, foundApp) @@ -67,8 +80,9 @@ func (k msgServer) UndelegateFromGateway(ctx context.Context, msg *apptypes.MsgU SessionEndHeight: sessionEndHeight, } if err := sdkCtx.EventManager().EmitTypedEvent(event); err != nil { - logger.Error(fmt.Sprintf("Failed to emit application redelegation event: %v", err)) - return nil, err + err = fmt.Errorf("failed to emit application redelegation event: %w", err) + logger.Error(err.Error()) + return nil, status.Error(codes.Internal, err.Error()) } logger.Info(fmt.Sprintf("Emitted application redelegation event %v", event)) diff --git a/x/application/keeper/msg_server_undelegate_from_gateway_test.go b/x/application/keeper/msg_server_undelegate_from_gateway_test.go index bc562a81a..4a2f7663b 100644 --- a/x/application/keeper/msg_server_undelegate_from_gateway_test.go +++ b/x/application/keeper/msg_server_undelegate_from_gateway_test.go @@ -174,7 +174,7 @@ func TestMsgServer_UndelegateFromGateway_FailNotDelegated(t *testing.T) { // Attempt to undelgate the application from the gateway _, err = srv.UndelegateFromGateway(ctx, undelegateMsg) - require.ErrorIs(t, err, types.ErrAppNotDelegated) + require.ErrorContains(t, err, types.ErrAppNotDelegated.Error()) foundApp, isAppFound := k.GetApplication(ctx, appAddr) require.True(t, isAppFound) require.Equal(t, appAddr, foundApp.Address) @@ -221,7 +221,7 @@ func TestMsgServer_UndelegateFromGateway_FailNotDelegated(t *testing.T) { // Ensure the failed undelegation did not affect the application _, err = srv.UndelegateFromGateway(ctx, undelegateMsg) - require.ErrorIs(t, err, types.ErrAppNotDelegated) + require.ErrorContains(t, err, apptypes.ErrAppNotDelegated.Error()) events = sdkCtx.EventManager().Events() require.Equal(t, 0, len(events), "expected no events") diff --git a/x/application/keeper/msg_server_unstake_application.go b/x/application/keeper/msg_server_unstake_application.go index 337df4382..bdd3a6bb5 100644 --- a/x/application/keeper/msg_server_unstake_application.go +++ b/x/application/keeper/msg_server_unstake_application.go @@ -31,25 +31,40 @@ func (k msgServer) UnstakeApplication( // Check if the application already exists or not. foundApp, isAppFound := k.GetApplication(ctx, msg.GetAddress()) if !isAppFound { - logger.Info(fmt.Sprintf("Application not found. Cannot unstake address (%s)", msg.GetAddress())) - return nil, apptypes.ErrAppNotFound.Wrapf("application (%s)", msg.GetAddress()) + logger.Info(fmt.Sprintf("Application not found. Cannot unstake address [%s]", msg.GetAddress())) + return nil, status.Error( + codes.NotFound, + apptypes.ErrAppNotFound.Wrapf( + "application with address %q", msg.GetAddress(), + ).Error(), + ) } - logger.Info(fmt.Sprintf("Application found. Unstaking application for address (%s)", msg.GetAddress())) + logger.Info(fmt.Sprintf("Application found. Unstaking application for address [%s]", msg.GetAddress())) // Check if the application has already initiated the unstaking process. if foundApp.IsUnbonding() { - logger.Warn(fmt.Sprintf("Application (%s) is still unbonding from previous unstaking", msg.GetAddress())) - return nil, apptypes.ErrAppIsUnstaking.Wrapf("application (%s)", msg.GetAddress()) + logger.Info(fmt.Sprintf("Application with address [%s] is still unbonding from previous unstaking", msg.GetAddress())) + return nil, status.Error( + codes.FailedPrecondition, + apptypes.ErrAppIsUnstaking.Wrapf( + "application with address %q", msg.GetAddress(), + ).Error(), + ) } // Check if the application has already initiated a transfer process. // Transferring applications CANNOT unstake. if foundApp.HasPendingTransfer() { logger.Warn(fmt.Sprintf( - "Application (%s) has a pending transfer to (%s)", + "Application with address [%s] has a pending transfer to [%s]", msg.Address, foundApp.GetPendingTransfer().GetDestinationAddress()), ) - return nil, apptypes.ErrAppHasPendingTransfer.Wrapf("application (%s)", msg.GetAddress()) + return nil, status.Error( + codes.FailedPrecondition, + apptypes.ErrAppHasPendingTransfer.Wrapf( + "application with address %q", msg.GetAddress(), + ).Error(), + ) } sdkCtx := sdk.UnwrapSDKContext(ctx) diff --git a/x/application/keeper/msg_server_unstake_application_test.go b/x/application/keeper/msg_server_unstake_application_test.go index fa1a59002..68fb1db13 100644 --- a/x/application/keeper/msg_server_unstake_application_test.go +++ b/x/application/keeper/msg_server_unstake_application_test.go @@ -224,7 +224,7 @@ func TestMsgServer_UnstakeApplication_FailIfNotStaked(t *testing.T) { unstakeMsg := &apptypes.MsgUnstakeApplication{Address: appAddr} _, err := srv.UnstakeApplication(ctx, unstakeMsg) require.Error(t, err) - require.ErrorIs(t, err, apptypes.ErrAppNotFound) + require.ErrorContains(t, err, apptypes.ErrAppNotFound.Error()) _, isAppFound = applicationModuleKeepers.GetApplication(ctx, appAddr) require.False(t, isAppFound) @@ -253,7 +253,7 @@ func TestMsgServer_UnstakeApplication_FailIfCurrentlyUnstaking(t *testing.T) { // Verify that the application cannot unstake if it is already unstaking. _, err = srv.UnstakeApplication(ctx, unstakeMsg) - require.ErrorIs(t, err, apptypes.ErrAppIsUnstaking) + require.ErrorContains(t, err, apptypes.ErrAppIsUnstaking.Error()) } func createAppStakeMsg(appAddr string, stakeAmount int64) *apptypes.MsgStakeApplication { diff --git a/x/application/keeper/msg_server_update_param.go b/x/application/keeper/msg_server_update_param.go index a06925e75..0912fcb14 100644 --- a/x/application/keeper/msg_server_update_param.go +++ b/x/application/keeper/msg_server_update_param.go @@ -17,12 +17,12 @@ func (k msgServer) UpdateParam(ctx context.Context, msg *apptypes.MsgUpdateParam ) if err := msg.ValidateBasic(); err != nil { - return nil, err + return nil, status.Error(codes.InvalidArgument, err.Error()) } if k.GetAuthority() != msg.Authority { return nil, status.Error( - codes.InvalidArgument, + codes.PermissionDenied, apptypes.ErrAppInvalidSigner.Wrapf( "invalid authority; expected %s, got %s", k.GetAuthority(), msg.Authority, @@ -38,12 +38,22 @@ func (k msgServer) UpdateParam(ctx context.Context, msg *apptypes.MsgUpdateParam params.MaxDelegatedGateways = msg.GetAsUint64() if _, ok := msg.AsType.(*apptypes.MsgUpdateParam_AsUint64); !ok { - return nil, apptypes.ErrAppParamInvalid.Wrapf("unsupported value type for %s param: %T", msg.Name, msg.AsType) + return nil, status.Error( + codes.InvalidArgument, + apptypes.ErrAppParamInvalid.Wrapf( + "unsupported value type for %s param: %T", msg.Name, msg.AsType, + ).Error(), + ) } maxDelegatedGateways := msg.GetAsUint64() if err := apptypes.ValidateMaxDelegatedGateways(maxDelegatedGateways); err != nil { - return nil, apptypes.ErrAppParamInvalid.Wrapf("maxdelegegated_gateways (%d): %v", maxDelegatedGateways, err) + return nil, status.Error( + codes.InvalidArgument, + apptypes.ErrAppParamInvalid.Wrapf( + "max_delegegated_gateways (%d): %s", maxDelegatedGateways, err, + ).Error(), + ) } params.MaxDelegatedGateways = maxDelegatedGateways case apptypes.ParamMinStake: diff --git a/x/application/keeper/msg_update_params.go b/x/application/keeper/msg_update_params.go index 52335b954..1e101297e 100644 --- a/x/application/keeper/msg_update_params.go +++ b/x/application/keeper/msg_update_params.go @@ -2,20 +2,34 @@ package keeper import ( "context" + "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "github.com/pokt-network/poktroll/x/application/types" ) func (k msgServer) UpdateParams(ctx context.Context, req *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + logger := k.Logger().With("method", "UpdateParams") + if err := req.ValidateBasic(); err != nil { - return nil, err + return nil, status.Error(codes.InvalidArgument, err.Error()) } if k.GetAuthority() != req.Authority { - return nil, types.ErrAppInvalidSigner.Wrapf("invalid authority; expected %s, got %s", k.GetAuthority(), req.Authority) + return nil, status.Error( + codes.PermissionDenied, + types.ErrAppInvalidSigner.Wrapf( + "invalid authority; expected %s, got %s", + k.GetAuthority(), req.Authority, + ).Error(), + ) } if err := k.SetParams(ctx, req.Params); err != nil { - return nil, err + err = fmt.Errorf("unable to set params: %w", err) + logger.Error(err.Error()) + return nil, status.Error(codes.Internal, err.Error()) } return &types.MsgUpdateParamsResponse{}, nil diff --git a/x/application/keeper/query_application.go b/x/application/keeper/query_application.go index 446449d29..4ec5e8ac6 100644 --- a/x/application/keeper/query_application.go +++ b/x/application/keeper/query_application.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "fmt" "cosmossdk.io/store/prefix" "github.com/cosmos/cosmos-sdk/runtime" @@ -13,6 +14,8 @@ import ( ) func (k Keeper) AllApplications(ctx context.Context, req *types.QueryAllApplicationsRequest) (*types.QueryAllApplicationsResponse, error) { + logger := k.Logger().With("method", "AllApplications") + if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -25,7 +28,8 @@ func (k Keeper) AllApplications(ctx context.Context, req *types.QueryAllApplicat pageRes, err := query.Paginate(applicationStore, req.Pagination, func(key []byte, value []byte) error { var application types.Application if err := k.cdc.Unmarshal(value, &application); err != nil { - return err + logger.Error(fmt.Sprintf("unmarshaling application with key (hex): %x: %+v", key, err)) + return status.Error(codes.Internal, err.Error()) } // Ensure that the PendingUndelegations is an empty map and not nil when From acd7fc8a60f44a05a117050c441609361dd608d3 Mon Sep 17 00:00:00 2001 From: Bryan White Date: Mon, 2 Dec 2024 14:14:57 +0100 Subject: [PATCH 18/21] [Supplier] feat: add `staking_fee` param to supplier module (#944) ## Summary Add `staking_fee` param to the tokenomics module. ## Issue - `TODO_BETA` ## Type of change Select one or more from the following: - [x] New feature, functionality or library - [ ] Consensus breaking; add the `consensus-breaking` label if so. See #791 for details - [ ] Bug fix - [ ] Code health or cleanup - [ ] Documentation - [ ] Other (specify) ## Testing - [ ] **Documentation**: `make docusaurus_start`; only needed if you make doc changes - [x] **Unit Tests**: `make go_develop_and_test` - [ ] **LocalNet E2E Tests**: `make test_e2e` - [x] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR. ## Sanity Checklist - [x] I have tested my changes using the available tooling - [ ] I have commented my code - [x] I have performed a self-review of my own code; both comments & source code - [ ] I create and reference any new tickets, if applicable - [ ] I have left TODOs throughout the codebase, if applicable --------- Co-authored-by: red-0ne --- api/poktroll/supplier/params.pulsar.go | 141 +++++++++++++++--- config.yml | 4 + makefiles/params.mk | 4 + proto/poktroll/supplier/params.proto | 3 + testutil/integration/suites/param_configs.go | 7 +- tools/scripts/params/supplier_all.json | 4 + .../scripts/params/supplier_staking_fee.json | 15 ++ x/supplier/keeper/msg_server_update_param.go | 3 + x/supplier/keeper/msg_update_params_test.go | 7 +- x/supplier/keeper/params_test.go | 61 +++++++- x/supplier/types/message_update_param.go | 19 ++- x/supplier/types/params.go | 72 +++++++-- x/supplier/types/params.pb.go | 92 ++++++++++-- 13 files changed, 369 insertions(+), 63 deletions(-) create mode 100644 tools/scripts/params/supplier_staking_fee.json diff --git a/api/poktroll/supplier/params.pulsar.go b/api/poktroll/supplier/params.pulsar.go index bb3c96973..9048f64d1 100644 --- a/api/poktroll/supplier/params.pulsar.go +++ b/api/poktroll/supplier/params.pulsar.go @@ -16,14 +16,16 @@ import ( ) var ( - md_Params protoreflect.MessageDescriptor - fd_Params_min_stake protoreflect.FieldDescriptor + md_Params protoreflect.MessageDescriptor + fd_Params_min_stake protoreflect.FieldDescriptor + fd_Params_staking_fee protoreflect.FieldDescriptor ) func init() { file_poktroll_supplier_params_proto_init() md_Params = File_poktroll_supplier_params_proto.Messages().ByName("Params") fd_Params_min_stake = md_Params.Fields().ByName("min_stake") + fd_Params_staking_fee = md_Params.Fields().ByName("staking_fee") } var _ protoreflect.Message = (*fastReflection_Params)(nil) @@ -97,6 +99,12 @@ func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, proto return } } + if x.StakingFee != nil { + value := protoreflect.ValueOfMessage(x.StakingFee.ProtoReflect()) + if !f(fd_Params_staking_fee, value) { + return + } + } } // Has reports whether a field is populated. @@ -114,6 +122,8 @@ func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { case "poktroll.supplier.Params.min_stake": return x.MinStake != nil + case "poktroll.supplier.Params.staking_fee": + return x.StakingFee != nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.supplier.Params")) @@ -132,6 +142,8 @@ func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { case "poktroll.supplier.Params.min_stake": x.MinStake = nil + case "poktroll.supplier.Params.staking_fee": + x.StakingFee = nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.supplier.Params")) @@ -151,6 +163,9 @@ func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) pro case "poktroll.supplier.Params.min_stake": value := x.MinStake return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "poktroll.supplier.Params.staking_fee": + value := x.StakingFee + return protoreflect.ValueOfMessage(value.ProtoReflect()) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.supplier.Params")) @@ -173,6 +188,8 @@ func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value proto switch fd.FullName() { case "poktroll.supplier.Params.min_stake": x.MinStake = value.Message().Interface().(*v1beta1.Coin) + case "poktroll.supplier.Params.staking_fee": + x.StakingFee = value.Message().Interface().(*v1beta1.Coin) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.supplier.Params")) @@ -198,6 +215,11 @@ func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protore x.MinStake = new(v1beta1.Coin) } return protoreflect.ValueOfMessage(x.MinStake.ProtoReflect()) + case "poktroll.supplier.Params.staking_fee": + if x.StakingFee == nil { + x.StakingFee = new(v1beta1.Coin) + } + return protoreflect.ValueOfMessage(x.StakingFee.ProtoReflect()) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.supplier.Params")) @@ -214,6 +236,9 @@ func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protor case "poktroll.supplier.Params.min_stake": m := new(v1beta1.Coin) return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "poktroll.supplier.Params.staking_fee": + m := new(v1beta1.Coin) + return protoreflect.ValueOfMessage(m.ProtoReflect()) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: poktroll.supplier.Params")) @@ -287,6 +312,10 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { l = options.Size(x.MinStake) n += 1 + l + runtime.Sov(uint64(l)) } + if x.StakingFee != nil { + l = options.Size(x.StakingFee) + n += 1 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -316,6 +345,20 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if x.StakingFee != nil { + encoded, err := options.Marshal(x.StakingFee) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } if x.MinStake != nil { encoded, err := options.Marshal(x.MinStake) if err != nil { @@ -415,6 +458,42 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err } iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field StakingFee", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.StakingFee == nil { + x.StakingFee = &v1beta1.Coin{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.StakingFee); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -472,6 +551,8 @@ type Params struct { // min_stake is the minimum amount of uPOKT that a supplier must stake to be // included in network sessions and remain staked. MinStake *v1beta1.Coin `protobuf:"bytes,1,opt,name=min_stake,json=minStake,proto3" json:"min_stake,omitempty"` + // staking_fee is the fee charged by the protocol for staking a supplier. + StakingFee *v1beta1.Coin `protobuf:"bytes,2,opt,name=staking_fee,json=stakingFee,proto3" json:"staking_fee,omitempty"` } func (x *Params) Reset() { @@ -501,6 +582,13 @@ func (x *Params) GetMinStake() *v1beta1.Coin { return nil } +func (x *Params) GetStakingFee() *v1beta1.Coin { + if x != nil { + return x.StakingFee + } + return nil +} + var File_poktroll_supplier_params_proto protoreflect.FileDescriptor var file_poktroll_supplier_params_proto_rawDesc = []byte{ @@ -511,28 +599,34 @@ var file_poktroll_supplier_params_proto_rawDesc = []byte{ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2f, 0x63, 0x6f, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x88, 0x01, 0x0a, + 0x31, 0x2f, 0x63, 0x6f, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xeb, 0x01, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x59, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x21, 0xea, 0xde, 0x1f, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x6b, 0x65, 0xf2, 0xde, 0x1f, 0x10, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x22, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x53, 0x74, 0x61, - 0x6b, 0x65, 0x3a, 0x23, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x1a, 0x70, 0x6f, 0x6b, - 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x78, 0x2f, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x72, - 0x2f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0xb1, 0x01, 0xd8, 0xe2, 0x1e, 0x01, 0x0a, 0x15, - 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x75, 0x70, - 0x70, 0x6c, 0x69, 0x65, 0x72, 0x42, 0x0b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x22, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, - 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, - 0x73, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x72, 0xa2, 0x02, 0x03, 0x50, 0x53, 0x58, 0xaa, 0x02, - 0x11, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x69, - 0x65, 0x72, 0xca, 0x02, 0x11, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x53, 0x75, - 0x70, 0x70, 0x6c, 0x69, 0x65, 0x72, 0xe2, 0x02, 0x1d, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, - 0x6c, 0x5c, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x12, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, - 0x6c, 0x3a, 0x3a, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x6b, 0x65, 0x12, 0x61, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x65, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, + 0x69, 0x6e, 0x42, 0x25, 0xea, 0xde, 0x1f, 0x0b, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x5f, + 0x66, 0x65, 0x65, 0xf2, 0xde, 0x1f, 0x12, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x73, 0x74, 0x61, + 0x6b, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x65, 0x65, 0x22, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x6b, 0x69, + 0x6e, 0x67, 0x46, 0x65, 0x65, 0x3a, 0x23, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x1a, + 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x78, 0x2f, 0x73, 0x75, 0x70, 0x70, 0x6c, + 0x69, 0x65, 0x72, 0x2f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0xb1, 0x01, 0xd8, 0xe2, 0x1e, + 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, + 0x73, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x42, 0x0b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x22, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, + 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x6f, 0x6b, 0x74, 0x72, 0x6f, + 0x6c, 0x6c, 0x2f, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x72, 0xa2, 0x02, 0x03, 0x50, 0x53, + 0x58, 0xaa, 0x02, 0x11, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x53, 0x75, 0x70, + 0x70, 0x6c, 0x69, 0x65, 0x72, 0xca, 0x02, 0x11, 0x50, 0x6f, 0x6b, 0x74, 0x72, 0x6f, 0x6c, 0x6c, + 0x5c, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x72, 0xe2, 0x02, 0x1d, 0x50, 0x6f, 0x6b, 0x74, + 0x72, 0x6f, 0x6c, 0x6c, 0x5c, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x12, 0x50, 0x6f, 0x6b, 0x74, + 0x72, 0x6f, 0x6c, 0x6c, 0x3a, 0x3a, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -554,11 +648,12 @@ var file_poktroll_supplier_params_proto_goTypes = []interface{}{ } var file_poktroll_supplier_params_proto_depIdxs = []int32{ 1, // 0: poktroll.supplier.Params.min_stake:type_name -> cosmos.base.v1beta1.Coin - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 1, // 1: poktroll.supplier.Params.staking_fee:type_name -> cosmos.base.v1beta1.Coin + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_poktroll_supplier_params_proto_init() } diff --git a/config.yml b/config.yml index f6bec72d1..ccde339a4 100644 --- a/config.yml +++ b/config.yml @@ -200,6 +200,10 @@ genesis: min_stake: amount: "1000000" # 1 POKT denom: upokt + # TODO_BETA(@bryanchriswhite): Determine realistic amount for supplier staking fee. + staking_fee: + amount: "1" # 1 uPOKT + denom: upokt supplierList: - owner_address: pokt19a3t4yunp0dlpfjrp7qwnzwlrzd5fzs2gjaaaj operator_address: pokt19a3t4yunp0dlpfjrp7qwnzwlrzd5fzs2gjaaaj diff --git a/makefiles/params.mk b/makefiles/params.mk index bbe99698a..a2968c102 100644 --- a/makefiles/params.mk +++ b/makefiles/params.mk @@ -148,6 +148,10 @@ params_update_supplier_all: ## Update the supplier module params params_update_supplier_min_stake: ## Update the supplier module min_stake param poktrolld tx authz exec ./tools/scripts/params/supplier_min_stake.json $(PARAM_FLAGS) +.PHONY: params_update_supplier_staking_fee +params_update_supplier_staking_fee: ## Update the supplier module staking_fee param + poktrolld tx authz exec ./tools/scripts/params/supplier_staking_fee.json $(PARAM_FLAGS) + ### Session Module Params ### .PHONY: params_get_session params_get_session: ## Get the session module params diff --git a/proto/poktroll/supplier/params.proto b/proto/poktroll/supplier/params.proto index d4e8c77ec..06fa9b7bc 100644 --- a/proto/poktroll/supplier/params.proto +++ b/proto/poktroll/supplier/params.proto @@ -16,4 +16,7 @@ message Params { // min_stake is the minimum amount of uPOKT that a supplier must stake to be // included in network sessions and remain staked. cosmos.base.v1beta1.Coin min_stake = 1 [(gogoproto.jsontag) = "min_stake", (gogoproto.moretags) = "yaml:\"min_stake\""]; + + // staking_fee is the fee charged by the protocol for staking a supplier. + cosmos.base.v1beta1.Coin staking_fee = 2 [(gogoproto.jsontag) = "staking_fee", (gogoproto.moretags) = "yaml:\"staking_fee\""]; } diff --git a/testutil/integration/suites/param_configs.go b/testutil/integration/suites/param_configs.go index 1e3a52e9e..d95a3050e 100644 --- a/testutil/integration/suites/param_configs.go +++ b/testutil/integration/suites/param_configs.go @@ -1,8 +1,6 @@ package suites import ( - "encoding/hex" - cosmostypes "github.com/cosmos/cosmos-sdk/types" "github.com/pokt-network/poktroll/app/volatile" @@ -70,8 +68,8 @@ var ( ValidProofMissingPenaltyCoin = cosmostypes.NewInt64Coin(volatile.DenomuPOKT, 500) ValidProofSubmissionFeeCoin = cosmostypes.NewInt64Coin(volatile.DenomuPOKT, 5000000) ValidProofRequirementThresholdCoin = cosmostypes.NewInt64Coin(volatile.DenomuPOKT, 100) - ValidRelayDifficultyTargetHash, _ = hex.DecodeString("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff") ValidActorMinStake = cosmostypes.NewInt64Coin(volatile.DenomuPOKT, 100) + ValidStakingFee = cosmostypes.NewInt64Coin(volatile.DenomuPOKT, 1) SharedModuleParamConfig = ModuleParamConfig{ ParamsMsgs: ModuleParamsMessages{ @@ -192,7 +190,8 @@ var ( QueryParamsResponse: suppliertypes.QueryParamsResponse{}, }, ValidParams: suppliertypes.Params{ - MinStake: &ValidActorMinStake, + MinStake: &ValidActorMinStake, + StakingFee: &ValidStakingFee, }, ParamTypes: map[ParamType]any{ ParamTypeCoin: suppliertypes.MsgUpdateParam_AsCoin{}, diff --git a/tools/scripts/params/supplier_all.json b/tools/scripts/params/supplier_all.json index cded3172f..01d632f4c 100644 --- a/tools/scripts/params/supplier_all.json +++ b/tools/scripts/params/supplier_all.json @@ -8,6 +8,10 @@ "min_stake": { "amount": "1000000", "denom": "upokt" + }, + "staking_fee": { + "amount": "1", + "denom": "upokt" } } } diff --git a/tools/scripts/params/supplier_staking_fee.json b/tools/scripts/params/supplier_staking_fee.json new file mode 100644 index 000000000..baad22561 --- /dev/null +++ b/tools/scripts/params/supplier_staking_fee.json @@ -0,0 +1,15 @@ +{ + "body": { + "messages": [ + { + "@type": "/poktroll.supplier.MsgUpdateParam", + "authority": "pokt10d07y265gmmuvt4z0w9aw880jnsr700j8yv32t", + "name": "staking_fee", + "as_coin": { + "amount": "1", + "denom": "upokt" + } + } + ] + } +} diff --git a/x/supplier/keeper/msg_server_update_param.go b/x/supplier/keeper/msg_server_update_param.go index 47e96f528..6d9a160ce 100644 --- a/x/supplier/keeper/msg_server_update_param.go +++ b/x/supplier/keeper/msg_server_update_param.go @@ -38,6 +38,9 @@ func (k msgServer) UpdateParam(ctx context.Context, msg *suppliertypes.MsgUpdate case suppliertypes.ParamMinStake: logger = logger.With("min_stake", msg.GetAsCoin()) params.MinStake = msg.GetAsCoin() + case suppliertypes.ParamStakingFee: + logger = logger.With("staking_fee", msg.GetAsCoin()) + params.StakingFee = msg.GetAsCoin() default: return nil, status.Error( codes.InvalidArgument, diff --git a/x/supplier/keeper/msg_update_params_test.go b/x/supplier/keeper/msg_update_params_test.go index 5a0019a64..5b2c45f1d 100644 --- a/x/supplier/keeper/msg_update_params_test.go +++ b/x/supplier/keeper/msg_update_params_test.go @@ -3,8 +3,10 @@ package keeper_test import ( "testing" + cosmostypes "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + "github.com/pokt-network/poktroll/app/volatile" suppliertypes "github.com/pokt-network/poktroll/x/supplier/types" ) @@ -13,6 +15,8 @@ func TestMsgUpdateParams(t *testing.T) { params := suppliertypes.DefaultParams() require.NoError(t, k.SetParams(ctx, params)) + zerouPokt := cosmostypes.NewInt64Coin(volatile.DenomuPOKT, 0) + // default params tests := []struct { desc string @@ -42,7 +46,8 @@ func TestMsgUpdateParams(t *testing.T) { params: &suppliertypes.MsgUpdateParams{ Authority: k.GetAuthority(), Params: suppliertypes.Params{ - MinStake: &suppliertypes.DefaultMinStake, + MinStake: &suppliertypes.DefaultMinStake, + StakingFee: &zerouPokt, }, }, shouldError: false, diff --git a/x/supplier/keeper/params_test.go b/x/supplier/keeper/params_test.go index 3d74b7813..8ac48c13f 100644 --- a/x/supplier/keeper/params_test.go +++ b/x/supplier/keeper/params_test.go @@ -38,7 +38,18 @@ func TestParams_ValidateMinStake(t *testing.T) { Amount: math.NewInt(-1), }, expectedErr: suppliertypes.ErrSupplierParamInvalid.Wrapf( - "min_stake amount must be greater than 0: got -1%s", + "min_stake amount must be positive: got -1%s", + volatile.DenomuPOKT, + ), + }, + { + desc: "MinStake equal to zero", + minStake: &cosmostypes.Coin{ + Denom: volatile.DenomuPOKT, + Amount: math.NewInt(0), + }, + expectedErr: suppliertypes.ErrSupplierParamInvalid.Wrapf( + "min_stake amount must be greater than 0: got 0%s", volatile.DenomuPOKT, ), }, @@ -60,3 +71,51 @@ func TestParams_ValidateMinStake(t *testing.T) { }) } } + +func TestParams_ValidateStakingFee(t *testing.T) { + tests := []struct { + desc string + minStake any + expectedErr error + }{ + { + desc: "invalid type", + minStake: "420", + expectedErr: suppliertypes.ErrSupplierParamInvalid.Wrapf("invalid parameter type: string"), + }, + { + desc: "SupplierStakingFee less than zero", + minStake: &cosmostypes.Coin{ + Denom: volatile.DenomuPOKT, + Amount: math.NewInt(-1), + }, + expectedErr: suppliertypes.ErrSupplierParamInvalid.Wrapf( + "staking_fee amount must be positive: got -1%s", + volatile.DenomuPOKT, + ), + }, + { + desc: "zero SupplierStakingFee", + minStake: &cosmostypes.Coin{ + Denom: volatile.DenomuPOKT, + Amount: math.NewInt(0), + }, + }, + { + desc: "valid SupplierStakingFee", + minStake: &suppliertypes.DefaultStakingFee, + }, + } + + for _, test := range tests { + t.Run(test.desc, func(t *testing.T) { + err := suppliertypes.ValidateStakingFee(test.minStake) + if test.expectedErr != nil { + require.Error(t, err) + require.Contains(t, err.Error(), test.expectedErr.Error()) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/x/supplier/types/message_update_param.go b/x/supplier/types/message_update_param.go index 0e6a1cc03..e1ce28298 100644 --- a/x/supplier/types/message_update_param.go +++ b/x/supplier/types/message_update_param.go @@ -45,23 +45,28 @@ func (msg *MsgUpdateParam) ValidateBasic() error { // Parameter name MUST be supported by this module. switch msg.Name { case ParamMinStake: - if err := msg.paramTypeIsCoin(); err != nil { + if err := genericParamTypeIs[*MsgUpdateParam_AsCoin](msg); err != nil { return err } return ValidateMinStake(msg.GetAsCoin()) + case ParamStakingFee: + if err := genericParamTypeIs[*MsgUpdateParam_AsCoin](msg); err != nil { + return err + } + return ValidateStakingFee(msg.GetAsCoin()) default: return ErrSupplierParamInvalid.Wrapf("unsupported param %q", msg.Name) } } -// paramTypeIsCoin checks if the parameter type is a Coin, returning an error if not. -func (msg *MsgUpdateParam) paramTypeIsCoin() error { - if _, ok := msg.AsType.(*MsgUpdateParam_AsCoin); !ok { +// genericParamTypeIs checks if the parameter type is T, returning an error if not. +func genericParamTypeIs[T any](msg *MsgUpdateParam) error { + if _, ok := msg.AsType.(T); !ok { return ErrSupplierParamInvalid.Wrapf( - "invalid type for param %q expected %T, got %T", - msg.Name, &MsgUpdateParam_AsCoin{}, - msg.AsType, + "invalid type for param %q; expected %T, got %T", + msg.Name, *new(T), msg.AsType, ) } + return nil } diff --git a/x/supplier/types/params.go b/x/supplier/types/params.go index 48a90f97d..7fe2e081a 100644 --- a/x/supplier/types/params.go +++ b/x/supplier/types/params.go @@ -14,6 +14,10 @@ var ( ParamMinStake = "min_stake" // TODO_MAINNET: Determine the default value. DefaultMinStake = cosmostypes.NewInt64Coin("upokt", 1000000) // 1 POKT + KeyStakingFee = []byte("StakingFee") + ParamStakingFee = "staking_fee" + // TODO_MAINNET: Determine the default value. + DefaultStakingFee = cosmostypes.NewInt64Coin("upokt", 1) // 1 uPOKT ) // ParamKeyTable the param key table for launch module @@ -22,15 +26,22 @@ func ParamKeyTable() paramtypes.KeyTable { } // NewParams creates a new Params instance -func NewParams(minStake *cosmostypes.Coin) Params { +func NewParams( + minStake *cosmostypes.Coin, + stakingFee *cosmostypes.Coin, +) Params { return Params{ - MinStake: minStake, + MinStake: minStake, + StakingFee: stakingFee, } } // DefaultParams returns a default set of parameters func DefaultParams() Params { - return NewParams(&DefaultMinStake) + return NewParams( + &DefaultMinStake, + &DefaultStakingFee, + ) } // ParamSetPairs get the params.ParamSet @@ -41,6 +52,11 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { &p.MinStake, ValidateMinStake, ), + paramtypes.NewParamSetPair( + KeyStakingFee, + &p.StakingFee, + ValidateStakingFee, + ), } } @@ -50,30 +66,58 @@ func (p Params) Validate() error { return err } + if err := ValidateStakingFee(p.StakingFee); err != nil { + return err + } + return nil } // ValidateMinStake validates the MinStake param. func ValidateMinStake(minStakeAny any) error { - minStakeCoin, ok := minStakeAny.(*cosmostypes.Coin) + minStakeCoin, err := paramAsPositiveuPOKT(minStakeAny, "min_stake") + if err != nil { + return err + } + + if minStakeCoin.IsZero() { + return ErrSupplierParamInvalid.Wrapf("min_stake amount must be greater than 0: got %s", minStakeCoin) + } + + return nil +} + +// ValidateStakingFee validates the StakingFee param. +func ValidateStakingFee(stakingFeeAny any) error { + if _, err := paramAsPositiveuPOKT(stakingFeeAny, "staking_fee"); err != nil { + return err + } + + return nil +} + +// paramAsPositiveuPOKT checks that paramAny is a *cosmostypes.Coin and that its +// amount is positive, returning an error if either is not the case. +func paramAsPositiveuPOKT(paramAny any, paramName string) (*cosmostypes.Coin, error) { + paramCoin, ok := paramAny.(*cosmostypes.Coin) if !ok { - return ErrSupplierParamInvalid.Wrapf("invalid parameter type: %T", minStakeAny) + return nil, ErrSupplierParamInvalid.Wrapf("invalid parameter type: %T", paramAny) } - if minStakeCoin == nil { - return ErrSupplierParamInvalid.Wrapf("missing min_stake") + if paramCoin == nil { + return nil, ErrSupplierParamInvalid.Wrapf("missing param") } - if minStakeCoin.Denom != volatile.DenomuPOKT { - return ErrSupplierParamInvalid.Wrapf( - "invalid min_stake denom %q; expected %q", - minStakeCoin.Denom, volatile.DenomuPOKT, + if paramCoin.Denom != volatile.DenomuPOKT { + return nil, ErrSupplierParamInvalid.Wrapf( + "invalid %s denom %q; expected %q", + paramName, paramCoin.Denom, volatile.DenomuPOKT, ) } - if minStakeCoin.IsZero() || minStakeCoin.IsNegative() { - return ErrSupplierParamInvalid.Wrapf("min_stake amount must be greater than 0: got %s", minStakeCoin) + if paramCoin.IsNegative() { + return nil, ErrSupplierParamInvalid.Wrapf("%s amount must be positive: got %s", paramName, paramCoin) } - return nil + return paramCoin, nil } diff --git a/x/supplier/types/params.pb.go b/x/supplier/types/params.pb.go index 8a79db314..06b031634 100644 --- a/x/supplier/types/params.pb.go +++ b/x/supplier/types/params.pb.go @@ -30,6 +30,8 @@ type Params struct { // min_stake is the minimum amount of uPOKT that a supplier must stake to be // included in network sessions and remain staked. MinStake *types.Coin `protobuf:"bytes,1,opt,name=min_stake,json=minStake,proto3" json:"min_stake" yaml:"min_stake"` + // staking_fee is the fee charged by the protocol for staking a supplier. + StakingFee *types.Coin `protobuf:"bytes,2,opt,name=staking_fee,json=stakingFee,proto3" json:"staking_fee" yaml:"staking_fee"` } func (m *Params) Reset() { *m = Params{} } @@ -68,6 +70,13 @@ func (m *Params) GetMinStake() *types.Coin { return nil } +func (m *Params) GetStakingFee() *types.Coin { + if m != nil { + return m.StakingFee + } + return nil +} + func init() { proto.RegisterType((*Params)(nil), "poktroll.supplier.Params") } @@ -75,25 +84,27 @@ func init() { func init() { proto.RegisterFile("poktroll/supplier/params.proto", fileDescriptor_60f7a8031a8c22d5) } var fileDescriptor_60f7a8031a8c22d5 = []byte{ - // 273 bytes of a gzipped FileDescriptorProto + // 313 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2b, 0xc8, 0xcf, 0x2e, 0x29, 0xca, 0xcf, 0xc9, 0xd1, 0x2f, 0x2e, 0x2d, 0x28, 0xc8, 0xc9, 0x4c, 0x2d, 0xd2, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x84, 0xc9, 0xeb, 0xc1, 0xe4, 0xa5, 0x04, 0x13, 0x73, 0x33, 0xf3, 0xf2, 0xf5, 0xc1, 0x24, 0x44, 0x95, 0x94, 0x48, 0x7a, 0x7e, 0x7a, 0x3e, 0x98, 0xa9, 0x0f, 0x62, 0x41, 0x45, 0xe5, 0x92, 0xf3, 0x8b, 0x73, 0xf3, 0x8b, 0xf5, 0x93, 0x12, 0x8b, 0x53, 0xf5, 0xcb, 0x0c, 0x93, 0x52, 0x4b, 0x12, 0x0d, 0xf5, 0x93, 0xf3, - 0x33, 0xf3, 0x20, 0xf2, 0x4a, 0x1d, 0x8c, 0x5c, 0x6c, 0x01, 0x60, 0xcb, 0x84, 0x22, 0xb9, 0x38, - 0x73, 0x33, 0xf3, 0xe2, 0x8b, 0x4b, 0x12, 0xb3, 0x53, 0x25, 0x18, 0x15, 0x18, 0x35, 0xb8, 0x8d, - 0x24, 0xf5, 0x20, 0xda, 0xf5, 0x40, 0xda, 0xf5, 0xa0, 0xda, 0xf5, 0x9c, 0xf3, 0x33, 0xf3, 0x9c, - 0x14, 0x5f, 0xdd, 0x93, 0x47, 0xa8, 0xff, 0x74, 0x4f, 0x5e, 0xa0, 0x32, 0x31, 0x37, 0xc7, 0x4a, - 0x09, 0x2e, 0xa4, 0x14, 0xc4, 0x91, 0x9b, 0x99, 0x17, 0x0c, 0x62, 0x5a, 0x29, 0xbf, 0x58, 0x20, - 0xcf, 0xd8, 0xf5, 0x7c, 0x83, 0x96, 0x14, 0xdc, 0xab, 0x15, 0x08, 0xcf, 0x42, 0xec, 0x77, 0xf2, - 0x3f, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x1b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, - 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0x0c, - 0xd3, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0x41, 0x86, 0xe8, 0xe6, 0xa5, - 0x96, 0x94, 0xe7, 0x17, 0x65, 0xeb, 0x63, 0x33, 0xb1, 0xa4, 0xb2, 0x20, 0xb5, 0x38, 0x89, 0x0d, - 0xec, 0x45, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc3, 0x4d, 0x0e, 0x37, 0x60, 0x01, 0x00, - 0x00, + 0x33, 0xf3, 0x20, 0xf2, 0x4a, 0xaf, 0x19, 0xb9, 0xd8, 0x02, 0xc0, 0x96, 0x09, 0x45, 0x72, 0x71, + 0xe6, 0x66, 0xe6, 0xc5, 0x17, 0x97, 0x24, 0x66, 0xa7, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x1b, + 0x49, 0xea, 0x41, 0xb4, 0xeb, 0x81, 0xb4, 0xeb, 0x41, 0xb5, 0xeb, 0x39, 0xe7, 0x67, 0xe6, 0x39, + 0x29, 0xbe, 0xba, 0x27, 0x8f, 0x50, 0xff, 0xe9, 0x9e, 0xbc, 0x40, 0x65, 0x62, 0x6e, 0x8e, 0x95, + 0x12, 0x5c, 0x48, 0x29, 0x88, 0x23, 0x37, 0x33, 0x2f, 0x18, 0xc4, 0x14, 0x4a, 0xe4, 0xe2, 0x06, + 0x89, 0x65, 0xe6, 0xa5, 0xc7, 0xa7, 0xa5, 0xa6, 0x4a, 0x30, 0x11, 0x32, 0x5c, 0xf5, 0xd5, 0x3d, + 0x79, 0x64, 0x1d, 0x9f, 0xee, 0xc9, 0x0b, 0x41, 0x8c, 0x47, 0x12, 0x54, 0x0a, 0xe2, 0x82, 0xf2, + 0xdc, 0x52, 0x53, 0xad, 0x94, 0x5f, 0x2c, 0x90, 0x67, 0xec, 0x7a, 0xbe, 0x41, 0x4b, 0x0a, 0x1e, + 0x9a, 0x15, 0x88, 0xf0, 0x84, 0x78, 0xd1, 0xc9, 0xff, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, + 0x18, 0x6f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, + 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x32, 0x4c, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, + 0xce, 0xcf, 0xd5, 0x07, 0x19, 0xa2, 0x9b, 0x97, 0x5a, 0x52, 0x9e, 0x5f, 0x94, 0xad, 0x8f, 0xcd, + 0xc4, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0x70, 0x28, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, + 0xff, 0xe0, 0x47, 0xa0, 0x65, 0xc3, 0x01, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { @@ -118,6 +129,9 @@ func (this *Params) Equal(that interface{}) bool { if !this.MinStake.Equal(that1.MinStake) { return false } + if !this.StakingFee.Equal(that1.StakingFee) { + return false + } return true } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -140,6 +154,18 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.StakingFee != nil { + { + size, err := m.StakingFee.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } if m.MinStake != nil { { size, err := m.MinStake.MarshalToSizedBuffer(dAtA[:i]) @@ -176,6 +202,10 @@ func (m *Params) Size() (n int) { l = m.MinStake.Size() n += 1 + l + sovParams(uint64(l)) } + if m.StakingFee != nil { + l = m.StakingFee.Size() + n += 1 + l + sovParams(uint64(l)) + } return n } @@ -250,6 +280,42 @@ func (m *Params) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StakingFee", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.StakingFee == nil { + m.StakingFee = &types.Coin{} + } + if err := m.StakingFee.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) From 1a6cabd63b41096c1222a60be035839ca3b29741 Mon Sep 17 00:00:00 2001 From: Bryan White Date: Mon, 2 Dec 2024 14:15:38 +0100 Subject: [PATCH 19/21] [Code Health] fix: supplier module gRPC return errors (#962) ## Summary Ensure all supplier message and query handlers return gRPC status errors. ## Issue - #860 ## Type of change Select one or more from the following: - [ ] New feature, functionality or library - [x] Consensus breaking; add the `consensus-breaking` label if so. See #791 for details - [ ] Bug fix - [x] Code health or cleanup - [ ] Documentation - [ ] Other (specify) ## Testing - [ ] **Documentation**: `make docusaurus_start`; only needed if you make doc changes - [x] **Unit Tests**: `make go_develop_and_test` - [ ] **LocalNet E2E Tests**: `make test_e2e` - [x] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR. ## Sanity Checklist - [x] I have tested my changes using the available tooling - [ ] I have commented my code - [x] I have performed a self-review of my own code; both comments & source code - [ ] I create and reference any new tickets, if applicable - [ ] I have left TODOs throughout the codebase, if applicable --- .../keeper/msg_server_unstake_supplier.go | 39 ++++++++++++------- .../msg_server_unstake_supplier_test.go | 4 +- x/supplier/keeper/msg_update_params.go | 19 +++++++-- x/supplier/keeper/query_supplier.go | 6 ++- 4 files changed, 49 insertions(+), 19 deletions(-) diff --git a/x/supplier/keeper/msg_server_unstake_supplier.go b/x/supplier/keeper/msg_server_unstake_supplier.go index 17cfda752..2ac70a39b 100644 --- a/x/supplier/keeper/msg_server_unstake_supplier.go +++ b/x/supplier/keeper/msg_server_unstake_supplier.go @@ -28,32 +28,45 @@ func (k msgServer) UnstakeSupplier( logger.Info(fmt.Sprintf("About to unstake supplier with msg: %v", msg)) if err := msg.ValidateBasic(); err != nil { - return nil, err + return nil, status.Error(codes.InvalidArgument, err.Error()) } // Check if the supplier already exists or not - supplier, isSupplierFound := k.GetSupplier(ctx, msg.OperatorAddress) + supplier, isSupplierFound := k.GetSupplier(ctx, msg.GetOperatorAddress()) if !isSupplierFound { - logger.Info(fmt.Sprintf("Supplier not found. Cannot unstake address %s", msg.OperatorAddress)) - return nil, suppliertypes.ErrSupplierNotFound + logger.Info(fmt.Sprintf("Supplier not found. Cannot unstake address %s", msg.GetOperatorAddress())) + return nil, status.Error( + codes.NotFound, + suppliertypes.ErrSupplierNotFound.Wrapf( + "supplier with operator address %q", msg.GetOperatorAddress(), + ).Error(), + ) } // Ensure the singer address matches the owner address or the operator address. - if !supplier.HasOperator(msg.Signer) && !supplier.HasOwner(msg.Signer) { - logger.Error("only the supplier owner or operator is allowed to unstake the supplier") - return nil, sharedtypes.ErrSharedUnauthorizedSupplierUpdate.Wrapf( - "signer %q is not allowed to unstake supplier %v", - msg.Signer, - supplier, + if !supplier.HasOperator(msg.GetSigner()) && !supplier.HasOwner(msg.GetSigner()) { + logger.Info("only the supplier owner or operator is allowed to unstake the supplier") + return nil, status.Error( + codes.PermissionDenied, + sharedtypes.ErrSharedUnauthorizedSupplierUpdate.Wrapf( + "signer %q is not allowed to unstake supplier %+v", + msg.Signer, + supplier, + ).Error(), ) } - logger.Info(fmt.Sprintf("Supplier found. Unstaking supplier for address %s", msg.OperatorAddress)) + logger.Info(fmt.Sprintf("Supplier found. Unstaking supplier with operating address %s", msg.GetOperatorAddress())) // Check if the supplier has already initiated the unstake action. if supplier.IsUnbonding() { - logger.Warn(fmt.Sprintf("Supplier %s still unbonding from previous unstaking", msg.OperatorAddress)) - return nil, suppliertypes.ErrSupplierIsUnstaking + logger.Info(fmt.Sprintf("Supplier %s still unbonding from previous unstaking", msg.GetOperatorAddress())) + return nil, status.Error( + codes.FailedPrecondition, + suppliertypes.ErrSupplierIsUnstaking.Wrapf( + "supplier with operator address %q", msg.GetOperatorAddress(), + ).Error(), + ) } sdkCtx := sdk.UnwrapSDKContext(ctx) diff --git a/x/supplier/keeper/msg_server_unstake_supplier_test.go b/x/supplier/keeper/msg_server_unstake_supplier_test.go index fc844e4e0..d96a433fd 100644 --- a/x/supplier/keeper/msg_server_unstake_supplier_test.go +++ b/x/supplier/keeper/msg_server_unstake_supplier_test.go @@ -280,7 +280,7 @@ func TestMsgServer_UnstakeSupplier_FailIfNotStaked(t *testing.T) { } _, err := srv.UnstakeSupplier(ctx, unstakeMsg) require.Error(t, err) - require.ErrorIs(t, err, suppliertypes.ErrSupplierNotFound) + require.ErrorContains(t, err, suppliertypes.ErrSupplierNotFound.Error()) _, isSupplierFound = supplierModuleKeepers.GetSupplier(ctx, supplierOperatorAddr) require.False(t, isSupplierFound) @@ -311,7 +311,7 @@ func TestMsgServer_UnstakeSupplier_FailIfCurrentlyUnstaking(t *testing.T) { ctx = keepertest.SetBlockHeight(ctx, sdkCtx.BlockHeight()+1) _, err = srv.UnstakeSupplier(ctx, unstakeMsg) - require.ErrorIs(t, err, suppliertypes.ErrSupplierIsUnstaking) + require.ErrorContains(t, err, suppliertypes.ErrSupplierIsUnstaking.Error()) } func TestMsgServer_UnstakeSupplier_OperatorCanUnstake(t *testing.T) { diff --git a/x/supplier/keeper/msg_update_params.go b/x/supplier/keeper/msg_update_params.go index ed841b914..4fa159dff 100644 --- a/x/supplier/keeper/msg_update_params.go +++ b/x/supplier/keeper/msg_update_params.go @@ -2,6 +2,10 @@ package keeper import ( "context" + "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "github.com/pokt-network/poktroll/x/supplier/types" ) @@ -10,15 +14,24 @@ func (k msgServer) UpdateParams( ctx context.Context, req *types.MsgUpdateParams, ) (*types.MsgUpdateParamsResponse, error) { + logger := k.Logger().With("method", "UpdateParams") + if err := req.ValidateBasic(); err != nil { - return nil, err + return nil, status.Error(codes.InvalidArgument, err.Error()) } if k.GetAuthority() != req.Authority { - return nil, types.ErrSupplierInvalidSigner.Wrapf("invalid authority; expected %s, got %s", k.GetAuthority(), req.Authority) + return nil, status.Error( + codes.PermissionDenied, + types.ErrSupplierInvalidSigner.Wrapf( + "invalid authority; expected %s, got %s", k.GetAuthority(), req.Authority, + ).Error(), + ) } if err := k.SetParams(ctx, req.Params); err != nil { - return nil, err + err = fmt.Errorf("unable to set params: %w", err) + logger.Error(err.Error()) + return nil, status.Error(codes.Internal, err.Error()) } return &types.MsgUpdateParamsResponse{}, nil diff --git a/x/supplier/keeper/query_supplier.go b/x/supplier/keeper/query_supplier.go index 92112827a..3d370a8fa 100644 --- a/x/supplier/keeper/query_supplier.go +++ b/x/supplier/keeper/query_supplier.go @@ -18,6 +18,8 @@ func (k Keeper) AllSuppliers( ctx context.Context, req *types.QueryAllSuppliersRequest, ) (*types.QueryAllSuppliersResponse, error) { + logger := k.Logger().With("method", "AllSuppliers") + if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } @@ -33,7 +35,9 @@ func (k Keeper) AllSuppliers( func(key []byte, value []byte) error { var supplier sharedtypes.Supplier if err := k.cdc.Unmarshal(value, &supplier); err != nil { - return err + err = fmt.Errorf("unmarshaling supplier with key (hex): %x: %+v", key, err) + logger.Error(err.Error()) + return status.Error(codes.Internal, err.Error()) } suppliers = append(suppliers, supplier) From 74a23ebb7f4a003763270e162989220176312ec1 Mon Sep 17 00:00:00 2001 From: Bryan White Date: Mon, 2 Dec 2024 14:15:53 +0100 Subject: [PATCH 20/21] [Code Health] fix: tokenomics module gRPC return errors (#963) ## Summary Ensure all supplier message and query handlers return gRPC status errors. ## Issue - #860 ## Type of change Select one or more from the following: - [ ] New feature, functionality or library - [ ] Consensus breaking; add the `consensus-breaking` label if so. See #791 for details - [ ] Bug fix - [x] Code health or cleanup - [ ] Documentation - [ ] Other (specify) ## Testing - [ ] **Documentation**: `make docusaurus_start`; only needed if you make doc changes - [x] **Unit Tests**: `make go_develop_and_test` - [ ] **LocalNet E2E Tests**: `make test_e2e` - [x] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR. ## Sanity Checklist - [x] I have tested my changes using the available tooling - [ ] I have commented my code - [x] I have performed a self-review of my own code; both comments & source code - [ ] I create and reference any new tickets, if applicable - [ ] I have left TODOs throughout the codebase, if applicable --------- Co-authored-by: red-0ne --- .../keeper/msg_server_update_param.go | 10 ++++++++-- x/tokenomics/keeper/msg_update_params.go | 20 +++++++++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/x/tokenomics/keeper/msg_server_update_param.go b/x/tokenomics/keeper/msg_server_update_param.go index 92af35e30..643ee17a8 100644 --- a/x/tokenomics/keeper/msg_server_update_param.go +++ b/x/tokenomics/keeper/msg_server_update_param.go @@ -22,11 +22,17 @@ func (k msgServer) UpdateParam( ) if err := msg.ValidateBasic(); err != nil { - return nil, err + return nil, status.Error(codes.InvalidArgument, err.Error()) } if k.GetAuthority() != msg.Authority { - return nil, tokenomicstypes.ErrTokenomicsInvalidSigner.Wrapf("invalid authority; expected %s, got %s", k.GetAuthority(), msg.Authority) + return nil, status.Error( + codes.PermissionDenied, + tokenomicstypes.ErrTokenomicsInvalidSigner.Wrapf( + "invalid authority; expected %s, got %s", + k.GetAuthority(), msg.Authority, + ).Error(), + ) } params := k.GetParams(ctx) diff --git a/x/tokenomics/keeper/msg_update_params.go b/x/tokenomics/keeper/msg_update_params.go index cefb8e7d6..16e1bfe95 100644 --- a/x/tokenomics/keeper/msg_update_params.go +++ b/x/tokenomics/keeper/msg_update_params.go @@ -4,6 +4,9 @@ import ( "context" "fmt" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "github.com/pokt-network/poktroll/x/tokenomics/types" ) @@ -11,21 +14,26 @@ func (k msgServer) UpdateParams(ctx context.Context, msg *types.MsgUpdateParams) logger := k.Logger() if err := msg.ValidateBasic(); err != nil { - return nil, err + return nil, status.Error(codes.InvalidArgument, err.Error()) } if msg.Authority != k.GetAuthority() { - return nil, types.ErrTokenomicsInvalidSigner.Wrapf( - "invalid authority; expected %s, got %s", - k.GetAuthority(), - msg.Authority, + return nil, status.Error( + codes.PermissionDenied, + types.ErrTokenomicsInvalidSigner.Wrapf( + "invalid authority; expected %s, got %s", + k.GetAuthority(), + msg.Authority, + ).Error(), ) } logger.Info(fmt.Sprintf("About to update params from [%v] to [%v]", k.GetParams(ctx), msg.Params)) if err := k.SetParams(ctx, msg.Params); err != nil { - return nil, err + err = fmt.Errorf("unable to set params: %w", err) + logger.Error(err.Error()) + return nil, status.Error(codes.Internal, err.Error()) } logger.Info("Done updating params") From ac4c77986cc52f76b53c54da5ecc2b952cc672d6 Mon Sep 17 00:00:00 2001 From: Bryan White Date: Mon, 2 Dec 2024 14:16:05 +0100 Subject: [PATCH 21/21] chore: add localnet_config option to disable hot-reloading (#979) ## Summary Add a top-level `hot-reloading` boolean field to `localnet_config.yaml` in order to support easier disabling hot-reload. ## Issue There are times where hot-reloading is not desireable. In these instances, in the absence of such a config option, it takes 6 button clicks in the UI to accomplish the same result. - #N/A ## Type of change Select one or more from the following: - [ ] New feature, functionality or library - [ ] Consensus breaking; add the `consensus-breaking` label if so. See #791 for details - [ ] Bug fix - [ ] Code health or cleanup - [ ] Documentation - [ ] Other (specify) ## Testing - [ ] **Documentation**: `make docusaurus_start`; only needed if you make doc changes - [ ] **Unit Tests**: `make go_develop_and_test` - [ ] **LocalNet E2E Tests**: `make test_e2e` - [ ] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR. ## Sanity Checklist - [x] I have tested my changes using the available tooling - [ ] I have commented my code - [x] I have performed a self-review of my own code; both comments & source code - [ ] I create and reference any new tickets, if applicable - [ ] I have left TODOs throughout the codebase, if applicable --- Tiltfile | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/Tiltfile b/Tiltfile index bc0d78b92..03cf76bb4 100644 --- a/Tiltfile +++ b/Tiltfile @@ -26,6 +26,7 @@ def merge_dicts(base, updates): # environment is not broken for future engineers. localnet_config_path = "localnet_config.yaml" localnet_config_defaults = { + "hot-reloading": True, "validator": { "cleanupBeforeEachStart": True, "logs": { @@ -182,29 +183,30 @@ secret_create_generic( # Import configuration files into Kubernetes ConfigMap configmap_create("poktrolld-configs", from_file=listdir("localnet/poktrolld/config/"), watch=True) -# Hot reload protobuf changes -local_resource( - "hot-reload: generate protobufs", - "make proto_regen", - deps=["proto"], - labels=["hot-reloading"], -) -# Hot reload the poktrolld binary used by the k8s cluster -local_resource( - "hot-reload: poktrolld", - "GOOS=linux ignite chain build --skip-proto --output=./bin --debug -v", - deps=hot_reload_dirs, - labels=["hot-reloading"], - resource_deps=["hot-reload: generate protobufs"], -) -# Hot reload the local poktrolld binary used by the CLI -local_resource( - "hot-reload: poktrolld - local cli", - "ignite chain build --skip-proto --debug -v -o $(go env GOPATH)/bin", - deps=hot_reload_dirs, - labels=["hot-reloading"], - resource_deps=["hot-reload: generate protobufs"], -) +if localnet_config["hot-reloading"]: + # Hot reload protobuf changes + local_resource( + "hot-reload: generate protobufs", + "make proto_regen", + deps=["proto"], + labels=["hot-reloading"], + ) + # Hot reload the poktrolld binary used by the k8s cluster + local_resource( + "hot-reload: poktrolld", + "GOOS=linux ignite chain build --skip-proto --output=./bin --debug -v", + deps=hot_reload_dirs, + labels=["hot-reloading"], + resource_deps=["hot-reload: generate protobufs"], + ) + # Hot reload the local poktrolld binary used by the CLI + local_resource( + "hot-reload: poktrolld - local cli", + "ignite chain build --skip-proto --debug -v -o $(go env GOPATH)/bin", + deps=hot_reload_dirs, + labels=["hot-reloading"], + resource_deps=["hot-reload: generate protobufs"], + ) # Build an image with a poktrolld binary docker_build_with_restart(