diff --git a/bittensor/core/extrinsics/asyncex/serving.py b/bittensor/core/extrinsics/asyncex/serving.py index c37c612191..ab20451dbd 100644 --- a/bittensor/core/extrinsics/asyncex/serving.py +++ b/bittensor/core/extrinsics/asyncex/serving.py @@ -235,6 +235,7 @@ async def publish_metadata( wait_for_inclusion: bool = False, wait_for_finalization: bool = True, period: Optional[int] = None, + reset_bonds: bool = False, ) -> bool: """ Publishes metadata on the Bittensor network using the specified wallet and network identifier. @@ -255,6 +256,7 @@ async def publish_metadata( period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + reset_bonds (bool, optional): If ``True``, the function will reset the bonds for the neuron. Defaults to ``False``. Returns: bool: ``True`` if the metadata was successfully published (and finalized if specified). ``False`` otherwise. @@ -268,13 +270,17 @@ async def publish_metadata( logging.error(unlock.message) return False + fields = [{f"{data_type}": data}] + if reset_bonds: + fields.append({"ResetBondsFlag": b""}) + async with subtensor.substrate as substrate: call = await substrate.compose_call( call_module="Commitments", call_function="set_commitment", call_params={ "netuid": netuid, - "info": {"fields": [[{f"{data_type}": data}]]}, + "info": {"fields": [fields]}, }, ) diff --git a/bittensor/core/extrinsics/serving.py b/bittensor/core/extrinsics/serving.py index d004fd7dba..370ec277c2 100644 --- a/bittensor/core/extrinsics/serving.py +++ b/bittensor/core/extrinsics/serving.py @@ -232,6 +232,7 @@ def publish_metadata( wait_for_inclusion: bool = False, wait_for_finalization: bool = True, period: Optional[int] = None, + reset_bonds: bool = False, ) -> bool: """ Publishes metadata on the Bittensor network using the specified wallet and network identifier. @@ -252,6 +253,7 @@ def publish_metadata( period (Optional[int]): The number of blocks during which the transaction will remain valid after it's submitted. If the transaction is not included in a block within that number of blocks, it will expire and be rejected. You can think of it as an expiration date for the transaction. + reset_bonds (bool, optional): If ``True``, the function will reset the bonds for the neuron. Defaults to ``False``. Returns: bool: ``True`` if the metadata was successfully published (and finalized if specified). ``False`` otherwise. @@ -265,12 +267,16 @@ def publish_metadata( logging.error(unlock.message) return False + fields = [{f"{data_type}": data}] + if reset_bonds: + fields.append({"ResetBondsFlag": b""}) + call = subtensor.substrate.compose_call( call_module="Commitments", call_function="set_commitment", call_params={ "netuid": netuid, - "info": {"fields": [[{f"{data_type}": data}]]}, + "info": {"fields": [fields]}, }, ) @@ -298,3 +304,16 @@ def get_metadata( block_hash=subtensor.determine_block_hash(block), ) return commit_data + + +def get_last_bonds_reset( + subtensor: "Subtensor", netuid: int, hotkey: str, block: Optional[int] = None +) -> bytes: + """Fetches the last bonds reset triggered at commitment from the blockchain for a given hotkey and netuid.""" + block = subtensor.substrate.query( + module="Commitments", + storage_function="LastBondsReset", + params=[netuid, hotkey], + block_hash=subtensor.determine_block_hash(block), + ) + return block diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 63634d9053..095d38e2a7 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -57,6 +57,7 @@ set_root_weights_extrinsic, ) from bittensor.core.extrinsics.serving import ( + get_last_bonds_reset, publish_metadata, get_metadata, serve_axon_extrinsic, @@ -855,6 +856,29 @@ def get_commitment(self, netuid: int, uid: int, block: Optional[int] = None) -> except TypeError: return "" + def get_last_commitment_bonds_reset_block( + self, netuid: int, uid: int + ) -> Optional[int]: + """ + Retrieves the last block number when the bonds reset were triggered by publish_metadata for a specific neuron. + Arguments: + netuid (int): The unique identifier of the subnetwork. + uid (int): The unique identifier of the neuron. + Returns: + Optional[int]: The block number when the bonds were last reset, or None if not found. + """ + + metagraph = self.metagraph(netuid) + try: + hotkey = metagraph.hotkeys[uid] # type: ignore + except IndexError: + logging.error( + "Your uid is not in the hotkeys. Please double-check your UID." + ) + return None + block = get_last_bonds_reset(self, netuid, hotkey) + return block.value + def get_all_commitments( self, netuid: int, block: Optional[int] = None ) -> dict[str, str]: