def test_serialize_first_segment(self): segment = TxSegment("1000", "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc", tx_hash="123abc", testnet=False, segment_count=1, sequence_num=0) json_ser = segment.serialize_to_json() assert json_ser == '{"i": "1000", "t": "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc", "s": 1, "h": "123abc", ' \ '"n": "m"}'
def to_segments(tx: bytes, payload_id: str, is_gotenna: bool = True, use_z85: bool = True, is_testnet: bool = False): def get_segment_lengths(): if is_gotenna: segment_0_length = GOTENNA_SEGMENT_0_LEN segment_m_length = GOTENNA_SEGMENT_1_LEN else: segment_0_length = SMS_SEGMENT_0_LEN segment_m_length = SMS_SEGMENT_1_LEN if use_z85: segment_0_length += 24 return (segment_0_length, segment_m_length) def get_tx_raw_data(): if use_z85: tx_encoded = encode(tx) hash = encode(bytes.fromhex(hash256(tx).hex())) else: tx_encoded = tx.hex() hash = hash256(tx).hex() return tx_encoded, hash segment_0_length, segment_m_length = get_segment_lengths() tx_raw, tx_hash = get_tx_raw_data() segments = [] raw_tx_length = len(tx_raw) segment_count = 1 if raw_tx_length > segment_0_length: raw_tx_length -= segment_0_length quotient, remainder = divmod(raw_tx_length, segment_m_length) segment_count += quotient + int(remainder > 0) else: segment_0_length = raw_tx_length for i in range(0, segment_count): if i == 0: tx_data = tx_raw[0:segment_0_length] seg_0 = TxSegment(payload_id, tx_data, 0, tx_hash=tx_hash, testnet=is_testnet, segment_count=segment_count) segments.append(seg_0) else: tx_raw_index = segment_0_length + (i - 1) * segment_m_length if i < segment_count - 1: tx_data = tx_raw[tx_raw_index:tx_raw_index + segment_m_length] else: tx_data = tx_raw[tx_raw_index:] seg = TxSegment(payload_id, tx_data, i) segments.append(seg) return segments
def hex_gotenna_segments(self): payload_segment_0 = TxSegment("1000", "010000000104f98a8dcd4ebc881603fe81e85b46f2e55dce862bf6a8489f46be56956997fb010000006b4830450221008b5d", tx_hash="350f6de5d2b86c4f1618c6dfe06e86541094f39b6db4e11b9869aece24a89883", sequence_num=0, segment_count=3) payload_segment_1 = TxSegment("1000", "109df78db7e9be30ddf59cf6b37826f495c35ec800f531f394db2ef036d8022021c0a0db1bae17a406f7f10017bfdc9c816febb60b8e5e3697ef3c7d57c87156012102c31ca8111f8adaf3cff9facd1ca30fba8e0acebebc7b51", sequence_num=1) payload_segment_2 = TxSegment("1000", "ad484ca615eaef6da1feffffff0240420f00000000001976a914e5bbd998864b9cf9ae76e5c0c779d9cc06e5457088ac8fa5a200000000001976a91441e85563ae76eccb3f2955906523b63c6394209a88ac00000000", sequence_num=2) return [payload_segment_0, payload_segment_1, payload_segment_2]
def z85_gotenna_segments(self): # 010000000104f98a8dcd4ebc881603fe81e85b46f2e55dce862bf6a8489f46be56956997fb010000006b4830450221008b5d109df78db7e9be30ddf59cf6b37826f495c35ec800f531f394db2ef036d8022021c0a0db1bae17a406f7f10017bfdc9c816febb60b8e5e3697ef3c7d57c87156012102c31ca8111f8adaf3cff9facd1ca30fba8e0acebebc7b51ad484ca615eaef6da1feffffff0240420f00000000001976a914e5bbd998864b9cf9ae76e5c0c779d9cc06e5457088ac8fa5a200000000001976a91441e85563ae76eccb3f2955906523b63c6394209a88ac00000000 # 0rr910r&jQJM>khH.Z9(F-{rc]5Tf5Haz$@ns@w=r*vx=}VcV%0bCaVmfjRjI^l)+{L(VDZa!yoOC6plcIiOvuDrctg4QT:f7p^K0W5V4PXyA*7O?of[C<xu*)&}l(:vgYun!esjBHqLAAi8-0(D1R5G=[:]uWme+]AF?X@EcyZpX!&TW(c.73+m8Q5L8(@@LCL4/=Of000)WStaEa/{EH!OCxsh<?O]Z/#%VZmr16:KenMJ000008fR$[lfIrUU6ffPkpGP]wH1SCw0wa8H]ZNR000 # 350f6de5d2b86c4f1618c6dfe06e86541094f39b6db4e11b9869aece24a89883 # h4KM=^ZT9?78U6G&bjoG5r#^Qzm5mvM$-.Gb=E8. payload_segment_0 = TxSegment("30", "0rr910r&jQJM>khH.Z9(F-{rc]5Tf5Haz$@ns@w=r*vx=}VcV%0bCaVmfjRjI^l)+{L(VDZa!yoOC6plcIiOvuDrctg4QT:f7p^K0W5V4PXyA*7O?of[C<xu*)&}", tx_hash="h4KM=^ZT9?78U6G&bjoG5r#^Qzm5mvM$-.Gb=E8.", sequence_num=0, segment_count=2, testnet=True) payload_segment_1 = TxSegment("30", "l(:vgYun!esjBHqLAAi8-0(D1R5G=[:]uWme+]AF?X@EcyZpX!&TW(c.73+m8Q5L8(@@LCL4/=Of000)WStaEa/{EH!OCxsh<?O]Z/#%VZmr16:KenMJ000008fR$[lfIrUU6ffPkpGP]wH1SCw0wa8H]ZNR000", sequence_num=1) return [payload_segment_0, payload_segment_1]
def test_repr(self): segment = TxSegment("1000", "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc", tx_hash="123abc", testnet=False, segment_count=1, sequence_num=0) segment_repr = repr(segment) assert segment_repr == '{"i": "1000", "t": "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc", "s": 1, "h": "123abc", ' \ '"n": "m"}'
def test_constructor_defaults(self): segment = TxSegment("1000", "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc") assert segment.tx_hash is None assert segment.payload_id == "1000" assert segment.tx_data == "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc" assert segment.sequence_num == 0 assert not segment.testnet assert segment.segment_count is None
def test_deserialize_non_first_from_json(self): json_ser = '{"i": "1000", "t": "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc", "c": 1}' segment = TxSegment.deserialize_from_json(json_ser) assert segment.payload_id == "1000" assert segment.sequence_num == 1 assert segment.segment_count is None assert segment.testnet is False assert segment.tx_data == "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc"
def test_from_segments_hash_mismatch(self, hex_gotenna_segments): payload_segment_0 = TxSegment("1000", "010000000104f98a8dcd4ebc881603fe81e85b46f2e55dce862bf6a8489f46be56956997fb010000006b4830450221008b5d", tx_hash="450f6de5d2b86c4f1618c6dfe06e86541094f39b6db4e11b9869aece24a89883", sequence_num=0, segment_count=3) bad_hash_segments = hex_gotenna_segments[1:] bad_hash_segments.insert(0, payload_segment_0) with pytest.raises(ValueError) as err: PayloadFactory.from_segments(bad_hash_segments) assert err.value.args[0] == "Transaction payload does not validate against transaction hash"
def test_segment_json_is_invalid_non_zero_sequence_with_segment_count(self): json_ser = '{"i": "1000", "t": "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc", "c": 1, "s": 2}' json_obj = json.loads(json_ser) assert not TxSegment.segment_json_is_valid(json_obj)
def test_segment_json_first_is_valid_explicit_zero_sequence(self): json_ser = '{"i": "1000", "t": "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc", "s": 1, "h": "123abc", "c": 0}' json_obj = json.loads(json_ser) assert TxSegment.segment_json_is_valid(json_obj)
def test_deserialize_invalid_segment_raises_exception(self): json_ser = '{"i": "1000", "t": "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc", "s": 1, "h": "123abc", "c": 1}' with pytest.raises(AttributeError): TxSegment.deserialize_from_json(json_ser)
def test_serialize_mainnet_segment_without_explicit_flag(self): segment = TxSegment("1000", "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc", tx_hash="123abc", segment_count=2, sequence_num=1) json_ser = segment.serialize_to_json() assert json_ser == '{"i": "1000", "t": "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc", "c": 1, "n": "m"}'
def test_serialize_testnet_segment(self): segment = TxSegment("1000", "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc", tx_hash="123abc", testnet=True, segment_count=2, sequence_num=1) json_ser = segment.serialize_to_json() assert json_ser == '{"i": "1000", "t": "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc", "c": 1, "n": "t"}'
def test_str(self): segment = TxSegment("1000", "w]8f<vRG}fayY4]vRG}fayYm#vRG}fayYnc", tx_hash="123abc", testnet=False, segment_count=1, sequence_num=0) segment_str = str(segment) assert segment_str == "Tx 123abc Part 0"
def from_json(json_segments): return PayloadFactory.from_segments([TxSegment.deserialize_from_json(json_segment) for json_segment in json_segments])