async def summary(rpc_port: int, wallet_rpc_port: int, harvester_rpc_port: int, farmer_rpc_port: int) -> None: amounts = await get_wallets_stats(wallet_rpc_port) plots = await get_plots(harvester_rpc_port) blockchain_state = await get_blockchain_state(rpc_port) farmer_running = await is_farmer_running(farmer_rpc_port) print("Farming status: ", end="") if blockchain_state is None: print("Not available") elif blockchain_state["sync"]["sync_mode"]: print("Syncing") elif not blockchain_state["sync"]["synced"]: print("Not synced or not connected to peers") elif not farmer_running: print("Not running") else: print("Farming") if amounts is not None: print(f"Total chia farmed: {amounts['farmed_amount'] / units['chia']}") print( f"User transaction fees: {amounts['fee_amount'] / units['chia']}") print( f"Block rewards: {(amounts['farmer_reward_amount'] + amounts['pool_reward_amount']) / units['chia']}" ) print(f"Last height farmed: {amounts['last_height_farmed']}") else: print("Total chia farmed: Unknown") print("User transaction fees: Unknown") print("Block rewards: Unknown") print("Last height farmed: Unknown") total_plot_size = 0 if plots is not None: total_plot_size = sum(map(lambda x: x["file_size"], plots["plots"])) print(f"Plot count: {len(plots['plots'])}") print("Total size of plots: ", end="") print(format_bytes(total_plot_size)) else: print("Plot count: Unknown") print("Total size of plots: Unknown") if blockchain_state is not None: print("Estimated network space: ", end="") print(format_bytes(blockchain_state["space"])) else: print("Estimated network space: Unknown") minutes = -1 if blockchain_state is not None and plots is not None: proportion = total_plot_size / blockchain_state[ "space"] if blockchain_state["space"] else -1 minutes = int((await get_average_block_time(rpc_port) / 60) / proportion) if proportion else -1 print("Expected time to win: " + format_minutes(minutes)) print( "Note: log into your key using 'chia wallet show' to see rewards for each key" )
async def netstorge_async(rpc_port: Optional[int], delta_block_height: str, start: str) -> None: """ Calculates the estimated space on the network given two block header hashes. """ try: config = load_config(DEFAULT_ROOT_PATH, "config.yaml") self_hostname = config["self_hostname"] if rpc_port is None: rpc_port = config["full_node"]["rpc_port"] client = await FullNodeRpcClient.create(self_hostname, uint16(rpc_port), DEFAULT_ROOT_PATH, config) if delta_block_height: if start == "": blockchain_state = await client.get_blockchain_state() if blockchain_state["peak"] is None: print("No blocks in blockchain") client.close() await client.await_closed() return None newer_block_height = blockchain_state["peak"].height else: newer_block = await client.get_block_record( hexstr_to_bytes(start)) if newer_block is None: print("Block header hash", start, "not found.") client.close() await client.await_closed() return None else: print("newer_height", newer_block.height) newer_block_height = newer_block.height newer_block_header = await client.get_block_record_by_height( newer_block_height) older_block_height = max( 0, newer_block_height - int(delta_block_height)) older_block_header = await client.get_block_record_by_height( older_block_height) network_space_bytes_estimate = await client.get_network_space( newer_block_header.header_hash, older_block_header.header_hash) print("Older Block\n" f"Block Height: {older_block_header.height}\n" f"Weight: {older_block_header.weight}\n" f"VDF Iterations: {older_block_header.total_iters}\n" f"Header Hash: 0x{older_block_header.header_hash}\n") print("Newer Block\n" f"Block Height: {newer_block_header.height}\n" f"Weight: {newer_block_header.weight}\n" f"VDF Iterations: {newer_block_header.total_iters}\n" f"Header Hash: 0x{newer_block_header.header_hash}\n") print(format_bytes(network_space_bytes_estimate)) except Exception as e: if isinstance(e, aiohttp.ClientConnectorError): print( f"Connection error. Check if full node rpc is running at {rpc_port}" ) else: print(f"Exception {e}") client.close() await client.await_closed()
async def summary( rpc_port: Optional[int], wallet_rpc_port: Optional[int], harvester_rpc_port: Optional[int], farmer_rpc_port: Optional[int], ) -> None: all_harvesters = await get_harvesters(farmer_rpc_port) blockchain_state = await get_blockchain_state(rpc_port) farmer_running = await is_farmer_running(farmer_rpc_port) wallet_not_ready: bool = False wallet_not_running: bool = False amounts = None try: amounts = await get_wallets_stats(wallet_rpc_port) except Exception as e: if isinstance(e, aiohttp.ClientConnectorError): wallet_not_running = True else: wallet_not_ready = True print("Farming status: ", end="") if blockchain_state is None: print("Not available") elif blockchain_state["sync"]["sync_mode"]: print("Syncing") elif not blockchain_state["sync"]["synced"]: print("Not synced or not connected to peers") elif not farmer_running: print("Not running") else: print("Farming") if amounts is not None: print(f"Total chia farmed: {amounts['farmed_amount'] / units['chia']}") print( f"User transaction fees: {amounts['fee_amount'] / units['chia']}") print( f"Block rewards: {(amounts['farmer_reward_amount'] + amounts['pool_reward_amount']) / units['chia']}" ) print(f"Last height farmed: {amounts['last_height_farmed']}") class PlotStats: total_plot_size = 0 total_plots = 0 if all_harvesters is not None: harvesters_local: dict = {} harvesters_remote: dict = {} for harvester in all_harvesters["harvesters"]: ip = harvester["connection"]["host"] if is_localhost(ip): harvesters_local[harvester["connection"] ["node_id"]] = harvester else: if ip not in harvesters_remote: harvesters_remote[ip] = {} harvesters_remote[ip][harvester["connection"] ["node_id"]] = harvester def process_harvesters(harvester_peers_in: dict): for harvester_peer_id, plots in harvester_peers_in.items(): total_plot_size_harvester = sum( map(lambda x: x["file_size"], plots["plots"])) PlotStats.total_plot_size += total_plot_size_harvester PlotStats.total_plots += len(plots["plots"]) print( f" {len(plots['plots'])} plots of size: {format_bytes(total_plot_size_harvester)}" ) if len(harvesters_local) > 0: print(f"Local Harvester{'s' if len(harvesters_local) > 1 else ''}") process_harvesters(harvesters_local) for harvester_ip, harvester_peers in harvesters_remote.items(): print( f"Remote Harvester{'s' if len(harvester_peers) > 1 else ''} for IP: {harvester_ip}" ) process_harvesters(harvester_peers) print(f"Plot count for all harvesters: {PlotStats.total_plots}") print("Total size of plots: ", end="") print(format_bytes(PlotStats.total_plot_size)) else: print("Plot count: Unknown") print("Total size of plots: Unknown") if blockchain_state is not None: print("Estimated network space: ", end="") print(format_bytes(blockchain_state["space"])) else: print("Estimated network space: Unknown") minutes = -1 if blockchain_state is not None and all_harvesters is not None: proportion = PlotStats.total_plot_size / blockchain_state[ "space"] if blockchain_state["space"] else -1 minutes = int((await get_average_block_time(rpc_port) / 60) / proportion) if proportion else -1 if all_harvesters is not None and PlotStats.total_plots == 0: print("Expected time to win: Never (no plots)") else: print("Expected time to win: " + format_minutes(minutes)) if amounts is None: if wallet_not_running: print( "For details on farmed rewards and fees you should run 'chia start wallet' and 'chia wallet show'" ) elif wallet_not_ready: print( "For details on farmed rewards and fees you should run 'chia wallet show'" ) else: print( "Note: log into your key using 'chia wallet show' to see rewards for each key" )
async def show_async( rpc_port: 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: import aiohttp import time import traceback from time import localtime, struct_time 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 from chia.util.config import load_config from chia.util.default_root import DEFAULT_ROOT_PATH from chia.util.ints import uint16 from chia.util.misc import format_bytes try: config = load_config(DEFAULT_ROOT_PATH, "config.yaml") self_hostname = config["self_hostname"] if rpc_port is None: rpc_port = config["full_node"]["rpc_port"] client = await FullNodeRpcClient.create(self_hostname, uint16(rpc_port), DEFAULT_ROOT_PATH, config) if state: blockchain_state = await client.get_blockchain_state() if blockchain_state is None: print("There is no blockchain found yet. Try again shortly") return None peak: Optional[BlockRecord] = blockchain_state["peak"] 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 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}." ) 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 client.get_block_record(peak_hash) while curr is not None and not curr.is_transaction_block: curr = await client.get_block_record(curr.prev_hash) peak_time = curr.timestamp peak_time_struct = struct_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("") print(" Height: | Hash:") added_blocks: List[BlockRecord] = [] curr = await 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 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") # if called together with show_connections, leave a blank line if show_connections: print("") if show_connections: connections = await client.get_connections() print("Connections:") print( "Type IP Ports NodeID Last Connect" + " MiB Up|Dwn") for con in connections: last_connect_tuple = struct_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 if host[0] == "[": host = host[1:39] # Nodetype length is 9 because INTRODUCER will be deprecated if NodeType(con["type"]) is NodeType.FULL_NODE: peak_height = con["peak_height"] peak_hash = con["peak_hash"] if peak_hash is None: peak_hash = "No Info" if peak_height is None: peak_height = 0 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 " f"-SB Height: {peak_height:8.0f} -Hash: {peak_hash[2:10]}..." ) 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) # 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: 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 != "": block: Optional[BlockRecord] = await client.get_block_record( hexstr_to_bytes(block_by_header_hash)) full_block: Optional[FullBlock] = await 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 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 = struct_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 = "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_header_hash_by_height, "not found") 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 'show' {tb}") client.close() await client.await_closed()
async def summary(rpc_port: int, wallet_rpc_port: int, harvester_rpc_port: int, farmer_rpc_port: int) -> None: all_plots = await get_plots(farmer_rpc_port) blockchain_state = await get_blockchain_state(rpc_port) farmer_running = await is_farmer_running(farmer_rpc_port) wallet_not_ready: bool = False wallet_not_running: bool = False amounts = None try: amounts = await get_wallets_stats(wallet_rpc_port) except Exception as e: if isinstance(e, aiohttp.ClientConnectorError): wallet_not_running = True else: wallet_not_ready = True print("Farming status: ", end="") if blockchain_state is None: print("Not available") elif blockchain_state["sync"]["sync_mode"]: print("Syncing") elif not blockchain_state["sync"]["synced"]: print("Not synced or not connected to peers") elif not farmer_running: print("Not running") else: print("Farming") if amounts is not None: print(f"Total chia farmed: {amounts['farmed_amount'] / units['chia']}") print(f"User transaction fees: {amounts['fee_amount'] / units['chia']}") print(f"Block rewards: {(amounts['farmer_reward_amount'] + amounts['pool_reward_amount']) / units['chia']}") print(f"Last height farmed: {amounts['last_height_farmed']}") total_plot_size = 0 total_plots = 0 if all_plots is not None: for harvester_ip, plots in all_plots.items(): if harvester_ip == "success": # This key is just "success": True continue total_plot_size_harvester = sum(map(lambda x: x["file_size"], plots["plots"])) total_plot_size += total_plot_size_harvester total_plots += len(plots["plots"]) print(f"Harvester {harvester_ip}:") print(f" {len(plots['plots'])} plots of size: {format_bytes(total_plot_size_harvester)}") print(f"Plot count for all harvesters: {total_plots}") print("Total size of plots: ", end="") print(format_bytes(total_plot_size)) else: print("Plot count: Unknown") print("Total size of plots: Unknown") if blockchain_state is not None: print("Estimated network space: ", end="") print(format_bytes(blockchain_state["space"])) else: print("Estimated network space: Unknown") minutes = -1 if blockchain_state is not None and all_plots is not None: proportion = total_plot_size / blockchain_state["space"] if blockchain_state["space"] else -1 minutes = int((await get_average_block_time(rpc_port) / 60) / proportion) if proportion else -1 if all_plots is not None and total_plots == 0: print("Expected time to win: Never (no plots)") else: print("Expected time to win: " + format_minutes(minutes)) if amounts is None: if wallet_not_running: print("For details on farmed rewards and fees you should run 'chia start wallet' and 'chia wallet show'") elif wallet_not_ready: print("For details on farmed rewards and fees you should run 'chia wallet show'") else: print("Note: log into your key using 'chia wallet show' to see rewards for each key")