Skip to content

Commit

Permalink
[Docs] Document (non-)custodial staking (#720)
Browse files Browse the repository at this point in the history
## Summary

Follow-up to #716 to document custodial and non-custodial staking
configuration.

## Issue


![image](https://github.com/user-attachments/assets/671278e9-911f-43d9-b7eb-e7994b959b72)

- #493

## Type of change

Select one or more:

- [ ] New feature, functionality or library
- [ ] Bug fix
- [ ] Code health or cleanup
- [x] Documentation
- [ ] Other (specify)

## Testing

**Documentation changes** (only if making doc changes)
- [x] `make docusaurus_start`; only needed if you make doc changes

**Local Testing** (only if making code changes)
- [ ] **Unit Tests**: `make go_develop_and_test`
- [ ] **LocalNet E2E Tests**: `make test_e2e`
- See [quickstart
guide](https://dev.poktroll.com/developer_guide/quickstart) for
instructions

**PR Testing** (only if making code changes)
- [ ] **DevNet E2E Tests**: Add the `devnet-test-e2e` label to the PR.
- **THIS IS VERY EXPENSIVE**, so only do it after all the reviews are
complete.
- Optionally run `make trigger_ci` if you want to re-trigger tests
without any code changes
- If tests fail, try re-running failed tests only using the GitHub UI as
shown
[here](https://github.com/pokt-network/poktroll/assets/1892194/607984e9-0615-4569-9452-4c730190c1d2)


## 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


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Enhanced command for supplier unstake, improving usability and
flexibility.
- Introduced new sections in documentation for "Staking types,"
detailing Custodial and Non-Custodial Staking.

- **Documentation**
- Expanded configuration documentation with detailed explanations of
`owner_address` and `operator_address`.

- **Config Updates**
- Added `owner_address` and `operator_address` parameters to multiple
staking configuration files for improved clarity.

- **Improvements**
- Streamlined configuration files by removing comments, enhancing
clarity on staking roles.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
red-0ne authored Aug 27, 2024
1 parent de840e8 commit cc70f65
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ supplier3_stake: ## Stake supplier3

.PHONY: supplier_unstake
supplier_unstake: ## Unstake an supplier (must specify the SUPPLIER env var)
poktrolld --home=$(POKTROLLD_HOME) tx supplier unstake-supplier --keyring-backend test --from $(SUPPLIER) --node $(POCKET_NODE)
poktrolld --home=$(POKTROLLD_HOME) tx supplier unstake-supplier $(SUPPLIER) --keyring-backend test --from $(SUPPLIER) --node $(POCKET_NODE)

.PHONY: supplier1_unstake
supplier1_unstake: ## Unstake supplier1
Expand Down
141 changes: 139 additions & 2 deletions docusaurus/docs/operate/configs/supplier_staking_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ a stake transaction required to provide RPC services on Pocket Network._

- [Reference Example](#reference-example)
- [Usage](#usage)
- [Staking types](#staking-types)
- [Custodial Staking](#custodial-staking)
- [Non-Custodial Staking](#non-custodial-staking)
- [Configuration](#configuration)
- [`owner_address`](#owner_address)
- [`operator_address`](#operator_address)
- [`stake_amount`](#stake_amount)
- [`default_rev_share_percent`](#default_rev_share_percent)
- [`services`](#services)
Expand Down Expand Up @@ -44,20 +48,153 @@ poktrolld tx supplier stake-supplier \
--node tcp://poktroll-node:26657
```

## Staking types

The `Supplier` staking command supports `Custodial` and `Non-Custodial` staking
which can be illustrated in the following flowchart:

```mermaid
flowchart TD
AWF(["Account with funds <br> owner_address"])
ISC{Is custodial?}
US[Unstake]
AWF -- stake --> ISC
ISC -- yes --> CS
ISC -- no --> NCS
subgraph CS[Custodial Staking]
direction LR
subgraph S1[Supplier]
OW1["address: owner_address"]
end
subgraph RM1[RelayMiner]
OW2["address: owner_address"]
end
S1 --- RM1
end
subgraph NCS[Non Custodial Staking]
direction LR
subgraph S2[Supplier]
OW21["address: owner_address"]
end
subgraph RM2[RelayMiner]
OP22["address: operator_address"]
end
S2 -.- RM2
end
CS ---> |owner_address| US
NCS ---> |owner_address or operator_address| US
US -- funds --> OWA{{owner_address}}
US -- remove on-chain record --> OPA{{owner_address or operator_address}}
classDef owner fill:#f9f, stroke:#333, stroke-width:2px, color:#222;
classDef operator fill:#eba69a, color: #333, stroke:#333, stroke-width:2px;
class OW1,OW2,OW21,AWF owner
class OP22 operator
```

### Custodial Staking

The owner of the `Supplier` is the same as the operator.
This means the account that receives the rewards is the same as the one that
signs the `RelayResponse`s and submits claims and proofs.

Custodial staking is the simplest to set up and manage, as there is no need to
manage multiple accounts. It is suitable for `Supplier`s that do not have concerns
about using the private key of the staking or the rewarded account to operate the
`RelayMiner` or update the `Supplier`'s stake and services.

### Non-Custodial Staking

The owner of the `Supplier` is different from the operator.
This means the account that receives the rewards is different from the one signing
the `RelayResponse`s and submitting claims and proofs.

Non-custodial staking is suitable for `Supplier`s that want to separate the `RelayMiner`
staking operations from the account that has custody over the staked funds, and in turn,
the rewards being earned.

:::note

When staking a `Supplier`, the signing account specified with the `--from` flag
(which may differ from the `Supplier`'s owner or operator) will have its `upokt`
balance deducted to stake the `Supplier`.

When unstaking a `Supplier`, the staked `upokt` will be returned to the `owner_address`
account.

:::

## Configuration

### `owner_address`

_`Required`_, _`Non-empty`_
_`Required`_

```yaml
owner_address: <address>
```
The `owner_address` is used as the unique shareholder address for the `Supplier`
The `owner_address` is the address of the account that owns the `Supplier`s staked
funds, which will be transferred to this account's balannce when the `Supplier`
unstakes and finishes unbonding.

For custodial staking, the `owner_address` is the same as the `operator_address`.

For non-custodial staking, the `owner_address` MUST be different from the `operator_address`.
This address receives the staked `upokt` when the `Supplier` is unstaked and finished unbonding.

The `owner_address` can only be changed with a stake message signed by the
`Supplier`'s owner account.
It is also used as the unique shareholder address for the `Supplier`
if none of `default_rev_share_percent` or `rev_share_percent` is defined in the
configuration file.
:::note
The `owner_address` does not identify a `Supplier`; multiple `Supplier`s can have
the same `owner_address`.
:::
### `operator_address`
_`Optional`_
```yaml
operator_address: <address>
```
The `operator_address` is the address that identifies the `Supplier`.
Its corresponding account is used for operational tasks such as signing `RelayResponse`s,
submitting `Claims` and `Proofs` as well as updating the `Supplier`'s info
(i.e. Adding or removing services, increasing the stake amount, etc.)

The operator account can also be used to unstake the `Supplier`, which will cause
the staked `upokt` to be sent to the `owner_address` after unbonding finishes.

If the `operator_address` is empty or not specified, the `owner_address` is used
as the `operator_address`.

If the `operator_address` is the same as the `owner_address`, then the staking
is custodial.

:::warning

Since the `operator_address` is the unique identifier of a `Supplier`, it cannot
be changed once the `Supplier` is created. If it needs to be changed, then the
corresponding `Supplier` has to be unstaked and a new one staked with the new
`operator_address`.

:::

### `stake_amount`

_`Required`_, _`Non-empty`_
Expand Down
13 changes: 1 addition & 12 deletions localnet/poktrolld/config/supplier1_stake_config.yaml
Original file line number Diff line number Diff line change
@@ -1,26 +1,15 @@
owner_address: pokt1mrqt5f7qh8uxs27cjm9t7v9e74a9vvdnq5jva4
# NB: The stake amount is exactly 1upokt greater than the value in genesis.json
# so that the stake command causes a state change.
operator_address: pokt1mrqt5f7qh8uxs27cjm9t7v9e74a9vvdnq5jva4
stake_amount: 1000069upokt
# If default_rev_share_percent is omitted, the owner receives 100% of the rewards.
# default_rev_share_percent cannot be empty - it must either be omitted completely
# or include at least one item.
default_rev_share_percent:
# The sum of all shares must equal 100%. Staking will fail otherwise.
- pokt1mrqt5f7qh8uxs27cjm9t7v9e74a9vvdnq5jva4: 80.5
- pokt1eeeksh2tvkh7wzmfrljnhw4wrhs55lcuvmekkw: 19.5
services:
# The endpoint URL for the Anvil service is provided via the RelayMiner.
# The RelayMiner acts as a proxy, forwarding requests to the actual Anvil data node behind it.
# This setup allows for flexible and dynamic service provisioning within the network.
- service_id: anvil
endpoints:
- publicly_exposed_url: http://relayminer1:8545
rpc_type: JSON_RPC
- service_id: ollama
# Service specific rev share, if rev_share_percent is omitted for a specific
# service, default_rev_share_percent is used.
# The sum of all shares must equal 100%. Staking will fail otherwise.
rev_share_percent:
- pokt1mrqt5f7qh8uxs27cjm9t7v9e74a9vvdnq5jva4: 50
- pokt1eeeksh2tvkh7wzmfrljnhw4wrhs55lcuvmekkw: 50
Expand Down
5 changes: 2 additions & 3 deletions localnet/poktrolld/config/supplier2_stake_config.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
owner_address: pokt1re27pw4llwnatx4sq7rlggqzcm6j3f39epq2wa
operator_address: pokt1re27pw4llwnatx4sq7rlggqzcm6j3f39epq2wa
stake_amount: 1000070upokt
services:
- service_id: anvil
endpoints:
# The endpoint URL for the Anvil service is provided via the RelayMiner.
# The RelayMiner acts as a proxy, forwarding requests to the actual Anvil data node behind it.
# This setup allows for flexible and dynamic service provisioning within the network.
- publicly_exposed_url: http://relayminer2:8545
rpc_type: JSON_RPC
- service_id: ollama
Expand Down
5 changes: 2 additions & 3 deletions localnet/poktrolld/config/supplier3_stake_config.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
owner_address: pokt1j6dun0x8eyq5mmsmq83zs3c2utt85q8478c89u
operator_address: pokt1j6dun0x8eyq5mmsmq83zs3c2utt85q8478c89u
stake_amount: 1000071upokt
services:
- service_id: anvil
endpoints:
# The endpoint URL for the Anvil service is provided via the RelayMiner.
# The RelayMiner acts as a proxy, forwarding requests to the actual Anvil data node behind it.
# This setup allows for flexible and dynamic service provisioning within the network.
- publicly_exposed_url: http://relayminer3:8545
rpc_type: JSON_RPC
- service_id: ollama
Expand Down
52 changes: 52 additions & 0 deletions localnet/poktrolld/config/supplier_stake_config_example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# This file is used to stake a Supplier or update an existing Supplier's information in the Pocket Network.
# Pocket Network supports two types of staking mechanisms: custodial and non-custodial staking:
# * Custodial staking is the default mechanism, where the owner address (i.e., the account that
# receives the rewards) is the same as the operator address (i.e., the address that operates
# the Supplier).
# * Non-custodial staking is an advanced mechanism, where the owner address is different from
# the operator address. This is useful to avoid overuse of the private key of the
# account that owns the staked funds and receives the rewards.

# The address of the supplier's owner. This address could stake a new Supplier or
# update any of its properties excluding the operator address which is immutable.
# The account corresponding to this address could also unstake the Suppliers it owns.
# The owner address does not identify the Supplier in the Pocket Network; the same owner
# account can stake multiple Suppliers.
owner_address: pokt19a3t4yunp0dlpfjrp7qwnzwlrzd5fzs2gjaaaj

# The address of the operator of the Supplier. This address operates the Supplier,
# (i.e., signs relay responses, submits claims and proofs, updates service endpoints, etc.).
# This address can also used to stake a new Supplier or unstake an existing one.
# It uniquely identifies the Supplier in the Pocket Network and cannot be changed
# once the Supplier is created.
# The operator address is optional; if it is empty or not provided, the owner
# address is used as the operator address.
operator_address: pokt19a3t4yunp0dlpfjrp7qwnzwlrzd5fzs2gjaaaj
# NB: The stake amount is exactly 1upokt greater than the value in genesis.json
# so that the stake command causes a state change.
stake_amount: 1000069upokt
# If default_rev_share_percent is omitted, the owner receives 100% of the rewards.
# default_rev_share_percent cannot be empty - it MUST either be omitted completely
# or include at least one item.
default_rev_share_percent:
# The sum of all shares MUST equal 100%. Staking will fail otherwise.
- pokt1mrqt5f7qh8uxs27cjm9t7v9e74a9vvdnq5jva4: 80.5
- pokt1eeeksh2tvkh7wzmfrljnhw4wrhs55lcuvmekkw: 19.5
services:
# The endpoint URL for the Anvil service is provided via the RelayMiner.
# The RelayMiner acts as a proxy, forwarding requests to the actual Anvil data node behind it.
# This setup allows for flexible and dynamic service provisioning within the network.
- service_id: anvil
endpoints:
- publicly_exposed_url: http://relayminer1:8545
rpc_type: JSON_RPC
- service_id: ollama
# Service specific rev share, if rev_share_percent is omitted for a specific
# service, default_rev_share_percent is used.
# The sum of all shares MUST equal 100%. Staking will fail otherwise.
rev_share_percent:
- pokt1mrqt5f7qh8uxs27cjm9t7v9e74a9vvdnq5jva4: 50
- pokt1eeeksh2tvkh7wzmfrljnhw4wrhs55lcuvmekkw: 50
endpoints:
- publicly_exposed_url: http://relayminer1:8545
rpc_type: REST
8 changes: 6 additions & 2 deletions x/supplier/module/tx_stake_supplier.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ func CmdStakeSupplier() *cobra.Command {
cmd := &cobra.Command{
Use: "stake-supplier --config <config_file.yaml>",
Short: "Stake a supplier",
Long: `Stake an supplier with the provided parameters. This is a broadcast operation that
will stake the tokens and associate them with the supplier specified by the 'from' address.
Long: `Stake a supplier using the specified configuration file. This command
supports both custodial and non-custodial staking of the signer's tokens.
It sources the necessary information from the provided configuration file.
For more details on the staking process, please refer to the supplier staking documentation at:
https://dev.poktroll.com/operate/configs/supplier_staking_config
Example:
$ poktrolld tx supplier stake-supplier --config stake_config.yaml --keyring-backend test --from $(OWNER_ADDRESS) --node $(POCKET_NODE) --home $(POKTROLLD_HOME)`,
Expand Down

0 comments on commit cc70f65

Please sign in to comment.