Skip to content

Commit 0d187da

Browse files
authored
sync-validator-keys: Add fees distribution (#57)
* sync-validator-keys: Add fees distribution * Add prater alias for goerli network * Update FEE_DISTRIBUTION_CONTRACT_ADDRESS for mainnet
1 parent 6f811cd commit 0d187da

9 files changed

Lines changed: 129 additions & 55 deletions

stakewise_cli/commands/create_referrals_proposal.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,7 @@
99
from stakewise_cli.coingecko import get_average_range_price
1010
from stakewise_cli.eth1 import get_block_timestamp, get_referrals, get_web3_client
1111
from stakewise_cli.ipfs import upload_to_ipfs
12-
from stakewise_cli.networks import (
13-
GNOSIS_CHAIN,
14-
GOERLI,
15-
HARBOUR_GOERLI,
16-
HARBOUR_MAINNET,
17-
MAINNET,
18-
NETWORKS,
19-
)
12+
from stakewise_cli.networks import AVAILABLE_NETWORKS, MAINNET, NETWORKS
2013
from stakewise_cli.proposals import generate_referrals_swise_specification
2114
from stakewise_cli.queries import get_ethereum_gql_client, get_stakewise_gql_client
2215

@@ -36,7 +29,7 @@
3629
help="The network to generate the referral proposal for",
3730
prompt="Enter the network name",
3831
type=click.Choice(
39-
[MAINNET, GOERLI, HARBOUR_MAINNET, HARBOUR_GOERLI, GNOSIS_CHAIN],
32+
AVAILABLE_NETWORKS,
4033
case_sensitive=False,
4134
),
4235
)

stakewise_cli/commands/sync_db.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,7 @@
22
from eth_typing import ChecksumAddress
33

44
from stakewise_cli.eth2 import prompt_beacon_client, validate_mnemonic
5-
from stakewise_cli.networks import (
6-
GNOSIS_CHAIN,
7-
GOERLI,
8-
HARBOUR_GOERLI,
9-
HARBOUR_MAINNET,
10-
MAINNET,
11-
)
5+
from stakewise_cli.networks import AVAILABLE_NETWORKS, MAINNET
126
from stakewise_cli.storages.database import Database, check_db_connection
137
from stakewise_cli.validators import validate_db_uri, validate_operator_address
148
from stakewise_cli.web3signer import Web3SignerManager
@@ -21,7 +15,7 @@
2115
help="The network you are targeting.",
2216
prompt="Please choose the network name",
2317
type=click.Choice(
24-
[MAINNET, GOERLI, HARBOUR_MAINNET, HARBOUR_GOERLI, GNOSIS_CHAIN],
18+
AVAILABLE_NETWORKS,
2519
case_sensitive=False,
2620
),
2721
)

stakewise_cli/commands/sync_local.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,7 @@
44
from eth_typing import ChecksumAddress
55

66
from stakewise_cli.eth2 import validate_mnemonic
7-
from stakewise_cli.networks import (
8-
GNOSIS_CHAIN,
9-
GOERLI,
10-
HARBOUR_GOERLI,
11-
HARBOUR_MAINNET,
12-
MAINNET,
13-
)
7+
from stakewise_cli.networks import AVAILABLE_NETWORKS, MAINNET
148
from stakewise_cli.storages.local import LocalStorage
159
from stakewise_cli.validators import validate_operator_address
1610

@@ -22,7 +16,7 @@
2216
help="The network of ETH2 you are targeting.",
2317
prompt="Please choose the network name",
2418
type=click.Choice(
25-
[MAINNET, GOERLI, HARBOUR_MAINNET, HARBOUR_GOERLI, GNOSIS_CHAIN],
19+
AVAILABLE_NETWORKS,
2620
case_sensitive=False,
2721
),
2822
)

stakewise_cli/commands/sync_validator_keys.py

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,35 @@
1+
import json
12
import os
23
from os import mkdir
34
from os.path import exists, join
4-
from typing import List
5+
from typing import Dict, List
56

67
import click
78
import yaml
89

10+
from stakewise_cli.networks import AVAILABLE_NETWORKS, MAINNET, NETWORKS
911
from stakewise_cli.storages.database import Database, check_db_connection
1012
from stakewise_cli.utils import is_lists_equal
1113
from stakewise_cli.validators import validate_db_uri, validate_env_name
1214

