def test_address(self): obj = RuntimeConfiguration().create_scale_object( 'Address', ScaleBytes("0xff1fa9d1bd1db014b65872ee20aee4fd4d3a942d95d3357f463ea6c799130b6318") ) obj.decode() self.assertEqual(obj.value, '1fa9d1bd1db014b65872ee20aee4fd4d3a942d95d3357f463ea6c799130b6318')
def test_valid_decoding_classes(self): for type_string in RuntimeConfiguration().type_registry['types'].keys( ): decoding_cls = RuntimeConfiguration().get_decoder_class( type_string) self.assertIsNotNone( decoding_cls, msg='"{}" didn\'t return decoding class'.format(type_string)) # Try to decode type mapping if present if decoding_cls.type_mapping: for name, sub_type_string in decoding_cls.type_mapping: sub_decoding_cls = RuntimeConfiguration( ).get_decoder_class(sub_type_string) self.assertIsNotNone( sub_decoding_cls, msg= f' Sub type "{sub_type_string}" didn\'t return decoding class' ) # Try to decode sub_type if present if sub_decoding_cls.sub_type: sub_decoding_cls = RuntimeConfiguration( ).get_decoder_class(sub_decoding_cls.sub_type) self.assertIsNotNone( sub_decoding_cls, msg= f' Sub type "{decoding_cls.sub_type}" didn\'t return decoding class' )
def ss58_decode_account_index(address: str, valid_ss58_format: Optional[int] = None) -> int: """ Decodes given SS58 encoded address to an AccountIndex Parameters ---------- address valid_ss58_format Returns ------- Decoded int AccountIndex """ account_index_bytes = ss58_decode(address, valid_ss58_format) if len(account_index_bytes) == 2: return RuntimeConfiguration().create_scale_object( 'u8', data=ScaleBytes('0x{}'.format(account_index_bytes))).decode() if len(account_index_bytes) == 4: return RuntimeConfiguration().create_scale_object( 'u16', data=ScaleBytes('0x{}'.format(account_index_bytes))).decode() if len(account_index_bytes) == 8: return RuntimeConfiguration().create_scale_object( 'u32', data=ScaleBytes('0x{}'.format(account_index_bytes))).decode() if len(account_index_bytes) == 16: return RuntimeConfiguration().create_scale_object( 'u64', data=ScaleBytes('0x{}'.format(account_index_bytes))).decode() else: raise ValueError("Invalid account index length")
def test_bytes_encode_bytearray(self): value = bytearray(b'This is a test') obj = RuntimeConfiguration().create_scale_object('Bytes') data = obj.encode(value) self.assertEqual("0x385468697320697320612074657374", data.to_hex())
def test_hashmap_decode(self): obj = RuntimeConfiguration().create_scale_object( 'HashMap<Vec<u8>, u32>', data=ScaleBytes( "0x10043102000000083233180000000832381e00000008343550000000")) self.assertEqual([('1', 2), ('23', 24), ('28', 30), ('45', 80)], obj.decode())
def test_bytes_encode_list_of_u8(self): value = [84, 104, 105, 115, 32, 105, 115, 32, 97, 32, 116, 101, 115, 116] obj = RuntimeConfiguration().create_scale_object('Bytes') data = obj.encode(value) self.assertEqual("0x385468697320697320612074657374", data.to_hex())
def setUp(self) -> None: RuntimeConfiguration().clear_type_registry() RuntimeConfiguration().update_type_registry( load_type_registry_preset("default")) RuntimeConfiguration().update_type_registry( load_type_registry_preset("kusama")) RuntimeConfiguration().set_active_spec_version_id(1045)
def test_hashmap_encode(self): obj = RuntimeConfiguration().create_scale_object( 'HashMap<Vec<u8>, u32>') data = obj.encode([('1', 2), ('23', 24), ('28', 30), ('45', 80)]) self.assertEqual( data.to_hex(), '0x10043102000000083233180000000832381e00000008343550000000')
def test_era_immortal(self): obj = RuntimeConfiguration().create_scale_object( 'Era', ScaleBytes('0x00')) obj.decode() self.assertEqual(obj.value, '00') self.assertIsNone(obj.period) self.assertIsNone(obj.phase)
def test_multi_encode(self): as_multi = RuntimeConfiguration().create_scale_object("Call", metadata=self.metadata_decoder) as_multi.encode( { "call_module": "Multisig", "call_function": "as_multi", "call_args": { "call": { "call_module": "Balances", "call_function": "transfer", "call_args": { "dest": "CofvaLbP3m8PLeNRQmLVPWmTT7jGgAXTwyT69k2wkfPxJ9V", "value": 10000000000000 }, }, "maybe_timepoint": {"height": 3012294, "index": 3}, "other_signatories": sorted(['D2bHQwFcQj11SvtkjULEdKhK4WAeP6MThXgosMHjW9DrmbE', 'CofvaLbP3m8PLeNRQmLVPWmTT7jGgAXTwyT69k2wkfPxJ9V']), "threshold": 2, "store_call": True, "max_weight": 10, }, } ) self.assertEqual(str(as_multi.data), "0x1f010200080a2ee2acc37fa96e818e2817afc104ce55770bcccb7333bbf8481d5bc3c6fa4614097421065c7bb0efc6770ffc5d604654159d45910cc7a3cb602be16acc552801c6f62d0003000000a80400000a2ee2acc37fa96e818e2817afc104ce55770bcccb7333bbf8481d5bc3c6fa460b00a0724e1809010a00000000000000")
def __init__(self): RuntimeConfiguration().update_type_registry( load_type_registry_preset('default')) if settings.TYPE_REGISTRY != 'default': RuntimeConfiguration().update_type_registry( load_type_registry_preset(settings.TYPE_REGISTRY)) super(AccountDetailResource, self).__init__()
def test_string_multibyte_chars(self): obj = RuntimeConfiguration().create_scale_object('String') data = obj.encode('µ') self.assertEqual('0x08c2b5', data.to_hex()) obj.decode() self.assertEqual(str(obj), "µ")
def test_string(self): obj = RuntimeConfiguration().create_scale_object('String', ScaleBytes("0x1054657374")) obj.decode() self.assertEqual(str(obj), "Test") data = obj.encode("Test") self.assertEqual("0x1054657374", data.to_hex())
def __init__(self, db_session, type_registry='default'): self.db_session = db_session RuntimeConfiguration().update_type_registry( load_type_registry('default')) if type_registry != 'default': RuntimeConfiguration().update_type_registry( load_type_registry(type_registry)) self.metadata_store = {}
def test_use_config_singleton(self): RuntimeConfiguration(config_id='test').update_type_registry({ 'types': { 'CustomTestType': 'u8' } }) self.assertIsNone(RuntimeConfiguration().get_decoder_class('CustomTestType')) self.assertIsNotNone(RuntimeConfiguration(config_id='test').get_decoder_class('CustomTestType'))
def test_validatorprefs_struct(self): obj = RuntimeConfiguration().create_scale_object( 'ValidatorPrefsTo145', ScaleBytes("0x0c00")) obj.decode() self.assertEqual(obj.value, { 'unstake_threshold': 3, 'validator_payment': 0 })
def setUpClass(cls): RuntimeConfiguration().clear_type_registry() RuntimeConfiguration().update_type_registry(load_type_registry_preset("default")) RuntimeConfiguration().update_type_registry(load_type_registry_preset("kusama")) RuntimeConfiguration().set_active_spec_version_id(1045) cls.metadata_decoder = MetadataDecoder(ScaleBytes(metadata_v10_hex)) cls.metadata_decoder.decode()
def test_set_with_base_class(self): RuntimeConfiguration().update_type_registry(load_type_registry_preset("test")) obj = RuntimeConfiguration().create_scale_object('SetWithoutBaseClass') self.assertFalse(isinstance(obj, GenericContractExecResult)) obj = RuntimeConfiguration().create_scale_object('SetWithBaseClass') self.assertTrue(isinstance(obj, GenericContractExecResult))
def test_dynamic_fixed_array_type_decode_u8(self): obj = RuntimeConfiguration().create_scale_object( '[u8; 65]', data=ScaleBytes( "0xc42b82d02bce3202f6a05d4b06d1ad46963d3be36fd0528bbe90e7f7a4e5fcd38d14234b1c9fcee920d76cfcf43b4ed5dd718e357c2bc1aae3a642975207e67f01" )) self.assertEqual( '0xc42b82d02bce3202f6a05d4b06d1ad46963d3be36fd0528bbe90e7f7a4e5fcd38d14234b1c9fcee920d76cfcf43b4ed5dd718e357c2bc1aae3a642975207e67f01', obj.decode())
def test_compact_u32_encode_decode(self): value = 2000001 obj = RuntimeConfiguration().create_scale_object('Compact<u32>') data = obj.encode(value) obj = CompactU32(data) self.assertEqual(obj.decode(), value)
def test_vec_accountid(self): obj = RuntimeConfiguration().create_scale_object( 'Vec<AccountId>', ScaleBytes("0x0865d2273adeb04478658e183dc5edf41f1d86e42255442af62e72dbf1e6c0b97765d2273adeb04478658e183dc5edf41f1d86e42255442af62e72dbf1e6c0b977") ) obj.decode() self.assertListEqual(obj.value, [ '0x65d2273adeb04478658e183dc5edf41f1d86e42255442af62e72dbf1e6c0b977', '0x65d2273adeb04478658e183dc5edf41f1d86e42255442af62e72dbf1e6c0b977' ])
def ss58_encode_account_index(account_index: int, ss58_format: int = 42) -> str: """ Encodes an AccountIndex to an Substrate address according to provided address_type Parameters ---------- account_index ss58_format Returns ------- """ if 0 <= account_index <= 2**8 - 1: account_idx_encoder = RuntimeConfiguration().create_scale_object('u8') elif 2**8 <= account_index <= 2**16 - 1: account_idx_encoder = RuntimeConfiguration().create_scale_object('u16') elif 2**16 <= account_index <= 2**32 - 1: account_idx_encoder = RuntimeConfiguration().create_scale_object('u32') elif 2**32 <= account_index <= 2**64 - 1: account_idx_encoder = RuntimeConfiguration().create_scale_object('u64') else: raise ValueError("Value too large for an account index") return ss58_encode( account_idx_encoder.encode(account_index).data, ss58_format)
def test_create_multi_sig_address(self): MultiAccountId = RuntimeConfiguration().get_decoder_class("MultiAccountId") multi_sig_account = MultiAccountId.create_from_account_list( ["CdVuGwX71W4oRbXHsLuLQxNPns23rnSSiZwZPN4etWf6XYo", "J9aQobenjZjwWtU2MsnYdGomvcYbgauCnBeb8xGrcqznvJc", "HvqnQxDQbi3LL2URh7WQfcmi8b2ZWfBhu7TEDmyyn5VK8e2"], 2) multi_sig_address = ss58_encode(multi_sig_account.value.replace('0x', ''), 2) self.assertEqual(multi_sig_address, "HFXXfXavDuKhLLBhFQTat2aaRQ5CMMw9mwswHzWi76m6iLt")
def test_parse_subtype(self): RuntimeConfiguration().update_type_registry(load_type_registry_preset("default")) obj = RuntimeConfiguration().create_scale_object('(BalanceOf, Vec<(AccountId, Data)>)') self.assertEqual(obj.type_mapping[0], "BalanceOf") self.assertEqual(obj.type_mapping[1], "Vec<(AccountId, Data)>") obj = RuntimeConfiguration().create_scale_object('Vec<UncleEntryItem<BlockNumber, Hash, AccountId>>') self.assertEqual(obj.sub_type, "UncleEntryItem<BlockNumber, Hash, AccountId>")
def setUpClass(cls): module_path = os.path.dirname(__file__) cls.metadata_fixture_dict = load_type_registry_file( os.path.join(module_path, 'fixtures', 'metadata_hex.json')) RuntimeConfiguration().update_type_registry( load_type_registry_preset("metadata_types")) cls.metadata_decoder = RuntimeConfiguration().create_scale_object( 'MetadataVersioned', data=ScaleBytes(cls.metadata_fixture_dict['V10'])) cls.metadata_decoder.decode()
def test_box_call(self): RuntimeConfiguration().update_type_registry(load_type_registry_preset("default")) scale_value = ScaleBytes("0x0400006e57561de4b4e63f0af8bf336008252a9597e5cdcb7622c72de4ff39731c5402070010a5d4e8") obj = RuntimeConfiguration().create_scale_object('Box<Call>', scale_value, metadata=self.metadata_decoder) value = obj.decode() self.assertEqual(value['call_function'], 'transfer') self.assertEqual(value['call_module'], 'Balances') self.assertEqual(value['call_args'][0]['value'], '0x6e57561de4b4e63f0af8bf336008252a9597e5cdcb7622c72de4ff39731c5402') self.assertEqual(value['call_args'][1]['value'], 1000000000000)
def accumulation_hook(self, db_session): self.block.count_log = len(self.block.logs) for idx, log_data in enumerate(self.block.logs): log_digest = LogDigest(ScaleBytes(log_data)) log_digest.decode() log = Log( block_id=self.block.id, log_idx=idx, type_id=log_digest.index, type=log_digest.index_value, data=log_digest.value, ) if log.type == 'PreRuntime': if log.data['value']['engine'] == 'BABE': # Determine block producer babe_predigest_cls = RuntimeConfiguration( ).get_decoder_class('RawBabePreDigest') babe_predigest = babe_predigest_cls( ScaleBytes( bytearray.fromhex( log.data['value']['data'].replace( '0x', '')))).decode() if len(list(babe_predigest.values())) > 0: babe_predigest_value = list(babe_predigest.values())[0] log.data['value']['data'] = babe_predigest_value self.block.authority_index = log.data['value']['data'][ 'authorityIndex'] self.block.slot_number = log.data['value']['data'][ 'slotNumber'] if log.data['value']['engine'] == 'aura': aura_predigest_cls = RuntimeConfiguration( ).get_decoder_class('RawAuraPreDigest') aura_predigest = aura_predigest_cls( ScaleBytes( bytearray.fromhex( log.data['value']['data'].replace( '0x', '')))).decode() log.data['value']['data'] = aura_predigest self.block.slot_number = aura_predigest['slotNumber'] log.save(db_session)
def test_dynamic_fixed_array_type_decode(self): obj = RuntimeConfiguration().create_scale_object('[u32; 1]', data=ScaleBytes("0x01000000")) self.assertEqual([1], obj.decode()) obj = RuntimeConfiguration().create_scale_object('[u32; 3]', data=ScaleBytes("0x010000000200000003000000")) self.assertEqual([1, 2, 3], obj.decode()) obj = RuntimeConfiguration().create_scale_object('[u32; 0]', data=ScaleBytes(bytes())) self.assertEqual([], obj.decode())
def test_type_registry_overloading(self): # Type BlockNumber defined as U32 in type registry 'kusama' RuntimeConfiguration().update_type_registry(load_type_registry_preset("kusama")) obj = ScaleDecoder.get_decoder_class('BlockNumber', ScaleBytes("0x0000000000000001")) self.assertRaises(RemainingScaleBytesNotEmptyException, obj.decode) # Type BlockNumber changed to U64 in type registry 'test' RuntimeConfiguration().update_type_registry(load_type_registry_preset("test")) obj = ScaleDecoder.get_decoder_class('BlockNumber', ScaleBytes("0x0000000000000001")) obj.decode() self.assertEqual(obj.value, 72057594037927936)
def test_compact_u32_2bytes(self): obj = RuntimeConfiguration().create_scale_object('Compact<u32>', ScaleBytes("0x18")) obj.decode() obj = RuntimeConfiguration().create_scale_object('Compact<u32>') obj.encode(6000) self.assertEqual(str(obj.data), "0xc15d")