Beispiel #1
0
  def test_sign_inputs_security_level(self):
    """
    You may include inputs with different security levels in the same
    bundle.
    """
    # noinspection SpellCheckingInspection
    self.bundle.add_transaction(
      ProposedTransaction(
        address =
          Address(
            b'TESTVALUE9DONTUSEINPRODUCTION99999XE9IVG'
            b'EFNDOCQCMERGUATCIEGGOHPHGFIAQEZGNHQ9W99CH',
          ),

        value = 84,
      ),
    )

    self.bundle.add_inputs([
      self.input_4_bal_eq_42_sl_2,
      self.input_5_bal_eq_42_sl_3,
    ])

    self.bundle.finalize()

    self.bundle.sign_inputs(KeyGenerator(self.seed))

    # Quick sanity check.
    self.assertEqual(len(self.bundle), 6)

    # The spending transaction does not have a signature.
    self.assertEqual(
      self.bundle[0].signature_message_fragment,
      Fragment(b''),
    )

    # The signature fragments are really long, and we already have unit
    # tests for the signature fragment generator, so to keep this test
    # focused, we are only interested in whether a signature fragment
    # gets applied.
    #
    # References:
    #   - :py:class:`test.crypto.signing_test.SignatureFragmentGeneratorTestCase`
    for i in range(1, len(self.bundle)):
      if self.bundle[i].signature_message_fragment == Fragment(b''):
        self.fail(
          "Transaction {i}'s signature fragment is unexpectedly empty!".format(
            i = i,
          ),
        )
Beispiel #2
0
  def test_sign_inputs(self):
    """
    Signing inputs in a finalized bundle, using a key generator.
    """
    # noinspection SpellCheckingInspection
    self.bundle.add_transaction(ProposedTransaction(
      address =
        Address(
          b'TESTVALUE9DONTUSEINPRODUCTION99999QARFLF'
          b'TDVATBVFTFCGEHLFJBMHPBOBOHFBSGAGWCM9PG9GX'
        ),

      value = 42,
    ))

    self.bundle.add_inputs([self.input_1_bal_eq_40, self.input_2_bal_eq_2])
    self.bundle.finalize()

    self.bundle.sign_inputs(KeyGenerator(self.seed))

    # Quick sanity check:
    # 1 spend + 2 inputs (security level 1) = 3 transactions.
    # Applying signatures should not introduce any new transactions
    # into the bundle.
    #
    # Note: we will see what happens when we use inputs with different
    # security levels in the next test.
    self.assertEqual(len(self.bundle), 3)

    # The spending transaction does not have a signature.
    self.assertEqual(
      self.bundle[0].signature_message_fragment,
      Fragment(b''),
    )

    # The signature fragments are really long, and we already have unit
    # tests for the signature fragment generator, so to keep this test
    # focused, we are only interested in whether a signature fragment
    # gets applied.
    #
    # References:
    #   - :py:class:`test.crypto.signing_test.SignatureFragmentGeneratorTestCase`
    for i in range(1, len(self.bundle)):
      if self.bundle[i].signature_message_fragment == Fragment(b''):
        self.fail(
          "Transaction {i}'s signature fragment is unexpectedly empty!".format(
            i = i,
          ),
        )
Beispiel #3
0
  def test_sign_input_at_single_fragment(self):
    """
    Signing an input at the specified index, only 1 fragment needed.
    """
    # Add a transaction so that we can finalize the bundle.
    # noinspection SpellCheckingInspection
    self.bundle.add_transaction(ProposedTransaction(
      address =
        Address(
          b'TESTVALUE9DONTUSEINPRODUCTION99999QARFLF'
          b'TDVATBVFTFCGEHLFJBMHPBOBOHFBSGAGWCM9PG9GX'
        ),

      value = 42,
    ))

    self.bundle.add_inputs([self.input_0_bal_eq_42])
    self.bundle.finalize()

    private_key =\
      KeyGenerator(self.seed).get_key_for(self.input_0_bal_eq_42)

    self.bundle.sign_input_at(1, private_key)

    # Only 2 transactions are needed for this bundle:
    # 1 spend + 1 input (security level = 1).
    self.assertEqual(len(self.bundle), 2)

    # The spending transaction does not have a signature.
    self.assertEqual(
      self.bundle[0].signature_message_fragment,
      Fragment(b''),
    )

    # The signature fragments are really long, and we already have unit
    # tests for the signature fragment generator, so to keep this test
    # focused, we are only interested in whether a signature fragment
    # gets applied.
    #
    # References:
    #   - :py:class:`test.crypto.signing_test.SignatureFragmentGeneratorTestCase`
    for i in range(1, len(self.bundle)):
      if self.bundle[i].signature_message_fragment == Fragment(b''):
        self.fail(
          "Transaction {i}'s signature fragment is unexpectedly empty!".format(
            i = i,
          ),
        )
