Skip to content

Commit ad21515

Browse files
authored
Merge pull request #2665 from opentensor/fix/thewhaleking/add-nonce-to-extrinsics-calls
Last-minute requests
2 parents 9a04b32 + c30c1bf commit ad21515

File tree

14 files changed

+231
-107
lines changed

14 files changed

+231
-107
lines changed

bittensor/core/async_subtensor.py

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
u16_normalized_float,
7676
_decode_hex_identity_dict,
7777
Certificate,
78+
u64_normalized_float,
7879
)
7980
from bittensor.utils.balance import (
8081
Balance,
@@ -891,7 +892,7 @@ async def get_children(
891892
block: Optional[int] = None,
892893
block_hash: Optional[str] = None,
893894
reuse_block: bool = False,
894-
) -> tuple[bool, list, str]:
895+
) -> tuple[bool, list[tuple[float, str]], str]:
895896
"""
896897
This method retrieves the children of a given hotkey and netuid. It queries the SubtensorModule's ChildKeys
897898
storage function to get the children and formats them before returning as a tuple.
@@ -921,8 +922,8 @@ async def get_children(
921922
for proportion, child in children.value:
922923
# Convert U64 to int
923924
formatted_child = decode_account_id(child[0])
924-
int_proportion = int(proportion)
925-
formatted_children.append((int_proportion, formatted_child))
925+
normalized_proportion = u64_normalized_float(proportion)
926+
formatted_children.append((normalized_proportion, formatted_child))
926927
return True, formatted_children, ""
927928
else:
928929
return True, [], ""
@@ -1665,6 +1666,40 @@ async def get_stake_for_coldkey(
16651666

16661667
get_stake_info_for_coldkey = get_stake_for_coldkey
16671668

1669+
async def get_stake_for_hotkey(
1670+
self,
1671+
hotkey_ss58: str,
1672+
netuid: int,
1673+
block: Optional[int] = None,
1674+
block_hash: Optional[str] = None,
1675+
reuse_block: bool = False,
1676+
) -> Balance:
1677+
"""
1678+
Retrieves the stake information for a given hotkey.
1679+
1680+
Args:
1681+
hotkey_ss58: The SS58 address of the hotkey.
1682+
netuid: The subnet ID to query for.
1683+
block: The block number at which to query the stake information. Do not specify if also specifying
1684+
block_hash or reuse_block
1685+
block_hash: The hash of the blockchain block number for the query. Do not specify if also specifying block
1686+
or reuse_block
1687+
reuse_block: Whether to reuse for this query the last-used block. Do not specify if also specifying block
1688+
or block_hash.
1689+
"""
1690+
hotkey_alpha_query = await self.query_subtensor(
1691+
name="TotalHotkeyAlpha",
1692+
params=[hotkey_ss58, netuid],
1693+
block=block,
1694+
block_hash=block_hash,
1695+
reuse_block=reuse_block,
1696+
)
1697+
balance = Balance.from_rao(hotkey_alpha_query.value)
1698+
balance.set_unit(netuid=netuid)
1699+
return balance
1700+
1701+
get_hotkey_stake = get_stake_for_hotkey
1702+
16681703
async def get_subnet_burn_cost(
16691704
self,
16701705
block: Optional[int] = None,
@@ -2683,6 +2718,9 @@ async def sign_and_send_extrinsic(
26832718
wait_for_inclusion: bool = True,
26842719
wait_for_finalization: bool = False,
26852720
sign_with: str = "coldkey",
2721+
use_nonce: bool = False,
2722+
period: Optional[int] = None,
2723+
nonce_key: str = "hotkey",
26862724
) -> tuple[bool, str]:
26872725
"""
26882726
Helper method to sign and submit an extrinsic call to chain.
@@ -2697,14 +2735,26 @@ async def sign_and_send_extrinsic(
26972735
Returns:
26982736
(success, error message)
26992737
"""
2700-
if sign_with not in ("coldkey", "hotkey", "coldkeypub"):
2738+
possible_keys = ("coldkey", "hotkey", "coldkeypub")
2739+
if sign_with not in possible_keys:
27012740
raise AttributeError(
27022741
f"'sign_with' must be either 'coldkey', 'hotkey' or 'coldkeypub', not '{sign_with}'"
27032742
)
2743+
signing_keypair = getattr(wallet, sign_with)
2744+
extrinsic_data = {"call": call, "keypair": signing_keypair}
2745+
if use_nonce:
2746+
if nonce_key not in possible_keys:
2747+
raise AttributeError(
2748+
f"'nonce_key' must be either 'coldkey', 'hotkey' or 'coldkeypub', not '{nonce_key}'"
2749+
)
2750+
next_nonce = await self.substrate.get_account_next_index(
2751+
getattr(wallet, nonce_key).ss58_address
2752+
)
2753+
extrinsic_data["nonce"] = next_nonce
2754+
if period is not None:
2755+
extrinsic_data["era"] = {"period": period}
27042756

2705-
extrinsic = await self.substrate.create_signed_extrinsic(
2706-
call=call, keypair=getattr(wallet, sign_with)
2707-
)
2757+
extrinsic = await self.substrate.create_signed_extrinsic(**extrinsic_data)
27082758
try:
27092759
response = await self.substrate.submit_extrinsic(
27102760
extrinsic,

bittensor/core/chain_data/dynamic_info.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from bittensor.core.chain_data.utils import decode_account_id
1111

1212
from bittensor.core.chain_data.subnet_identity import SubnetIdentity
13-
from bittensor.utils.balance import Balance
13+
from bittensor.utils.balance import Balance, fixed_to_float
1414

1515

1616
@dataclass
@@ -38,6 +38,7 @@ class DynamicInfo(InfoBase):
3838
network_registered_at: int
3939
subnet_volume: Balance
4040
subnet_identity: Optional[SubnetIdentity]
41+
moving_price: float
4142

4243
@classmethod
4344
def _from_dict(cls, decoded: dict) -> "DynamicInfo":
@@ -120,6 +121,7 @@ def _from_dict(cls, decoded: dict) -> "DynamicInfo":
120121
network_registered_at=int(decoded["network_registered_at"]),
121122
subnet_identity=subnet_identity,
122123
subnet_volume=subnet_volume,
124+
moving_price=fixed_to_float(decoded["moving_price"]),
123125
)
124126

125127
def tao_to_alpha(self, tao: Union[Balance, float, int]) -> Balance:

bittensor/core/extrinsics/asyncex/staking.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,13 @@ async def add_stake_extrinsic(
112112
},
113113
)
114114
staking_response, err_msg = await subtensor.sign_and_send_extrinsic(
115-
call, wallet, wait_for_inclusion, wait_for_finalization
115+
call,
116+
wallet,
117+
wait_for_inclusion,
118+
wait_for_finalization,
119+
nonce_key="coldkeypub",
120+
sign_with="coldkey",
121+
use_nonce=True,
116122
)
117123
if staking_response is True: # If we successfully staked.
118124
# We only wait here if we expect finalization.
@@ -296,7 +302,13 @@ async def add_stake_multiple_extrinsic(
296302
},
297303
)
298304
staking_response, err_msg = await subtensor.sign_and_send_extrinsic(
299-
call, wallet, wait_for_inclusion, wait_for_finalization
305+
call,
306+
wallet,
307+
wait_for_inclusion,
308+
wait_for_finalization,
309+
nonce_key="coldkeypub",
310+
sign_with="coldkey",
311+
use_nonce=True,
300312
)
301313

302314
if staking_response is True: # If we successfully staked.

bittensor/core/extrinsics/asyncex/unstaking.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,13 @@ async def unstake_extrinsic(
9898
},
9999
)
100100
staking_response, err_msg = await subtensor.sign_and_send_extrinsic(
101-
call, wallet, wait_for_inclusion, wait_for_finalization
101+
call,
102+
wallet,
103+
wait_for_inclusion,
104+
wait_for_finalization,
105+
nonce_key="coldkeypub",
106+
sign_with="coldkey",
107+
use_nonce=True,
102108
)
103109

104110
if staking_response is True: # If we successfully unstaked.
@@ -261,8 +267,15 @@ async def unstake_multiple_extrinsic(
261267
"netuid": netuid,
262268
},
263269
)
270+
264271
staking_response, err_msg = await subtensor.sign_and_send_extrinsic(
265-
call, wallet, wait_for_inclusion, wait_for_finalization
272+
call,
273+
wallet,
274+
wait_for_inclusion,
275+
wait_for_finalization,
276+
nonce_key="coldkeypub",
277+
sign_with="coldkey",
278+
use_nonce=True,
266279
)
267280

268281
if staking_response is True: # If we successfully unstaked.

bittensor/core/extrinsics/asyncex/weights.py

Lines changed: 25 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,42 +14,6 @@
1414
from bittensor_wallet import Wallet
1515
from bittensor.core.async_subtensor import AsyncSubtensor
1616
from bittensor.utils.registration import torch
17-
from scalecodec.types import GenericCall
18-
19-
20-
async def sign_and_send_with_nonce(
21-
subtensor: "AsyncSubtensor",
22-
call: "GenericCall",
23-
wallet: "Wallet",
24-
wait_for_inclusion: bool,
25-
wait_for_finalization: bool,
26-
period: Optional[int] = None,
27-
):
28-
"""
29-
Signs an extrinsic call with the wallet hotkey, adding an optional era for period
30-
"""
31-
next_nonce = await subtensor.substrate.get_account_next_index(
32-
wallet.hotkey.ss58_address
33-
)
34-
35-
extrinsic_data = {"call": call, "keypair": wallet.hotkey, "nonce": next_nonce}
36-
if period is not None:
37-
extrinsic_data["era"] = {"period": period}
38-
39-
extrinsic = await subtensor.substrate.create_signed_extrinsic(**extrinsic_data)
40-
response = await subtensor.substrate.submit_extrinsic(
41-
extrinsic=extrinsic,
42-
wait_for_inclusion=wait_for_inclusion,
43-
wait_for_finalization=wait_for_finalization,
44-
)
45-
46-
if not wait_for_finalization and not wait_for_inclusion:
47-
return True, None
48-
49-
if await response.is_success:
50-
return True, None
51-
52-
return False, format_error_message(await response.error_message)
5317

5418

5519
async def _do_commit_weights(
@@ -87,8 +51,14 @@ async def _do_commit_weights(
8751
"commit_hash": commit_hash,
8852
},
8953
)
90-
return await sign_and_send_with_nonce(
91-
subtensor, call, wallet, wait_for_inclusion, wait_for_finalization
54+
return await subtensor.sign_and_send_extrinsic(
55+
call,
56+
wallet,
57+
wait_for_inclusion,
58+
wait_for_finalization,
59+
use_nonce=True,
60+
nonce_key="hotkey",
61+
sign_with="hotkey",
9262
)
9363

9464

@@ -184,8 +154,14 @@ async def _do_reveal_weights(
184154
"version_key": version_key,
185155
},
186156
)
187-
return await sign_and_send_with_nonce(
188-
subtensor, call, wallet, wait_for_inclusion, wait_for_finalization
157+
return await subtensor.sign_and_send_extrinsic(
158+
call,
159+
wallet,
160+
wait_for_inclusion,
161+
wait_for_finalization,
162+
sign_with="hotkey",
163+
nonce_key="hotkey",
164+
use_nonce=True,
189165
)
190166

191167

@@ -290,8 +266,15 @@ async def _do_set_weights(
290266
"version_key": version_key,
291267
},
292268
)
293-
return await sign_and_send_with_nonce(
294-
subtensor, call, wallet, wait_for_inclusion, wait_for_finalization, period
269+
return await subtensor.sign_and_send_extrinsic(
270+
call,
271+
wallet,
272+
wait_for_inclusion,
273+
wait_for_finalization,
274+
period=period,
275+
use_nonce=True,
276+
nonce_key="hotkey",
277+
sign_with="hotkey",
295278
)
296279

297280

bittensor/core/extrinsics/commit_weights.py

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,6 @@
1010
from bittensor.core.subtensor import Subtensor
1111

1212

13-
def sign_and_send_with_nonce(
14-
subtensor: "Subtensor", call, wallet, wait_for_inclusion, wait_for_finalization
15-
):
16-
next_nonce = subtensor.substrate.get_account_next_index(wallet.hotkey.ss58_address)
17-
extrinsic = subtensor.substrate.create_signed_extrinsic(
18-
call=call,
19-
keypair=wallet.hotkey,
20-
nonce=next_nonce,
21-
)
22-
response = subtensor.substrate.submit_extrinsic(
23-
extrinsic=extrinsic,
24-
wait_for_inclusion=wait_for_inclusion,
25-
wait_for_finalization=wait_for_finalization,
26-
)
27-
28-
if not wait_for_finalization and not wait_for_inclusion:
29-
return True, None
30-
31-
if response.is_success:
32-
return True, None
33-
34-
return False, format_error_message(response.error_message)
35-
36-
3713
def _do_commit_weights(
3814
subtensor: "Subtensor",
3915
wallet: "Wallet",
@@ -68,9 +44,14 @@ def _do_commit_weights(
6844
"commit_hash": commit_hash,
6945
},
7046
)
71-
72-
return sign_and_send_with_nonce(
73-
subtensor, call, wallet, wait_for_inclusion, wait_for_finalization
47+
return subtensor.sign_and_send_extrinsic(
48+
call,
49+
wallet,
50+
wait_for_inclusion,
51+
wait_for_finalization,
52+
use_nonce=True,
53+
sign_with="hotkey",
54+
nonce_key="hotkey",
7455
)
7556

7657

@@ -164,8 +145,14 @@ def _do_reveal_weights(
164145
"version_key": version_key,
165146
},
166147
)
167-
return sign_and_send_with_nonce(
168-
subtensor, call, wallet, wait_for_inclusion, wait_for_finalization
148+
return subtensor.sign_and_send_extrinsic(
149+
call,
150+
wallet,
151+
wait_for_inclusion,
152+
wait_for_finalization,
153+
use_nonce=True,
154+
sign_with="hotkey",
155+
nonce_key="hotkey",
169156
)
170157

171158

bittensor/core/extrinsics/staking.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,13 @@ def add_stake_extrinsic(
107107
},
108108
)
109109
staking_response, err_msg = subtensor.sign_and_send_extrinsic(
110-
call, wallet, wait_for_inclusion, wait_for_finalization
110+
call,
111+
wallet,
112+
wait_for_inclusion,
113+
wait_for_finalization,
114+
use_nonce=True,
115+
sign_with="coldkey",
116+
nonce_key="coldkeypub",
111117
)
112118
if staking_response is True: # If we successfully staked.
113119
# We only wait here if we expect finalization.
@@ -280,7 +286,13 @@ def add_stake_multiple_extrinsic(
280286
},
281287
)
282288
staking_response, err_msg = subtensor.sign_and_send_extrinsic(
283-
call, wallet, wait_for_inclusion, wait_for_finalization
289+
call,
290+
wallet,
291+
wait_for_inclusion,
292+
wait_for_finalization,
293+
use_nonce=True,
294+
nonce_key="coldkeypub",
295+
sign_with="coldkey",
284296
)
285297

286298
if staking_response is True: # If we successfully staked.

0 commit comments

Comments
 (0)