예제 #1
0
    def test_metadata_registry_v13(self):

        metadata_obj = self.runtime_config.create_scale_object(
            "MetadataVersioned",
            data=ScaleBytes(self.metadata_fixture_dict['V13']))
        metadata_obj.decode()
        self.assertEqual(metadata_obj.value_object[1].index, 13)
        self.assertIsNone(metadata_obj.portable_registry)
        self.assertGreater(len(metadata_obj[1][1]['modules']), 0)
        self.assertGreater(len(metadata_obj.value[1]['V13']['modules']), 0)
        self.assertGreater(len(metadata_obj.call_index.items()), 0)
예제 #2
0
    def test_enum_multiple_fields(self):

        obj = self.runtime_config.create_scale_object(
            'sp_runtime::generic::digest::DigestItem',
            ScaleBytes("0x06010203041054657374"))
        obj.decode()

        self.assertEqual({'PreRuntime': ("0x01020304", "Test")}, obj.value)

        data = obj.encode({'PreRuntime': ("0x01020304", "Test")})
        self.assertEqual("0x06010203041054657374", data.to_hex())
예제 #3
0
파일: types.py 프로젝트: mvs-org/explorer
    def process_encode(self, value):
        if value == '00':
            self.period = None
            self.phase = None
            return ScaleBytes('0x00')
        if isinstance(value, dict):
            value = self._tuple_from_dict(value)
        if isinstance(value, tuple) and len(value) == 2:
            period, phase = value
            if not isinstance(phase, int) or not isinstance(period, int):
                raise ValueError("Phase and period must be ints")
            if phase > period:
                raise ValueError("Phase must be less than period")
            self.period = period
            self.phase = phase
            quantize_factor = max(period >> 12, 1)
            encoded = min(15, max(1, trailing_zeros(period) - 1)) | ((phase // quantize_factor) << 4)
            return ScaleBytes(encoded.to_bytes(length=2, byteorder='little', signed=False))

        raise ValueError("Value must be the string '00' or tuple of two ints")
예제 #4
0
    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()
예제 #5
0
 def test_vec_accountid(self):
     obj = ScaleDecoder.get_decoder_class(
         'Vec<AccountId>',
         ScaleBytes(
             "0x0865d2273adeb04478658e183dc5edf41f1d86e42255442af62e72dbf1e6c0b97765d2273adeb04478658e183dc5edf41f1d86e42255442af62e72dbf1e6c0b977"
         ))
     obj.decode()
     self.assertListEqual(obj.value, [
         '0x65d2273adeb04478658e183dc5edf41f1d86e42255442af62e72dbf1e6c0b977',
         '0x65d2273adeb04478658e183dc5edf41f1d86e42255442af62e72dbf1e6c0b977'
     ])
예제 #6
0
    def test_generic_vote(self):
        runtime_config = RuntimeConfigurationObject(ss58_format=2)

        vote = runtime_config.create_scale_object('GenericVote')
        data = vote.encode({'aye': True, 'conviction': 'Locked2x'})

        self.assertEqual('0x82', data.to_hex())

        vote.decode(ScaleBytes('0x04'))

        self.assertEqual(vote.value, {'aye': False, 'conviction': 'Locked4x'})
예제 #7
0
 def test_vec_accountid(self):
     obj = RuntimeConfiguration().create_scale_object(
         'Vec<AccountId>',
         ScaleBytes(
             "0x0865d2273adeb04478658e183dc5edf41f1d86e42255442af62e72dbf1e6c0b97765d2273adeb04478658e183dc5edf41f1d86e42255442af62e72dbf1e6c0b977"
         ))
     obj.decode()
     self.assertListEqual(obj.value, [
         '0x65d2273adeb04478658e183dc5edf41f1d86e42255442af62e72dbf1e6c0b977',
         '0x65d2273adeb04478658e183dc5edf41f1d86e42255442af62e72dbf1e6c0b977'
     ])
예제 #8
0
    def process(self):
        value = super().process()
        try:
            call_obj = self.get_decoder_class(type_string='Call',
                                              data=ScaleBytes('0x{}'.format(
                                                  self.raw_value)),
                                              metadata=self.metadata)

            return call_obj.process()
        except:
            return value
예제 #9
0
파일: types.py 프로젝트: mvs-org/explorer
    def process_encode(self, value):
        if self.type_mapping:

            if type(value) == str:
                # Convert simple enum values
                value = {value: None}

            if type(value) != dict:
                raise ValueError(
                    "Value must be a dict when type_mapping is set, not '{}'".
                    format(value))

            if len(value) != 1:
                raise ValueError(
                    "Value for enum with type_mapping can only have one value")

            for enum_key, enum_value in value.items():
                for idx, (item_key,
                          item_value) in enumerate(self.type_mapping):
                    if item_key == enum_key:
                        self.index = idx
                        struct_obj = self.get_decoder_class(
                            type_string='Struct',
                            type_mapping=[self.type_mapping[self.index]],
                            runtime_config=self.runtime_config)
                        return ScaleBytes(bytearray(
                            [self.index])) + struct_obj.encode(value)

                raise ValueError(
                    "Value '{}' not present in type_mapping of this enum".
                    format(enum_key))

        else:
            for idx, item in enumerate(self.value_list):
                if item == value:
                    self.index = idx
                    return ScaleBytes(bytearray([self.index]))

            raise ValueError(
                "Value '{}' not present in value list of this enum".format(
                    value))
예제 #10
0
    def test_dynamic_set(self):
        RuntimeConfiguration().update_type_registry(
            load_type_registry_preset("default"))

        obj = ScaleDecoder.get_decoder_class('WithdrawReasons',
                                             ScaleBytes("0x0100000000000000"))
        obj.decode()

        self.assertEqual(obj.value, ["TransactionPayment"])

        obj = ScaleDecoder.get_decoder_class('WithdrawReasons',
                                             ScaleBytes("0x0300000000000000"))
        obj.decode()

        self.assertEqual(obj.value, ["TransactionPayment", "Transfer"])

        obj = ScaleDecoder.get_decoder_class('WithdrawReasons',
                                             ScaleBytes("0x1600000000000000"))
        obj.decode()

        self.assertEqual(obj.value, ["Transfer", "Reserve", "Tip"])
예제 #11
0
    def test_era_mortal(self):
        obj = RuntimeConfiguration().create_scale_object(
            'Era', ScaleBytes('0x4e9c'))
        obj.decode()
        self.assertTupleEqual(obj.value, (32768, 20000))
        self.assertEqual(obj.period, 32768)
        self.assertEqual(obj.phase, 20000)

        obj = RuntimeConfiguration().create_scale_object(
            'Era', ScaleBytes('0xc503'))
        obj.decode()
        self.assertTupleEqual(obj.value, (64, 60))
        self.assertEqual(obj.period, 64)
        self.assertEqual(obj.phase, 60)

        obj = RuntimeConfiguration().create_scale_object(
            'Era', ScaleBytes('0x8502'))
        obj.decode()
        self.assertTupleEqual(obj.value, (64, 40))
        self.assertEqual(obj.period, 64)
        self.assertEqual(obj.phase, 40)
    def test_compact_balance_encode_decode(self):
        scale_data = ScaleBytes('0x070010a5d4e8')
        value = 1000000000000

        obj = ScaleDecoder.get_decoder_class('Compact<Balance>')
        data = obj.encode(value)

        self.assertEqual(str(scale_data), str(data))

        obj_check = ScaleDecoder.get_decoder_class('Compact<Balance>', data)

        self.assertEqual(obj_check.decode(), value)
예제 #13
0
    def encode(self, value: int):

        if value <= 0b00111111:
            self.data = ScaleBytes(bytearray(int(value << 2).to_bytes(1, 'little')))

        elif value <= 0b0011111111111111:
            self.data = ScaleBytes(bytearray(int((value << 2) | 0b01).to_bytes(2, 'little')))

        elif value <= 0b00111111111111111111111111111111:

            self.data = ScaleBytes(bytearray(int((value << 2) | 0b10).to_bytes(4, 'little')))

        else:
            for bytes_length in range(5, 68):
                if 2 ** (8 * (bytes_length-1)) <= value < 2 ** (8 * bytes_length):
                    self.data = ScaleBytes(bytearray(((bytes_length - 4) << 2 | 0b11).to_bytes(1, 'little') + value.to_bytes(bytes_length, 'little')))
                    break
            else:
                raise ValueError('{} out of range'.format(value))

        return self.data
예제 #14
0
 def test_wrapped_opaque_decode_fail(self):
     opaque_hex = '0x180a000022db73'
     wrapped_obj = self.runtime_config_v14.create_scale_object(
         type_string="WrapperKeepOpaque",
         metadata=self.metadata_v14_obj
     )
     wrapped_obj.type_mapping = ("Compact<u32>", "Call")
     wrapped_obj.decode(ScaleBytes(opaque_hex))
     self.assertEqual(
         "0x0a000022db73",
         wrapped_obj.value
     )
예제 #15
0
    def test_box_call(self):
        RuntimeConfiguration().update_type_registry(load_type_registry_preset("default"))

        scale_value = ScaleBytes("0x0400006e57561de4b4e63f0af8bf336008252a9597e5cdcb7622c72de4ff39731c5402070010a5d4e8")

        obj = ScaleDecoder.get_decoder_class('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)
예제 #16
0
    def test_unnamed_struct_multiple_elements(self):
        # pallet_democracy::vote::PriorLock
        obj = self.runtime_config.create_scale_object(
            'scale_info::377',
            ScaleBytes("0x0c00000022000000000000000000000000000000"))

        obj.decode()
        self.assertEqual((12, 34), obj.value)

        data = obj.encode((12, 34))
        self.assertEqual(data.to_hex(),
                         '0x0c00000022000000000000000000000000000000')
예제 #17
0
    def test_compact_balance_encode_decode(self):
        scale_data = ScaleBytes('0x070010a5d4e8')
        value = 1000000000000

        obj = RuntimeConfiguration().create_scale_object('Compact<Balance>')
        data = obj.encode(value)

        self.assertEqual(str(scale_data), str(data))

        obj_check = RuntimeConfiguration().create_scale_object('Compact<Balance>', data)

        self.assertEqual(obj_check.decode(), value)
예제 #18
0
    def process(self):

        result = {}
        for key, data_type in self.type_mapping:
            result[key] = self.process_type(data_type,
                                            metadata=self.metadata).value

        # Replace HexBytes with actual proposal
        result['proposal'] = Proposal(ScaleBytes(result['proposal']),
                                      metadata=self.metadata).decode()

        return result
예제 #19
0
    def test_metadata_registry_decode_v14(self):
        metadata_obj = self.runtime_config.create_scale_object(
            "MetadataVersioned", data=ScaleBytes(self.metadata_fixture_dict['V14'])
        )
        metadata_obj.decode()
        self.assertEqual(metadata_obj.value_object[1].index, 14)
        self.assertIsNotNone(metadata_obj.portable_registry)

        self.assertGreater(len(metadata_obj[1][1]['pallets']), 0)
        self.assertGreater(len(metadata_obj.value[1]['V14']['pallets']), 0)

        self.assertGreater(len(metadata_obj.get_signed_extensions().items()), 0)
예제 #20
0
class LogDigest(Enum):
    value_list = [
        'Other', 'AuthoritiesChange', 'ChangesTrieRoot', 'Seal', 'Consensus',
        'SealV0', 'PreRuntime'
    ]

    # value_list = ['System', 'Consensus', 'Sharding', 'Crfg']

    def __init__(self, data, **kwargs):
        self.log_type = None
        self.index_value = None
        super().__init__(data, **kwargs)

    def process(self):
        self.index = int(self.get_next_bytes(1).hex())
        self.index_value = self.value_list[self.index]

        if self.data.__str__()[0:10] == '0x00180200':
            self.data = ScaleBytes('0x' + self.data.__str__()[10:18])
            self.log_type = self.process_type('ShardInfoLog')
            return {
                'type': self.log_type.type_string,
                'value': self.log_type.value
            }

        if self.data.__str__()[0:10] == '0x00280400':
            self.data = ScaleBytes('0x' + self.data.__str__()[10:26])
            self.log_type = self.process_type('U64')
            return {'type': 'Finalitytracker', 'value': self.log_type.value}

        if self.data.__str__()[0:12] == '0x00ed030300':
            self.data = ScaleBytes('0x' + self.data.__str__()[28:])
            self.log_type = self.process_type('Vec<(SessionKey, u64)>')
            return {'type': 'Crfg', 'value': self.log_type.value}

        self.log_type = self.process_type(self.value_list[self.index])
        return {
            'type': self.log_type.type_string,
            'value': self.log_type.value
        }
예제 #21
0
    def process(self):
        self.index = int(self.get_next_bytes(1).hex())
        self.index_value = self.value_list[self.index]

        if self.data.__str__()[0:10] == '0x00180200':
            self.data = ScaleBytes('0x' + self.data.__str__()[10:18])
            self.log_type = self.process_type('ShardInfoLog')
            return {
                'type': self.log_type.type_string,
                'value': self.log_type.value
            }

        if self.data.__str__()[0:10] == '0x00280400':
            self.data = ScaleBytes('0x' + self.data.__str__()[10:26])
            self.log_type = self.process_type('U64')
            return {'type': 'Finalitytracker', 'value': self.log_type.value}

        if self.data.__str__()[0:12] == '0x00ed030300':
            self.data = ScaleBytes('0x' + self.data.__str__()[28:])
            self.log_type = self.process_type('Vec<(SessionKey, u64)>')
            return {'type': 'Crfg', 'value': self.log_type.value}

        self.log_type = self.process_type(self.value_list[self.index])
        return {
            'type': self.log_type.type_string,
            'value': self.log_type.value
        }
예제 #22
0
    def test_struct_encode_decode(self):

        value = {'unstake_threshold': 3, 'validator_payment': 0}
        scale_data = ScaleBytes("0x0c00")

        obj = RuntimeConfiguration().create_scale_object('ValidatorPrefsTo145')
        data = obj.encode(value)

        self.assertEqual(str(scale_data), str(data))

        obj_check = RuntimeConfiguration().create_scale_object('ValidatorPrefsTo145', data)

        self.assertEqual(obj_check.decode(), value)
예제 #23
0
    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'))
        cls.runtime_config = RuntimeConfigurationObject(
            implements_scale_info=True)
        cls.runtime_config.update_type_registry(
            load_type_registry_preset("metadata_types"))

        cls.metadata_obj = cls.runtime_config.create_scale_object(
            'MetadataVersioned',
            data=ScaleBytes(cls.metadata_fixture_dict['V14']))
        cls.metadata_obj.decode()
    def test_struct_encode_decode(self):

        value = {'unstakeThreshold': 3, 'validatorPayment': 0}
        scale_data = ScaleBytes("0x0c00")

        obj = ScaleDecoder.get_decoder_class('ValidatorPrefsLegacy')
        data = obj.encode(value)

        self.assertEqual(str(scale_data), str(data))

        obj_check = ScaleDecoder.get_decoder_class('ValidatorPrefsLegacy', data)

        self.assertEqual(obj_check.decode(), value)
예제 #25
0
    def test_named_struct(self):
        # scale_info::111 = ['frame_support', 'weights', 'RuntimeDbWeight']
        obj = self.runtime_config.create_scale_object(
            'scale_info::111',
            ScaleBytes("0xe110000000000000d204000000000000"))
        obj.decode()

        self.assertEqual(obj.value, {'read': 4321, 'write': 1234})

        obj.encode({'read': 4321, 'write': 1234})

        self.assertEqual(obj.data.to_hex(),
                         '0xe110000000000000d204000000000000')
예제 #26
0
    def process_encode(self, value):

        value = int(value)

        if value <= 0b00111111:
            return ScaleBytes(bytearray(int(value << 2).to_bytes(1, 'little')))

        elif value <= 0b0011111111111111:
            return ScaleBytes(bytearray(int((value << 2) | 0b01).to_bytes(2, 'little')))

        elif value <= 0b00111111111111111111111111111111:

            return ScaleBytes(bytearray(int((value << 2) | 0b10).to_bytes(4, 'little')))

        else:
            for bytes_length in range(4, 68):
                if 2 ** (8 * (bytes_length - 1)) <= value < 2 ** (8 * bytes_length):
                    return ScaleBytes(bytearray(
                        ((bytes_length - 4) << 2 | 0b11).to_bytes(1, 'little') + value.to_bytes(bytes_length,
                                                                                                'little')))
            else:
                raise ValueError('{} out of range'.format(value))
예제 #27
0
    def test_enum_with_specified_index_number(self):
        RuntimeConfiguration().update_type_registry(
            load_type_registry_preset("test"))

        obj = RuntimeConfiguration().create_scale_object('EnumSpecifiedIndex')

        data = obj.encode("KSM")
        self.assertEqual("0x82", data.to_hex())

        obj = RuntimeConfiguration().create_scale_object(
            'EnumSpecifiedIndex', data=ScaleBytes("0x80"))

        self.assertEqual("KAR", obj.decode())
예제 #28
0
def ss58_decode_account_index(address, valid_address_type=None):

    account_index_bytes = ss58_decode(address, valid_address_type)

    if len(account_index_bytes) == 2:
        return ScaleDecoder.get_decoder_class(
            'u8',
            data=ScaleBytes('0x{}'.format(account_index_bytes))).decode()
    if len(account_index_bytes) == 4:
        return ScaleDecoder.get_decoder_class(
            'u16',
            data=ScaleBytes('0x{}'.format(account_index_bytes))).decode()
    if len(account_index_bytes) == 8:
        return ScaleDecoder.get_decoder_class(
            'u32',
            data=ScaleBytes('0x{}'.format(account_index_bytes))).decode()
    if len(account_index_bytes) == 16:
        return ScaleDecoder.get_decoder_class(
            'u64',
            data=ScaleBytes('0x{}'.format(account_index_bytes))).decode()
    else:
        raise ValueError("Invalid account index length")
예제 #29
0
    def test_bounded_vec(self):
        # 'scale_info::90' = frame_support::storage::bounded_vec::BoundedVec
        obj = self.runtime_config.create_scale_object('scale_info::90',
                                                      ScaleBytes("0x084345"))

        obj.decode()

        self.assertEqual('CE', obj.value)

        data = obj.encode([67, 69])
        self.assertEqual('0x084345', data.to_hex())

        data = obj.encode('CE')
        self.assertEqual('0x084345', data.to_hex())
예제 #30
0
    def generate_hash(self):
        if self.contains_transaction:

            if self.extrinsic_length:
                extrinsic_data = self.data.data
            else:
                # Fallback for legacy version, prefix additional Compact<u32> with length
                extrinsic_length_type = CompactU32(ScaleBytes(bytearray()))
                extrinsic_length_type.encode(self.data.length)
                extrinsic_data = extrinsic_length_type.data.data + self.data.data

            return blake2b(extrinsic_data, digest_size=32).digest().hex()
        else:
            return None