Skip to content

Commit 3bc829f

Browse files
feat: set_children and get_pending_children methods
1 parent 9730f51 commit 3bc829f

9 files changed

+653
-60
lines changed

bittensor/core/async_subtensor.py

+122
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,12 @@
7777
from bittensor.utils import (
7878
Certificate,
7979
decode_hex_identity_dict,
80+
float_to_u64,
8081
format_error_message,
8182
torch,
8283
u16_normalized_float,
8384
u64_normalized_float,
85+
unlock_key,
8486
)
8587
from bittensor.utils.balance import (
8688
Balance,
@@ -934,6 +936,57 @@ async def get_children(
934936
except SubstrateRequestException as e:
935937
return False, [], format_error_message(e)
936938

939+
async def get_children_pending(
940+
self,
941+
hotkey: str,
942+
netuid: int,
943+
block: Optional[int] = None,
944+
block_hash: Optional[str] = None,
945+
reuse_block: bool = False,
946+
) -> tuple[
947+
list[tuple[float, str]],
948+
int,
949+
]:
950+
"""
951+
This method retrieves the pending children of a given hotkey and netuid.
952+
It queries the SubtensorModule's PendingChildKeys storage function.
953+
954+
Arguments:
955+
hotkey (str): The hotkey value.
956+
netuid (int): The netuid value.
957+
block (Optional[int]): The block number for which the children are to be retrieved.
958+
block_hash (Optional[str]): The hash of the block to retrieve the subnet unique identifiers from.
959+
reuse_block (bool): Whether to reuse the last-used block hash.
960+
961+
Returns:
962+
list[tuple[float, str]]: A list of children with their proportions.
963+
int: The cool-down block number.
964+
"""
965+
966+
response = await self.substrate.query(
967+
module="SubtensorModule",
968+
storage_function="PendingChildKeys",
969+
params=[netuid, hotkey],
970+
block_hash=await self.determine_block_hash(
971+
block,
972+
block_hash,
973+
reuse_block,
974+
),
975+
reuse_block_hash=reuse_block,
976+
)
977+
children, cooldown = response.value
978+
979+
return (
980+
[
981+
(
982+
u64_normalized_float(proportion),
983+
decode_account_id(child[0]),
984+
)
985+
for proportion, child in children
986+
],
987+
cooldown,
988+
)
989+
937990
async def get_commitment(
938991
self,
939992
netuid: int,
@@ -3269,6 +3322,75 @@ async def root_set_weights(
32693322
wait_for_inclusion=wait_for_inclusion,
32703323
)
32713324

3325+
async def set_children(
3326+
self,
3327+
wallet: "Wallet",
3328+
hotkey: str,
3329+
netuid: int,
3330+
children: list[tuple[float, str]],
3331+
wait_for_inclusion: bool = True,
3332+
wait_for_finalization: bool = True,
3333+
raise_error: bool = False,
3334+
) -> tuple[bool, str]:
3335+
"""
3336+
Allows a coldkey to set children keys.
3337+
3338+
Arguments:
3339+
wallet (bittensor_wallet.Wallet): bittensor wallet instance.
3340+
hotkey (str): The ``SS58`` address of the neuron's hotkey.
3341+
netuid (int): The netuid value.
3342+
children (list[tuple[float, str]]): A list of children with their proportions.
3343+
wait_for_inclusion (bool): Waits for the transaction to be included in a block.
3344+
wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain.
3345+
raise_error: Raises relevant exception rather than returning `False` if unsuccessful.
3346+
3347+
Returns:
3348+
tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure of the
3349+
operation, and the second element is a message providing additional information.
3350+
3351+
Raises:
3352+
DuplicateChild: There are duplicates in the list of children.
3353+
InvalidChild: Child is the hotkey.
3354+
NonAssociatedColdKey: The coldkey does not own the hotkey or the child is the same as the hotkey.
3355+
NotEnoughStakeToSetChildkeys: Parent key doesn't have minimum own stake.
3356+
ProportionOverflow: The sum of the proportions does exceed uint64.
3357+
RegistrationNotPermittedOnRootSubnet: Attempting to register a child on the root network.
3358+
SubNetworkDoesNotExist: Attempting to register to a non-existent network.
3359+
TooManyChildren: Too many children in request.
3360+
TxRateLimitExceeded: Hotkey hit the rate limit.
3361+
bittensor_wallet.errors.KeyFileError: Failed to decode keyfile data.
3362+
bittensor_wallet.errors.PasswordError: Decryption failed or wrong password for decryption provided.
3363+
"""
3364+
3365+
unlock = unlock_key(wallet, raise_error=raise_error)
3366+
3367+
if not unlock.success:
3368+
return False, unlock.message
3369+
3370+
call = await self.substrate.compose_call(
3371+
call_module="SubtensorModule",
3372+
call_function="set_children",
3373+
call_params={
3374+
"children": [
3375+
(
3376+
float_to_u64(proportion),
3377+
child_hotkey,
3378+
)
3379+
for proportion, child_hotkey in children
3380+
],
3381+
"hotkey": hotkey,
3382+
"netuid": netuid,
3383+
},
3384+
)
3385+
3386+
return await self.sign_and_send_extrinsic(
3387+
call,
3388+
wallet,
3389+
wait_for_inclusion,
3390+
wait_for_finalization,
3391+
raise_error=raise_error,
3392+
)
3393+
32723394
async def set_delegate_take(
32733395
self,
32743396
wallet: "Wallet",

bittensor/core/errors.py

+94-24
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,6 @@ class ChainTransactionError(ChainError):
6363
"""Error for any chain transaction related errors."""
6464

6565

66-
class ChainQueryError(ChainError):
67-
"""Error for any chain query related errors."""
68-
69-
7066
class DelegateTakeTooHigh(ChainTransactionError):
7167
"""
7268
Delegate take is too high.
@@ -79,9 +75,9 @@ class DelegateTakeTooLow(ChainTransactionError):
7975
"""
8076

8177

82-
class DelegateTxRateLimitExceeded(ChainTransactionError):
78+
class DuplicateChild(ChainTransactionError):
8379
"""
84-
A transactor exceeded the rate limit for delegate transaction.
80+
Duplicate child when setting children.
8581
"""
8682

8783

@@ -91,50 +87,124 @@ class HotKeyAccountNotExists(ChainTransactionError):
9187
"""
9288

9389

90+
class IdentityError(ChainTransactionError):
91+
"""
92+
Error raised when an identity transaction fails.
93+
"""
94+
95+
96+
class InvalidChild(ChainTransactionError):
97+
"""
98+
Attempting to set an invalid child for a hotkey on a network.
99+
"""
100+
101+
102+
class MetadataError(ChainTransactionError):
103+
"""
104+
Error raised when metadata commitment transaction fails.
105+
"""
106+
107+
108+
class NominationError(ChainTransactionError):
109+
"""
110+
Error raised when a nomination transaction fails.
111+
"""
112+
113+
94114
class NonAssociatedColdKey(ChainTransactionError):
95115
"""
96116
Request to stake, unstake or subscribe is made by a coldkey that is not associated with the hotkey account.
97117
"""
98118

99119

100-
class StakeError(ChainTransactionError):
101-
"""Error raised when a stake transaction fails."""
120+
class NotEnoughStakeToSetChildkeys(ChainTransactionError):
121+
"""
122+
The parent hotkey doesn't have enough own stake to set childkeys.
123+
"""
102124

103125

104-
class UnstakeError(ChainTransactionError):
105-
"""Error raised when an unstake transaction fails."""
126+
class NotRegisteredError(ChainTransactionError):
127+
"""
128+
Error raised when a neuron is not registered, and the transaction requires it to be.
129+
"""
106130

107131

108-
class IdentityError(ChainTransactionError):
109-
"""Error raised when an identity transaction fails."""
132+
class ProportionOverflow(ChainTransactionError):
133+
"""
134+
Proportion overflow when setting children.
135+
"""
110136

111137

112-
class NominationError(ChainTransactionError):
113-
"""Error raised when a nomination transaction fails."""
138+
class RegistrationError(ChainTransactionError):
139+
"""
140+
Error raised when a neuron registration transaction fails.
141+
"""
142+
143+
144+
class RegistrationNotPermittedOnRootSubnet(ChainTransactionError):
145+
"""
146+
Operation is not permitted on the root subnet.
147+
"""
148+
149+
150+
class StakeError(ChainTransactionError):
151+
"""
152+
Error raised when a stake transaction fails.
153+
"""
154+
155+
156+
class NotDelegateError(StakeError):
157+
"""
158+
Error raised when a hotkey you are trying to stake to is not a delegate.
159+
"""
160+
161+
162+
class SubNetworkDoesNotExist(ChainTransactionError):
163+
"""
164+
The subnet does not exist.
165+
"""
114166

115167

116168
class TakeError(ChainTransactionError):
117-
"""Error raised when an increase / decrease take transaction fails."""
169+
"""
170+
Error raised when an increase / decrease take transaction fails.
171+
"""
118172

119173

120174
class TransferError(ChainTransactionError):
121-
"""Error raised when a transfer transaction fails."""
175+
"""
176+
Error raised when a transfer transaction fails.
177+
"""
122178

123179

124-
class RegistrationError(ChainTransactionError):
125-
"""Error raised when a neuron registration transaction fails."""
180+
class TooManyChildren(ChainTransactionError):
181+
"""
182+
Too many children MAX 5.
183+
"""
126184

127185

128-
class NotRegisteredError(ChainTransactionError):
129-
"""Error raised when a neuron is not registered, and the transaction requires it to be."""
186+
class TxRateLimitExceeded(ChainTransactionError):
187+
"""
188+
Default transaction rate limit exceeded.
189+
"""
130190

131191

132-
class NotDelegateError(StakeError):
133-
"""Error raised when a hotkey you are trying to stake to is not a delegate."""
192+
class DelegateTxRateLimitExceeded(TxRateLimitExceeded):
193+
"""
194+
A transactor exceeded the rate limit for delegate transaction.
195+
"""
134196

135197

136-
class MetadataError(ChainTransactionError):
137-
"""Error raised when metadata commitment transaction fails."""
198+
class UnstakeError(ChainTransactionError):
199+
"""
200+
Error raised when an unstake transaction fails.
201+
"""
202+
203+
204+
class ChainQueryError(ChainError):
205+
"""
206+
Error for any chain query related errors.
207+
"""
138208

139209

140210
class InvalidRequestNameError(Exception):

0 commit comments

Comments
 (0)