Skip to content

Commit 2bd89de

Browse files
committed
Merge branch 'staging' into changelog/9.11.0
2 parents 3f5d558 + 49b8384 commit 2bd89de

File tree

9 files changed

+505
-34
lines changed

9 files changed

+505
-34
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,22 @@ BTCLI accepts a few environment variables that can alter how it works:
174174
- DISK_CACHE (default 0, also settable in config): If set to 1 (or set in config), will use disk caching for various safe-cachable substrate
175175
calls (such as block number to block hash mapping), which can speed up subsequent calls.
176176
- BTCLI_CONFIG_PATH (default `~/.bittensor/config.yml`): This will set the config file location, creating if it does not exist.
177+
- BTCLI_DEBUG_FILE (default `~/.bittensor/debug.txt`): The file stores the most recent's command's debug log.
178+
179+
---
180+
181+
## Debugging
182+
BTCLI will store a debug log for every command run. This file is overwritten for each new command run. The default location
183+
of this file is `~/.bittensor/debug.txt` and can be set with the `BTCLI_DEBUG_FILE` env var (see above section).
184+
185+
The debug log will **NOT** contain any sensitive data (private keys), and is intended to be sent to the developers
186+
for debugging. This file contains basic information about the command being run, the config, and the back and forth of requests and responses
187+
to and from the chain.
188+
189+
If you encounter an issue, and would like to save the file somewhere it won't be overwritten, run `btcli --debug`,
190+
and set the save file location. We recommend doing this first before anything, and then starting your debugging with
191+
us on our [Discord](https://discord.gg/bittensor), or by opening an issue on [GitHub](https://github.com/opentensor/btcli/issues/new)
192+
(where you can also upload your debug file).
177193

178194
---
179195

bittensor_cli/cli.py

Lines changed: 359 additions & 28 deletions
Large diffs are not rendered by default.

bittensor_cli/src/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class Defaults:
8989
class config:
9090
base_path = "~/.bittensor"
9191
path = "~/.bittensor/config.yml"
92+
debug_file_path = "~/.bittensor/debug.txt"
9293
dictionary = {
9394
"network": None,
9495
"wallet_path": None,

bittensor_cli/src/bittensor/utils.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,10 +269,26 @@ def get_hotkey_wallets_for_wallet(
269269
except FileNotFoundError:
270270
hotkeys = []
271271
for h_name in hotkeys:
272-
hotkey_for_name = Wallet(path=str(wallet_path), name=wallet.name, hotkey=h_name)
272+
if h_name.endswith("pub.txt"):
273+
if h_name.split("pub.txt")[0] in hotkeys:
274+
continue
275+
else:
276+
hotkey_for_name = Wallet(
277+
path=str(wallet_path),
278+
name=wallet.name,
279+
hotkey=h_name.split("pub.txt")[0],
280+
)
281+
else:
282+
hotkey_for_name = Wallet(
283+
path=str(wallet_path), name=wallet.name, hotkey=h_name
284+
)
273285
try:
286+
exists = (
287+
hotkey_for_name.hotkey_file.exists_on_device()
288+
or hotkey_for_name.hotkeypub_file.exists_on_device()
289+
)
274290
if (
275-
(exists := hotkey_for_name.hotkey_file.exists_on_device())
291+
exists
276292
and not hotkey_for_name.hotkey_file.is_encrypted()
277293
# and hotkey_for_name.coldkeypub.ss58_address
278294
and get_hotkey_pub_ss58(hotkey_for_name)

bittensor_cli/src/commands/stake/remove.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ async def unstake(
361361
)
362362
if json_output:
363363
json_console.print(json.dumps(successes))
364+
return True
364365

365366

366367
async def unstake_all(

bittensor_cli/src/commands/subnets/subnets.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2448,3 +2448,71 @@ async def start_subnet(
24482448
await get_start_schedule(subtensor, netuid)
24492449
print_error(f":cross_mark: Failed to start subnet: {error_msg}")
24502450
return False
2451+
2452+
2453+
async def set_symbol(
2454+
wallet: "Wallet",
2455+
subtensor: "SubtensorInterface",
2456+
netuid: int,
2457+
symbol: str,
2458+
prompt: bool = False,
2459+
json_output: bool = False,
2460+
) -> bool:
2461+
"""
2462+
Set a subtensor's symbol, given the netuid and symbol.
2463+
2464+
The symbol must be a symbol that subtensor recognizes as available
2465+
(defined in https://github.com/opentensor/subtensor/blob/main/pallets/subtensor/src/subnets/symbols.rs#L8)
2466+
"""
2467+
if not await subtensor.subnet_exists(netuid):
2468+
err = f"Subnet {netuid} does not exist."
2469+
if json_output:
2470+
json_console.print_json(data={"success": False, "message": err})
2471+
else:
2472+
err_console.print(err)
2473+
return False
2474+
2475+
if prompt and not json_output:
2476+
sn_info = await subtensor.subnet(netuid=netuid)
2477+
if not Confirm.ask(
2478+
f"Your current subnet symbol for SN{netuid} is {sn_info.symbol}. Do you want to update it to {symbol}?"
2479+
):
2480+
return False
2481+
2482+
if not (unlock_status := unlock_key(wallet, print_out=False)).success:
2483+
err = unlock_status.message
2484+
if json_output:
2485+
json_console.print_json(data={"success": False, "message": err})
2486+
else:
2487+
console.print(err)
2488+
return False
2489+
2490+
start_call = await subtensor.substrate.compose_call(
2491+
call_module="SubtensorModule",
2492+
call_function="update_symbol",
2493+
call_params={"netuid": netuid, "symbol": symbol.encode("utf-8")},
2494+
)
2495+
2496+
signed_ext = await subtensor.substrate.create_signed_extrinsic(
2497+
call=start_call,
2498+
keypair=wallet.coldkey,
2499+
)
2500+
2501+
response = await subtensor.substrate.submit_extrinsic(
2502+
extrinsic=signed_ext,
2503+
wait_for_inclusion=True,
2504+
)
2505+
if await response.is_success:
2506+
message = f"Successfully updated SN{netuid}'s symbol to {symbol}."
2507+
if json_output:
2508+
json_console.print_json(data={"success": True, "message": message})
2509+
else:
2510+
console.print(f":white_heavy_check_mark:[dark_sea_green3] {message}\n")
2511+
return True
2512+
else:
2513+
err = format_error_message(await response.error_message)
2514+
if json_output:
2515+
json_console.print_json(data={"success": False, "message": err})
2516+
else:
2517+
err_console.print(f":cross_mark: [red]Failed[/red]: {err}")
2518+
return False

bittensor_cli/src/commands/wallets.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -846,12 +846,21 @@ async def wallet_list(wallet_path: str, json_output: bool):
846846
data = f"[bold red]Hotkey[/bold red][green] {hkey}[/green] (?)"
847847
hk_data = {"name": hkey.name, "ss58_address": "?"}
848848
if hkey:
849-
hkey_ss58 = get_hotkey_pub_ss58(hkey)
849+
try:
850+
hkey_ss58 = hkey.get_hotkey().ss58_address
851+
pub_only = False
852+
except KeyFileError:
853+
hkey_ss58 = hkey.get_hotkeypub().ss58_address
854+
pub_only = True
850855
try:
851856
data = (
852857
f"[bold red]Hotkey[/bold red] [green]{hkey.hotkey_str}[/green] "
853-
f"ss58_address [green]{hkey_ss58}[/green]\n"
858+
f"ss58_address [green]{hkey_ss58}[/green]"
854859
)
860+
if pub_only:
861+
data += " [blue](hotkeypub only)[/blue]\n"
862+
else:
863+
data += "\n"
855864
hk_data["name"] = hkey.hotkey_str
856865
hk_data["ss58_address"] = hkey_ss58
857866
except UnicodeDecodeError:
@@ -1836,7 +1845,7 @@ async def check_coldkey_swap(wallet: Wallet, subtensor: SubtensorInterface):
18361845

18371846

18381847
async def sign(
1839-
wallet: Wallet, message: str, use_hotkey: str, json_output: bool = False
1848+
wallet: Wallet, message: str, use_hotkey: bool, json_output: bool = False
18401849
):
18411850
"""Sign a message using the provided wallet or hotkey."""
18421851

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ scripts = { btcli = "bittensor_cli.cli:main" }
1515
requires-python = ">=3.9,<3.14"
1616
dependencies = [
1717
"wheel",
18-
"async-substrate-interface>=1.4.2",
18+
"async-substrate-interface>=1.5.2",
1919
"aiohttp~=3.10.2",
2020
"backoff~=2.2.1",
2121
"GitPython>=3.0.0",

tests/e2e_tests/test_staking_sudo.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* btcli subnets create
1111
* btcli subnets set-identity
1212
* btcli subnets get-identity
13+
* btcli subnets set-symbol
1314
* btcli subnets register
1415
* btcli subnets price
1516
* btcli stake add
@@ -235,6 +236,34 @@ def test_staking(local_chain, wallet_setup):
235236
assert get_identity_output["logo_url"] == sn_logo_url
236237
assert get_identity_output["additional"] == sn_add_info
237238

239+
# set symbol
240+
set_symbol = exec_command_alice(
241+
"subnets",
242+
"set-symbol",
243+
extra_args=[
244+
"--wallet-path",
245+
wallet_path_alice,
246+
"--wallet-name",
247+
wallet_alice.name,
248+
"--hotkey",
249+
wallet_alice.hotkey_str,
250+
"--chain",
251+
"ws://127.0.0.1:9945",
252+
"--netuid",
253+
netuid,
254+
"--json-output",
255+
"--no-prompt",
256+
"シ",
257+
],
258+
)
259+
set_symbol_output = json.loads(set_symbol.stdout)
260+
assert set_symbol_output["success"] is True, set_symbol_output
261+
assert set_symbol_output["success"] is True, set_symbol_output
262+
assert (
263+
set_symbol_output["message"]
264+
== f"Successfully updated SN{netuid}'s symbol to シ."
265+
)
266+
238267
get_s_price = exec_command_alice(
239268
"subnets",
240269
"price",

0 commit comments

Comments
 (0)