def test_from_string_wrong_length(self): with self.assertRaises(ValueError) as ctx: UInt160.from_string("1122") self.assertEqual("Invalid UInt160 Format: 4 chars != 40 chars", str(ctx.exception)) with self.assertRaises(ValueError) as ctx: UInt256.from_string("1122") self.assertEqual("Invalid UInt256 Format: 4 chars != 64 chars", str(ctx.exception))
def _internal_transaction_get(self, hash: types.UInt256): tx_bytes = self._real_db.get(DBPrefixes.TRANSACTIONS + hash.to_array()) if tx_bytes is None: # this is a must if not found! raise KeyError with serialization.BinaryReader(tx_bytes) as br: tx = payloads.Transaction._serializable_init() tx.deserialize_special(br) return tx
def test_from_string_various(self): uint160 = UInt160.from_string("11" * 20) expected_data_uint160 = bytearray([0x11] * 20) self.assertEqual(expected_data_uint160, uint160.to_array()) uint256 = UInt256.from_string("11" * 32) expected_data_uint256 = bytearray([0x11] * 32) self.assertEqual(expected_data_uint256, uint256.to_array()) uint160_from_bytes = UInt160.deserialize_from_bytes( expected_data_uint160) self.assertEqual(expected_data_uint160, uint160_from_bytes.to_array()) uint256_from_bytes = UInt256.deserialize_from_bytes( expected_data_uint256) self.assertEqual(expected_data_uint256, uint256_from_bytes.to_array()) # test deserialize with too much data data_uint160 = bytearray(21 * [0x11]) uint160_from_bytes = UInt160.deserialize_from_bytes(data_uint160) self.assertEqual(data_uint160[:20], uint160_from_bytes.to_array()) data_uint256 = bytearray(33 * [0x11]) uint256_from_bytes = UInt256.deserialize_from_bytes(data_uint256) self.assertEqual(expected_data_uint256[:32], uint256_from_bytes.to_array()) # test deserialize with too little data data_uint160 = bytearray(19 * [0x11]) data_uint256 = bytearray(31 * [0x11]) with self.assertRaises(ValueError) as ctx: UInt160.deserialize_from_bytes(data_uint160) self.assertEqual( "Insufficient data 19 bytes is less than the required 20", str(ctx.exception)) with self.assertRaises(ValueError) as ctx: UInt256.deserialize_from_bytes(data_uint256) self.assertEqual( "Insufficient data 31 bytes is less than the required 32", str(ctx.exception))
def test_serialize_to_stream(self): data_uint160 = bytearray(20 * [0x11]) data_uint256 = bytearray(32 * [0x11]) uint160 = UInt160(data_uint160) uint256 = UInt256(data_uint256) with serialization.BinaryWriter() as bw: bw.write_serializable(uint160) self.assertEqual(data_uint160, bw._stream.getvalue()) with serialization.BinaryWriter() as bw: bw.write_serializable(uint256) self.assertEqual(data_uint256, bw._stream.getvalue())
def test_deserialize_from_stream(self): data_uint160 = bytearray(20 * [0x11]) data_uint256 = bytearray(32 * [0x11]) with serialization.BinaryReader(data_uint160) as br: # we explicitly call deserialize, instead of br.read_uint160() for coverage uint160 = UInt160.zero() uint160.deserialize(br) self.assertEqual(data_uint160, uint160._data) with serialization.BinaryReader(data_uint256) as br: uint256 = UInt256.zero() uint256.deserialize(br) self.assertEqual(data_uint256, uint256._data)
def parse_single_item(item: Union[Dict, List]): if 'iterator' in item: item = item['iterator'] if item: if type(item[0]['value']) is not list: return [parse_single_item(i) for i in item] else: return { parse_single_item(i['value'][0]): parse_single_item(i['value'][1]) for i in item } _type = item['type'] if _type == 'Any' and 'value' not in item: return None else: value = item['value'] if _type == 'Integer': return int(value) elif _type == 'Boolean': return value elif _type == 'ByteString' or _type == 'Buffer': byte_value = base64.b64decode(value) try: return byte_value.decode() except UnicodeDecodeError: try: len_bytes = len(byte_value) if len_bytes == 20: return Hash160Str.from_UInt160(UInt160(byte_value)) if len_bytes == 32: return Hash256Str.from_UInt256(UInt256(byte_value)) except Exception: pass # may be an N3 address starting with 'N' # TODO: decode to N3 address return byte_value elif _type == 'Array': return [parse_single_item(i) for i in value] elif _type == 'Struct': return tuple([parse_single_item(i) for i in value]) elif _type == 'Map': return { parse_single_item(i['key']): parse_single_item(i['value']) for i in value } elif _type == 'Pointer': return int(value) else: raise ValueError(f'Unknown type {_type}')
def _internal_block_delete(self, hash: types.UInt256, batch=None): if batch: db = batch else: db = self._real_db block_hash_bytes = hash.to_array() block_bytes = self._real_db.get(DBPrefixes.BLOCKS + block_hash_bytes) if block_bytes is not None: # Instead of full block deserialization, which includes merkletree calculation and such, we manually extract # the 4 bytes block.index from the stream. start_idx = 4 + 32 + 32 + 8 block_height_bytes = block_bytes[start_idx:start_idx + 4] db.delete(DBPrefixes.BLOCKS + block_hash_bytes) db.delete(DBPrefixes.BLOCKS_HEIGHT_MAP + block_height_bytes)
def _internal_transaction_delete(self, hash: types.UInt256, batch=None): if batch: db = batch else: db = self._real_db db.delete(DBPrefixes.TRANSACTIONS + hash.to_array())
def _internal_block_get(self, hash: types.UInt256): block_bytes = self._real_db.get(DBPrefixes.BLOCKS + hash.to_array()) if block_bytes is None: raise KeyError return payloads.Block.deserialize_from_bytes(block_bytes)
def test_zero(self): uint160 = UInt160.zero() self.assertEqual(20, len(uint160.to_array())) uint256 = UInt256.zero() self.assertEqual(32, len(uint256.to_array()))