11
11
from bittensor_wallet .utils import SS58_FORMAT
12
12
from numpy .typing import NDArray
13
13
from scalecodec import GenericCall
14
- from scalecodec .base import RuntimeConfiguration
15
- from scalecodec .type_registry import load_type_registry_preset
16
14
from substrateinterface .exceptions import SubstrateRequestException
17
15
18
16
from bittensor .core .chain_data import (
19
17
DelegateInfo ,
20
- custom_rpc_type_registry ,
21
18
StakeInfo ,
22
19
NeuronInfoLite ,
23
20
NeuronInfo ,
50
47
from bittensor .core .settings import version_as_int
51
48
from bittensor .utils import (
52
49
torch ,
53
- ss58_to_vec_u8 ,
54
50
format_error_message ,
55
51
decode_hex_identity_dict ,
56
52
validate_chain_endpoint ,
@@ -498,17 +494,15 @@ async def get_delegates(
498
494
List of DelegateInfo objects, or an empty list if there are no delegates.
499
495
"""
500
496
block_hash = await self ._determine_block_hash (block , block_hash , reuse_block )
501
- hex_bytes_result = await self .query_runtime_api (
497
+ result = await self .query_runtime_api (
502
498
runtime_api = "DelegateInfoRuntimeApi" ,
503
499
method = "get_delegates" ,
504
500
params = [],
505
501
block_hash = block_hash ,
506
502
reuse_block = reuse_block ,
507
503
)
508
- if hex_bytes_result is not None :
509
- return DelegateInfo .list_from_vec_u8 (hex_to_bytes (hex_bytes_result ))
510
- else :
511
- return []
504
+
505
+ return DelegateInfo .list_from_any (result ) if result is not None else []
512
506
513
507
async def get_stake_info_for_coldkey (
514
508
self ,
@@ -534,20 +528,19 @@ async def get_stake_info_for_coldkey(
534
528
Stake information is vital for account holders to assess their investment and participation in the network's
535
529
delegation and consensus processes.
536
530
"""
537
- encoded_coldkey = ss58_to_vec_u8 (coldkey_ss58 )
538
531
block_hash = await self ._determine_block_hash (block , block_hash , reuse_block )
539
- hex_bytes_result = await self .query_runtime_api (
532
+ result = await self .query_runtime_api (
540
533
runtime_api = "StakeInfoRuntimeApi" ,
541
534
method = "get_stake_info_for_coldkey" ,
542
- params = [encoded_coldkey ],
535
+ params = [coldkey_ss58 ],
543
536
block_hash = block_hash ,
544
537
reuse_block = reuse_block ,
545
538
)
546
539
547
- if hex_bytes_result is None :
540
+ if result is None :
548
541
return []
549
542
550
- return StakeInfo .list_from_vec_u8 ( hex_to_bytes ( hex_bytes_result ) )
543
+ return StakeInfo .list_from_any ( result )
551
544
552
545
async def get_stake_for_coldkey_and_hotkey (
553
546
self ,
@@ -585,11 +578,11 @@ async def query_runtime_api(
585
578
self ,
586
579
runtime_api : str ,
587
580
method : str ,
588
- params : Optional [Union [list [list [ int ]] , dict [str , int ], list [ int ]]],
581
+ params : Optional [Union [list [Any ] , dict [str , Any ]]],
589
582
block : Optional [int ] = None ,
590
583
block_hash : Optional [str ] = None ,
591
584
reuse_block : bool = False ,
592
- ) -> Optional [str ]:
585
+ ) -> Optional [Any ]:
593
586
"""
594
587
Queries the runtime API of the Bittensor blockchain, providing a way to interact with the underlying runtime and
595
588
retrieve data encoded in Scale Bytes format. This function is essential for advanced users who need to
@@ -605,46 +598,17 @@ async def query_runtime_api(
605
598
reuse_block: Whether to reuse the last-used block hash. Do not set if using block_hash or block
606
599
607
600
Returns:
608
- The Scale Bytes encoded result from the runtime API call, or `None` if the call fails.
601
+ The decoded result from the runtime API call, or `None` if the call fails.
609
602
610
603
This function enables access to the deeper layers of the Bittensor blockchain, allowing for detailed and
611
604
specific interactions with the network's runtime environment.
612
605
"""
613
606
block_hash = await self ._determine_block_hash (block , block_hash , reuse_block )
614
-
615
- call_definition = TYPE_REGISTRY ["runtime_api" ][runtime_api ]["methods" ][method ]
616
-
617
- data = (
618
- "0x"
619
- if params is None
620
- else await self .encode_params (
621
- call_definition = call_definition , params = params
622
- )
623
- )
624
- api_method = f"{ runtime_api } _{ method } "
625
-
626
- json_result = await self .substrate .rpc_request (
627
- method = "state_call" ,
628
- params = [api_method , data , block_hash ] if block_hash else [api_method , data ],
629
- reuse_block_hash = reuse_block ,
607
+ result = await self .substrate .runtime_call (
608
+ runtime_api , method , params , block_hash
630
609
)
631
610
632
- if json_result is None :
633
- return None
634
-
635
- return_type = call_definition ["type" ]
636
-
637
- as_scale_bytes = scalecodec .ScaleBytes (json_result ["result" ]) # type: ignore
638
-
639
- rpc_runtime_config = RuntimeConfiguration ()
640
- rpc_runtime_config .update_type_registry (load_type_registry_preset ("legacy" ))
641
- rpc_runtime_config .update_type_registry (custom_rpc_type_registry )
642
-
643
- obj = rpc_runtime_config .create_scale_object (return_type , as_scale_bytes )
644
- if obj .data .to_hex () == "0x0400" : # RPC returned None result
645
- return None
646
-
647
- return obj .decode ()
611
+ return result
648
612
649
613
async def get_balance (
650
614
self ,
@@ -1002,18 +966,18 @@ async def neurons(
1002
966
decentralized structure and the dynamics of its consensus and governance processes.
1003
967
"""
1004
968
block_hash = await self ._determine_block_hash (block , block_hash , reuse_block )
1005
- hex_bytes_result = await self .query_runtime_api (
969
+ result = await self .query_runtime_api (
1006
970
runtime_api = "NeuronInfoRuntimeApi" ,
1007
971
method = "get_neurons" ,
1008
972
params = [netuid ],
1009
973
block_hash = block_hash ,
1010
974
reuse_block = reuse_block ,
1011
975
)
1012
976
1013
- if hex_bytes_result is None :
977
+ if result is None :
1014
978
return []
1015
979
1016
- return NeuronInfo .list_from_vec_u8 ( hex_to_bytes ( hex_bytes_result ) )
980
+ return NeuronInfo .list_from_any ( result )
1017
981
1018
982
async def neurons_lite (
1019
983
self ,
@@ -1041,18 +1005,18 @@ async def neurons_lite(
1041
1005
of the network's decentralized structure and neuron dynamics.
1042
1006
"""
1043
1007
block_hash = await self ._determine_block_hash (block , block_hash , reuse_block )
1044
- hex_bytes_result = await self .query_runtime_api (
1008
+ result = await self .query_runtime_api (
1045
1009
runtime_api = "NeuronInfoRuntimeApi" ,
1046
1010
method = "get_neurons_lite" ,
1047
1011
params = [netuid ],
1048
1012
block_hash = block_hash ,
1049
1013
reuse_block = reuse_block ,
1050
1014
)
1051
1015
1052
- if hex_bytes_result is None :
1016
+ if result is None :
1053
1017
return []
1054
1018
1055
- return NeuronInfoLite .list_from_vec_u8 ( hex_to_bytes ( hex_bytes_result ) )
1019
+ return NeuronInfoLite .list_from_any ( result )
1056
1020
1057
1021
async def get_neuron_for_pubkey_and_subnet (
1058
1022
self ,
@@ -1092,16 +1056,20 @@ async def get_neuron_for_pubkey_and_subnet(
1092
1056
if uid is None :
1093
1057
return NeuronInfo .get_null_neuron ()
1094
1058
1095
- params = [netuid , uid ]
1096
- json_body = await self .substrate .rpc_request (
1097
- method = "neuronInfo_getNeuron" ,
1098
- params = params ,
1059
+ result = await self .query_runtime_api (
1060
+ runtime_api = "NeuronInfoRuntimeApi" ,
1061
+ method = "get_neuron" ,
1062
+ params = [
1063
+ netuid ,
1064
+ uid ,
1065
+ ], # TODO check to see if this can accept more than one at a time
1066
+ block_hash = block_hash ,
1099
1067
)
1100
1068
1101
- if not ( result := json_body . get ( "result" , None )) :
1069
+ if not result :
1102
1070
return NeuronInfo .get_null_neuron ()
1103
1071
1104
- return NeuronInfo .from_vec_u8 ( bytes ( result ) )
1072
+ return NeuronInfo .from_any ( result )
1105
1073
1106
1074
async def neuron_for_uid (
1107
1075
self ,
@@ -1137,16 +1105,20 @@ async def neuron_for_uid(
1137
1105
if reuse_block :
1138
1106
block_hash = self .substrate .last_block_hash
1139
1107
1140
- params = [netuid , uid , block_hash ] if block_hash else [netuid , uid ]
1141
- json_body = await self .substrate .rpc_request (
1142
- method = "neuronInfo_getNeuron" ,
1143
- params = params , # custom rpc method
1108
+ result = await self .query_runtime_api (
1109
+ runtime_api = "NeuronInfoRuntimeApi" ,
1110
+ method = "get_neuron" ,
1111
+ params = [
1112
+ netuid ,
1113
+ uid ,
1114
+ ],
1115
+ block_hash = block_hash ,
1144
1116
)
1145
- if not (result := json_body .get ("result" , None )):
1117
+
1118
+ if not result :
1146
1119
return NeuronInfo .get_null_neuron ()
1147
1120
1148
- bytes_result = bytes (result )
1149
- return NeuronInfo .from_vec_u8 (bytes_result )
1121
+ return NeuronInfo .from_any (result )
1150
1122
1151
1123
async def get_delegated (
1152
1124
self ,
@@ -1177,16 +1149,18 @@ async def get_delegated(
1177
1149
if (bh := await self ._determine_block_hash (block , block_hash , reuse_block ))
1178
1150
else (self .substrate .last_block_hash if reuse_block else None )
1179
1151
)
1180
- encoded_coldkey = ss58_to_vec_u8 (coldkey_ss58 )
1181
- json_body = await self .substrate .rpc_request (
1182
- method = "delegateInfo_getDelegated" ,
1183
- params = ([block_hash , encoded_coldkey ] if block_hash else [encoded_coldkey ]),
1152
+
1153
+ result = await self .query_runtime_api (
1154
+ runtime_api = "DelegateInfoRuntimeApi" ,
1155
+ method = "get_delegated" ,
1156
+ params = [coldkey_ss58 ],
1157
+ block_hash = block_hash ,
1184
1158
)
1185
1159
1186
- if not ( result := json_body . get ( "result" )) :
1160
+ if not result :
1187
1161
return []
1188
1162
1189
- return DelegateInfo .delegated_list_from_vec_u8 ( bytes ( result ) )
1163
+ return DelegateInfo .delegated_list_from_any ( result )
1190
1164
1191
1165
async def query_identity (
1192
1166
self ,
@@ -1496,18 +1470,18 @@ async def get_subnet_hyperparameters(
1496
1470
they interact with the network's consensus and incentive mechanisms.
1497
1471
"""
1498
1472
block_hash = await self ._determine_block_hash (block , block_hash , reuse_block )
1499
- hex_bytes_result = await self .query_runtime_api (
1473
+ result = await self .query_runtime_api (
1500
1474
runtime_api = "SubnetInfoRuntimeApi" ,
1501
1475
method = "get_subnet_hyperparams" ,
1502
1476
params = [netuid ],
1503
1477
block_hash = block_hash ,
1504
1478
reuse_block = reuse_block ,
1505
1479
)
1506
1480
1507
- if hex_bytes_result is None :
1481
+ if result is None :
1508
1482
return []
1509
1483
1510
- return SubnetHyperparameters .from_vec_u8 ( hex_to_bytes ( hex_bytes_result ) )
1484
+ return SubnetHyperparameters .from_any ( result )
1511
1485
1512
1486
async def get_vote_data (
1513
1487
self ,
0 commit comments