|
| 1 | +from __future__ import annotations |
| 2 | + |
| 3 | +import os |
| 4 | +import pathlib |
| 5 | +import sys |
| 6 | +from multiprocessing import freeze_support |
| 7 | +from typing import Any, Optional |
| 8 | + |
| 9 | +from chia_rs import ConsensusConstants |
| 10 | +from chia_rs.sized_ints import uint16 |
| 11 | + |
| 12 | +from chia.apis import ApiProtocolRegistry |
| 13 | +from chia.consensus.constants import replace_str_to_bytes |
| 14 | +from chia.consensus.default_constants import DEFAULT_CONSTANTS, update_testnet_overrides |
| 15 | +from chia.full_node.full_node import FullNode |
| 16 | +from chia.full_node.full_node_api import FullNodeAPI |
| 17 | +from chia.full_node.full_node_rpc_api import FullNodeRpcApi |
| 18 | +from chia.protocols.outbound_message import NodeType |
| 19 | +from chia.server.aliases import FullNodeService |
| 20 | +from chia.server.signal_handlers import SignalHandlers |
| 21 | +from chia.server.start_service import RpcInfo, Service, async_run |
| 22 | +from chia.util.chia_logging import initialize_service_logging |
| 23 | +from chia.util.config import load_config, load_config_cli |
| 24 | +from chia.util.default_root import resolve_root_path |
| 25 | +from chia.util.task_timing import maybe_manage_task_instrumentation |
| 26 | + |
| 27 | +# See: https://bugs.python.org/issue29288 |
| 28 | +"".encode("idna") |
| 29 | + |
| 30 | +SERVICE_NAME = "solver" |
| 31 | + |
| 32 | + |
| 33 | +async def create_solver_service( |
| 34 | + root_path: pathlib.Path, |
| 35 | + config: dict[str, Any], |
| 36 | + consensus_constants: ConsensusConstants, |
| 37 | + connect_to_daemon: bool = True, |
| 38 | + override_capabilities: Optional[list[tuple[uint16, str]]] = None, |
| 39 | +) -> FullNodeService: |
| 40 | + service_config = config[SERVICE_NAME] |
| 41 | + |
| 42 | + network_id = service_config["selected_network"] |
| 43 | + upnp_list = [] |
| 44 | + if service_config["enable_upnp"]: |
| 45 | + upnp_list = [service_config["port"]] |
| 46 | + |
| 47 | + node = await FullNode.create( |
| 48 | + service_config, |
| 49 | + root_path=root_path, |
| 50 | + consensus_constants=consensus_constants, |
| 51 | + ) |
| 52 | + peer_api = FullNodeAPI(node) |
| 53 | + |
| 54 | + rpc_info: Optional[RpcInfo[FullNodeRpcApi]] = None |
| 55 | + if service_config.get("start_rpc_server", True): |
| 56 | + rpc_info = (FullNodeRpcApi, service_config["rpc_port"]) |
| 57 | + |
| 58 | + return Service( |
| 59 | + root_path=root_path, |
| 60 | + config=config, |
| 61 | + node=node, |
| 62 | + peer_api=peer_api, |
| 63 | + node_type=NodeType.SOLVER, |
| 64 | + advertised_port=service_config["port"], |
| 65 | + service_name=SERVICE_NAME, |
| 66 | + upnp_ports=upnp_list, |
| 67 | + # connect_peers=get_unresolved_peer_infos(service_config, NodeType.SOLVER), |
| 68 | + on_connect_callback=node.on_connect, |
| 69 | + network_id=network_id, |
| 70 | + rpc_info=rpc_info, |
| 71 | + connect_to_daemon=connect_to_daemon, |
| 72 | + override_capabilities=override_capabilities, |
| 73 | + class_for_type=ApiProtocolRegistry, |
| 74 | + ) |
| 75 | + |
| 76 | + |
| 77 | +async def async_main(service_config: dict[str, Any], root_path: pathlib.Path) -> int: |
| 78 | + # TODO: refactor to avoid the double load |
| 79 | + config = load_config(root_path, "config.yaml") |
| 80 | + config[SERVICE_NAME] = service_config |
| 81 | + network_id = service_config["selected_network"] |
| 82 | + overrides = service_config["network_overrides"]["constants"][network_id] |
| 83 | + update_testnet_overrides(network_id, overrides) |
| 84 | + updated_constants = replace_str_to_bytes(DEFAULT_CONSTANTS, **overrides) |
| 85 | + initialize_service_logging(service_name=SERVICE_NAME, config=config, root_path=root_path) |
| 86 | + |
| 87 | + service = await create_solver_service(root_path, config, updated_constants) |
| 88 | + async with SignalHandlers.manage() as signal_handlers: |
| 89 | + await service.setup_process_global_state(signal_handlers=signal_handlers) |
| 90 | + await service.run() |
| 91 | + |
| 92 | + return 0 |
| 93 | + |
| 94 | + |
| 95 | +def main() -> int: |
| 96 | + freeze_support() |
| 97 | + root_path = resolve_root_path(override=None) |
| 98 | + |
| 99 | + with maybe_manage_task_instrumentation( |
| 100 | + enable=os.environ.get(f"CHIA_INSTRUMENT_{SERVICE_NAME.upper()}") is not None |
| 101 | + ): |
| 102 | + service_config = load_config_cli(root_path, "config.yaml", SERVICE_NAME) |
| 103 | + # target_peer_count = service_config.get("target_peer_count", 40) - service_config.get( |
| 104 | + # "target_outbound_peer_count", 8 |
| 105 | + # ) |
| 106 | + # if target_peer_count < 0: |
| 107 | + # target_peer_count = None |
| 108 | + # if not service_config.get("use_chia_loop_policy", True): |
| 109 | + # target_peer_count = None |
| 110 | + return async_run(coro=async_main(service_config, root_path=root_path)) |
| 111 | + |
| 112 | + |
| 113 | +if __name__ == "__main__": |
| 114 | + sys.exit(main()) |
0 commit comments