From e3a016cf5f3581dea9c71f6ccbe6b0357109ef9a Mon Sep 17 00:00:00 2001 From: wallentx Date: Mon, 7 Mar 2022 16:01:49 -0600 Subject: [PATCH 01/28] Adding chia peer command --- chia/cmds/chia.py | 2 + chia/cmds/peer.py | 181 ++++++++++++++++++++++++++++ chia/cmds/show.py | 248 +++++++++++++++++++------------------- chia/cmds/wallet_funcs.py | 2 +- 4 files changed, 308 insertions(+), 125 deletions(-) create mode 100644 chia/cmds/peer.py diff --git a/chia/cmds/chia.py b/chia/cmds/chia.py index 9825964f649f..3fb6e28ab8bb 100644 --- a/chia/cmds/chia.py +++ b/chia/cmds/chia.py @@ -8,6 +8,7 @@ from chia.cmds.keys import keys_cmd from chia.cmds.netspace import netspace_cmd from chia.cmds.passphrase import passphrase_cmd +from chia.cmds.peer import peer_cmd from chia.cmds.plots import plots_cmd from chia.cmds.show import show_cmd from chia.cmds.start import start_cmd @@ -138,6 +139,7 @@ def run_daemon_cmd(ctx: click.Context, wait_for_unlock: bool) -> None: cli.add_command(farm_cmd) cli.add_command(plotters_cmd) cli.add_command(db_cmd) +cli.add_command(peer_cmd) if supports_keyring_passphrase(): cli.add_command(passphrase_cmd) diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py new file mode 100644 index 000000000000..16f9e29a9dae --- /dev/null +++ b/chia/cmds/peer.py @@ -0,0 +1,181 @@ +from typing import Dict +from typing import Any, Optional, Union, Dict + +import click + +from chia.util.network import is_trusted_inner + + +async def print_connections(client, time, NodeType, trusted_peers: Dict): + connections = await client.get_connections() + print("Connections:") + print("Type IP Ports NodeID Last Connect" + " MiB Up|Dwn") + for con in connections: + last_connect_tuple = time.struct_time(time.localtime(con["last_message_time"])) + last_connect = time.strftime("%b %d %T", last_connect_tuple) + mb_down = con["bytes_read"] / (1024 * 1024) + mb_up = con["bytes_written"] / (1024 * 1024) + + host = con["peer_host"] + # Strip IPv6 brackets + host = host.strip("[]") + + trusted: bool = is_trusted_inner(host, con["node_id"], trusted_peers, False) + # Nodetype length is 9 because INTRODUCER will be deprecated + if NodeType(con["type"]) is NodeType.FULL_NODE: + peak_height = con.get("peak_height", None) + connection_peak_hash = con.get("peak_hash", None) + if connection_peak_hash is None: + connection_peak_hash = "No Info" + else: + if connection_peak_hash.startswith(("0x", "0X")): + connection_peak_hash = connection_peak_hash[2:] + connection_peak_hash = f"{connection_peak_hash[:8]}..." + con_str = ( + f"{NodeType(con['type']).name:9} {host:38} " + f"{con['peer_port']:5}/{con['peer_server_port']:<5}" + f" {con['node_id'].hex()[:8]}... " + f"{last_connect} " + f"{mb_up:7.1f}|{mb_down:<7.1f}" + f"\n " + ) + if peak_height is not None: + con_str += f"-Height: {peak_height:8.0f} -Hash: {connection_peak_hash} -Trusted: {trusted}" + else: + con_str += f"-Height: No Info -Hash: {connection_peak_hash} -Trusted: {trusted}" + else: + con_str = ( + f"{NodeType(con['type']).name:9} {host:38} " + f"{con['peer_port']:5}/{con['peer_server_port']:<5}" + f" {con['node_id'].hex()[:8]}... " + f"{last_connect} " + f"{mb_up:7.1f}|{mb_down:<7.1f}" + ) + print(con_str) + + +async def peer_async( + show_connections: bool, + add_connection: str, + remove_connection: str, + rpc_port: Optional[int], +) -> None: + import aiohttp + import traceback + import time + from chia.rpc.full_node_rpc_client import FullNodeRpcClient + from chia.server.outbound_message import NodeType + from chia.util.config import load_config + from chia.util.default_root import DEFAULT_ROOT_PATH + from chia.util.ints import uint16 + + try: + config = load_config(DEFAULT_ROOT_PATH, "config.yaml") + self_hostname = config["self_hostname"] + rpc_port = config["full_node"]["rpc_port"] + client = await FullNodeRpcClient.create(self_hostname, uint16(rpc_port), DEFAULT_ROOT_PATH, config) + + if show_connections: + trusted_peers: Dict = config["full_node"].get("trusted_peers", {}) + await print_connections(client, time, NodeType, trusted_peers) + if add_connection: + if ":" not in add_connection: + print("Enter a valid IP and port in the following format: 10.5.4.3:8000") + else: + ip, port = ( + ":".join(add_connection.split(":")[:-1]), + add_connection.split(":")[-1], + ) + print(f"Connecting to {ip}, {port}") + try: + await client.open_connection(ip, int(port)) + except Exception: + print(f"Failed to connect to {ip}:{port}") + if remove_connection: + result_txt = "" + if len(remove_connection) != 8: + result_txt = "Invalid NodeID. Do not include '.'" + else: + connections = await client.get_connections() + for con in connections: + if remove_connection == con["node_id"].hex()[:8]: + print("Attempting to disconnect", "NodeID", remove_connection) + try: + await client.close_connection(con["node_id"]) + except Exception: + result_txt = f"Failed to disconnect NodeID {remove_connection}" + else: + result_txt = f"NodeID {remove_connection}... {NodeType(con['type']).name} " + f"{con['peer_host']} disconnected" + elif result_txt == "": + result_txt = f"NodeID {remove_connection}... not found" + print(result_txt) + except Exception as e: + if isinstance(e, aiohttp.ClientConnectorError): + print(f"Connection error. Check if full node rpc is running at {rpc_port}") + print("This is normal if full node is still starting up") + else: + tb = traceback.format_exc() + print(f"Exception from 'peer' {tb}") + + client.close() + await client.await_closed() + + +@click.command("peer", short_help="Show, or modify peering connections") +@click.option( + "-c", + "--connections", + help="List nodes connected to this Full Node", + is_flag=True, + type=bool, + default=True +) +@click.option( + "-a", + "--add-connection", + help="Connect to another Full Node by ip:port", + type=str, + default="" +) +@click.option( + "-r", + "--remove-connection", + help="Remove a Node by the first 8 characters of NodeID", + type=str, + default="" +) +@click.option( + "-p", + "--rpc-port", + help=( + "Set the port where the Full Node is hosting the RPC interface. " + "See the rpc_port under full_node in config.yaml" + ), + type=int, + default=None, +) +@click.option( + "-wp", + "--wallet-rpc-port", + help="Set the port where the Wallet is hosting the RPC interface. See the rpc_port under wallet in config.yaml", + type=int, + default=None, +) +def peer_cmd( + connections: bool, + add_connection: str, + remove_connection: str, + rpc_port: Optional[int], + wallet_rpc_port: Optional[int], +) -> None: + import asyncio + + asyncio.run( + peer_async( + connections, + add_connection, + remove_connection, + rpc_port, + ) + ) \ No newline at end of file diff --git a/chia/cmds/show.py b/chia/cmds/show.py index ed03ef72b7e7..f50dca534cac 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -6,64 +6,64 @@ from chia.util.network import is_trusted_inner -async def print_connections(client, time, NodeType, trusted_peers: Dict): - connections = await client.get_connections() - print("Connections:") - print("Type IP Ports NodeID Last Connect" + " MiB Up|Dwn") - for con in connections: - last_connect_tuple = time.struct_time(time.localtime(con["last_message_time"])) - last_connect = time.strftime("%b %d %T", last_connect_tuple) - mb_down = con["bytes_read"] / (1024 * 1024) - mb_up = con["bytes_written"] / (1024 * 1024) +# async def print_connections(client, time, NodeType, trusted_peers: Dict): +# connections = await client.get_connections() +# print("Connections:") +# print("Type IP Ports NodeID Last Connect" + " MiB Up|Dwn") +# for con in connections: +# last_connect_tuple = time.struct_time(time.localtime(con["last_message_time"])) +# last_connect = time.strftime("%b %d %T", last_connect_tuple) +# mb_down = con["bytes_read"] / (1024 * 1024) +# mb_up = con["bytes_written"] / (1024 * 1024) - host = con["peer_host"] - # Strip IPv6 brackets - host = host.strip("[]") +# host = con["peer_host"] +# # Strip IPv6 brackets +# host = host.strip("[]") - trusted: bool = is_trusted_inner(host, con["node_id"], trusted_peers, False) - # Nodetype length is 9 because INTRODUCER will be deprecated - if NodeType(con["type"]) is NodeType.FULL_NODE: - peak_height = con.get("peak_height", None) - connection_peak_hash = con.get("peak_hash", None) - if connection_peak_hash is None: - connection_peak_hash = "No Info" - else: - if connection_peak_hash.startswith(("0x", "0X")): - connection_peak_hash = connection_peak_hash[2:] - connection_peak_hash = f"{connection_peak_hash[:8]}..." - con_str = ( - f"{NodeType(con['type']).name:9} {host:38} " - f"{con['peer_port']:5}/{con['peer_server_port']:<5}" - f" {con['node_id'].hex()[:8]}... " - f"{last_connect} " - f"{mb_up:7.1f}|{mb_down:<7.1f}" - f"\n " - ) - if peak_height is not None: - con_str += f"-Height: {peak_height:8.0f} -Hash: {connection_peak_hash}" - else: - con_str += f"-Height: No Info -Hash: {connection_peak_hash}" - # Only show when Trusted is True - if trusted: - con_str += f" -Trusted: {trusted}" - else: - con_str = ( - f"{NodeType(con['type']).name:9} {host:38} " - f"{con['peer_port']:5}/{con['peer_server_port']:<5}" - f" {con['node_id'].hex()[:8]}... " - f"{last_connect} " - f"{mb_up:7.1f}|{mb_down:<7.1f}" - ) - print(con_str) +# trusted: bool = is_trusted_inner(host, con["node_id"], trusted_peers, False) +# # Nodetype length is 9 because INTRODUCER will be deprecated +# if NodeType(con["type"]) is NodeType.FULL_NODE: +# peak_height = con.get("peak_height", None) +# connection_peak_hash = con.get("peak_hash", None) +# if connection_peak_hash is None: +# connection_peak_hash = "No Info" +# else: +# if connection_peak_hash.startswith(("0x", "0X")): +# connection_peak_hash = connection_peak_hash[2:] +# connection_peak_hash = f"{connection_peak_hash[:8]}..." +# con_str = ( +# f"{NodeType(con['type']).name:9} {host:38} " +# f"{con['peer_port']:5}/{con['peer_server_port']:<5}" +# f" {con['node_id'].hex()[:8]}... " +# f"{last_connect} " +# f"{mb_up:7.1f}|{mb_down:<7.1f}" +# f"\n " +# ) +# if peak_height is not None: +# con_str += f"-Height: {peak_height:8.0f} -Hash: {connection_peak_hash}" +# else: +# con_str += f"-Height: No Info -Hash: {connection_peak_hash}" +# # Only show when Trusted is True +# if trusted: +# con_str += f" -Trusted: {trusted}" +# else: +# con_str = ( +# f"{NodeType(con['type']).name:9} {host:38} " +# f"{con['peer_port']:5}/{con['peer_server_port']:<5}" +# f" {con['node_id'].hex()[:8]}... " +# f"{last_connect} " +# f"{mb_up:7.1f}|{mb_down:<7.1f}" +# ) +# print(con_str) async def show_async( - rpc_port: Optional[int], + # rpc_port: Optional[int], state: bool, - show_connections: bool, + # show_connections: bool, exit_node: bool, - add_connection: str, - remove_connection: str, + # add_connection: str, + # remove_connection: str, block_header_hash_by_height: str, block_by_header_hash: str, ) -> None: @@ -163,49 +163,49 @@ async def show_async( print("Blockchain has no blocks yet") # if called together with show_connections, leave a blank line - if show_connections: - print("") - if show_connections: - trusted_peers: Dict = config["full_node"].get("trusted_peers", {}) - await print_connections(client, time, NodeType, trusted_peers) - # if called together with state, leave a blank line - if state: - print("") + # if show_connections: + # print("") + # if show_connections: + # trusted_peers: Dict = config["full_node"].get("trusted_peers", {}) + # await print_connections(client, time, NodeType, trusted_peers) + # # if called together with state, leave a blank line + # if state: + # print("") if exit_node: node_stop = await client.stop_node() print(node_stop, "Node stopped") - if add_connection: - if ":" not in add_connection: - print("Enter a valid IP and port in the following format: 10.5.4.3:8000") - else: - ip, port = ( - ":".join(add_connection.split(":")[:-1]), - add_connection.split(":")[-1], - ) - print(f"Connecting to {ip}, {port}") - try: - await client.open_connection(ip, int(port)) - except Exception: - print(f"Failed to connect to {ip}:{port}") - if remove_connection: - result_txt = "" - if len(remove_connection) != 8: - result_txt = "Invalid NodeID. Do not include '.'" - else: - connections = await client.get_connections() - for con in connections: - if remove_connection == con["node_id"].hex()[:8]: - print("Attempting to disconnect", "NodeID", remove_connection) - try: - await client.close_connection(con["node_id"]) - except Exception: - result_txt = f"Failed to disconnect NodeID {remove_connection}" - else: - result_txt = f"NodeID {remove_connection}... {NodeType(con['type']).name} " - f"{con['peer_host']} disconnected" - elif result_txt == "": - result_txt = f"NodeID {remove_connection}... not found" - print(result_txt) + # if add_connection: + # if ":" not in add_connection: + # print("Enter a valid IP and port in the following format: 10.5.4.3:8000") + # else: + # ip, port = ( + # ":".join(add_connection.split(":")[:-1]), + # add_connection.split(":")[-1], + # ) + # print(f"Connecting to {ip}, {port}") + # try: + # await client.open_connection(ip, int(port)) + # except Exception: + # print(f"Failed to connect to {ip}:{port}") + # if remove_connection: + # result_txt = "" + # if len(remove_connection) != 8: + # result_txt = "Invalid NodeID. Do not include '.'" + # else: + # connections = await client.get_connections() + # for con in connections: + # if remove_connection == con["node_id"].hex()[:8]: + # print("Attempting to disconnect", "NodeID", remove_connection) + # try: + # await client.close_connection(con["node_id"]) + # except Exception: + # result_txt = f"Failed to disconnect NodeID {remove_connection}" + # else: + # result_txt = f"NodeID {remove_connection}... {NodeType(con['type']).name} " + # f"{con['peer_host']} disconnected" + # elif result_txt == "": + # result_txt = f"NodeID {remove_connection}... not found" + # print(result_txt) if block_header_hash_by_height != "": block_header = await client.get_block_record_by_height(block_header_hash_by_height) if block_header is not None: @@ -287,44 +287,44 @@ async def show_async( @click.command("show", short_help="Show node information") -@click.option( - "-p", - "--rpc-port", - help=( - "Set the port where the Full Node is hosting the RPC interface. " - "See the rpc_port under full_node in config.yaml" - ), - type=int, - default=None, -) -@click.option( - "-wp", - "--wallet-rpc-port", - help="Set the port where the Wallet is hosting the RPC interface. See the rpc_port under wallet in config.yaml", - type=int, - default=None, -) +# @click.option( +# "-p", +# "--rpc-port", +# help=( +# "Set the port where the Full Node is hosting the RPC interface. " +# "See the rpc_port under full_node in config.yaml" +# ), +# type=int, +# default=None, +# ) +# @click.option( +# "-wp", +# "--wallet-rpc-port", +# help="Set the port where the Wallet is hosting the RPC interface. See the rpc_port under wallet in config.yaml", +# type=int, +# default=None, +# ) @click.option("-s", "--state", help="Show the current state of the blockchain", is_flag=True, type=bool, default=False) -@click.option( - "-c", "--connections", help="List nodes connected to this Full Node", is_flag=True, type=bool, default=False -) +# @click.option( +# "-c", "--connections", help="List nodes connected to this Full Node", is_flag=True, type=bool, default=False +# ) @click.option("-e", "--exit-node", help="Shut down the running Full Node", is_flag=True, default=False) -@click.option("-a", "--add-connection", help="Connect to another Full Node by ip:port", type=str, default="") -@click.option( - "-r", "--remove-connection", help="Remove a Node by the first 8 characters of NodeID", type=str, default="" -) +# @click.option("-a", "--add-connection", help="Connect to another Full Node by ip:port", type=str, default="") +# @click.option( +# "-r", "--remove-connection", help="Remove a Node by the first 8 characters of NodeID", type=str, default="" +# ) @click.option( "-bh", "--block-header-hash-by-height", help="Look up a block header hash by block height", type=str, default="" ) @click.option("-b", "--block-by-header-hash", help="Look up a block by block header hash", type=str, default="") def show_cmd( - rpc_port: Optional[int], - wallet_rpc_port: Optional[int], + # rpc_port: Optional[int], + # wallet_rpc_port: Optional[int], state: bool, - connections: bool, + # connections: bool, exit_node: bool, - add_connection: str, - remove_connection: str, + # add_connection: str, + # remove_connection: str, block_header_hash_by_height: str, block_by_header_hash: str, ) -> None: @@ -332,12 +332,12 @@ def show_cmd( asyncio.run( show_async( - rpc_port, + # rpc_port, state, - connections, + # connections, exit_node, - add_connection, - remove_connection, + # add_connection, + # remove_connection, block_header_hash_by_height, block_by_header_hash, ) diff --git a/chia/cmds/wallet_funcs.py b/chia/cmds/wallet_funcs.py index c4759e232a92..62d0e46e08d9 100644 --- a/chia/cmds/wallet_funcs.py +++ b/chia/cmds/wallet_funcs.py @@ -8,7 +8,7 @@ import aiohttp -from chia.cmds.show import print_connections +from chia.cmds.peer import print_connections from chia.cmds.units import units from chia.rpc.wallet_rpc_client import WalletRpcClient from chia.server.outbound_message import NodeType From f3ba37fc4f13fbf668b4f0fb9b238a1373b3f922 Mon Sep 17 00:00:00 2001 From: wallentx Date: Tue, 15 Mar 2022 17:21:34 -0500 Subject: [PATCH 02/28] Cleaning up peer and show commands --- chia/cmds/peer.py | 10 +-- chia/cmds/show.py | 177 ++++++++++------------------------------------ 2 files changed, 40 insertions(+), 147 deletions(-) diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index 16f9e29a9dae..596a49572685 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -153,21 +153,13 @@ async def peer_async( "See the rpc_port under full_node in config.yaml" ), type=int, - default=None, -) -@click.option( - "-wp", - "--wallet-rpc-port", - help="Set the port where the Wallet is hosting the RPC interface. See the rpc_port under wallet in config.yaml", - type=int, - default=None, + default=None ) def peer_cmd( connections: bool, add_connection: str, remove_connection: str, rpc_port: Optional[int], - wallet_rpc_port: Optional[int], ) -> None: import asyncio diff --git a/chia/cmds/show.py b/chia/cmds/show.py index f50dca534cac..209873c58cbe 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -1,69 +1,12 @@ -from typing import Any, Optional, Union, Dict - from chia.types.blockchain_format.sized_bytes import bytes32 -import click - from chia.util.network import is_trusted_inner - - -# async def print_connections(client, time, NodeType, trusted_peers: Dict): -# connections = await client.get_connections() -# print("Connections:") -# print("Type IP Ports NodeID Last Connect" + " MiB Up|Dwn") -# for con in connections: -# last_connect_tuple = time.struct_time(time.localtime(con["last_message_time"])) -# last_connect = time.strftime("%b %d %T", last_connect_tuple) -# mb_down = con["bytes_read"] / (1024 * 1024) -# mb_up = con["bytes_written"] / (1024 * 1024) - -# host = con["peer_host"] -# # Strip IPv6 brackets -# host = host.strip("[]") - -# trusted: bool = is_trusted_inner(host, con["node_id"], trusted_peers, False) -# # Nodetype length is 9 because INTRODUCER will be deprecated -# if NodeType(con["type"]) is NodeType.FULL_NODE: -# peak_height = con.get("peak_height", None) -# connection_peak_hash = con.get("peak_hash", None) -# if connection_peak_hash is None: -# connection_peak_hash = "No Info" -# else: -# if connection_peak_hash.startswith(("0x", "0X")): -# connection_peak_hash = connection_peak_hash[2:] -# connection_peak_hash = f"{connection_peak_hash[:8]}..." -# con_str = ( -# f"{NodeType(con['type']).name:9} {host:38} " -# f"{con['peer_port']:5}/{con['peer_server_port']:<5}" -# f" {con['node_id'].hex()[:8]}... " -# f"{last_connect} " -# f"{mb_up:7.1f}|{mb_down:<7.1f}" -# f"\n " -# ) -# if peak_height is not None: -# con_str += f"-Height: {peak_height:8.0f} -Hash: {connection_peak_hash}" -# else: -# con_str += f"-Height: No Info -Hash: {connection_peak_hash}" -# # Only show when Trusted is True -# if trusted: -# con_str += f" -Trusted: {trusted}" -# else: -# con_str = ( -# f"{NodeType(con['type']).name:9} {host:38} " -# f"{con['peer_port']:5}/{con['peer_server_port']:<5}" -# f" {con['node_id'].hex()[:8]}... " -# f"{last_connect} " -# f"{mb_up:7.1f}|{mb_down:<7.1f}" -# ) -# print(con_str) +import click +from typing import Any, Optional, Union, Dict async def show_async( - # rpc_port: Optional[int], state: bool, - # show_connections: bool, exit_node: bool, - # add_connection: str, - # remove_connection: str, block_header_hash_by_height: str, block_by_header_hash: str, ) -> None: @@ -162,50 +105,10 @@ async def show_async( else: print("Blockchain has no blocks yet") - # if called together with show_connections, leave a blank line - # if show_connections: - # print("") - # if show_connections: - # trusted_peers: Dict = config["full_node"].get("trusted_peers", {}) - # await print_connections(client, time, NodeType, trusted_peers) - # # if called together with state, leave a blank line - # if state: - # print("") if exit_node: node_stop = await client.stop_node() print(node_stop, "Node stopped") - # if add_connection: - # if ":" not in add_connection: - # print("Enter a valid IP and port in the following format: 10.5.4.3:8000") - # else: - # ip, port = ( - # ":".join(add_connection.split(":")[:-1]), - # add_connection.split(":")[-1], - # ) - # print(f"Connecting to {ip}, {port}") - # try: - # await client.open_connection(ip, int(port)) - # except Exception: - # print(f"Failed to connect to {ip}:{port}") - # if remove_connection: - # result_txt = "" - # if len(remove_connection) != 8: - # result_txt = "Invalid NodeID. Do not include '.'" - # else: - # connections = await client.get_connections() - # for con in connections: - # if remove_connection == con["node_id"].hex()[:8]: - # print("Attempting to disconnect", "NodeID", remove_connection) - # try: - # await client.close_connection(con["node_id"]) - # except Exception: - # result_txt = f"Failed to disconnect NodeID {remove_connection}" - # else: - # result_txt = f"NodeID {remove_connection}... {NodeType(con['type']).name} " - # f"{con['peer_host']} disconnected" - # elif result_txt == "": - # result_txt = f"NodeID {remove_connection}... not found" - # print(result_txt) + if block_header_hash_by_height != "": block_header = await client.get_block_record_by_height(block_header_hash_by_height) if block_header is not None: @@ -286,45 +189,47 @@ async def show_async( await client.await_closed() -@click.command("show", short_help="Show node information") -# @click.option( -# "-p", -# "--rpc-port", -# help=( -# "Set the port where the Full Node is hosting the RPC interface. " -# "See the rpc_port under full_node in config.yaml" -# ), -# type=int, -# default=None, -# ) -# @click.option( -# "-wp", -# "--wallet-rpc-port", -# help="Set the port where the Wallet is hosting the RPC interface. See the rpc_port under wallet in config.yaml", -# type=int, -# default=None, -# ) -@click.option("-s", "--state", help="Show the current state of the blockchain", is_flag=True, type=bool, default=False) -# @click.option( -# "-c", "--connections", help="List nodes connected to this Full Node", is_flag=True, type=bool, default=False -# ) -@click.option("-e", "--exit-node", help="Shut down the running Full Node", is_flag=True, default=False) -# @click.option("-a", "--add-connection", help="Connect to another Full Node by ip:port", type=str, default="") -# @click.option( -# "-r", "--remove-connection", help="Remove a Node by the first 8 characters of NodeID", type=str, default="" -# ) +@click.command( + "show", + short_help="Show node information" +) + +@click.option( + "-s", + "--state", + help="Show the current state of the blockchain", + is_flag=True, + type=bool, + default=False +) + @click.option( - "-bh", "--block-header-hash-by-height", help="Look up a block header hash by block height", type=str, default="" + "-e", + "--exit-node", + help="Shut down the running Full Node", + is_flag=True, + default=False ) -@click.option("-b", "--block-by-header-hash", help="Look up a block by block header hash", type=str, default="") + +@click.option( + "-bh", + "--block-header-hash-by-height", + help="Look up a block header hash by block height", + type=str, + default="" +) + +@click.option( + "-b", + "--block-by-header-hash", + help="Look up a block by block header hash", + type=str, + default="" +) + def show_cmd( - # rpc_port: Optional[int], - # wallet_rpc_port: Optional[int], state: bool, - # connections: bool, exit_node: bool, - # add_connection: str, - # remove_connection: str, block_header_hash_by_height: str, block_by_header_hash: str, ) -> None: @@ -332,12 +237,8 @@ def show_cmd( asyncio.run( show_async( - # rpc_port, state, - # connections, exit_node, - # add_connection, - # remove_connection, block_header_hash_by_height, block_by_header_hash, ) From b8f68a569088242c15137ce7c6b7513da52b5eb5 Mon Sep 17 00:00:00 2001 From: wallentx Date: Mon, 21 Mar 2022 15:19:11 -0500 Subject: [PATCH 03/28] Formatting to please flake8 --- chia/cmds/peer.py | 28 ++++++--------------------- chia/cmds/show.py | 48 +++++++---------------------------------------- 2 files changed, 13 insertions(+), 63 deletions(-) diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index 596a49572685..05316d7562eb 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -1,5 +1,4 @@ -from typing import Dict -from typing import Any, Optional, Union, Dict +from typing import Optional, Dict import click @@ -124,26 +123,11 @@ async def peer_async( @click.command("peer", short_help="Show, or modify peering connections") @click.option( - "-c", - "--connections", - help="List nodes connected to this Full Node", - is_flag=True, - type=bool, - default=True + "-c", "--connections", help="List nodes connected to this Full Node", is_flag=True, type=bool, default=True ) +@click.option("-a", "--add-connection", help="Connect to another Full Node by ip:port", type=str, default="") @click.option( - "-a", - "--add-connection", - help="Connect to another Full Node by ip:port", - type=str, - default="" -) -@click.option( - "-r", - "--remove-connection", - help="Remove a Node by the first 8 characters of NodeID", - type=str, - default="" + "-r", "--remove-connection", help="Remove a Node by the first 8 characters of NodeID", type=str, default="" ) @click.option( "-p", @@ -153,7 +137,7 @@ async def peer_async( "See the rpc_port under full_node in config.yaml" ), type=int, - default=None + default=None, ) def peer_cmd( connections: bool, @@ -170,4 +154,4 @@ def peer_cmd( remove_connection, rpc_port, ) - ) \ No newline at end of file + ) diff --git a/chia/cmds/show.py b/chia/cmds/show.py index 209873c58cbe..262eca3db09f 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -1,7 +1,6 @@ from chia.types.blockchain_format.sized_bytes import bytes32 -from chia.util.network import is_trusted_inner import click -from typing import Any, Optional, Union, Dict +from typing import Any, Union async def show_async( @@ -16,7 +15,6 @@ async def show_async( from typing import List, Optional from chia.consensus.block_record import BlockRecord from chia.rpc.full_node_rpc_client import FullNodeRpcClient - from chia.server.outbound_message import NodeType from chia.types.full_block import FullBlock from chia.util.bech32m import encode_puzzle_hash from chia.util.byte_types import hexstr_to_bytes @@ -28,8 +26,7 @@ async def show_async( 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"] + rpc_port = config["full_node"]["rpc_port"] client = await FullNodeRpcClient.create(self_hostname, uint16(rpc_port), DEFAULT_ROOT_PATH, config) if state: @@ -189,44 +186,13 @@ async def show_async( await client.await_closed() -@click.command( - "show", - short_help="Show node information" -) - -@click.option( - "-s", - "--state", - help="Show the current state of the blockchain", - is_flag=True, - type=bool, - default=False -) - -@click.option( - "-e", - "--exit-node", - help="Shut down the running Full Node", - is_flag=True, - default=False -) - -@click.option( - "-bh", - "--block-header-hash-by-height", - help="Look up a block header hash by block height", - type=str, - default="" -) - +@click.command("show", short_help="Show node information") +@click.option("-s", "--state", help="Show the current state of the blockchain", is_flag=True, type=bool, default=False) +@click.option("-e", "--exit-node", help="Shut down the running Full Node", is_flag=True, default=False) @click.option( - "-b", - "--block-by-header-hash", - help="Look up a block by block header hash", - type=str, - default="" + "-bh", "--block-header-hash-by-height", help="Look up a block header hash by block height", type=str, default="" ) - +@click.option("-b", "--block-by-header-hash", help="Look up a block by block header hash", type=str, default="") def show_cmd( state: bool, exit_node: bool, From 87cb68e88e204b7537c0293e8415019b2fc0d89e Mon Sep 17 00:00:00 2001 From: William Allen Date: Tue, 22 Mar 2022 15:46:01 -0500 Subject: [PATCH 04/28] Update chia/cmds/peer.py Adding as suggested Co-authored-by: Kyle Altendorf --- chia/cmds/peer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index 05316d7562eb..3b967a24ae1b 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -75,7 +75,7 @@ async def peer_async( client = await FullNodeRpcClient.create(self_hostname, uint16(rpc_port), DEFAULT_ROOT_PATH, config) if show_connections: - trusted_peers: Dict = config["full_node"].get("trusted_peers", {}) + trusted_peers: Dict[str, str] = config["full_node"].get("trusted_peers", {}) await print_connections(client, time, NodeType, trusted_peers) if add_connection: if ":" not in add_connection: From 84e69701beaf6dcf4cd4212ddf8ac8733f6277fc Mon Sep 17 00:00:00 2001 From: wallentx Date: Tue, 22 Mar 2022 15:48:33 -0500 Subject: [PATCH 05/28] Making suggested changes to peer.py --- chia/cmds/peer.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index 05316d7562eb..3e6e27cec9b3 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -1,11 +1,11 @@ -from typing import Optional, Dict +from typing import Dict, Optional import click from chia.util.network import is_trusted_inner -async def print_connections(client, time, NodeType, trusted_peers: Dict): +async def print_connections(client, time, NodeType, trusted_peers: Dict[str, str]) -> None: connections = await client.get_connections() print("Connections:") print("Type IP Ports NodeID Last Connect" + " MiB Up|Dwn") @@ -59,9 +59,11 @@ async def peer_async( remove_connection: str, rpc_port: Optional[int], ) -> None: - import aiohttp - import traceback import time + import traceback + + import aiohttp + from chia.rpc.full_node_rpc_client import FullNodeRpcClient from chia.server.outbound_message import NodeType from chia.util.config import load_config @@ -75,7 +77,7 @@ async def peer_async( client = await FullNodeRpcClient.create(self_hostname, uint16(rpc_port), DEFAULT_ROOT_PATH, config) if show_connections: - trusted_peers: Dict = config["full_node"].get("trusted_peers", {}) + trusted_peers: Dict[str, str] = config["full_node"].get("trusted_peers", {}) await print_connections(client, time, NodeType, trusted_peers) if add_connection: if ":" not in add_connection: From df333b18a245ed5d15e9f93e496486ac4f69dcce Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Thu, 7 Jul 2022 00:50:40 -0400 Subject: [PATCH 06/28] finalize pr very nice i basically did half the work when i refactored it Co-Authored-By: William Allen --- chia/cmds/peer.py | 154 ++++++++++++++++++++++------------------------ chia/cmds/show.py | 147 +++---------------------------------------- 2 files changed, 82 insertions(+), 219 deletions(-) diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index 087fefc45541..8717fdfb47b1 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -1,12 +1,56 @@ -from typing import Dict, Optional +from typing import Dict, Optional, Any import click -from chia.util.network import is_trusted_inner +from chia.cmds.show import execute_with_node +from chia.rpc.full_node_rpc_client import FullNodeRpcClient -async def print_connections(client, time, NodeType, trusted_peers: Dict[str, str]) -> None: - connections = await client.get_connections() +async def add_node_connection(node_client: FullNodeRpcClient, add_connection: str) -> None: + if ":" not in add_connection: + print("Enter a valid IP and port in the following format: 10.5.4.3:8000") + else: + ip, port = ( + ":".join(add_connection.split(":")[:-1]), + add_connection.split(":")[-1], + ) + print(f"Connecting to {ip}, {port}") + try: + await node_client.open_connection(ip, int(port)) + except Exception: + print(f"Failed to connect to {ip}:{port}") + + +async def remove_node_connection(node_client: FullNodeRpcClient, remove_connection: str) -> None: + from chia.server.outbound_message import NodeType + + result_txt = "" + if len(remove_connection) != 8: + result_txt = "Invalid NodeID. Do not include '.'" + else: + connections = await node_client.get_connections() + for con in connections: + if remove_connection == con["node_id"].hex()[:8]: + print("Attempting to disconnect", "NodeID", remove_connection) + try: + await node_client.close_connection(con["node_id"]) + except Exception: + result_txt = f"Failed to disconnect NodeID {remove_connection}" + else: + result_txt = f"NodeID {remove_connection}... {NodeType(con['type']).name} " + f"{con['peer_host']} disconnected" + elif result_txt == "": + result_txt = f"NodeID {remove_connection}... not found" + print(result_txt) + + +async def print_connections(node_client: FullNodeRpcClient, trusted_peers: Dict[str, Any]) -> None: + import time + + from chia.server.outbound_message import NodeType + from chia.util.network import is_trusted_inner + + connections = await node_client.get_connections() print("Connections:") print("Type IP Ports NodeID Last Connect" + " MiB Up|Dwn") for con in connections: @@ -39,9 +83,12 @@ async def print_connections(client, time, NodeType, trusted_peers: Dict[str, str f"\n " ) if peak_height is not None: - con_str += f"-Height: {peak_height:8.0f} -Hash: {connection_peak_hash} -Trusted: {trusted}" + con_str += f"-Height: {peak_height:8.0f} -Hash: {connection_peak_hash}" else: - con_str += f"-Height: No Info -Hash: {connection_peak_hash} -Trusted: {trusted}" + con_str += f"-Height: No Info -Hash: {connection_peak_hash}" + # Only show when Trusted is True + if trusted: + con_str += f" -Trusted: {trusted}" else: con_str = ( f"{NodeType(con['type']).name:9} {host:38} " @@ -54,83 +101,24 @@ async def print_connections(client, time, NodeType, trusted_peers: Dict[str, str async def peer_async( + node_client: FullNodeRpcClient, + config: Dict[str, Any], show_connections: bool, add_connection: str, remove_connection: str, - rpc_port: Optional[int], ) -> None: - import time - import traceback - - import aiohttp - - from chia.rpc.full_node_rpc_client import FullNodeRpcClient - from chia.server.outbound_message import NodeType - from chia.util.config import load_config - from chia.util.default_root import DEFAULT_ROOT_PATH - from chia.util.ints import uint16 - - try: - config = load_config(DEFAULT_ROOT_PATH, "config.yaml") - self_hostname = config["self_hostname"] - rpc_port = config["full_node"]["rpc_port"] - client = await FullNodeRpcClient.create(self_hostname, uint16(rpc_port), DEFAULT_ROOT_PATH, config) - - if show_connections: - trusted_peers: Dict[str, str] = config["full_node"].get("trusted_peers", {}) - await print_connections(client, time, NodeType, trusted_peers) - if add_connection: - if ":" not in add_connection: - print("Enter a valid IP and port in the following format: 10.5.4.3:8000") - else: - ip, port = ( - ":".join(add_connection.split(":")[:-1]), - add_connection.split(":")[-1], - ) - print(f"Connecting to {ip}, {port}") - try: - await client.open_connection(ip, int(port)) - except Exception: - print(f"Failed to connect to {ip}:{port}") - if remove_connection: - result_txt = "" - if len(remove_connection) != 8: - result_txt = "Invalid NodeID. Do not include '.'" - else: - connections = await client.get_connections() - for con in connections: - if remove_connection == con["node_id"].hex()[:8]: - print("Attempting to disconnect", "NodeID", remove_connection) - try: - await client.close_connection(con["node_id"]) - except Exception: - result_txt = f"Failed to disconnect NodeID {remove_connection}" - else: - result_txt = f"NodeID {remove_connection}... {NodeType(con['type']).name} " - f"{con['peer_host']} disconnected" - elif result_txt == "": - result_txt = f"NodeID {remove_connection}... not found" - print(result_txt) - except Exception as e: - if isinstance(e, aiohttp.ClientConnectorError): - print(f"Connection error. Check if full node rpc is running at {rpc_port}") - print("This is normal if full node is still starting up") - else: - tb = traceback.format_exc() - print(f"Exception from 'peer' {tb}") - - client.close() - await client.await_closed() + # Check or edit node connections + if show_connections: + trusted_peers: Dict[str, Any] = config["full_node"].get("trusted_peers", {}) + await print_connections(node_client, trusted_peers) + # if called together with state, leave a blank line + if add_connection: + await add_node_connection(node_client, add_connection) + if remove_connection: + await remove_node_connection(node_client, remove_connection) @click.command("peer", short_help="Show, or modify peering connections", no_args_is_help=True) -@click.option( - "-c", "--connections", help="List nodes connected to this Full Node", is_flag=True, type=bool, default=True -) -@click.option("-a", "--add-connection", help="Connect to another Full Node by ip:port", type=str, default="") -@click.option( - "-r", "--remove-connection", help="Remove a Node by the first 8 characters of NodeID", type=str, default="" -) @click.option( "-p", "--rpc-port", @@ -141,19 +129,27 @@ async def peer_async( type=int, default=None, ) +@click.option( + "-c", "--connections", help="List nodes connected to this Full Node", is_flag=True, type=bool, default=False +) +@click.option("-a", "--add-connection", help="Connect to another Full Node by ip:port", type=str, default="") +@click.option( + "-r", "--remove-connection", help="Remove a Node by the first 8 characters of NodeID", type=str, default="" +) def peer_cmd( + rpc_port: Optional[int], connections: bool, add_connection: str, remove_connection: str, - rpc_port: Optional[int], ) -> None: import asyncio asyncio.run( - peer_async( + execute_with_node( + rpc_port, + peer_async, connections, add_connection, remove_connection, - rpc_port, ) ) diff --git a/chia/cmds/show.py b/chia/cmds/show.py index 99e8308bdae4..7c274aad195a 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -1,65 +1,10 @@ from typing import Any, Callable, Dict, List, Optional, Union import click +from chia.rpc.full_node_rpc_client import FullNodeRpcClient -async def print_connections(node_client, trusted_peers: Dict): - import time - - from chia.server.outbound_message import NodeType - from chia.util.network import is_trusted_inner - - connections = await node_client.get_connections() - print("Connections:") - print("Type IP Ports NodeID Last Connect" + " MiB Up|Dwn") - for con in connections: - last_connect_tuple = time.struct_time(time.localtime(con["last_message_time"])) - last_connect = time.strftime("%b %d %T", last_connect_tuple) - mb_down = con["bytes_read"] / (1024 * 1024) - mb_up = con["bytes_written"] / (1024 * 1024) - - host = con["peer_host"] - # Strip IPv6 brackets - host = host.strip("[]") - - trusted: bool = is_trusted_inner(host, con["node_id"], trusted_peers, False) - # Nodetype length is 9 because INTRODUCER will be deprecated - if NodeType(con["type"]) is NodeType.FULL_NODE: - peak_height = con.get("peak_height", None) - connection_peak_hash = con.get("peak_hash", None) - if connection_peak_hash is None: - connection_peak_hash = "No Info" - else: - if connection_peak_hash.startswith(("0x", "0X")): - connection_peak_hash = connection_peak_hash[2:] - connection_peak_hash = f"{connection_peak_hash[:8]}..." - con_str = ( - f"{NodeType(con['type']).name:9} {host:38} " - f"{con['peer_port']:5}/{con['peer_server_port']:<5}" - f" {con['node_id'].hex()[:8]}... " - f"{last_connect} " - f"{mb_up:7.1f}|{mb_down:<7.1f}" - f"\n " - ) - if peak_height is not None: - con_str += f"-Height: {peak_height:8.0f} -Hash: {connection_peak_hash}" - else: - con_str += f"-Height: No Info -Hash: {connection_peak_hash}" - # Only show when Trusted is True - if trusted: - con_str += f" -Trusted: {trusted}" - else: - con_str = ( - f"{NodeType(con['type']).name:9} {host:38} " - f"{con['peer_port']:5}/{con['peer_server_port']:<5}" - f" {con['node_id'].hex()[:8]}... " - f"{last_connect} " - f"{mb_up:7.1f}|{mb_down:<7.1f}" - ) - print(con_str) - - -async def print_blockchain_state(node_client, config: Dict): +async def print_blockchain_state(node_client: FullNodeRpcClient, config: Dict) -> bool: # node_client is FullNodeRpcClient import time @@ -142,9 +87,10 @@ async def print_blockchain_state(node_client, config: Dict): print(f"{b.height:>9} | {b.header_hash}") else: print("Blockchain has no blocks yet") + return True -async def print_block_from_hash(node_client, config: Dict, block_by_header_hash: str): +async def print_block_from_hash(node_client: FullNodeRpcClient, config: Dict, block_by_header_hash: str) -> None: import time from chia.consensus.block_record import BlockRecord @@ -213,50 +159,11 @@ async def print_block_from_hash(node_client, config: Dict, block_by_header_hash: print("Block with header hash", block_by_header_hash, "not found") -async def add_node_connection(node_client, add_connection: str): - if ":" not in add_connection: - print("Enter a valid IP and port in the following format: 10.5.4.3:8000") - else: - ip, port = ( - ":".join(add_connection.split(":")[:-1]), - add_connection.split(":")[-1], - ) - print(f"Connecting to {ip}, {port}") - try: - await node_client.open_connection(ip, int(port)) - except Exception: - print(f"Failed to connect to {ip}:{port}") - - -async def remove_node_connection(node_client, remove_connection: str): - from chia.server.outbound_message import NodeType - - result_txt = "" - if len(remove_connection) != 8: - result_txt = "Invalid NodeID. Do not include '.'" - else: - connections = await node_client.get_connections() - for con in connections: - if remove_connection == con["node_id"].hex()[:8]: - print("Attempting to disconnect", "NodeID", remove_connection) - try: - await node_client.close_connection(con["node_id"]) - except Exception: - result_txt = f"Failed to disconnect NodeID {remove_connection}" - else: - result_txt = f"NodeID {remove_connection}... {NodeType(con['type']).name} " - f"{con['peer_host']} disconnected" - elif result_txt == "": - result_txt = f"NodeID {remove_connection}... not found" - print(result_txt) - - -async def execute_with_node(rpc_port: Optional[int], function: Callable, *args): +async def execute_with_node(rpc_port: Optional[int], function: Callable, *args) -> None: import traceback from aiohttp import ClientConnectorError - from chia.rpc.full_node_rpc_client import FullNodeRpcClient from chia.util.config import load_config from chia.util.default_root import DEFAULT_ROOT_PATH from chia.util.ints import uint16 @@ -284,12 +191,9 @@ async def execute_with_node(rpc_port: Optional[int], function: Callable, *args): async def show_async( - node_client, + node_client: FullNodeRpcClient, config: Dict, state: bool, - show_connections: bool, - add_connection: str, - remove_connection: str, block_header_hash_by_height: str, block_by_header_hash: str, ) -> None: @@ -298,22 +202,6 @@ async def show_async( if state: if await print_blockchain_state(node_client, config) is True: return None # if no blockchain is found - # if called together with show_connections, leave a blank line - if show_connections: - print("") - - # Check or edit node connections - if show_connections: - trusted_peers: Dict = config["full_node"].get("trusted_peers", {}) - await print_connections(node_client, trusted_peers) - # if called together with state, leave a blank line - if state: - print("") - if add_connection: - await add_node_connection(node_client, add_connection) - if remove_connection: - await remove_node_connection(node_client, remove_connection) - # Get Block Information if block_header_hash_by_height != "": block_header = await node_client.get_block_record_by_height(block_header_hash_by_height) @@ -336,32 +224,14 @@ async def show_async( type=int, default=None, ) -@click.option( - "-wp", - "--wallet-rpc-port", - help="Set the port where the Wallet is hosting the RPC interface. See the rpc_port under wallet in config.yaml", - type=int, - default=None, -) @click.option("-s", "--state", help="Show the current state of the blockchain", is_flag=True, type=bool, default=False) -@click.option( - "-c", "--connections", help="List nodes connected to this Full Node", is_flag=True, type=bool, default=False -) -@click.option("-a", "--add-connection", help="Connect to another Full Node by ip:port", type=str, default="") -@click.option( - "-r", "--remove-connection", help="Remove a Node by the first 8 characters of NodeID", type=str, default="" -) @click.option( "-bh", "--block-header-hash-by-height", help="Look up a block header hash by block height", type=str, default="" ) @click.option("-b", "--block-by-header-hash", help="Look up a block by block header hash", type=str, default="") def show_cmd( rpc_port: Optional[int], - wallet_rpc_port: Optional[int], state: bool, - connections: bool, - add_connection: str, - remove_connection: str, block_header_hash_by_height: str, block_by_header_hash: str, ) -> None: @@ -372,10 +242,7 @@ def show_cmd( rpc_port, show_async, state, - connections, - add_connection, - remove_connection, block_header_hash_by_height, block_by_header_hash, ) - ) \ No newline at end of file + ) From d3984347973b3989a1827e735bbe59b189bdd7d3 Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Thu, 7 Jul 2022 00:58:49 -0400 Subject: [PATCH 07/28] fix lint, damn isort REEEE Co-Authored-By: William Allen --- chia/cmds/peer.py | 5 +++-- chia/cmds/show.py | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index 8717fdfb47b1..1cccaf763a1b 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -1,9 +1,10 @@ -from typing import Dict, Optional, Any +from typing import Any, Dict, Optional import click from chia.cmds.show import execute_with_node from chia.rpc.full_node_rpc_client import FullNodeRpcClient +from chia.rpc.rpc_client import RpcClient async def add_node_connection(node_client: FullNodeRpcClient, add_connection: str) -> None: @@ -44,7 +45,7 @@ async def remove_node_connection(node_client: FullNodeRpcClient, remove_connecti print(result_txt) -async def print_connections(node_client: FullNodeRpcClient, trusted_peers: Dict[str, Any]) -> None: +async def print_connections(node_client: RpcClient, trusted_peers: Dict[str, Any]) -> None: import time from chia.server.outbound_message import NodeType diff --git a/chia/cmds/show.py b/chia/cmds/show.py index 7c274aad195a..6efa26dae4d5 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -1,6 +1,7 @@ from typing import Any, Callable, Dict, List, Optional, Union import click + from chia.rpc.full_node_rpc_client import FullNodeRpcClient From ece1178187020c1c974b9ffc2c1a21767121209f Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Sat, 9 Jul 2022 20:32:28 -0400 Subject: [PATCH 08/28] allow passthrough of root_dir --- chia/cmds/peer.py | 3 +++ chia/cmds/show.py | 13 +++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index 1cccaf763a1b..96981c7ef401 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -137,7 +137,9 @@ async def peer_async( @click.option( "-r", "--remove-connection", help="Remove a Node by the first 8 characters of NodeID", type=str, default="" ) +@click.pass_context def peer_cmd( + ctx: click.Context, rpc_port: Optional[int], connections: bool, add_connection: str, @@ -149,6 +151,7 @@ def peer_cmd( execute_with_node( rpc_port, peer_async, + ctx.obj["root_path"], connections, add_connection, remove_connection, diff --git a/chia/cmds/show.py b/chia/cmds/show.py index 6efa26dae4d5..847f3a93bd03 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -1,8 +1,10 @@ +from pathlib import Path from typing import Any, Callable, Dict, List, Optional, Union import click from chia.rpc.full_node_rpc_client import FullNodeRpcClient +from chia.util.default_root import DEFAULT_ROOT_PATH async def print_blockchain_state(node_client: FullNodeRpcClient, config: Dict) -> bool: @@ -160,16 +162,16 @@ async def print_block_from_hash(node_client: FullNodeRpcClient, config: Dict, bl print("Block with header hash", block_by_header_hash, "not found") -async def execute_with_node(rpc_port: Optional[int], function: Callable, *args) -> None: +async def execute_with_node( + rpc_port: Optional[int], function: Callable, root_path: Path = DEFAULT_ROOT_PATH, *args +) -> None: import traceback - from aiohttp import ClientConnectorError from chia.util.config import load_config - from chia.util.default_root import DEFAULT_ROOT_PATH from chia.util.ints import uint16 - config = load_config(DEFAULT_ROOT_PATH, "config.yaml") + config = load_config(root_path, "config.yaml") self_hostname = config["self_hostname"] if rpc_port is None: rpc_port = config["full_node"]["rpc_port"] @@ -230,7 +232,9 @@ async def show_async( "-bh", "--block-header-hash-by-height", help="Look up a block header hash by block height", type=str, default="" ) @click.option("-b", "--block-by-header-hash", help="Look up a block by block header hash", type=str, default="") +@click.pass_context def show_cmd( + ctx: click.Context, rpc_port: Optional[int], state: bool, block_header_hash_by_height: str, @@ -242,6 +246,7 @@ def show_cmd( execute_with_node( rpc_port, show_async, + ctx.obj["root_path"], state, block_header_hash_by_height, block_by_header_hash, From 9623f06242395be51f9f36218b544935aeb810e7 Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Sat, 9 Jul 2022 21:59:17 -0400 Subject: [PATCH 09/28] yikes --- chia/cmds/show.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chia/cmds/show.py b/chia/cmds/show.py index 847f3a93bd03..08157c1d08c5 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -177,7 +177,7 @@ async def execute_with_node( rpc_port = config["full_node"]["rpc_port"] try: node_client: FullNodeRpcClient = await FullNodeRpcClient.create( - self_hostname, uint16(rpc_port), DEFAULT_ROOT_PATH, config + self_hostname, uint16(rpc_port), root_path, config ) await function(node_client, config, *args) From 36fbfd37a88d1e230d65ebd10e5a5310fb6a7d25 Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Wed, 13 Jul 2022 18:11:00 -0400 Subject: [PATCH 10/28] Update show.py --- chia/cmds/show.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/chia/cmds/show.py b/chia/cmds/show.py index 08157c1d08c5..06f23c416a2d 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -229,9 +229,12 @@ async def show_async( ) @click.option("-s", "--state", help="Show the current state of the blockchain", is_flag=True, type=bool, default=False) @click.option( - "-bh", "--block-header-hash-by-height", help="Look up a block header hash by block height", type=str, default="" + "-h", "--block-header-hash-by-height", help="Look up a block header hash by block height", type=str, default="" ) @click.option("-b", "--block-by-header-hash", help="Look up a block by block header hash", type=str, default="") +@click.option( + "-c", "--connections", help="Use `chia peer -c`", is_flag=True, type=bool, default=False +) @click.pass_context def show_cmd( ctx: click.Context, @@ -239,9 +242,11 @@ def show_cmd( state: bool, block_header_hash_by_height: str, block_by_header_hash: str, + connections: bool, ) -> None: import asyncio - + if connections: + print("'chia show -c' has been renamed to 'chia peer -c' ") asyncio.run( execute_with_node( rpc_port, From 3579824ba97da9ab4b2af7e1210a56821f5ae1a6 Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Wed, 13 Jul 2022 18:23:07 -0400 Subject: [PATCH 11/28] fix --- chia/cmds/show.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/chia/cmds/show.py b/chia/cmds/show.py index 06f23c416a2d..2ed9e49e60c9 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -229,12 +229,10 @@ async def show_async( ) @click.option("-s", "--state", help="Show the current state of the blockchain", is_flag=True, type=bool, default=False) @click.option( - "-h", "--block-header-hash-by-height", help="Look up a block header hash by block height", type=str, default="" + "-bh", "--block-header-hash-by-height", help="Look up a block header hash by block height", type=str, default="" ) @click.option("-b", "--block-by-header-hash", help="Look up a block by block header hash", type=str, default="") -@click.option( - "-c", "--connections", help="Use `chia peer -c`", is_flag=True, type=bool, default=False -) +@click.option("-c", "--connections", help="Use `chia peer -c`", is_flag=True, type=bool, default=False) @click.pass_context def show_cmd( ctx: click.Context, @@ -245,6 +243,7 @@ def show_cmd( connections: bool, ) -> None: import asyncio + if connections: print("'chia show -c' has been renamed to 'chia peer -c' ") asyncio.run( From 34f6adf7a2977a965f6a3f089cf8a910715f18f0 Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Wed, 13 Jul 2022 18:45:47 -0400 Subject: [PATCH 12/28] happiness is a thing --- chia/cmds/show.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/chia/cmds/show.py b/chia/cmds/show.py index 2ed9e49e60c9..588a4c1a3013 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -218,34 +218,45 @@ async def show_async( @click.command("show", short_help="Show node information") @click.option( - "-p", - "--rpc-port", - help=( - "Set the port where the Full Node is hosting the RPC interface. " - "See the rpc_port under full_node in config.yaml" - ), + "-wp", + "--wallet-rpc-port", + help="Set the port where the Wallet is hosting the RPC interface. See the rpc_port under wallet in config.yaml", type=int, default=None, + deprecated=True, ) @click.option("-s", "--state", help="Show the current state of the blockchain", is_flag=True, type=bool, default=False) +@click.option( + "-c", "--connections", help="List nodes connected to this Full Node", is_flag=True, type=bool, default=False +) +@click.option("-a", "--add-connection", help="Connect to another Full Node by ip:port", type=str, default="") +@click.option( + "-r", "--remove-connection", help="Remove a Node by the first 8 characters of NodeID", type=str, default="" +) @click.option( "-bh", "--block-header-hash-by-height", help="Look up a block header hash by block height", type=str, default="" ) @click.option("-b", "--block-by-header-hash", help="Look up a block by block header hash", type=str, default="") -@click.option("-c", "--connections", help="Use `chia peer -c`", is_flag=True, type=bool, default=False) @click.pass_context def show_cmd( ctx: click.Context, rpc_port: Optional[int], + wallet_rpc_port: Optional[int], state: bool, + connections: bool, + add_connection: str, + remove_connection: str, block_header_hash_by_height: str, block_by_header_hash: str, - connections: bool, ) -> None: import asyncio if connections: print("'chia show -c' has been renamed to 'chia peer -c' ") + if add_connection != "": + print("'chia show -a' has been renamed to 'chia peer -a' ") + if remove_connection != "": + print("'chia show -r' has been renamed to 'chia peer -r' ") asyncio.run( execute_with_node( rpc_port, From 93cb6f9e6b07290d83047d92cd89aeaa4a9b1810 Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Thu, 14 Jul 2022 13:29:44 -0400 Subject: [PATCH 13/28] Update show.py --- chia/cmds/show.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chia/cmds/show.py b/chia/cmds/show.py index 588a4c1a3013..0c0a71cfb5fe 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -223,7 +223,6 @@ async def show_async( help="Set the port where the Wallet is hosting the RPC interface. See the rpc_port under wallet in config.yaml", type=int, default=None, - deprecated=True, ) @click.option("-s", "--state", help="Show the current state of the blockchain", is_flag=True, type=bool, default=False) @click.option( @@ -257,6 +256,8 @@ def show_cmd( print("'chia show -a' has been renamed to 'chia peer -a' ") if remove_connection != "": print("'chia show -r' has been renamed to 'chia peer -r' ") + if wallet_rpc_port is not None: + print("'chia show -wp' is not used, please remove it from your command.") asyncio.run( execute_with_node( rpc_port, From bda20cb085b7352032a4b1a0fd0d7be673dc97bf Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Thu, 14 Jul 2022 21:16:42 -0400 Subject: [PATCH 14/28] re add rpc, oops --- chia/cmds/show.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/chia/cmds/show.py b/chia/cmds/show.py index 0c0a71cfb5fe..737e92c39729 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -217,6 +217,16 @@ async def show_async( @click.command("show", short_help="Show node information") +@click.option( + "-p", + "--rpc-port", + help=( + "Set the port where the Full Node is hosting the RPC interface. " + "See the rpc_port under full_node in config.yaml" + ), + type=int, + default=None, +) @click.option( "-wp", "--wallet-rpc-port", From 18267e77b3e618e0b509ff8befad92e7e88715b6 Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Thu, 21 Jul 2022 16:05:05 -0400 Subject: [PATCH 15/28] allow any node type, per request --- chia/cmds/peer.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index 96981c7ef401..76770ed1f461 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -7,7 +7,7 @@ from chia.rpc.rpc_client import RpcClient -async def add_node_connection(node_client: FullNodeRpcClient, add_connection: str) -> None: +async def add_node_connection(rpc_client: RpcClient, add_connection: str) -> None: if ":" not in add_connection: print("Enter a valid IP and port in the following format: 10.5.4.3:8000") else: @@ -17,24 +17,24 @@ async def add_node_connection(node_client: FullNodeRpcClient, add_connection: st ) print(f"Connecting to {ip}, {port}") try: - await node_client.open_connection(ip, int(port)) + await rpc_client.open_connection(ip, int(port)) except Exception: print(f"Failed to connect to {ip}:{port}") -async def remove_node_connection(node_client: FullNodeRpcClient, remove_connection: str) -> None: +async def remove_node_connection(rpc_client: RpcClient, remove_connection: str) -> None: from chia.server.outbound_message import NodeType result_txt = "" if len(remove_connection) != 8: result_txt = "Invalid NodeID. Do not include '.'" else: - connections = await node_client.get_connections() + connections = await rpc_client.get_connections() for con in connections: if remove_connection == con["node_id"].hex()[:8]: print("Attempting to disconnect", "NodeID", remove_connection) try: - await node_client.close_connection(con["node_id"]) + await rpc_client.close_connection(con["node_id"]) except Exception: result_txt = f"Failed to disconnect NodeID {remove_connection}" else: @@ -45,13 +45,13 @@ async def remove_node_connection(node_client: FullNodeRpcClient, remove_connecti print(result_txt) -async def print_connections(node_client: RpcClient, trusted_peers: Dict[str, Any]) -> None: +async def print_connections(rpc_client: RpcClient, trusted_peers: Dict[str, Any]) -> None: import time from chia.server.outbound_message import NodeType from chia.util.network import is_trusted_inner - connections = await node_client.get_connections() + connections = await rpc_client.get_connections() print("Connections:") print("Type IP Ports NodeID Last Connect" + " MiB Up|Dwn") for con in connections: @@ -102,21 +102,22 @@ async def print_connections(node_client: RpcClient, trusted_peers: Dict[str, Any async def peer_async( - node_client: FullNodeRpcClient, + rpc_client: RpcClient, config: Dict[str, Any], show_connections: bool, add_connection: str, remove_connection: str, + #trusted_peers: Dict[str, Any], ) -> None: # Check or edit node connections if show_connections: trusted_peers: Dict[str, Any] = config["full_node"].get("trusted_peers", {}) - await print_connections(node_client, trusted_peers) + await print_connections(rpc_client, trusted_peers) # if called together with state, leave a blank line if add_connection: - await add_node_connection(node_client, add_connection) + await add_node_connection(rpc_client, add_connection) if remove_connection: - await remove_node_connection(node_client, remove_connection) + await remove_node_connection(rpc_client, remove_connection) @click.command("peer", short_help="Show, or modify peering connections", no_args_is_help=True) From dad21be089b7efe383cf047710d02ea260c84168 Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Thu, 21 Jul 2022 16:40:19 -0400 Subject: [PATCH 16/28] make separate funcs files to align with rest of codebase --- chia/cmds/peer.py | 124 +------------- chia/cmds/peer_funcs.py | 115 +++++++++++++ chia/cmds/show.py | 349 ++++++++------------------------------ chia/cmds/show_funcs.py | 213 +++++++++++++++++++++++ chia/cmds/wallet_funcs.py | 2 +- 5 files changed, 402 insertions(+), 401 deletions(-) create mode 100644 chia/cmds/peer_funcs.py create mode 100644 chia/cmds/show_funcs.py diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index 76770ed1f461..4a1fdb2a38f0 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -1,123 +1,7 @@ -from typing import Any, Dict, Optional - +from typing import Optional import click - -from chia.cmds.show import execute_with_node -from chia.rpc.full_node_rpc_client import FullNodeRpcClient -from chia.rpc.rpc_client import RpcClient - - -async def add_node_connection(rpc_client: RpcClient, add_connection: str) -> None: - if ":" not in add_connection: - print("Enter a valid IP and port in the following format: 10.5.4.3:8000") - else: - ip, port = ( - ":".join(add_connection.split(":")[:-1]), - add_connection.split(":")[-1], - ) - print(f"Connecting to {ip}, {port}") - try: - await rpc_client.open_connection(ip, int(port)) - except Exception: - print(f"Failed to connect to {ip}:{port}") - - -async def remove_node_connection(rpc_client: RpcClient, remove_connection: str) -> None: - from chia.server.outbound_message import NodeType - - result_txt = "" - if len(remove_connection) != 8: - result_txt = "Invalid NodeID. Do not include '.'" - else: - connections = await rpc_client.get_connections() - for con in connections: - if remove_connection == con["node_id"].hex()[:8]: - print("Attempting to disconnect", "NodeID", remove_connection) - try: - await rpc_client.close_connection(con["node_id"]) - except Exception: - result_txt = f"Failed to disconnect NodeID {remove_connection}" - else: - result_txt = f"NodeID {remove_connection}... {NodeType(con['type']).name} " - f"{con['peer_host']} disconnected" - elif result_txt == "": - result_txt = f"NodeID {remove_connection}... not found" - print(result_txt) - - -async def print_connections(rpc_client: RpcClient, trusted_peers: Dict[str, Any]) -> None: - import time - - from chia.server.outbound_message import NodeType - from chia.util.network import is_trusted_inner - - connections = await rpc_client.get_connections() - print("Connections:") - print("Type IP Ports NodeID Last Connect" + " MiB Up|Dwn") - for con in connections: - last_connect_tuple = time.struct_time(time.localtime(con["last_message_time"])) - last_connect = time.strftime("%b %d %T", last_connect_tuple) - mb_down = con["bytes_read"] / (1024 * 1024) - mb_up = con["bytes_written"] / (1024 * 1024) - - host = con["peer_host"] - # Strip IPv6 brackets - host = host.strip("[]") - - trusted: bool = is_trusted_inner(host, con["node_id"], trusted_peers, False) - # Nodetype length is 9 because INTRODUCER will be deprecated - if NodeType(con["type"]) is NodeType.FULL_NODE: - peak_height = con.get("peak_height", None) - connection_peak_hash = con.get("peak_hash", None) - if connection_peak_hash is None: - connection_peak_hash = "No Info" - else: - if connection_peak_hash.startswith(("0x", "0X")): - connection_peak_hash = connection_peak_hash[2:] - connection_peak_hash = f"{connection_peak_hash[:8]}..." - con_str = ( - f"{NodeType(con['type']).name:9} {host:38} " - f"{con['peer_port']:5}/{con['peer_server_port']:<5}" - f" {con['node_id'].hex()[:8]}... " - f"{last_connect} " - f"{mb_up:7.1f}|{mb_down:<7.1f}" - f"\n " - ) - if peak_height is not None: - con_str += f"-Height: {peak_height:8.0f} -Hash: {connection_peak_hash}" - else: - con_str += f"-Height: No Info -Hash: {connection_peak_hash}" - # Only show when Trusted is True - if trusted: - con_str += f" -Trusted: {trusted}" - else: - con_str = ( - f"{NodeType(con['type']).name:9} {host:38} " - f"{con['peer_port']:5}/{con['peer_server_port']:<5}" - f" {con['node_id'].hex()[:8]}... " - f"{last_connect} " - f"{mb_up:7.1f}|{mb_down:<7.1f}" - ) - print(con_str) - - -async def peer_async( - rpc_client: RpcClient, - config: Dict[str, Any], - show_connections: bool, - add_connection: str, - remove_connection: str, - #trusted_peers: Dict[str, Any], -) -> None: - # Check or edit node connections - if show_connections: - trusted_peers: Dict[str, Any] = config["full_node"].get("trusted_peers", {}) - await print_connections(rpc_client, trusted_peers) - # if called together with state, leave a blank line - if add_connection: - await add_node_connection(rpc_client, add_connection) - if remove_connection: - await remove_node_connection(rpc_client, remove_connection) +from chia.cmds.peer_funcs import peer_async +from chia.cmds.show_funcs import execute_with_node @click.command("peer", short_help="Show, or modify peering connections", no_args_is_help=True) @@ -125,7 +9,7 @@ async def peer_async( "-p", "--rpc-port", help=( - "Set the port where the Full Node is hosting the RPC interface. " + "Set the port where the Selected Node is hosting the RPC interface. " "See the rpc_port under full_node in config.yaml" ), type=int, diff --git a/chia/cmds/peer_funcs.py b/chia/cmds/peer_funcs.py new file mode 100644 index 000000000000..14de7e5c9394 --- /dev/null +++ b/chia/cmds/peer_funcs.py @@ -0,0 +1,115 @@ +from typing import Any, Dict +from chia.rpc.rpc_client import RpcClient + + +async def add_node_connection(rpc_client: RpcClient, add_connection: str) -> None: + if ":" not in add_connection: + print("Enter a valid IP and port in the following format: 10.5.4.3:8000") + else: + ip, port = ( + ":".join(add_connection.split(":")[:-1]), + add_connection.split(":")[-1], + ) + print(f"Connecting to {ip}, {port}") + try: + await rpc_client.open_connection(ip, int(port)) + except Exception: + print(f"Failed to connect to {ip}:{port}") + + +async def remove_node_connection(rpc_client: RpcClient, remove_connection: str) -> None: + from chia.server.outbound_message import NodeType + + result_txt = "" + if len(remove_connection) != 8: + result_txt = "Invalid NodeID. Do not include '.'" + else: + connections = await rpc_client.get_connections() + for con in connections: + if remove_connection == con["node_id"].hex()[:8]: + print("Attempting to disconnect", "NodeID", remove_connection) + try: + await rpc_client.close_connection(con["node_id"]) + except Exception: + result_txt = f"Failed to disconnect NodeID {remove_connection}" + else: + result_txt = f"NodeID {remove_connection}... {NodeType(con['type']).name} " + f"{con['peer_host']} disconnected" + elif result_txt == "": + result_txt = f"NodeID {remove_connection}... not found" + print(result_txt) + + +async def print_connections(rpc_client: RpcClient, trusted_peers: Dict[str, Any]) -> None: + import time + + from chia.server.outbound_message import NodeType + from chia.util.network import is_trusted_inner + + connections = await rpc_client.get_connections() + print("Connections:") + print("Type IP Ports NodeID Last Connect" + " MiB Up|Dwn") + for con in connections: + last_connect_tuple = time.struct_time(time.localtime(con["last_message_time"])) + last_connect = time.strftime("%b %d %T", last_connect_tuple) + mb_down = con["bytes_read"] / (1024 * 1024) + mb_up = con["bytes_written"] / (1024 * 1024) + + host = con["peer_host"] + # Strip IPv6 brackets + host = host.strip("[]") + + trusted: bool = is_trusted_inner(host, con["node_id"], trusted_peers, False) + # Nodetype length is 9 because INTRODUCER will be deprecated + if NodeType(con["type"]) is NodeType.FULL_NODE: + peak_height = con.get("peak_height", None) + connection_peak_hash = con.get("peak_hash", None) + if connection_peak_hash is None: + connection_peak_hash = "No Info" + else: + if connection_peak_hash.startswith(("0x", "0X")): + connection_peak_hash = connection_peak_hash[2:] + connection_peak_hash = f"{connection_peak_hash[:8]}..." + con_str = ( + f"{NodeType(con['type']).name:9} {host:38} " + f"{con['peer_port']:5}/{con['peer_server_port']:<5}" + f" {con['node_id'].hex()[:8]}... " + f"{last_connect} " + f"{mb_up:7.1f}|{mb_down:<7.1f}" + f"\n " + ) + if peak_height is not None: + con_str += f"-Height: {peak_height:8.0f} -Hash: {connection_peak_hash}" + else: + con_str += f"-Height: No Info -Hash: {connection_peak_hash}" + # Only show when Trusted is True + if trusted: + con_str += f" -Trusted: {trusted}" + else: + con_str = ( + f"{NodeType(con['type']).name:9} {host:38} " + f"{con['peer_port']:5}/{con['peer_server_port']:<5}" + f" {con['node_id'].hex()[:8]}... " + f"{last_connect} " + f"{mb_up:7.1f}|{mb_down:<7.1f}" + ) + print(con_str) + + +async def peer_async( + rpc_client: RpcClient, + config: Dict[str, Any], + show_connections: bool, + add_connection: str, + remove_connection: str, + # trusted_peers: Dict[str, Any], +) -> None: + # Check or edit node connections + if show_connections: + trusted_peers: Dict[str, Any] = config["full_node"].get("trusted_peers", {}) + await print_connections(rpc_client, trusted_peers) + # if called together with state, leave a blank line + if add_connection: + await add_node_connection(rpc_client, add_connection) + if remove_connection: + await remove_node_connection(rpc_client, remove_connection) diff --git a/chia/cmds/show.py b/chia/cmds/show.py index 737e92c39729..46e6bcb846c8 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -1,280 +1,69 @@ -from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Union - -import click - -from chia.rpc.full_node_rpc_client import FullNodeRpcClient -from chia.util.default_root import DEFAULT_ROOT_PATH - - -async def print_blockchain_state(node_client: FullNodeRpcClient, config: Dict) -> bool: - # node_client is FullNodeRpcClient - import time - - from chia.consensus.block_record import BlockRecord - from chia.util.ints import uint64 - from chia.util.misc import format_bytes - - blockchain_state = await node_client.get_blockchain_state() - if blockchain_state is None: - print("There is no blockchain found yet. Try again shortly") - return True - peak: Optional[BlockRecord] = blockchain_state["peak"] - node_id = blockchain_state["node_id"] - difficulty = blockchain_state["difficulty"] - sub_slot_iters = blockchain_state["sub_slot_iters"] - synced = blockchain_state["sync"]["synced"] - sync_mode = blockchain_state["sync"]["sync_mode"] - total_iters = peak.total_iters if peak is not None else 0 - num_blocks: int = 10 - network_name = config["selected_network"] - genesis_challenge = config["farmer"]["network_overrides"]["constants"][network_name]["GENESIS_CHALLENGE"] - full_node_port = config["full_node"]["port"] - full_node_rpc_port = config["full_node"]["rpc_port"] - - print(f"Network: {network_name} Port: {full_node_port} RPC Port: {full_node_rpc_port}") - print(f"Node ID: {node_id}") - print(f"Genesis Challenge: {genesis_challenge}") - - if synced: - print("Current Blockchain Status: Full Node Synced") - print("\nPeak: Hash:", peak.header_hash if peak is not None else "") - elif peak is not None and sync_mode: - sync_max_block = blockchain_state["sync"]["sync_tip_height"] - sync_current_block = blockchain_state["sync"]["sync_progress_height"] - print( - f"Current Blockchain Status: Syncing {sync_current_block}/{sync_max_block} " - f"({sync_max_block - sync_current_block} behind)." - ) - print("Peak: Hash:", peak.header_hash if peak is not None else "") - elif peak is not None: - print(f"Current Blockchain Status: Not Synced. Peak height: {peak.height}") - else: - print("\nSearching for an initial chain\n") - print("You may be able to expedite with 'chia show -a host:port' using a known node.\n") - - if peak is not None: - if peak.is_transaction_block: - peak_time = peak.timestamp - else: - peak_hash = peak.header_hash - curr = await node_client.get_block_record(peak_hash) - while curr is not None and not curr.is_transaction_block: - curr = await node_client.get_block_record(curr.prev_hash) - if curr is not None: - peak_time = curr.timestamp - else: - peak_time = uint64(0) - peak_time_struct = time.struct_time(time.localtime(peak_time)) - - print( - " Time:", - f"{time.strftime('%a %b %d %Y %T %Z', peak_time_struct)}", - f" Height: {peak.height:>10}\n", - ) - - print("Estimated network space: ", end="") - print(format_bytes(blockchain_state["space"])) - print(f"Current difficulty: {difficulty}") - print(f"Current VDF sub_slot_iters: {sub_slot_iters}") - print("Total iterations since the start of the blockchain:", total_iters) - print("\n Height: | Hash:") - - added_blocks: List[BlockRecord] = [] - curr = await node_client.get_block_record(peak.header_hash) - while curr is not None and len(added_blocks) < num_blocks and curr.height > 0: - added_blocks.append(curr) - curr = await node_client.get_block_record(curr.prev_hash) - - for b in added_blocks: - print(f"{b.height:>9} | {b.header_hash}") - else: - print("Blockchain has no blocks yet") - return True - - -async def print_block_from_hash(node_client: FullNodeRpcClient, config: Dict, block_by_header_hash: str) -> None: - import time - - from chia.consensus.block_record import BlockRecord - from chia.types.blockchain_format.sized_bytes import bytes32 - from chia.types.full_block import FullBlock - from chia.util.bech32m import encode_puzzle_hash - from chia.util.byte_types import hexstr_to_bytes - - block: Optional[BlockRecord] = await node_client.get_block_record(hexstr_to_bytes(block_by_header_hash)) - full_block: Optional[FullBlock] = await node_client.get_block(hexstr_to_bytes(block_by_header_hash)) - # Would like to have a verbose flag for this - if block is not None: - assert full_block is not None - prev_b = await node_client.get_block_record(block.prev_hash) - if prev_b is not None: - difficulty = block.weight - prev_b.weight - else: - difficulty = block.weight - if block.is_transaction_block: - assert full_block.transactions_info is not None - block_time = time.struct_time( - time.localtime( - full_block.foliage_transaction_block.timestamp if full_block.foliage_transaction_block else None - ) - ) - block_time_string = time.strftime("%a %b %d %Y %T %Z", block_time) - cost = str(full_block.transactions_info.cost) - tx_filter_hash: Union[str, bytes32] = "Not a transaction block" - if full_block.foliage_transaction_block: - tx_filter_hash = full_block.foliage_transaction_block.filter_hash - fees: Any = block.fees - else: - block_time_string = "Not a transaction block" - cost = "Not a transaction block" - tx_filter_hash = "Not a transaction block" - fees = "Not a transaction block" - address_prefix = config["network_overrides"]["config"][config["selected_network"]]["address_prefix"] - farmer_address = encode_puzzle_hash(block.farmer_puzzle_hash, address_prefix) - pool_address = encode_puzzle_hash(block.pool_puzzle_hash, address_prefix) - pool_pk = ( - full_block.reward_chain_block.proof_of_space.pool_public_key - if full_block.reward_chain_block.proof_of_space.pool_public_key is not None - else "Pay to pool puzzle hash" - ) - print( - f"Block Height {block.height}\n" - f"Header Hash 0x{block.header_hash.hex()}\n" - f"Timestamp {block_time_string}\n" - f"Weight {block.weight}\n" - f"Previous Block 0x{block.prev_hash.hex()}\n" - f"Difficulty {difficulty}\n" - f"Sub-slot iters {block.sub_slot_iters}\n" - f"Cost {cost}\n" - f"Total VDF Iterations {block.total_iters}\n" - f"Is a Transaction Block?{block.is_transaction_block}\n" - f"Deficit {block.deficit}\n" - f"PoSpace 'k' Size {full_block.reward_chain_block.proof_of_space.size}\n" - f"Plot Public Key 0x{full_block.reward_chain_block.proof_of_space.plot_public_key}\n" - f"Pool Public Key {pool_pk}\n" - f"Tx Filter Hash {tx_filter_hash}\n" - f"Farmer Address {farmer_address}\n" - f"Pool Address {pool_address}\n" - f"Fees Amount {fees}\n" - ) - else: - print("Block with header hash", block_by_header_hash, "not found") - - -async def execute_with_node( - rpc_port: Optional[int], function: Callable, root_path: Path = DEFAULT_ROOT_PATH, *args -) -> None: - import traceback - from aiohttp import ClientConnectorError - - from chia.util.config import load_config - from chia.util.ints import uint16 - - config = load_config(root_path, "config.yaml") - self_hostname = config["self_hostname"] - if rpc_port is None: - rpc_port = config["full_node"]["rpc_port"] - try: - node_client: FullNodeRpcClient = await FullNodeRpcClient.create( - self_hostname, uint16(rpc_port), root_path, config - ) - await function(node_client, config, *args) - - except Exception as e: - if isinstance(e, ClientConnectorError): - print(f"Connection error. Check if full node rpc is running at {rpc_port}") - print("This is normal if full node is still starting up") - else: - tb = traceback.format_exc() - print(f"Exception from 'show' {tb}") - - node_client.close() - await node_client.await_closed() - - -async def show_async( - node_client: FullNodeRpcClient, - config: Dict, - state: bool, - block_header_hash_by_height: str, - block_by_header_hash: str, -) -> None: - - # Check State - if state: - if await print_blockchain_state(node_client, config) is True: - return None # if no blockchain is found - # Get Block Information - if block_header_hash_by_height != "": - block_header = await node_client.get_block_record_by_height(block_header_hash_by_height) - if block_header is not None: - print(f"Header hash of block {block_header_hash_by_height}: " f"{block_header.header_hash.hex()}") - else: - print("Block height", block_header_hash_by_height, "not found") - if block_by_header_hash != "": - await print_block_from_hash(node_client, config, block_by_header_hash) - - -@click.command("show", short_help="Show node information") -@click.option( - "-p", - "--rpc-port", - help=( - "Set the port where the Full Node is hosting the RPC interface. " - "See the rpc_port under full_node in config.yaml" - ), - type=int, - default=None, -) -@click.option( - "-wp", - "--wallet-rpc-port", - help="Set the port where the Wallet is hosting the RPC interface. See the rpc_port under wallet in config.yaml", - type=int, - default=None, -) -@click.option("-s", "--state", help="Show the current state of the blockchain", is_flag=True, type=bool, default=False) -@click.option( - "-c", "--connections", help="List nodes connected to this Full Node", is_flag=True, type=bool, default=False -) -@click.option("-a", "--add-connection", help="Connect to another Full Node by ip:port", type=str, default="") -@click.option( - "-r", "--remove-connection", help="Remove a Node by the first 8 characters of NodeID", type=str, default="" -) -@click.option( - "-bh", "--block-header-hash-by-height", help="Look up a block header hash by block height", type=str, default="" -) -@click.option("-b", "--block-by-header-hash", help="Look up a block by block header hash", type=str, default="") -@click.pass_context -def show_cmd( - ctx: click.Context, - rpc_port: Optional[int], - wallet_rpc_port: Optional[int], - state: bool, - connections: bool, - add_connection: str, - remove_connection: str, - block_header_hash_by_height: str, - block_by_header_hash: str, -) -> None: - import asyncio - - if connections: - print("'chia show -c' has been renamed to 'chia peer -c' ") - if add_connection != "": - print("'chia show -a' has been renamed to 'chia peer -a' ") - if remove_connection != "": - print("'chia show -r' has been renamed to 'chia peer -r' ") - if wallet_rpc_port is not None: - print("'chia show -wp' is not used, please remove it from your command.") - asyncio.run( - execute_with_node( - rpc_port, - show_async, - ctx.obj["root_path"], - state, - block_header_hash_by_height, - block_by_header_hash, - ) - ) +from typing import Optional + +import click + +from chia.cmds.show_funcs import show_async, execute_with_node + + +@click.command("show", short_help="Show node information") +@click.option( + "-p", + "--rpc-port", + help=( + "Set the port where the Full Node is hosting the RPC interface. " + "See the rpc_port under full_node in config.yaml" + ), + type=int, + default=None, +) +@click.option( + "-wp", + "--wallet-rpc-port", + help="Set the port where the Wallet is hosting the RPC interface. See the rpc_port under wallet in config.yaml", + type=int, + default=None, +) +@click.option("-s", "--state", help="Show the current state of the blockchain", is_flag=True, type=bool, default=False) +@click.option( + "-c", "--connections", help="List nodes connected to this Full Node", is_flag=True, type=bool, default=False +) +@click.option("-a", "--add-connection", help="Connect to another Full Node by ip:port", type=str, default="") +@click.option( + "-r", "--remove-connection", help="Remove a Node by the first 8 characters of NodeID", type=str, default="" +) +@click.option( + "-bh", "--block-header-hash-by-height", help="Look up a block header hash by block height", type=str, default="" +) +@click.option("-b", "--block-by-header-hash", help="Look up a block by block header hash", type=str, default="") +@click.pass_context +def show_cmd( + ctx: click.Context, + rpc_port: Optional[int], + wallet_rpc_port: Optional[int], + state: bool, + connections: bool, + add_connection: str, + remove_connection: str, + block_header_hash_by_height: str, + block_by_header_hash: str, +) -> None: + import asyncio + + if connections: + print("'chia show -c' has been renamed to 'chia peer -c' ") + if add_connection != "": + print("'chia show -a' has been renamed to 'chia peer -a' ") + if remove_connection != "": + print("'chia show -r' has been renamed to 'chia peer -r' ") + if wallet_rpc_port is not None: + print("'chia show -wp' is not used, please remove it from your command.") + asyncio.run( + execute_with_node( + rpc_port, + show_async, + ctx.obj["root_path"], + state, + block_header_hash_by_height, + block_by_header_hash, + ) + ) diff --git a/chia/cmds/show_funcs.py b/chia/cmds/show_funcs.py new file mode 100644 index 000000000000..267ec71dbabe --- /dev/null +++ b/chia/cmds/show_funcs.py @@ -0,0 +1,213 @@ +from pathlib import Path +from typing import Any, Callable, Dict, List, Optional, Union + +from chia.rpc.full_node_rpc_client import FullNodeRpcClient +from chia.util.default_root import DEFAULT_ROOT_PATH + + +async def print_blockchain_state(node_client: FullNodeRpcClient, config: Dict) -> bool: + # node_client is FullNodeRpcClient + import time + + from chia.consensus.block_record import BlockRecord + from chia.util.ints import uint64 + from chia.util.misc import format_bytes + + blockchain_state = await node_client.get_blockchain_state() + if blockchain_state is None: + print("There is no blockchain found yet. Try again shortly") + return True + peak: Optional[BlockRecord] = blockchain_state["peak"] + node_id = blockchain_state["node_id"] + difficulty = blockchain_state["difficulty"] + sub_slot_iters = blockchain_state["sub_slot_iters"] + synced = blockchain_state["sync"]["synced"] + sync_mode = blockchain_state["sync"]["sync_mode"] + total_iters = peak.total_iters if peak is not None else 0 + num_blocks: int = 10 + network_name = config["selected_network"] + genesis_challenge = config["farmer"]["network_overrides"]["constants"][network_name]["GENESIS_CHALLENGE"] + full_node_port = config["full_node"]["port"] + full_node_rpc_port = config["full_node"]["rpc_port"] + + print(f"Network: {network_name} Port: {full_node_port} RPC Port: {full_node_rpc_port}") + print(f"Node ID: {node_id}") + print(f"Genesis Challenge: {genesis_challenge}") + + if synced: + print("Current Blockchain Status: Full Node Synced") + print("\nPeak: Hash:", peak.header_hash if peak is not None else "") + elif peak is not None and sync_mode: + sync_max_block = blockchain_state["sync"]["sync_tip_height"] + sync_current_block = blockchain_state["sync"]["sync_progress_height"] + print( + f"Current Blockchain Status: Syncing {sync_current_block}/{sync_max_block} " + f"({sync_max_block - sync_current_block} behind)." + ) + print("Peak: Hash:", peak.header_hash if peak is not None else "") + elif peak is not None: + print(f"Current Blockchain Status: Not Synced. Peak height: {peak.height}") + else: + print("\nSearching for an initial chain\n") + print("You may be able to expedite with 'chia show -a host:port' using a known node.\n") + + if peak is not None: + if peak.is_transaction_block: + peak_time = peak.timestamp + else: + peak_hash = peak.header_hash + curr = await node_client.get_block_record(peak_hash) + while curr is not None and not curr.is_transaction_block: + curr = await node_client.get_block_record(curr.prev_hash) + if curr is not None: + peak_time = curr.timestamp + else: + peak_time = uint64(0) + peak_time_struct = time.struct_time(time.localtime(peak_time)) + + print( + " Time:", + f"{time.strftime('%a %b %d %Y %T %Z', peak_time_struct)}", + f" Height: {peak.height:>10}\n", + ) + + print("Estimated network space: ", end="") + print(format_bytes(blockchain_state["space"])) + print(f"Current difficulty: {difficulty}") + print(f"Current VDF sub_slot_iters: {sub_slot_iters}") + print("Total iterations since the start of the blockchain:", total_iters) + print("\n Height: | Hash:") + + added_blocks: List[BlockRecord] = [] + curr = await node_client.get_block_record(peak.header_hash) + while curr is not None and len(added_blocks) < num_blocks and curr.height > 0: + added_blocks.append(curr) + curr = await node_client.get_block_record(curr.prev_hash) + + for b in added_blocks: + print(f"{b.height:>9} | {b.header_hash}") + else: + print("Blockchain has no blocks yet") + return True + + +async def print_block_from_hash(node_client: FullNodeRpcClient, config: Dict, block_by_header_hash: str) -> None: + import time + + from chia.consensus.block_record import BlockRecord + from chia.types.blockchain_format.sized_bytes import bytes32 + from chia.types.full_block import FullBlock + from chia.util.bech32m import encode_puzzle_hash + from chia.util.byte_types import hexstr_to_bytes + + block: Optional[BlockRecord] = await node_client.get_block_record(hexstr_to_bytes(block_by_header_hash)) + full_block: Optional[FullBlock] = await node_client.get_block(hexstr_to_bytes(block_by_header_hash)) + # Would like to have a verbose flag for this + if block is not None: + assert full_block is not None + prev_b = await node_client.get_block_record(block.prev_hash) + if prev_b is not None: + difficulty = block.weight - prev_b.weight + else: + difficulty = block.weight + if block.is_transaction_block: + assert full_block.transactions_info is not None + block_time = time.struct_time( + time.localtime( + full_block.foliage_transaction_block.timestamp if full_block.foliage_transaction_block else None + ) + ) + block_time_string = time.strftime("%a %b %d %Y %T %Z", block_time) + cost = str(full_block.transactions_info.cost) + tx_filter_hash: Union[str, bytes32] = "Not a transaction block" + if full_block.foliage_transaction_block: + tx_filter_hash = full_block.foliage_transaction_block.filter_hash + fees: Any = block.fees + else: + block_time_string = "Not a transaction block" + cost = "Not a transaction block" + tx_filter_hash = "Not a transaction block" + fees = "Not a transaction block" + address_prefix = config["network_overrides"]["config"][config["selected_network"]]["address_prefix"] + farmer_address = encode_puzzle_hash(block.farmer_puzzle_hash, address_prefix) + pool_address = encode_puzzle_hash(block.pool_puzzle_hash, address_prefix) + pool_pk = ( + full_block.reward_chain_block.proof_of_space.pool_public_key + if full_block.reward_chain_block.proof_of_space.pool_public_key is not None + else "Pay to pool puzzle hash" + ) + print( + f"Block Height {block.height}\n" + f"Header Hash 0x{block.header_hash.hex()}\n" + f"Timestamp {block_time_string}\n" + f"Weight {block.weight}\n" + f"Previous Block 0x{block.prev_hash.hex()}\n" + f"Difficulty {difficulty}\n" + f"Sub-slot iters {block.sub_slot_iters}\n" + f"Cost {cost}\n" + f"Total VDF Iterations {block.total_iters}\n" + f"Is a Transaction Block?{block.is_transaction_block}\n" + f"Deficit {block.deficit}\n" + f"PoSpace 'k' Size {full_block.reward_chain_block.proof_of_space.size}\n" + f"Plot Public Key 0x{full_block.reward_chain_block.proof_of_space.plot_public_key}\n" + f"Pool Public Key {pool_pk}\n" + f"Tx Filter Hash {tx_filter_hash}\n" + f"Farmer Address {farmer_address}\n" + f"Pool Address {pool_address}\n" + f"Fees Amount {fees}\n" + ) + else: + print("Block with header hash", block_by_header_hash, "not found") + + +async def execute_with_node( + rpc_port: Optional[int], function: Callable, root_path: Path = DEFAULT_ROOT_PATH, *args +) -> None: + import traceback + from aiohttp import ClientConnectorError + + from chia.util.config import load_config + from chia.util.ints import uint16 + + config = load_config(root_path, "config.yaml") + self_hostname = config["self_hostname"] + if rpc_port is None: + rpc_port = config["full_node"]["rpc_port"] + try: + node_client: FullNodeRpcClient = await FullNodeRpcClient.create( + self_hostname, uint16(rpc_port), root_path, config + ) + await function(node_client, config, *args) + + except Exception as e: + if isinstance(e, ClientConnectorError): + print(f"Connection error. Check if full node rpc is running at {rpc_port}") + print("This is normal if full node is still starting up") + else: + tb = traceback.format_exc() + print(f"Exception from 'show' {tb}") + + node_client.close() + await node_client.await_closed() + + +async def show_async( + node_client: FullNodeRpcClient, + config: Dict, + state: bool, + block_header_hash_by_height: str, + block_by_header_hash: str, +) -> None: + # Check State + if state: + if await print_blockchain_state(node_client, config) is True: + return None # if no blockchain is found + # Get Block Information + if block_header_hash_by_height != "": + block_header = await node_client.get_block_record_by_height(block_header_hash_by_height) + if block_header is not None: + print(f"Header hash of block {block_header_hash_by_height}: " f"{block_header.header_hash.hex()}") + else: + print("Block height", block_header_hash_by_height, "not found") + if block_by_header_hash != "": + await print_block_from_hash(node_client, config, block_by_header_hash) diff --git a/chia/cmds/wallet_funcs.py b/chia/cmds/wallet_funcs.py index b2eed746940a..78964157ed51 100644 --- a/chia/cmds/wallet_funcs.py +++ b/chia/cmds/wallet_funcs.py @@ -9,7 +9,7 @@ import aiohttp from chia.cmds.cmds_util import transaction_status_msg, transaction_submitted_msg -from chia.cmds.peer import print_connections +from chia.cmds.peer_funcs import print_connections from chia.cmds.units import units from chia.rpc.wallet_rpc_client import WalletRpcClient from chia.server.start_wallet import SERVICE_NAME From 54158737a4887096715b734d0b7fb43280acc8ab Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Thu, 21 Jul 2022 16:59:43 -0400 Subject: [PATCH 17/28] Revert "make separate funcs files to align with rest of codebase" This reverts commit dad21be089b7efe383cf047710d02ea260c84168. --- chia/cmds/peer.py | 124 +++++++++++++- chia/cmds/peer_funcs.py | 115 ------------- chia/cmds/show.py | 349 ++++++++++++++++++++++++++++++-------- chia/cmds/show_funcs.py | 213 ----------------------- chia/cmds/wallet_funcs.py | 2 +- 5 files changed, 401 insertions(+), 402 deletions(-) delete mode 100644 chia/cmds/peer_funcs.py delete mode 100644 chia/cmds/show_funcs.py diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index 4a1fdb2a38f0..76770ed1f461 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -1,7 +1,123 @@ -from typing import Optional +from typing import Any, Dict, Optional + import click -from chia.cmds.peer_funcs import peer_async -from chia.cmds.show_funcs import execute_with_node + +from chia.cmds.show import execute_with_node +from chia.rpc.full_node_rpc_client import FullNodeRpcClient +from chia.rpc.rpc_client import RpcClient + + +async def add_node_connection(rpc_client: RpcClient, add_connection: str) -> None: + if ":" not in add_connection: + print("Enter a valid IP and port in the following format: 10.5.4.3:8000") + else: + ip, port = ( + ":".join(add_connection.split(":")[:-1]), + add_connection.split(":")[-1], + ) + print(f"Connecting to {ip}, {port}") + try: + await rpc_client.open_connection(ip, int(port)) + except Exception: + print(f"Failed to connect to {ip}:{port}") + + +async def remove_node_connection(rpc_client: RpcClient, remove_connection: str) -> None: + from chia.server.outbound_message import NodeType + + result_txt = "" + if len(remove_connection) != 8: + result_txt = "Invalid NodeID. Do not include '.'" + else: + connections = await rpc_client.get_connections() + for con in connections: + if remove_connection == con["node_id"].hex()[:8]: + print("Attempting to disconnect", "NodeID", remove_connection) + try: + await rpc_client.close_connection(con["node_id"]) + except Exception: + result_txt = f"Failed to disconnect NodeID {remove_connection}" + else: + result_txt = f"NodeID {remove_connection}... {NodeType(con['type']).name} " + f"{con['peer_host']} disconnected" + elif result_txt == "": + result_txt = f"NodeID {remove_connection}... not found" + print(result_txt) + + +async def print_connections(rpc_client: RpcClient, trusted_peers: Dict[str, Any]) -> None: + import time + + from chia.server.outbound_message import NodeType + from chia.util.network import is_trusted_inner + + connections = await rpc_client.get_connections() + print("Connections:") + print("Type IP Ports NodeID Last Connect" + " MiB Up|Dwn") + for con in connections: + last_connect_tuple = time.struct_time(time.localtime(con["last_message_time"])) + last_connect = time.strftime("%b %d %T", last_connect_tuple) + mb_down = con["bytes_read"] / (1024 * 1024) + mb_up = con["bytes_written"] / (1024 * 1024) + + host = con["peer_host"] + # Strip IPv6 brackets + host = host.strip("[]") + + trusted: bool = is_trusted_inner(host, con["node_id"], trusted_peers, False) + # Nodetype length is 9 because INTRODUCER will be deprecated + if NodeType(con["type"]) is NodeType.FULL_NODE: + peak_height = con.get("peak_height", None) + connection_peak_hash = con.get("peak_hash", None) + if connection_peak_hash is None: + connection_peak_hash = "No Info" + else: + if connection_peak_hash.startswith(("0x", "0X")): + connection_peak_hash = connection_peak_hash[2:] + connection_peak_hash = f"{connection_peak_hash[:8]}..." + con_str = ( + f"{NodeType(con['type']).name:9} {host:38} " + f"{con['peer_port']:5}/{con['peer_server_port']:<5}" + f" {con['node_id'].hex()[:8]}... " + f"{last_connect} " + f"{mb_up:7.1f}|{mb_down:<7.1f}" + f"\n " + ) + if peak_height is not None: + con_str += f"-Height: {peak_height:8.0f} -Hash: {connection_peak_hash}" + else: + con_str += f"-Height: No Info -Hash: {connection_peak_hash}" + # Only show when Trusted is True + if trusted: + con_str += f" -Trusted: {trusted}" + else: + con_str = ( + f"{NodeType(con['type']).name:9} {host:38} " + f"{con['peer_port']:5}/{con['peer_server_port']:<5}" + f" {con['node_id'].hex()[:8]}... " + f"{last_connect} " + f"{mb_up:7.1f}|{mb_down:<7.1f}" + ) + print(con_str) + + +async def peer_async( + rpc_client: RpcClient, + config: Dict[str, Any], + show_connections: bool, + add_connection: str, + remove_connection: str, + #trusted_peers: Dict[str, Any], +) -> None: + # Check or edit node connections + if show_connections: + trusted_peers: Dict[str, Any] = config["full_node"].get("trusted_peers", {}) + await print_connections(rpc_client, trusted_peers) + # if called together with state, leave a blank line + if add_connection: + await add_node_connection(rpc_client, add_connection) + if remove_connection: + await remove_node_connection(rpc_client, remove_connection) @click.command("peer", short_help="Show, or modify peering connections", no_args_is_help=True) @@ -9,7 +125,7 @@ "-p", "--rpc-port", help=( - "Set the port where the Selected Node is hosting the RPC interface. " + "Set the port where the Full Node is hosting the RPC interface. " "See the rpc_port under full_node in config.yaml" ), type=int, diff --git a/chia/cmds/peer_funcs.py b/chia/cmds/peer_funcs.py deleted file mode 100644 index 14de7e5c9394..000000000000 --- a/chia/cmds/peer_funcs.py +++ /dev/null @@ -1,115 +0,0 @@ -from typing import Any, Dict -from chia.rpc.rpc_client import RpcClient - - -async def add_node_connection(rpc_client: RpcClient, add_connection: str) -> None: - if ":" not in add_connection: - print("Enter a valid IP and port in the following format: 10.5.4.3:8000") - else: - ip, port = ( - ":".join(add_connection.split(":")[:-1]), - add_connection.split(":")[-1], - ) - print(f"Connecting to {ip}, {port}") - try: - await rpc_client.open_connection(ip, int(port)) - except Exception: - print(f"Failed to connect to {ip}:{port}") - - -async def remove_node_connection(rpc_client: RpcClient, remove_connection: str) -> None: - from chia.server.outbound_message import NodeType - - result_txt = "" - if len(remove_connection) != 8: - result_txt = "Invalid NodeID. Do not include '.'" - else: - connections = await rpc_client.get_connections() - for con in connections: - if remove_connection == con["node_id"].hex()[:8]: - print("Attempting to disconnect", "NodeID", remove_connection) - try: - await rpc_client.close_connection(con["node_id"]) - except Exception: - result_txt = f"Failed to disconnect NodeID {remove_connection}" - else: - result_txt = f"NodeID {remove_connection}... {NodeType(con['type']).name} " - f"{con['peer_host']} disconnected" - elif result_txt == "": - result_txt = f"NodeID {remove_connection}... not found" - print(result_txt) - - -async def print_connections(rpc_client: RpcClient, trusted_peers: Dict[str, Any]) -> None: - import time - - from chia.server.outbound_message import NodeType - from chia.util.network import is_trusted_inner - - connections = await rpc_client.get_connections() - print("Connections:") - print("Type IP Ports NodeID Last Connect" + " MiB Up|Dwn") - for con in connections: - last_connect_tuple = time.struct_time(time.localtime(con["last_message_time"])) - last_connect = time.strftime("%b %d %T", last_connect_tuple) - mb_down = con["bytes_read"] / (1024 * 1024) - mb_up = con["bytes_written"] / (1024 * 1024) - - host = con["peer_host"] - # Strip IPv6 brackets - host = host.strip("[]") - - trusted: bool = is_trusted_inner(host, con["node_id"], trusted_peers, False) - # Nodetype length is 9 because INTRODUCER will be deprecated - if NodeType(con["type"]) is NodeType.FULL_NODE: - peak_height = con.get("peak_height", None) - connection_peak_hash = con.get("peak_hash", None) - if connection_peak_hash is None: - connection_peak_hash = "No Info" - else: - if connection_peak_hash.startswith(("0x", "0X")): - connection_peak_hash = connection_peak_hash[2:] - connection_peak_hash = f"{connection_peak_hash[:8]}..." - con_str = ( - f"{NodeType(con['type']).name:9} {host:38} " - f"{con['peer_port']:5}/{con['peer_server_port']:<5}" - f" {con['node_id'].hex()[:8]}... " - f"{last_connect} " - f"{mb_up:7.1f}|{mb_down:<7.1f}" - f"\n " - ) - if peak_height is not None: - con_str += f"-Height: {peak_height:8.0f} -Hash: {connection_peak_hash}" - else: - con_str += f"-Height: No Info -Hash: {connection_peak_hash}" - # Only show when Trusted is True - if trusted: - con_str += f" -Trusted: {trusted}" - else: - con_str = ( - f"{NodeType(con['type']).name:9} {host:38} " - f"{con['peer_port']:5}/{con['peer_server_port']:<5}" - f" {con['node_id'].hex()[:8]}... " - f"{last_connect} " - f"{mb_up:7.1f}|{mb_down:<7.1f}" - ) - print(con_str) - - -async def peer_async( - rpc_client: RpcClient, - config: Dict[str, Any], - show_connections: bool, - add_connection: str, - remove_connection: str, - # trusted_peers: Dict[str, Any], -) -> None: - # Check or edit node connections - if show_connections: - trusted_peers: Dict[str, Any] = config["full_node"].get("trusted_peers", {}) - await print_connections(rpc_client, trusted_peers) - # if called together with state, leave a blank line - if add_connection: - await add_node_connection(rpc_client, add_connection) - if remove_connection: - await remove_node_connection(rpc_client, remove_connection) diff --git a/chia/cmds/show.py b/chia/cmds/show.py index 46e6bcb846c8..737e92c39729 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -1,69 +1,280 @@ -from typing import Optional - -import click - -from chia.cmds.show_funcs import show_async, execute_with_node - - -@click.command("show", short_help="Show node information") -@click.option( - "-p", - "--rpc-port", - help=( - "Set the port where the Full Node is hosting the RPC interface. " - "See the rpc_port under full_node in config.yaml" - ), - type=int, - default=None, -) -@click.option( - "-wp", - "--wallet-rpc-port", - help="Set the port where the Wallet is hosting the RPC interface. See the rpc_port under wallet in config.yaml", - type=int, - default=None, -) -@click.option("-s", "--state", help="Show the current state of the blockchain", is_flag=True, type=bool, default=False) -@click.option( - "-c", "--connections", help="List nodes connected to this Full Node", is_flag=True, type=bool, default=False -) -@click.option("-a", "--add-connection", help="Connect to another Full Node by ip:port", type=str, default="") -@click.option( - "-r", "--remove-connection", help="Remove a Node by the first 8 characters of NodeID", type=str, default="" -) -@click.option( - "-bh", "--block-header-hash-by-height", help="Look up a block header hash by block height", type=str, default="" -) -@click.option("-b", "--block-by-header-hash", help="Look up a block by block header hash", type=str, default="") -@click.pass_context -def show_cmd( - ctx: click.Context, - rpc_port: Optional[int], - wallet_rpc_port: Optional[int], - state: bool, - connections: bool, - add_connection: str, - remove_connection: str, - block_header_hash_by_height: str, - block_by_header_hash: str, -) -> None: - import asyncio - - if connections: - print("'chia show -c' has been renamed to 'chia peer -c' ") - if add_connection != "": - print("'chia show -a' has been renamed to 'chia peer -a' ") - if remove_connection != "": - print("'chia show -r' has been renamed to 'chia peer -r' ") - if wallet_rpc_port is not None: - print("'chia show -wp' is not used, please remove it from your command.") - asyncio.run( - execute_with_node( - rpc_port, - show_async, - ctx.obj["root_path"], - state, - block_header_hash_by_height, - block_by_header_hash, - ) - ) +from pathlib import Path +from typing import Any, Callable, Dict, List, Optional, Union + +import click + +from chia.rpc.full_node_rpc_client import FullNodeRpcClient +from chia.util.default_root import DEFAULT_ROOT_PATH + + +async def print_blockchain_state(node_client: FullNodeRpcClient, config: Dict) -> bool: + # node_client is FullNodeRpcClient + import time + + from chia.consensus.block_record import BlockRecord + from chia.util.ints import uint64 + from chia.util.misc import format_bytes + + blockchain_state = await node_client.get_blockchain_state() + if blockchain_state is None: + print("There is no blockchain found yet. Try again shortly") + return True + peak: Optional[BlockRecord] = blockchain_state["peak"] + node_id = blockchain_state["node_id"] + difficulty = blockchain_state["difficulty"] + sub_slot_iters = blockchain_state["sub_slot_iters"] + synced = blockchain_state["sync"]["synced"] + sync_mode = blockchain_state["sync"]["sync_mode"] + total_iters = peak.total_iters if peak is not None else 0 + num_blocks: int = 10 + network_name = config["selected_network"] + genesis_challenge = config["farmer"]["network_overrides"]["constants"][network_name]["GENESIS_CHALLENGE"] + full_node_port = config["full_node"]["port"] + full_node_rpc_port = config["full_node"]["rpc_port"] + + print(f"Network: {network_name} Port: {full_node_port} RPC Port: {full_node_rpc_port}") + print(f"Node ID: {node_id}") + print(f"Genesis Challenge: {genesis_challenge}") + + if synced: + print("Current Blockchain Status: Full Node Synced") + print("\nPeak: Hash:", peak.header_hash if peak is not None else "") + elif peak is not None and sync_mode: + sync_max_block = blockchain_state["sync"]["sync_tip_height"] + sync_current_block = blockchain_state["sync"]["sync_progress_height"] + print( + f"Current Blockchain Status: Syncing {sync_current_block}/{sync_max_block} " + f"({sync_max_block - sync_current_block} behind)." + ) + print("Peak: Hash:", peak.header_hash if peak is not None else "") + elif peak is not None: + print(f"Current Blockchain Status: Not Synced. Peak height: {peak.height}") + else: + print("\nSearching for an initial chain\n") + print("You may be able to expedite with 'chia show -a host:port' using a known node.\n") + + if peak is not None: + if peak.is_transaction_block: + peak_time = peak.timestamp + else: + peak_hash = peak.header_hash + curr = await node_client.get_block_record(peak_hash) + while curr is not None and not curr.is_transaction_block: + curr = await node_client.get_block_record(curr.prev_hash) + if curr is not None: + peak_time = curr.timestamp + else: + peak_time = uint64(0) + peak_time_struct = time.struct_time(time.localtime(peak_time)) + + print( + " Time:", + f"{time.strftime('%a %b %d %Y %T %Z', peak_time_struct)}", + f" Height: {peak.height:>10}\n", + ) + + print("Estimated network space: ", end="") + print(format_bytes(blockchain_state["space"])) + print(f"Current difficulty: {difficulty}") + print(f"Current VDF sub_slot_iters: {sub_slot_iters}") + print("Total iterations since the start of the blockchain:", total_iters) + print("\n Height: | Hash:") + + added_blocks: List[BlockRecord] = [] + curr = await node_client.get_block_record(peak.header_hash) + while curr is not None and len(added_blocks) < num_blocks and curr.height > 0: + added_blocks.append(curr) + curr = await node_client.get_block_record(curr.prev_hash) + + for b in added_blocks: + print(f"{b.height:>9} | {b.header_hash}") + else: + print("Blockchain has no blocks yet") + return True + + +async def print_block_from_hash(node_client: FullNodeRpcClient, config: Dict, block_by_header_hash: str) -> None: + import time + + from chia.consensus.block_record import BlockRecord + from chia.types.blockchain_format.sized_bytes import bytes32 + from chia.types.full_block import FullBlock + from chia.util.bech32m import encode_puzzle_hash + from chia.util.byte_types import hexstr_to_bytes + + block: Optional[BlockRecord] = await node_client.get_block_record(hexstr_to_bytes(block_by_header_hash)) + full_block: Optional[FullBlock] = await node_client.get_block(hexstr_to_bytes(block_by_header_hash)) + # Would like to have a verbose flag for this + if block is not None: + assert full_block is not None + prev_b = await node_client.get_block_record(block.prev_hash) + if prev_b is not None: + difficulty = block.weight - prev_b.weight + else: + difficulty = block.weight + if block.is_transaction_block: + assert full_block.transactions_info is not None + block_time = time.struct_time( + time.localtime( + full_block.foliage_transaction_block.timestamp if full_block.foliage_transaction_block else None + ) + ) + block_time_string = time.strftime("%a %b %d %Y %T %Z", block_time) + cost = str(full_block.transactions_info.cost) + tx_filter_hash: Union[str, bytes32] = "Not a transaction block" + if full_block.foliage_transaction_block: + tx_filter_hash = full_block.foliage_transaction_block.filter_hash + fees: Any = block.fees + else: + block_time_string = "Not a transaction block" + cost = "Not a transaction block" + tx_filter_hash = "Not a transaction block" + fees = "Not a transaction block" + address_prefix = config["network_overrides"]["config"][config["selected_network"]]["address_prefix"] + farmer_address = encode_puzzle_hash(block.farmer_puzzle_hash, address_prefix) + pool_address = encode_puzzle_hash(block.pool_puzzle_hash, address_prefix) + pool_pk = ( + full_block.reward_chain_block.proof_of_space.pool_public_key + if full_block.reward_chain_block.proof_of_space.pool_public_key is not None + else "Pay to pool puzzle hash" + ) + print( + f"Block Height {block.height}\n" + f"Header Hash 0x{block.header_hash.hex()}\n" + f"Timestamp {block_time_string}\n" + f"Weight {block.weight}\n" + f"Previous Block 0x{block.prev_hash.hex()}\n" + f"Difficulty {difficulty}\n" + f"Sub-slot iters {block.sub_slot_iters}\n" + f"Cost {cost}\n" + f"Total VDF Iterations {block.total_iters}\n" + f"Is a Transaction Block?{block.is_transaction_block}\n" + f"Deficit {block.deficit}\n" + f"PoSpace 'k' Size {full_block.reward_chain_block.proof_of_space.size}\n" + f"Plot Public Key 0x{full_block.reward_chain_block.proof_of_space.plot_public_key}\n" + f"Pool Public Key {pool_pk}\n" + f"Tx Filter Hash {tx_filter_hash}\n" + f"Farmer Address {farmer_address}\n" + f"Pool Address {pool_address}\n" + f"Fees Amount {fees}\n" + ) + else: + print("Block with header hash", block_by_header_hash, "not found") + + +async def execute_with_node( + rpc_port: Optional[int], function: Callable, root_path: Path = DEFAULT_ROOT_PATH, *args +) -> None: + import traceback + from aiohttp import ClientConnectorError + + from chia.util.config import load_config + from chia.util.ints import uint16 + + config = load_config(root_path, "config.yaml") + self_hostname = config["self_hostname"] + if rpc_port is None: + rpc_port = config["full_node"]["rpc_port"] + try: + node_client: FullNodeRpcClient = await FullNodeRpcClient.create( + self_hostname, uint16(rpc_port), root_path, config + ) + await function(node_client, config, *args) + + except Exception as e: + if isinstance(e, ClientConnectorError): + print(f"Connection error. Check if full node rpc is running at {rpc_port}") + print("This is normal if full node is still starting up") + else: + tb = traceback.format_exc() + print(f"Exception from 'show' {tb}") + + node_client.close() + await node_client.await_closed() + + +async def show_async( + node_client: FullNodeRpcClient, + config: Dict, + state: bool, + block_header_hash_by_height: str, + block_by_header_hash: str, +) -> None: + + # Check State + if state: + if await print_blockchain_state(node_client, config) is True: + return None # if no blockchain is found + # Get Block Information + if block_header_hash_by_height != "": + block_header = await node_client.get_block_record_by_height(block_header_hash_by_height) + if block_header is not None: + print(f"Header hash of block {block_header_hash_by_height}: " f"{block_header.header_hash.hex()}") + else: + print("Block height", block_header_hash_by_height, "not found") + if block_by_header_hash != "": + await print_block_from_hash(node_client, config, block_by_header_hash) + + +@click.command("show", short_help="Show node information") +@click.option( + "-p", + "--rpc-port", + help=( + "Set the port where the Full Node is hosting the RPC interface. " + "See the rpc_port under full_node in config.yaml" + ), + type=int, + default=None, +) +@click.option( + "-wp", + "--wallet-rpc-port", + help="Set the port where the Wallet is hosting the RPC interface. See the rpc_port under wallet in config.yaml", + type=int, + default=None, +) +@click.option("-s", "--state", help="Show the current state of the blockchain", is_flag=True, type=bool, default=False) +@click.option( + "-c", "--connections", help="List nodes connected to this Full Node", is_flag=True, type=bool, default=False +) +@click.option("-a", "--add-connection", help="Connect to another Full Node by ip:port", type=str, default="") +@click.option( + "-r", "--remove-connection", help="Remove a Node by the first 8 characters of NodeID", type=str, default="" +) +@click.option( + "-bh", "--block-header-hash-by-height", help="Look up a block header hash by block height", type=str, default="" +) +@click.option("-b", "--block-by-header-hash", help="Look up a block by block header hash", type=str, default="") +@click.pass_context +def show_cmd( + ctx: click.Context, + rpc_port: Optional[int], + wallet_rpc_port: Optional[int], + state: bool, + connections: bool, + add_connection: str, + remove_connection: str, + block_header_hash_by_height: str, + block_by_header_hash: str, +) -> None: + import asyncio + + if connections: + print("'chia show -c' has been renamed to 'chia peer -c' ") + if add_connection != "": + print("'chia show -a' has been renamed to 'chia peer -a' ") + if remove_connection != "": + print("'chia show -r' has been renamed to 'chia peer -r' ") + if wallet_rpc_port is not None: + print("'chia show -wp' is not used, please remove it from your command.") + asyncio.run( + execute_with_node( + rpc_port, + show_async, + ctx.obj["root_path"], + state, + block_header_hash_by_height, + block_by_header_hash, + ) + ) diff --git a/chia/cmds/show_funcs.py b/chia/cmds/show_funcs.py deleted file mode 100644 index 267ec71dbabe..000000000000 --- a/chia/cmds/show_funcs.py +++ /dev/null @@ -1,213 +0,0 @@ -from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Union - -from chia.rpc.full_node_rpc_client import FullNodeRpcClient -from chia.util.default_root import DEFAULT_ROOT_PATH - - -async def print_blockchain_state(node_client: FullNodeRpcClient, config: Dict) -> bool: - # node_client is FullNodeRpcClient - import time - - from chia.consensus.block_record import BlockRecord - from chia.util.ints import uint64 - from chia.util.misc import format_bytes - - blockchain_state = await node_client.get_blockchain_state() - if blockchain_state is None: - print("There is no blockchain found yet. Try again shortly") - return True - peak: Optional[BlockRecord] = blockchain_state["peak"] - node_id = blockchain_state["node_id"] - difficulty = blockchain_state["difficulty"] - sub_slot_iters = blockchain_state["sub_slot_iters"] - synced = blockchain_state["sync"]["synced"] - sync_mode = blockchain_state["sync"]["sync_mode"] - total_iters = peak.total_iters if peak is not None else 0 - num_blocks: int = 10 - network_name = config["selected_network"] - genesis_challenge = config["farmer"]["network_overrides"]["constants"][network_name]["GENESIS_CHALLENGE"] - full_node_port = config["full_node"]["port"] - full_node_rpc_port = config["full_node"]["rpc_port"] - - print(f"Network: {network_name} Port: {full_node_port} RPC Port: {full_node_rpc_port}") - print(f"Node ID: {node_id}") - print(f"Genesis Challenge: {genesis_challenge}") - - if synced: - print("Current Blockchain Status: Full Node Synced") - print("\nPeak: Hash:", peak.header_hash if peak is not None else "") - elif peak is not None and sync_mode: - sync_max_block = blockchain_state["sync"]["sync_tip_height"] - sync_current_block = blockchain_state["sync"]["sync_progress_height"] - print( - f"Current Blockchain Status: Syncing {sync_current_block}/{sync_max_block} " - f"({sync_max_block - sync_current_block} behind)." - ) - print("Peak: Hash:", peak.header_hash if peak is not None else "") - elif peak is not None: - print(f"Current Blockchain Status: Not Synced. Peak height: {peak.height}") - else: - print("\nSearching for an initial chain\n") - print("You may be able to expedite with 'chia show -a host:port' using a known node.\n") - - if peak is not None: - if peak.is_transaction_block: - peak_time = peak.timestamp - else: - peak_hash = peak.header_hash - curr = await node_client.get_block_record(peak_hash) - while curr is not None and not curr.is_transaction_block: - curr = await node_client.get_block_record(curr.prev_hash) - if curr is not None: - peak_time = curr.timestamp - else: - peak_time = uint64(0) - peak_time_struct = time.struct_time(time.localtime(peak_time)) - - print( - " Time:", - f"{time.strftime('%a %b %d %Y %T %Z', peak_time_struct)}", - f" Height: {peak.height:>10}\n", - ) - - print("Estimated network space: ", end="") - print(format_bytes(blockchain_state["space"])) - print(f"Current difficulty: {difficulty}") - print(f"Current VDF sub_slot_iters: {sub_slot_iters}") - print("Total iterations since the start of the blockchain:", total_iters) - print("\n Height: | Hash:") - - added_blocks: List[BlockRecord] = [] - curr = await node_client.get_block_record(peak.header_hash) - while curr is not None and len(added_blocks) < num_blocks and curr.height > 0: - added_blocks.append(curr) - curr = await node_client.get_block_record(curr.prev_hash) - - for b in added_blocks: - print(f"{b.height:>9} | {b.header_hash}") - else: - print("Blockchain has no blocks yet") - return True - - -async def print_block_from_hash(node_client: FullNodeRpcClient, config: Dict, block_by_header_hash: str) -> None: - import time - - from chia.consensus.block_record import BlockRecord - from chia.types.blockchain_format.sized_bytes import bytes32 - from chia.types.full_block import FullBlock - from chia.util.bech32m import encode_puzzle_hash - from chia.util.byte_types import hexstr_to_bytes - - block: Optional[BlockRecord] = await node_client.get_block_record(hexstr_to_bytes(block_by_header_hash)) - full_block: Optional[FullBlock] = await node_client.get_block(hexstr_to_bytes(block_by_header_hash)) - # Would like to have a verbose flag for this - if block is not None: - assert full_block is not None - prev_b = await node_client.get_block_record(block.prev_hash) - if prev_b is not None: - difficulty = block.weight - prev_b.weight - else: - difficulty = block.weight - if block.is_transaction_block: - assert full_block.transactions_info is not None - block_time = time.struct_time( - time.localtime( - full_block.foliage_transaction_block.timestamp if full_block.foliage_transaction_block else None - ) - ) - block_time_string = time.strftime("%a %b %d %Y %T %Z", block_time) - cost = str(full_block.transactions_info.cost) - tx_filter_hash: Union[str, bytes32] = "Not a transaction block" - if full_block.foliage_transaction_block: - tx_filter_hash = full_block.foliage_transaction_block.filter_hash - fees: Any = block.fees - else: - block_time_string = "Not a transaction block" - cost = "Not a transaction block" - tx_filter_hash = "Not a transaction block" - fees = "Not a transaction block" - address_prefix = config["network_overrides"]["config"][config["selected_network"]]["address_prefix"] - farmer_address = encode_puzzle_hash(block.farmer_puzzle_hash, address_prefix) - pool_address = encode_puzzle_hash(block.pool_puzzle_hash, address_prefix) - pool_pk = ( - full_block.reward_chain_block.proof_of_space.pool_public_key - if full_block.reward_chain_block.proof_of_space.pool_public_key is not None - else "Pay to pool puzzle hash" - ) - print( - f"Block Height {block.height}\n" - f"Header Hash 0x{block.header_hash.hex()}\n" - f"Timestamp {block_time_string}\n" - f"Weight {block.weight}\n" - f"Previous Block 0x{block.prev_hash.hex()}\n" - f"Difficulty {difficulty}\n" - f"Sub-slot iters {block.sub_slot_iters}\n" - f"Cost {cost}\n" - f"Total VDF Iterations {block.total_iters}\n" - f"Is a Transaction Block?{block.is_transaction_block}\n" - f"Deficit {block.deficit}\n" - f"PoSpace 'k' Size {full_block.reward_chain_block.proof_of_space.size}\n" - f"Plot Public Key 0x{full_block.reward_chain_block.proof_of_space.plot_public_key}\n" - f"Pool Public Key {pool_pk}\n" - f"Tx Filter Hash {tx_filter_hash}\n" - f"Farmer Address {farmer_address}\n" - f"Pool Address {pool_address}\n" - f"Fees Amount {fees}\n" - ) - else: - print("Block with header hash", block_by_header_hash, "not found") - - -async def execute_with_node( - rpc_port: Optional[int], function: Callable, root_path: Path = DEFAULT_ROOT_PATH, *args -) -> None: - import traceback - from aiohttp import ClientConnectorError - - from chia.util.config import load_config - from chia.util.ints import uint16 - - config = load_config(root_path, "config.yaml") - self_hostname = config["self_hostname"] - if rpc_port is None: - rpc_port = config["full_node"]["rpc_port"] - try: - node_client: FullNodeRpcClient = await FullNodeRpcClient.create( - self_hostname, uint16(rpc_port), root_path, config - ) - await function(node_client, config, *args) - - except Exception as e: - if isinstance(e, ClientConnectorError): - print(f"Connection error. Check if full node rpc is running at {rpc_port}") - print("This is normal if full node is still starting up") - else: - tb = traceback.format_exc() - print(f"Exception from 'show' {tb}") - - node_client.close() - await node_client.await_closed() - - -async def show_async( - node_client: FullNodeRpcClient, - config: Dict, - state: bool, - block_header_hash_by_height: str, - block_by_header_hash: str, -) -> None: - # Check State - if state: - if await print_blockchain_state(node_client, config) is True: - return None # if no blockchain is found - # Get Block Information - if block_header_hash_by_height != "": - block_header = await node_client.get_block_record_by_height(block_header_hash_by_height) - if block_header is not None: - print(f"Header hash of block {block_header_hash_by_height}: " f"{block_header.header_hash.hex()}") - else: - print("Block height", block_header_hash_by_height, "not found") - if block_by_header_hash != "": - await print_block_from_hash(node_client, config, block_by_header_hash) diff --git a/chia/cmds/wallet_funcs.py b/chia/cmds/wallet_funcs.py index 78964157ed51..b2eed746940a 100644 --- a/chia/cmds/wallet_funcs.py +++ b/chia/cmds/wallet_funcs.py @@ -9,7 +9,7 @@ import aiohttp from chia.cmds.cmds_util import transaction_status_msg, transaction_submitted_msg -from chia.cmds.peer_funcs import print_connections +from chia.cmds.peer import print_connections from chia.cmds.units import units from chia.rpc.wallet_rpc_client import WalletRpcClient from chia.server.start_wallet import SERVICE_NAME From cf9b2409b807dcaef45e42351a7d317e42287bbf Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Thu, 21 Jul 2022 17:05:45 -0400 Subject: [PATCH 18/28] remake changes --- chia/cmds/peer.py | 124 +--------------------- chia/cmds/peer_funcs.py | 115 ++++++++++++++++++++ chia/cmds/show.py | 216 +------------------------------------- chia/cmds/show_funcs.py | 214 +++++++++++++++++++++++++++++++++++++ chia/cmds/wallet_funcs.py | 2 +- 5 files changed, 336 insertions(+), 335 deletions(-) create mode 100644 chia/cmds/peer_funcs.py create mode 100644 chia/cmds/show_funcs.py diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index 76770ed1f461..4a1fdb2a38f0 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -1,123 +1,7 @@ -from typing import Any, Dict, Optional - +from typing import Optional import click - -from chia.cmds.show import execute_with_node -from chia.rpc.full_node_rpc_client import FullNodeRpcClient -from chia.rpc.rpc_client import RpcClient - - -async def add_node_connection(rpc_client: RpcClient, add_connection: str) -> None: - if ":" not in add_connection: - print("Enter a valid IP and port in the following format: 10.5.4.3:8000") - else: - ip, port = ( - ":".join(add_connection.split(":")[:-1]), - add_connection.split(":")[-1], - ) - print(f"Connecting to {ip}, {port}") - try: - await rpc_client.open_connection(ip, int(port)) - except Exception: - print(f"Failed to connect to {ip}:{port}") - - -async def remove_node_connection(rpc_client: RpcClient, remove_connection: str) -> None: - from chia.server.outbound_message import NodeType - - result_txt = "" - if len(remove_connection) != 8: - result_txt = "Invalid NodeID. Do not include '.'" - else: - connections = await rpc_client.get_connections() - for con in connections: - if remove_connection == con["node_id"].hex()[:8]: - print("Attempting to disconnect", "NodeID", remove_connection) - try: - await rpc_client.close_connection(con["node_id"]) - except Exception: - result_txt = f"Failed to disconnect NodeID {remove_connection}" - else: - result_txt = f"NodeID {remove_connection}... {NodeType(con['type']).name} " - f"{con['peer_host']} disconnected" - elif result_txt == "": - result_txt = f"NodeID {remove_connection}... not found" - print(result_txt) - - -async def print_connections(rpc_client: RpcClient, trusted_peers: Dict[str, Any]) -> None: - import time - - from chia.server.outbound_message import NodeType - from chia.util.network import is_trusted_inner - - connections = await rpc_client.get_connections() - print("Connections:") - print("Type IP Ports NodeID Last Connect" + " MiB Up|Dwn") - for con in connections: - last_connect_tuple = time.struct_time(time.localtime(con["last_message_time"])) - last_connect = time.strftime("%b %d %T", last_connect_tuple) - mb_down = con["bytes_read"] / (1024 * 1024) - mb_up = con["bytes_written"] / (1024 * 1024) - - host = con["peer_host"] - # Strip IPv6 brackets - host = host.strip("[]") - - trusted: bool = is_trusted_inner(host, con["node_id"], trusted_peers, False) - # Nodetype length is 9 because INTRODUCER will be deprecated - if NodeType(con["type"]) is NodeType.FULL_NODE: - peak_height = con.get("peak_height", None) - connection_peak_hash = con.get("peak_hash", None) - if connection_peak_hash is None: - connection_peak_hash = "No Info" - else: - if connection_peak_hash.startswith(("0x", "0X")): - connection_peak_hash = connection_peak_hash[2:] - connection_peak_hash = f"{connection_peak_hash[:8]}..." - con_str = ( - f"{NodeType(con['type']).name:9} {host:38} " - f"{con['peer_port']:5}/{con['peer_server_port']:<5}" - f" {con['node_id'].hex()[:8]}... " - f"{last_connect} " - f"{mb_up:7.1f}|{mb_down:<7.1f}" - f"\n " - ) - if peak_height is not None: - con_str += f"-Height: {peak_height:8.0f} -Hash: {connection_peak_hash}" - else: - con_str += f"-Height: No Info -Hash: {connection_peak_hash}" - # Only show when Trusted is True - if trusted: - con_str += f" -Trusted: {trusted}" - else: - con_str = ( - f"{NodeType(con['type']).name:9} {host:38} " - f"{con['peer_port']:5}/{con['peer_server_port']:<5}" - f" {con['node_id'].hex()[:8]}... " - f"{last_connect} " - f"{mb_up:7.1f}|{mb_down:<7.1f}" - ) - print(con_str) - - -async def peer_async( - rpc_client: RpcClient, - config: Dict[str, Any], - show_connections: bool, - add_connection: str, - remove_connection: str, - #trusted_peers: Dict[str, Any], -) -> None: - # Check or edit node connections - if show_connections: - trusted_peers: Dict[str, Any] = config["full_node"].get("trusted_peers", {}) - await print_connections(rpc_client, trusted_peers) - # if called together with state, leave a blank line - if add_connection: - await add_node_connection(rpc_client, add_connection) - if remove_connection: - await remove_node_connection(rpc_client, remove_connection) +from chia.cmds.peer_funcs import peer_async +from chia.cmds.show_funcs import execute_with_node @click.command("peer", short_help="Show, or modify peering connections", no_args_is_help=True) @@ -125,7 +9,7 @@ async def peer_async( "-p", "--rpc-port", help=( - "Set the port where the Full Node is hosting the RPC interface. " + "Set the port where the Selected Node is hosting the RPC interface. " "See the rpc_port under full_node in config.yaml" ), type=int, diff --git a/chia/cmds/peer_funcs.py b/chia/cmds/peer_funcs.py new file mode 100644 index 000000000000..14de7e5c9394 --- /dev/null +++ b/chia/cmds/peer_funcs.py @@ -0,0 +1,115 @@ +from typing import Any, Dict +from chia.rpc.rpc_client import RpcClient + + +async def add_node_connection(rpc_client: RpcClient, add_connection: str) -> None: + if ":" not in add_connection: + print("Enter a valid IP and port in the following format: 10.5.4.3:8000") + else: + ip, port = ( + ":".join(add_connection.split(":")[:-1]), + add_connection.split(":")[-1], + ) + print(f"Connecting to {ip}, {port}") + try: + await rpc_client.open_connection(ip, int(port)) + except Exception: + print(f"Failed to connect to {ip}:{port}") + + +async def remove_node_connection(rpc_client: RpcClient, remove_connection: str) -> None: + from chia.server.outbound_message import NodeType + + result_txt = "" + if len(remove_connection) != 8: + result_txt = "Invalid NodeID. Do not include '.'" + else: + connections = await rpc_client.get_connections() + for con in connections: + if remove_connection == con["node_id"].hex()[:8]: + print("Attempting to disconnect", "NodeID", remove_connection) + try: + await rpc_client.close_connection(con["node_id"]) + except Exception: + result_txt = f"Failed to disconnect NodeID {remove_connection}" + else: + result_txt = f"NodeID {remove_connection}... {NodeType(con['type']).name} " + f"{con['peer_host']} disconnected" + elif result_txt == "": + result_txt = f"NodeID {remove_connection}... not found" + print(result_txt) + + +async def print_connections(rpc_client: RpcClient, trusted_peers: Dict[str, Any]) -> None: + import time + + from chia.server.outbound_message import NodeType + from chia.util.network import is_trusted_inner + + connections = await rpc_client.get_connections() + print("Connections:") + print("Type IP Ports NodeID Last Connect" + " MiB Up|Dwn") + for con in connections: + last_connect_tuple = time.struct_time(time.localtime(con["last_message_time"])) + last_connect = time.strftime("%b %d %T", last_connect_tuple) + mb_down = con["bytes_read"] / (1024 * 1024) + mb_up = con["bytes_written"] / (1024 * 1024) + + host = con["peer_host"] + # Strip IPv6 brackets + host = host.strip("[]") + + trusted: bool = is_trusted_inner(host, con["node_id"], trusted_peers, False) + # Nodetype length is 9 because INTRODUCER will be deprecated + if NodeType(con["type"]) is NodeType.FULL_NODE: + peak_height = con.get("peak_height", None) + connection_peak_hash = con.get("peak_hash", None) + if connection_peak_hash is None: + connection_peak_hash = "No Info" + else: + if connection_peak_hash.startswith(("0x", "0X")): + connection_peak_hash = connection_peak_hash[2:] + connection_peak_hash = f"{connection_peak_hash[:8]}..." + con_str = ( + f"{NodeType(con['type']).name:9} {host:38} " + f"{con['peer_port']:5}/{con['peer_server_port']:<5}" + f" {con['node_id'].hex()[:8]}... " + f"{last_connect} " + f"{mb_up:7.1f}|{mb_down:<7.1f}" + f"\n " + ) + if peak_height is not None: + con_str += f"-Height: {peak_height:8.0f} -Hash: {connection_peak_hash}" + else: + con_str += f"-Height: No Info -Hash: {connection_peak_hash}" + # Only show when Trusted is True + if trusted: + con_str += f" -Trusted: {trusted}" + else: + con_str = ( + f"{NodeType(con['type']).name:9} {host:38} " + f"{con['peer_port']:5}/{con['peer_server_port']:<5}" + f" {con['node_id'].hex()[:8]}... " + f"{last_connect} " + f"{mb_up:7.1f}|{mb_down:<7.1f}" + ) + print(con_str) + + +async def peer_async( + rpc_client: RpcClient, + config: Dict[str, Any], + show_connections: bool, + add_connection: str, + remove_connection: str, + # trusted_peers: Dict[str, Any], +) -> None: + # Check or edit node connections + if show_connections: + trusted_peers: Dict[str, Any] = config["full_node"].get("trusted_peers", {}) + await print_connections(rpc_client, trusted_peers) + # if called together with state, leave a blank line + if add_connection: + await add_node_connection(rpc_client, add_connection) + if remove_connection: + await remove_node_connection(rpc_client, remove_connection) diff --git a/chia/cmds/show.py b/chia/cmds/show.py index 0e50b4dd7d4c..6d40971179a2 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -1,219 +1,7 @@ -from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Union - +from typing import Optional import click -from chia.rpc.full_node_rpc_client import FullNodeRpcClient -from chia.util.default_root import DEFAULT_ROOT_PATH - - -async def print_blockchain_state(node_client: FullNodeRpcClient, config: Dict) -> bool: - # node_client is FullNodeRpcClient - import time - - from chia.consensus.block_record import BlockRecord - from chia.util.ints import uint64 - from chia.util.misc import format_bytes - - blockchain_state = await node_client.get_blockchain_state() - if blockchain_state is None: - print("There is no blockchain found yet. Try again shortly") - return True - peak: Optional[BlockRecord] = blockchain_state["peak"] - node_id = blockchain_state["node_id"] - difficulty = blockchain_state["difficulty"] - sub_slot_iters = blockchain_state["sub_slot_iters"] - synced = blockchain_state["sync"]["synced"] - sync_mode = blockchain_state["sync"]["sync_mode"] - total_iters = peak.total_iters if peak is not None else 0 - num_blocks: int = 10 - network_name = config["selected_network"] - genesis_challenge = config["farmer"]["network_overrides"]["constants"][network_name]["GENESIS_CHALLENGE"] - full_node_port = config["full_node"]["port"] - full_node_rpc_port = config["full_node"]["rpc_port"] - - print(f"Network: {network_name} Port: {full_node_port} RPC Port: {full_node_rpc_port}") - print(f"Node ID: {node_id}") - print(f"Genesis Challenge: {genesis_challenge}") - - if synced: - print("Current Blockchain Status: Full Node Synced") - print("\nPeak: Hash:", peak.header_hash if peak is not None else "") - elif peak is not None and sync_mode: - sync_max_block = blockchain_state["sync"]["sync_tip_height"] - sync_current_block = blockchain_state["sync"]["sync_progress_height"] - print( - f"Current Blockchain Status: Syncing {sync_current_block}/{sync_max_block} " - f"({sync_max_block - sync_current_block} behind)." - ) - print("Peak: Hash:", peak.header_hash if peak is not None else "") - elif peak is not None: - print(f"Current Blockchain Status: Not Synced. Peak height: {peak.height}") - else: - print("\nSearching for an initial chain\n") - print("You may be able to expedite with 'chia show -a host:port' using a known node.\n") - - if peak is not None: - if peak.is_transaction_block: - peak_time = peak.timestamp - else: - peak_hash = peak.header_hash - curr = await node_client.get_block_record(peak_hash) - while curr is not None and not curr.is_transaction_block: - curr = await node_client.get_block_record(curr.prev_hash) - if curr is not None: - peak_time = curr.timestamp - else: - peak_time = uint64(0) - peak_time_struct = time.struct_time(time.localtime(peak_time)) - - print( - " Time:", - f"{time.strftime('%a %b %d %Y %T %Z', peak_time_struct)}", - f" Height: {peak.height:>10}\n", - ) - - print("Estimated network space: ", end="") - print(format_bytes(blockchain_state["space"])) - print(f"Current difficulty: {difficulty}") - print(f"Current VDF sub_slot_iters: {sub_slot_iters}") - print("Total iterations since the start of the blockchain:", total_iters) - print("\n Height: | Hash:") - - added_blocks: List[BlockRecord] = [] - curr = await node_client.get_block_record(peak.header_hash) - while curr is not None and len(added_blocks) < num_blocks and curr.height > 0: - added_blocks.append(curr) - curr = await node_client.get_block_record(curr.prev_hash) - - for b in added_blocks: - print(f"{b.height:>9} | {b.header_hash}") - else: - print("Blockchain has no blocks yet") - return True - - -async def print_block_from_hash(node_client: FullNodeRpcClient, config: Dict, block_by_header_hash: str) -> None: - import time - - from chia.consensus.block_record import BlockRecord - from chia.types.blockchain_format.sized_bytes import bytes32 - from chia.types.full_block import FullBlock - from chia.util.bech32m import encode_puzzle_hash - from chia.util.byte_types import hexstr_to_bytes - - block: Optional[BlockRecord] = await node_client.get_block_record(hexstr_to_bytes(block_by_header_hash)) - full_block: Optional[FullBlock] = await node_client.get_block(hexstr_to_bytes(block_by_header_hash)) - # Would like to have a verbose flag for this - if block is not None: - assert full_block is not None - prev_b = await node_client.get_block_record(block.prev_hash) - if prev_b is not None: - difficulty = block.weight - prev_b.weight - else: - difficulty = block.weight - if block.is_transaction_block: - assert full_block.transactions_info is not None - block_time = time.struct_time( - time.localtime( - full_block.foliage_transaction_block.timestamp if full_block.foliage_transaction_block else None - ) - ) - block_time_string = time.strftime("%a %b %d %Y %T %Z", block_time) - cost = str(full_block.transactions_info.cost) - tx_filter_hash: Union[str, bytes32] = "Not a transaction block" - if full_block.foliage_transaction_block: - tx_filter_hash = full_block.foliage_transaction_block.filter_hash - fees: Any = block.fees - else: - block_time_string = "Not a transaction block" - cost = "Not a transaction block" - tx_filter_hash = "Not a transaction block" - fees = "Not a transaction block" - address_prefix = config["network_overrides"]["config"][config["selected_network"]]["address_prefix"] - farmer_address = encode_puzzle_hash(block.farmer_puzzle_hash, address_prefix) - pool_address = encode_puzzle_hash(block.pool_puzzle_hash, address_prefix) - pool_pk = ( - full_block.reward_chain_block.proof_of_space.pool_public_key - if full_block.reward_chain_block.proof_of_space.pool_public_key is not None - else "Pay to pool puzzle hash" - ) - print( - f"Block Height {block.height}\n" - f"Header Hash 0x{block.header_hash.hex()}\n" - f"Timestamp {block_time_string}\n" - f"Weight {block.weight}\n" - f"Previous Block 0x{block.prev_hash.hex()}\n" - f"Difficulty {difficulty}\n" - f"Sub-slot iters {block.sub_slot_iters}\n" - f"Cost {cost}\n" - f"Total VDF Iterations {block.total_iters}\n" - f"Is a Transaction Block?{block.is_transaction_block}\n" - f"Deficit {block.deficit}\n" - f"PoSpace 'k' Size {full_block.reward_chain_block.proof_of_space.size}\n" - f"Plot Public Key 0x{full_block.reward_chain_block.proof_of_space.plot_public_key}\n" - f"Pool Public Key {pool_pk}\n" - f"Tx Filter Hash {tx_filter_hash}\n" - f"Farmer Address {farmer_address}\n" - f"Pool Address {pool_address}\n" - f"Fees Amount {fees}\n" - ) - else: - print("Block with header hash", block_by_header_hash, "not found") - - -async def execute_with_node( - rpc_port: Optional[int], function: Callable, root_path: Path = DEFAULT_ROOT_PATH, *args -) -> None: - import traceback - from aiohttp import ClientConnectorError - - from chia.util.config import load_config - from chia.util.ints import uint16 - - config = load_config(root_path, "config.yaml") - self_hostname = config["self_hostname"] - if rpc_port is None: - rpc_port = config["full_node"]["rpc_port"] - try: - node_client: FullNodeRpcClient = await FullNodeRpcClient.create( - self_hostname, uint16(rpc_port), root_path, config - ) - await function(node_client, config, *args) - - except Exception as e: - if isinstance(e, ClientConnectorError): - print(f"Connection error. Check if full node rpc is running at {rpc_port}") - print("This is normal if full node is still starting up") - else: - tb = traceback.format_exc() - print(f"Exception from 'show' {tb}") - - node_client.close() - await node_client.await_closed() - - -async def show_async( - node_client: FullNodeRpcClient, - config: Dict, - state: bool, - block_header_hash_by_height: str, - block_by_header_hash: str, -) -> None: - - # Check State - if state: - if await print_blockchain_state(node_client, config) is True: - return None # if no blockchain is found - # Get Block Information - if block_header_hash_by_height != "": - block_header = await node_client.get_block_record_by_height(block_header_hash_by_height) - if block_header is not None: - print(f"Header hash of block {block_header_hash_by_height}: " f"{block_header.header_hash.hex()}") - else: - print("Block height", block_header_hash_by_height, "not found") - if block_by_header_hash != "": - await print_block_from_hash(node_client, config, block_by_header_hash) +from chia.cmds.show_funcs import execute_with_node, show_async @click.command("show", short_help="Show node information", no_args_is_help=True) diff --git a/chia/cmds/show_funcs.py b/chia/cmds/show_funcs.py new file mode 100644 index 000000000000..09a272e880d9 --- /dev/null +++ b/chia/cmds/show_funcs.py @@ -0,0 +1,214 @@ +from pathlib import Path +from typing import Any, Callable, Dict, List, Optional, Union + +from chia.rpc.full_node_rpc_client import FullNodeRpcClient +from chia.util.default_root import DEFAULT_ROOT_PATH + +async def print_blockchain_state(node_client: FullNodeRpcClient, config: Dict) -> bool: + # node_client is FullNodeRpcClient + import time + + from chia.consensus.block_record import BlockRecord + from chia.util.ints import uint64 + from chia.util.misc import format_bytes + + blockchain_state = await node_client.get_blockchain_state() + if blockchain_state is None: + print("There is no blockchain found yet. Try again shortly") + return True + peak: Optional[BlockRecord] = blockchain_state["peak"] + node_id = blockchain_state["node_id"] + difficulty = blockchain_state["difficulty"] + sub_slot_iters = blockchain_state["sub_slot_iters"] + synced = blockchain_state["sync"]["synced"] + sync_mode = blockchain_state["sync"]["sync_mode"] + total_iters = peak.total_iters if peak is not None else 0 + num_blocks: int = 10 + network_name = config["selected_network"] + genesis_challenge = config["farmer"]["network_overrides"]["constants"][network_name]["GENESIS_CHALLENGE"] + full_node_port = config["full_node"]["port"] + full_node_rpc_port = config["full_node"]["rpc_port"] + + print(f"Network: {network_name} Port: {full_node_port} RPC Port: {full_node_rpc_port}") + print(f"Node ID: {node_id}") + print(f"Genesis Challenge: {genesis_challenge}") + + if synced: + print("Current Blockchain Status: Full Node Synced") + print("\nPeak: Hash:", peak.header_hash if peak is not None else "") + elif peak is not None and sync_mode: + sync_max_block = blockchain_state["sync"]["sync_tip_height"] + sync_current_block = blockchain_state["sync"]["sync_progress_height"] + print( + f"Current Blockchain Status: Syncing {sync_current_block}/{sync_max_block} " + f"({sync_max_block - sync_current_block} behind)." + ) + print("Peak: Hash:", peak.header_hash if peak is not None else "") + elif peak is not None: + print(f"Current Blockchain Status: Not Synced. Peak height: {peak.height}") + else: + print("\nSearching for an initial chain\n") + print("You may be able to expedite with 'chia show -a host:port' using a known node.\n") + + if peak is not None: + if peak.is_transaction_block: + peak_time = peak.timestamp + else: + peak_hash = peak.header_hash + curr = await node_client.get_block_record(peak_hash) + while curr is not None and not curr.is_transaction_block: + curr = await node_client.get_block_record(curr.prev_hash) + if curr is not None: + peak_time = curr.timestamp + else: + peak_time = uint64(0) + peak_time_struct = time.struct_time(time.localtime(peak_time)) + + print( + " Time:", + f"{time.strftime('%a %b %d %Y %T %Z', peak_time_struct)}", + f" Height: {peak.height:>10}\n", + ) + + print("Estimated network space: ", end="") + print(format_bytes(blockchain_state["space"])) + print(f"Current difficulty: {difficulty}") + print(f"Current VDF sub_slot_iters: {sub_slot_iters}") + print("Total iterations since the start of the blockchain:", total_iters) + print("\n Height: | Hash:") + + added_blocks: List[BlockRecord] = [] + curr = await node_client.get_block_record(peak.header_hash) + while curr is not None and len(added_blocks) < num_blocks and curr.height > 0: + added_blocks.append(curr) + curr = await node_client.get_block_record(curr.prev_hash) + + for b in added_blocks: + print(f"{b.height:>9} | {b.header_hash}") + else: + print("Blockchain has no blocks yet") + return True + + +async def print_block_from_hash(node_client: FullNodeRpcClient, config: Dict, block_by_header_hash: str) -> None: + import time + + from chia.consensus.block_record import BlockRecord + from chia.types.blockchain_format.sized_bytes import bytes32 + from chia.types.full_block import FullBlock + from chia.util.bech32m import encode_puzzle_hash + from chia.util.byte_types import hexstr_to_bytes + + block: Optional[BlockRecord] = await node_client.get_block_record(hexstr_to_bytes(block_by_header_hash)) + full_block: Optional[FullBlock] = await node_client.get_block(hexstr_to_bytes(block_by_header_hash)) + # Would like to have a verbose flag for this + if block is not None: + assert full_block is not None + prev_b = await node_client.get_block_record(block.prev_hash) + if prev_b is not None: + difficulty = block.weight - prev_b.weight + else: + difficulty = block.weight + if block.is_transaction_block: + assert full_block.transactions_info is not None + block_time = time.struct_time( + time.localtime( + full_block.foliage_transaction_block.timestamp if full_block.foliage_transaction_block else None + ) + ) + block_time_string = time.strftime("%a %b %d %Y %T %Z", block_time) + cost = str(full_block.transactions_info.cost) + tx_filter_hash: Union[str, bytes32] = "Not a transaction block" + if full_block.foliage_transaction_block: + tx_filter_hash = full_block.foliage_transaction_block.filter_hash + fees: Any = block.fees + else: + block_time_string = "Not a transaction block" + cost = "Not a transaction block" + tx_filter_hash = "Not a transaction block" + fees = "Not a transaction block" + address_prefix = config["network_overrides"]["config"][config["selected_network"]]["address_prefix"] + farmer_address = encode_puzzle_hash(block.farmer_puzzle_hash, address_prefix) + pool_address = encode_puzzle_hash(block.pool_puzzle_hash, address_prefix) + pool_pk = ( + full_block.reward_chain_block.proof_of_space.pool_public_key + if full_block.reward_chain_block.proof_of_space.pool_public_key is not None + else "Pay to pool puzzle hash" + ) + print( + f"Block Height {block.height}\n" + f"Header Hash 0x{block.header_hash.hex()}\n" + f"Timestamp {block_time_string}\n" + f"Weight {block.weight}\n" + f"Previous Block 0x{block.prev_hash.hex()}\n" + f"Difficulty {difficulty}\n" + f"Sub-slot iters {block.sub_slot_iters}\n" + f"Cost {cost}\n" + f"Total VDF Iterations {block.total_iters}\n" + f"Is a Transaction Block?{block.is_transaction_block}\n" + f"Deficit {block.deficit}\n" + f"PoSpace 'k' Size {full_block.reward_chain_block.proof_of_space.size}\n" + f"Plot Public Key 0x{full_block.reward_chain_block.proof_of_space.plot_public_key}\n" + f"Pool Public Key {pool_pk}\n" + f"Tx Filter Hash {tx_filter_hash}\n" + f"Farmer Address {farmer_address}\n" + f"Pool Address {pool_address}\n" + f"Fees Amount {fees}\n" + ) + else: + print("Block with header hash", block_by_header_hash, "not found") + + +async def execute_with_node( + rpc_port: Optional[int], function: Callable, root_path: Path = DEFAULT_ROOT_PATH, *args +) -> None: + import traceback + from aiohttp import ClientConnectorError + + from chia.util.config import load_config + from chia.util.ints import uint16 + + config = load_config(root_path, "config.yaml") + self_hostname = config["self_hostname"] + if rpc_port is None: + rpc_port = config["full_node"]["rpc_port"] + try: + node_client: FullNodeRpcClient = await FullNodeRpcClient.create( + self_hostname, uint16(rpc_port), root_path, config + ) + await function(node_client, config, *args) + + except Exception as e: + if isinstance(e, ClientConnectorError): + print(f"Connection error. Check if full node rpc is running at {rpc_port}") + print("This is normal if full node is still starting up") + else: + tb = traceback.format_exc() + print(f"Exception from 'show' {tb}") + + node_client.close() + await node_client.await_closed() + + +async def show_async( + node_client: FullNodeRpcClient, + config: Dict, + state: bool, + block_header_hash_by_height: str, + block_by_header_hash: str, +) -> None: + + # Check State + if state: + if await print_blockchain_state(node_client, config) is True: + return None # if no blockchain is found + # Get Block Information + if block_header_hash_by_height != "": + block_header = await node_client.get_block_record_by_height(block_header_hash_by_height) + if block_header is not None: + print(f"Header hash of block {block_header_hash_by_height}: " f"{block_header.header_hash.hex()}") + else: + print("Block height", block_header_hash_by_height, "not found") + if block_by_header_hash != "": + await print_block_from_hash(node_client, config, block_by_header_hash) + diff --git a/chia/cmds/wallet_funcs.py b/chia/cmds/wallet_funcs.py index 3cce1c931080..723be4472a5e 100644 --- a/chia/cmds/wallet_funcs.py +++ b/chia/cmds/wallet_funcs.py @@ -9,7 +9,7 @@ import aiohttp from chia.cmds.cmds_util import transaction_status_msg, transaction_submitted_msg -from chia.cmds.peer import print_connections +from chia.cmds.peer_funcs import print_connections from chia.cmds.units import units from chia.rpc.wallet_rpc_client import WalletRpcClient from chia.server.start_wallet import SERVICE_NAME From 785ff3d1e60173bb3bfd260b1e81805dd205b704 Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Thu, 21 Jul 2022 18:25:02 -0400 Subject: [PATCH 19/28] lint & finish chia peer --- chia/cmds/peer.py | 12 ++++---- chia/cmds/peer_funcs.py | 63 ++++++++++++++++++++++++++++++++++++++++- chia/cmds/show.py | 6 ++-- chia/cmds/show_funcs.py | 34 +--------------------- 4 files changed, 74 insertions(+), 41 deletions(-) diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index 4a1fdb2a38f0..30c6e84b83be 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -1,7 +1,6 @@ from typing import Optional import click -from chia.cmds.peer_funcs import peer_async -from chia.cmds.show_funcs import execute_with_node +from chia.cmds.peer_funcs import peer_async, NODE_TYPES, execute_with_any_node @click.command("peer", short_help="Show, or modify peering connections", no_args_is_help=True) @@ -9,8 +8,8 @@ "-p", "--rpc-port", help=( - "Set the port where the Selected Node is hosting the RPC interface. " - "See the rpc_port under full_node in config.yaml" + "Set the port where the farmer, wallet, full node or harvester " + "is hosting the RPC interface. See the rpc_port in config.yaml" ), type=int, default=None, @@ -22,6 +21,7 @@ @click.option( "-r", "--remove-connection", help="Remove a Node by the first 8 characters of NodeID", type=str, default="" ) +@click.argument("node_type", type=click.Choice(NODE_TYPES), nargs=-1, required=True) @click.pass_context def peer_cmd( ctx: click.Context, @@ -29,11 +29,13 @@ def peer_cmd( connections: bool, add_connection: str, remove_connection: str, + node_type: str, ) -> None: import asyncio asyncio.run( - execute_with_node( + execute_with_any_node( + node_type, rpc_port, peer_async, ctx.obj["root_path"], diff --git a/chia/cmds/peer_funcs.py b/chia/cmds/peer_funcs.py index 14de7e5c9394..a2eceffdcf1a 100644 --- a/chia/cmds/peer_funcs.py +++ b/chia/cmds/peer_funcs.py @@ -1,5 +1,10 @@ -from typing import Any, Dict +from pathlib import Path +from typing import Any, Dict, Optional, Callable + from chia.rpc.rpc_client import RpcClient +from chia.util.default_root import DEFAULT_ROOT_PATH + +NODE_TYPES = ["farmer", "wallet", "full_node", "harvester"] async def add_node_connection(rpc_client: RpcClient, add_connection: str) -> None: @@ -96,6 +101,62 @@ async def print_connections(rpc_client: RpcClient, trusted_peers: Dict[str, Any] print(con_str) +async def execute_with_any_node( + node_type: str, + rpc_port: Optional[int], + function: Callable, + root_path: Path = DEFAULT_ROOT_PATH, + *args, +) -> Any: + import traceback + from aiohttp import ClientConnectorError + + from chia.util.config import load_config + from chia.util.ints import uint16 + + if node_type not in NODE_TYPES: + print(f"Invalid node type: {node_type}") + return + config = load_config(root_path, "config.yaml") + self_hostname = config["self_hostname"] + if rpc_port is None: + rpc_port = config[node_type]["rpc_port"] + result = None + try: + client_args = self_hostname, uint16(rpc_port), root_path, config + if node_type == "farmer": + from chia.rpc.farmer_rpc_client import FarmerRpcClient + + node_client: FarmerRpcClient = await FarmerRpcClient.create(*client_args) + elif node_type == "wallet": + from chia.rpc.wallet_rpc_client import WalletRpcClient + + node_client: WalletRpcClient = await WalletRpcClient.create(*client_args) + elif node_type == "full_node": + from chia.rpc.full_node_rpc_client import FullNodeRpcClient + + node_client: FullNodeRpcClient = await FullNodeRpcClient.create(*client_args) + elif node_type == "harvester": + from chia.rpc.harvester_rpc_client import HarvesterRpcClient + + node_client: HarvesterRpcClient = await HarvesterRpcClient.create(*client_args) + else: + raise NotImplementedError(f"Missing node type: {node_type}") + result = await function(node_client, config, *args) + + except Exception as e: + if isinstance(e, ClientConnectorError): + print(f"Connection error. Check if full node rpc is running at {rpc_port}") + print(f"This is normal if {node_type.replace('_', ' ')} is still starting up") + else: + tb = traceback.format_exc() + print(f"Exception from 'show' {tb}") + + node_client.close() + await node_client.await_closed() + return result + + async def peer_async( rpc_client: RpcClient, config: Dict[str, Any], diff --git a/chia/cmds/show.py b/chia/cmds/show.py index 6d40971179a2..3acd18519523 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -1,7 +1,8 @@ from typing import Optional import click -from chia.cmds.show_funcs import execute_with_node, show_async +from chia.cmds.peer_funcs import execute_with_any_node +from chia.cmds.show_funcs import show_async @click.command("show", short_help="Show node information", no_args_is_help=True) @@ -57,7 +58,8 @@ def show_cmd( if wallet_rpc_port is not None: print("'chia show -wp' is not used, please remove it from your command.") asyncio.run( - execute_with_node( + execute_with_any_node( + "full_node", rpc_port, show_async, ctx.obj["root_path"], diff --git a/chia/cmds/show_funcs.py b/chia/cmds/show_funcs.py index 09a272e880d9..8473e9953b94 100644 --- a/chia/cmds/show_funcs.py +++ b/chia/cmds/show_funcs.py @@ -4,8 +4,8 @@ from chia.rpc.full_node_rpc_client import FullNodeRpcClient from chia.util.default_root import DEFAULT_ROOT_PATH + async def print_blockchain_state(node_client: FullNodeRpcClient, config: Dict) -> bool: - # node_client is FullNodeRpcClient import time from chia.consensus.block_record import BlockRecord @@ -159,37 +159,6 @@ async def print_block_from_hash(node_client: FullNodeRpcClient, config: Dict, bl print("Block with header hash", block_by_header_hash, "not found") -async def execute_with_node( - rpc_port: Optional[int], function: Callable, root_path: Path = DEFAULT_ROOT_PATH, *args -) -> None: - import traceback - from aiohttp import ClientConnectorError - - from chia.util.config import load_config - from chia.util.ints import uint16 - - config = load_config(root_path, "config.yaml") - self_hostname = config["self_hostname"] - if rpc_port is None: - rpc_port = config["full_node"]["rpc_port"] - try: - node_client: FullNodeRpcClient = await FullNodeRpcClient.create( - self_hostname, uint16(rpc_port), root_path, config - ) - await function(node_client, config, *args) - - except Exception as e: - if isinstance(e, ClientConnectorError): - print(f"Connection error. Check if full node rpc is running at {rpc_port}") - print("This is normal if full node is still starting up") - else: - tb = traceback.format_exc() - print(f"Exception from 'show' {tb}") - - node_client.close() - await node_client.await_closed() - - async def show_async( node_client: FullNodeRpcClient, config: Dict, @@ -211,4 +180,3 @@ async def show_async( print("Block height", block_header_hash_by_height, "not found") if block_by_header_hash != "": await print_block_from_hash(node_client, config, block_by_header_hash) - From 7917dd9ee5c0d1a923626572b904721ea5309297 Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Thu, 21 Jul 2022 18:26:18 -0400 Subject: [PATCH 20/28] isort --- chia/cmds/peer.py | 4 +++- chia/cmds/peer_funcs.py | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index 30c6e84b83be..e30bdace3dd4 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -1,6 +1,8 @@ from typing import Optional + import click -from chia.cmds.peer_funcs import peer_async, NODE_TYPES, execute_with_any_node + +from chia.cmds.peer_funcs import NODE_TYPES, execute_with_any_node, peer_async @click.command("peer", short_help="Show, or modify peering connections", no_args_is_help=True) diff --git a/chia/cmds/peer_funcs.py b/chia/cmds/peer_funcs.py index a2eceffdcf1a..808013450660 100644 --- a/chia/cmds/peer_funcs.py +++ b/chia/cmds/peer_funcs.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Any, Dict, Optional, Callable +from typing import Any, Callable, Dict, Optional from chia.rpc.rpc_client import RpcClient from chia.util.default_root import DEFAULT_ROOT_PATH @@ -109,6 +109,7 @@ async def execute_with_any_node( *args, ) -> Any: import traceback + from aiohttp import ClientConnectorError from chia.util.config import load_config From 4b389b91d7654eb5a35da17d2f9e1bc124432c43 Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Thu, 21 Jul 2022 18:30:39 -0400 Subject: [PATCH 21/28] lint --- chia/cmds/show_funcs.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/chia/cmds/show_funcs.py b/chia/cmds/show_funcs.py index 8473e9953b94..323cccbf29fc 100644 --- a/chia/cmds/show_funcs.py +++ b/chia/cmds/show_funcs.py @@ -1,8 +1,6 @@ -from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Union from chia.rpc.full_node_rpc_client import FullNodeRpcClient -from chia.util.default_root import DEFAULT_ROOT_PATH async def print_blockchain_state(node_client: FullNodeRpcClient, config: Dict) -> bool: From 038cf757eed5b74bce81c628088543bf4f1977c5 Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Thu, 21 Jul 2022 19:15:22 -0400 Subject: [PATCH 22/28] tad more lint never hurt --- chia/cmds/peer_funcs.py | 18 ++++++++++-------- chia/cmds/show_funcs.py | 6 +++--- chia/rpc/rpc_client.py | 4 ++-- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/chia/cmds/peer_funcs.py b/chia/cmds/peer_funcs.py index 808013450660..e18acd3489ef 100644 --- a/chia/cmds/peer_funcs.py +++ b/chia/cmds/peer_funcs.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Any, Callable, Dict, Optional +from typing import Any, Callable, Dict, Optional, Coroutine, Awaitable from chia.rpc.rpc_client import RpcClient from chia.util.default_root import DEFAULT_ROOT_PATH @@ -123,26 +123,28 @@ async def execute_with_any_node( if rpc_port is None: rpc_port = config[node_type]["rpc_port"] result = None + node_client: Optional[RpcClient] = None try: client_args = self_hostname, uint16(rpc_port), root_path, config if node_type == "farmer": from chia.rpc.farmer_rpc_client import FarmerRpcClient - node_client: FarmerRpcClient = await FarmerRpcClient.create(*client_args) + node_client = await FarmerRpcClient.create(*client_args) elif node_type == "wallet": from chia.rpc.wallet_rpc_client import WalletRpcClient - node_client: WalletRpcClient = await WalletRpcClient.create(*client_args) + node_client = await WalletRpcClient.create(*client_args) elif node_type == "full_node": from chia.rpc.full_node_rpc_client import FullNodeRpcClient - node_client: FullNodeRpcClient = await FullNodeRpcClient.create(*client_args) + node_client = await FullNodeRpcClient.create(*client_args) elif node_type == "harvester": from chia.rpc.harvester_rpc_client import HarvesterRpcClient - node_client: HarvesterRpcClient = await HarvesterRpcClient.create(*client_args) + node_client = await HarvesterRpcClient.create(*client_args) else: raise NotImplementedError(f"Missing node type: {node_type}") + assert node_client is not None result = await function(node_client, config, *args) except Exception as e: @@ -152,9 +154,9 @@ async def execute_with_any_node( else: tb = traceback.format_exc() print(f"Exception from 'show' {tb}") - - node_client.close() - await node_client.await_closed() + if node_client is not None: + node_client.close() + await node_client.await_closed() return result diff --git a/chia/cmds/show_funcs.py b/chia/cmds/show_funcs.py index 323cccbf29fc..adde4c06f68a 100644 --- a/chia/cmds/show_funcs.py +++ b/chia/cmds/show_funcs.py @@ -3,7 +3,7 @@ from chia.rpc.full_node_rpc_client import FullNodeRpcClient -async def print_blockchain_state(node_client: FullNodeRpcClient, config: Dict) -> bool: +async def print_blockchain_state(node_client: FullNodeRpcClient, config: Dict[str, Any]) -> bool: import time from chia.consensus.block_record import BlockRecord @@ -88,7 +88,7 @@ async def print_blockchain_state(node_client: FullNodeRpcClient, config: Dict) - return True -async def print_block_from_hash(node_client: FullNodeRpcClient, config: Dict, block_by_header_hash: str) -> None: +async def print_block_from_hash(node_client: FullNodeRpcClient, config: Dict[str, Any], block_by_header_hash: str) -> None: import time from chia.consensus.block_record import BlockRecord @@ -159,7 +159,7 @@ async def print_block_from_hash(node_client: FullNodeRpcClient, config: Dict, bl async def show_async( node_client: FullNodeRpcClient, - config: Dict, + config: Dict[str, Any], state: bool, block_header_hash_by_height: str, block_by_header_hash: str, diff --git a/chia/rpc/rpc_client.py b/chia/rpc/rpc_client.py index 4e7b8f94def2..90f1647617dc 100644 --- a/chia/rpc/rpc_client.py +++ b/chia/rpc/rpc_client.py @@ -70,9 +70,9 @@ async def stop_node(self) -> Dict: async def healthz(self) -> Dict: return await self.fetch("healthz", {}) - def close(self): + def close(self) -> None: self.closing_task = asyncio.create_task(self.session.close()) - async def await_closed(self): + async def await_closed(self) -> None: if self.closing_task is not None: await self.closing_task From b76034bc72e5f080467f948fb7c4fb85d7e2486a Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Thu, 21 Jul 2022 21:48:04 -0400 Subject: [PATCH 23/28] cleaner code is fun Kyle saved me from type hell Co-Authored-By: Kyle Altendorf --- chia/cmds/peer.py | 2 +- chia/cmds/peer_funcs.py | 91 +++++++++++++++++++---------------------- chia/cmds/show_funcs.py | 4 +- 3 files changed, 47 insertions(+), 50 deletions(-) diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index e30bdace3dd4..273ac6ce2800 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -23,7 +23,7 @@ @click.option( "-r", "--remove-connection", help="Remove a Node by the first 8 characters of NodeID", type=str, default="" ) -@click.argument("node_type", type=click.Choice(NODE_TYPES), nargs=-1, required=True) +@click.argument("node_type", type=click.Choice(list(NODE_TYPES.keys())), nargs=1, required=True) @click.pass_context def peer_cmd( ctx: click.Context, diff --git a/chia/cmds/peer_funcs.py b/chia/cmds/peer_funcs.py index e18acd3489ef..7e753edbb520 100644 --- a/chia/cmds/peer_funcs.py +++ b/chia/cmds/peer_funcs.py @@ -1,10 +1,19 @@ from pathlib import Path -from typing import Any, Callable, Dict, Optional, Coroutine, Awaitable +from typing import Any, Callable, Dict, Optional, Type from chia.rpc.rpc_client import RpcClient from chia.util.default_root import DEFAULT_ROOT_PATH +from chia.rpc.farmer_rpc_client import FarmerRpcClient +from chia.rpc.wallet_rpc_client import WalletRpcClient +from chia.rpc.full_node_rpc_client import FullNodeRpcClient +from chia.rpc.harvester_rpc_client import HarvesterRpcClient -NODE_TYPES = ["farmer", "wallet", "full_node", "harvester"] +NODE_TYPES: Dict[str, Type[RpcClient]] = { + "farmer": FarmerRpcClient, + "wallet": WalletRpcClient, + "full_node": FullNodeRpcClient, + "harvester": HarvesterRpcClient, +} async def add_node_connection(rpc_client: RpcClient, add_connection: str) -> None: @@ -101,72 +110,58 @@ async def print_connections(rpc_client: RpcClient, trusted_peers: Dict[str, Any] print(con_str) +async def check_client_connection(rpc_client: RpcClient, node_type: str, rpc_port: int) -> bool: + from aiohttp import ClientConnectorError + + try: + await rpc_client.healthz() + except ClientConnectorError: + print(f"Connection error. Check if {node_type.replace('_', ' ')} rpc is running at {rpc_port}") + print(f"This is normal if {node_type.replace('_', ' ')} is still starting up") + return False + return True + + async def execute_with_any_node( - node_type: str, - rpc_port: Optional[int], - function: Callable, - root_path: Path = DEFAULT_ROOT_PATH, - *args, + node_type: str, + rpc_port: Optional[int], + function: Callable, + root_path: Path = DEFAULT_ROOT_PATH, + *args, ) -> Any: import traceback - from aiohttp import ClientConnectorError from chia.util.config import load_config from chia.util.ints import uint16 - if node_type not in NODE_TYPES: + if node_type not in NODE_TYPES.keys(): print(f"Invalid node type: {node_type}") return config = load_config(root_path, "config.yaml") self_hostname = config["self_hostname"] if rpc_port is None: rpc_port = config[node_type]["rpc_port"] + node_client_type = NODE_TYPES[node_type] result = None - node_client: Optional[RpcClient] = None try: - client_args = self_hostname, uint16(rpc_port), root_path, config - if node_type == "farmer": - from chia.rpc.farmer_rpc_client import FarmerRpcClient - - node_client = await FarmerRpcClient.create(*client_args) - elif node_type == "wallet": - from chia.rpc.wallet_rpc_client import WalletRpcClient - - node_client = await WalletRpcClient.create(*client_args) - elif node_type == "full_node": - from chia.rpc.full_node_rpc_client import FullNodeRpcClient - - node_client = await FullNodeRpcClient.create(*client_args) - elif node_type == "harvester": - from chia.rpc.harvester_rpc_client import HarvesterRpcClient - - node_client = await HarvesterRpcClient.create(*client_args) - else: - raise NotImplementedError(f"Missing node type: {node_type}") - assert node_client is not None - result = await function(node_client, config, *args) - - except Exception as e: - if isinstance(e, ClientConnectorError): - print(f"Connection error. Check if full node rpc is running at {rpc_port}") - print(f"This is normal if {node_type.replace('_', ' ')} is still starting up") - else: - tb = traceback.format_exc() - print(f"Exception from 'show' {tb}") - if node_client is not None: - node_client.close() - await node_client.await_closed() + node_client = await node_client_type.create(self_hostname, uint16(rpc_port), root_path, config) + if check_client_connection(node_client, node_type, rpc_port): + result = await function(node_client, config, *args) + finally: + if node_client is not None: + node_client.close() + await node_client.await_closed() return result async def peer_async( - rpc_client: RpcClient, - config: Dict[str, Any], - show_connections: bool, - add_connection: str, - remove_connection: str, - # trusted_peers: Dict[str, Any], + rpc_client: RpcClient, + config: Dict[str, Any], + show_connections: bool, + add_connection: str, + remove_connection: str, + # trusted_peers: Dict[str, Any], ) -> None: # Check or edit node connections if show_connections: diff --git a/chia/cmds/show_funcs.py b/chia/cmds/show_funcs.py index adde4c06f68a..79d764f1ca19 100644 --- a/chia/cmds/show_funcs.py +++ b/chia/cmds/show_funcs.py @@ -88,7 +88,9 @@ async def print_blockchain_state(node_client: FullNodeRpcClient, config: Dict[st return True -async def print_block_from_hash(node_client: FullNodeRpcClient, config: Dict[str, Any], block_by_header_hash: str) -> None: +async def print_block_from_hash( + node_client: FullNodeRpcClient, config: Dict[str, Any], block_by_header_hash: str +) -> None: import time from chia.consensus.block_record import BlockRecord From 43f1b11b612bd16cd84af86638888e2e6b4732da Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Thu, 21 Jul 2022 21:57:43 -0400 Subject: [PATCH 24/28] final change oops, last lint mypy ignore isort Revert "isort" This reverts commit 4bef38a885c0481ec844a9f06185a4ef993f7374. final change isort does not work on windows --- chia/cmds/cmds_util.py | 61 ++++++++++++++++++++++++++++++++++ chia/cmds/peer.py | 3 +- chia/cmds/peer_funcs.py | 72 ++++------------------------------------- chia/cmds/show.py | 2 +- mypy.ini | 2 +- 5 files changed, 72 insertions(+), 68 deletions(-) diff --git a/chia/cmds/cmds_util.py b/chia/cmds/cmds_util.py index f2c764bfc9a1..03dda579ee4c 100644 --- a/chia/cmds/cmds_util.py +++ b/chia/cmds/cmds_util.py @@ -1,7 +1,23 @@ +from pathlib import Path +from typing import Any, Callable, Dict, Optional, Type + +from chia.rpc.farmer_rpc_client import FarmerRpcClient +from chia.rpc.full_node_rpc_client import FullNodeRpcClient +from chia.rpc.harvester_rpc_client import HarvesterRpcClient +from chia.rpc.rpc_client import RpcClient +from chia.rpc.wallet_rpc_client import WalletRpcClient from chia.types.blockchain_format.sized_bytes import bytes32 from chia.types.mempool_submission_status import MempoolSubmissionStatus +from chia.util.default_root import DEFAULT_ROOT_PATH from chia.wallet.transaction_record import TransactionRecord +NODE_TYPES: Dict[str, Type[RpcClient]] = { + "farmer": FarmerRpcClient, + "wallet": WalletRpcClient, + "full_node": FullNodeRpcClient, + "harvester": HarvesterRpcClient, +} + def transaction_submitted_msg(tx: TransactionRecord) -> str: sent_to = [MempoolSubmissionStatus(s[0], s[1], s[2]).to_json_dict_convenience() for s in tx.sent_to] @@ -10,3 +26,48 @@ def transaction_submitted_msg(tx: TransactionRecord) -> str: def transaction_status_msg(fingerprint: int, tx_id: bytes32) -> str: return f"Run 'chia wallet get_transaction -f {fingerprint} -tx 0x{tx_id}' to get status" + + +async def check_client_connection(rpc_client: RpcClient, node_type: str, rpc_port: int) -> bool: + from aiohttp import ClientConnectorError + + try: + await rpc_client.healthz() + except ClientConnectorError: + print(f"Connection error. Check if {node_type.replace('_', ' ')} rpc is running at {rpc_port}") + print(f"This is normal if {node_type.replace('_', ' ')} is still starting up") + return False + return True + + +async def execute_with_any_node( + node_type: str, + rpc_port: Optional[int], + function: Callable, + root_path: Path = DEFAULT_ROOT_PATH, + *args, +) -> Any: + from chia.util.config import load_config + from chia.util.ints import uint16 + + if node_type not in NODE_TYPES.keys(): + print(f"Invalid node type: {node_type}") + return + # load variables from config file + config = load_config(root_path, "config.yaml") + self_hostname = config["self_hostname"] + if rpc_port is None: + rpc_port = config[node_type]["rpc_port"] + # select node client type based on string + node_client_type = NODE_TYPES[node_type] + result = None + try: + node_client = await node_client_type.create(self_hostname, uint16(rpc_port), root_path, config) + # check if we can connect to node, this makes the code cleaner + if check_client_connection(node_client, node_type, rpc_port): + result = await function(node_client, config, *args) + finally: + if node_client is not None: + node_client.close() + await node_client.await_closed() + return result diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index 273ac6ce2800..3058da316317 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -2,7 +2,8 @@ import click -from chia.cmds.peer_funcs import NODE_TYPES, execute_with_any_node, peer_async +from chia.cmds.cmds_util import NODE_TYPES, execute_with_any_node +from chia.cmds.peer_funcs import peer_async @click.command("peer", short_help="Show, or modify peering connections", no_args_is_help=True) diff --git a/chia/cmds/peer_funcs.py b/chia/cmds/peer_funcs.py index 7e753edbb520..8f6ffa16bf0f 100644 --- a/chia/cmds/peer_funcs.py +++ b/chia/cmds/peer_funcs.py @@ -1,19 +1,6 @@ -from pathlib import Path -from typing import Any, Callable, Dict, Optional, Type +from typing import Any, Dict from chia.rpc.rpc_client import RpcClient -from chia.util.default_root import DEFAULT_ROOT_PATH -from chia.rpc.farmer_rpc_client import FarmerRpcClient -from chia.rpc.wallet_rpc_client import WalletRpcClient -from chia.rpc.full_node_rpc_client import FullNodeRpcClient -from chia.rpc.harvester_rpc_client import HarvesterRpcClient - -NODE_TYPES: Dict[str, Type[RpcClient]] = { - "farmer": FarmerRpcClient, - "wallet": WalletRpcClient, - "full_node": FullNodeRpcClient, - "harvester": HarvesterRpcClient, -} async def add_node_connection(rpc_client: RpcClient, add_connection: str) -> None: @@ -110,58 +97,13 @@ async def print_connections(rpc_client: RpcClient, trusted_peers: Dict[str, Any] print(con_str) -async def check_client_connection(rpc_client: RpcClient, node_type: str, rpc_port: int) -> bool: - from aiohttp import ClientConnectorError - - try: - await rpc_client.healthz() - except ClientConnectorError: - print(f"Connection error. Check if {node_type.replace('_', ' ')} rpc is running at {rpc_port}") - print(f"This is normal if {node_type.replace('_', ' ')} is still starting up") - return False - return True - - -async def execute_with_any_node( - node_type: str, - rpc_port: Optional[int], - function: Callable, - root_path: Path = DEFAULT_ROOT_PATH, - *args, -) -> Any: - import traceback - - - from chia.util.config import load_config - from chia.util.ints import uint16 - - if node_type not in NODE_TYPES.keys(): - print(f"Invalid node type: {node_type}") - return - config = load_config(root_path, "config.yaml") - self_hostname = config["self_hostname"] - if rpc_port is None: - rpc_port = config[node_type]["rpc_port"] - node_client_type = NODE_TYPES[node_type] - result = None - try: - node_client = await node_client_type.create(self_hostname, uint16(rpc_port), root_path, config) - if check_client_connection(node_client, node_type, rpc_port): - result = await function(node_client, config, *args) - finally: - if node_client is not None: - node_client.close() - await node_client.await_closed() - return result - - async def peer_async( - rpc_client: RpcClient, - config: Dict[str, Any], - show_connections: bool, - add_connection: str, - remove_connection: str, - # trusted_peers: Dict[str, Any], + rpc_client: RpcClient, + config: Dict[str, Any], + show_connections: bool, + add_connection: str, + remove_connection: str, + # trusted_peers: Dict[str, Any], ) -> None: # Check or edit node connections if show_connections: diff --git a/chia/cmds/show.py b/chia/cmds/show.py index 3acd18519523..ebdc825f1d28 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -1,7 +1,7 @@ from typing import Optional import click -from chia.cmds.peer_funcs import execute_with_any_node +from chia.cmds.cmds_util import execute_with_any_node from chia.cmds.show_funcs import show_async diff --git a/mypy.ini b/mypy.ini index dba101a39043..7680a653b33c 100644 --- a/mypy.ini +++ b/mypy.ini @@ -17,7 +17,7 @@ no_implicit_reexport = True strict_equality = True # list created by: venv/bin/mypy | sed -n 's/.py:.*//p' | sort | uniq | tr '/' '.' | tr '\n' ',' -[mypy-benchmarks.block_ref,benchmarks.block_store,benchmarks.coin_store,benchmarks.utils,build_scripts.installer-version,chia.cmds.configure,chia.cmds.db,chia.cmds.db_upgrade_func,chia.cmds.farm_funcs,chia.cmds.init,chia.cmds.init_funcs,chia.cmds.keys,chia.cmds.keys_funcs,chia.cmds.passphrase,chia.cmds.passphrase_funcs,chia.cmds.plotnft,chia.cmds.plotnft_funcs,chia.cmds.plots,chia.cmds.plotters,chia.cmds.show,chia.cmds.start_funcs,chia.cmds.wallet,chia.cmds.wallet_funcs,chia.daemon.client,chia.daemon.keychain_proxy,chia.daemon.keychain_server,chia.daemon.server,chia.farmer.farmer,chia.farmer.farmer_api,chia.full_node.block_height_map,chia.full_node.block_store,chia.full_node.bundle_tools,chia.full_node.coin_store,chia.full_node.full_node,chia.full_node.full_node_api,chia.full_node.full_node_store,chia.full_node.generator,chia.full_node.hint_store,chia.full_node.lock_queue,chia.full_node.mempool,chia.full_node.mempool_check_conditions,chia.full_node.mempool_manager,chia.full_node.pending_tx_cache,chia.full_node.sync_store,chia.full_node.weight_proof,chia.harvester.harvester,chia.harvester.harvester_api,chia.introducer.introducer,chia.introducer.introducer_api,chia.plotters.bladebit,chia.plotters.chiapos,chia.plotters.install_plotter,chia.plotters.madmax,chia.plotters.plotters,chia.plotters.plotters_util,chia.plotting.check_plots,chia.plotting.create_plots,chia.plotting.manager,chia.plotting.util,chia.pools.pool_config,chia.pools.pool_puzzles,chia.pools.pool_wallet,chia.pools.pool_wallet_info,chia.protocols.pool_protocol,chia.rpc.crawler_rpc_api,chia.rpc.farmer_rpc_api,chia.rpc.farmer_rpc_client,chia.rpc.full_node_rpc_api,chia.rpc.full_node_rpc_client,chia.rpc.harvester_rpc_api,chia.rpc.harvester_rpc_client,chia.rpc.rpc_client,chia.rpc.timelord_rpc_api,chia.rpc.util,chia.rpc.wallet_rpc_api,chia.rpc.wallet_rpc_client,chia.seeder.crawler,chia.seeder.crawler_api,chia.seeder.crawl_store,chia.seeder.dns_server,chia.seeder.peer_record,chia.seeder.start_crawler,chia.server.address_manager,chia.server.address_manager_store,chia.server.connection_utils,chia.server.introducer_peers,chia.server.node_discovery,chia.server.peer_store_resolver,chia.server.rate_limits,chia.server.reconnect_task,chia.server.server,chia.server.ssl_context,chia.server.start_farmer,chia.server.start_full_node,chia.server.start_harvester,chia.server.start_introducer,chia.server.start_service,chia.server.start_timelord,chia.server.start_wallet,chia.server.ws_connection,chia.simulator.full_node_simulator,chia.simulator.start_simulator,chia.ssl.create_ssl,chia.timelord.iters_from_block,chia.timelord.timelord,chia.timelord.timelord_api,chia.timelord.timelord_launcher,chia.timelord.timelord_state,chia.types.announcement,chia.types.blockchain_format.classgroup,chia.types.blockchain_format.coin,chia.types.blockchain_format.program,chia.types.blockchain_format.proof_of_space,chia.types.blockchain_format.tree_hash,chia.types.blockchain_format.vdf,chia.types.full_block,chia.types.header_block,chia.types.mempool_item,chia.types.name_puzzle_condition,chia.types.peer_info,chia.types.spend_bundle,chia.types.transaction_queue_entry,chia.types.unfinished_block,chia.types.unfinished_header_block,chia.util.api_decorators,chia.util.block_cache,chia.util.cached_bls,chia.util.check_fork_next_block,chia.util.chia_logging,chia.util.config,chia.util.db_wrapper,chia.util.dump_keyring,chia.util.file_keyring,chia.util.files,chia.util.hash,chia.util.json_util,chia.util.keychain,chia.util.keyring_wrapper,chia.util.log_exceptions,chia.util.lru_cache,chia.util.make_test_constants,chia.util.merkle_set,chia.util.network,chia.util.partial_func,chia.util.pip_import,chia.util.profiler,chia.util.safe_cancel_task,chia.util.service_groups,chia.util.ssl_check,chia.util.validate_alert,chia.wallet.block_record,chia.wallet.cat_wallet.cat_utils,chia.wallet.cat_wallet.cat_wallet,chia.wallet.cat_wallet.lineage_store,chia.wallet.chialisp,chia.wallet.did_wallet.did_wallet,chia.wallet.did_wallet.did_wallet_puzzles,chia.wallet.key_val_store,chia.wallet.lineage_proof,chia.wallet.nft_wallet.nft_wallet,chia.wallet.payment,chia.wallet.puzzles.load_clvm,chia.wallet.puzzles.p2_conditions,chia.wallet.puzzles.p2_delegated_conditions,chia.wallet.puzzles.p2_delegated_puzzle,chia.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle,chia.wallet.puzzles.p2_m_of_n_delegate_direct,chia.wallet.puzzles.p2_puzzle_hash,chia.wallet.puzzles.prefarm.spend_prefarm,chia.wallet.puzzles.puzzle_utils,chia.wallet.puzzles.rom_bootstrap_generator,chia.wallet.puzzles.singleton_top_layer,chia.wallet.puzzles.tails,chia.wallet.rl_wallet.rl_wallet,chia.wallet.rl_wallet.rl_wallet_puzzles,chia.wallet.secret_key_store,chia.wallet.settings.user_settings,chia.wallet.trade_manager,chia.wallet.trade_record,chia.wallet.trading.offer,chia.wallet.trading.trade_store,chia.wallet.transaction_record,chia.wallet.util.debug_spend_bundle,chia.wallet.util.new_peak_queue,chia.wallet.util.peer_request_cache,chia.wallet.util.wallet_sync_utils,chia.wallet.wallet,chia.wallet.wallet_action_store,chia.wallet.wallet_blockchain,chia.wallet.wallet_coin_store,chia.wallet.wallet_interested_store,chia.wallet.wallet_node,chia.wallet.wallet_node_api,chia.wallet.wallet_pool_store,chia.wallet.wallet_puzzle_store,chia.wallet.wallet_state_manager,chia.wallet.wallet_sync_store,chia.wallet.wallet_transaction_store,chia.wallet.wallet_user_store,chia.wallet.wallet_weight_proof_handler,installhelper,tests.blockchain.blockchain_test_utils,tests.blockchain.test_blockchain,tests.blockchain.test_blockchain_transactions,tests.block_tools,tests.build-init-files,tests.build-workflows,tests.clvm.coin_store,tests.clvm.test_chialisp_deserialization,tests.clvm.test_clvm_compilation,tests.clvm.test_program,tests.clvm.test_puzzle_compression,tests.clvm.test_puzzles,tests.clvm.test_serialized_program,tests.clvm.test_singletons,tests.clvm.test_spend_sim,tests.conftest,tests.connection_utils,tests.core.cmds.test_keys,tests.core.consensus.test_pot_iterations,tests.core.custom_types.test_coin,tests.core.custom_types.test_proof_of_space,tests.core.custom_types.test_spend_bundle,tests.core.daemon.test_daemon,tests.core.full_node.full_sync.test_full_sync,tests.core.full_node.stores.test_block_store,tests.core.full_node.stores.test_coin_store,tests.core.full_node.stores.test_full_node_store,tests.core.full_node.stores.test_hint_store,tests.core.full_node.stores.test_sync_store,tests.core.full_node.test_address_manager,tests.core.full_node.test_block_height_map,tests.core.full_node.test_conditions,tests.core.full_node.test_full_node,tests.core.full_node.test_mempool,tests.core.full_node.test_mempool_performance,tests.core.full_node.test_node_load,tests.core.full_node.test_peer_store_resolver,tests.core.full_node.test_performance,tests.core.full_node.test_transactions,tests.core.make_block_generator,tests.core.node_height,tests.core.server.test_dos,tests.core.server.test_rate_limits,tests.core.ssl.test_ssl,tests.core.test_cost_calculation,tests.core.test_crawler_rpc,tests.core.test_daemon_rpc,tests.core.test_db_conversion,tests.core.test_db_validation,tests.core.test_farmer_harvester_rpc,tests.core.test_filter,tests.core.test_full_node_rpc,tests.core.test_merkle_set,tests.core.test_setproctitle,tests.core.util.test_cached_bls,tests.core.util.test_config,tests.core.util.test_file_keyring_synchronization,tests.core.util.test_files,tests.core.util.test_keychain,tests.core.util.test_keyring_wrapper,tests.core.util.test_lru_cache,tests.core.util.test_significant_bits,tests.farmer_harvester.test_farmer_harvester,tests.generator.test_compression,tests.generator.test_generator_types,tests.generator.test_list_to_batches,tests.generator.test_rom,tests.generator.test_scan,tests.plotting.test_plot_manager,tests.pools.test_pool_cmdline,tests.pools.test_pool_config,tests.pools.test_pool_puzzles_lifecycle,tests.pools.test_pool_rpc,tests.pools.test_wallet_pool_store,tests.setup_nodes,tests.setup_services,tests.simulation.test_simulation,tests.time_out_assert,tests.tools.test_full_sync,tests.tools.test_run_block,tests.util.alert_server,tests.util.benchmark_cost,tests.util.blockchain,tests.util.build_network_protocol_files,tests.util.db_connection,tests.util.generator_tools_testing,tests.util.keyring,tests.util.key_tool,tests.util.rpc,tests.util.test_full_block_utils,tests.util.test_lock_queue,tests.util.test_misc,tests.util.test_network,tests.util.test_network_protocol_files,tests.wallet.cat_wallet.test_cat_lifecycle,tests.wallet.cat_wallet.test_cat_wallet,tests.wallet.cat_wallet.test_offer_lifecycle,tests.wallet.cat_wallet.test_trades,tests.wallet.did_wallet.test_did,tests.wallet.did_wallet.test_did_rpc,tests.wallet.did_wallet.test_nft_rpc,tests.wallet.did_wallet.test_nft_wallet,tests.wallet.rl_wallet.test_rl_rpc,tests.wallet.rl_wallet.test_rl_wallet,tests.wallet.rpc.test_wallet_rpc,tests.wallet.simple_sync.test_simple_sync_protocol,tests.wallet.sync.test_wallet_sync,tests.wallet.test_bech32m,tests.wallet.test_chialisp,tests.wallet.test_puzzle_store,tests.wallet.test_singleton,tests.wallet.test_singleton_lifecycle,tests.wallet.test_singleton_lifecycle_fast,tests.wallet.test_taproot,tests.wallet.test_wallet_blockchain,tests.wallet.test_wallet_interested_store,tests.wallet.test_wallet_key_val_store,tests.wallet.test_wallet_user_store,tests.wallet_tools,tests.weight_proof.test_weight_proof,tools.analyze-chain,tools.run_block,tools.test_full_sync,tests.wallet.nft_wallet.test_nft_wallet,chia.wallet.nft_wallet.nft_puzzles,tests.wallet.nft_wallet.test_nft_puzzles] +[mypy-benchmarks.block_ref,benchmarks.block_store,benchmarks.coin_store,benchmarks.utils,build_scripts.installer-version,chia.cmds.configure,chia.cmds.db,chia.cmds.db_upgrade_func,chia.cmds.farm_funcs,chia.cmds.init,chia.cmds.init_funcs,chia.cmds.keys,chia.cmds.keys_funcs,chia.cmds.passphrase,chia.cmds.passphrase_funcs,chia.cmds.plotnft,chia.cmds.plotnft_funcs,chia.cmds.plots,chia.cmds.plotters,chia.cmds.cmds_util,chia.cmds.start_funcs,chia.cmds.wallet,chia.cmds.wallet_funcs,chia.daemon.client,chia.daemon.keychain_proxy,chia.daemon.keychain_server,chia.daemon.server,chia.farmer.farmer,chia.farmer.farmer_api,chia.full_node.block_height_map,chia.full_node.block_store,chia.full_node.bundle_tools,chia.full_node.coin_store,chia.full_node.full_node,chia.full_node.full_node_api,chia.full_node.full_node_store,chia.full_node.generator,chia.full_node.hint_store,chia.full_node.lock_queue,chia.full_node.mempool,chia.full_node.mempool_check_conditions,chia.full_node.mempool_manager,chia.full_node.pending_tx_cache,chia.full_node.sync_store,chia.full_node.weight_proof,chia.harvester.harvester,chia.harvester.harvester_api,chia.introducer.introducer,chia.introducer.introducer_api,chia.plotters.bladebit,chia.plotters.chiapos,chia.plotters.install_plotter,chia.plotters.madmax,chia.plotters.plotters,chia.plotters.plotters_util,chia.plotting.check_plots,chia.plotting.create_plots,chia.plotting.manager,chia.plotting.util,chia.pools.pool_config,chia.pools.pool_puzzles,chia.pools.pool_wallet,chia.pools.pool_wallet_info,chia.protocols.pool_protocol,chia.rpc.crawler_rpc_api,chia.rpc.farmer_rpc_api,chia.rpc.farmer_rpc_client,chia.rpc.full_node_rpc_api,chia.rpc.full_node_rpc_client,chia.rpc.harvester_rpc_api,chia.rpc.harvester_rpc_client,chia.rpc.rpc_client,chia.rpc.timelord_rpc_api,chia.rpc.util,chia.rpc.wallet_rpc_api,chia.rpc.wallet_rpc_client,chia.seeder.crawler,chia.seeder.crawler_api,chia.seeder.crawl_store,chia.seeder.dns_server,chia.seeder.peer_record,chia.seeder.start_crawler,chia.server.address_manager,chia.server.address_manager_store,chia.server.connection_utils,chia.server.introducer_peers,chia.server.node_discovery,chia.server.peer_store_resolver,chia.server.rate_limits,chia.server.reconnect_task,chia.server.server,chia.server.ssl_context,chia.server.start_farmer,chia.server.start_full_node,chia.server.start_harvester,chia.server.start_introducer,chia.server.start_service,chia.server.start_timelord,chia.server.start_wallet,chia.server.ws_connection,chia.simulator.full_node_simulator,chia.simulator.start_simulator,chia.ssl.create_ssl,chia.timelord.iters_from_block,chia.timelord.timelord,chia.timelord.timelord_api,chia.timelord.timelord_launcher,chia.timelord.timelord_state,chia.types.announcement,chia.types.blockchain_format.classgroup,chia.types.blockchain_format.coin,chia.types.blockchain_format.program,chia.types.blockchain_format.proof_of_space,chia.types.blockchain_format.tree_hash,chia.types.blockchain_format.vdf,chia.types.full_block,chia.types.header_block,chia.types.mempool_item,chia.types.name_puzzle_condition,chia.types.peer_info,chia.types.spend_bundle,chia.types.transaction_queue_entry,chia.types.unfinished_block,chia.types.unfinished_header_block,chia.util.api_decorators,chia.util.block_cache,chia.util.cached_bls,chia.util.check_fork_next_block,chia.util.chia_logging,chia.util.config,chia.util.db_wrapper,chia.util.dump_keyring,chia.util.file_keyring,chia.util.files,chia.util.hash,chia.util.json_util,chia.util.keychain,chia.util.keyring_wrapper,chia.util.log_exceptions,chia.util.lru_cache,chia.util.make_test_constants,chia.util.merkle_set,chia.util.network,chia.util.partial_func,chia.util.pip_import,chia.util.profiler,chia.util.safe_cancel_task,chia.util.service_groups,chia.util.ssl_check,chia.util.validate_alert,chia.wallet.block_record,chia.wallet.cat_wallet.cat_utils,chia.wallet.cat_wallet.cat_wallet,chia.wallet.cat_wallet.lineage_store,chia.wallet.chialisp,chia.wallet.did_wallet.did_wallet,chia.wallet.did_wallet.did_wallet_puzzles,chia.wallet.key_val_store,chia.wallet.lineage_proof,chia.wallet.nft_wallet.nft_wallet,chia.wallet.payment,chia.wallet.puzzles.load_clvm,chia.wallet.puzzles.p2_conditions,chia.wallet.puzzles.p2_delegated_conditions,chia.wallet.puzzles.p2_delegated_puzzle,chia.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle,chia.wallet.puzzles.p2_m_of_n_delegate_direct,chia.wallet.puzzles.p2_puzzle_hash,chia.wallet.puzzles.prefarm.spend_prefarm,chia.wallet.puzzles.puzzle_utils,chia.wallet.puzzles.rom_bootstrap_generator,chia.wallet.puzzles.singleton_top_layer,chia.wallet.puzzles.tails,chia.wallet.rl_wallet.rl_wallet,chia.wallet.rl_wallet.rl_wallet_puzzles,chia.wallet.secret_key_store,chia.wallet.settings.user_settings,chia.wallet.trade_manager,chia.wallet.trade_record,chia.wallet.trading.offer,chia.wallet.trading.trade_store,chia.wallet.transaction_record,chia.wallet.util.debug_spend_bundle,chia.wallet.util.new_peak_queue,chia.wallet.util.peer_request_cache,chia.wallet.util.wallet_sync_utils,chia.wallet.wallet,chia.wallet.wallet_action_store,chia.wallet.wallet_blockchain,chia.wallet.wallet_coin_store,chia.wallet.wallet_interested_store,chia.wallet.wallet_node,chia.wallet.wallet_node_api,chia.wallet.wallet_pool_store,chia.wallet.wallet_puzzle_store,chia.wallet.wallet_state_manager,chia.wallet.wallet_sync_store,chia.wallet.wallet_transaction_store,chia.wallet.wallet_user_store,chia.wallet.wallet_weight_proof_handler,installhelper,tests.blockchain.blockchain_test_utils,tests.blockchain.test_blockchain,tests.blockchain.test_blockchain_transactions,tests.block_tools,tests.build-init-files,tests.build-workflows,tests.clvm.coin_store,tests.clvm.test_chialisp_deserialization,tests.clvm.test_clvm_compilation,tests.clvm.test_program,tests.clvm.test_puzzle_compression,tests.clvm.test_puzzles,tests.clvm.test_serialized_program,tests.clvm.test_singletons,tests.clvm.test_spend_sim,tests.conftest,tests.connection_utils,tests.core.cmds.test_keys,tests.core.consensus.test_pot_iterations,tests.core.custom_types.test_coin,tests.core.custom_types.test_proof_of_space,tests.core.custom_types.test_spend_bundle,tests.core.daemon.test_daemon,tests.core.full_node.full_sync.test_full_sync,tests.core.full_node.stores.test_block_store,tests.core.full_node.stores.test_coin_store,tests.core.full_node.stores.test_full_node_store,tests.core.full_node.stores.test_hint_store,tests.core.full_node.stores.test_sync_store,tests.core.full_node.test_address_manager,tests.core.full_node.test_block_height_map,tests.core.full_node.test_conditions,tests.core.full_node.test_full_node,tests.core.full_node.test_mempool,tests.core.full_node.test_mempool_performance,tests.core.full_node.test_node_load,tests.core.full_node.test_peer_store_resolver,tests.core.full_node.test_performance,tests.core.full_node.test_transactions,tests.core.make_block_generator,tests.core.node_height,tests.core.server.test_dos,tests.core.server.test_rate_limits,tests.core.ssl.test_ssl,tests.core.test_cost_calculation,tests.core.test_crawler_rpc,tests.core.test_daemon_rpc,tests.core.test_db_conversion,tests.core.test_db_validation,tests.core.test_farmer_harvester_rpc,tests.core.test_filter,tests.core.test_full_node_rpc,tests.core.test_merkle_set,tests.core.test_setproctitle,tests.core.util.test_cached_bls,tests.core.util.test_config,tests.core.util.test_file_keyring_synchronization,tests.core.util.test_files,tests.core.util.test_keychain,tests.core.util.test_keyring_wrapper,tests.core.util.test_lru_cache,tests.core.util.test_significant_bits,tests.farmer_harvester.test_farmer_harvester,tests.generator.test_compression,tests.generator.test_generator_types,tests.generator.test_list_to_batches,tests.generator.test_rom,tests.generator.test_scan,tests.plotting.test_plot_manager,tests.pools.test_pool_cmdline,tests.pools.test_pool_config,tests.pools.test_pool_puzzles_lifecycle,tests.pools.test_pool_rpc,tests.pools.test_wallet_pool_store,tests.setup_nodes,tests.setup_services,tests.simulation.test_simulation,tests.time_out_assert,tests.tools.test_full_sync,tests.tools.test_run_block,tests.util.alert_server,tests.util.benchmark_cost,tests.util.blockchain,tests.util.build_network_protocol_files,tests.util.db_connection,tests.util.generator_tools_testing,tests.util.keyring,tests.util.key_tool,tests.util.rpc,tests.util.test_full_block_utils,tests.util.test_lock_queue,tests.util.test_misc,tests.util.test_network,tests.util.test_network_protocol_files,tests.wallet.cat_wallet.test_cat_lifecycle,tests.wallet.cat_wallet.test_cat_wallet,tests.wallet.cat_wallet.test_offer_lifecycle,tests.wallet.cat_wallet.test_trades,tests.wallet.did_wallet.test_did,tests.wallet.did_wallet.test_did_rpc,tests.wallet.did_wallet.test_nft_rpc,tests.wallet.did_wallet.test_nft_wallet,tests.wallet.rl_wallet.test_rl_rpc,tests.wallet.rl_wallet.test_rl_wallet,tests.wallet.rpc.test_wallet_rpc,tests.wallet.simple_sync.test_simple_sync_protocol,tests.wallet.sync.test_wallet_sync,tests.wallet.test_bech32m,tests.wallet.test_chialisp,tests.wallet.test_puzzle_store,tests.wallet.test_singleton,tests.wallet.test_singleton_lifecycle,tests.wallet.test_singleton_lifecycle_fast,tests.wallet.test_taproot,tests.wallet.test_wallet_blockchain,tests.wallet.test_wallet_interested_store,tests.wallet.test_wallet_key_val_store,tests.wallet.test_wallet_user_store,tests.wallet_tools,tests.weight_proof.test_weight_proof,tools.analyze-chain,tools.run_block,tools.test_full_sync,tests.wallet.nft_wallet.test_nft_wallet,chia.wallet.nft_wallet.nft_puzzles,tests.wallet.nft_wallet.test_nft_puzzles] disallow_any_generics = False disallow_subclassing_any = False disallow_untyped_calls = False From bf31816cc9f980150cd7e900c900ffd7f7e973dc Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Thu, 21 Jul 2022 23:20:23 -0400 Subject: [PATCH 25/28] Update cmds_util.py --- chia/cmds/cmds_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chia/cmds/cmds_util.py b/chia/cmds/cmds_util.py index 03dda579ee4c..336d94d1336b 100644 --- a/chia/cmds/cmds_util.py +++ b/chia/cmds/cmds_util.py @@ -64,7 +64,7 @@ async def execute_with_any_node( try: node_client = await node_client_type.create(self_hostname, uint16(rpc_port), root_path, config) # check if we can connect to node, this makes the code cleaner - if check_client_connection(node_client, node_type, rpc_port): + if await check_client_connection(node_client, node_type, rpc_port): result = await function(node_client, config, *args) finally: if node_client is not None: From d5bb5d31c8f212f5bf41fada8fa59dd1a6c54028 Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Fri, 22 Jul 2022 13:43:15 -0400 Subject: [PATCH 26/28] Update chia.py --- chia/cmds/chia.py | 1 - 1 file changed, 1 deletion(-) diff --git a/chia/cmds/chia.py b/chia/cmds/chia.py index 7821e4e5d88f..1439cfca7bf3 100644 --- a/chia/cmds/chia.py +++ b/chia/cmds/chia.py @@ -137,7 +137,6 @@ def run_daemon_cmd(ctx: click.Context, wait_for_unlock: bool) -> None: cli.add_command(passphrase_cmd) - def main() -> None: monkey_patch_click() cli() # pylint: disable=no-value-for-parameter From e8dfcd9b19d0c8b2bf3890441e5fc0e126a34b06 Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Fri, 22 Jul 2022 16:24:36 -0400 Subject: [PATCH 27/28] remove accidental change --- chia/cmds/peer_funcs.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/chia/cmds/peer_funcs.py b/chia/cmds/peer_funcs.py index 8f6ffa16bf0f..a6f49fb35e04 100644 --- a/chia/cmds/peer_funcs.py +++ b/chia/cmds/peer_funcs.py @@ -34,8 +34,9 @@ async def remove_node_connection(rpc_client: RpcClient, remove_connection: str) except Exception: result_txt = f"Failed to disconnect NodeID {remove_connection}" else: - result_txt = f"NodeID {remove_connection}... {NodeType(con['type']).name} " - f"{con['peer_host']} disconnected" + result_txt = ( + f"NodeID {remove_connection}... {NodeType(con['type']).name} {con['peer_host']} disconnected" + ) elif result_txt == "": result_txt = f"NodeID {remove_connection}... not found" print(result_txt) From 042577083fda5608f2162f2fa3551c8cf02101f7 Mon Sep 17 00:00:00 2001 From: Jack Nelson Date: Mon, 25 Jul 2022 01:58:01 -0400 Subject: [PATCH 28/28] rename function makes sense to me --- chia/cmds/cmds_util.py | 2 +- chia/cmds/peer.py | 4 ++-- chia/cmds/show.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/chia/cmds/cmds_util.py b/chia/cmds/cmds_util.py index 336d94d1336b..c7de05fc5433 100644 --- a/chia/cmds/cmds_util.py +++ b/chia/cmds/cmds_util.py @@ -40,7 +40,7 @@ async def check_client_connection(rpc_client: RpcClient, node_type: str, rpc_por return True -async def execute_with_any_node( +async def execute_with_any_service( node_type: str, rpc_port: Optional[int], function: Callable, diff --git a/chia/cmds/peer.py b/chia/cmds/peer.py index 3058da316317..956ecfeab45e 100644 --- a/chia/cmds/peer.py +++ b/chia/cmds/peer.py @@ -2,7 +2,7 @@ import click -from chia.cmds.cmds_util import NODE_TYPES, execute_with_any_node +from chia.cmds.cmds_util import NODE_TYPES, execute_with_any_service from chia.cmds.peer_funcs import peer_async @@ -37,7 +37,7 @@ def peer_cmd( import asyncio asyncio.run( - execute_with_any_node( + execute_with_any_service( node_type, rpc_port, peer_async, diff --git a/chia/cmds/show.py b/chia/cmds/show.py index ebdc825f1d28..2e961ba112fb 100644 --- a/chia/cmds/show.py +++ b/chia/cmds/show.py @@ -1,7 +1,7 @@ from typing import Optional import click -from chia.cmds.cmds_util import execute_with_any_node +from chia.cmds.cmds_util import execute_with_any_service from chia.cmds.show_funcs import show_async @@ -58,7 +58,7 @@ def show_cmd( if wallet_rpc_port is not None: print("'chia show -wp' is not used, please remove it from your command.") asyncio.run( - execute_with_any_node( + execute_with_any_service( "full_node", rpc_port, show_async,