From 46a21fb9bea5097dc05b3ffac5947ba461bfe999 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Mon, 6 Oct 2025 20:34:26 -0400 Subject: [PATCH 1/5] change legacy (old) runtimeApi params encoding --- async_substrate_interface/async_substrate.py | 4 +++- async_substrate_interface/sync_substrate.py | 4 +++- async_substrate_interface/type_registry.py | 16 +++++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/async_substrate_interface/async_substrate.py b/async_substrate_interface/async_substrate.py index 3ccf8af..5e258f5 100644 --- a/async_substrate_interface/async_substrate.py +++ b/async_substrate_interface/async_substrate.py @@ -3055,7 +3055,9 @@ async def _do_runtime_call_old( param_data = b"" if "encoder" in runtime_call_def: - param_data = runtime_call_def["encoder"](params) + if runtime is None: + runtime = await self.init_runtime(block_hash=block_hash) + param_data = runtime_call_def["encoder"](params, runtime.registry) else: for idx, param in enumerate(runtime_call_def["params"]): param_type_string = f"{param['type']}" diff --git a/async_substrate_interface/sync_substrate.py b/async_substrate_interface/sync_substrate.py index 1622d78..3e8222c 100644 --- a/async_substrate_interface/sync_substrate.py +++ b/async_substrate_interface/sync_substrate.py @@ -2541,7 +2541,9 @@ def _do_runtime_call_old( param_data = b"" if "encoder" in runtime_call_def: - param_data = runtime_call_def["encoder"](params) + if runtime is None: + runtime = self.init_runtime(block_hash=block_hash) + param_data = runtime_call_def["encoder"](params, runtime.registry) else: for idx, param in enumerate(runtime_call_def["params"]): param_type_string = f"{param['type']}" diff --git a/async_substrate_interface/type_registry.py b/async_substrate_interface/type_registry.py index 0f224e8..53fcb8b 100644 --- a/async_substrate_interface/type_registry.py +++ b/async_substrate_interface/type_registry.py @@ -8,7 +8,7 @@ SubnetInfoV2, encode, ) -from scalecodec import ss58_encode +from scalecodec import ss58_decode _TYPE_REGISTRY: dict[str, dict] = { "types": { @@ -24,7 +24,9 @@ "type": "Vec", }, ], - "encoder": lambda addr: encode(ss58_encode(addr), "Vec"), + "encoder": lambda addr, reg: encode( + "Vec", reg, list(bytes.fromhex(ss58_decode(addr))) + ), "type": "Vec", "decoder": DelegateInfo.decode_delegated, }, @@ -97,7 +99,9 @@ }, ], "type": "Vec", - "encoder": lambda addr: encode(ss58_encode(addr), "Vec"), + "encoder": lambda addr, reg: encode( + "Vec", reg, list(bytes.fromhex(ss58_decode(addr))) + ), "decoder": StakeInfo.decode_vec, }, "get_stake_info_for_coldkeys": { @@ -108,8 +112,10 @@ }, ], "type": "Vec", - "encoder": lambda addrs: encode( - [ss58_encode(addr) for addr in addrs], "Vec>" + "encoder": lambda addrs, reg: encode( + "Vec>", + reg, + [list(bytes.fromhex(ss58_decode(addr))) for addr in addrs], ), "decoder": StakeInfo.decode_vec_tuple_vec, }, From e083cfc99a291813712c8ff851c070f1403f9810 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Wed, 8 Oct 2025 17:18:51 +0200 Subject: [PATCH 2/5] Small fixes, still WIP --- async_substrate_interface/sync_substrate.py | 3 +-- async_substrate_interface/type_registry.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/async_substrate_interface/sync_substrate.py b/async_substrate_interface/sync_substrate.py index 3e8222c..f00ea25 100644 --- a/async_substrate_interface/sync_substrate.py +++ b/async_substrate_interface/sync_substrate.py @@ -2541,8 +2541,7 @@ def _do_runtime_call_old( param_data = b"" if "encoder" in runtime_call_def: - if runtime is None: - runtime = self.init_runtime(block_hash=block_hash) + runtime = self.init_runtime(block_hash=block_hash) param_data = runtime_call_def["encoder"](params, runtime.registry) else: for idx, param in enumerate(runtime_call_def["params"]): diff --git a/async_substrate_interface/type_registry.py b/async_substrate_interface/type_registry.py index 53fcb8b..5374820 100644 --- a/async_substrate_interface/type_registry.py +++ b/async_substrate_interface/type_registry.py @@ -100,7 +100,7 @@ ], "type": "Vec", "encoder": lambda addr, reg: encode( - "Vec", reg, list(bytes.fromhex(ss58_decode(addr))) + "Vec", reg, list(bytes.fromhex(ss58_decode(addr[0] if isinstance(addr, list) else addr["coldkey"]))) ), "decoder": StakeInfo.decode_vec, }, From 936d6e89b9595180b0ac36c6383feac1e2a5a265 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Wed, 8 Oct 2025 17:21:13 +0200 Subject: [PATCH 3/5] Added test (failing currently, needs to pass) --- tests/integration_tests/test_substrate_interface.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/integration_tests/test_substrate_interface.py b/tests/integration_tests/test_substrate_interface.py index ad80401..0f65864 100644 --- a/tests/integration_tests/test_substrate_interface.py +++ b/tests/integration_tests/test_substrate_interface.py @@ -112,3 +112,12 @@ def test_query_map_with_odd_number_of_params(): first_record = qm.records[0] assert len(first_record) == 2 assert len(first_record[0]) == 4 + + +def test_old_runtime_calls(): + from bittensor import SubtensorApi + sub = SubtensorApi(network='archive', legacy_methods=True, async_subtensor=False) + # will pass + assert sub.get_stake_info_for_coldkey('5CQ6dMW8JZhKCZX9kWsZRqa3kZRKmNHxbPPVFEt6FgyvGv2G', 4943592) + # needs to use legacy + assert sub.get_stake_info_for_coldkey('5CQ6dMW8JZhKCZX9kWsZRqa3kZRKmNHxbPPVFEt6FgyvGv2G', 4670227) From e85cec2ad09e9e10182100a7eb722f490efdbe2d Mon Sep 17 00:00:00 2001 From: bdhimes Date: Wed, 8 Oct 2025 18:12:30 +0200 Subject: [PATCH 4/5] Add Legacy conversion namedtuple --- async_substrate_interface/type_registry.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/async_substrate_interface/type_registry.py b/async_substrate_interface/type_registry.py index 5374820..d292bc9 100644 --- a/async_substrate_interface/type_registry.py +++ b/async_substrate_interface/type_registry.py @@ -1,3 +1,5 @@ +from typing import Union +from collections import namedtuple from bt_decode import ( NeuronInfo, NeuronInfoLite, @@ -10,6 +12,18 @@ ) from scalecodec import ss58_decode + +def stake_info_decode_vec_legacy_compatibility(item) -> list[dict[str, Union[str, int, bytes, bool]]]: + stake_infos: list[StakeInfo] = StakeInfo.decode_vec(item) + NewStakeInfo = namedtuple("NewStakeInfo", ["netuid", "hotkey", "coldkey", "stake", "locked", "emission", "drain", "is_registered"]) + output = [] + for stake_info in stake_infos: + output.append( + NewStakeInfo(0, stake_info.hotkey, stake_info.coldkey, stake_info.stake, 0, 0, 0, False) + ) + return output + + _TYPE_REGISTRY: dict[str, dict] = { "types": { "Balance": "u64", # Need to override default u128 @@ -102,7 +116,7 @@ "encoder": lambda addr, reg: encode( "Vec", reg, list(bytes.fromhex(ss58_decode(addr[0] if isinstance(addr, list) else addr["coldkey"]))) ), - "decoder": StakeInfo.decode_vec, + "decoder": stake_info_decode_vec_legacy_compatibility, }, "get_stake_info_for_coldkeys": { "params": [ From 33a9f181c6b503e456bb2fe158e126aeb678a6b6 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Wed, 8 Oct 2025 18:25:27 +0200 Subject: [PATCH 5/5] WIP --- async_substrate_interface/type_registry.py | 55 +++++++++++++++++-- .../test_substrate_interface.py | 11 +++- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/async_substrate_interface/type_registry.py b/async_substrate_interface/type_registry.py index d292bc9..7e2e246 100644 --- a/async_substrate_interface/type_registry.py +++ b/async_substrate_interface/type_registry.py @@ -13,17 +13,52 @@ from scalecodec import ss58_decode -def stake_info_decode_vec_legacy_compatibility(item) -> list[dict[str, Union[str, int, bytes, bool]]]: +def stake_info_decode_vec_legacy_compatibility( + item, +) -> list[dict[str, Union[str, int, bytes, bool]]]: stake_infos: list[StakeInfo] = StakeInfo.decode_vec(item) - NewStakeInfo = namedtuple("NewStakeInfo", ["netuid", "hotkey", "coldkey", "stake", "locked", "emission", "drain", "is_registered"]) + NewStakeInfo = namedtuple( + "NewStakeInfo", + [ + "netuid", + "hotkey", + "coldkey", + "stake", + "locked", + "emission", + "drain", + "is_registered", + ], + ) output = [] for stake_info in stake_infos: output.append( - NewStakeInfo(0, stake_info.hotkey, stake_info.coldkey, stake_info.stake, 0, 0, 0, False) + NewStakeInfo( + 0, + stake_info.hotkey, + stake_info.coldkey, + stake_info.stake, + 0, + 0, + 0, + False, + ) ) return output +def preprocess_get_stake_info_for_coldkeys(addrs): + output = [] + if isinstance(addrs[0], list): # I think + for addr in addrs[0]: + output.append(list(bytes.fromhex(ss58_decode(addr)))) + else: + if isinstance(addrs[0], dict): + for addr in addrs[0]["coldkey_accounts"]: + output.append(list(bytes.fromhex(ss58_decode(addr)))) + return output + + _TYPE_REGISTRY: dict[str, dict] = { "types": { "Balance": "u64", # Need to override default u128 @@ -114,7 +149,17 @@ def stake_info_decode_vec_legacy_compatibility(item) -> list[dict[str, Union[str ], "type": "Vec", "encoder": lambda addr, reg: encode( - "Vec", reg, list(bytes.fromhex(ss58_decode(addr[0] if isinstance(addr, list) else addr["coldkey"]))) + "Vec", + reg, + list( + bytes.fromhex( + ss58_decode( + addr[0] + if isinstance(addr, list) + else addr["coldkey_account"] + ) + ) + ), ), "decoder": stake_info_decode_vec_legacy_compatibility, }, @@ -129,7 +174,7 @@ def stake_info_decode_vec_legacy_compatibility(item) -> list[dict[str, Union[str "encoder": lambda addrs, reg: encode( "Vec>", reg, - [list(bytes.fromhex(ss58_decode(addr))) for addr in addrs], + preprocess_get_stake_info_for_coldkeys(addrs), ), "decoder": StakeInfo.decode_vec_tuple_vec, }, diff --git a/tests/integration_tests/test_substrate_interface.py b/tests/integration_tests/test_substrate_interface.py index 0f65864..2fc8d0f 100644 --- a/tests/integration_tests/test_substrate_interface.py +++ b/tests/integration_tests/test_substrate_interface.py @@ -116,8 +116,13 @@ def test_query_map_with_odd_number_of_params(): def test_old_runtime_calls(): from bittensor import SubtensorApi - sub = SubtensorApi(network='archive', legacy_methods=True, async_subtensor=False) + + sub = SubtensorApi(network="archive", legacy_methods=True, async_subtensor=False) # will pass - assert sub.get_stake_info_for_coldkey('5CQ6dMW8JZhKCZX9kWsZRqa3kZRKmNHxbPPVFEt6FgyvGv2G', 4943592) + assert sub.get_stake_info_for_coldkey( + "5CQ6dMW8JZhKCZX9kWsZRqa3kZRKmNHxbPPVFEt6FgyvGv2G", 4943592 + ) # needs to use legacy - assert sub.get_stake_info_for_coldkey('5CQ6dMW8JZhKCZX9kWsZRqa3kZRKmNHxbPPVFEt6FgyvGv2G', 4670227) + assert sub.get_stake_info_for_coldkey( + "5CQ6dMW8JZhKCZX9kWsZRqa3kZRKmNHxbPPVFEt6FgyvGv2G", 4670227 + )