|
27 | 27 | decode_account_id, |
28 | 28 | DynamicInfo, |
29 | 29 | ) |
| 30 | +from bittensor_commit_reveal import get_encrypted_commitment |
30 | 31 | from bittensor.core.chain_data.chain_identity import ChainIdentity |
31 | 32 | from bittensor.core.chain_data.delegate_info import DelegatedInfo |
32 | | -from bittensor.core.chain_data.utils import decode_metadata |
| 33 | +from bittensor.core.chain_data.utils import ( |
| 34 | + decode_metadata, |
| 35 | + decode_revealed_commitment, |
| 36 | + decode_revealed_commitment_with_hotkey, |
| 37 | +) |
33 | 38 | from bittensor.core.config import Config |
34 | 39 | from bittensor.core.errors import ChainError, SubstrateRequestException |
35 | 40 | from bittensor.core.extrinsics.asyncex.commit_reveal import commit_reveal_v3_extrinsic |
@@ -1059,6 +1064,68 @@ async def get_all_commitments( |
1059 | 1064 | result[decode_account_id(id_[0])] = decode_metadata(value) |
1060 | 1065 | return result |
1061 | 1066 |
|
| 1067 | + async def get_revealed_commitment( |
| 1068 | + self, |
| 1069 | + netuid: int, |
| 1070 | + hotkey_ss58_address: Optional[str] = None, |
| 1071 | + block: Optional[int] = None, |
| 1072 | + block_hash: Optional[str] = None, |
| 1073 | + reuse_block: bool = False, |
| 1074 | + ) -> Optional[tuple[int, str]]: |
| 1075 | + """Returns hotkey related revealed commitment for a given netuid. |
| 1076 | +
|
| 1077 | + Arguments: |
| 1078 | + netuid (int): The unique identifier of the subnetwork. |
| 1079 | + block (Optional[int]): The block number to retrieve the commitment from. Default is ``None``. |
| 1080 | + hotkey_ss58_address (str): The ss58 address of the committee member. |
| 1081 | + block_hash (Optional[str]): The hash of the block to retrieve the subnet unique identifiers from. |
| 1082 | + reuse_block (bool): Whether to reuse the last-used block hash. |
| 1083 | +
|
| 1084 | + Returns: |
| 1085 | + result (tuple[int, str): A tuple of reveal block and commitment message. |
| 1086 | + """ |
| 1087 | + query = await self.query_module( |
| 1088 | + module="Commitments", |
| 1089 | + name="RevealedCommitments", |
| 1090 | + params=[netuid, hotkey_ss58_address], |
| 1091 | + block=block, |
| 1092 | + block_hash=block_hash, |
| 1093 | + reuse_block=reuse_block, |
| 1094 | + ) |
| 1095 | + return decode_revealed_commitment(query) |
| 1096 | + |
| 1097 | + async def get_all_revealed_commitments( |
| 1098 | + self, |
| 1099 | + netuid: int, |
| 1100 | + block: Optional[int] = None, |
| 1101 | + block_hash: Optional[str] = None, |
| 1102 | + reuse_block: bool = False, |
| 1103 | + ) -> dict[str, tuple[int, str]]: |
| 1104 | + """Returns all revealed commitments for a given netuid. |
| 1105 | +
|
| 1106 | + Arguments: |
| 1107 | + netuid (int): The unique identifier of the subnetwork. |
| 1108 | + block (Optional[int]): The block number to retrieve the commitment from. Default is ``None``. |
| 1109 | + block_hash (Optional[str]): The hash of the block to retrieve the subnet unique identifiers from. |
| 1110 | + reuse_block (bool): Whether to reuse the last-used block hash. |
| 1111 | +
|
| 1112 | + Returns: |
| 1113 | + result (dict): A dictionary of all revealed commitments in view {ss58_address: (reveal block, commitment message)}. |
| 1114 | + """ |
| 1115 | + query = await self.query_map( |
| 1116 | + module="Commitments", |
| 1117 | + name="RevealedCommitments", |
| 1118 | + params=[netuid], |
| 1119 | + block=block, |
| 1120 | + block_hash=block_hash, |
| 1121 | + reuse_block=reuse_block, |
| 1122 | + ) |
| 1123 | + |
| 1124 | + result = {} |
| 1125 | + async for item in query: |
| 1126 | + result.update(decode_revealed_commitment_with_hotkey(item)) |
| 1127 | + return result |
| 1128 | + |
1062 | 1129 | async def get_current_weight_commit_info( |
1063 | 1130 | self, |
1064 | 1131 | netuid: int, |
@@ -1572,6 +1639,36 @@ async def get_neuron_for_pubkey_and_subnet( |
1572 | 1639 | reuse_block=reuse_block, |
1573 | 1640 | ) |
1574 | 1641 |
|
| 1642 | + async def get_owned_hotkeys( |
| 1643 | + self, |
| 1644 | + coldkey_ss58: str, |
| 1645 | + block: Optional[int] = None, |
| 1646 | + block_hash: Optional[str] = None, |
| 1647 | + reuse_block: bool = False, |
| 1648 | + ) -> list[str]: |
| 1649 | + """ |
| 1650 | + Retrieves all hotkeys owned by a specific coldkey address. |
| 1651 | +
|
| 1652 | + Args: |
| 1653 | + coldkey_ss58 (str): The SS58 address of the coldkey to query. |
| 1654 | + block (int): The blockchain block number for the query. |
| 1655 | + block_hash (str): The hash of the blockchain block number for the query. |
| 1656 | + reuse_block (bool): Whether to reuse the last-used blockchain block hash. |
| 1657 | +
|
| 1658 | + Returns: |
| 1659 | + list[str]: A list of hotkey SS58 addresses owned by the coldkey. |
| 1660 | + """ |
| 1661 | + block_hash = await self.determine_block_hash(block, block_hash, reuse_block) |
| 1662 | + owned_hotkeys = await self.substrate.query( |
| 1663 | + module="SubtensorModule", |
| 1664 | + storage_function="OwnedHotkeys", |
| 1665 | + params=[coldkey_ss58], |
| 1666 | + block_hash=block_hash, |
| 1667 | + reuse_block_hash=reuse_block, |
| 1668 | + ) |
| 1669 | + |
| 1670 | + return [decode_account_id(hotkey[0]) for hotkey in owned_hotkeys or []] |
| 1671 | + |
1575 | 1672 | async def get_stake( |
1576 | 1673 | self, |
1577 | 1674 | coldkey_ss58: str, |
@@ -2620,6 +2717,46 @@ async def recycle( |
2620 | 2717 | ) |
2621 | 2718 | return None if call is None else Balance.from_rao(int(call)) |
2622 | 2719 |
|
| 2720 | + async def set_reveal_commitment( |
| 2721 | + self, |
| 2722 | + wallet, |
| 2723 | + netuid: int, |
| 2724 | + data: str, |
| 2725 | + blocks_until_reveal: int = 360, |
| 2726 | + block_time: Union[int, float] = 12, |
| 2727 | + ) -> tuple[bool, int]: |
| 2728 | + """ |
| 2729 | + Commits arbitrary data to the Bittensor network by publishing metadata. |
| 2730 | +
|
| 2731 | + Arguments: |
| 2732 | + wallet (bittensor_wallet.Wallet): The wallet associated with the neuron committing the data. |
| 2733 | + netuid (int): The unique identifier of the subnetwork. |
| 2734 | + data (str): The data to be committed to the network. |
| 2735 | + blocks_until_reveal (int): The number of blocks from now after which the data will be revealed. Defaults to `360`. |
| 2736 | + Then amount of blocks in one epoch. |
| 2737 | + block_time (Union[int, float]): The number of seconds between each block. Defaults to `12`. |
| 2738 | +
|
| 2739 | + Returns: |
| 2740 | + bool: `True` if the commitment was successful, `False` otherwise. |
| 2741 | +
|
| 2742 | + Note: A commitment can be set once per subnet epoch and is reset at the next epoch in the chain automatically. |
| 2743 | + """ |
| 2744 | + |
| 2745 | + encrypted, reveal_round = get_encrypted_commitment( |
| 2746 | + data, blocks_until_reveal, block_time |
| 2747 | + ) |
| 2748 | + |
| 2749 | + # increase reveal_round in return + 1 because we want to fetch data from the chain after that round was revealed |
| 2750 | + # and stored. |
| 2751 | + data_ = {"encrypted": encrypted, "reveal_round": reveal_round} |
| 2752 | + return await publish_metadata( |
| 2753 | + subtensor=self, |
| 2754 | + wallet=wallet, |
| 2755 | + netuid=netuid, |
| 2756 | + data_type=f"TimelockEncrypted", |
| 2757 | + data=data_, |
| 2758 | + ), reveal_round |
| 2759 | + |
2623 | 2760 | async def subnet( |
2624 | 2761 | self, |
2625 | 2762 | netuid: int, |
|
0 commit comments