async def get_transactions(args: dict, wallet_client: WalletRpcClient, fingerprint: int) -> None: wallet_id = args["id"] paginate = args["paginate"] if paginate is None: paginate = sys.stdout.isatty() txs: List[TransactionRecord] = await wallet_client.get_transactions( wallet_id) config = load_config(DEFAULT_ROOT_PATH, "config.yaml", SERVICE_NAME) address_prefix = config["network_overrides"]["config"][ config["selected_network"]]["address_prefix"] if len(txs) == 0: print("There are no transactions to this address") try: wallet_type = await get_wallet_type(wallet_id=wallet_id, wallet_client=wallet_client) mojo_per_unit = get_mojo_per_unit(wallet_type=wallet_type) name = await get_name_for_wallet_id( config=config, wallet_type=wallet_type, wallet_id=wallet_id, wallet_client=wallet_client, ) except LookupError as e: print(e.args[0]) return offset = args["offset"] num_per_screen = 5 if paginate else len(txs) for i in range(offset, len(txs), num_per_screen): for j in range(0, num_per_screen): if i + j >= len(txs): break print_transaction( txs[i + j], verbose=(args["verbose"] > 0), name=name, address_prefix=address_prefix, mojo_per_unit=mojo_per_unit, ) if i + num_per_screen >= len(txs): return None print("Press q to quit, or c to continue") while True: entered_key = sys.stdin.read(1) if entered_key == "q": return None elif entered_key == "c": break
async def join_pool(args: dict, wallet_client: WalletRpcClient, fingerprint: int) -> None: config = load_config(DEFAULT_ROOT_PATH, "config.yaml") enforce_https = config["full_node"]["selected_network"] == "mainnet" pool_url: str = args["pool_url"] fee = Decimal(args.get("fee", 0)) fee_mojos = uint64(int(fee * units["chia"])) if enforce_https and not pool_url.startswith("https://"): print(f"Pool URLs must be HTTPS on mainnet {pool_url}. Aborting.") return wallet_id = args.get("id", None) prompt = not args.get("yes", False) try: async with aiohttp.ClientSession() as session: async with session.get(f"{pool_url}/pool_info", ssl=ssl_context_for_root( get_mozilla_ca_crt())) as response: if response.ok: json_dict = json.loads(await response.text()) else: print(f"Response not OK: {response.status}") return except Exception as e: print(f"Error connecting to pool {pool_url}: {e}") return if json_dict["relative_lock_height"] > 1000: print("Relative lock height too high for this pool, cannot join") return if json_dict["protocol_version"] != POOL_PROTOCOL_VERSION: print( f"Incorrect version: {json_dict['protocol_version']}, should be {POOL_PROTOCOL_VERSION}" ) return pprint(json_dict) msg = f"\nWill join pool: {pool_url} with Plot NFT {fingerprint}." func = functools.partial( wallet_client.pw_join_pool, wallet_id, hexstr_to_bytes(json_dict["target_puzzle_hash"]), pool_url, json_dict["relative_lock_height"], fee_mojos, ) await submit_tx_with_confirmation(msg, prompt, func, wallet_client, fingerprint, wallet_id)
def remove_plot_directory(root_path: Path, str_path: str) -> None: log.debug(f"remove_plot_directory {str_path}") config = load_config(root_path, "config.yaml") str_paths: List[str] = get_plot_directories(root_path, config) # If path str matches exactly, remove if str_path in str_paths: str_paths.remove(str_path) # If path matches full path, remove new_paths = [Path(sp).resolve() for sp in str_paths] if Path(str_path).resolve() in new_paths: new_paths.remove(Path(str_path).resolve()) config["harvester"]["plot_directories"] = [str(np) for np in new_paths] save_config(root_path, "config.yaml", config)
async def get_average_block_time(rpc_port: int) -> float: try: blocks_to_compare = 500 config = load_config(DEFAULT_ROOT_PATH, "config.yaml") self_hostname = config["self_hostname"] if rpc_port is None: rpc_port = config["full_node"]["rpc_port"] client = await FullNodeRpcClient.create(self_hostname, uint16(rpc_port), DEFAULT_ROOT_PATH, config) blockchain_state = await client.get_blockchain_state() curr: Optional[BlockRecord] = blockchain_state["peak"] if curr is None or curr.height < (blocks_to_compare + 100): client.close() await client.await_closed() return SECONDS_PER_BLOCK while curr is not None and curr.height > 0 and not curr.is_transaction_block: curr = await client.get_block_record(curr.prev_hash) if curr is None: client.close() await client.await_closed() return SECONDS_PER_BLOCK past_curr = await client.get_block_record_by_height(curr.height - blocks_to_compare) while past_curr is not None and past_curr.height > 0 and not past_curr.is_transaction_block: past_curr = await client.get_block_record(past_curr.prev_hash) if past_curr is None: client.close() await client.await_closed() return SECONDS_PER_BLOCK client.close() await client.await_closed() return (curr.timestamp - past_curr.timestamp) / (curr.height - past_curr.height) except Exception as e: if isinstance(e, aiohttp.ClientConnectorError): print( f"Connection error. Check if full node is running at {rpc_port}" ) else: print(f"Exception from 'full node' {e}") client.close() await client.await_closed() return SECONDS_PER_BLOCK
def test_load_config(self, root_path_populated_with_config, default_config_dict): """ Call load_config() with a default config and verify a few values are set to the expected values """ root_path: Path = root_path_populated_with_config # When: loading a newly created config config: Dict = load_config(root_path=root_path, filename="config.yaml") assert config is not None # Expect: config values should match the defaults (from a small sampling) assert config["daemon_port"] == default_config_dict["daemon_port"] == 55400 assert config["self_hostname"] == default_config_dict["self_hostname"] == "localhost" assert ( config["farmer"]["network_overrides"]["constants"]["mainnet"]["GENESIS_CHALLENGE"] == default_config_dict["farmer"]["network_overrides"]["constants"]["mainnet"]["GENESIS_CHALLENGE"] == "ccd5bb71183532bff220ba46c268991a3ff07eb358e8255a65c30a2dce0e5fbb" )
def read_and_compare_config(root_path: Path, default_config: Dict): """ Wait for a random amount of time, read the config and compare with the default config data. If the config file is partially-written or corrupt, load_config should fail or return bad data """ # Wait a moment. The read and write threads are delayed by a random amount # in an attempt to interleave their execution. sleep(random.random()) # log.warning(f"[pid:{os.getpid()}:{threading.get_ident()}] read_and_compare_config") config: Dict = load_config(root_path=root_path, filename="config.yaml") assert len(config) > 0 # if config != default_config: # log.error(f"[pid:{os.getpid()}:{threading.get_ident()}] bad config: {config}") # log.error(f"[pid:{os.getpid()}:{threading.get_ident()}] default config: {default_config}") assert config == default_config
async def set_payout_instructions(self, launcher_id: bytes32, payout_instructions: str): for p2_singleton_puzzle_hash, pool_state_dict in self.pool_state.items(): if launcher_id == pool_state_dict["pool_config"].launcher_id: config = load_config(self._root_path, "config.yaml") new_list = [] for list_element in config["pool"]["pool_list"]: if hexstr_to_bytes(list_element["launcher_id"]) == bytes(launcher_id): list_element["payout_instructions"] = payout_instructions new_list.append(list_element) config["pool"]["pool_list"] = new_list save_config(self._root_path, "config.yaml", config) # Force a GET /farmer which triggers the PUT /farmer if it detects the changed instructions pool_state_dict["next_farmer_update"] = 0 return self.log.warning(f"Launcher id: {launcher_id} not found")
def test_save_config(self, root_path_populated_with_config, default_config_dict): """ Test modifying the config and saving it to disk. The modified value(s) should be present after calling load_config(). """ root_path: Path = root_path_populated_with_config config: Dict = copy.deepcopy(default_config_dict) # When: modifying the config config["harvester"]["farmer_peer"]["host"] = "oldmacdonald.eie.io" # Sanity check that we didn't modify the default config assert config["harvester"]["farmer_peer"]["host"] != default_config_dict["harvester"]["farmer_peer"]["host"] # When: saving the modified config save_config(root_path=root_path, filename="config.yaml", config_data=config) # Expect: modifications should be preserved in the config read from disk loaded: Dict = load_config(root_path=root_path, filename="config.yaml") assert loaded["harvester"]["farmer_peer"]["host"] == "oldmacdonald.eie.io"
async def print_balances(args: dict, wallet_client: WalletRpcClient, fingerprint: int) -> None: summaries_response = await wallet_client.get_wallets() config = load_config(DEFAULT_ROOT_PATH, "config.yaml") address_prefix = config["network_overrides"]["config"][ config["selected_network"]]["address_prefix"] print(f"Wallet height: {await wallet_client.get_height_info()}") print(f"Balances, fingerprint: {fingerprint}") for summary in summaries_response: wallet_id = summary["id"] balances = await wallet_client.get_wallet_balance(wallet_id) typ = WalletType(int(summary["type"])).name if typ != "STANDARD_WALLET": print(f"Wallet ID {wallet_id} type {typ} {summary['name']}") print( f" -Confirmed: " f"{balances['confirmed_wallet_balance']/units['colouredcoin']}" ) print( f" -Confirmed - Pending Outgoing: {balances['unconfirmed_wallet_balance']/units['colouredcoin']}" ) print( f" -Spendable: {balances['spendable_balance']/units['colouredcoin']}" ) print( f" -Pending change: {balances['pending_change']/units['colouredcoin']}" ) else: print(f"Wallet ID {wallet_id} type {typ}") print( f" -Confirmed: {balances['confirmed_wallet_balance']} mojo " f"({balances['confirmed_wallet_balance']/units['chia']} {address_prefix})" ) print( f" -Unconfirmed: {balances['unconfirmed_wallet_balance']} mojo " f"({balances['unconfirmed_wallet_balance']/units['chia']} {address_prefix})" ) print( f" -Spendable: {balances['spendable_balance']} mojo " f"({balances['spendable_balance']/units['chia']} {address_prefix})" ) print( f" -Pending change: {balances['pending_change']} mojo " f"({balances['pending_change']/units['chia']} {address_prefix})" )
async def get_plots(farmer_rpc_port: int) -> Optional[Dict[str, Any]]: try: config = load_config(DEFAULT_ROOT_PATH, "config.yaml") self_hostname = config["self_hostname"] if farmer_rpc_port is None: farmer_rpc_port = config["farmer"]["rpc_port"] farmer_client = await FarmerRpcClient.create(self_hostname, uint16(farmer_rpc_port), DEFAULT_ROOT_PATH, config) plots = await farmer_client.get_plots() except Exception as e: if isinstance(e, aiohttp.ClientConnectorError): print(f"Connection error. Check if farmer is running at {farmer_rpc_port}") else: print(f"Exception from 'harvester' {e}") return None farmer_client.close() await farmer_client.await_closed() return plots
async def get_wallets_stats(wallet_rpc_port: int) -> Optional[Dict[str, Any]]: amounts = None try: config = load_config(DEFAULT_ROOT_PATH, "config.yaml") self_hostname = config["self_hostname"] if wallet_rpc_port is None: wallet_rpc_port = config["wallet"]["rpc_port"] wallet_client = await WalletRpcClient.create(self_hostname, uint16(wallet_rpc_port), DEFAULT_ROOT_PATH, config) amounts = await wallet_client.get_farmed_amount() # # Don't catch any exceptions, the caller will handle it # finally: wallet_client.close() await wallet_client.await_closed() return amounts
async def get_blockchain_state(rpc_port: int) -> Optional[Dict[str, Any]]: blockchain_state = None try: config = load_config(DEFAULT_ROOT_PATH, "config.yaml") self_hostname = config["self_hostname"] if rpc_port is None: rpc_port = config["full_node"]["rpc_port"] client = await FullNodeRpcClient.create(self_hostname, uint16(rpc_port), DEFAULT_ROOT_PATH, config) blockchain_state = await client.get_blockchain_state() except Exception as e: if isinstance(e, aiohttp.ClientConnectorError): print(f"Connection error. Check if full node is running at {rpc_port}") else: print(f"Exception from 'full node' {e}") client.close() await client.await_closed() return blockchain_state
async def get_wallets_stats(wallet_rpc_port: int) -> Optional[Dict[str, Any]]: amounts = None try: config = load_config(DEFAULT_ROOT_PATH, "config.yaml") self_hostname = config["self_hostname"] if wallet_rpc_port is None: wallet_rpc_port = config["wallet"]["rpc_port"] wallet_client = await WalletRpcClient.create(self_hostname, uint16(wallet_rpc_port), DEFAULT_ROOT_PATH, config) amounts = await wallet_client.get_farmed_amount() except Exception as e: if isinstance(e, aiohttp.ClientConnectorError): print(f"Connection error. Check if wallet is running at {wallet_rpc_port}") else: print(f"Exception from 'wallet' {e}") wallet_client.close() await wallet_client.await_closed() return amounts
def __init__(self, root_path: Path, ca_crt_path: Path, ca_key_path: Path, crt_path: Path, key_path: Path): self.root_path = root_path self.log = log self.services: Dict = dict() self.plots_queue: List[Dict] = [] self.connections: Dict[str, List[WebSocketServerProtocol]] = dict( ) # service_name : [WebSocket] self.remote_address_map: Dict[WebSocketServerProtocol, str] = dict() # socket: service_name self.ping_job: Optional[asyncio.Task] = None self.net_config = load_config(root_path, "config.yaml") self.self_hostname = self.net_config["self_hostname"] self.daemon_port = self.net_config["daemon_port"] self.websocket_server = None self.ssl_context = ssl_context_for_server(ca_crt_path, ca_key_path, crt_path, key_path) self.shut_down = False
async def is_farmer_running(farmer_rpc_port: int) -> bool: is_running = False try: config = load_config(DEFAULT_ROOT_PATH, "config.yaml") self_hostname = config["self_hostname"] if farmer_rpc_port is None: farmer_rpc_port = config["farmer"]["rpc_port"] farmer_client = await FarmerRpcClient.create(self_hostname, uint16(farmer_rpc_port), DEFAULT_ROOT_PATH, config) await farmer_client.get_connections() is_running = True except Exception as e: if isinstance(e, aiohttp.ClientConnectorError): print(f"Connection error. Check if farmer is running at {farmer_rpc_port}") else: print(f"Exception from 'farmer' {e}") farmer_client.close() await farmer_client.await_closed() return is_running
async def print_balances(args: dict, wallet_client: WalletRpcClient, fingerprint: int) -> None: summaries_response = await wallet_client.get_wallets() config = load_config(DEFAULT_ROOT_PATH, "config.yaml") address_prefix = config["network_overrides"]["config"][config["selected_network"]]["address_prefix"] print(f"Wallet height: {await wallet_client.get_height_info()}") print(f"Sync status: {'Synced' if (await wallet_client.get_synced()) else 'Not synced'}") print(f"Balances, fingerprint: {fingerprint}") for summary in summaries_response: wallet_id = summary["id"] balances = await wallet_client.get_wallet_balance(wallet_id) typ = WalletType(int(summary["type"])) address_prefix, scale = wallet_coin_unit(typ, address_prefix) print(f"Wallet ID {wallet_id} type {typ.name} {summary['name']}") print(f" -Total Balance: {print_balance(balances['confirmed_wallet_balance'], scale, address_prefix)}") print( f" -Pending Total Balance: {print_balance(balances['unconfirmed_wallet_balance'], scale, address_prefix)}" ) print(f" -Spendable: {print_balance(balances['spendable_balance'], scale, address_prefix)}")
def show_all_keys(show_mnemonic: bool): """ Prints all keys and mnemonics (if available). """ root_path = DEFAULT_ROOT_PATH config = load_config(root_path, "config.yaml") private_keys = keychain.get_all_private_keys() selected = config["selected_network"] prefix = config["network_overrides"]["config"][selected]["address_prefix"] if len(private_keys) == 0: print("There are no saved private keys") return msg = "Showing all public keys derived from your private keys:" if show_mnemonic: msg = "Showing all public and private keys" print(msg) for sk, seed in private_keys: print("") print("Fingerprint:", sk.get_g1().get_fingerprint()) print("Master public key (m):", sk.get_g1()) print( "Farmer public key (m/12381/8444/0/0):", master_sk_to_farmer_sk(sk).get_g1(), ) print("Pool public key (m/12381/8444/1/0):", master_sk_to_pool_sk(sk).get_g1()) print( "First wallet address:", encode_puzzle_hash( create_puzzlehash_for_pk( master_sk_to_wallet_sk(sk, uint32(0)).get_g1()), prefix), ) assert seed is not None if show_mnemonic: print("Master private key (m):", bytes(sk).hex()) print( "First wallet secret key (m/12381/8444/2/0):", master_sk_to_wallet_sk(sk, uint32(0)).get_g1(), ) mnemonic = bytes_to_mnemonic(seed) print(" Mnemonic seed (24 secret words):") print(mnemonic)
async def get_harvesters(farmer_rpc_port: int) -> Optional[List[str]]: harvester_hosts = [] try: config = load_config(DEFAULT_ROOT_PATH, "config.yaml") self_hostname = config["self_hostname"] if farmer_rpc_port is None: farmer_rpc_port = config["farmer"]["rpc_port"] farmer_client = await FarmerRpcClient.create(self_hostname, uint16(farmer_rpc_port), DEFAULT_ROOT_PATH, config) connections = await farmer_client.get_connections() for c in connections: if c['type'] == NodeType.HARVESTER: harvester_hosts.append(c['peer_host']) except Exception as e: print(f"Exception from 'farmer' {e}") farmer_client.close() await farmer_client.await_closed() return harvester_hosts
async def set_payout_instructions(self, launcher_id: bytes32, payout_instructions: str): for p2_singleton_puzzle_hash, pool_state_dict in self.pool_state.items( ): if launcher_id == pool_state_dict["pool_config"].launcher_id: config = load_config(self._root_path, "config.yaml") new_list = [] for list_element in config["pool"]["pool_list"]: if bytes.fromhex( list_element["launcher_id"]) == bytes(launcher_id): list_element[ "payout_instructions"] = payout_instructions new_list.append(list_element) config["pool"]["pool_list"] = new_list save_config(self._root_path, "config.yaml", config) await self.update_pool_state() return self.log.warning(f"Launcher id: {launcher_id} not found")
async def start_pool_server(): private_key: PrivateKey = AugSchemeMPL.key_gen(std_hash(b"123")) config = load_config(DEFAULT_ROOT_PATH, "config.yaml", "full_node") overrides = config["network_overrides"]["constants"][ config["selected_network"]] constants: ConsensusConstants = DEFAULT_CONSTANTS.replace_str_to_bytes( **overrides) server = PoolServer(private_key, config, constants) await server.start() # TODO: support TLS app = web.Application() app.add_routes([ web.get("/", server.wrap_http_handler(server.index)), web.get("/get_pool_info", server.wrap_http_handler(server.get_pool_info)), web.post("/submit_partial", server.wrap_http_handler(server.submit_partial)), ]) web.run_app(app)
def test_pool_config(): test_root = Path("/tmp") test_path = Path("/tmp/config") eg_config = test_path / "config.yaml" to_config = test_path / "test_pool_config.yaml" create_default_chia_config(test_root, ["config.yaml"]) assert eg_config.exists() eg_config.rename(to_config) config = load_config(test_root, "test_pool_config.yaml") auth_sk: PrivateKey = AugSchemeMPL.key_gen(b"1" * 32) d = { "authentication_public_key": bytes(auth_sk.get_g1()).hex(), "owner_public_key": "84c3fcf9d5581c1ddc702cb0f3b4a06043303b334dd993ab42b2c320ebfa98e5ce558448615b3f69638ba92cf7f43da5", "p2_singleton_puzzle_hash": "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", "payout_instructions": "c2b08e41d766da4116e388357ed957d04ad754623a915f3fd65188a8746cf3e8", "pool_url": "localhost", "launcher_id": "ae4ef3b9bfe68949691281a015a9c16630fc8f66d48c19ca548fb80768791afa", "target_puzzle_hash": "344587cf06a39db471d2cc027504e8688a0a67cce961253500c956c73603fd58", } pwc = PoolWalletConfig.from_json_dict(d) config_a = config.copy() config_b = config.copy() config_a["wallet"]["pool_list"] = [d] config_b["wallet"]["pool_list"] = [pwc.to_json_dict()] print(config["wallet"]["pool_list"]) save_config(test_root, "test_pool_config_a.yaml", config_a) save_config(test_root, "test_pool_config_b.yaml", config_b) assert config_a == config_b
async def connect_to_daemon_and_validate(root_path: Path) -> Optional[DaemonProxy]: """ Connect to the local daemon and do a ping to ensure that something is really there and running. """ try: net_config = load_config(root_path, "config.yaml") crt_path = root_path / net_config["daemon_ssl"]["private_crt"] key_path = root_path / net_config["daemon_ssl"]["private_key"] ca_crt_path = root_path / net_config["private_ssl_ca"]["crt"] ca_key_path = root_path / net_config["private_ssl_ca"]["key"] ssl_context = ssl_context_for_client(ca_crt_path, ca_key_path, crt_path, key_path) connection = await connect_to_daemon(net_config["self_hostname"], net_config["daemon_port"], ssl_context) r = await connection.ping() if "value" in r["data"] and r["data"]["value"] == "pong": return connection except Exception: print("Daemon not started yet") return None return None
def main(): root_path = DEFAULT_ROOT_PATH config = load_config(root_path, "config.yaml", SERVICE_NAME) initialize_logging(SERVICE_NAME, config["logging"], root_path) global D global ns global TTL global soa_record global ns_records D = DomainName(config["domain_name"]) ns = DomainName(config["nameserver"]) TTL = config["ttl"] soa_record = SOA( mname=ns, # primary name server rname=config["soa"]["rname"], # email of the domain administrator times=( config["soa"]["serial_number"], config["soa"]["refresh"], config["soa"]["retry"], config["soa"]["expire"], config["soa"]["minimum"], ), ) ns_records = [NS(ns)] def signal_received(): asyncio.create_task(kill_processes()) loop = asyncio.get_event_loop() try: loop.add_signal_handler(signal.SIGINT, signal_received) loop.add_signal_handler(signal.SIGTERM, signal_received) except NotImplementedError: log.info("signal handlers unsupported") try: loop.run_until_complete(serve_dns()) finally: loop.close()
def migrate_from( old_root: Path, new_root: Path, manifest: List[str], do_not_migrate_settings: List[str], ): """ Copy all the files in "manifest" to the new config directory. """ if old_root == new_root: print("same as new path, exiting") return 1 if not old_root.is_dir(): print( f"{old_root} not found - this is ok if you did not install this version" ) return 0 print(f"\n{old_root} found") print(f"Copying files from {old_root} to {new_root}\n") for f in manifest: old_path = old_root / f new_path = new_root / f copy_files_rec(old_path, new_path) # update config yaml with new keys config: Dict = load_config(new_root, "config.yaml") config_str: str = initial_config_file("config.yaml") default_config: Dict = yaml.safe_load(config_str) flattened_keys = unflatten_properties( {k: "" for k in do_not_migrate_settings}) dict_add_new_default(config, default_config, flattened_keys) save_config(new_root, "config.yaml", config) create_all_ssl(new_root) return 1
async def async_run_daemon(root_path: Path, wait_for_unlock: bool = False) -> int: # When wait_for_unlock is true, we want to skip the check_keys() call in chia_init # since it might be necessary to wait for the GUI to unlock the keyring first. chia_init(root_path, should_check_keys=(not wait_for_unlock)) config = load_config(root_path, "config.yaml") setproctitle("chia_daemon") initialize_logging("daemon", config["logging"], root_path) lockfile = singleton(daemon_launch_lock_path(root_path)) crt_path = root_path / config["daemon_ssl"]["private_crt"] key_path = root_path / config["daemon_ssl"]["private_key"] ca_crt_path = root_path / config["private_ssl_ca"]["crt"] ca_key_path = root_path / config["private_ssl_ca"]["key"] sys.stdout.flush() json_msg = dict_to_json_str( { "message": "cert_path", "success": True, "cert": f"{crt_path}", "key": f"{key_path}", "ca_crt": f"{ca_crt_path}", } ) sys.stdout.write("\n" + json_msg + "\n") sys.stdout.flush() if lockfile is None: print("daemon: already launching") return 2 # TODO: clean this up, ensuring lockfile isn't removed until the listen port is open create_server_for_daemon(root_path) ws_server = WebSocketServer( root_path, ca_crt_path, ca_key_path, crt_path, key_path, run_check_keys_on_unlock=wait_for_unlock ) await ws_server.start() assert ws_server.websocket_server is not None await ws_server.websocket_server.wait_closed() log.info("Daemon WebSocketServer closed") # sys.stdout.close() return 0
def __init__( self, config: Dict, root_path: Path, consensus_constants: ConsensusConstants, name: str = None, local_keychain: Optional[Keychain] = None, ): self.config = config self.constants = consensus_constants self.keychain_proxy = None self.local_keychain = local_keychain self.root_path = root_path self.base_config = load_config(root_path, "config.yaml") self.log = logging.getLogger(name if name else __name__) # Normal operation data self.cached_blocks: Dict = {} self.future_block_hashes: Dict = {} # Sync data self._shut_down = False self.proof_hashes: List = [] self.header_hashes: List = [] self.header_hashes_error = False self.short_sync_threshold = 15 # Change the test when changing this self.potential_blocks_received: Dict = {} self.potential_header_hashes: Dict = {} self.state_changed_callback = None self.wallet_state_manager = None self.backup_initialized = False # Delay first launch sync after user imports backup info or decides to skip self.server = None self.wsm_close_task = None self.sync_task: Optional[asyncio.Task] = None self.logged_in_fingerprint: Optional[int] = None self.peer_task = None self.logged_in = False self.wallet_peers_initialized = False self.last_new_peak_messages = LRUCache(5)
async def get_transactions(args: dict, wallet_client: WalletRpcClient, fingerprint: int) -> None: wallet_id = args["id"] txs: List[TransactionRecord] = await wallet_client.get_transactions(wallet_id) config = load_config(DEFAULT_ROOT_PATH, "config.yaml", SERVICE_NAME) name = config["network_overrides"]["config"][config["selected_network"]]["address_prefix"] if len(txs) == 0: print("There are no transactions to this address") num_per_screen = 5 for i in range(0, len(txs), num_per_screen): for j in range(0, num_per_screen): if i + j >= len(txs): break print_transaction(txs[i + j], verbose=(args["verbose"] > 0), name=name) if i + num_per_screen >= len(txs): return print("Press q to quit, or c to continue") while True: entered_key = sys.stdin.read(1) if entered_key == "q": return elif entered_key == "c": break
async def execute_with_wallet(wallet_rpc_port: int, fingerprint: int, extra_params: dict, function: Callable) -> None: try: config = load_config(DEFAULT_ROOT_PATH, "config.yaml") self_hostname = config["self_hostname"] if wallet_rpc_port is None: wallet_rpc_port = config["wallet"]["rpc_port"] wallet_client = await WalletRpcClient.create(self_hostname, uint16(wallet_rpc_port), DEFAULT_ROOT_PATH, config) wallet_client_f = await get_wallet(wallet_client, fingerprint=fingerprint) if wallet_client_f is None: wallet_client.close() await wallet_client.await_closed() return None wallet_client, fingerprint = wallet_client_f await function(extra_params, wallet_client, fingerprint) except KeyboardInterrupt: pass except Exception as e: if isinstance(e, aiohttp.ClientConnectorError): print(f"Connection error. Check if wallet is running at {wallet_rpc_port}") else: print(f"Exception from 'wallet' {e}") wallet_client.close() await wallet_client.await_closed()
def main(): root_path = DEFAULT_ROOT_PATH setproctitle("chia_timelord_launcher") net_config = load_config(root_path, "config.yaml") config = net_config["timelord_launcher"] initialize_logging("TLauncher", config["logging"], root_path) def signal_received(): asyncio.create_task(kill_processes()) loop = asyncio.get_event_loop() try: loop.add_signal_handler(signal.SIGINT, signal_received) loop.add_signal_handler(signal.SIGTERM, signal_received) except NotImplementedError: log.info("signal handlers unsupported") try: loop.run_until_complete(spawn_all_processes(config, net_config)) finally: log.info("Launcher fully closed.") loop.close()
def load_pool_config(root_path: Path) -> List[PoolWalletConfig]: config = load_config(root_path, "config.yaml") ret_list: List[PoolWalletConfig] = [] pool_list = config["pool"].get("pool_list", []) if pool_list is not None: for pool_config_dict in pool_list: try: pool_config = PoolWalletConfig( bytes32.from_hexstr(pool_config_dict["launcher_id"]), pool_config_dict["pool_url"], pool_config_dict["payout_instructions"], bytes32.from_hexstr( pool_config_dict["target_puzzle_hash"]), bytes32.from_hexstr( pool_config_dict["p2_singleton_puzzle_hash"]), G1Element.from_bytes( hexstr_to_bytes(pool_config_dict["owner_public_key"])), ) ret_list.append(pool_config) except Exception as e: log.error(f"Exception loading config: {pool_config_dict} {e}") return ret_list