Beispiel #4
0
    def test_add_signature_or_message(self):
        """
    Add a fragment to a transaction.
    """
        # Add a transaction
        self.bundle.add_transaction(
            ProposedTransaction(
                address=Address(b'TESTVALUE9DONTUSEINPRODUCTION99999QARFLF'
                                b'TDVATBVFTFCGEHLFJBMHPBOBOHFBSGAGWCM9PG9GX'),
                message=TryteString.from_unicode('This should be overwritten'),
                value=0,
            ))
        custom_msg = \
          'The early bird gets the worm, but the custom-msg gets into the bundle.'
        custom_fragment = Fragment.from_unicode(custom_msg)

        # Before finalization, the method adds to message field...
        self.bundle.add_signature_or_message([custom_fragment])
        self.assertEqual(self.bundle._transactions[0].message, custom_fragment)

        # ... because upon finalization, this is translated into
        # signature_message_fragment field.
        self.bundle.finalize()
        self.assertEqual(
            self.bundle._transactions[0].signature_message_fragment,
            custom_fragment)

        # Do we have the right text inside?
        self.assertEqual(self.bundle.get_messages()[0], custom_msg)
Beispiel #5
0
  def test_add_signature_or_message_too_long_fragments(self):
    """
    Trying to add too many fragments to a bundle, when there aren't enough
    transactions to hold them.
    """
    # Add 3 transactions to the bundle.
    for i in ['A', 'B', 'C']:
      self.bundle.add_transaction(ProposedTransaction(
        address =
          Address(
            'TESTVALUE' + i + 'DONTUSEINPRODUCTION99999QARFLF'
            'TDVATBVFTFCGEHLFJBMHPBOBOHFBSGAGWCM9PG9GX'
          ),
        message= TryteString.from_unicode('This should be overwritten'),
        value = 0,
      ))

    fragment1 = Fragment.from_unicode('This is the first fragment.')
    # 4 fragments, 3 txs in bundle
    fragments = [fragment1] * 4

    with self.assertRaises(ValueError):
      self.bundle.add_signature_or_message(fragments)

    # Length is okay, but overflow because of offset
    fragments = [fragment1] * 3

    with self.assertRaises(ValueError):
      self.bundle.add_signature_or_message(fragments,start_index=1)
Beispiel #6
0
    def test_single_transaction(self):
        """
    Getting a bundle that contains a single transaction.
    """
        transaction = \
            Transaction(
                current_index=0,
                last_index=0,
                tag=Tag(b''),
                timestamp=1484960990,
                value=0,
                attachment_timestamp=1484960990,
                attachment_timestamp_lower_bound=12,
                attachment_timestamp_upper_bound=0,

                # These values are not relevant for 0-value transactions.
                nonce=Nonce(b''),
                signature_message_fragment=Fragment(b''),

                # This value is computed automatically, so it has to be real.
                hash_=TransactionHash(
                    b'XPJIYZWPF9LBCYZPNBFARDRCSUGJGF9TWZT9K9PX'
                    b'VYDFPZOZBGXUCKLTJEUCFBEKQQ9VCSQVQDMMJQAY9',
                ),

                address=Address(
                    b'TESTVALUE9DONTUSEINPRODUCTION99999OCSGVF'
                    b'IBQA99KGTCPCZ9NHR9VGLGADDDIEGGPCGBDEDDTBC',
                ),

                bundle_hash=BundleHash(
                    b'TESTVALUE9DONTUSEINPRODUCTION99999DIOAZD'
                    b'M9AIUHXGVGBC9EMGI9SBVBAIXCBFJ9EELCPDRAD9U',
                ),

                branch_transaction_hash=TransactionHash(
                    b'TESTVALUE9DONTUSEINPRODUCTION99999BBCEDI'
                    b'ZHUDWBYDJEXHHAKDOCKEKDFIMB9AMCLFW9NBDEOFV',
                ),

                trunk_transaction_hash=TransactionHash(
                    b'TESTVALUE9DONTUSEINPRODUCTION999999ARAYA'
                    b'MHCB9DCFEIWEWDLBCDN9LCCBQBKGDDAECFIAAGDAS',
                ),
            )

        self.adapter.seed_response('getTrytes', {
            'trytes': [transaction.as_tryte_string()],
        })

        response = self.command(transaction=transaction.hash)

        bundle = response['bundles'][0]  # type: Bundle
        self.assertEqual(len(bundle), 1)

        self.maxDiff = None
        self.assertDictEqual(
            bundle[0].as_json_compatible(),
            transaction.as_json_compatible(),
        )
Beispiel #7
0
  def test_add_signature_or_message_invalid_start_index(self):
    """
    Attempting to add fragments to a bundle, but `start_index` is invalid.
    """
    # Add 3 transactions to the bundle.
    for i in ['A', 'B', 'C']:
      self.bundle.add_transaction(ProposedTransaction(
        address =
          Address(
            'TESTVALUE' + i + 'DONTUSEINPRODUCTION99999QARFLF'
            'TDVATBVFTFCGEHLFJBMHPBOBOHFBSGAGWCM9PG9GX'
          ),
        message = TryteString.from_unicode('This should be overwritten'),
        value = 0,
      ))

    fragment1 = Fragment.from_unicode('This is the first fragment.')

    with self.assertRaises(ValueError):
      self.bundle.add_signature_or_message([fragment1], start_index=-1)

    with self.assertRaises(ValueError):
      self.bundle.add_signature_or_message([fragment1], start_index=3)

    with self.assertRaises(TypeError):
      self.bundle.add_signature_or_message([fragment1], 'not an int')
Beispiel #8
0
    def test_sign_input_at_error_already_signed(self):
        """
    Attempting to sign an input that is already signed.
    """
        # Add a transaction so that we can finalize the bundle.
        # noinspection SpellCheckingInspection
        self.bundle.add_transaction(
            ProposedTransaction(
                address=Address(b'TESTVALUE9DONTUSEINPRODUCTION99999QARFLF'
                                b'TDVATBVFTFCGEHLFJBMHPBOBOHFBSGAGWCM9PG9GX'),
                value=42,
            ))

        self.bundle.add_inputs([self.input_0_bal_eq_42])
        self.bundle.finalize()

        # The existing signature fragment doesn't have to be valid; it just
        # has to be not empty.
        self.bundle[1].signature_message_fragment = Fragment(b'A')

        private_key =\
          KeyGenerator(self.seed).get_key_for(self.input_0_bal_eq_42)

        with self.assertRaises(ValueError):
            self.bundle.sign_input_at(1, private_key)
Beispiel #9
0
def track_bundle_loop(hash):
    all_tx = None
    try:
        all_tx = api.find_transactions(addresses=[Address(hash)])
        all_inclusion = api.get_latest_inclusion(all_tx['hashes'])
    except:
        return all_tx, 4
    tx_list = {
        key: val
        for key, val in all_inclusion['states'].items() if val == True
    }

    input = None
    ds = 0
    for tx_hash in tx_list:
        tx = Transaction.from_tryte_string(
            api.get_trytes([tx_hash])['trytes'][0])
        if tx.value < 0:
            input = tx
            ds += 1
            break

    if input is None:
        return hash, 1  #"Address hasn't used yet."
    elif ds > 1:
        return hash, 2  #"Address has been reused twice or more."

    while input.current_index != input.last_index:
        input = Transaction.from_tryte_string(
            api.get_trytes([input.trunk_transaction_hash])['trytes'][0])

    if input.signature_message_fragment != Fragment(b''):
        return input.address, 3  #"Track failed."

    return input.address, 0
Beispiel #10
0
    def test_add_signature_or_messagee_multiple(self):
        """
    Add multiple fragments.
    """
        # Add 3 transactions to the bundle, For convenience, we use
        # 3 different addresses, so they are not grouped together and
        # bundle.get_messages() returns a list of messages mapping to
        # the 3 transactions.
        for i in ['A', 'B', 'C']:
            self.bundle.add_transaction(
                ProposedTransaction(
                    address=Address(
                        'TESTVALUE' + i + 'DONTUSEINPRODUCTION99999QARFLF'
                        'TDVATBVFTFCGEHLFJBMHPBOBOHFBSGAGWCM9PG9GX'),
                    message=TryteString.from_unicode(
                        'This should be overwritten'),
                    value=0,
                ))

        fragment1 = Fragment.from_unicode('This is the first fragment.')
        fragment2 = Fragment.from_unicode('This is the second fragment.')

        self.bundle.add_signature_or_message([fragment1, fragment2])

        bundle_fragments = []
        for tx in self.bundle:
            bundle_fragments.append(tx.message)

        self.assertListEqual(bundle_fragments, [
            fragment1, fragment2,
            TryteString.from_unicode('This should be overwritten')
        ])

        self.bundle.finalize()

        bundle_fragments_unicode = []
        for tx in self.bundle:
            bundle_fragments_unicode.append(
                tx.signature_message_fragment.decode())

        self.assertListEqual(bundle_fragments_unicode, [
            fragment1.decode(),
            fragment2.decode(), 'This should be overwritten'
        ])
