Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions bittensor/core/async_subtensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,12 @@
from bittensor.utils import (
Certificate,
decode_hex_identity_dict,
float_to_u64,
format_error_message,
torch,
u16_normalized_float,
u64_normalized_float,
unlock_key,
)
from bittensor.utils.balance import (
Balance,
Expand Down Expand Up @@ -934,6 +936,57 @@ async def get_children(
except SubstrateRequestException as e:
return False, [], format_error_message(e)

async def get_children_pending(
self,
hotkey: str,
netuid: int,
block: Optional[int] = None,
block_hash: Optional[str] = None,
reuse_block: bool = False,
) -> tuple[
list[tuple[float, str]],
int,
]:
"""
This method retrieves the pending children of a given hotkey and netuid.
It queries the SubtensorModule's PendingChildKeys storage function.

Arguments:
hotkey (str): The hotkey value.
netuid (int): The netuid value.
block (Optional[int]): The block number for which the children are to be retrieved.
block_hash (Optional[str]): The hash of the block to retrieve the subnet unique identifiers from.
reuse_block (bool): Whether to reuse the last-used block hash.

Returns:
list[tuple[float, str]]: A list of children with their proportions.
int: The cool-down block number.
"""

response = await self.substrate.query(
module="SubtensorModule",
storage_function="PendingChildKeys",
params=[netuid, hotkey],
block_hash=await self.determine_block_hash(
block,
block_hash,
reuse_block,
),
reuse_block_hash=reuse_block,
)
children, cooldown = response.value

return (
[
(
u64_normalized_float(proportion),
decode_account_id(child[0]),
)
for proportion, child in children
],
cooldown,
)

async def get_commitment(
self,
netuid: int,
Expand Down Expand Up @@ -3381,6 +3434,75 @@ async def root_set_weights(
wait_for_inclusion=wait_for_inclusion,
)

async def set_children(
self,
wallet: "Wallet",
hotkey: str,
netuid: int,
children: list[tuple[float, str]],
wait_for_inclusion: bool = True,
wait_for_finalization: bool = True,
raise_error: bool = False,
) -> tuple[bool, str]:
"""
Allows a coldkey to set children keys.

Arguments:
wallet (bittensor_wallet.Wallet): bittensor wallet instance.
hotkey (str): The ``SS58`` address of the neuron's hotkey.
netuid (int): The netuid value.
children (list[tuple[float, str]]): A list of children with their proportions.
wait_for_inclusion (bool): Waits for the transaction to be included in a block.
wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain.
raise_error: Raises relevant exception rather than returning `False` if unsuccessful.

Returns:
tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure of the
operation, and the second element is a message providing additional information.

Raises:
DuplicateChild: There are duplicates in the list of children.
InvalidChild: Child is the hotkey.
NonAssociatedColdKey: The coldkey does not own the hotkey or the child is the same as the hotkey.
NotEnoughStakeToSetChildkeys: Parent key doesn't have minimum own stake.
ProportionOverflow: The sum of the proportions does exceed uint64.
RegistrationNotPermittedOnRootSubnet: Attempting to register a child on the root network.
SubNetworkDoesNotExist: Attempting to register to a non-existent network.
TooManyChildren: Too many children in request.
TxRateLimitExceeded: Hotkey hit the rate limit.
bittensor_wallet.errors.KeyFileError: Failed to decode keyfile data.
bittensor_wallet.errors.PasswordError: Decryption failed or wrong password for decryption provided.
"""

unlock = unlock_key(wallet, raise_error=raise_error)

if not unlock.success:
return False, unlock.message

call = await self.substrate.compose_call(
call_module="SubtensorModule",
call_function="set_children",
call_params={
"children": [
(
float_to_u64(proportion),
child_hotkey,
)
for proportion, child_hotkey in children
],
"hotkey": hotkey,
"netuid": netuid,
},
)

return await self.sign_and_send_extrinsic(
call,
wallet,
wait_for_inclusion,
wait_for_finalization,
raise_error=raise_error,
)

async def set_delegate_take(
self,
wallet: "Wallet",
Expand Down
118 changes: 94 additions & 24 deletions bittensor/core/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ class ChainTransactionError(ChainError):
"""Error for any chain transaction related errors."""


class ChainQueryError(ChainError):
"""Error for any chain query related errors."""


class DelegateTakeTooHigh(ChainTransactionError):
"""
Delegate take is too high.
Expand All @@ -79,9 +75,9 @@ class DelegateTakeTooLow(ChainTransactionError):
"""


class DelegateTxRateLimitExceeded(ChainTransactionError):
class DuplicateChild(ChainTransactionError):
"""
A transactor exceeded the rate limit for delegate transaction.
Duplicate child when setting children.
"""


Expand All @@ -91,50 +87,124 @@ class HotKeyAccountNotExists(ChainTransactionError):
"""


class IdentityError(ChainTransactionError):
"""
Error raised when an identity transaction fails.
"""


class InvalidChild(ChainTransactionError):
"""
Attempting to set an invalid child for a hotkey on a network.
"""


class MetadataError(ChainTransactionError):
"""
Error raised when metadata commitment transaction fails.
"""


class NominationError(ChainTransactionError):
"""
Error raised when a nomination transaction fails.
"""


class NonAssociatedColdKey(ChainTransactionError):
"""
Request to stake, unstake or subscribe is made by a coldkey that is not associated with the hotkey account.
"""


class StakeError(ChainTransactionError):
"""Error raised when a stake transaction fails."""
class NotEnoughStakeToSetChildkeys(ChainTransactionError):
"""
The parent hotkey doesn't have enough own stake to set childkeys.
"""


class UnstakeError(ChainTransactionError):
"""Error raised when an unstake transaction fails."""
class NotRegisteredError(ChainTransactionError):
"""
Error raised when a neuron is not registered, and the transaction requires it to be.
"""


class IdentityError(ChainTransactionError):
"""Error raised when an identity transaction fails."""
class ProportionOverflow(ChainTransactionError):
"""
Proportion overflow when setting children.
"""


class NominationError(ChainTransactionError):
"""Error raised when a nomination transaction fails."""
class RegistrationError(ChainTransactionError):
"""
Error raised when a neuron registration transaction fails.
"""


class RegistrationNotPermittedOnRootSubnet(ChainTransactionError):
"""
Operation is not permitted on the root subnet.
"""


class StakeError(ChainTransactionError):
"""
Error raised when a stake transaction fails.
"""


class NotDelegateError(StakeError):
"""
Error raised when a hotkey you are trying to stake to is not a delegate.
"""


class SubNetworkDoesNotExist(ChainTransactionError):
"""
The subnet does not exist.
"""


class TakeError(ChainTransactionError):
"""Error raised when an increase / decrease take transaction fails."""
"""
Error raised when an increase / decrease take transaction fails.
"""


class TransferError(ChainTransactionError):
"""Error raised when a transfer transaction fails."""
"""
Error raised when a transfer transaction fails.
"""


class RegistrationError(ChainTransactionError):
"""Error raised when a neuron registration transaction fails."""
class TooManyChildren(ChainTransactionError):
"""
Too many children MAX 5.
"""


class NotRegisteredError(ChainTransactionError):
"""Error raised when a neuron is not registered, and the transaction requires it to be."""
class TxRateLimitExceeded(ChainTransactionError):
"""
Default transaction rate limit exceeded.
"""


class NotDelegateError(StakeError):
"""Error raised when a hotkey you are trying to stake to is not a delegate."""
class DelegateTxRateLimitExceeded(TxRateLimitExceeded):
"""
A transactor exceeded the rate limit for delegate transaction.
"""


class MetadataError(ChainTransactionError):
"""Error raised when metadata commitment transaction fails."""
class UnstakeError(ChainTransactionError):
"""
Error raised when an unstake transaction fails.
"""


class ChainQueryError(ChainError):
"""
Error for any chain query related errors.
"""


class InvalidRequestNameError(Exception):
Expand Down
Loading
Loading