Files
chia-blockchain/chia/cmds/start_funcs.py
Matt HauffandGitHub 40db4635a8 [LABS-245] Enable PEP604 Ruff rules (#20269)
* Enable PEP604 Ruff rules

* Fix harcoded signature in test

* Hack CLVMStreamable test with note to fast follow
2025-11-18 12:34:00 -08:00

110 lines
3.8 KiB
Python

from __future__ import annotations
import asyncio
import os
import shutil
import subprocess
import sys
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
from typing import Any
from chia.cmds.passphrase_funcs import get_current_passphrase
from chia.daemon.client import DaemonProxy, connect_to_daemon_and_validate
from chia.util.errors import KeychainMaxUnlockAttempts
from chia.util.keychain import Keychain
from chia.util.service_groups import services_for_groups
def launch_start_daemon(root_path: Path) -> subprocess.Popen:
os.environ["CHIA_ROOT"] = str(root_path)
creationflags = 0
if sys.platform == "win32":
creationflags = subprocess.CREATE_NEW_PROCESS_GROUP | subprocess.CREATE_NO_WINDOW
path_helper: Path = Path(sys.argv[0])
cmd_to_execute = None
if len(path_helper.suffix) == 0:
cmd_to_execute = shutil.which(cmd=path_helper.name, path=path_helper.parent)
if cmd_to_execute is None:
cmd_to_execute = sys.argv[0]
print(f"Starting daemon: {cmd_to_execute} run_daemon --wait-for-unlock", flush=True)
process = subprocess.Popen(
[cmd_to_execute, "run_daemon", "--wait-for-unlock"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
stdin=subprocess.DEVNULL,
creationflags=creationflags,
start_new_session=True,
)
return process
async def create_start_daemon_connection(
root_path: Path, config: dict[str, Any], *, skip_keyring: bool
) -> DaemonProxy | None:
connection = await connect_to_daemon_and_validate(root_path, config)
if connection is None:
print("Starting daemon", flush=True)
# launch a daemon
launch_start_daemon(root_path)
connection = await connect_to_daemon_and_validate(root_path, config, wait_for_start=True)
if connection:
if skip_keyring:
print("Skipping to unlock keyring")
else:
passphrase = None
if await connection.is_keyring_locked():
passphrase = Keychain.get_cached_master_passphrase()
if passphrase is None or not Keychain.master_passphrase_is_valid(passphrase):
with ThreadPoolExecutor(max_workers=1, thread_name_prefix="get_current_passphrase") as executor:
passphrase = await asyncio.get_running_loop().run_in_executor(executor, get_current_passphrase)
if passphrase:
print("Unlocking daemon keyring")
await connection.unlock_keyring(passphrase)
return connection
return None
async def async_start(
root_path: Path, config: dict[str, Any], group: tuple[str, ...], restart: bool, *, skip_keyring: bool
) -> None:
try:
daemon = await create_start_daemon_connection(root_path, config, skip_keyring=skip_keyring)
except KeychainMaxUnlockAttempts:
print("Failed to unlock keyring")
return None
if daemon is None:
print("Failed to create the chia daemon")
return None
for service in services_for_groups(group):
if await daemon.is_running(service_name=service):
print(f"{service}: ", end="", flush=True)
if restart:
if await daemon.stop_service(service_name=service):
print("stopped")
else:
print("stop failed")
else:
print("Already running, use `-r` to restart")
continue
print(f"{service}: ", end="", flush=True)
msg = await daemon.start_service(service_name=service)
success = msg and msg["data"]["success"]
if success is True:
print("started")
else:
error = "no response"
if msg:
error = msg["data"]["error"]
print(f"{service} failed to start. Error: {error}")
await daemon.close()