Beispiel #11
0
    def test_add_signature_or_message_multiple_offset(self):
        """
    Add multiple fragments with offset.
    """
        # Add 3 transactions to the bundle.
        for i in ['A', 'B', 'C']:
            self.bundle.add_transaction(
                ProposedTransaction(
                    address=Address(
                        'TESTVALUE' + i + 'DONTUSEINPRODUCTION99999QARFLF'
                        'TDVATBVFTFCGEHLFJBMHPBOBOHFBSGAGWCM9PG9GX'),
                    message=TryteString.from_unicode(
                        'This should be overwritten'),
                    value=0,
                ))

        fragment1 = Fragment.from_unicode('This is the first fragment.')
        fragment2 = Fragment.from_unicode('This is the second fragment.')

        self.bundle.add_signature_or_message([fragment1, fragment2], 1)

        bundle_fragments = []
        for tx in self.bundle:
            bundle_fragments.append(tx.message)

        self.assertListEqual(bundle_fragments, [
            TryteString.from_unicode('This should be overwritten'), fragment1,
            fragment2
        ])

        self.bundle.finalize()

        bundle_fragments_unicode = []
        for tx in self.bundle:
            bundle_fragments_unicode.append(
                tx.signature_message_fragment.decode())

        self.assertListEqual(bundle_fragments_unicode, [
            'This should be overwritten',
            fragment1.decode(),
            fragment2.decode()
        ])
Beispiel #12
0
 def cache_txn_in_tangle_simple(self, data, tag):
     address = "JVSVAFSXWHUIZPFDLORNDMASGNXWFGZFMXGLCJQGFWFEZWWOA9KYSPHCLZHFBCOHMNCCBAGNACPIGHVYX"
     txns = self.api.get_transactions_to_approve(self.depth)
     tr = self.api.get_trytes([txns[u'branchTransaction']])
     txn = Transaction.from_tryte_string(tr[u'trytes'][0], txns[u'branchTransaction'])
     txn.trunk_transaction_hash = txns[u'trunkTransaction']
     txn.branch_transaction_hash = txns[u'branchTransaction']
     txn.tag = Tag(TryteString.from_string(tag))
     txn.signature_message_fragment = Fragment(TryteString.from_bytes(data))
     attach_trytes = attachToTangle(self.uri, txns[u'trunkTransaction'].__str__(), txns[u'branchTransaction'].__str__(), 1, txn.as_tryte_string().__str__())
     res = self.api.broadcast_and_store(attach_trytes[u'trytes'])
     return res
def finalize(bundle):
    sponge = Kerl()
    last_index = len(bundle) - 1

    for (i, txn) in enumerate(bundle):  # type: Tuple[int, ProposedTransaction]
        txn.current_index = i
        txn.last_index = last_index
        sponge.absorb(txn.get_signature_validation_trytes().as_trits())

    bundle_hash_trits = [0] * HASH_LENGTH  # type: MutableSequence[int]
    sponge.squeeze(bundle_hash_trits)
    bundle_hash = BundleHash.from_trits(bundle_hash_trits)

    for txn in bundle:
        txn.bundle_hash = bundle_hash
        # Initialize signature/message fragment.
        txn.signature_message_fragment = Fragment(txn.message or b'')
Beispiel #14
0
def finalize(bundle):
    sponge = Kerl()
    last_index = len(bundle) - 1

    for (i, txn) in enumerate(bundle):
        txn.current_index = i
        txn.last_index = last_index
        sponge.absorb(txn.get_signature_validation_trytes().as_trits())

    bundle_hash_trits = [0] * HASH_LENGTH
    sponge.squeeze(bundle_hash_trits)

    bundle_hash = BundleHash.from_trits(bundle_hash_trits)

    for txn in bundle:
        txn.bundle_hash = bundle_hash
        txn.signature_message_fragment = Fragment(txn.message or b'')
Beispiel #15
0
    def test_add_signature_or_message_finalized_bundle(self):
        """
    Try to call the method on a finalized bundle.
    """
        self.bundle.add_transaction(
            ProposedTransaction(
                address=Address(b'TESTVALUE9DONTUSEINPRODUCTION99999QARFLF'
                                b'TDVATBVFTFCGEHLFJBMHPBOBOHFBSGAGWCM9PG9GX'),
                message=TryteString.from_unicode('This should be overwritten'),
                value=0,
            ))

        custom_msg = \
          'The early bird gets the worm, but the custom-msg gets into the bundle.'
        custom_fragment = Fragment.from_unicode(custom_msg)

        # Finalize the bundle, no further changes should be permitted.
        self.bundle.finalize()

        with self.assertRaises(RuntimeError):
            self.bundle.add_signature_or_message([custom_fragment])
