Skip to content

Commit

Permalink
Add permissioned goerli network (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
tsudmi authored Feb 20, 2022
1 parent f195b64 commit df350e9
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 76 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Operator CLI

Operators CLI generates validators keys and deposit data for the validators.
The validator keys have to be uploaded to the Hashicorp Vault for the secure storage.
Read more about operators onboarding process [here](https://docs.stakewise.io/node-operator/dao-proposal)
The validator keys have to be uploaded to the Hashicorp Vault or fetched locally.
Read more about [operators onboarding process](https://docs.stakewise.io/node-operator/onboarding-process)

## Usage

Expand All @@ -12,7 +12,7 @@ See [releases page](https://github.com/stakewise/cli/releases) to download and d

### Step 2. Create Deposit Data

Run the following command to generate the DAO proposal specification:
Run the following command to create deposit data and DAO proposal specification:

```bash
./operator-cli create-deposit-data
Expand All @@ -28,7 +28,7 @@ In your post you must include the `Specification` section that was generated in

### Step 4. Deploy ETH2 infrastructure

If the proposal from the previous step got approved by the DAO, follow the instructions [here](https://docs.stakewise.io/node-operator/stakewise-infra-package)
If the proposal from the previous step got approved by the DAO, follow the instructions [here](https://docs.stakewise.io/node-operator/stakewise-infra-package/usage)
to deploy the ETH2 staking infrastructure.

### Step 5. Sync keys to the Vault or locally
Expand All @@ -48,13 +48,13 @@ or to sync them locally
./operator-cli sync-local
```

After uploading the keys, make sure you have the right number of validators running and restart those that got new keys added.
After fetching the keys, make sure you have the right number of validators running and restart those that got new keys added.

### Step 6. Commit Operator

Once you're 100% ready for Ether assignments, commit your operator:

- Go to the Operators smart contract ([Goerli](https://goerli.etherscan.io/address/0x0d92156861a0BC7037cC21470327Bd3Bc750EB1D#writeProxyContract), [Mainnet](https://etherscan.io/address/0x002932e11E95DC84C17ed5f94a0439645D8a97BC))
- Go to the Operators smart contract ([Goerli](https://goerli.etherscan.io/address/0x0d92156861a0BC7037cC21470327Bd3Bc750EB1D#writeProxyContract), [Perm Goerli](https://goerli.etherscan.io/address/0x7C27896338e3130036E53BCC0f013cB20e21991c#writeProxyContract), [Mainnet](https://etherscan.io/address/0x002932e11E95DC84C17ed5f94a0439645D8a97BC))
- Click on `Connect to Web3` button and connect your wallet. The address must match the one used during proposal generation.
- Call `commitOperator` function. If that's your onboarding, you must deposit 1 ETH (specified in Wei) collateral together with the call.

Expand Down
44 changes: 22 additions & 22 deletions operator_cli/commands/create_deposit_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,18 @@
validate_mnemonic,
)
from operator_cli.ipfs import upload_deposit_data_to_ipfs
from operator_cli.networks import (
ETHEREUM_GOERLI,
ETHEREUM_MAINNET,
GNOSIS_CHAIN,
NETWORKS,
)
from operator_cli.networks import GNOSIS_CHAIN, GOERLI, MAINNET, NETWORKS, PERM_GOERLI
from operator_cli.queries import get_ethereum_gql_client, get_stakewise_gql_client


@click.command(help="Creates deposit data and generates a forum post specification")
@click.option(
"--network",
default=ETHEREUM_MAINNET,
default=MAINNET,
help="The network to generate the deposit data for",
prompt="Enter the network name",
type=click.Choice(
[ETHEREUM_MAINNET, ETHEREUM_GOERLI, GNOSIS_CHAIN], case_sensitive=False
[MAINNET, GOERLI, PERM_GOERLI, GNOSIS_CHAIN], case_sensitive=False
),
)
@click.option(
Expand Down Expand Up @@ -90,13 +85,15 @@ def create_deposit_data(

# 4. Generate private key shares for the committee
sw_gql_client = get_stakewise_gql_client(network)
committee_paths = create_committee_shares(
network=network,
gql_client=sw_gql_client,
operator=operator,
committee_folder=committee_folder,
keypairs=keypairs,
)
if network != PERM_GOERLI:
# no private key shares form permissioned network
committee_paths = create_committee_shares(
network=network,
gql_client=sw_gql_client,
operator=operator,
committee_folder=committee_folder,
keypairs=keypairs,
)

# 5. Upload deposit data to IPFS
ipfs_url = upload_deposit_data_to_ipfs(deposit_data)
Expand All @@ -117,10 +114,13 @@ def create_deposit_data(
click.echo(specification)

# 7. Generate committee message
click.secho(
"Share the encrypted validator key shares with the committee members through Telegram:",
bold=True,
fg="green",
)
for username, path in committee_paths.items():
click.echo(f"- @{username}: {path}")
if network != PERM_GOERLI:
# no private key shares form permissioned network
click.secho(
"Share the encrypted validator key shares with the committee members through Telegram:",
bold=True,
fg="green",
)
# noinspection PyUnboundLocalVariable
for username, path in committee_paths.items():
click.echo(f"- @{username}: {path}")
11 changes: 3 additions & 8 deletions operator_cli/commands/sync_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@
from web3 import Web3

from operator_cli.eth2 import get_beacon_client, validate_mnemonic
from operator_cli.networks import (
ETHEREUM_GOERLI,
ETHEREUM_MAINNET,
GNOSIS_CHAIN,
NETWORKS,
)
from operator_cli.networks import GNOSIS_CHAIN, GOERLI, MAINNET, NETWORKS, PERM_GOERLI
from operator_cli.storages.local import LocalStorage


Expand All @@ -29,11 +24,11 @@ def validate_operator_address(ctx, param, value):
@click.command(help="Synchronizes validator keystores to the local folder")
@click.option(
"--network",
default=ETHEREUM_MAINNET,
default=MAINNET,
help="The network of ETH2 you are targeting.",
prompt="Please choose the network name",
type=click.Choice(
[ETHEREUM_MAINNET, ETHEREUM_GOERLI, GNOSIS_CHAIN], case_sensitive=False
[MAINNET, GOERLI, PERM_GOERLI, GNOSIS_CHAIN], case_sensitive=False
),
)
@click.option(
Expand Down
11 changes: 3 additions & 8 deletions operator_cli/commands/sync_vault.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@
from web3 import Web3

from operator_cli.eth2 import get_beacon_client, validate_mnemonic
from operator_cli.networks import (
ETHEREUM_GOERLI,
ETHEREUM_MAINNET,
GNOSIS_CHAIN,
NETWORKS,
)
from operator_cli.networks import GNOSIS_CHAIN, GOERLI, MAINNET, NETWORKS, PERM_GOERLI
from operator_cli.settings import VAULT_VALIDATORS_MOUNT_POINT
from operator_cli.storages.vault import Vault

Expand Down Expand Up @@ -44,11 +39,11 @@ def validate_operator_address(ctx, param, value):
@click.command(help="Synchronizes validator keystores in the vault")
@click.option(
"--network",
default=ETHEREUM_MAINNET,
default=MAINNET,
help="The network of ETH2 you are targeting.",
prompt="Please choose the network name",
type=click.Choice(
[ETHEREUM_MAINNET, ETHEREUM_GOERLI, GNOSIS_CHAIN], case_sensitive=False
[MAINNET, GOERLI, PERM_GOERLI, GNOSIS_CHAIN], case_sensitive=False
),
)
@click.option(
Expand Down
11 changes: 3 additions & 8 deletions operator_cli/commands/upload_deposit_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,7 @@
from operator_cli.eth2 import verify_deposit_data
from operator_cli.ipfs import upload_deposit_data_to_ipfs
from operator_cli.merkle_tree import MerkleTree
from operator_cli.networks import (
ETHEREUM_GOERLI,
ETHEREUM_MAINNET,
GNOSIS_CHAIN,
NETWORKS,
)
from operator_cli.networks import GNOSIS_CHAIN, GOERLI, MAINNET, NETWORKS, PERM_GOERLI
from operator_cli.queries import (
REGISTRATIONS_QUERY,
get_ethereum_gql_client,
Expand Down Expand Up @@ -162,11 +157,11 @@ def check_public_keys_not_registered(
)
@click.option(
"--network",
default=ETHEREUM_MAINNET,
default=MAINNET,
help="The network of ETH2 you are targeting.",
prompt="Please choose the network name",
type=click.Choice(
[ETHEREUM_MAINNET, ETHEREUM_GOERLI, GNOSIS_CHAIN], case_sensitive=False
[MAINNET, GOERLI, PERM_GOERLI, GNOSIS_CHAIN], case_sensitive=False
),
)
@click.option(
Expand Down
4 changes: 2 additions & 2 deletions operator_cli/eth1.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from operator_cli.contracts import get_ens_node_id, get_ens_resolver, get_web3_client
from operator_cli.ipfs import ipfs_fetch
from operator_cli.networks import ETHEREUM_MAINNET, GNOSIS_CHAIN, NETWORKS
from operator_cli.networks import GNOSIS_CHAIN, MAINNET, NETWORKS
from operator_cli.queries import OPERATOR_QUERY, VALIDATORS_QUERY


Expand Down Expand Up @@ -63,7 +63,7 @@ def get_operators_committee(network: str) -> List[List[str]]:
"""Fetches committee config from the DAO's ENS text record."""
# XXX: ENS does not support gnosis chain
if network == GNOSIS_CHAIN:
network = ETHEREUM_MAINNET
network = MAINNET

w3 = get_web3_client(network)
ens_resolver = get_ens_resolver(network, w3)
Expand Down
35 changes: 30 additions & 5 deletions operator_cli/networks.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from decouple import config

ETHEREUM_MAINNET = "mainnet"
ETHEREUM_GOERLI = "goerli"
MAINNET = "mainnet"
GOERLI = "goerli"
PERM_GOERLI = "perm_goerli"
GNOSIS_CHAIN = "gnosis"

NETWORKS = {
ETHEREUM_MAINNET: dict(
MAINNET: dict(
STAKEWISE_SUBGRAPH_URL=config(
"STAKEWISE_SUBGRAPH_URL",
default="https://api.thegraph.com/subgraphs/name/stakewise/stakewise-mainnet",
Expand All @@ -29,7 +30,7 @@
OPERATORS_COMMITTEE_ENS_KEY="operators_committee",
IS_POA=False,
),
ETHEREUM_GOERLI: dict(
GOERLI: dict(
STAKEWISE_SUBGRAPH_URL=config(
"STAKEWISE_SUBGRAPH_URL",
default="https://api.thegraph.com/subgraphs/name/stakewise/stakewise-goerli",
Expand All @@ -45,14 +46,38 @@
GENESIS_FORK_VERSION=bytes.fromhex("00001020"),
MAX_KEYS_PER_VALIDATOR=100,
ETH1_ENDPOINT=config(
"WITHDRAWAL_CREDENTIALS",
"ETH1_ENDPOINT",
default="https://goerli.infura.io/v3/84842078b09946638c03157f83405213",
),
DAO_ENS_NAME="stakewise.eth",
ENS_RESOLVER_CONTRACT_ADDRESS="0x4B1488B7a6B320d2D721406204aBc3eeAa9AD329",
OPERATORS_COMMITTEE_ENS_KEY="operators_committee",
IS_POA=True,
),
PERM_GOERLI: dict(
STAKEWISE_SUBGRAPH_URL=config(
"STAKEWISE_SUBGRAPH_URL",
default="https://api.thegraph.com/subgraphs/name/stakewise/stakewise-perm-goerli",
),
ETHEREUM_SUBGRAPH_URL=config(
"ETHEREUM_SUBGRAPH_URL",
default="https://api.thegraph.com/subgraphs/name/stakewise/ethereum-goerli",
),
WITHDRAWAL_CREDENTIALS=config(
"WITHDRAWAL_CREDENTIALS",
default="0x0100000000000000000000006dfc9682e3c3263758ad96e2b2ba9822167f81ee",
),
GENESIS_FORK_VERSION=bytes.fromhex("00001020"),
MAX_KEYS_PER_VALIDATOR=100,
ETH1_ENDPOINT=config(
"ETH1_ENDPOINT",
default="https://goerli.infura.io/v3/84842078b09946638c03157f83405213",
),
DAO_ENS_NAME="",
ENS_RESOLVER_CONTRACT_ADDRESS="0x4B1488B7a6B320d2D721406204aBc3eeAa9AD329",
OPERATORS_COMMITTEE_ENS_KEY="",
IS_POA=True,
),
GNOSIS_CHAIN: dict(
STAKEWISE_SUBGRAPH_URL=config(
"STAKEWISE_SUBGRAPH_URL",
Expand Down
32 changes: 16 additions & 16 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "operator-cli"
version = "0.1.0"
version = "1.0.0"
description = "StakeWise Operator CLI is used to generate and manage ETH2 validator keys."
authors = ["Dmitri Tsumak <[email protected]>"]
license = "AGPL-3.0-only"
Expand Down

0 comments on commit df350e9

Please sign in to comment.