diff --git a/bittensor/commands/stake.py b/bittensor/commands/stake.py index 132529a131..eff415d1a1 100644 --- a/bittensor/commands/stake.py +++ b/bittensor/commands/stake.py @@ -44,19 +44,25 @@ def get_netuid( - cli: "bittensor.cli", subtensor: "bittensor.subtensor" + cli: "bittensor.cli", subtensor: "bittensor.subtensor", prompt: bool = True ) -> Tuple[bool, int]: """Retrieve and validate the netuid from the user or configuration.""" console = Console() - if not cli.config.is_set("netuid"): - try: - cli.config.netuid = int(Prompt.ask("Enter netuid")) - except ValueError: - console.print( - "[red]Invalid input. Please enter a valid integer for netuid.[/red]" - ) - return False, -1 + if not cli.config.is_set("netuid") and prompt: + cli.config.netuid = Prompt.ask("Enter netuid") + try: + cli.config.netuid = int(cli.config.netuid) + except ValueError: + console.print( + "[red]Invalid input. Please enter a valid integer for netuid.[/red]" + ) + return False, -1 netuid = cli.config.netuid + if netuid < 0 or netuid > 65535: + console.print( + "[red]Invalid input. Please enter a valid integer for netuid in subnet range.[/red]" + ) + return False, -1 if not subtensor.subnet_exists(netuid=netuid): console.print( "[red]Network with netuid {} does not exist. Please try again.[/red]".format( @@ -1136,10 +1142,27 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): wallet = bittensor.wallet(config=cli.config) # check all - if not cli.config.is_set("all"): - exists, netuid = get_netuid(cli, subtensor) - if not exists: - return + if cli.config.is_set("all"): + cli.config.netuid = None + cli.config.all = True + elif cli.config.is_set("netuid"): + if cli.config.netuid == "all": + cli.config.all = True + else: + cli.config.netuid = int(cli.config.netuid) + exists, netuid = get_netuid(cli, subtensor) + if not exists: + return + else: + netuid_input = Prompt.ask("Enter netuid or 'all'", default="all") + if netuid_input == "all": + cli.config.netuid = None + cli.config.all = True + else: + cli.config.netuid = int(netuid_input) + exists, netuid = get_netuid(cli, subtensor, False) + if not exists: + return # get parent hotkey hotkey = get_hotkey(wallet, cli.config) @@ -1148,11 +1171,7 @@ def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor"): return try: - netuids = ( - subtensor.get_all_subnet_netuids() - if cli.config.is_set("all") - else [netuid] - ) + netuids = subtensor.get_all_subnet_netuids() if cli.config.all else [netuid] hotkey_stake = GetChildrenCommand.get_parent_stake_info( console, subtensor, hotkey ) @@ -1236,7 +1255,7 @@ def add_args(parser: argparse.ArgumentParser): parser = parser.add_parser( "get_children", help="""Get child hotkeys on subnet.""" ) - parser.add_argument("--netuid", dest="netuid", type=int, required=False) + parser.add_argument("--netuid", dest="netuid", type=str, required=False) parser.add_argument("--hotkey", dest="hotkey", type=str, required=False) parser.add_argument( "--all", @@ -1294,7 +1313,7 @@ def render_table( # Add columns to the table with specific styles table.add_column("Index", style="bold yellow", no_wrap=True, justify="center") - table.add_column("ChildHotkey", style="bold green") + table.add_column("Child Hotkey", style="bold green") table.add_column("Proportion", style="bold cyan", no_wrap=True, justify="right") table.add_column( "Childkey Take", style="bold blue", no_wrap=True, justify="right" diff --git a/tests/e2e_tests/subcommands/subnet/test_metagraph.py b/tests/e2e_tests/subcommands/subnet/test_metagraph.py index e8e18ef617..a57bf67a82 100644 --- a/tests/e2e_tests/subcommands/subnet/test_metagraph.py +++ b/tests/e2e_tests/subcommands/subnet/test_metagraph.py @@ -23,30 +23,35 @@ def test_metagraph_command(local_chain, capsys): logging.info("Testing test_metagraph_command") # Register root as Alice keypair, exec_command, wallet = setup_wallet("//Alice") - exec_command(RegisterSubnetworkCommand, ["s", "create"]) - # Verify subnet 1 created successfully - assert local_chain.query( - "SubtensorModule", "NetworksAdded", [1] - ).serialize(), "Subnet wasn't created successfully" + # The rest of the test will use subnet 2 + netuid = 2 + + for i in range(netuid): + # Register subnet + exec_command(RegisterSubnetworkCommand, ["s", "create"]) + # Verify subnet created successfully + assert local_chain.query( + "SubtensorModule", "NetworksAdded", [i + 1] + ).serialize(), f"Subnet {netuid+1} wasn't created successfully" subtensor = bittensor.subtensor(network="ws://localhost:9945") - metagraph = subtensor.metagraph(netuid=1) + metagraph = subtensor.metagraph(netuid=netuid) # Assert metagraph is empty assert len(metagraph.uids) == 0, "Metagraph is not empty" # Execute btcli metagraph command - exec_command(MetagraphCommand, ["subnet", "metagraph", "--netuid", "1"]) + exec_command(MetagraphCommand, ["subnet", "metagraph", "--netuid", str(netuid)]) captured = capsys.readouterr() - # Assert metagraph is printed for netuid 1 + # Assert metagraph is printed for netuid assert ( - "Metagraph: net: local:1" in captured.out - ), "Netuid 1 was not displayed in metagraph" + f"Metagraph: net: local:{netuid}" in captured.out + ), f"Netuid {netuid} was not displayed in metagraph" # Register Bob as neuron to the subnet bob_keypair, bob_exec_command, bob_wallet = setup_wallet("//Bob") @@ -56,7 +61,7 @@ def test_metagraph_command(local_chain, capsys): "s", "register", "--netuid", - "1", + str(netuid), ], ) @@ -67,7 +72,7 @@ def test_metagraph_command(local_chain, capsys): assert "✅ Registered" in captured.out, "Neuron was not registered" # Refresh the metagraph - metagraph = subtensor.metagraph(netuid=1) + metagraph = subtensor.metagraph(netuid=netuid) # Assert metagraph has registered neuron assert len(metagraph.uids) == 1, "Metagraph doesn't have exactly 1 neuron" @@ -75,15 +80,18 @@ def test_metagraph_command(local_chain, capsys): metagraph.hotkeys[0] == "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty" ), "Neuron's hotkey in metagraph doesn't match" # Execute btcli metagraph command - exec_command(MetagraphCommand, ["subnet", "metagraph", "--netuid", "1"]) + exec_command(MetagraphCommand, ["subnet", "metagraph", "--netuid", str(netuid)]) captured = capsys.readouterr() # Assert the neuron is registered and displayed assert ( - "Metagraph: net: local:1" and "N: 1/1" in captured.out + f"Metagraph: net: local:{netuid}" in captured.out and "N: 1/1" in captured.out ), "Neuron isn't displayed in metagraph" + # Create a secondary metagraph to test .load() later on + metagraph_pre_dave = subtensor.metagraph(netuid=netuid) + # Register Dave as neuron to the subnet dave_keypair, dave_exec_command, dave_wallet = setup_wallet("//Dave") dave_exec_command( @@ -92,7 +100,7 @@ def test_metagraph_command(local_chain, capsys): "s", "register", "--netuid", - "1", + str(netuid), ], ) @@ -103,7 +111,7 @@ def test_metagraph_command(local_chain, capsys): assert "✅ Registered" in captured.out, "Neuron was not registered" # Refresh the metagraph - metagraph = subtensor.metagraph(netuid=1) + metagraph = subtensor.metagraph(netuid=netuid) # Assert metagraph has registered neuron assert len(metagraph.uids) == 2 @@ -112,11 +120,27 @@ def test_metagraph_command(local_chain, capsys): ), "Neuron's hotkey in metagraph doesn't match" # Execute btcli metagraph command - exec_command(MetagraphCommand, ["subnet", "metagraph", "--netuid", "1"]) + exec_command(MetagraphCommand, ["subnet", "metagraph", "--netuid", str(netuid)]) captured = capsys.readouterr() # Assert the neuron is registered and displayed - assert "Metagraph: net: local:1" and "N: 2/2" in captured.out + assert f"Metagraph: net: local:{netuid}" in captured.out + assert "N: 2/2" in captured.out + + # Check save/load cycle + metagraph.save() + metagraph_pre_dave.load() + + # Assert in progressive detail + assert len(metagraph.uids) == len(metagraph_pre_dave.uids) + assert (metagraph.uids == metagraph_pre_dave.uids).all() + + assert len(metagraph.axons) == len(metagraph_pre_dave.axons) + assert metagraph.axons[1].hotkey == metagraph_pre_dave.axons[1].hotkey + assert metagraph.axons == metagraph_pre_dave.axons + + assert len(metagraph.neurons) == len(metagraph_pre_dave.neurons) + assert metagraph.neurons == metagraph_pre_dave.neurons logging.info("Passed test_metagraph_command")