1315
PUBLIC_KEYS_CSV_FILENAME = "validator_keys.csv"
1416
LIGHTHOUSE_CONFIG_FILENAME = "validator_definitions.yml"
1517
SIGNER_CONFIG_FILENAME = "signer_keys.yml"
18+
SIGNER_PROPOSER_CONFIG_FILENAME = "proposerConfig.json"
1619
WEB3SIGNER_URL_ENV = "WEB3SIGNER_URL"
1720

1821

1922
@click.command(help="Synchronizes validator public keys from the database")
23+
@click.option(
24+
"--network",
25+
default=MAINNET,
26+
help="The network to generate the deposit data for",
27+
prompt="Enter the network name",
28+
type=click.Choice(
29+
AVAILABLE_NETWORKS,
30+
case_sensitive=False,
31+
),
32+
)
2033
@click.option(
2134
"--db-url",
2235
help="The database connection address.",
@@ -39,8 +52,18 @@
3952
default=WEB3SIGNER_URL_ENV,
4053
callback=validate_env_name,
4154
)
55+
@click.option(
56+
"--solo-fees-file",
57+
help="The path to solo validator's fee distribution path",
58+
type=click.Path(exists=True, file_okay=True, dir_okay=False),
59+
)
4260
def sync_validator_keys(
43-
db_url: str, index: int, output_dir: str, web3signer_url_env: str
61+
network: str,
62+
db_url: str,
63+
index: int,
64+
output_dir: str,
65+
web3signer_url_env: str,
66+
solo_fees_file: str,
4467
) -> None:
4568
"""
4669
The command is running by the init container in validator pods.
@@ -67,10 +90,19 @@ def sync_validator_keys(
6790
)
6891
return
6992

93+
default_fee_recipient = NETWORKS[network]["FEE_DISTRIBUTION_CONTRACT_ADDRESS"]
94+
solo_fee_mapping = {}
95+
if solo_fees_file:
96+
with open(solo_fees_file) as f:
97+
solo_fee_mapping = json.load(f)
98+
7099
# save lighthouse config
71100
web3signer_url = os.environ[web3signer_url_env]
72101
lighthouse_config = _generate_lighthouse_config(
73-
public_keys=keys, web3signer_url=web3signer_url
102+
public_keys=keys,
103+
web3signer_url=web3signer_url,
104+
default_fee_recipient=default_fee_recipient,
105+
solo_fee_mapping=solo_fee_mapping,
74106
)
75107
with open(join(output_dir, LIGHTHOUSE_CONFIG_FILENAME), "w") as f:
76108
f.write(lighthouse_config)
@@ -79,6 +111,12 @@ def sync_validator_keys(
79111
signer_keys_config = _generate_signer_keys_config(public_keys=keys)
80112
with open(join(output_dir, SIGNER_CONFIG_FILENAME), "w") as f:
81113
f.write(signer_keys_config)
114+
proposer_config = _generate_proposer_config(
115+
default_fee_recipient=default_fee_recipient,
116+
solo_fee_mapping=solo_fee_mapping,
117+
)
118+
with open(join(output_dir, SIGNER_PROPOSER_CONFIG_FILENAME), "w") as f:
119+
f.write(proposer_config)
82120

83121
click.secho(
84122
f"The validator now uses {len(keys)} public keys.\n",
@@ -87,7 +125,12 @@ def sync_validator_keys(
87125
)
88126

89127

90-
def _generate_lighthouse_config(public_keys: List[str], web3signer_url: str) -> str:
128+
def _generate_lighthouse_config(
129+
public_keys: List[str],
130+
web3signer_url: str,
131+
default_fee_recipient: str,
132+
solo_fee_mapping: Dict[str, str],
133+
) -> str:
91134
"""
92135
Generate config for Lighthouse clients
93136
"""
@@ -97,6 +140,9 @@ def _generate_lighthouse_config(public_keys: List[str], web3signer_url: str) ->
97140
"voting_public_key": public_key,
98141
"type": "web3signer",
99142
"url": web3signer_url,
143+
"suggested_fee_recipient": solo_fee_mapping.get(
144+
public_key, default_fee_recipient
145+
),
100146
}
101147
for public_key in public_keys
102148
]
@@ -121,3 +167,31 @@ def _generate_signer_keys_config(public_keys: List[str]) -> str:
121167
"""
122168
keys = ",".join([f'"{public_key}"' for public_key in public_keys])
123169
return f"""validators-external-signer-public-keys: [{keys}]"""
170+
171+
172+
def _generate_proposer_config(
173+
default_fee_recipient: str, solo_fee_mapping: Dict[str, str]
174+
) -> str:
175+
"""
176+
Generate config for Teku and Prysm clients
177+
"""
178+
config = {
179+
"proposer_config": {
180+
**{
181+
public_key: {
182+
"fee_recipient": fee_recipient,
183+
"builder": {
184+
"enabled": True,
185+
},
186+
}
187+
for public_key, fee_recipient in solo_fee_mapping.items()
188+
}
189+
},
190+
"default_config": {
191+
"fee_recipient": default_fee_recipient,
192+
"builder": {
193+
"enabled": True,
194+
},
195+
},
196+
}
197+
return json.dumps(config)

