diff --git a/async_substrate_interface/async_substrate.py b/async_substrate_interface/async_substrate.py index 3235372..d3f3d04 100644 --- a/async_substrate_interface/async_substrate.py +++ b/async_substrate_interface/async_substrate.py @@ -1186,6 +1186,7 @@ class AsyncSubstrateInterface(SubstrateMixin): def __init__( self, url: str, + *, use_remote_preset: bool = False, auto_discover: bool = True, ss58_format: Optional[int] = None, @@ -1418,7 +1419,7 @@ async def encode_scale( runtime: Optional[Runtime] = None, ) -> bytes: """ - Helper function to encode arbitrary data into SCALE-bytes for given RUST type_string. If neither `block_hash` + Helper function to encode arbitrary data into SCALE-bytes for given type_string. If neither `block_hash` nor `runtime` are supplied, the runtime of the current block will be used. Args: @@ -1572,10 +1573,6 @@ async def _get_runtime_for_version( metadata = await self.get_block_metadata( block_hash=runtime_block_hash, runtime_config=runtime_config ) - logger.debug( - f"Exported method Metadata_metadata_at_version is not found for {runtime_version}. " - f"This indicates the block is quite old, decoding for this block will use legacy Python decoding." - ) if metadata is None: raise SubstrateRequestException( f"No metadata for block '{runtime_block_hash}'" diff --git a/async_substrate_interface/substrate_addons.py b/async_substrate_interface/substrate_addons.py index 71975b5..cc5d6d8 100644 --- a/async_substrate_interface/substrate_addons.py +++ b/async_substrate_interface/substrate_addons.py @@ -106,6 +106,7 @@ class RetrySyncSubstrate(SubstrateInterface): def __init__( self, url: str, + *, use_remote_preset: bool = False, fallback_chains: Optional[list[str]] = None, retry_forever: bool = False, @@ -251,6 +252,7 @@ class RetryAsyncSubstrate(AsyncSubstrateInterface): def __init__( self, url: str, + *, use_remote_preset: bool = False, fallback_chains: Optional[list[str]] = None, retry_forever: bool = False, diff --git a/async_substrate_interface/sync_substrate.py b/async_substrate_interface/sync_substrate.py index 0cc651d..985ff9f 100644 --- a/async_substrate_interface/sync_substrate.py +++ b/async_substrate_interface/sync_substrate.py @@ -472,6 +472,7 @@ class SubstrateInterface(SubstrateMixin): def __init__( self, url: str, + *, use_remote_preset: bool = False, auto_discover: bool = True, ss58_format: Optional[int] = None, @@ -660,6 +661,30 @@ def _load_registry_at_block(self, block_hash: Optional[str], runtime_config=None return None return _decode_v15_metadata(inner_bytes, runtime_config=runtime_config) + def encode_scale( + self, + type_string, + value: Any, + block_hash: Optional[str] = None, + runtime: Optional[Runtime] = None, + ) -> bytes: + """ + Helper function to encode arbitrary data into SCALE-bytes for given type_string. If neither `block_hash` + nor `runtime` are supplied, the runtime of the current block will be used. + + Args: + type_string: the type string of the SCALE object for decoding + value: value to encode + block_hash: hash of the block where the desired runtime is located. Ignored if supplying `runtime` + runtime: the runtime to use for the scale encoding. If supplied, `block_hash` is ignored + + Returns: + encoded bytes + """ + if runtime is None: + runtime = self.init_runtime(block_hash=block_hash) + return self._encode_scale(type_string, value, runtime=runtime) + def decode_scale( self, type_string: str, @@ -798,10 +823,6 @@ def get_runtime_for_version( ) else: metadata = self.get_block_metadata(block_hash=runtime_block_hash) - logger.debug( - f"Exported method Metadata_metadata_at_version is not found for {runtime_version}. " - f"This indicates the block is quite old, decoding for this block will use legacy Python decoding." - ) if metadata is None: raise SubstrateRequestException( f"No metadata for block '{runtime_block_hash}'" @@ -2371,7 +2392,7 @@ def _do_runtime_call_old( param_data = runtime_call_def["encoder"](params, runtime) param_hex = param_data.hex() else: - param_data = self._encode_scale_legacy( + param_data = self._encode_scale_without_encoder( runtime_call_def, params or [], runtime ) param_hex = param_data.to_hex() @@ -3239,5 +3260,3 @@ def close(self): self.supports_rpc_method.cache_clear() self._get_block_hash.cache_clear() self._cached_get_block_number.cache_clear() - - encode_scale = SubstrateMixin._encode_scale diff --git a/async_substrate_interface/types.py b/async_substrate_interface/types.py index 043bf5d..cb0cf6d 100644 --- a/async_substrate_interface/types.py +++ b/async_substrate_interface/types.py @@ -991,72 +991,20 @@ def _encode_scale( encoded bytes """ if value is None: - result = b"\x00" - else: - if not runtime: - runtime = self.runtime - assert runtime is not None - try: - vec_acct_id = ( - f"scale_info::{runtime.registry_type_map['Vec']}" - ) - except KeyError: - vec_acct_id = "scale_info::152" - try: - optional_acct_u16 = f"scale_info::{runtime.registry_type_map['Option<(AccountId32, u16)>']}" - except KeyError: - optional_acct_u16 = "scale_info::579" - - if type_string == "scale_info::0": # Is an AccountId - # encode string into AccountId - ## AccountId is a composite type with one, unnamed field - return self._encode_account_id(value) - - elif type_string == optional_acct_u16: - if value is None: - return b"\x00" # None - - if not isinstance(value, (list, tuple)) or len(value) != 2: - raise ValueError("Expected tuple of (account_id, u16)") - account_id, u16_value = value - - result = b"\x01" - result += self._encode_account_id(account_id) - result += u16_value.to_bytes(2, "little") - return result - - elif type_string == vec_acct_id: # Vec - if not isinstance(value, (list, tuple)): - value = [value] - - # Encode length - length = len(value) - if length < 64: - result = bytes([length << 2]) # Single byte mode - else: - raise ValueError("Vector length too large") - - # Encode each AccountId - for account in value: - result += self._encode_account_id(account) - return result - - if isinstance(value, ScaleType): - if value.data is not None and value.data.data is not None: - # Already encoded - return bytes(value.data.data) - else: - value = value.value # Unwrap the value of the type - - result = bytes( - runtime.runtime_config.create_scale_object(type_string) - .encode(value) - .data - ) - return result + return b"\x00" + if not runtime: + runtime = self.runtime + assert runtime is not None + if isinstance(value, ScaleType): + if value.data is not None and value.data.data is not None: + return bytes(value.data.data) + value = value.value + return bytes( + runtime.runtime_config.create_scale_object(type_string).encode(value).data + ) @staticmethod - def _encode_scale_legacy( + def _encode_scale_without_encoder( call_definition: list[dict], params: list[Any] | dict[str, Any], runtime: Runtime, @@ -1076,20 +1024,6 @@ def _encode_scale_legacy( return param_data - @staticmethod - def _encode_account_id(account) -> bytes: - """Encode an account ID into bytes. - - Args: - account: Either bytes (already encoded) or SS58 string - - Returns: - bytes: The encoded account ID - """ - if isinstance(account, bytes): - return account # Already encoded - return bytes.fromhex(ss58_decode(account, SS58_FORMAT)) # SS58 string - def generate_multisig_account( self, signatories: list, threshold: int ) -> MultiAccountId: