Skip to content

Commit ecbd321

Browse files
committed
Pre-merge merge (async extrinsics)
1 parent d7bc745 commit ecbd321

File tree

14 files changed

+900
-240
lines changed

14 files changed

+900
-240
lines changed

bittensor/core/async_subtensor.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@
2727
PrometheusInfo,
2828
ProposalVoteData,
2929
)
30-
from bittensor.core.extrinsics.asyncio.registration import register_extrinsic
31-
from bittensor.core.extrinsics.asyncio.transfer import transfer_extrinsic
32-
from bittensor.core.extrinsics.asyncio.weights import (
30+
from bittensor.core.extrinsics.asyncex.registration import register_extrinsic
31+
from bittensor.core.extrinsics.asyncex.transfer import transfer_extrinsic
32+
from bittensor.core.extrinsics.asyncex.weights import (
3333
commit_weights_extrinsic,
3434
set_weights_extrinsic,
3535
)
36-
from bittensor.core.extrinsics.asyncio.serving import serve_axon_extrinsic
37-
from bittensor.core.extrinsics.asyncio.unstaking import unstake_extrinsic
38-
from bittensor.core.extrinsics.asyncio.commit_reveal import commit_reveal_v3_extrinsic
36+
from bittensor.core.extrinsics.asyncex.serving import serve_axon_extrinsic
37+
from bittensor.core.extrinsics.asyncex.unstaking import unstake_extrinsic
38+
from bittensor.core.extrinsics.asyncex.commit_reveal import commit_reveal_v3_extrinsic
3939
from bittensor.core.settings import (
4040
TYPE_REGISTRY,
4141
DEFAULTS,
File renamed without changes.

bittensor/core/extrinsics/asyncio/commit_reveal.py renamed to bittensor/core/extrinsics/asyncex/commit_reveal.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
"""This module provides async functionality for commit reveal in the Bittensor network."""
2+
13
from typing import Optional, Union, TYPE_CHECKING
24

35
import numpy as np
46
from bittensor_commit_reveal import get_encrypted_commit
57
from numpy.typing import NDArray
68

7-
from bittensor.core.extrinsics.utils import async_submit_extrinsic
89
from bittensor.core.settings import version_as_int
910
from bittensor.utils import format_error_message
1011
from bittensor.utils.btlogging import logging
@@ -26,10 +27,10 @@ async def _do_commit_reveal_v3(
2627
wait_for_finalization: bool = False,
2728
) -> tuple[bool, Optional[str]]:
2829
"""
29-
Executes the commit-reveal phase 3 for a given netuid and commit, and optionally waits for extrinsic inclusion or
30-
finalization.
30+
Executes the commit-reveal phase 3 for a given netuid and commit, and optionally waits for extrinsic inclusion or finalization.
3131
3232
Arguments:
33+
subtensor: An instance of the Subtensor class.
3334
wallet: Wallet An instance of the Wallet class containing the user's keypair.
3435
netuid: int The network unique identifier.
3536
commit bytes The commit data in bytes format.
@@ -38,8 +39,7 @@ async def _do_commit_reveal_v3(
3839
wait_for_finalization: bool, optional Flag indicating whether to wait for the extrinsic to be finalized.
3940
4041
Returns:
41-
A tuple where the first element is a boolean indicating success or failure, and the second element is an
42-
optional string containing error message if any.
42+
A tuple where the first element is a boolean indicating success or failure, and the second element is an optional string containing error message if any.
4343
"""
4444
logging.info(
4545
f"Committing weights hash [blue]{commit.hex()}[/blue] for subnet #[blue]{netuid}[/blue] with "
@@ -55,13 +55,13 @@ async def _do_commit_reveal_v3(
5555
"reveal_round": reveal_round,
5656
},
5757
)
58+
5859
extrinsic = await subtensor.substrate.create_signed_extrinsic(
5960
call=call,
6061
keypair=wallet.hotkey,
6162
)
6263

63-
response = await async_submit_extrinsic(
64-
subtensor=subtensor,
64+
response = await subtensor.substrate.submit_extrinsic(
6565
extrinsic=extrinsic,
6666
wait_for_inclusion=wait_for_inclusion,
6767
wait_for_finalization=wait_for_finalization,
@@ -70,10 +70,10 @@ async def _do_commit_reveal_v3(
7070
if not wait_for_finalization and not wait_for_inclusion:
7171
return True, "Not waiting for finalization or inclusion."
7272

73-
if response.is_success:
73+
if await response.is_success:
7474
return True, None
75-
else:
76-
return False, format_error_message(response.error_message)
75+
76+
return False, format_error_message(await response.error_message)
7777

7878

7979
async def commit_reveal_v3_extrinsic(
@@ -143,15 +143,15 @@ async def commit_reveal_v3_extrinsic(
143143
wait_for_finalization=wait_for_finalization,
144144
)
145145

146-
if success is True:
147-
logging.success(
148-
f"[green]Finalized![/green] Weights commited with reveal round [blue]{reveal_round}[/blue]."
149-
)
150-
return True, f"reveal_round:{reveal_round}"
151-
else:
146+
if success is not True:
152147
logging.error(message)
153148
return False, message
154149

150+
logging.success(
151+
f"[green]Finalized![/green] Weights commited with reveal round [blue]{reveal_round}[/blue]."
152+
)
153+
return True, f"reveal_round:{reveal_round}"
154+
155155
except Exception as e:
156156
logging.error(f":cross_mark: [red]Failed. Error:[/red] {e}")
157157
return False, str(e)

bittensor/core/extrinsics/asyncio/registration.py renamed to bittensor/core/extrinsics/asyncex/registration.py

Lines changed: 151 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
"""
2-
This module provides functionalities for registering a wallet with the subtensor network using Proof-of-Work (PoW).
2+
This module provides asynchronous functionalities for registering a wallet with the subtensor network using
3+
Proof-of-Work (PoW).
34
45
Extrinsics:
56
- register_extrinsic: Registers the wallet to the subnet.
6-
- run_faucet_extrinsic: Runs a continual POW to get a faucet of TAO on the test net.
7+
- burned_register_extrinsic: Registers the wallet to chain by recycling TAO.
78
"""
89

910
import asyncio
1011
from typing import Optional, Union, TYPE_CHECKING
1112

12-
from bittensor_wallet import Wallet
13-
1413
from bittensor.utils import format_error_message
14+
from bittensor.utils import unlock_key
1515
from bittensor.utils.btlogging import logging
1616
from bittensor.utils.registration import log_no_torch_error, create_pow_async
1717

18-
# For annotation and lazy import purposes
1918
if TYPE_CHECKING:
2019
import torch
20+
from bittensor_wallet import Wallet
2121
from bittensor.core.async_subtensor import AsyncSubtensor
2222
from bittensor.utils.registration.pow import POWSolution
2323
else:
@@ -34,6 +34,147 @@ class MaxAttemptsException(Exception):
3434
"""Raised when the POW Solver has reached the max number of attempts."""
3535

3636

37+
async def _do_burned_register(
38+
subtensor: "AsyncSubtensor",
39+
netuid: int,
40+
wallet: "Wallet",
41+
wait_for_inclusion: bool = False,
42+
wait_for_finalization: bool = True,
43+
) -> tuple[bool, Optional[str]]:
44+
"""
45+
Performs a burned register extrinsic call to the Subtensor chain.
46+
47+
This method sends a registration transaction to the Subtensor blockchain using the burned register mechanism.
48+
49+
Args:
50+
subtensor (bittensor.core.subtensor.Subtensor): Subtensor instance.
51+
netuid (int): The network unique identifier to register on.
52+
wallet (bittensor_wallet.Wallet): The wallet to be registered.
53+
wait_for_inclusion (bool): Whether to wait for the transaction to be included in a block. Default is False.
54+
wait_for_finalization (bool): Whether to wait for the transaction to be finalized. Default is True.
55+
56+
Returns:
57+
Tuple[bool, Optional[str]]: A tuple containing a boolean indicating success or failure, and an optional error message.
58+
"""
59+
60+
# create extrinsic call
61+
call = await subtensor.substrate.compose_call(
62+
call_module="SubtensorModule",
63+
call_function="burned_register",
64+
call_params={
65+
"netuid": netuid,
66+
"hotkey": wallet.hotkey.ss58_address,
67+
},
68+
)
69+
extrinsic = await subtensor.substrate.create_signed_extrinsic(
70+
call=call, keypair=wallet.coldkey
71+
)
72+
response = await subtensor.substrate.submit_extrinsic(
73+
extrinsic=extrinsic,
74+
wait_for_inclusion=wait_for_inclusion,
75+
wait_for_finalization=wait_for_finalization,
76+
)
77+
78+
# We only wait here if we expect finalization.
79+
if not wait_for_finalization and not wait_for_inclusion:
80+
return True, None
81+
82+
# process if registration successful, try again if pow is still valid
83+
if not await response.is_success:
84+
return False, format_error_message(await response.error_message)
85+
# Successful registration
86+
87+
return True, None
88+
89+
90+
async def burned_register_extrinsic(
91+
subtensor: "AsyncSubtensor",
92+
wallet: "Wallet",
93+
netuid: int,
94+
wait_for_inclusion: bool = False,
95+
wait_for_finalization: bool = True,
96+
) -> bool:
97+
"""Registers the wallet to chain by recycling TAO.
98+
99+
Args:
100+
subtensor (bittensor.core.subtensor.Subtensor): Subtensor instance.
101+
wallet (bittensor.wallet): Bittensor wallet object.
102+
netuid (int): The ``netuid`` of the subnet to register on.
103+
wait_for_inclusion (bool): If set, waits for the extrinsic to enter a block before returning ``true``, or
104+
returns ``false`` if the extrinsic fails to enter the block within the timeout.
105+
wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning
106+
``true``, or returns ``false`` if the extrinsic fails to be finalized within the timeout.
107+
108+
Returns:
109+
success (bool): Flag is ``true`` if extrinsic was finalized or uncluded in the block. If we did not wait for finalization / inclusion, the response is ``true``.
110+
"""
111+
if not await subtensor.subnet_exists(netuid):
112+
logging.error(
113+
f":cross_mark: [red]Failed error:[/red] subnet [blue]{netuid}[/blue] does not exist."
114+
)
115+
return False
116+
117+
if not (unlock := unlock_key(wallet)).success:
118+
logging.error(unlock.message)
119+
return False
120+
121+
logging.info(
122+
f":satellite: [magenta]Checking Account on subnet[/magenta] [blue]{netuid}[/blue][magenta] ...[/magenta]"
123+
)
124+
neuron = await subtensor.get_neuron_for_pubkey_and_subnet(
125+
wallet.hotkey.ss58_address, netuid=netuid
126+
)
127+
128+
old_balance = await subtensor.get_balance(wallet.coldkeypub.ss58_address)
129+
130+
if not neuron.is_null:
131+
logging.info(":white_heavy_check_mark: [green]Already Registered[/green]")
132+
logging.info(f"\t\tuid: [blue]{neuron.uid}[/blue]")
133+
logging.info(f"\t\tnetuid: [blue]{neuron.netuid}[/blue]")
134+
logging.info(f"\t\thotkey: [blue]{neuron.hotkey}[/blue]")
135+
logging.info(f"\t\tcoldkey: [blue]{neuron.coldkey}[/blue]")
136+
return True
137+
138+
logging.info(":satellite: [magenta]Recycling TAO for Registration...[/magenta]")
139+
140+
recycle_amount = await subtensor.recycle(netuid=netuid)
141+
logging.info(f"Recycling {recycle_amount} to register on subnet:{netuid}")
142+
143+
success, err_msg = await _do_burned_register(
144+
subtensor=subtensor,
145+
netuid=netuid,
146+
wallet=wallet,
147+
wait_for_inclusion=wait_for_inclusion,
148+
wait_for_finalization=wait_for_finalization,
149+
)
150+
151+
if not success:
152+
logging.error(f":cross_mark: [red]Failed error:[/red] {err_msg}")
153+
await asyncio.sleep(0.5)
154+
return False
155+
# Successful registration, final check for neuron and pubkey
156+
else:
157+
logging.info(":satellite: [magenta]Checking Balance...[/magenta]")
158+
block_hash = await subtensor.substrate.get_chain_head()
159+
new_balance = await subtensor.get_balance(
160+
wallet.coldkeypub.ss58_address, block_hash=block_hash
161+
)
162+
163+
logging.info(
164+
f"Balance: [blue]{old_balance}[/blue] :arrow_right: [green]{new_balance}[/green]"
165+
)
166+
is_registered = await subtensor.is_hotkey_registered(
167+
netuid=netuid, hotkey_ss58=wallet.hotkey.ss58_address
168+
)
169+
if is_registered:
170+
logging.info(":white_heavy_check_mark: [green]Registered[/green]")
171+
return True
172+
else:
173+
# neuron not found, try again
174+
logging.error(":cross_mark: [red]Unknown error. Neuron not found.[/red]")
175+
return False
176+
177+
37178
async def _do_pow_register(
38179
subtensor: "AsyncSubtensor",
39180
netuid: int,
@@ -142,9 +283,11 @@ async def register_extrinsic(
142283
)
143284

144285
if not neuron.is_null:
145-
logging.debug(
146-
f"Wallet [green]{wallet}[/green] is already registered on subnet [blue]{neuron.netuid}[/blue] with uid[blue]{neuron.uid}[/blue]."
147-
)
286+
logging.info(":white_heavy_check_mark: [green]Already Registered[/green]")
287+
logging.info(f"\t\tuid: [blue]{neuron.uid}[/blue]")
288+
logging.info(f"\t\tnetuid: [blue]{neuron.netuid}[/blue]")
289+
logging.info(f"\t\thotkey: [blue]{neuron.hotkey}[/blue]")
290+
logging.info(f"\t\tcoldkey: [blue]{neuron.coldkey}[/blue]")
148291
return True
149292

150293
logging.debug(
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,11 @@ async def _do_set_root_weights(
119119
wallet: "Wallet",
120120
netuids: Union[NDArray[np.int64], list[int]],
121121
weights: Union[NDArray[np.float32], list[float]],
122+
netuid: int = 0,
122123
version_key: int = 0,
123124
wait_for_inclusion: bool = False,
124125
wait_for_finalization: bool = False,
126+
period: int = 5,
125127
) -> tuple[bool, str]:
126128
"""
127129
Sets the root weights on the Subnet for the given wallet hotkey account.
@@ -134,9 +136,11 @@ async def _do_set_root_weights(
134136
wallet (bittensor_wallet.Wallet): The wallet containing the hotkey and coldkey for the transaction.
135137
netuids (Union[NDArray[np.int64], list[int]]): List of UIDs to set weights for.
136138
weights (Union[NDArray[np.float32], list[float]]): Corresponding weights to set for each UID.
139+
netuid (int): The netuid of the subnet to set weights for. Defaults to 0.
137140
version_key (int, optional): The version key of the validator. Defaults to 0.
138141
wait_for_inclusion (bool, optional): If True, waits for the extrinsic to be included in a block. Defaults to False.
139142
wait_for_finalization (bool, optional): If True, waits for the extrinsic to be finalized on the chain. Defaults to False.
143+
period (int, optional): The period in seconds to wait for extrinsic inclusion or finalization. Defaults to 5.
140144
141145
Returns:
142146
tuple: Returns a tuple containing a boolean indicating success and a message describing the result of the operation.
@@ -147,7 +151,7 @@ async def _do_set_root_weights(
147151
call_params={
148152
"dests": netuids,
149153
"weights": weights,
150-
"netuid": 0,
154+
"netuid": netuid,
151155
"version_key": version_key,
152156
"hotkey": wallet.hotkey.ss58_address,
153157
},
@@ -156,10 +160,10 @@ async def _do_set_root_weights(
156160
extrinsic = await subtensor.substrate.create_signed_extrinsic(
157161
call=call,
158162
keypair=wallet.coldkey,
159-
era={"period": 5},
163+
era={"period": period},
160164
)
161165
response = await subtensor.substrate.submit_extrinsic(
162-
extrinsic,
166+
extrinsic=extrinsic,
163167
wait_for_inclusion=wait_for_inclusion,
164168
wait_for_finalization=wait_for_finalization,
165169
)

0 commit comments

Comments
 (0)