Beispiel #16
0
    def get_messages_from_address(self, address):
        """
        Gets messages (sorted by timestamp).
        Returns a dict with 'json_message' and 'timestamp keys'

        :param address:
           Address to fetch messages from

        """
        sorted_transactions = self.get_transactions_from_address(address)
        messages = list(
            map(
                lambda t: {
                    'json_message':
                    json.loads(Fragment.as_string(t.signature_message_fragment)
                               ),
                    'timestamp':
                    t.timestamp
                }, sorted_transactions))

        return messages
Beispiel #17
0
  def test_as_tryte_string(self):
    """
    Converting a Transaction into a TryteString.
    """
    transaction = Transaction(
      hash_ =
        TransactionHash(
          b'SYABNCYPLULQQBTDCUWJPVVMYNWHKEHGAZPKRBGE'
          b'QKEHUIKJCHWGAUKLSYMDOUUBMXPKCPTNFWUFU9JKW'
        ),

      signature_message_fragment =
        Fragment(
          b'GYPRVHBEZOOFXSHQBLCYW9ICTCISLHDBNMMVYD9JJHQMPQCTIQAQTJNNNJ9IDXLRCC'
          b'OYOXYPCLR9PBEY9ORZIEPPDNTI9CQWYZUOTAVBXPSBOFEQAPFLWXSWUIUSJMSJIIIZ'
          b'WIKIRH9GCOEVZFKNXEVCUCIIWZQCQEUVRZOCMEL9AMGXJNMLJCIA9UWGRPPHCEOPTS'
          b'VPKPPPCMQXYBHMSODTWUOABPKWFFFQJHCBVYXLHEWPD9YUDFTGNCYAKQKVEZYRBQRB'
          b'XIAUX9SVEDUKGMTWQIYXRGSWYRK9SRONVGTW9YGHSZRIXWGPCCUCDRMAXBPDFVHSRY'
          b'WHGB9DQSQFQKSNICGPIPTRZINYRXQAFSWSEWIFRMSBMGTNYPRWFSOIIWWT9IDSELM9'
          b'JUOOWFNCCSHUSMGNROBFJX9JQ9XT9PKEGQYQAWAFPRVRRVQPUQBHLSNTEFCDKBWRCD'
          b'X9EYOBB9KPMTLNNQLADBDLZPRVBCKVCYQEOLARJYAGTBFR9QLPKZBOYWZQOVKCVYRG'
          b'YI9ZEFIQRKYXLJBZJDBJDJVQZCGYQMROVHNDBLGNLQODPUXFNTADDVYNZJUVPGB9LV'
          b'PJIYLAPBOEHPMRWUIAJXVQOEM9ROEYUOTNLXVVQEYRQWDTQGDLEYFIYNDPRAIXOZEB'
          b'CS9P99AZTQQLKEILEVXMSHBIDHLXKUOMMNFKPYHONKEYDCHMUNTTNRYVMMEYHPGASP'
          b'ZXASKRUPWQSHDMU9VPS99ZZ9SJJYFUJFFMFORBYDILBXCAVJDPDFHTTTIYOVGLRDYR'
          b'TKHXJORJVYRPTDH9ZCPZ9ZADXZFRSFPIQKWLBRNTWJHXTOAUOL9FVGTUMMPYGYICJD'
          b'XMOESEVDJWLMCVTJLPIEKBE9JTHDQWV9MRMEWFLPWGJFLUXI9BXPSVWCMUWLZSEWHB'
          b'DZKXOLYNOZAPOYLQVZAQMOHGTTQEUAOVKVRRGAHNGPUEKHFVPVCOYSJAWHZU9DRROH'
          b'BETBAFTATVAUGOEGCAYUXACLSSHHVYDHMDGJP9AUCLWLNTFEVGQGHQXSKEMVOVSKQE'
          b'EWHWZUDTYOBGCURRZSJZLFVQQAAYQO9TRLFFN9HTDQXBSPPJYXMNGLLBHOMNVXNOWE'
          b'IDMJVCLLDFHBDONQJCJVLBLCSMDOUQCKKCQJMGTSTHBXPXAMLMSXRIPUBMBAWBFNLH'
          b'LUJTRJLDERLZFUBUSMF999XNHLEEXEENQJNOFFPNPQ9PQICHSATPLZVMVIWLRTKYPI'
          b'XNFGYWOJSQDAXGFHKZPFLPXQEHCYEAGTIWIJEZTAVLNUMAFWGGLXMBNUQTOFCNLJTC'
          b'DMWVVZGVBSEBCPFSM99FLOIDTCLUGPSEDLOKZUAEVBLWNMODGZBWOVQT9DPFOTSKRA'
          b'BQAVOQ9RXWBMAKFYNDCZOJGTCIDMQSQQSODKDXTPFLNOKSIZEOY9HFUTLQRXQMEPGO'
          b'XQGLLPNSXAUCYPGZMNWMQWSWCKAQYKXJTWINSGPPZG9HLDLEAWUWEVCTVRCBDFOXKU'
          b'ROXH9HXXAXVPEJFRSLOGRVGYZASTEBAQNXJJROCYRTDPYFUIQJVDHAKEG9YACV9HCP'
          b'JUEUKOYFNWDXCCJBIFQKYOXGRDHVTHEQUMHO999999999999999999999999999999'
          b'999999999999999999999999999999999999999999999999999999999999999999'
          b'999999999999999999999999999999999999999999999999999999999999999999'
          b'999999999999999999999999999999999999999999999999999999999999999999'
          b'999999999999999999999999999999999999999999999999999999999999999999'
          b'999999999999999999999999999999999999999999999999999999999999999999'
          b'999999999999999999999999999999999999999999999999999999999999999999'
          b'999999999999999999999999999999999999999999999999999999999999999999'
          b'999999999999999999999999999999999999999999999999999999999999999999'
          b'999999999'
        ),

      address =
        Address(
          b'99999999999999999999999999999999999999999'
          b'9999999999999999999999999999999999999999'
        ),

      value         = 0,
      timestamp     = 1480690413,
      current_index = 1,
      last_index    = 1,

      bundle_hash =
        BundleHash(
          b'NFDPEEZCWVYLKZGSLCQNOFUSENIXRHWWTZFBXMPS'
          b'QHEDFWZULBZFEOMNLRNIDQKDNNIELAOXOVMYEI9PG'
        ),

      trunk_transaction_hash =
        TransactionHash(
          b'TKORV9IKTJZQUBQAWTKBKZ9NEZHBFIMCLV9TTNJN'
          b'QZUIJDFPTTCTKBJRHAITVSKUCUEMD9M9SQJ999999'
        ),

      branch_transaction_hash =
        TransactionHash(
          b'TKORV9IKTJZQUBQAWTKBKZ9NEZHBFIMCLV9TTNJN'
          b'QZUIJDFPTTCTKBJRHAITVSKUCUEMD9M9SQJ999999'
        ),

      tag                               = Tag(b'999999999999999999999999999'),
      attachment_timestamp              = 1480690413,
      attachment_timestamp_lower_bound  = 1480690413,
      attachment_timestamp_upper_bound  = 1480690413,


      nonce =
        Nonce(
          b'999999999999999999999999999'
        ),
    )

    self.assertEqual(
      transaction.as_tryte_string(),

     TransactionTrytes(
        b'GYPRVHBEZOOFXSHQBLCYW9ICTCISLHDBNMMVYD9JJHQMPQCTIQAQTJNNNJ9IDXLRCC'
        b'OYOXYPCLR9PBEY9ORZIEPPDNTI9CQWYZUOTAVBXPSBOFEQAPFLWXSWUIUSJMSJIIIZ'
        b'WIKIRH9GCOEVZFKNXEVCUCIIWZQCQEUVRZOCMEL9AMGXJNMLJCIA9UWGRPPHCEOPTS'
        b'VPKPPPCMQXYBHMSODTWUOABPKWFFFQJHCBVYXLHEWPD9YUDFTGNCYAKQKVEZYRBQRB'
        b'XIAUX9SVEDUKGMTWQIYXRGSWYRK9SRONVGTW9YGHSZRIXWGPCCUCDRMAXBPDFVHSRY'
        b'WHGB9DQSQFQKSNICGPIPTRZINYRXQAFSWSEWIFRMSBMGTNYPRWFSOIIWWT9IDSELM9'
        b'JUOOWFNCCSHUSMGNROBFJX9JQ9XT9PKEGQYQAWAFPRVRRVQPUQBHLSNTEFCDKBWRCD'
        b'X9EYOBB9KPMTLNNQLADBDLZPRVBCKVCYQEOLARJYAGTBFR9QLPKZBOYWZQOVKCVYRG'
        b'YI9ZEFIQRKYXLJBZJDBJDJVQZCGYQMROVHNDBLGNLQODPUXFNTADDVYNZJUVPGB9LV'
        b'PJIYLAPBOEHPMRWUIAJXVQOEM9ROEYUOTNLXVVQEYRQWDTQGDLEYFIYNDPRAIXOZEB'
        b'CS9P99AZTQQLKEILEVXMSHBIDHLXKUOMMNFKPYHONKEYDCHMUNTTNRYVMMEYHPGASP'
        b'ZXASKRUPWQSHDMU9VPS99ZZ9SJJYFUJFFMFORBYDILBXCAVJDPDFHTTTIYOVGLRDYR'
        b'TKHXJORJVYRPTDH9ZCPZ9ZADXZFRSFPIQKWLBRNTWJHXTOAUOL9FVGTUMMPYGYICJD'
        b'XMOESEVDJWLMCVTJLPIEKBE9JTHDQWV9MRMEWFLPWGJFLUXI9BXPSVWCMUWLZSEWHB'
        b'DZKXOLYNOZAPOYLQVZAQMOHGTTQEUAOVKVRRGAHNGPUEKHFVPVCOYSJAWHZU9DRROH'
        b'BETBAFTATVAUGOEGCAYUXACLSSHHVYDHMDGJP9AUCLWLNTFEVGQGHQXSKEMVOVSKQE'
        b'EWHWZUDTYOBGCURRZSJZLFVQQAAYQO9TRLFFN9HTDQXBSPPJYXMNGLLBHOMNVXNOWE'
        b'IDMJVCLLDFHBDONQJCJVLBLCSMDOUQCKKCQJMGTSTHBXPXAMLMSXRIPUBMBAWBFNLH'
        b'LUJTRJLDERLZFUBUSMF999XNHLEEXEENQJNOFFPNPQ9PQICHSATPLZVMVIWLRTKYPI'
        b'XNFGYWOJSQDAXGFHKZPFLPXQEHCYEAGTIWIJEZTAVLNUMAFWGGLXMBNUQTOFCNLJTC'
        b'DMWVVZGVBSEBCPFSM99FLOIDTCLUGPSEDLOKZUAEVBLWNMODGZBWOVQT9DPFOTSKRA'
        b'BQAVOQ9RXWBMAKFYNDCZOJGTCIDMQSQQSODKDXTPFLNOKSIZEOY9HFUTLQRXQMEPGO'
        b'XQGLLPNSXAUCYPGZMNWMQWSWCKAQYKXJTWINSGPPZG9HLDLEAWUWEVCTVRCBDFOXKU'
        b'ROXH9HXXAXVPEJFRSLOGRVGYZASTEBAQNXJJROCYRTDPYFUIQJVDHAKEG9YACV9HCP'
        b'JUEUKOYFNWDXCCJBIFQKYOXGRDHVTHEQUMHO999999999999999999999999999999'
        b'999999999999999999999999999999999999999999999999999999999999999999'
        b'999999999999999999999999999999999999999999999999999999999999999999'
        b'999999999999999999999999999999999999999999999999999999999999999999'
        b'999999999999999999999999999999999999999999999999999999999999999999'
        b'999999999999999999999999999999999999999999999999999999999999999999'
        b'999999999999999999999999999999999999999999999999999999999999999999'
        b'999999999999999999999999999999999999999999999999999999999999999999'
        b'999999999999999999999999999999999999999999999999999999999999999999'
        b'999999999999999999999999999999999999999999999999999999999999999999'
        b'999999999999999999999999999999999999999999999999999999999999999999'
        b'999999999999RKWEEVD99A99999999A99999999NFDPEEZCWVYLKZGSLCQNOFUSENI'
        b'XRHWWTZFBXMPSQHEDFWZULBZFEOMNLRNIDQKDNNIELAOXOVMYEI9PGTKORV9IKTJZQ'
        b'UBQAWTKBKZ9NEZHBFIMCLV9TTNJNQZUIJDFPTTCTKBJRHAITVSKUCUEMD9M9SQJ999'
        b'999TKORV9IKTJZQUBQAWTKBKZ9NEZHBFIMCLV9TTNJNQZUIJDFPTTCTKBJRHAITVSK'
        b'UCUEMD9M9SQJ999999999999999999999999999999999RKWEEVD99RKWEEVD99RKW'
        b'EEVD99999999999999999999999999999'
      ),
    )
Beispiel #18
0
  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,
      ),
    ])
    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 test_single_transaction(self):
        """
    Getting a bundle that contains a single transaction.
    """
        transaction =\
          Transaction(
              current_index = 0,
              last_index    = 0,
              tag           = Tag(b''),
              timestamp     = 1484960990,
              value         = 0,

              # These values are not relevant for 0-value transactions.
              nonce                       = Hash(b''),
              signature_message_fragment  = Fragment(b''),

              # This value is computed automatically, so it has to be real.
              hash_ =
                TransactionHash(
                  b'UGQBSMKGNXXWDCS9XZCFTPUXFADCT9I9KCNQGUXK'
                  b'NDJDUXLWODOVJQWJHCLWTODAELDXGL9SMQYQZFWHE',
                ),

              address =
                Address(
                  b'TESTVALUE9DONTUSEINPRODUCTION99999OCSGVF'
                  b'IBQA99KGTCPCZ9NHR9VGLGADDDIEGGPCGBDEDDTBC',
                ),

              bundle_hash =
                BundleHash(
                  b'TESTVALUE9DONTUSEINPRODUCTION99999DIOAZD'
                  b'M9AIUHXGVGBC9EMGI9SBVBAIXCBFJ9EELCPDRAD9U',
                ),

              branch_transaction_hash =
                TransactionHash(
                  b'TESTVALUE9DONTUSEINPRODUCTION99999BBCEDI'
                  b'ZHUDWBYDJEXHHAKDOCKEKDFIMB9AMCLFW9NBDEOFV',
                ),

              trunk_transaction_hash =
                TransactionHash(
                  b'TESTVALUE9DONTUSEINPRODUCTION999999ARAYA'
                  b'MHCB9DCFEIWEWDLBCDN9LCCBQBKGDDAECFIAAGDAS',
                ),
            )

        self.adapter.seed_response('getTrytes', {
            'trytes': [transaction.as_tryte_string()],
        })

        response = self.command(transaction=transaction.hash)

        bundle = response['bundles'][0]  # type: Bundle
        self.assertEqual(len(bundle), 1)

        self.maxDiff = None
        self.assertDictEqual(
            bundle[0].as_json_compatible(),
            transaction.as_json_compatible(),
        )
    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''))
