def send_bundle(trytes): gtta = api.get_transactions_to_approve(depth=3) trunk = str(gtta['trunkTransaction']) # set a non-tail to fail rule 1 branch = str(gtta['branchTransaction']) #set a non-tail to fail rule 1 attached_trytes = api.attach_to_tangle(trunk, branch, trytes, 9).get('trytes') api.broadcast_and_store(attached_trytes) bundle = Bundle.from_tryte_strings(attached_trytes) pprint('Bundle is:') pprint(bundle.as_json_compatible()) return attached_trytes
async def test_validator_error(self): """ TraverseBundleCommand returns bundle but it is invalid. """ # Make the returned bundle invalid bundle = Bundle.from_tryte_strings(self.bundle_trytes) bundle.transactions[0].value = 999 # Unbalanced bundle for txn in bundle.transactions: self.adapter.seed_response('getTrytes', { 'trytes': [txn.as_tryte_string()], }) self.adapter.seed_response('getTrytes', { 'trytes': [self.spam_trytes], }) with self.assertRaises(BadApiResponse): response = await self.command(transactions = [self.tx_hash])
async def test_correct_transfer(self): """ Tests the good weather case for transfers """ bundle = Bundle([self.tx2]) self.wallet.create_wallet() # Set up mocks. self.wallet.get_balance = lambda: \ succeed({'available': 42, 'pending': 0, 'currency': self.identifier, 'precision': 0}) self.wallet.provider.submit_transaction = lambda transaction: succeed( bundle) self.wallet.provider.get_all_bundles = lambda: succeed([bundle]) self.wallet.provider.get_seed_transactions = lambda: succeed( [self.tx2]) # Send a correct transfer result = await self.wallet.transfer(1, self.tx2.address.__str__()) # Update the database await self.wallet.update_transactions_database() await self.wallet.update_bundles_database() # Check correct bundle storage all_bundles = self.wallet.database.query(DatabaseBundle) \ .all() # Get the bundle sent in the transaction bundle_query = self.wallet.database.query(DatabaseBundle) \ .filter(DatabaseBundle.hash.__eq__(bundle.hash.__str__())) \ .all() self.assertEqual(len(all_bundles), 1) self.assertEqual(bundle_query, all_bundles) # Check correct transaction storage all_txs = self.wallet.database.query(DatabaseTransaction) \ .all() # Get the transaction that's part of the bundle tx_query = self.wallet.database.query(DatabaseTransaction) \ .filter(DatabaseTransaction.hash.__eq__(self.tx2.hash.__str__())) \ .all() self.assertEqual(len(all_txs), 1) self.assertEqual(all_txs, tx_query) # Assert correct return value self.assertEqual(bundle.hash.__str__(), result) self.wallet.cancel_all_pending_tasks()
async def test_happy_path(self): """ Get a bundle with multiple transactions. """ for txn_trytes in self.bundle_trytes: self.adapter.seed_response('getTrytes', { 'trytes': [txn_trytes], }) self.adapter.seed_response('getTrytes', { 'trytes': [self.spam_trytes], }) response = await self.command(transactions = [self.tx_hash]) self.maxDiff = None original_bundle = Bundle.from_tryte_strings(self.bundle_trytes) self.assertListEqual( response['bundles'][0].as_json_compatible(), original_bundle.as_json_compatible(), )
def _execute(self, request): transaction_hash = request['transaction'] # type: TransactionHash bundle = Bundle(self._traverse_bundle(transaction_hash)) validator = BundleValidator(bundle) if not validator.is_valid(): raise with_context( exc=BadApiResponse( 'Bundle failed validation (``exc.context`` has more info).', ), context={ 'bundle': bundle, 'errors': validator.errors, }, ) return { # Always return a list, so that we have the necessary structure # to return multiple bundles in a future iteration. 'bundles': [bundle], }
def _execute(self, request): change_address = request['changeAddress'] # type: Optional[Address] depth = request['depth'] # type: int inputs = request['inputs'] # type: Optional[List[Address]] min_weight_magnitude = request['minWeightMagnitude'] # type: int seed = request['seed'] # type: Seed transfers = request['transfers'] # type: List[ProposedTransaction] pt_response = PrepareTransferCommand(self.adapter)( changeAddress = change_address, inputs = inputs, seed = seed, transfers = transfers, ) st_response = SendTrytesCommand(self.adapter)( depth = depth, minWeightMagnitude = min_weight_magnitude, trytes = pt_response['trytes'], ) return { 'bundle': Bundle.from_tryte_strings(st_response['trytes']), }
def test_wrongly_ordered_bundle(self): """ Supply bundle trytes in wrong order. `attach_to_tangle` constructs a bundle object from the trytes, that should reorder transactions in correct order based on index. """ wrong_bundle_trytes = [] for txn in reversed(self.bundle.as_tryte_strings()): wrong_bundle_trytes.append(txn) test_trytes = ccurl_interface.attach_to_tangle(wrong_bundle_trytes, self.branch, self.trunk, mwm=14) test_bundle = Bundle.from_tryte_strings(test_trytes) validator = BundleValidator(test_bundle) if not validator.is_valid(): raise ValueError( 'Bundle failed validation:\n{errors}'.format(errors='\n'.join( (' - ' + e) for e in validator.errors), ), ) self.assertTrue(validator.is_valid())
def _execute(self, request): change_address = request['changeAddress'] # type: Optional[Address] depth = request['depth'] # type: int inputs = request['inputs'] # type: Optional[List[Address]] min_weight_magnitude = request['minWeightMagnitude'] # type: int seed = request['seed'] # type: Seed transfers = request['transfers'] # type: List[ProposedTransaction] pt_response = PrepareTransferCommand(self.adapter)( changeAddress=change_address, inputs=inputs, seed=seed, transfers=transfers, ) st_response = SendTrytesCommand(self.adapter)( depth=depth, minWeightMagnitude=min_weight_magnitude, trytes=pt_response['trytes'], ) return { 'bundle': Bundle.from_tryte_strings(st_response['trytes']), }
def test_full_scan(self): """ Scanning the Tangle for all transfers. """ # To speed up the test, we will mock the address generator. # :py:class:`iota.crypto.addresses.AddressGenerator` already has # its own test case, so this does not impact the stability of the # codebase. # noinspection PyUnusedLocal def create_generator(ag, start, step=1): for addy in [self.addy1, self.addy2][start::step]: yield addy # The first address received IOTA. self.adapter.seed_response( 'findTransactions', { 'duration': 42, 'hashes': [ 'TESTVALUEFIVE9DONTUSEINPRODUCTION99999VH' 'YHRHJETGYCAFZGABTEUBWCWAS9WF99UHBHRHLIOFJ', ], }, ) # The second address is unused. self.adapter.seed_response( 'findTransactions', { 'duration': 1, 'hashes': [], }, ) self.adapter.seed_response( 'getTrytes', { 'duration': 99, # Thankfully, we do not have to seed a realistic response for # ``getTrytes``, as we will be mocking the ``getBundles`` # command that uses on it. 'trytes': [''], }, ) bundle = Bundle([ Transaction( address=self.addy1, timestamp=1483033814, # These values are not relevant to the test. hash_=None, signature_message_fragment=None, value=42, tag=Tag(b''), current_index=0, last_index=0, bundle_hash=None, trunk_transaction_hash=None, branch_transaction_hash=None, attachment_timestamp=1483033814, attachment_timestamp_lower_bound=12, attachment_timestamp_upper_bound=0, nonce=None, ) ]) mock_get_bundles = \ mock.Mock(return_value={ 'bundles': [bundle], }) with mock.patch( 'iota.crypto.addresses.AddressGenerator.create_iterator', create_generator, ): with mock.patch( 'iota.commands.extended.get_bundles.GetBundlesCommand._execute', mock_get_bundles, ): response = self.command(seed=Seed.random()) self.assertDictEqual( response, { 'bundles': [bundle], }, )
def execute(self, api, **arguments): # type: (Iota, ...) -> int channel_key_index = arguments['channel_key_index'] # type: int count = arguments['count'] # type: int depth = arguments['depth'] # type: int dry_run = arguments['dry_run'] # type: bool mam_encrypt_path = arguments['mam_encrypt_path'] # type: Text min_weight_magnitude = arguments['min_weight_magnitude'] # type: int message_encoding = arguments['message_encoding'] # type: Text message_file = arguments['message_file'] # type: Optional[Text] security_level = arguments['security_level'] # type: int start = arguments['start'] # type: int if message_file: with codecs.open( message_file, 'r', message_encoding) as f_: # type: codecs.StreamReaderWriter message = f_.read() else: self.stdout.write( 'Enter message to send. Press Ctrl-D on a blank line when done.\n\n', ) message = self.stdin.read().strip() self.stdout.write('\n') # Generating the encrypted message may take a little while, so we # should provide some feedback to the user so that they know that # their input is being processed (this is especially important if # the user typed in their message, so that they don't press ^D # again, thinking that the program didn't register the first one). self.stdout.write('Encrypting message...\n') proc =\ run( args = [ # mam_encrypt.js mam_encrypt_path, # Required arguments binary_type(api.seed), message, # Options '--channel-key-index', text_type(channel_key_index), '--start', text_type(start), '--count', text_type(count), '--security-level', text_type(security_level), ], check = True, stdout = PIPE, stderr = self.stderr, ) # The output of the JS script is a collection of transaction # trytes, encoded as JSON. filter_ =\ f.FilterRunner( starting_filter = f.Required | f.Unicode | f.JsonDecode | f.Array | f.FilterRepeater( f.ByteString(encoding='ascii') | Trytes(result_type=TransactionTrytes) ), incoming_data = proc.stdout, ) if not filter_.is_valid(): self.stderr.write( 'Invalid output from {mam_encrypt_path}:\n' '\n' 'Output:\n' '{output}\n' '\n' 'Errors:\n' '{errors}\n'.format( errors=pformat(filter_.get_errors(with_context=True)), mam_encrypt_path=mam_encrypt_path, output=proc.stdout, ), ) return 2 transaction_trytes = filter_.cleaned_data # type: List[TransactionTrytes] bundle = Bundle.from_tryte_strings(transaction_trytes) if dry_run: self.stdout.write('Transactions:\n\n') self.stdout.write(json.dumps(bundle, cls=JsonEncoder, indent=2)) else: api.send_trytes( depth=depth, trytes=transaction_trytes, min_weight_magnitude=min_weight_magnitude, ) self.stdout.write('Message broadcast successfully!\n') self.stdout.write( 'Bundle ID: {bundle_hash}\n'.format( bundle_hash=bundle.hash, ), ) return 0
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=Nonce(b'LIJVXBVTYMEEPCKJRIQTGAKWJRA'), 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, attachment_timestamp=0, attachment_timestamp_lower_bound=0, attachment_timestamp_upper_bound=0, ), # 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=Nonce(b'VRYLDCKEWZJXPQVSWOJVYVBJSCW'), 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, attachment_timestamp=0, attachment_timestamp_lower_bound=0, attachment_timestamp_upper_bound=0, ), # 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=Nonce(b'AAKVYZOEZSOXTX9LOLHZYLNAS9C'), 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, attachment_timestamp=0, attachment_timestamp_lower_bound=0, attachment_timestamp_upper_bound=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=Nonce(b'TPGXQFUGNEYYFFKPFWJSXKTWEUK'), 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, attachment_timestamp=0, attachment_timestamp_lower_bound=0, attachment_timestamp_upper_bound=0, ), ]) mock_get_bundles =\ mock.Mock(return_value={ 'bundles': [bundle], }) send_trytes_response = { 'trytes': bundle.as_tryte_strings(), } def mock_send_trytes(_, request): """ Ensures that the correct trytes are sent to the ``sendTrytes`` command to replay the bundle. References: - https://github.com/iotaledger/iota.lib.py/issues/74 """ self.assertEqual(request['trytes'], send_trytes_response['trytes']) return 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)
https://github.com/iotaledger/wiki/blob/master/multisigs.md#how-m-of-n-works For this example, the structure of the bundle looks like this: - Transaction 0: Spend IOTAs. - Transactions 1-8: Transactions that will hold the signature fragments for the multisig input: - 1-3: Generated from ``digest_1`` (security level 3). - 4-6: Generated from ``digest_2`` (security level 3). - 7-8: Generated from ``digest_3`` (security level 2). Note that transactions 1-8 don't have signatures yet; we need the corresponding private keys in order to create those! """ bundle = Bundle.from_tryte_strings(prepared_trytes) # Note that we must use the same parameters that we provided to the # ``get_digests`` method, in order to generate the correct value to # sign the input! gpk_result = api_1.get_private_keys(index=0, count=1, security_level=3) private_key_1 = gpk_result['keys'][0] # type: PrivateKey private_key_1.sign_input_transactions(bundle, 1) gpk_result = api_2.get_private_keys(index=42, count=1, security_level=3) private_key_2 = gpk_result['keys'][0] # type: PrivateKey private_key_2.sign_input_transactions(bundle, 4) gpk_result = api_3.get_private_keys(index=8, count=1, security_level=2) private_key_3 = gpk_result['keys'][0] # type: PrivateKey private_key_3.sign_input_transactions(bundle, 7)
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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), ])
"DQEUSNVVGKZUMYXKDUIEDYHCDVVAXGWU9RZUGOGFCFSTDVJEIWIETEGLKUIEKMKKFOKHVGUAELCMWE999", # type: Optional[TransactionHash] tag="QA9999999999999999999999999", # type: Optional[Tag] attachment_timestamp=1574903769168, # type: Optional[int] attachment_timestamp_lower_bound=0, # type: Optional[int] attachment_timestamp_upper_bound=3812798742493, # type: Optional[int] nonce="CVREKSTNCZMMXIEWQJLPADWVEBB", # type: Optional[Nonce] legacy_tag=None # type: Optional[Tag] ) trans = list() trans.append(bundle_trans) trans.append(bundle_trans_2) trans.append(bundle_trans_3) trans.append(bundle_trans_4) print('\n in processing bundle') bundle = Bundle(transactions=trans) print(bundle.transactions[1].signature_message_fragment) print('bundle creation is finished\n') ## # Create digest 1 of 3. # # noinspection SpellCheckingInspection api_1 = MultisigIota( adapter='http://localhost:14265', seed=Seed( b'TESTVALUE9DONTUSEINPRODUCTION99999XKMYQP' b'OIFGQSMIIWCQVMBSOKZASRQOFSIUSSHNDKVL9PJVS', ), ) gd_result = api_1.get_digests( # Starting key index.
async def test_happy_path(self): """ Preparing a bundle with a multisig input. """ self.adapter.seed_response( command=GetBalancesCommand.command, response={ 'balances': [42], # Would it be cheeky to put "7½ million years" here? 'duration': 86, }, ) pmt_result =\ await self.command( transfers = [ ProposedTransaction( address = Address(self.trytes_1), value = 42, ), ], multisigInput = MultisigAddress( digests = [self.digest_1, self.digest_2], trytes = self.trytes_2, ), ) # The command returns the raw trytes. This is useful in a # real-world scenario because trytes are easier to transfer between # each entity that needs to apply their signature. # # However, for purposes of this test, we will convert the trytes # back into a bundle so that we can inspect the end result more # easily. bundle = Bundle.from_tryte_strings(pmt_result['trytes']) # # This bundle looks almost identical to what you would expect from # :py:meth:`iota.api.Iota.prepare_transfer`, except: # - There are 4 inputs (to hold all of the signature fragments). # - The inputs are unsigned. # self.assertEqual(len(bundle), 5) # Spend Transaction txn_1 = bundle[0] self.assertEqual(txn_1.address, self.trytes_1) self.assertEqual(txn_1.value, 42) # Input 1, Part 1 of 4 txn_2 = bundle[1] self.assertEqual(txn_2.address, self.trytes_2) self.assertEqual(txn_2.value, -42) self.assertEqual(txn_2.signature_message_fragment, Fragment(b'')) # Input 1, Part 2 of 4 txn_3 = bundle[2] self.assertEqual(txn_3.address, self.trytes_2) self.assertEqual(txn_3.value, 0) self.assertEqual(txn_3.signature_message_fragment, Fragment(b'')) # Input 1, Part 3 of 4 txn_4 = bundle[3] self.assertEqual(txn_4.address, self.trytes_2) self.assertEqual(txn_4.value, 0) self.assertEqual(txn_4.signature_message_fragment, Fragment(b'')) # Input 1, Part 4 of 4 txn_5 = bundle[4] self.assertEqual(txn_5.address, self.trytes_2) self.assertEqual(txn_5.value, 0) self.assertEqual(txn_5.signature_message_fragment, Fragment(b''))
def search_hash(type, hash): result = None if type == "tag" or type == "search": try: result = api.find_transactions(tags=[hash]) if result['hashes'][0]: return "tag", result['hashes'] except BaseException as e: result = e if type == "address" or type =="search": try: result = api.find_transactions(addresses=[hash]) if result['hashes'][0]: balance = get_price(api.get_balances([hash])['balances'][0]) tx = api.get_trytes(result['hashes'])['trytes'] for num in range(len(tx)): tx[num] = Transaction.from_tryte_string(tx[num]) confirm = confirmation([element.hash for element in tx]) for t in tx: t.is_confirmed = confirm[t.hash] t.timestamp = calculate_time(t.attachment_timestamp/1000) t.value = get_convert(t.value) tx = sorted(tx, key=lambda k: k.attachment_timestamp, reverse=True) results = {'balance':balance, 'transactions':tx} return "address", results except BaseException as e: result = e if type == "transaction" or type =="search": try: tx = api.get_trytes(hashes=[hash]) result = Transaction.from_tryte_string(tx['trytes'][0]) if result.hash != TransactionHash(b''): result.timestamp = calculate_time(result.attachment_timestamp/1000) result.is_confirmed = confirmation([result.hash])[result.hash] result.value = get_price(result.value) return "transaction", result except BaseException as e: result = e if type == "bundle" or type =="search": try: result = api.find_transactions(bundles=[hash])['hashes'] if result[0]: results = Bundle.from_tryte_strings(api.get_trytes(result)['trytes']) if True in confirmation(result).values(): results.is_confirmed = True for result in results: result.value = get_convert(result.value) newlis = sorted(results, key=lambda k: k.attachment_timestamp, reverse=True) size = newlis[0].last_index+1 newlist = [newlis[i:i+size] for i in range(0, len(newlis), size)] for x in newlist: x[0].timestamp = calculate_time(x[0].attachment_timestamp/1000) return "bundle", newlist except BaseException as e: result = e return "error", str(result)
def attach_to_tangle( bundle_trytes, # Iterable[TryteString] trunk_transaction_hash, # TransactionHash branch_transaction_hash, # TransactionHash mwm=14): # Int """ Attaches the bundle to the Tangle by doing Proof-of-Work locally. No connection to the Tangle is needed in this step. :param bundle_trytes: List of TryteString(s) that contain raw transaction trytes. :param trunk_transaction_hash: Trunk transaction hash obtained from an iota node. Result of the tip selection process. :param branch_transaction_hash: Branch transaction hash obtained from an iota node. Result of the tip selection process. :param mwm: Minimum Weight Magnitude to be used during the PoW. Number of trailing zero trits in transaction hash. :returns: The bundle as a list of transaction trytes (TryteStrings). Attachment timestamp and nonce included. """ previoustx = None # Construct bundle object bundle = Bundle.from_tryte_strings(bundle_trytes) # reversed, beause pyota bundles look like [...tx2,tx1,tx0] # and we need the tail tx first (tx0) for txn in reversed(bundle.transactions): txn.attachment_timestamp = get_current_ms() txn.attachment_timestamp_upper_bound = (math.pow(3, 27) - 1) // 2 if (not previoustx): # this is the tail transaction if txn.current_index == txn.last_index: txn.branch_transaction_hash = branch_transaction_hash txn.trunk_transaction_hash = trunk_transaction_hash else: raise ValueError('Tail transaction is inconsistent in bundle') else: # It is not a tail transaction txn.branch_transaction_hash = trunk_transaction_hash txn.trunk_transaction_hash = previoustx # the previous transaction # Let's do the pow locally txn_string = txn.as_tryte_string().__str__() # returns a python unicode string powed_txn_string = get_powed_tx_trytes(txn_string, mwm) # construct trytestring from python string powed_txn_trytes = TryteString(powed_txn_string) # compute transaction hash hash_string = get_hash_trytes(powed_txn_string) hash_trytes = TryteString(hash_string) hash_ = TransactionHash(hash_trytes) # Create powed txn object powed_txn = Transaction.from_tryte_string(trytes=powed_txn_trytes, hash_=hash_) previoustx = powed_txn.hash # put that back in the bundle bundle.transactions[txn.current_index] = powed_txn return bundle.as_tryte_strings()
def setUp(self) -> None: # Need two valid bundles super().setUp() self.adapter = MockAdapter() self.single_bundle = Bundle.from_tryte_strings([ TransactionTrytes( '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999POALVTTGQHJFGINKJ9' 'EWRJZBQLLWMMNMNRUT9VFWDDMDWHPJMNDOFZXUQUABGCXZRH9OI9NWEUSHVYXDO' '999999999999999999999999999C99999999999999999999999999RIGEHBD99' '999999999999999999RPCKQTYDOV9IYVYYALBTBLHRFCLFMTCC9ZLOKKGENTDFY' 'COKFUITXUIUJLBNWAEKBJKBYDSRLVHSGELCCCZGNHCYEAKJ9OPRZFIBYEEBTRFT' 'QTWJUKRDKNSEESICPJRTDNZQQYNXOFVXI9CPRNBO9APJMEXATA9999CZGNHCYEA' 'KJ9OPRZFIBYEEBTRFTQTWJUKRDKNSEESICPJRTDNZQQYNXOFVXI9CPRNBO9APJM' 'EXATA9999C99999999999999999999999999FQFFNIHPF999999999MMMMMMMMM' 'BCDJOVFVODAQEPAXIWDRFKCTOFI') ]) self.three_tx_bundle = Bundle.from_tryte_strings(([ TransactionTrytes( 'PBXCFDGDHDEAHDFDPCBDGDPCRCHDXCCDBDEAXCBDEAHDWCTCEAQCIDBDSC9DTCS' 'A99999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999M9OVNPOWKUNQYDHFN9' 'YAL9WIQJDVAFKBU9ZPIHSGTZLGFJODRZINZMDALS9ERTNAJ9VTENWYLBSYALQQL' '999999999999999999999999999EYOTA9TESTS9999999999999999BOPIHBD99' '999999999B99999999JWFDGHYGEQIKSPCWEAHHQACOYHQWINSA9GELCEZNQEUHV' 'DH9UAYJVSTIIKW9URTHHIJYGWXGE9AEWISYWZSLPKSJETGKZEQVPISQSNDHIAXQ' 'RZVFJXFOXZAVMRUGALCQRHUEZPDFNLCIKQGWEKDJURLZLMUZVA99999BSJCSWTG' 'RTJSGZPOXRPICUDATCLCVTF9BEDHSZZRLSH9IRMTFRVAMSSHC9TRYZGHPWRDVTX' 'EXWTZ9999PYOTA9TESTS9999999999999999OSZRBMHPF999999999MMMMMMMMM' 'IVL9PTSTAIRGJLGXFQGIWOJHBKF'), TransactionTrytes( 'BCTCRCCDBDSCEAHDFDPCBDGDPCRCHDXCCDBDEAXCBDEAHDWCTCEAQCIDBDSC9DT' 'CSA999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999LSTTHILAJWQEXWVOJQ' 'GRANRLNHQLKYXVQFBYJ9QDFRISQR9WJYMSSZUBOCVLXF9TACHKGQUEGMJPICXVY' '999999999999999999999999999PYOTA9TESTS9999999999999999BOPIHBD99' 'A99999999B99999999JWFDGHYGEQIKSPCWEAHHQACOYHQWINSA9GELCEZNQEUHV' 'DH9UAYJVSTIIKW9URTHHIJYGWXGE9AEWISYWQQAWNWHDSGZWFTKTYSV99PJIFFM' 'OPFWONAOTRBUEDGLORTHNMXM9EZNILYEIWCQIAVMAGDBHYWWOA99999BSJCSWTG' 'RTJSGZPOXRPICUDATCLCVTF9BEDHSZZRLSH9IRMTFRVAMSSHC9TRYZGHPWRDVTX' 'EXWTZ9999PYOTA9TESTS9999999999999999EMSRBMHPF999999999MMMMMMMMM' 'NXTVOIJXAAJUS9SRVJEVDVOSIUE'), TransactionTrytes( 'CCWCXCFDSCEAHDFDPCBDGDPCRCHDXCCDBDEAXCBDEAHDWCTCEAQCIDBDSC9DTCS' 'A99999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999FSXLFSGAHTGSFPK9FH' 'HURWZJAWQDQCRIFUHMSZWUTNRAIDNGEHGPHLNJOEAIDGLYQRCYSCYDTBZQFDGQK' '999999999999999999999999999PYOTA9TESTS9999999999999999BOPIHBD99' 'B99999999B99999999JWFDGHYGEQIKSPCWEAHHQACOYHQWINSA9GELCEZNQEUHV' 'DH9UAYJVSTIIKW9URTHHIJYGWXGE9AEWISYW9BSJCSWTGRTJSGZPOXRPICUDATC' 'LCVTF9BEDHSZZRLSH9IRMTFRVAMSSHC9TRYZGHPWRDVTXEXWTZ99999BSJCSWTG' 'RTJSGZPOXRPICUDATCLCVTF9BEDHSZZRLSH9IRMTFRVAMSSHC9TRYZGHPWRDVTX' 'EXWTZ9999PYOTA9TESTS9999999999999999LUSRBMHPF999999999MMMMMMMMM' 'BOCWSYQAKMZXDR9ZPHXTXZORELC'), ]))
def _reattach(self, bundle: Bundle) -> Bundle: response = self._iota_api.replay_bundle( bundle.tail_transaction.hash, DEPTH, ) return Bundle.from_tryte_strings(response['trytes'])
def test_stop(self): """ Scanning the Tangle for all transfers, with stop index. """ # noinspection PyUnusedLocal def create_generator(ag, start, step=1): # Inject an invalid value into the generator, to ensure it is # skipped. for addy in [self.addy1, None][start::step]: yield addy # The first address received IOTA. self.adapter.seed_response( 'findTransactions', { 'duration': 42, 'hashes': [ 'TESTVALUEFIVE9DONTUSEINPRODUCTION99999VH' 'YHRHJETGYCAFZGABTEUBWCWAS9WF99UHBHRHLIOFJ', ], }, ) self.adapter.seed_response( 'getTrytes', { 'duration': 99, 'trytes': [''], }, ) bundle = Bundle([ Transaction( address=self.addy1, timestamp=1483033814, # These values are not relevant to the test. hash_=None, signature_message_fragment=None, value=42, tag=Tag(b''), current_index=0, last_index=0, bundle_hash=None, trunk_transaction_hash=None, branch_transaction_hash=None, attachment_timestamp=1483033814, attachment_timestamp_lower_bound=12, attachment_timestamp_upper_bound=0, nonce=None, ) ]) mock_get_bundles = mock.Mock(return_value={ 'bundles': [bundle], }) with mock.patch( 'iota.crypto.addresses.AddressGenerator.create_iterator', create_generator, ): with mock.patch( 'iota.commands.extended.get_bundles.GetBundlesCommand._execute', mock_get_bundles, ): response = self.command(seed=Seed.random(), stop=1) self.assertDictEqual( response, { 'bundles': [bundle], }, )
class BundleTestCase(TestCase): def setUp(self): super(BundleTestCase, self).setUp() 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # This transaction has a message that fits into a single # fragment. Transaction( signature_message_fragment = Fragment.from_unicode('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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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_unicode('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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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_unicode('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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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_unicode('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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), ]) def test_get_messages_errors_drop(self): """ Decoding messages from a bundle, with ``errors='drop'``. """ messages = self.bundle.get_messages('drop') self.assertEqual(len(messages), 3) self.assertEqual(messages[0], 'Hello, world!') self.assertEqual( messages[1], ''' "Good morning," said Deep Thought at last. "Er... Good morning, O Deep Thought," said Loonquawl nervously. "Do you have... er, that is..." "... an answer for you?" interrupted Deep Thought majestically. "Yes. I have." The two men shivered with expectancy. Their waiting had not been in vain. "There really is one?" breathed Phouchg. "There really is one," confirmed Deep Thought. "To Everything? To the great Question of Life, the Universe and Everything?" "Yes." Both of the men had been trained for this moment; their lives had been a preparation for it; they had been selected at birth as those who would witness the answer; but even so they found themselves gasping and squirming like excited children. "And you're ready to give it to us?" urged Loonquawl. "I am." "Now?" "Now," said Deep Thought. They both licked their dry lips. "Though I don't think," added Deep Thought, "that you're going to like it." "Doesn't matter," said Phouchg. "We must know it! Now!" "Now?" enquired Deep Thought. "Yes! Now!" "All right," said the computer and settled into silence again. The two men fidgeted. The tension was unbearable. "You're really not going to like it," observed Deep Thought. "Tell us!" "All right," said Deep Thought. "The Answer to the Great Question..." "Yes?" "Of Life, the Universe and Everything..." said Deep Thought. "Yes??" "Is..." "Yes?!" "Forty-two," said Deep Thought, with infinite majesty and calm. ''', ) self.assertEqual(messages[2], 'I can haz change?') def test_get_messages_errors_strict(self): """ Decoding messages from a bundle, with ``errors='strict'``. """ with self.assertRaises(UnicodeDecodeError): self.bundle.get_messages('strict') def test_get_messages_errors_ignore(self): """ Decoding messages from a bundle, with ``errors='ignore'``. """ messages = self.bundle.get_messages('ignore') self.assertEqual(len(messages), 4) # The only message that is treated differently is the invalid one. self.assertEqual(messages[0], '祝你好运\x15') def test_get_messages_errors_replace(self): """ Decoding messages from a bundle, with ``errors='replace'``. """ messages = self.bundle.get_messages('replace') self.assertEqual(len(messages), 4) # The only message that is treated differently is the invalid one. self.assertEqual(messages[0], '祝你好运�\x15')
def test_get_inclusion_states(self): """ Fetching inclusion states with transactions. """ # noinspection PyUnusedLocal def create_generator(ag, start, step=1): for addy in [self.addy1][start::step]: yield addy # The first address received IOTA. self.adapter.seed_response( 'findTransactions', { 'duration': 42, 'hashes': [ 'TESTVALUEFIVE9DONTUSEINPRODUCTION99999VH' 'YHRHJETGYCAFZGABTEUBWCWAS9WF99UHBHRHLIOFJ', ], }, ) # For this test, we have to generate a real TryteString. transaction_trytes = \ TryteString( b'KMYUMNEUAYODAQSNGWTAERRRHNZBZCOLMVVOBTVWLOFYCJKYMGRAMH9RQ9MTZOSZMH' b'QNZFHFEJEDFQ99HSUNVOTULDJGXEDULS9ZHABVDZODJUMCNWVCPNSCUVKVYWCEXBHW' b'RBZBSWFPQLWZWMUPGQIGAEGOVE9DDXBVCIPKQYCFZFBELTSMVFSIXLPTACTKAFMCTK' b'CPYD9BWDJMLKWAOBDSJNQYAHS9GFIQKZCROLFZJVUEIVXVNBRRLEIWTYVHURUXHSCG' b'DKEIEGPOCXKCYWIBUG9ABYCALYJVFLBNGMS9ARHGTQXBZFLENXCJVKHPVKD9KSAEOL' b'FFVAJCNKLDVHOCDARWUNKARDYMVKFKRSMUTYOUXSBFFYTKRREBDJZTLVUROQFCBXQN' b'SXDDYTZTEBRSXOBMLXHJKSJAVOOVCXATOWNQDWHT9CCUAAJUJKDOQLMAEZACSNFKXZ' b'IGWDQEUEFRZYAOSDNVMSXWYLVDAUXZSHNHAIBEMNPFUGORYUETNJK9UCEMSUJYBBDK' b'BHIPKEINQCGOVYCPKUPJMUCUVZOJSIWYRFMFXYUVSMOUALAQBWIMXBUBXSAETGKJRP' b'AHVAXHQJDMEVSRFYEXUSIEBKMGYCUKFD9JPGUV9AIYUVCRUURKMYUHMVE9OJCYYWTQ' b'WUWFMTBZYFXASHHVCMSWXKBRQFHHQVEQMEULJRWZKLWFFSGGKEHUZZFNDNITSRAUH9' b'PQK9OGLYMVBSHXQLLZHOBBIM9KVUWDLHZRDKQQVLQXGWYXEEVQPDZUO9PVXMALOMRQ' b'VCTHGIZLILSCFKTBRESYZGBZKHXEODNDJZ9GK9ROWYXNGFHZCCBHHZEYEOGWXRGSUD' b'SUZFUAUBXVXZHCUVJSYBWTCYCEDYKZNGWFZYKSQLW9FUYMWDVXKZEWT9SCVMQCODZK' b'DRNKTINTPNOJOLGQJDAJMFWRFSWZJLYZGSTSIDSXLUJBZRZNLEDNBKAUNGTCYUPDRW' b'JOCEBQ9YG9IZLLRMJITISJOTLQMOGXVQIZXHMTJVMMWM9FOIOT9KFZMANEPOEOV9HX' b'JNEGURUKRWDGYNPVGAWMWQVABIJNL9MDXKONEPMYACOZ9BE9UZMAFTKYWPFWIQWAPK' b'GUXQTOQVWYYVZYGQDLBIQDVOZIWGOMGOBAUARICQZVNXD9UVEFBBAJKQBHRHXTBUOW' b'VBFKYQWZWTMMXVKZRIZUBVPQ9XHLJHFHWFZUIZVSNAKBDHDFGJCYQETOMEDTOXIUT9' b'OAJVIHWAGTCNPEZTERMMN9EZEWSJHKQAUMXPBZTNQOEQCVXIMAAYO9NIUFLTCFIMK9' b'9AFAGWJFA9VOFPUDJLRAMORGSUDBLWWKXEDZ9XPQUZSGANGESHKKGGQSGSYDCRLHZD' b'PKA9HKYBKLKKCXYRQQIPXCFETJJDZYPCLUNHGBKEJDRCIHEXKCQQNOV9QFHLGFXOCR' b'HPAFCUTPMY9NOZVQHROYJSCMGRSVMOBWADAZNFIAHWGIQUUZBOVODSFAUNRTXSDU9W' b'EIRBXQNRSJXFRAQGHA9DYOQJGLVZUJKAQ9CTUOTT9ZKQOQNNLJDUPDXZJYPRCVLRZT' b'UCZPNBREYCCKHK9FUWGITAJATFPUOFLZDHPNJYUTXFGNYJOBRD9BVHKZENFXIUYDTL' b'CE9JYIIYMXMCXMWTHOLTQFKFHDLVPGMQNITEUXSYLAQULCZOJVBIPYP9M9X9QCNKBX' b'W9DVJEQFFY9KQVMKNVTAHQVRXUKEM9FZOJLHAGEECZBUHOQFZOSPRXKZOCCKAOHMSV' b'QCFG9CWAHKVWNA9QTLYQI9NKOSHWJCNGPJBLEQPUIWJBIOAWKLBXUCERTSL9FVCLYN' b'ADPYTPKJOIEMAQGWBVGSRCZINXEJODUDCT9FHOUMQM9ZHRMBJYSOMPNMEAJGEHICJI' b'PVXRKCYX9RZVT9TDZIMXGZJAIYJRGIVMSOICSUINRBQILMJOUQYXCYNJ9WGGJFHYTU' b'LWOIPUXXFNTIFNOJRZFSQQNAWBQZOLHHLVGHEPWTKKQEVIPVWZUN9ZBICZ9DZZBVII' b'BF9EPHARZJUFJGBQXQFQIBUECAWRSEKYJNYKNSVBCOWTFBZ9NAHFSAMRBPEYGPRGKW' b'WTWACZOAPEOECUO9OTMGABJVAIICIPXGSXACVINSYEQFTRCQPCEJXZCY9XZWVWVJRZ' b'CYEYNFUUBKPWCHICGJZXKE9GSUDXZYUAPLHAKAHYHDXNPHENTERYMMBQOPSQIDENXK' b'LKCEYCPVTZQLEEJVYJZV9BWU999999999999999999999999999FFL999999999999' b'9999999999999RJQGVD99999999999A99999999USGBXHGJUEWAUAKNPPRHJXDDMQV' b'YDSYZJSDWFYLOQVFGBOSLE9KHFDLDYHUYTXVSFAFCOCLQUHJXTEIQRNBTLHEGJFGVF' b'DJCE9IKAOCSYHLCLWPVVNWNESKLYAJG9FGGZOFXCEYOTWLVIJUHGY9QCU9FMZJY999' b'9999HYBUYQKKRNAVDPVGYBTVDZ9SVQBLCCVLJTPEQWWOIG9CQZIFQKCROH9YHUCNJT' b'SYPBVZVBNESX999999D9TARGPQTNIYRZURQGVHCAWEDRBJIIEJIUZYENVE9LLJQMXH' b'GSUUYUCPSOWBCXVFDCHHAZUDC9LUODYWO' ) self.adapter.seed_response( 'getTrytes', { 'duration': 99, 'trytes': [binary_type(transaction_trytes)], }, ) transaction = Transaction.from_tryte_string(transaction_trytes) mock_get_bundles = mock.Mock(return_value={ 'bundles': [Bundle([transaction])], }) mock_get_latest_inclusion = mock.Mock(return_value={ 'states': { transaction.hash: True, }, }) with mock.patch( 'iota.crypto.addresses.AddressGenerator.create_iterator', create_generator, ): with mock.patch( 'iota.commands.extended.get_bundles.GetBundlesCommand._execute', mock_get_bundles, ): with mock.patch( 'iota.commands.extended.get_latest_inclusion.GetLatestInclusionCommand._execute', mock_get_latest_inclusion, ): response = self.command( seed=Seed.random(), inclusionStates=True, # To keep the test focused, only retrieve a single # transaction. start=0, stop=1, ) bundle = response['bundles'][0] # type: Bundle self.assertTrue(bundle[0].is_confirmed)
def extract_data(bundle): json = Bundle.as_json_compatible(bundle) data = json[0]["signature_message_fragment"] return data
async def test_unspent_inputs_with_change_address(self): """ The bundle has unspent inputs, so it uses the provided change address. """ self.adapter.seed_response( command=GetBalancesCommand.command, response={ 'balances': [101], 'duration': 86, }, ) pmt_result =\ await self.command( transfers = [ ProposedTransaction( address = Address(self.trytes_1), value = 42, ), ], multisigInput = MultisigAddress( digests = [self.digest_1, self.digest_2], trytes = self.trytes_2, ), changeAddress = Address(self.trytes_3), ) bundle = Bundle.from_tryte_strings(pmt_result['trytes']) self.assertEqual(len(bundle), 6) # Spend Transaction txn_1 = bundle[0] self.assertEqual(txn_1.address, self.trytes_1) self.assertEqual(txn_1.value, 42) # Input 1, Part 1 of 4 txn_2 = bundle[1] self.assertEqual(txn_2.address, self.trytes_2) self.assertEqual(txn_2.value, -101) self.assertEqual(txn_2.signature_message_fragment, Fragment(b'')) # Input 1, Part 2 of 4 txn_3 = bundle[2] self.assertEqual(txn_3.address, self.trytes_2) self.assertEqual(txn_3.value, 0) self.assertEqual(txn_3.signature_message_fragment, Fragment(b'')) # Input 1, Part 3 of 4 txn_4 = bundle[3] self.assertEqual(txn_4.address, self.trytes_2) self.assertEqual(txn_4.value, 0) self.assertEqual(txn_4.signature_message_fragment, Fragment(b'')) # Input 1, Part 4 of 4 txn_5 = bundle[4] self.assertEqual(txn_5.address, self.trytes_2) self.assertEqual(txn_5.value, 0) self.assertEqual(txn_5.signature_message_fragment, Fragment(b'')) # Change txn_6 = bundle[5] self.assertEqual(txn_6.address, self.trytes_3) self.assertEqual(txn_6.value, 59)
def setUpClass(self): # This is a valid bundle taken from the Tangle self.bundle = Bundle.from_tryte_strings([ TransactionTrytes( '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999GTSOCZLYYATDVK9FYRZXRFEHYUWTSXNALBGHO9T9GHANN' '9YTJIZHOBWZHYSLDRTIVSYRRBUJZFUKWVNJAJSNA99999999999999999999999FBNGLE9BE' 'AT9CYCLUX999999999RFAVOBD99999999999B99999999BGNBAIUZAHWWAIHAWHXIDGYQYKI' 'LEWDCBQXYBNQBFNPOIICLCJKHSX9KLPECYBGWW9CGILRKTVEYTL99AAVSD99RCNCYGIVIRVI' 'TNVOVQNQE9RFJIRAXCEXQEHEXQEKFXSDQVBQGJQWBRTRSAUPMXJLMFKUJKZ9999UIBLZWXJQ' 'DMZCPEQRLSFYJLEPIFTOCY9ODVKIYAMXMKYKHFWKEHNGLVKEYDGR9GOXWWNXLOCQFD999999' 'TANGLE9BEAT9CYCLUX999999999FIAMTJGOF999999999MMMMMMMMMZCJOZALASXIERYTDLY' 'WMZTJF9HQ'), TransactionTrytes( '9PTKKTOZFZBKCJTYHMKZZDRHCOYXHOTDQY9ALYIBNGD9UDPTUKPHJBORIICRNLDTECKLGPOGE' 'VQIVFHIYI9UUYWYEKGRDDGAAXD9EMFSKX9TDWGGPKTIXBCWQKPERPUIRYEEYXYPXGHBSRGQAH' 'ZOIBPERAWSCMIFJZGYAFQ9XBVYDXVJAXXX9XPTXJTSDMJSLNCBACGQ9CHVCYMEKOKSEBRUGTX' 'KMU9HLWRNWOZJGIOIKLPZEHDZKCQXFDMYOA9DRK9CJVRQSWZSDUWDCXWFPZIL9PJDQUQNMMBM' 'STGMOFCXKKCRZKDCRCBYSVDSKXTDKFBYIRVSTIVHGWTBFRGNNAYXZBVNSZDQDQRSJBNMBRZTG' 'VDWYAHHFEMSWF9CLSZPQYKFD9MOIR9CUZCPQAGBZSPSCRHSYVDKX9ZVEQONHOO9EAAHZSTHAW' 'SLSVI9HSOYKIGDWSKXCHHPFXMKCIBEASGQXHEIGOAETCBLHWPUBSLMELCUVARTPHGOG9BEQTM' 'NHA9MJHCRVNKXZTZTMEMSHFKJMWNBXLBLMVJDONO9JDYALFCBQ9GELAXSOEGOLNCPYGSKWRFF' 'IZNUGVHECQKRIZ9NTCPAXEKIAZLTXCBM9PJCOKSFDL99YPEVKOMWEXED9IAAOVPZLLFBZHVAM' 'DXEXCAZBGKWVQCXPFSEUNTPYVSLPEYKCTTGPVBSXQYFVWFUCGYLARMB9HA9PTRXAXKEOQLVXQ' 'TTHYZEXSOLFSEHMVJ9QOLMBGFHPTEQAYDZWSAPADJSSHTBWOZGVSLLPTMOLFZWUQFVKJZQPMZ' 'T9QACMCOEKJVWBOSKQHUTGLHAWMQHPDHCZEDKVUTYVMZCSMR9YPLRJGLUNTRGSEXLNBYJXLAR' 'MWWAWVPLZXYAYACMJCNYWISCHBMQAAMGTCFOZN9OZCITSFGBUJVERM9FRYHJYVKXLBALTHKWM' 'JMECDKGPKNWFWNHXAFQ9UEWBTUJADYFFMD9WAWE9PYEZIHGO9DSRBLLHCKIIVLHRPYR9UIYRN' 'VDYAL9Y9AEPVYOKBEDXJDYYBKEOLOAZCNLSBOULLOHEYAAJBZDNTNKVULUSUAME9LTAIEEUJV' 'QRVFXSDDTNDMNRSLAXKZTRCAGLIDVJJVGEJWSGDIH9HGVHDKLXVEEFTHAMLSUVEDMMVSDRPOI' 'UJTSNZJVMGBCFZYOMUSARYNXTRMFVMZOCZYPTBSOZUXXSYBRKKLZEAQDPNGLYAKAWTSEJKLBK' 'NASQQPZAB9MKOUZN9TO9ZYUVSTAPWGTMGO9ZARUWBVQT9ZLHAYEVJM9FNJCQNSBIRZ9AIXZEX' 'N9QMLPZBHTVNVKRPIXMQIA9OAWQFPNHMXOOPEUJQCKXZQOOYLMMJXXQAIVHRLGDKLGBOSKERQ' 'ZYNQOTVJW9IKMWZSORHMXFNOLSR9SIKBNTOANAZBGPGIPVVIFYWTUMATZAJPMUGYVITWCBBSQ' 'RVAY9MXJCECVTYASSAVUGKKQBDXYVWLTSL9HCAD9NUEWEHQXQUCDJC9WPVAZEDLTGTLZXUUOH' 'WCEUXCDYHATVRSJXJNLWCPEOENOBLXHTDOXSQCIDSEOHZHWBAYJV9ALDOBYMLXKNUQYQTEYAW' 'ZFSWGQOAHFXHZDBNCJDIJXRJDGRIOPCLPGPLG9AVFGQQBWPKNJROPIQDLXHNDGWGZOVBXHRBP' 'JQ9YHIJ9MNJFFLDTVLXJA9EBVPGVIAIHCDDHHTNX9KZARELDIZVQYUQGCPPCRTU9CDUXCVBYZ' 'RAUJDUMGGTKKOFQQTEGXRQKYPQTGHBGRCJ9IENKLNBIZNRSPVQ9VBKQLCG9YPYBEKJEYNAIDJ' 'PHABZJXBWHZLMADR9SDEWICFGRRTVAGZYCMJ9CANUSGIUKKHWUSWBQIBC9TXONXYDURJJWWE9' 'FKPPRWEJVWVJVKFKLMD9HCYASRUYCZPKM9VUCLOUVBYSMWIRFYJMTNOYXNKLNDWZJSRRZKLQL' 'YCODRSAKLMIRSPFYOANY9DUCYZYLEXDTGEJAKUDFWZNEGIBLMXZTW9OKF9SQGNNMHMUWIICFX' 'LFQMSLLSVJIMDEEWGOG9PDAPTZCRAL9TJRFPIOPMSFJOTLPRMEOUWGLTTXODGD9LSDJBTKX9Y' '9JNNIYNERDRQWJGICGHUFJCMGBBUZWLHQJUSUMUXNWRNIVHSFSRGMBMO9VTBGBBFOMHGNZQYI' 'OIIITMJDZLCJGNUWRJPJKOSSKRLUMGDXNRZFUFTZTSKXEZOCHUEWBONL9OBRYNWLPKSGCFE9W' 'TBVEXQHMZ99999999999999999999999999999999999999999999999999RFAVOBD99A9999' '9999B99999999BGNBAIUZAHWWAIHAWHXIDGYQYKILEWDCBQXYBNQBFNPOIICLCJKHSX9KLPEC' 'YBGWW9CGILRKTVEYTL99AYUMYMXIZRU9IIWNDROROZOINKOLXPOFCRZZTXAWDXUKVV9LMEMNG' 'HYZUMAPCESBINZGITBMIOQYX99999UIBLZWXJQDMZCPEQRLSFYJLEPIFTOCY9ODVKIYAMXMKY' 'KHFWKEHNGLVKEYDGR9GOXWWNXLOCQFD999999999999999999999999999999999ZS9MTJGOF' '999999999MMMMMMMMMMJVAHLRNJKJGTOLKSKNZWBTJNQP'), TransactionTrytes( 'M9STFJDJXSROWSPZTZXDYCWQDOQPBPAGATRY9SOXIXJOQL99OMWXPNXKCKJHHRPGWEDBLT9EO' 'IBTFDKZYXFMELEBQABMPIXUKYZKONEQESB9XHXYMQBULQVQLEEPHCZSFSMJKDGKEDRVBKLFKZ' 'JFNKLZWQPMTQGJKWQNAN9NQRKGWHEMIVZNODTNQNPXOTISDNWT9WZKC9DGLYWHUD9EQ9VTZRF' 'YUYU9BDHZULDGNUGUOUUXQTXZJVCBPZWYVTBEWVUJAOCZVNUJNMSMSVN9CPXWDSFCMRSWAMLP' 'AJRAEGSCOPLWYEGWPKKSXYJSBNLGMBLDEQ9NQEM9XDCSYZLUHLLEICKFHBFPIYDNGEZJEJXBE' '9HJGFRMHAHNXIGDDZRPAOTUZPEEUGLZYDEJYIYFCMOUNRLZFBYC9BDPWUVIR9DE9QGBEPVMDL' 'J9HUDJMGVDQNIDQQTCRXLCPNSLZXSUUPNKUCDHKWCMQ9HPVWXSZXKGXCDKX9BXNOFDUYUBBGD' 'DOJEZISFJLFUMKJJHXNBMLUWZWBQ9QDITUUZWHFEXQVAAKBUEXCO9XFBPAD9IKEODAPALAGSG' 'XFDLORKHCXSPINKO9HSJF9BXUIBRXNUX9APPTPIUYXVVWIYXGARPKDYNEGQXPWYCRAPZMZYKW' 'ICPYJWUEBIBPTXNJTBSSQDFKH9ZFQXNNH9MUTVKEYQIYOJTLFJLAQOFZFIVMTHESCNDLGXZXA' 'OWHXPEDVVBFJHIKCNFGPLUZQBYVRRMYCIAJOOJINAHSATUVCLQNMOAERIAJESBZOABTMBMJVQ' 'DVBMLDBBONGRW9QJUAXS9LQWRRKH9PLQUEVUDHWRZFP9FPYSWOQQRINOCHSJYPVKEUQPDOHXQ' 'WZFKOLZFXYQF9WDHKTHBVMACJMNUVYFLDBCCCHKTBJINNBPKVXYTVLVGADMYEYVLYROARFBWE' 'ATEIHEENZVRNOJRJYIMQJRAOFKUWSDKFTNNDTLCFHXQNRFEUFJN9GFFJXWDPKIQUQBXDARMRK' 'LSGUSATHVZMJSXFTWIJPCWNG9UWDGQYUGPMSGJSZBCSUPAKQKIHP9EGIXNRNMDGUVJNVMW9RL' 'TOHXUXI9UZTCRLVMMREWFSRUOBKFVQYH9PUVOWATYNDULLZ9RCBHDUVNJDMOJETQ9H9RKOSQF' 'XEVDVVJNZZSMFMLLQJTYXAALRIHQJWDCZYFZBLODYGYUP9XGPZVILG9WBGOVVYRUTHDGF9TRZ' 'GSFIYHAAAGXJTJKRG9ZYBFDSRQPQAOIJHDENVQAPJMBLOIVUZIGHMVXHBKZOFUJVEWCZJNCTS' 'TDEPQTYCPGGG9ZEDEYTSDBOMLOO9QO9LMJKNRXHLWNJUOLVNGXMLNHXZVKTRJGDD9CERBOTKR' 'EDGEGUQDBFIKPYPOXXF9KLYAX9SDCCDTCFULSOZRYJSORRZUUN9CCNRQKTCDCOGIYHAHWYBUX' 'EYVIJTGXCPGIGBFQWOTJX9APYNDCPQ9FSNXUZF9MDRLZIJSYDGYKBQGWTQLEKZSATDKVWFFMH' 'QNTMNWWJNBKVGI9QDXYYWOFAKI9OZRBOWMZZHLXUJQKIICFTBZAHUTZFIZIAUO9CWSTYMGZPO' 'PBKIO9ZYNSRHXCCIMKD9SPDQNXALFLNTXWVVYDAFHWLD9YSDGGRQJUBWZXQHVULYVDON9WADY' 'XPEVAGKTXIUTDRMLE9TTKD9TSHXFHQSOLHOCQ9SYWJWTOC99GAKHRSREJKHCBLYSHPOEYJNYX' 'IYNSQITTFSMKFL9HRNEKDZSJSYEBJACGTVBRVQGUREAYZEIQQIGWVRWIWSDGBRLAMPKQGZCEO' 'JPHANGFVYRXZJCDO9MGKBPYPQYVHQWDJVSUKA9VGLJELXFJKTNMQYZYGBHNFLGETZ9SWLDRNO' 'OUCAWNFOTBFICNEQJNPAZABLPOR99DPWTZZWLIRA9MFPXXHMJL9QWVJOAPYA9REAHBATJYJYJ' 'DYAGCKFDRSVTXMFFIBDPIBXBINGXTWMM9PSRVAKQEEQGRDJNOHKJDCCFBZZRLIVXPGEZYAV9G' 'CUGCATAQLMSOABNYLSNSTRPOGIRMKCGDDITKO9TEVOWPRGQHJDYWPZTZ9RVLPWGFDZOZICSUZ' 'AUPZJVTXCMUEADAKPZMNOTHLMGDJKTQWJQBK9TIGUTLDWYEPNDLJLDDYHQUWNLLH9MJUFAQYI' 'OIIITMJDZLCJGNUWRJPJKOSSKRLUMGDXNRZFUFTZTSKXEZOCHUEWBONL9OBRYNWLPKSGCFE9W' 'TBVEX999999999999999999999999999999999999999999999999999999RFAVOBD99B9999' '9999B99999999BGNBAIUZAHWWAIHAWHXIDGYQYKILEWDCBQXYBNQBFNPOIICLCJKHSX9KLPEC' 'YBGWW9CGILRKTVEYTL99AUIBLZWXJQDMZCPEQRLSFYJLEPIFTOCY9ODVKIYAMXMKYKHFWKEHN' 'GLVKEYDGR9GOXWWNXLOCQFD999999IFJ9JLPZON9CZJWMKJWPMUWHKOYTUOSBWQYCTCGBXAJG' 'T9KRVDDLBCNXFYKRXDEKJYQMTAMYJXJRA9999999999999999999999999999999BGYMTJGOF' '999999999MMMMMMMMMOGZMHCGFJIGGC9JYILNUCHZSDGV') ]) self.single_tx_bundle = Bundle.from_tryte_strings([ TransactionTrytes( 'VBCDFDTCADEAXCDDGDIDADEASCCD9DCDFDEAGDXCHDEAPCADTCHDQAEARCCDBDGDTCRCHDTCH' 'DIDFDEAPCSCXCDDXCGDRCXCBDVCEATC9DXCHDSAEASBBDEABDCDBDEA9DXCQCTCFDCDEAXCSC' 'EABDXCQCWCEAUCPCRCXC9DXCGDXCGDEAXCADDDTCFDSCXCTCHDEATCIDEAGDTCSCEAGDPCDDX' 'CTCBDSAEABCTCSCEASCXCVCBDXCGDGDXCADEA9DXCVCID9DPCEAXCBDEATCGDHDEAADPC9DTC' 'GDIDPCSCPCEA9DCDQCCDFDHDXCGDSAEAOBHDXCPCADEAJDPCFDXCIDGDEAADCD9DTCGDHDXCT' 'CEABDID9D9DPCEADDFDTCHDXCIDADEAHDXCBDRCXCSCIDBDHDSAEAXBPCADEAJDTCWCXCRCID' '9DPCEA9DPCRCXCBDXCPCEA9DXCQCTCFDCDSAEAMBIDFDPCQCXCHDIDFDEAXCBDEACDFDBDPCF' 'DTCEA9DTCCDSAEAMBFDPCGDEATCIDEASCCD9DCDFDEAEDIDXCGDEAHDCDFDHDCDFDEAXCADDD' 'TCFDSCXCTCHDEAPC9DXCEDIDTCHDSAEANBCDBDTCRCEAPCEAHDTC9D9DIDGDEATCFDPCHDSAE' 'AXBIDBDRCEAXCSCEAXCPCRCID9DXCGDEASCIDXCSA99999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999MZW' 'YYLQNAKEWITJSJZJCPFZWMEYGOVYOKUZYUWMUDLGAAAHTBYNQQNGHLUMSGZNQCJCHOULIZSDC' 'ATEXD999999999999999999999999999VHURLINTERFACE9TEST9TX999999KGVOBD9999999' '9999999999999DLWTLGSTHZKRDSIRWCZ9HCJWNUJBKTWHCBZGRIFTASCTBIBZZNNWFVGHEGJB' 'EWWXKRFOXD9GLTXPFGRBY9999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999999999999999999999999999999999999999' '9999999999999999999999999999999999999CCURLINTERFACE9TEST9TX99999999999999' '999999999999999999999999999999999999999999999') ]) self.trunk = TransactionHash('TRUNKTXHASH9TESTVALUEONLY') self.branch = TransactionHash('BRANCHTXHASH9TESTVALUEONLY') # Result is reused accross tests, no need to calculate it # multiple times. # Mock away current time calculation, timestamps are imaginary from # this point on. self.before = 99 with patch('pow.ccurl_interface.get_current_ms', MagicMock(return_value=100)): self.powed = ccurl_interface.attach_to_tangle( self.bundle.as_tryte_strings(), self.branch, self.trunk, mwm=14) self.after = 101 self.powed_bundle = Bundle.from_tryte_strings(self.powed)
def test_multiple_transactions(self): """ Getting a bundle that contains multiple transactions. """ bundle = Bundle.from_tryte_strings([ TransactionTrytes( b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999WUQXEGBVIECGIWO9IGSYKWWPYCIVUJJGSJPWGIAFJPYSF9NSQOHWAHS9P' b'9PWQHOBXNNQIF9IRHVQXKPZW999999999999999999999999999XZUIENOTTBKJMDP' b'RXWGQYG9PWGTHNLFMVD99A99999999A99999999PDQWLVVDPUU9VIBODGMRIAZPGQX' b'DOGSEXIHKIBWSLDAWUKZCZMK9Z9YZSPCKBDJSVDPRQLJSTKUMTNVSXBGUEHHGAIWWQ' b'BCJZHZAQOWZMAIDAFUZBVMUVPWQJLUGGQKNKLMGTWXXNZKUCBJLEDAMYVRGABAWBY9' b'999MYIYBTGIOQYYZFJBLIAWMPSZEFFTXUZPCDIXSLLQDQSFYGQSQOGSPKCZNLVSZ9L' b'MCUWVNGEN9EJEW9999XZUIENOTTBKJMDPRXWGQYG9PWGTXUO9AXMP9FLMDRMADLRPW' b'CZCJBROYCDRJMYU9HDYJM9NDBFUPIZVTR'), # Well, it was bound to happen sooner or later... the ASCII # representation of this tryte sequence contains a very naughty # phrase. But I don't feel like doing another POW, so... enjoy. TransactionTrytes( b'NBTCPCFDEACCPCBDVC9DTCQAJ9RBTC9D9DCDQAEAKDCDFD9DSCFAJ9VBCDJDTCQAJ9' b'ZBMDYBCCKB99999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999999999999999999' b'999999999999999999999999999999999999999999999999999SYRABNN9JD9PNDL' b'IKUNCECUELTOHNLFMVD99999999999A99999999PDQWLVVDPUU9VIBODGMRIAZPGQX' b'DOGSEXIHKIBWSLDAWUKZCZMK9Z9YZSPCKBDJSVDPRQLJSTKUMTNVSXFSEWUNJOEGNU' b'I9QOCRFMYSIFAZLJHKZBPQZZYFG9ORYCRDX9TOMJPFCRB9R9KPUUGFPVOWYXFIWEW9' b'999BGUEHHGAIWWQBCJZHZAQOWZMAIDAFUZBVMUVPWQJLUGGQKNKLMGTWXXNZKUCBJL' b'EDAMYVRGABAWBY9999SYRABNN9JD9PNDLIKUNCECUELTOQZPSBDILVHJQVCEOICFAD' b'YKZVGMOAXJRQNTCKMHGTAUMPGJJMX9LNF'), ]) for txn in bundle: self.adapter.seed_response('getTrytes', { 'trytes': [txn.as_tryte_string()], }) self.adapter.seed_response( 'getTrytes', { 'trytes': [ 'SPAMSPAMSPAM999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999999999999999999' '999999999999999999999999999999999999999999999999999JECDITWO9999999' '999999999999ONLFMVD99999999999999999999VVCHSQSRVFKSBONDWB9EAQEMQOY' 'YRBIZHTBJLYNAVDHZPUZAZ9LYHXWKBEJ9IPR9FAMFLT9EEOHVYWUPRHHSRCILCLWFD' 'GBYBFFOKMCSAPVD9VGZZRRGBLGMZMXD9RMZQDBLMGN9BATWZGULRBCYQEIKIRBPHC9' '999KTLTRSYOWBD9HVNP9GCUABARNGMYXUZKXWRPGOPETZLKYYC9Z9EYXIWVARUBMBM' 'BPXGORN9WPBLY99999ZRBVQWULRFXDNDYZKRKIXPZQT9JJJH9FZU9PVWZJWLXBPODP' 'EHMKTTAGEPLPHUQCZNLDSHERONOMHJCOI' ], }) response = self.command(transaction=TransactionHash( b'TOYJPHKMLQNDVLDHDILARUJCCIUMQBLUSWPCTIVA' b'DRXICGYDGSVPXFTILFFGAPICYHGGJ9OHXINFX9999'), ) self.maxDiff = None self.assertListEqual( response['bundles'][0].as_json_compatible(), bundle.as_json_compatible(), )
class BundleTestCase(TestCase): 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), ]) def test_get_messages_errors_drop(self): """ Decoding messages from a bundle, with ``errors='drop'``. """ messages = self.bundle.get_messages('drop') self.assertEqual(len(messages), 3) self.assertEqual(messages[0], 'Hello, world!') # noinspection SpellCheckingInspection self.assertEqual( messages[1], ''' "Good morning," said Deep Thought at last. "Er... Good morning, O Deep Thought," said Loonquawl nervously. "Do you have... er, that is..." "... an answer for you?" interrupted Deep Thought majestically. "Yes. I have." The two men shivered with expectancy. Their waiting had not been in vain. "There really is one?" breathed Phouchg. "There really is one," confirmed Deep Thought. "To Everything? To the great Question of Life, the Universe and Everything?" "Yes." Both of the men had been trained for this moment; their lives had been a preparation for it; they had been selected at birth as those who would witness the answer; but even so they found themselves gasping and squirming like excited children. "And you're ready to give it to us?" urged Loonquawl. "I am." "Now?" "Now," said Deep Thought. They both licked their dry lips. "Though I don't think," added Deep Thought, "that you're going to like it." "Doesn't matter," said Phouchg. "We must know it! Now!" "Now?" enquired Deep Thought. "Yes! Now!" "All right," said the computer and settled into silence again. The two men fidgeted. The tension was unbearable. "You're really not going to like it," observed Deep Thought. "Tell us!" "All right," said Deep Thought. "The Answer to the Great Question..." "Yes?" "Of Life, the Universe and Everything..." said Deep Thought. "Yes??" "Is..." "Yes?!" "Forty-two," said Deep Thought, with infinite majesty and calm. ''', ) self.assertEqual(messages[2], 'I can haz change?') def test_get_messages_errors_strict(self): """ Decoding messages from a bundle, with ``errors='strict'``. """ with self.assertRaises(UnicodeDecodeError): self.bundle.get_messages('strict') def test_get_messages_errors_ignore(self): """ Decoding messages from a bundle, with ``errors='ignore'``. """ messages = self.bundle.get_messages('ignore') self.assertEqual(len(messages), 4) # The only message that is treated differently is the invalid one. self.assertEqual(messages[0], '祝你好运\x15') def test_get_messages_errors_replace(self): """ Decoding messages from a bundle, with ``errors='replace'``. """ messages = self.bundle.get_messages('replace') self.assertEqual(len(messages), 4) # The only message that is treated differently is the invalid one. self.assertEqual(messages[0], '祝你好运�\x15')
]).get('trytes') gtta_response = api.get_transactions_to_approve(3) trunk = gtta_response.get('trunkTransaction') branch = gtta_response.get('branchTransaction') attached_original_trytes = api.attach_to_tangle(trunk, branch, original_trytes).get('trytes') # So we have the original bundle attached, time to construct the new one # We need to re-attach, but take special care, so we dont use the api, rather we do it ourself re_attached_trytes = custom_attach(attached_original_trytes, 9) original_bundle = Bundle.from_tryte_strings(attached_original_trytes) re_attached_bundle = Bundle.from_tryte_strings(re_attached_trytes) pprint('Original bundle is:') pprint(original_bundle.as_json_compatible()) pprint('Reattached bundle is:') pprint(re_attached_bundle.as_json_compatible()) #api.broadcast_and_store(attached_original_trytes) api.broadcast_and_store(re_attached_trytes) # bundles # BJRYHWKLREEUQCAZSUQFDNQAIL9LFRBZVEFFWPQZ99GNKATZBUZKFJYJIRYTFBPPESFJYDQRAYHNHH9LW good # UYBVN9EZKNA9KGGCSILJJGRTNGI9ZHVIUEYB9VXZXHLKZBTFGPHGJPJ9OHCUILSRBAA9XYSDKIXHYVLJW bad
def attach_to_tangle( bundle_trytes, # Iterable[TryteString] trunk_transaction_hash, # TransactionHash branch_transaction_hash, # TransactionHash mwm=14): # Int """ Attaches the bundle to the Tangle by doing Proof-of-Work locally. No connection to the Tangle is needed in this step. :param bundle_trytes: List of TryteString(s) that contain raw transaction trytes. :param trunk_transaction_hash: Trunk transaction hash obtained from an iota node. Result of the tip selection process. :param branch_transaction_hash: Branch transaction hash obtained from an iota node. Result of the tip selection process. :param mwm: Minimum Weight Magnitude to be used during the PoW. Number of trailing zero trits in transaction hash. :returns: The bundle as a list of transaction trytes (TryteStrings). Attachment timestamp and nonce included. """ previoustx = None # Construct bundle object bundle = Bundle.from_tryte_strings(bundle_trytes) # Used for checking hash trailing_zeros = [0] * mwm # reversed, beause pyota bundles look like [tx0,tx1,...] # and we need the head (last) tx first for txn in reversed(bundle.transactions): # Ccurl lib sometimes needs a kick to return the correct powed trytes. # We can check the correctness by examining trailing zeros of the # transaction hash. If that fails, we try calculating the pow again. # Use `max_iter` to prevent infinite loop. Calculation error appears # rarely, and usually the second try yields correct result. If we reach # `max_iter`, we raise a ValueError. max_iter = 5 i = 0 # If calculation is successful, we break out from the while loop. while i != max_iter: # Fill timestamps txn.attachment_timestamp = get_current_ms() txn.attachment_timestamp_upper_bound = (math.pow(3, 27) - 1) // 2 # Determine correct trunk and branch transaction if (not previoustx): # this is the head transaction if txn.current_index == txn.last_index: txn.branch_transaction_hash = branch_transaction_hash txn.trunk_transaction_hash = trunk_transaction_hash else: raise ValueError( 'Head transaction is inconsistent in bundle') else: # It is not the head transaction txn.branch_transaction_hash = trunk_transaction_hash txn.trunk_transaction_hash = previoustx # the previous transaction # Let's do the pow locally txn_string = txn.as_tryte_string().__str__() # returns a python unicode string powed_txn_string = get_powed_tx_trytes(txn_string, mwm) # construct trytestring from python string powed_txn_trytes = TryteString(powed_txn_string) # Create powed txn object # This method calculates the hash for the transaction powed_txn = Transaction.from_tryte_string(trytes=powed_txn_trytes) previoustx = powed_txn.hash # put that back in the bundle bundle.transactions[txn.current_index] = powed_txn # Check for inconsistency in hash hash_trits = powed_txn.hash.as_trits() if hash_trits[-mwm:] == trailing_zeros: # We are good to go, exit from while loop break else: i = i + 1 logger.info( 'Ooops, wrong hash detected in try' ' #{rounds}. Recalculating pow... '.format(rounds=i)) # Something really bad happened if i == max_iter: raise with_context( exc=ValueError( 'PoW calculation failed for {max_iter} times.' ' Make sure that the transaction is valid: {tx}'.format( max_iter=max_iter, tx=powed_txn.as_json_compatible())), context={ 'original': txn, }, ) return bundle.as_tryte_strings()
def setUp(self): super(BundleTestCase, self).setUp() 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # This transaction has a message that fits into a single # fragment. Transaction( signature_message_fragment = Fragment.from_unicode('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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), 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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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_unicode('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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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_unicode('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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), # 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_unicode('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 = Nonce(b''), timestamp = 1485020456, trunk_transaction_hash = TransactionHash(b''), tag = Tag(b''), attachment_timestamp = 1485020456, attachment_timestamp_upper_bound = 1485020456, attachment_timestamp_lower_bound = 1485020456, ), ])
def execute(self, api, **arguments): # type: (Iota, ...) -> int channel_key_index = arguments['channel_key_index'] # type: int count = arguments['count'] # type: int depth = arguments['depth'] # type: int dry_run = arguments['dry_run'] # type: bool mam_encrypt_path = arguments['mam_encrypt_path'] # type: Text min_weight_magnitude = arguments['min_weight_magnitude'] # type: int message_encoding = arguments['message_encoding'] # type: Text message_file = arguments['message_file'] # type: Optional[Text] security_level = arguments['security_level'] # type: int start = arguments['start'] # type: int if message_file: with codecs.open(message_file, 'r', message_encoding) as f_: # type: codecs.StreamReaderWriter message = f_.read() else: self.stdout.write( 'Enter message to send. Press Ctrl-D on a blank line when done.\n\n', ) message = self.stdin.read().strip() self.stdout.write('\n') # Generating the encrypted message may take a little while, so we # should provide some feedback to the user so that they know that # their input is being processed (this is especially important if # the user typed in their message, so that they don't press ^D # again, thinking that the program didn't register the first one). self.stdout.write('Encrypting message...\n') proc =\ run( args = [ # mam_encrypt.js mam_encrypt_path, # Required arguments binary_type(api.seed), message, # Options '--channel-key-index', text_type(channel_key_index), '--start', text_type(start), '--count', text_type(count), '--security-level', text_type(security_level), ], check = True, stdout = PIPE, stderr = self.stderr, ) # The output of the JS script is a collection of transaction # trytes, encoded as JSON. filter_ =\ f.FilterRunner( starting_filter = f.Required | f.Unicode | f.JsonDecode | f.Array | f.FilterRepeater( f.ByteString(encoding='ascii') | Trytes(result_type=TransactionTrytes) ), incoming_data = proc.stdout, ) if not filter_.is_valid(): self.stderr.write( 'Invalid output from {mam_encrypt_path}:\n' '\n' 'Output:\n' '{output}\n' '\n' 'Errors:\n' '{errors}\n'.format( errors = pformat(filter_.get_errors(with_context=True)), mam_encrypt_path = mam_encrypt_path, output = proc.stdout, ), ) return 2 transaction_trytes = filter_.cleaned_data # type: List[TransactionTrytes] bundle = Bundle.from_tryte_strings(transaction_trytes) if dry_run: self.stdout.write('Transactions:\n\n') self.stdout.write(json.dumps(bundle, cls=JsonEncoder, indent=2)) else: api.send_trytes( depth = depth, trytes = transaction_trytes, min_weight_magnitude = min_weight_magnitude, ) self.stdout.write('Message broadcast successfully!\n') self.stdout.write( 'Bundle ID: {bundle_hash}\n'.format( bundle_hash = bundle.hash, ), ) return 0