Skip to content

Commit

Permalink
Add support for lists of peers in the config (#16376)
Browse files Browse the repository at this point in the history
Co-authored-by: Kyle Altendorf <[email protected]>
  • Loading branch information
felixbrucker and altendky authored Oct 24, 2023
1 parent 90c1441 commit ef98949
Show file tree
Hide file tree
Showing 11 changed files with 538 additions and 65 deletions.
30 changes: 18 additions & 12 deletions chia/cmds/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@

import click

from chia.util.config import load_defaults_for_missing_services, lock_and_load_config, save_config, str2bool
from chia.server.outbound_message import NodeType
from chia.util.config import (
load_defaults_for_missing_services,
lock_and_load_config,
save_config,
set_peer_info,
str2bool,
)


def configure(
Expand Down Expand Up @@ -51,18 +58,17 @@ def configure(
":".join(set_farmer_peer.split(":")[:-1]),
set_farmer_peer.split(":")[-1],
)
config["harvester"]["farmer_peer"]["host"] = host
config["harvester"]["farmer_peer"]["port"] = int(port)
set_peer_info(config["harvester"], peer_type=NodeType.FARMER, peer_host=host, peer_port=int(port))
print("Farmer peer updated, make sure your harvester has the proper cert installed")
change_made = True
except ValueError:
print("Farmer address must be in format [IP:Port]")
if set_fullnode_port:
config["full_node"]["port"] = int(set_fullnode_port)
config["full_node"]["introducer_peer"]["port"] = int(set_fullnode_port)
config["farmer"]["full_node_peer"]["port"] = int(set_fullnode_port)
config["timelord"]["full_node_peer"]["port"] = int(set_fullnode_port)
config["wallet"]["full_node_peer"]["port"] = int(set_fullnode_port)
set_peer_info(config["farmer"], peer_type=NodeType.FULL_NODE, peer_port=int(set_fullnode_port))
set_peer_info(config["timelord"], peer_type=NodeType.FULL_NODE, peer_port=int(set_fullnode_port))
set_peer_info(config["wallet"], peer_type=NodeType.FULL_NODE, peer_port=int(set_fullnode_port))
config["wallet"]["introducer_peer"]["port"] = int(set_fullnode_port)
config["introducer"]["port"] = int(set_fullnode_port)
print("Default full node port updated")
Expand Down Expand Up @@ -110,9 +116,9 @@ def configure(
config["wallet"]["introducer_peer"] = {}
assert config["wallet"]["introducer_peer"] is not None # mypy
config["full_node"]["introducer_peer"]["port"] = int(testnet_port)
config["farmer"]["full_node_peer"]["port"] = int(testnet_port)
config["timelord"]["full_node_peer"]["port"] = int(testnet_port)
config["wallet"]["full_node_peer"]["port"] = int(testnet_port)
set_peer_info(config["farmer"], peer_type=NodeType.FULL_NODE, peer_port=int(testnet_port))
set_peer_info(config["timelord"], peer_type=NodeType.FULL_NODE, peer_port=int(testnet_port))
set_peer_info(config["wallet"], peer_type=NodeType.FULL_NODE, peer_port=int(testnet_port))
config["wallet"]["introducer_peer"]["port"] = int(testnet_port)
config["introducer"]["port"] = int(testnet_port)
config["full_node"]["introducer_peer"]["host"] = testnet_introducer
Expand Down Expand Up @@ -148,9 +154,9 @@ def configure(
net = "mainnet"
config["full_node"]["port"] = int(mainnet_port)
config["full_node"]["introducer_peer"]["port"] = int(mainnet_port)
config["farmer"]["full_node_peer"]["port"] = int(mainnet_port)
config["timelord"]["full_node_peer"]["port"] = int(mainnet_port)
config["wallet"]["full_node_peer"]["port"] = int(mainnet_port)
set_peer_info(config["farmer"], peer_type=NodeType.FULL_NODE, peer_port=int(mainnet_port))
set_peer_info(config["timelord"], peer_type=NodeType.FULL_NODE, peer_port=int(mainnet_port))
set_peer_info(config["wallet"], peer_type=NodeType.FULL_NODE, peer_port=int(mainnet_port))
config["wallet"]["introducer_peer"]["port"] = int(mainnet_port)
config["introducer"]["port"] = int(mainnet_port)
config["full_node"]["introducer_peer"]["host"] = mainnet_introducer
Expand Down
5 changes: 3 additions & 2 deletions chia/cmds/sim_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
from chia.cmds.cmds_util import get_any_service_client
from chia.cmds.start_funcs import async_start
from chia.consensus.coinbase import create_puzzlehash_for_pk
from chia.server.outbound_message import NodeType
from chia.simulator.simulator_full_node_rpc_client import SimulatorFullNodeRpcClient
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.types.coin_record import CoinRecord
from chia.util.bech32m import decode_puzzle_hash, encode_puzzle_hash
from chia.util.config import load_config, save_config
from chia.util.config import load_config, save_config, set_peer_info
from chia.util.errors import KeychainFingerprintExists
from chia.util.ints import uint32
from chia.util.keychain import Keychain, bytes_to_mnemonic
Expand Down Expand Up @@ -90,7 +91,7 @@ def create_chia_directory(
config["full_node"]["port"] -= port_offset
config["full_node"]["rpc_port"] += port_offset
# connect wallet to full node
config["wallet"]["full_node_peer"]["port"] = config["full_node"]["port"]
set_peer_info(config["wallet"], peer_type=NodeType.FULL_NODE, peer_port=config["full_node"]["port"])
# ui
config["ui"]["daemon_port"] = config["daemon_port"]
else:
Expand Down
8 changes: 2 additions & 6 deletions chia/server/start_farmer.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@
from chia.rpc.farmer_rpc_api import FarmerRpcApi
from chia.server.outbound_message import NodeType
from chia.server.start_service import RpcInfo, Service, async_run
from chia.types.peer_info import UnresolvedPeerInfo
from chia.util.chia_logging import initialize_service_logging
from chia.util.config import load_config, load_config_cli
from chia.util.config import get_unresolved_peer_infos, load_config, load_config_cli
from chia.util.default_root import DEFAULT_ROOT_PATH
from chia.util.keychain import Keychain
from chia.util.misc import SignalHandlers
Expand All @@ -34,9 +33,6 @@ def create_farmer_service(
) -> Service[Farmer, FarmerAPI]:
service_config = config[SERVICE_NAME]

fnp = service_config.get("full_node_peer")
connect_peers = set() if fnp is None else {UnresolvedPeerInfo(fnp["host"], fnp["port"])}

network_id = service_config["selected_network"]
overrides = service_config["network_overrides"]["constants"][network_id]
update_testnet_overrides(network_id, overrides)
Expand All @@ -57,7 +53,7 @@ def create_farmer_service(
node_type=NodeType.FARMER,
advertised_port=service_config["port"],
service_name=SERVICE_NAME,
connect_peers=connect_peers,
connect_peers=get_unresolved_peer_infos(service_config, NodeType.FULL_NODE),
on_connect_callback=farmer.on_connect,
network_id=network_id,
rpc_info=rpc_info,
Expand Down
12 changes: 6 additions & 6 deletions chia/server/start_harvester.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import pathlib
import sys
from typing import Any, Dict, Optional
from typing import Any, Dict, Optional, Set

from chia.consensus.constants import ConsensusConstants
from chia.consensus.default_constants import DEFAULT_CONSTANTS
Expand All @@ -13,7 +13,7 @@
from chia.server.start_service import RpcInfo, Service, async_run
from chia.types.peer_info import UnresolvedPeerInfo
from chia.util.chia_logging import initialize_service_logging
from chia.util.config import load_config, load_config_cli
from chia.util.config import get_unresolved_peer_infos, load_config, load_config_cli
from chia.util.default_root import DEFAULT_ROOT_PATH
from chia.util.misc import SignalHandlers

Expand All @@ -27,7 +27,7 @@ def create_harvester_service(
root_path: pathlib.Path,
config: Dict[str, Any],
consensus_constants: ConsensusConstants,
farmer_peer: Optional[UnresolvedPeerInfo],
farmer_peers: Set[UnresolvedPeerInfo],
connect_to_daemon: bool = True,
) -> Service[Harvester, HarvesterAPI]:
service_config = config[SERVICE_NAME]
Expand All @@ -49,7 +49,7 @@ def create_harvester_service(
node_type=NodeType.HARVESTER,
advertised_port=None,
service_name=SERVICE_NAME,
connect_peers=set() if farmer_peer is None else {farmer_peer},
connect_peers=farmer_peers,
network_id=network_id,
rpc_info=rpc_info,
connect_to_daemon=connect_to_daemon,
Expand All @@ -62,8 +62,8 @@ async def async_main() -> int:
service_config = load_config_cli(DEFAULT_ROOT_PATH, "config.yaml", SERVICE_NAME)
config[SERVICE_NAME] = service_config
initialize_service_logging(service_name=SERVICE_NAME, config=config)
farmer_peer = UnresolvedPeerInfo(service_config["farmer_peer"]["host"], service_config["farmer_peer"]["port"])
service = create_harvester_service(DEFAULT_ROOT_PATH, config, DEFAULT_CONSTANTS, farmer_peer)
farmer_peers = get_unresolved_peer_infos(service_config, NodeType.FARMER)
service = create_harvester_service(DEFAULT_ROOT_PATH, config, DEFAULT_CONSTANTS, farmer_peers)
async with SignalHandlers.manage() as signal_handlers:
await service.setup_process_global_state(signal_handlers=signal_handlers)
await service.run()
Expand Down
9 changes: 2 additions & 7 deletions chia/server/start_timelord.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
from chia.server.start_service import RpcInfo, Service, async_run
from chia.timelord.timelord import Timelord
from chia.timelord.timelord_api import TimelordAPI
from chia.types.peer_info import UnresolvedPeerInfo
from chia.util.chia_logging import initialize_service_logging
from chia.util.config import load_config, load_config_cli
from chia.util.config import get_unresolved_peer_infos, load_config, load_config_cli
from chia.util.default_root import DEFAULT_ROOT_PATH
from chia.util.misc import SignalHandlers

Expand All @@ -34,10 +33,6 @@ def create_timelord_service(
connect_to_daemon: bool = True,
) -> Service[Timelord, TimelordAPI]:
service_config = config[SERVICE_NAME]

connect_peers = {
UnresolvedPeerInfo(service_config["full_node_peer"]["host"], service_config["full_node_peer"]["port"])
}
overrides = service_config["network_overrides"]["constants"][service_config["selected_network"]]
updated_constants = constants.replace_str_to_bytes(**overrides)

Expand All @@ -57,7 +52,7 @@ def create_timelord_service(
node_type=NodeType.TIMELORD,
advertised_port=None,
service_name=SERVICE_NAME,
connect_peers=connect_peers,
connect_peers=get_unresolved_peer_infos(service_config, NodeType.FULL_NODE),
network_id=network_id,
rpc_info=rpc_info,
connect_to_daemon=connect_to_daemon,
Expand Down
7 changes: 2 additions & 5 deletions chia/server/start_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@
from chia.rpc.wallet_rpc_api import WalletRpcApi
from chia.server.outbound_message import NodeType
from chia.server.start_service import RpcInfo, Service, async_run
from chia.types.peer_info import UnresolvedPeerInfo
from chia.util.chia_logging import initialize_service_logging
from chia.util.config import load_config, load_config_cli
from chia.util.config import get_unresolved_peer_infos, load_config, load_config_cli
from chia.util.default_root import DEFAULT_ROOT_PATH
from chia.util.keychain import Keychain
from chia.util.misc import SignalHandlers
Expand Down Expand Up @@ -49,8 +48,6 @@ def create_wallet_service(
local_keychain=keychain,
)
peer_api = WalletNodeAPI(node)
fnp = service_config.get("full_node_peer")
connect_peers = set() if fnp is None else {UnresolvedPeerInfo(fnp["host"], fnp["port"])}

network_id = service_config["selected_network"]
rpc_port = service_config.get("rpc_port")
Expand All @@ -66,7 +63,7 @@ def create_wallet_service(
node_type=NodeType.WALLET,
service_name=SERVICE_NAME,
on_connect_callback=node.on_connect,
connect_peers=connect_peers,
connect_peers=get_unresolved_peer_infos(service_config, NodeType.FULL_NODE),
network_id=network_id,
rpc_info=rpc_info,
advertised_port=None,
Expand Down
32 changes: 22 additions & 10 deletions chia/simulator/setup_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from chia.seeder.crawler_api import CrawlerAPI
from chia.seeder.dns_server import DNSServer, create_dns_server_service
from chia.seeder.start_crawler import create_full_node_crawler_service
from chia.server.outbound_message import NodeType
from chia.server.start_farmer import create_farmer_service
from chia.server.start_full_node import create_full_node_service
from chia.server.start_harvester import create_harvester_service
Expand All @@ -46,7 +47,7 @@
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.types.peer_info import UnresolvedPeerInfo
from chia.util.bech32m import encode_puzzle_hash
from chia.util.config import config_path_for_filename, load_config, lock_and_load_config, save_config
from chia.util.config import config_path_for_filename, load_config, lock_and_load_config, save_config, set_peer_info
from chia.util.ints import uint16
from chia.util.keychain import bytes_to_mnemonic
from chia.util.lock import Lockfile
Expand Down Expand Up @@ -309,11 +310,16 @@ async def setup_wallet_node(
service_config["introducer_peer"] = None

if full_node_port is not None:
service_config["full_node_peer"] = {}
service_config["full_node_peer"]["host"] = self_hostname
service_config["full_node_peer"]["port"] = full_node_port
service_config.pop("full_node_peer", None)
service_config["full_node_peers"] = [
{
"host": self_hostname,
"port": full_node_port,
},
]
else:
del service_config["full_node_peer"]
service_config.pop("full_node_peer", None)
service_config.pop("full_node_peers", None)

service = create_wallet_service(
local_bt.root_path,
Expand Down Expand Up @@ -375,7 +381,7 @@ async def setup_harvester(
root_path,
config,
consensus_constants,
farmer_peer=farmer_peer,
farmer_peers={farmer_peer} if farmer_peer is not None else set(),
connect_to_daemon=False,
)

Expand Down Expand Up @@ -414,10 +420,16 @@ async def setup_farmer(
config_pool["xch_target_address"] = encode_puzzle_hash(b_tools.pool_ph, "xch")

if full_node_port:
service_config["full_node_peer"]["host"] = self_hostname
service_config["full_node_peer"]["port"] = full_node_port
service_config.pop("full_node_peer", None)
service_config["full_node_peers"] = [
{
"host": self_hostname,
"port": full_node_port,
},
]
else:
del service_config["full_node_peer"]
service_config.pop("full_node_peer", None)
service_config.pop("full_node_peers", None)

service = create_farmer_service(
root_path,
Expand Down Expand Up @@ -534,7 +546,7 @@ async def setup_timelord(
vdf_port: uint16 = uint16(0),
) -> AsyncGenerator[Service[Timelord, TimelordAPI], None]:
service_config = config["timelord"]
service_config["full_node_peer"]["port"] = full_node_port
set_peer_info(service_config, peer_type=NodeType.FULL_NODE, peer_port=full_node_port)
service_config["bluebox_mode"] = sanitizer
service_config["fast_algorithm"] = False
service_config["vdf_server"]["port"] = vdf_port
Expand Down
39 changes: 38 additions & 1 deletion chia/util/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
import time
import traceback
from pathlib import Path
from typing import Any, Callable, Dict, Iterator, List, Optional, Union, cast
from typing import Any, Callable, Dict, Iterator, List, Optional, Set, Union, cast

import pkg_resources
import yaml
from typing_extensions import Literal

from chia.server.outbound_message import NodeType
from chia.types.peer_info import UnresolvedPeerInfo
from chia.util.lock import Lockfile

PEER_DB_PATH_KEY_DEPRECATED = "peer_db_path" # replaced by "peers_file_path"
Expand Down Expand Up @@ -328,3 +330,38 @@ def load_defaults_for_missing_services(config: Dict[str, Any], config_name: str)
defaulted[service]["selected_network"] = "".join(to_be_referenced)

return defaulted


PEER_INFO_MAPPING: Dict[NodeType, str] = {
NodeType.FULL_NODE: "full_node_peer",
NodeType.FARMER: "farmer_peer",
}


def get_unresolved_peer_infos(service_config: Dict[str, Any], peer_type: NodeType) -> Set[UnresolvedPeerInfo]:
peer_info_key = PEER_INFO_MAPPING[peer_type]
peer_infos: List[Dict[str, Any]] = service_config.get(f"{peer_info_key}s", [])
peer_info: Optional[Dict[str, Any]] = service_config.get(peer_info_key)
if peer_info is not None:
peer_infos.append(peer_info)

return {UnresolvedPeerInfo(host=peer["host"], port=peer["port"]) for peer in peer_infos}


def set_peer_info(
service_config: Dict[str, Any],
peer_type: NodeType,
peer_host: Optional[str] = None,
peer_port: Optional[int] = None,
) -> None:
peer_info_key = PEER_INFO_MAPPING[peer_type]
if peer_info_key in service_config:
if peer_host is not None:
service_config[peer_info_key]["host"] = peer_host
if peer_port is not None:
service_config[peer_info_key]["port"] = peer_port
elif f"{peer_info_key}s" in service_config and len(service_config[f"{peer_info_key}s"]) > 0:
if peer_host is not None:
service_config[f"{peer_info_key}s"][0]["host"] = peer_host
if peer_port is not None:
service_config[f"{peer_info_key}s"][0]["port"] = peer_port
Loading

0 comments on commit ef98949

Please sign in to comment.