def validate_search(self, input): if not Tag(input.data): if not Hash(input.data): if not Address(input.data): raise ValidationError('Please enter an address, transaction hash, bundle or tag.') else: input.data = Address(input.data) else: input.data = Hash(input.data) else: input.data = Tag(input.data)
def __init__(self, address, value, tag=None, message=None, timestamp=None): # type: (Address, int, Optional[Tag], Optional[TryteString], Optional[int]) -> None if not timestamp: timestamp = get_current_timestamp() super(ProposedTransaction, self).__init__( address=address, tag=Tag(b'') if tag is None else tag, timestamp=timestamp, value=value, # These values will be populated when the bundle is finalized. bundle_hash=None, current_index=None, hash_=None, last_index=None, signature_message_fragment=None, # These values start out empty; they will be populated when the # node does PoW. branch_transaction_hash=TransactionHash(b''), nonce=Hash(b''), trunk_transaction_hash=TransactionHash(b''), ) self.message = TryteString(b'') if message is None else message
def from_tryte_string(cls, trytes): # type: (TrytesCompatible) -> Transaction """ Creates a Transaction object from a sequence of trytes. """ tryte_string = TransactionTrytes(trytes) hash_ = [0] * HASH_LENGTH # type: MutableSequence[int] sponge = Curl() sponge.absorb(tryte_string.as_trits()) sponge.squeeze(hash_) return cls( hash_=TransactionHash.from_trits(hash_), signature_message_fragment=Fragment(tryte_string[0:2187]), address=Address(tryte_string[2187:2268]), value=int_from_trits(tryte_string[2268:2295].as_trits()), tag=Tag(tryte_string[2295:2322]), timestamp=int_from_trits(tryte_string[2322:2331].as_trits()), current_index=int_from_trits(tryte_string[2331:2340].as_trits()), last_index=int_from_trits(tryte_string[2340:2349].as_trits()), bundle_hash=BundleHash(tryte_string[2349:2430]), trunk_transaction_hash=TransactionHash(tryte_string[2430:2511]), branch_transaction_hash=TransactionHash(tryte_string[2511:2592]), nonce=Hash(tryte_string[2592:2673]), )
def gtta(node_url): command = { "command": "getTransactionsToApprove", "depth": DEPTH } url = node_url data = command headers = {'Content-type': 'application/json', 'X-IOTA-API-Version': '1'} r = requests.post(url, data=str(data), headers=headers) if r.status_code == 200: obj_nonce = json.loads(r.text) return obj_nonce['trunkTransaction'], obj_nonce['branchTransaction'] else: return Hash(''), Hash('')
def finalize(self): # type: () -> None """ Finalizes the bundle, preparing it to be attached to the Tangle. """ if self.hash: raise RuntimeError('Bundle is already finalized.') if not self: raise ValueError('Bundle has no transactions.') # Quick validation. balance = self.balance if balance < 0: if self.change_address: self.add_transaction(ProposedTransaction( address = self.change_address, value = -balance, tag = self.tag, )) else: raise ValueError( 'Bundle has unspent inputs (balance: {balance}); ' 'use ``send_unspent_inputs_to`` to create ' 'change transaction.'.format( balance = balance, ), ) elif balance > 0: raise ValueError( 'Inputs are insufficient to cover bundle spend ' '(balance: {balance}).'.format( balance = balance, ), ) # Generate bundle hash. sponge = Curl() last_index = len(self) - 1 for (i, txn) in enumerate(self): # type: Tuple[int, ProposedTransaction] txn.current_index = i txn.last_index = last_index sponge.absorb(txn.get_signature_validation_trytes().as_trits()) bundle_hash = [0] * HASH_LENGTH # type: MutableSequence[int] sponge.squeeze(bundle_hash) self.hash = Hash.from_trits(bundle_hash) # Copy bundle hash to individual transactions. for txn in self: txn.bundle_hash = self.hash # Initialize signature/message fragment. txn.signature_message_fragment = Fragment(txn.message or b'')
def get_hash_for(self, trytes): curl = crypto.pycurl.Curl() # curl = crypto.Curl() trits = trytes.as_trits() self.pearldiver.search(trits, self.MIN_WEIGHT_MAGNITUDE, self.NUM_CORES) curl.absorb(trits) curl.squeeze(self.hash_trits) curl.reset() return Hash.from_trits(self.hash_trits)
def from_tryte_string_and_hash(cls, trytes,hash): # type: (TrytesCompatible) -> Transaction """ Creates a Transaction object from a sequence of trytes. """ tryte_string = TransactionTrytes(trytes) hash_ = hash return cls( hash_=TransactionHash(hash_), signature_message_fragment=Fragment(tryte_string[0:2187]), address=Address(tryte_string[2187:2268]), value=int_from_trits(tryte_string[2268:2295].as_trits()), tag=Tag(tryte_string[2295:2322]), timestamp=int_from_trits(tryte_string[2322:2331].as_trits()), current_index=int_from_trits(tryte_string[2331:2340].as_trits()), last_index=int_from_trits(tryte_string[2340:2349].as_trits()), bundle_hash=BundleHash(tryte_string[2349:2430]), trunk_transaction_hash=TransactionHash(tryte_string[2430:2511]), branch_transaction_hash=TransactionHash(tryte_string[2511:2592]), nonce=Hash(tryte_string[2592:2673]), )
def normalize(hash_: Hash) -> List[List[int]]: """ "Normalizes" a hash, converting it into a sequence of integers (not trits!) suitable for use in signature generation/validation. The hash is divided up into 3 parts, each of which is "balanced" (sum of all the values is equal to zero). """ normalized = [] source = hash_.as_integers() chunk_size = 27 for i in range(Hash.LEN // chunk_size): start = i * chunk_size stop = start + chunk_size chunk = source[start:stop] chunk_sum = sum(chunk) while chunk_sum > 0: chunk_sum -= 1 for j in range(chunk_size): if chunk[j] > -13: chunk[j] -= 1 break while chunk_sum < 0: chunk_sum += 1 for j in range(chunk_size): if chunk[j] < 13: chunk[j] += 1 break normalized.append(chunk) return normalized
def test_from_tryte_string(self): """ Initializing a Transaction object from a TryteString. References: - http://iotasupport.com/news/index.php/2016/12/02/fixing-the-latest-solid-subtangle-milestone-issue/ """ trytes =\ TransactionTrytes( b'GYPRVHBEZOOFXSHQBLCYW9ICTCISLHDBNMMVYD9JJHQMPQCTIQAQTJNNNJ9IDXLRCC' b'OYOXYPCLR9PBEY9ORZIEPPDNTI9CQWYZUOTAVBXPSBOFEQAPFLWXSWUIUSJMSJIIIZ' b'WIKIRH9GCOEVZFKNXEVCUCIIWZQCQEUVRZOCMEL9AMGXJNMLJCIA9UWGRPPHCEOPTS' b'VPKPPPCMQXYBHMSODTWUOABPKWFFFQJHCBVYXLHEWPD9YUDFTGNCYAKQKVEZYRBQRB' b'XIAUX9SVEDUKGMTWQIYXRGSWYRK9SRONVGTW9YGHSZRIXWGPCCUCDRMAXBPDFVHSRY' b'WHGB9DQSQFQKSNICGPIPTRZINYRXQAFSWSEWIFRMSBMGTNYPRWFSOIIWWT9IDSELM9' b'JUOOWFNCCSHUSMGNROBFJX9JQ9XT9PKEGQYQAWAFPRVRRVQPUQBHLSNTEFCDKBWRCD' b'X9EYOBB9KPMTLNNQLADBDLZPRVBCKVCYQEOLARJYAGTBFR9QLPKZBOYWZQOVKCVYRG' b'YI9ZEFIQRKYXLJBZJDBJDJVQZCGYQMROVHNDBLGNLQODPUXFNTADDVYNZJUVPGB9LV' b'PJIYLAPBOEHPMRWUIAJXVQOEM9ROEYUOTNLXVVQEYRQWDTQGDLEYFIYNDPRAIXOZEB' b'CS9P99AZTQQLKEILEVXMSHBIDHLXKUOMMNFKPYHONKEYDCHMUNTTNRYVMMEYHPGASP' b'ZXASKRUPWQSHDMU9VPS99ZZ9SJJYFUJFFMFORBYDILBXCAVJDPDFHTTTIYOVGLRDYR' b'TKHXJORJVYRPTDH9ZCPZ9ZADXZFRSFPIQKWLBRNTWJHXTOAUOL9FVGTUMMPYGYICJD' b'XMOESEVDJWLMCVTJLPIEKBE9JTHDQWV9MRMEWFLPWGJFLUXI9BXPSVWCMUWLZSEWHB' b'DZKXOLYNOZAPOYLQVZAQMOHGTTQEUAOVKVRRGAHNGPUEKHFVPVCOYSJAWHZU9DRROH' b'BETBAFTATVAUGOEGCAYUXACLSSHHVYDHMDGJP9AUCLWLNTFEVGQGHQXSKEMVOVSKQE' b'EWHWZUDTYOBGCURRZSJZLFVQQAAYQO9TRLFFN9HTDQXBSPPJYXMNGLLBHOMNVXNOWE' b'IDMJVCLLDFHBDONQJCJVLBLCSMDOUQCKKCQJMGTSTHBXPXAMLMSXRIPUBMBAWBFNLH' b'LUJTRJLDERLZFUBUSMF999XNHLEEXEENQJNOFFPNPQ9PQICHSATPLZVMVIWLRTKYPI' b'XNFGYWOJSQDAXGFHKZPFLPXQEHCYEAGTIWIJEZTAVLNUMAFWGGLXMBNUQTOFCNLJTC' b'DMWVVZGVBSEBCPFSM99FLOIDTCLUGPSEDLOKZUAEVBLWNMODGZBWOVQT9DPFOTSKRA' b'BQAVOQ9RXWBMAKFYNDCZOJGTCIDMQSQQSODKDXTPFLNOKSIZEOY9HFUTLQRXQMEPGO' b'XQGLLPNSXAUCYPGZMNWMQWSWCKAQYKXJTWINSGPPZG9HLDLEAWUWEVCTVRCBDFOXKU' b'ROXH9HXXAXVPEJFRSLOGRVGYZASTEBAQNXJJROCYRTDPYFUIQJVDHAKEG9YACV9HCP' b'JUEUKOYFNWDXCCJBIFQKYOXGRDHVTHEQUMHO999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999RKWEEVD99A99999999A99999999NFDPEEZCWVYLKZGSLCQNOFUSENI' b'XRHWWTZFBXMPSQHEDFWZULBZFEOMNLRNIDQKDNNIELAOXOVMYEI9PGTKORV9IKTJZQ' b'UBQAWTKBKZ9NEZHBFIMCLV9TTNJNQZUIJDFPTTCTKBJRHAITVSKUCUEMD9M9SQJ999' b'999TKORV9IKTJZQUBQAWTKBKZ9NEZHBFIMCLV9TTNJNQZUIJDFPTTCTKBJRHAITVSK' b'UCUEMD9M9SQJ999999999999999999999999999999999RKWEEVD99RKWEEVD99RKW' b'EEVD99999999999999999999999999999' ) transaction = Transaction.from_tryte_string(trytes) self.assertIsInstance(transaction, Transaction) self.assertEqual( transaction.hash, Hash( b'JBVVEWEPYNZ9KRHNUUTRENXXAVXT9MKAVPAUQ9SJ' b'NSIHDCPQM9LJHIZGXO9PIRWUUVBOXNCBE9XJGMOZF' ), ) self.assertEqual( transaction.signature_message_fragment, Fragment( b'GYPRVHBEZOOFXSHQBLCYW9ICTCISLHDBNMMVYD9JJHQMPQCTIQAQTJNNNJ9IDXLRCC' b'OYOXYPCLR9PBEY9ORZIEPPDNTI9CQWYZUOTAVBXPSBOFEQAPFLWXSWUIUSJMSJIIIZ' b'WIKIRH9GCOEVZFKNXEVCUCIIWZQCQEUVRZOCMEL9AMGXJNMLJCIA9UWGRPPHCEOPTS' b'VPKPPPCMQXYBHMSODTWUOABPKWFFFQJHCBVYXLHEWPD9YUDFTGNCYAKQKVEZYRBQRB' b'XIAUX9SVEDUKGMTWQIYXRGSWYRK9SRONVGTW9YGHSZRIXWGPCCUCDRMAXBPDFVHSRY' b'WHGB9DQSQFQKSNICGPIPTRZINYRXQAFSWSEWIFRMSBMGTNYPRWFSOIIWWT9IDSELM9' b'JUOOWFNCCSHUSMGNROBFJX9JQ9XT9PKEGQYQAWAFPRVRRVQPUQBHLSNTEFCDKBWRCD' b'X9EYOBB9KPMTLNNQLADBDLZPRVBCKVCYQEOLARJYAGTBFR9QLPKZBOYWZQOVKCVYRG' b'YI9ZEFIQRKYXLJBZJDBJDJVQZCGYQMROVHNDBLGNLQODPUXFNTADDVYNZJUVPGB9LV' b'PJIYLAPBOEHPMRWUIAJXVQOEM9ROEYUOTNLXVVQEYRQWDTQGDLEYFIYNDPRAIXOZEB' b'CS9P99AZTQQLKEILEVXMSHBIDHLXKUOMMNFKPYHONKEYDCHMUNTTNRYVMMEYHPGASP' b'ZXASKRUPWQSHDMU9VPS99ZZ9SJJYFUJFFMFORBYDILBXCAVJDPDFHTTTIYOVGLRDYR' b'TKHXJORJVYRPTDH9ZCPZ9ZADXZFRSFPIQKWLBRNTWJHXTOAUOL9FVGTUMMPYGYICJD' b'XMOESEVDJWLMCVTJLPIEKBE9JTHDQWV9MRMEWFLPWGJFLUXI9BXPSVWCMUWLZSEWHB' b'DZKXOLYNOZAPOYLQVZAQMOHGTTQEUAOVKVRRGAHNGPUEKHFVPVCOYSJAWHZU9DRROH' b'BETBAFTATVAUGOEGCAYUXACLSSHHVYDHMDGJP9AUCLWLNTFEVGQGHQXSKEMVOVSKQE' b'EWHWZUDTYOBGCURRZSJZLFVQQAAYQO9TRLFFN9HTDQXBSPPJYXMNGLLBHOMNVXNOWE' b'IDMJVCLLDFHBDONQJCJVLBLCSMDOUQCKKCQJMGTSTHBXPXAMLMSXRIPUBMBAWBFNLH' b'LUJTRJLDERLZFUBUSMF999XNHLEEXEENQJNOFFPNPQ9PQICHSATPLZVMVIWLRTKYPI' b'XNFGYWOJSQDAXGFHKZPFLPXQEHCYEAGTIWIJEZTAVLNUMAFWGGLXMBNUQTOFCNLJTC' b'DMWVVZGVBSEBCPFSM99FLOIDTCLUGPSEDLOKZUAEVBLWNMODGZBWOVQT9DPFOTSKRA' b'BQAVOQ9RXWBMAKFYNDCZOJGTCIDMQSQQSODKDXTPFLNOKSIZEOY9HFUTLQRXQMEPGO' b'XQGLLPNSXAUCYPGZMNWMQWSWCKAQYKXJTWINSGPPZG9HLDLEAWUWEVCTVRCBDFOXKU' b'ROXH9HXXAXVPEJFRSLOGRVGYZASTEBAQNXJJROCYRTDPYFUIQJVDHAKEG9YACV9HCP' b'JUEUKOYFNWDXCCJBIFQKYOXGRDHVTHEQUMHO999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999' ), ) self.assertEqual( transaction.address, Address( b'9999999999999999999999999999999999999999' b'99999999999999999999999999999999999999999' ), ) self.assertEqual(transaction.value, 0) self.assertEqual(transaction.legacy_tag, Tag(b'999999999999999999999999999')) self.assertEqual(transaction.timestamp, 1480690413) self.assertEqual(transaction.current_index, 1) self.assertEqual(transaction.last_index, 1) self.assertEqual( transaction.bundle_hash, BundleHash( b'NFDPEEZCWVYLKZGSLCQNOFUSENIXRHWWTZFBXMPS' b'QHEDFWZULBZFEOMNLRNIDQKDNNIELAOXOVMYEI9PG' ), ) self.assertEqual( transaction.trunk_transaction_hash, TransactionHash( b'TKORV9IKTJZQUBQAWTKBKZ9NEZHBFIMCLV9TTNJN' b'QZUIJDFPTTCTKBJRHAITVSKUCUEMD9M9SQJ999999' ), ) self.assertEqual( transaction.branch_transaction_hash, TransactionHash( b'TKORV9IKTJZQUBQAWTKBKZ9NEZHBFIMCLV9TTNJN' b'QZUIJDFPTTCTKBJRHAITVSKUCUEMD9M9SQJ999999' ), ) self.assertEqual(transaction.tag, Tag(b'999999999999999999999999999')) self.assertEqual(transaction.attachment_timestamp,1480690413) self.assertEqual(transaction.attachment_timestamp_lower_bound,1480690413) self.assertEqual(transaction.attachment_timestamp_upper_bound,1480690413) self.assertEqual( transaction.nonce, Nonce( b'999999999999999999999999999' ), )
def test_random(self): """ Generating a random Hash. """ rand = Hash.random() self.assertEqual(len(rand), Hash.LEN)
def setUp(self): super(BundleTestCase, self).setUp() # noinspection SpellCheckingInspection self.bundle = Bundle([ # This transaction does not have a message. Transaction( signature_message_fragment=Fragment(b''), address=Address(b'TESTVALUE9DONTUSEINPRODUCTION99999A9PG9A' b'XCQANAWGJBTFWEAEQCN9WBZB9BJAIIY9UDLIGFOAA'), current_index=0, last_index=7, value=0, # These values are not relevant to the tests. branch_transaction_hash=TransactionHash(b''), bundle_hash=BundleHash(b''), hash_=TransactionHash(b''), nonce=Hash(b''), tag=Tag(b''), timestamp=1485020456, trunk_transaction_hash=TransactionHash(b''), ), # This transaction has something that can't be decoded as a UTF-8 # sequence. Transaction( signature_message_fragment=Fragment( b'OHCFVELH9GYEMHCF9GPHBGIEWHZFU'), address=Address(b'TESTVALUE9DONTUSEINPRODUCTION99999HAA9UA' b'MHCGKEUGYFUBIARAXBFASGLCHCBEVGTBDCSAEBTBM'), current_index=1, last_index=7, value=10, # These values are not relevant to the tests. branch_transaction_hash=TransactionHash(b''), bundle_hash=BundleHash(b''), hash_=TransactionHash(b''), nonce=Hash(b''), tag=Tag(b''), timestamp=1485020456, trunk_transaction_hash=TransactionHash(b''), ), # This transaction has a message that fits into a single # fragment. Transaction( signature_message_fragment=Fragment.from_string( 'Hello, world!'), address=Address(b'TESTVALUE9DONTUSEINPRODUCTION99999D99HEA' b'M9XADCPFJDFANCIHR9OBDHTAGGE9TGCI9EO9ZCRBN'), current_index=2, last_index=7, value=20, # These values are not relevant to the tests. branch_transaction_hash=TransactionHash(b''), bundle_hash=BundleHash(b''), hash_=TransactionHash(b''), nonce=Hash(b''), tag=Tag(b''), timestamp=1485020456, trunk_transaction_hash=TransactionHash(b''), ), # This transaction has a message that spans multiple fragments. Transaction( signature_message_fragment=Fragment( b'J9GAQBCDCDSCEAADCDFDBDXCBDVCQAGAEAGDPCXCSCEANBTCTCDDEACCWCCDIDVC' b'WCHDEAPCHDEA9DPCGDHDSAJ9GAOBFDSASASAEAQBCDCDSCEAADCDFDBDXCBDVCQA' b'EAYBEANBTCTCDDEACCWCCDIDVCWCHDQAGAEAGDPCXCSCEAVBCDCDBDEDIDPCKD9D' b'EABDTCFDJDCDIDGD9DMDSAJ9EAEAGANBCDEAMDCDIDEAWCPCJDTCSASASAEATCFD' b'QAEAHDWCPCHDEAXCGDSASASAGAJ9GASASASAEAPCBDEAPCBDGDKDTCFDEAUCCDFD' b'EAMDCDIDIBGAEAXCBDHDTCFDFDIDDDHDTCSCEANBTCTCDDEACCWCCDIDVCWCHDEA' b'ADPCYCTCGDHDXCRCPC9D9DMDSAEAGAHCTCGDSAEASBEAWCPCJDTCSAGAJ9CCWCTC' b'EAHDKDCDEAADTCBDEAGDWCXCJDTCFDTCSCEAKDXCHDWCEATCLDDDTCRCHDPCBDRC' b'MDSAEACCWCTCXCFDEAKDPCXCHDXCBDVCEAWCPCSCEABDCDHDEAQCTCTCBDEAXCBD' b'EAJDPCXCBDSAJ9GACCWCTCFDTCEAFDTCPC9D9DMDEAXCGDEACDBDTCIBGAEAQCFD' b'TCPCHDWCTCSCEAZBWCCDIDRCWCVCSAJ9GACCWCTCFDTCEAFDTCPC9D9DMDEAXCGD' b'EACDBDTCQAGAEARCCDBDUCXCFDADTCSCEANBTCTCDDEACCWCCDIDVCWCHDSAJ9GA' b'CCCDEAOBJDTCFDMDHDWCXCBDVCIBEACCCDEAHDWCTCEAVCFDTCPCHDEA9CIDTCGD' b'HDXCCDBDEACDUCEAVBXCUCTCQAEAHDWCTCEADCBDXCJDTCFDGDTCEAPCBDSCEAOB' b'JDTCFDMDHDWCXCBDVCIBGAJ9GAHCTCGDSAGAJ9LBCDHDWCEACDUCEAHDWCTCEAAD' b'TCBDEAWCPCSCEAQCTCTCBDEAHDFDPCXCBDTCSCEAUCCDFDEAHDWCXCGDEAADCDAD' b'TCBDHDEBEAHDWCTCXCFDEA9DXCJDTCGDEAWCPCSCEAQCTCTCBDEAPCJ9EAEADDFD' b'TCDDPCFDPCHDXCCDBDEAUCCDFDEAXCHDEBEAHDWCTCMDEAWCPCSCEAQCTCTCBDEA' b'GDTC9DTCRCHDTCSCEAPCHDEAQCXCFDHDWCEAPCGDEAHDWCCDGDTCEAKDWCCDEAKD' b'CDID9DSCJ9EAEAKDXCHDBDTCGDGDEAHDWCTCEAPCBDGDKDTCFDEBEAQCIDHDEATC' b'JDTCBDEAGDCDEAHDWCTCMDEAUCCDIDBDSCEAHDWCTCADGDTC9DJDTCGDEAVCPCGD' b'DDXCBDVCEAPCBDSCEAGDEDIDXCFDADXCBDVCJ9EAEA9DXCZCTCEATCLDRCXCHDTC' b'SCEARCWCXC9DSCFDTCBDSAJ9GAKBBDSCEAMDCDIDLAFDTCEAFDTCPCSCMDEAHDCD' b'EAVCXCJDTCEAXCHDEAHDCDEAIDGDIBGAEAIDFDVCTCSCEAVBCDCDBDEDIDPCKD9D' b'SAJ9GASBEAPCADSAGAJ9GAXBCDKDIBGAJ9GAXBCDKDQAGAEAGDPCXCSCEANBTCTC' b'DDEACCWCCDIDVCWCHDSAJ9CCWCTCMDEAQCCDHDWCEA9DXCRCZCTCSCEAHDWCTCXC' b'FDEASCFDMDEA9DXCDDGDSAJ9GACCWCCDIDVCWCEASBEASCCDBDLAHDEAHDWCXCBD' b'ZCQAGAEAPCSCSCTCSCEANBTCTCDDEACCWCCDIDVCWCHDQAEAGAHDWCPCHDEAMDCD' b'IDLAFDTCEAVCCDXCBDVCEAHDCDEA9DXCZCTCEAXCHDSAGAJ9GANBCDTCGDBDLAHD' b'EAADPCHDHDTCFDQAGAEAGDPCXCSCEAZBWCCDIDRCWCVCSAEAGAFCTCEAADIDGDHD' b'EAZCBDCDKDEAXCHDFAEAXBCDKDFAGAJ9GAXBCDKDIBGAEATCBDEDIDXCFDTCSCEA' b'NBTCTCDDEACCWCCDIDVCWCHDSAJ9GAHCTCGDFAEAXBCDKDFAGAJ9GAKB9D9DEAFD' b'XCVCWCHDQAGAEAGDPCXCSCEAHDWCTCEARCCDADDDIDHDTCFDEAPCBDSCEAGDTCHD' b'HD9DTCSCEAXCBDHDCDEAGDXC9DTCBDRCTCEAPCVCPCXCBDSAJ9EAEACCWCTCEAHD' b'KDCDEAADTCB'), address=Address(b'TESTVALUE9DONTUSEINPRODUCTION99999A9PG9A' b'XCQANAWGJBTFWEAEQCN9WBZB9BJAIIY9UDLIGFOAA'), current_index=3, last_index=7, value=30, # These values are not relevant to the tests. branch_transaction_hash=TransactionHash(b''), bundle_hash=BundleHash(b''), hash_=TransactionHash(b''), nonce=Hash(b''), tag=Tag(b''), timestamp=1485020456, trunk_transaction_hash=TransactionHash(b''), ), Transaction( signature_message_fragment=Fragment( b'DEAUCXCSCVCTCHDTCSCSAEACCWCTCEAHDTCBDGDXCCDBDEAKDPCGDEAIDBDQCTCP' b'CFDPCQC9DTCSAJ9GAHCCDIDLAFDTCEAFDTCPC9D9DMDEABDCDHDEAVCCDXCBDVCE' b'AHDCDEA9DXCZCTCEAXCHDQAGAEACDQCGDTCFDJDTCSCEANBTCTCDDEACCWCCDIDV' b'CWCHDSAJ9GACCTC9D9DEAIDGDFAGAJ9GAKB9D9DEAFDXCVCWCHDQAGAEAGDPCXCS' b'CEANBTCTCDDEACCWCCDIDVCWCHDSAEAGACCWCTCEAKBBDGDKDTCFDEAHDCDEAHDW' b'CTCEAQBFDTCPCHDEA9CIDTCGDHDXCCDBDSASASAGAJ9GAHCTCGDIBGAJ9GAYBUCE' b'AVBXCUCTCQAEAHDWCTCEADCBDXCJDTCFDGDTCEAPCBDSCEAOBJDTCFDMDHDWCXCB' b'DVCSASASAGAEAGDPCXCSCEANBTCTCDDEACCWCCDIDVCWCHDSAJ9GAHCTCGDIBIBG' b'AJ9GASBGDSASASAGAJ9GAHCTCGDIBFAGAJ9GAPBCDFDHDMDRAHDKDCDQAGAEAGDP' b'CXCSCEANBTCTCDDEACCWCCDIDVCWCHDQAEAKDXCHDWCEAXCBDUCXCBDXCHDTCEAA' b'DPCYCTCGDHDMDEAPCBDSCEARCPC9DADSAJ9EAEAEAEAEAEAEAEA'), address=Address(b'TESTVALUE9DONTUSEINPRODUCTION99999A9PG9A' b'XCQANAWGJBTFWEAEQCN9WBZB9BJAIIY9UDLIGFOAA'), current_index=4, last_index=7, value=0, # These values are not relevant to the tests. branch_transaction_hash=TransactionHash(b''), bundle_hash=BundleHash(b''), hash_=TransactionHash(b''), nonce=Hash(b''), tag=Tag(b''), timestamp=1485020456, trunk_transaction_hash=TransactionHash(b''), ), # Input, Part 1 of 2 Transaction( # Make the signature look like a message, so we can verify that # the Bundle skips it correctly. signature_message_fragment=Fragment.from_string( 'This is a signature, not a message!'), address=Address(b'TESTVALUE9DONTUSEINPRODUCTION99999WGSBUA' b'HDVHYHOBHGP9VCGIZHNCAAQFJGE9YHEHEFTDAGXHY'), current_index=5, last_index=7, value=-100, # These values are not relevant to the tests. branch_transaction_hash=TransactionHash(b''), bundle_hash=BundleHash(b''), hash_=TransactionHash(b''), nonce=Hash(b''), tag=Tag(b''), timestamp=1485020456, trunk_transaction_hash=TransactionHash(b''), ), # Input, Part 2 of 2 Transaction( # Make the signature look like a message, so we can verify that # the Bundle skips it correctly. signature_message_fragment=Fragment.from_string( 'This is a signature, not a message!'), address=Address(b'TESTVALUE9DONTUSEINPRODUCTION99999WGSBUA' b'HDVHYHOBHGP9VCGIZHNCAAQFJGE9YHEHEFTDAGXHY'), current_index=6, last_index=7, value=0, # These values are not relevant to the tests. branch_transaction_hash=TransactionHash(b''), bundle_hash=BundleHash(b''), hash_=TransactionHash(b''), nonce=Hash(b''), tag=Tag(b''), timestamp=1485020456, trunk_transaction_hash=TransactionHash(b''), ), # Change Transaction( # It's unusual for a change transaction to have a message, but # half the fun of unit tests is designing unusual scenarios! signature_message_fragment=Fragment.from_string( 'I can haz change?'), address=Address(b'TESTVALUE9DONTUSEINPRODUCTION99999FFYALH' b'N9ACYCP99GZBSDK9CECFI9RAIH9BRCCAHAIAWEFAN'), current_index=7, last_index=7, value=40, # These values are not relevant to the tests. branch_transaction_hash=TransactionHash(b''), bundle_hash=BundleHash(b''), hash_=TransactionHash(b''), nonce=Hash(b''), tag=Tag(b''), timestamp=1485020456, trunk_transaction_hash=TransactionHash(b''), ), ])
def test_single_transaction(self): """ Getting a bundle that contains a single transaction. """ transaction =\ Transaction( current_index = 0, last_index = 0, tag = Tag(b''), timestamp = 1484960990, value = 0, # These values are not relevant for 0-value transactions. nonce = Hash(b''), signature_message_fragment = Fragment(b''), # This value is computed automatically, so it has to be real. hash_ = TransactionHash( b'UGQBSMKGNXXWDCS9XZCFTPUXFADCT9I9KCNQGUXK' b'NDJDUXLWODOVJQWJHCLWTODAELDXGL9SMQYQZFWHE', ), address = Address( b'TESTVALUE9DONTUSEINPRODUCTION99999OCSGVF' b'IBQA99KGTCPCZ9NHR9VGLGADDDIEGGPCGBDEDDTBC', ), bundle_hash = BundleHash( b'TESTVALUE9DONTUSEINPRODUCTION99999DIOAZD' b'M9AIUHXGVGBC9EMGI9SBVBAIXCBFJ9EELCPDRAD9U', ), branch_transaction_hash = TransactionHash( b'TESTVALUE9DONTUSEINPRODUCTION99999BBCEDI' b'ZHUDWBYDJEXHHAKDOCKEKDFIMB9AMCLFW9NBDEOFV', ), trunk_transaction_hash = TransactionHash( b'TESTVALUE9DONTUSEINPRODUCTION999999ARAYA' b'MHCB9DCFEIWEWDLBCDN9LCCBQBKGDDAECFIAAGDAS', ), ) self.adapter.seed_response('getTrytes', { 'trytes': [transaction.as_tryte_string()], }) response = self.command(transaction=transaction.hash) bundle = response['bundles'][0] # type: Bundle self.assertEqual(len(bundle), 1) self.maxDiff = None self.assertDictEqual( bundle[0].as_json_compatible(), transaction.as_json_compatible(), )
def test_single_transaction(self): """ Getting a bundle that contains a single transaction. """ transaction =\ Transaction( current_index = 0, last_index = 0, tag = Tag(b''), timestamp = 1484960990, value = 0, # These values are not relevant for 0-value transactions. nonce = Hash(b''), signature_message_fragment = Fragment(b''), # This value is computed automatically, so it has to be real. hash_ = TransactionHash( b'TAOICZV9ZSXIZINMNRLOLCWNLL9IDKGVWTJITNGU' b'HAIKLHZLBZWOQ9HJSODUDISTYGIYPWTYDCFMVRBQN' ), address = Address( b'TESTVALUE9DONTUSEINPRODUCTION99999OCSGVF' b'IBQA99KGTCPCZ9NHR9VGLGADDDIEGGPCGBDEDDTBC' ), bundle_hash = BundleHash( b'TESTVALUE9DONTUSEINPRODUCTION99999DIOAZD' b'M9AIUHXGVGBC9EMGI9SBVBAIXCBFJ9EELCPDRAD9U' ), branch_transaction_hash = TransactionHash( b'TESTVALUE9DONTUSEINPRODUCTION99999BBCEDI' b'ZHUDWBYDJEXHHAKDOCKEKDFIMB9AMCLFW9NBDEOFV' ), trunk_transaction_hash = TransactionHash( b'TESTVALUE9DONTUSEINPRODUCTION999999ARAYA' b'MHCB9DCFEIWEWDLBCDN9LCCBQBKGDDAECFIAAGDAS' ), ) self.adapter.seed_response('getTrytes', { 'trytes': [transaction.as_tryte_string()], }) response = self.command(transaction=transaction.hash) bundle = response['bundles'][0] # type: Bundle self.assertEqual(len(bundle), 1) self.maxDiff = None self.assertDictEqual( bundle[0].as_json_compatible(), transaction.as_json_compatible(), )
def test_happy_path(self): """ Successfully replaying a bundle. """ # noinspection SpellCheckingInspection bundle = Bundle([ # "Spend" transaction, Part 1 of 1 Transaction( hash_=TransactionHash( b'LUQJUUDAZIHSTPBLCZYXWXYKXTFCOCQJ9EHXKLEB' b'IJBPSRFSBYRBYODDAZ9NPKPYSMPVNEFXYZQ999999'), address=Address(b'FZXUHBBLASPIMBDIHYTDFCDFIRII9LRJPXFTQTPO' b'VLEIFE9NWTFPPQZHDCXYUOUCXHHNRPKCIROYYTWSA'), branch_transaction_hash=TransactionHash( b'UKGIAYNLALFGJOVUZYJGNIOZSXBBZDXVQLUMHGQE' b'PZJWYDMGTPJIQXS9GOKXR9WIGWFRWRSKGCJ999999'), bundle_hash=BundleHash( b'ZSATLX9HDENCIARERVLWYHXPQETFL9QKTNC9LUOL' b'CDXKKW9MYTLZJDXBNOHURUXSYWMGGD9UDGLHCSZO9'), nonce=Hash(b'LIJVXBVTYMEEPCKJRIQTGAKWJRAMYNPJEGHEWAUL' b'XPBBUQPCJTJPRZTISQPJRJGMSBGQLER9OXYQXFGQO'), trunk_transaction_hash=TransactionHash( b'KFCQSGDYENCECCPNNZDVDTBINCBRBERPTQIHFH9G' b'YLTCSGUFMVWWSAHVZFXDVEZO9UHAUIU9LNX999999'), signature_message_fragment=Fragment(b''), current_index=0, last_index=3, tag=Tag(b''), timestamp=1483033814, value=1, ), # Input #1, Part 1 of 2 Transaction( hash_=TransactionHash( b'KFCQSGDYENCECCPNNZDVDTBINCBRBERPTQIHFH9G' b'YLTCSGUFMVWWSAHVZFXDVEZO9UHAUIU9LNX999999'), address=Address(b'GMHOSRRGXJLDPVWRWVSRWI9BCIVLUXWKTJYZATIA' b'RAZRUCRGTWXWP9SZPFOVAMLISUPQUKHNDMITUJKIB'), branch_transaction_hash=TransactionHash( b'UKGIAYNLALFGJOVUZYJGNIOZSXBBZDXVQLUMHGQE' b'PZJWYDMGTPJIQXS9GOKXR9WIGWFRWRSKGCJ999999'), bundle_hash=BundleHash( b'ZSATLX9HDENCIARERVLWYHXPQETFL9QKTNC9LUOL' b'CDXKKW9MYTLZJDXBNOHURUXSYWMGGD9UDGLHCSZO9'), nonce=Hash(b'VRYLDCKEWZJXPQVSWOJVYVBJSCWZQEVKPBG9KGEZ' b'GPRQFKFSRNBPXCSVQNJINBRNEPIKAXNHOTJFIVYJO'), trunk_transaction_hash=TransactionHash( b'QSTUKDIBYAZIQVEOMFGKQPHAIPBHUPSDQFFKKHRA' b'ABYMYMQDHMTEWCM9IMZHQMGXOTWNSJYHRNA999999'), signature_message_fragment=Fragment( b'XS9OVIXHIGGR9IYQBHGMFAHPZBWLIBNAQPFMPVYUZDOLLFDJIPZEMIOGVANQJSCU' b'IPDNNUNAMWEL9OFXXK9NV9UTCRBYTARBJHPQYJYKNAQGMATG9EXQMHGXY9QOHPBA' b'FEVABDYMCXORXHBMPLEWJYGYFFBWVXAUXHGLTABBKOQMZLFAYWDAKEOMJPJX9TMT' b'GXIJXZTKRRIPAMYY9UNSPPEGFPJE9NFSJFWKYOFZRMPBXZDNQUEKLRUVPXMCTQRE' b'ZWICSCVXN9VBLN9DRINRPAZTYJYXPGGRZJLMYXGCLUQNZ9NJGH9GFQPKKVK9N9WR' b'IJXDNKUMLLJUVIQRGPHEVWTXQHRLRCWQJCHTPASCVLRGPNWSIUKWIBMDJJ9EUTQ9' b'NXZZEJFWY9LCJJSOEPXWETUBKKVZNUKTLUPEPDBLUWCQGYTOXZ9NZUXHBDOUYQBP' b'MNECVJ9HGWA9AWU9VHGETWKBU9YZEZGEQKMVTAKPLCZVWKQFXDEFBPKNUCQDSPWA' b'LMPFTUFGRFDZH9PQHJ9WXZPCDWGMNASVVEUXEGWATM9ZIMCEEXTHCXFLYG9LQAKV' b'UOGORP9UUWYFTWGZ9OFOGSP9KDNPDSQKEMMISEMWQDVFKCSQXSP9RUMNUQJOBACU' b'MPIXCGBJLQQGB9GDSMUUUSYWIY9ZNIAIZBJYTAJKJKZIBFPMGDWUEPXSO9HUJRNV' b'QE9OTVUPKBVNVUBSILVZEDPC9AMEYAIATE9JEIQQWIMGCZXMHOPXPFUTEPJEATJN' b'QWDFZQ9OGPNBFUHLJDJZQJLXCFEUDPZKVCPEBTNBRYNIIKJHUV9EUFVMB9AHTARQ' b'DN9TZ9JPAPCEXSYHZPAQLBJMNQ9R9KPWVZLDLFNHYCCQBFVEPMEZSXAB9GOKGOGC' b'SOVL9XJSAQYSECY9UUNSVQSJB9BZVYRUURNUDMZVBJTMIDQUKQLMVW99XFDWTOPR' b'UBRPKS9BGEAQPIODAMJAILNCH9UVYVWSDCZXZWLO9XJJZ9FQOL9F9ZJDNGMUGFKJ' b'PCYURGYBGYRVKPEBKMJPZZGDKZKT9UBFSJEELREWOYDQZVUPVSGPZYIDVOJGNTXC' b'OFGCHBGVZPQDNRKAQNVJEYKYTKHTFBJRDMKVSHEWADNYIQOAUFXYMZKNJPLXGYFX' b'DTCVDDBUHBDPG9WLNMWPSCCCGVTIOOLEECXKNVAYNNTDLJMDGDGSKOGWO9UYXTTF' b'FCRZEDDQNN9ZODTETGMGGUXOYECGNMHGMGXHZSPODIBMBATJJHSPQHDUCZOMWQNI' b'CUZG9LAMBOQRQQDIPIBMIDCIAJBBBNDUAIEMFCEASHPUJPFPPXNDUVGDNNYBRRTW' b'SPXGXMCSUXYJSTFIRUIDNEUSVKNIDKIBRQNMEDCYQOMJYTMGRZLYHBUYXCRGSAXR' b'ZVHTZEAKNAUKJPFGPOGQLTDMSOXR9NVOIAIMCBVWOF9FXAZUKKZKHJEGHFNLUB9B' b'TGAICGQGAYZRRHSFIDTNIJPHIHCXTHQUSKJRSVAWFUXLBYA99QKMGLHDNUHOPEW9' b'OFNWPDXXRVZREUIQKSVSDCFIJ99TSGSZ9KU9JGE9VXDVVOLMGNMUGSHUZAOFCIMK' b'CPEWMG9IHUZAILQCANIUUG9JNEZMT9EONSN9CWWQOTFBEPZRTTJTQFSTQTBERKGE' b'NGFFIYMZMCFBYNIOBPOFOIYPUMYYPRXEHUJEVVELOPNXAPCYFXQ9ORMSFICDOZTS' b'GQOMDI9FKEKRIMZTWSIWMYAUSBIN9TPFSMQZCYGVPVWKSFZXPE9BP9ALNWQOVJGM' b'SCSJSTNUTMUAJUIQTITPPOHG9NKIFRNXSCMDAEW9LSUCTCXITSTZSBYMPOMSMTXP' b'CEBEOAUJK9STIZRXUORRQBCYJPCNHFKEVY9YBJL9QGLVUCSZKOLHD9BDNKIVJX9T' b'PPXQVGAXUSQQYGFDWQRZPKZKKWB9ZBFXTUGUGOAQLDTJPQXPUPHNATSGILEQCSQX' b'X9IAGIVKUW9MVNGKTSCYDMPSVWXCGLXEHWKRPVARKJFWGRYFCATYNZDTRZDGNZAI' b'OULYHRIPACAZLN9YHOFDSZYIRZJEGDUZBHFFWWQRNOLLWKZZENKOWQQYHGLMBMPF' b'HE9VHDDTBZYHMKQGZNCSLACYRCGYSFFTZQJUSZGJTZKKLWAEBGCRLXQRADCSFQYZ' b'G9CM9VLMQZA'), current_index=1, last_index=3, tag=Tag(b''), timestamp=1483033814, value=-99, ), # Input #1, Part 2 of 2 Transaction( hash_=TransactionHash( b'QSTUKDIBYAZIQVEOMFGKQPHAIPBHUPSDQFFKKHRA' b'ABYMYMQDHMTEWCM9IMZHQMGXOTWNSJYHRNA999999'), address=Address(b'GMHOSRRGXJLDPVWRWVSRWI9BCIVLUXWKTJYZATIA' b'RAZRUCRGTWXWP9SZPFOVAMLISUPQUKHNDMITUJKIB'), branch_transaction_hash=TransactionHash( b'UKGIAYNLALFGJOVUZYJGNIOZSXBBZDXVQLUMHGQE' b'PZJWYDMGTPJIQXS9GOKXR9WIGWFRWRSKGCJ999999'), bundle_hash=BundleHash( b'ZSATLX9HDENCIARERVLWYHXPQETFL9QKTNC9LUOL' b'CDXKKW9MYTLZJDXBNOHURUXSYWMGGD9UDGLHCSZO9'), nonce=Hash(b'AAKVYZOEZSOXTX9LOLHZYLNAS9CXBLSWVZQAMRGW' b'YW9GHHMVIOHWBMTXHDBXRTF9DEFFQFQESNVJORNXK'), trunk_transaction_hash=TransactionHash( b'ZYQGVZABMFVLJXHXXJMVAXOXHRJTTQUVDIIQOOXN' b'NDPQGDFDRIDQMUWJGCQKKLGEUQRBFAJWZBC999999'), signature_message_fragment=Fragment( b'YSNEGUCUHXEEFXPQEABV9ATGQMMXEVGMZWKKAFAVOVGUECOZZJFQDNRBCSXCOTBD' b'BRUJ9HF9CITXQI9ZQGZFKCXMFZTOYHUTCXDIBIMTBKVXMMTPNKRDRLQESLWFZSQQ' b'9BCGKVIZAHBWYTNXG9OWOXHAMQECMOVKN9SOEVJBBARPXUXYUQVFPYXWXQQMDIVP' b'VITRWTNNBY9CYBHXJTZUVIPJJG9WLTNMFVPXGYZCNOGSLGVMS9YXXNSV9AYPXZTA' b'QJYUNUFBCSZBZNKWCPMVMOGFIDENTOOOCPRDJTNGQRLA9YKMLYZQRO9QQJMCSYVF' b'YLISFIWQQYMWMHUOEZPATYCEZARLWLAMCZWYWJZVD9WWKYJURTOLITFFRXQUBKST' b'DG9CKDBLPXTPCIMKEKRGEXJGLRL9ZST9VOLV9NOFZLIMVOZBDZJUQISUWZKOJCRN' b'YRBRJLCTNPV9QIWQJZDQFVPSTW9BJYWHNRVQTITWJYB9HBUQBXTAGK9BZCHYWYPE' b'IREDOXCYRW9UXVSLZBBPAFIUEJABMBYKSUPNWVVKAFQJKDAYYRDICTGOTWWDSFLG' b'BQFZZ9NBEHZHPHVQUYEETIRUDM9V9LBXFUXTUGUMZG9HRBLXCKMMWWMK9VTKVZSA' b'PRSMJVBLFFDHTYCPDXKBUYYLZDPW9EVXANPZOPBASQUPRNCDGHNUK9NDUQSULUZI' b'VMIJTPUGMZPCYR9AERBAGUYNGVEHWIIADAAPPMYQOAGBQCXEDTQOGHWHHSWDFZLC' b'DVLNPYMGDPZWOZURT9OZKDJKFECXSFIALXJDRJWMWMTNUUNVDUCJAZLDRN9ZWLHH' b'SNXDWULUBNLVRDJZQMKCTRCKULKS9VARFZSRYZCPNH9FHXCAFWKPNGOPOFMYXJLE' b'LTKUHSZVDQRDJIGQRGOSKYWDCU9EBJMXQDBKTBNQTIZNCALHRNTHKN99WOBQVVEV' b'HEDTDRKFPGLIWOSPLAAELQQXDCDWPIFED9OEUPYPKHZBOHPQGQGSEKO9BFIQFYZK' b'YEULWSIBZVSPXBGOJTTYBVIIIPAXGL9ZJNNIELFYAUOUBRDWLJJMSAXHQOYGOWDV' b'HHPISRZFSHPDLNQDFWRHLWNAJPYM9REAJLZDIAIVLQBFAUJIQKVHJDFPXENI9ZM9' b'SFNGSQHDFEDC9CQVXAXTQVLWYMVSLEDCOVNSQLSANLVA9TWSY9BHAJKOCGI9YLAB' b'VROCBJRVXRWBKNUXCAXJIAYWSFRDZHIPQSNBRYNKZAFXHDUENVLHFHYIKH9IANFV' b'FKWVFJCSEELVTDDUHBPIYNFLTJLINNORIMDEAXMN9LGNGBWVWYWQIPWKBFDKNDOX' b'WFKGBAMZIUFYA9DXGAL9OQQTJAUUXTINWZSQUTPUKUMOZCGOBKKFBXCVR9AGTAQS' b'SVGTUBBHSIRHFRSIR9SKSZPXQFG9AOYAHZNQR9AHSEFCKWCJHUTLREDVGBQYVBZR' b'CZDXFG9PTSAWQOURYKNWYAZNASV9UMUYUMFCQSFDHZD99WUMCORLYTIZMRGNBAY9' b'UJYJMMRCLJP9XVLXTAZOHNVVYSCOSDHGUOPXIRBJDXJUCJYLQKUJOTNJCPRBDOKV' b'ZEMIGZRNJOQKFFAXQVGGY9YRJORZCOD9REIIIDDTRQ9TJWTFYRKOPLAFNUUPCHXA' b'WVPYUQXAFFCTYAESWAFUTQQYZRQVLVZW9OWAAJMPSAEPKWXVEZVTVPQEEBVXNZJP' b'ZU9JJSIAEPIT9HE99XNAUYOAKRIFQQJQTFIMWEOKLCH9JKCQTGZPEGWORFB9ARNS' b'DPYKRONBONYOGEVEFXGTMQTQBEMFQWEMIDSGAVEQHVHAPSMTCJ9FMEYBWAQWWJCE' b'ABUUMMVNDMSBORFLHVIIDOUQHHXQKXTVGRAYTLMECCSVZOZM9JKUWIGGFLMMDGBU' b'DBIHJFUINVOKSFTOGFCZEMIBSZNGPL9HXWGTNNAKYIMDITCRMSHFR9BDSFGHXQMR' b'ACZOVUOTSJSKMNHNYIFEOD9CVBWYVVMG9ZDNR9FOIXSZSTIO9GLOLPLMW9RPAJYB' b'WTCKV9JMSEVGD9ZPEGKXF9XYQMUMJPWTMFZJODFIEYNLI9PWODSPPW9MVJOWZQZU' b'CIKXCVVXDKWHXV99GOEZ9CMGUH9OWGLLISNZEPSAPEDHVRKKGFFNGBXFLDBQTTQL' b'WVLUITJQ9JM'), current_index=2, last_index=3, tag=Tag(b''), timestamp=1483033814, value=0, ), # "Change" transaction, Part 1 of 1 Transaction( hash_=TransactionHash( b'ZYQGVZABMFVLJXHXXJMVAXOXHRJTTQUVDIIQOOXN' b'NDPQGDFDRIDQMUWJGCQKKLGEUQRBFAJWZBC999999'), address=Address(b'YOTMYW9YLZQCSLHB9WRSTZDYYYGUUWLVDRHFQFEX' b'UVOQARTQWZGLBU9DVSRDPCWYWQZHLFHY9NGLPZRAQ'), branch_transaction_hash=TransactionHash( b'QCHKLZZBG9XQMNGCDVXZGDRXIJMFZP9XUGAWNNVP' b'GXBWB9NVEKEFMUWOEACULFUR9Q9XCWPBRNF999999'), bundle_hash=BundleHash( b'ZSATLX9HDENCIARERVLWYHXPQETFL9QKTNC9LUOL' b'CDXKKW9MYTLZJDXBNOHURUXSYWMGGD9UDGLHCSZO9'), nonce=Hash(b'TPGXQFUGNEYYFFKPFWJSXKTWEUKUFTRJCQKKXLXL' b'PSOHBZTGIBFPGLSVRIVYAC9NZMOMZLARFZYCNNRCM'), trunk_transaction_hash=TransactionHash( b'UKGIAYNLALFGJOVUZYJGNIOZSXBBZDXVQLUMHGQE' b'PZJWYDMGTPJIQXS9GOKXR9WIGWFRWRSKGCJ999999'), signature_message_fragment=Fragment(b''), current_index=3, last_index=3, tag=Tag(b''), timestamp=1483033814, value=98, ), ]) mock_get_bundles =\ mock.Mock(return_value={ 'bundles': [bundle], }) send_trytes_response = { 'trytes': bundle.as_tryte_strings(head_to_tail=True), } mock_send_trytes = mock.Mock(return_value=send_trytes_response) with mock.patch( 'iota.commands.extended.get_bundles.GetBundlesCommand._execute', mock_get_bundles, ): with mock.patch( 'iota.commands.extended.send_trytes.SendTrytesCommand._execute', mock_send_trytes, ): response = self.command( depth=100, minWeightMagnitude=18, transaction=bundle[0].hash, ) self.assertDictEqual(response, send_trytes_response)