stakewise_cli/commands/sync_vault.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,7 @@
55
from requests.exceptions import ConnectionError
66

77
from stakewise_cli.eth2 import prompt_beacon_client, validate_mnemonic
8-
from stakewise_cli.networks import (
9-
GNOSIS_CHAIN,
10-
GOERLI,
11-
HARBOUR_GOERLI,
12-
HARBOUR_MAINNET,
13-
MAINNET,
14-
)
8+
from stakewise_cli.networks import AVAILABLE_NETWORKS, MAINNET
159
from stakewise_cli.settings import VAULT_VALIDATORS_MOUNT_POINT
1610
from stakewise_cli.storages.vault import Vault
1711
from stakewise_cli.validators import validate_operator_address
@@ -38,7 +32,7 @@ def get_kubernetes_api_server() -> str:
3832
help="The network of ETH2 you are targeting.",
3933
prompt="Please choose the network name",
4034
type=click.Choice(
41-
[MAINNET, GOERLI, HARBOUR_MAINNET, HARBOUR_GOERLI, GNOSIS_CHAIN],
35+
AVAILABLE_NETWORKS,
4236
case_sensitive=False,
4337
),
4438
)

stakewise_cli/commands/upload_deposit_data.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,7 @@
1111
from stakewise_cli.eth2 import get_registered_public_keys, verify_deposit_data
1212
from stakewise_cli.ipfs import upload_to_ipfs
1313
from stakewise_cli.merkle_tree import MerkleTree
14-
from stakewise_cli.networks import (
15-
GNOSIS_CHAIN,
16-
GOERLI,
17-
HARBOUR_GOERLI,
18-
HARBOUR_MAINNET,
19-
MAINNET,
20-
NETWORKS,
21-
)
14+
from stakewise_cli.networks import AVAILABLE_NETWORKS, MAINNET, NETWORKS
2215
from stakewise_cli.queries import get_ethereum_gql_client, get_stakewise_gql_client
2316
from stakewise_cli.typings import Bytes4, Bytes32, Gwei, MerkleDepositData
2417
from stakewise_cli.validators import validate_operator_address_prompt
@@ -124,7 +117,7 @@ def process_file(
124117
help="The network of ETH2 you are targeting.",
125118
prompt="Please choose the network name",
126119
type=click.Choice(
127-
[MAINNET, GOERLI, HARBOUR_MAINNET, HARBOUR_GOERLI, GNOSIS_CHAIN],
120+
AVAILABLE_NETWORKS,
128121
case_sensitive=False,
129122
),
130123
)

stakewise_cli/commands/verify_deposit_data.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,7 @@
88
from stakewise_cli.eth2 import get_deposit_data_roots, get_registered_public_keys
99
from stakewise_cli.ipfs import ipfs_fetch
1010
from stakewise_cli.merkle_tree import MerkleTree
11-
from stakewise_cli.networks import (
12-
GNOSIS_CHAIN,
13-
GOERLI,
14-
HARBOUR_GOERLI,
15-
HARBOUR_MAINNET,
16-
MAINNET,
17-
NETWORKS,
18-
)
11+
from stakewise_cli.networks import AVAILABLE_NETWORKS, MAINNET, NETWORKS
1912
from stakewise_cli.queries import get_ethereum_gql_client
2013
from stakewise_cli.typings import Bytes32, Gwei
2114