Beispiel #22
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)
Beispiel #23
0
  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,
      ),
    ])
Beispiel #24
0
 def test_random(self):
     """
 Creating a random Fragment object.
 """
     random_fragment = Fragment.random()
     self.assertEqual(len(random_fragment), Fragment.LEN)
Beispiel #25
0
    def test_single_transaction(self):
        """
    Getting a bundle that contains a single transaction.
    """
        transaction =\
          Transaction(
              current_index = 0,
              last_index    = 0,
              tag           = Tag(b''),
              timestamp     = 1484960990,
              value         = 0,

              # These values are not relevant for 0-value transactions.
              nonce                       = Hash(b''),
              signature_message_fragment  = Fragment(b''),

              # This value is computed automatically, so it has to be real.
              hash_ =
                TransactionHash(
                  b'TAOICZV9ZSXIZINMNRLOLCWNLL9IDKGVWTJITNGU'
                  b'HAIKLHZLBZWOQ9HJSODUDISTYGIYPWTYDCFMVRBQN'
                ),

              address =
                Address(
                  b'TESTVALUE9DONTUSEINPRODUCTION99999OCSGVF'
                  b'IBQA99KGTCPCZ9NHR9VGLGADDDIEGGPCGBDEDDTBC'
                ),

              bundle_hash =
                BundleHash(
                  b'TESTVALUE9DONTUSEINPRODUCTION99999DIOAZD'
                  b'M9AIUHXGVGBC9EMGI9SBVBAIXCBFJ9EELCPDRAD9U'
                ),

              branch_transaction_hash =
                TransactionHash(
                  b'TESTVALUE9DONTUSEINPRODUCTION99999BBCEDI'
                  b'ZHUDWBYDJEXHHAKDOCKEKDFIMB9AMCLFW9NBDEOFV'
                ),

              trunk_transaction_hash =
                TransactionHash(
                  b'TESTVALUE9DONTUSEINPRODUCTION999999ARAYA'
                  b'MHCB9DCFEIWEWDLBCDN9LCCBQBKGDDAECFIAAGDAS'
                ),
            )

        self.adapter.seed_response('getTrytes', {
            'trytes': [transaction.as_tryte_string()],
        })

        response = self.command(transaction=transaction.hash)

        bundle = response['bundles'][0]  # type: Bundle
        self.assertEqual(len(bundle), 1)

        self.maxDiff = None
        self.assertDictEqual(
            bundle[0].as_json_compatible(),
            transaction.as_json_compatible(),
        )