@@ -32,7 +25,7 @@
3225
help="The network deposit data was generated for.",
3326
prompt="Please choose the network name",
3427
type=click.Choice(
35-
[MAINNET, GOERLI, HARBOUR_MAINNET, HARBOUR_GOERLI, GNOSIS_CHAIN],
28+
AVAILABLE_NETWORKS,
3629
case_sensitive=False,
3730
),
3831
)

stakewise_cli/networks.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
HARBOUR_GOERLI = "harbour_goerli"
77
GNOSIS_CHAIN = "gnosis"
88

9+
# aliases
10+
PRATER = "prater"
11+
912
NETWORKS = {
1013
MAINNET: dict(
1114
STAKEWISE_SUBGRAPH_URL=config(
@@ -29,6 +32,7 @@
2932
DAO_ENS_NAME="stakewise.eth",
3033
ENS_RESOLVER_CONTRACT_ADDRESS="0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41",
3134
SWISE_TOKEN_CONTRACT_ADDRESS="0x48C3399719B582dD63eB5AADf12A40B4C3f52FA2",
35+
FEE_DISTRIBUTION_CONTRACT_ADDRESS="0x6b333B20fBae3c5c0969dd02176e30802e2fbBdB",
3236
OPERATORS_COMMITTEE_ENS_KEY="operators_committee",
3337
IS_POA=False,
3438
),
@@ -54,6 +58,7 @@
5458
DAO_ENS_NAME="stakewise.eth",
5559
ENS_RESOLVER_CONTRACT_ADDRESS="0x4B1488B7a6B320d2D721406204aBc3eeAa9AD329",
5660
SWISE_TOKEN_CONTRACT_ADDRESS="0x0e2497aACec2755d831E4AFDEA25B4ef1B823855",
61+
FEE_DISTRIBUTION_CONTRACT_ADDRESS="0x6A9d30e05C6832E868390F155388c7d97A6faEAC",
5762
OPERATORS_COMMITTEE_ENS_KEY="operators_committee",
5863
IS_POA=True,
5964
),
@@ -79,6 +84,7 @@
7984
DAO_ENS_NAME="",
8085
ENS_RESOLVER_CONTRACT_ADDRESS="",
8186
SWISE_TOKEN_CONTRACT_ADDRESS="0x48C3399719B582dD63eB5AADf12A40B4C3f52FA2",
87+
FEE_DISTRIBUTION_CONTRACT_ADDRESS="0x0000000000000000000000000000000000000000",
8288
OPERATORS_COMMITTEE_ENS_KEY="",
8389
IS_POA=False,
8490
),
@@ -104,6 +110,7 @@
104110
DAO_ENS_NAME="",
105111
ENS_RESOLVER_CONTRACT_ADDRESS="",
106112
SWISE_TOKEN_CONTRACT_ADDRESS="0x0e2497aACec2755d831E4AFDEA25B4ef1B823855",
113+
FEE_DISTRIBUTION_CONTRACT_ADDRESS="0x0000000000000000000000000000000000000000",
107114
OPERATORS_COMMITTEE_ENS_KEY="",
108115
IS_POA=True,
109116
),
@@ -127,7 +134,13 @@
127134
DAO_ENS_NAME="",
128135
ENS_RESOLVER_CONTRACT_ADDRESS="",
129136
SWISE_TOKEN_CONTRACT_ADDRESS="0xfdA94F056346d2320d4B5E468D6Ad099b2277746",
137+
FEE_DISTRIBUTION_CONTRACT_ADDRESS="0x0000000000000000000000000000000000000000",
130138
OPERATORS_COMMITTEE_ENS_KEY="",
131139
IS_POA=True,
132140
),
133141
}
142+
143+
# Alias
144+
NETWORKS[PRATER] = NETWORKS[GOERLI]
145+
146+
AVAILABLE_NETWORKS = NETWORKS.keys()

0 commit comments

Comments
 (0)