示例#1
0
    def test_no_transactions(self):
        """
    There are no transactions for the specified seed.
    """

        # To speed up the test, we will mock the address generator.
        # :py:class:`iota_async.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][start::step]:
                yield addy

        self.adapter.seed_response(
            'findTransactions',
            {
                'duration': 1,
                'hashes': [],
            },
        )

        with mock.patch(
                'iota_async.crypto.addresses.AddressGenerator.create_iterator',
                create_generator,
        ):
            response = self.command(seed=Seed.random())

        self.assertDictEqual(response, {'bundles': []})
    def test_stop_threshold_zero(self):
        """
    ``stop`` provided, ``threshold`` is 0.
    """
        # Note that the first address has a zero balance.
        self.adapter.seed_response('getBalances', {
            'balances': [0, 1],
        })

        # To keep the unit test nice and speedy, we will mock the address
        # generator.  We already have plenty of unit tests for that
        # functionality, so we can get away with mocking it here.
        mock_address_generator = mock.Mock(
            return_value=[self.addy0, self.addy1])

        with mock.patch(
                'iota_async.crypto.addresses.AddressGenerator.get_addresses',
                mock_address_generator,
        ):
            response = self.command(
                seed=Seed.random(),
                stop=2,
                threshold=0,
            )

        self.assertEqual(response['totalBalance'], 1)
        self.assertEqual(len(response['inputs']), 1)

        # Address 0 was skipped because it has a zero balance.
        input0 = response['inputs'][0]
        self.assertIsInstance(input0, Address)

        self.assertEqual(input0, self.addy1)
        self.assertEqual(input0.balance, 1)
        self.assertEqual(input0.key_index, 1)
    def test_no_stop_threshold_not_met(self):
        """
    No ``stop`` provided, balance does not meet ``threshold``.
    """
        self.adapter.seed_response('getBalances', {
            'balances': [42, 29, 0],
        })

        # To keep the unit test nice and speedy, we will mock the address
        # generator.  We already have plenty of unit tests for that
        # functionality, so we can get away with mocking it here.
        # noinspection PyUnusedLocal
        def mock_address_generator(ag, start, step=1):
            for addy in [self.addy0, self.addy1, self.addy2][start::step]:
                yield addy

        # When ``stop`` is None, the command uses a generator internally.
        with mock.patch(
                'iota_async.crypto.addresses.AddressGenerator.create_iterator',
                mock_address_generator,
        ):
            with self.assertRaises(BadApiResponse):
                self.command(
                    seed=Seed.random(),
                    threshold=72,
                )
示例#4
0
  def test_generate_multiple_digests(self):
    """
    Generating multiple digests.
    """
    seed = Seed.random()

    mock_get_private_keys =\
      mock.Mock(return_value={'keys': [self.key1, self.key2]})

    with mock.patch(
        'iota_async.multisig.commands.get_private_keys.GetPrivateKeysCommand._execute',
        mock_get_private_keys
    ):
      # noinspection PyUnresolvedReferences
      with mock.patch.object(self.key1, 'get_digest') as mock_get_digest_1: # type: mock.MagicMock
        mock_get_digest_1.return_value = self.digest1

        # noinspection PyUnresolvedReferences
        with mock.patch.object(self.key2, 'get_digest') as mock_get_digest_2: # type: mock.MagicMock
          mock_get_digest_2.return_value = self.digest2

          result = self.command(seed=seed, index=0, count=2, securityLevel=1)

    self.assertDictEqual(result, {'digests': [self.digest1, self.digest2]})

    mock_get_private_keys.assert_called_once_with({
      'count':          2,
      'index':          0,
      'securityLevel':  1,
      'seed':           seed,
    })
    def test_start(self):
        """
    Using ``start`` to offset the key range.
    """
        self.adapter.seed_response('getBalances', {
            'balances': [86],
        })

        # ``getInputs`` uses ``findTransactions`` to identify unused
        # addresses.
        # noinspection SpellCheckingInspection
        self.adapter.seed_response(
            'findTransactions', {
                'hashes': [
                    TransactionHash(
                        b'TESTVALUE9DONTUSEINPRODUCTION99999YFXGOD'
                        b'GISBJAX9PDJIRDMDV9DCRDCAEG9FN9KECCBDDFZ9H'),
                ],
            })

        self.adapter.seed_response('findTransactions', {
            'hashes': [],
        })

        # To keep the unit test nice and speedy, we will mock the address
        # generator.  We already have plenty of unit tests for that
        # functionality, so we can get away with mocking it here.
        # noinspection PyUnusedLocal
        def mock_address_generator(ag, start, step=1):
            # If ``start`` has the wrong value, return garbage to make the
            # test asplode.
            for addy in [None, self.addy1, self.addy2][start::step]:
                yield addy

        # When ``stop`` is None, the command uses a generator internally.
        with mock.patch(
                'iota_async.crypto.addresses.AddressGenerator.create_iterator',
                mock_address_generator,
        ):
            response = self.command(
                seed=Seed.random(),
                start=1,
            )

        self.assertEqual(response['totalBalance'], 86)
        self.assertEqual(len(response['inputs']), 1)

        input0 = response['inputs'][0]
        self.assertIsInstance(input0, Address)

        self.assertEqual(input0, self.addy1)
        self.assertEqual(input0.balance, 86)
        self.assertEqual(input0.key_index, 1)
示例#6
0
    def prompt_for_seed():
        # type: () -> Seed
        """
        Prompts the user to enter their seed via stdin.
        """
        seed = secure_input(
            'Enter seed and press return (typing will not be shown).\n'
            'If no seed is specified, a random one will be used instead.\n')

        if isinstance(seed, text_type):
            seed = seed.encode('ascii')

        return Seed(seed) if seed else Seed.random()
示例#7
0
    def __init__(self, adapter, seed=None, testnet=False):
        # type: (AdapterSpec, Optional[TrytesCompatible], bool) -> None
        """
        :param seed:
            Seed used to generate new addresses.
            If not provided, a random one will be generated.

            .. note::
                This value is never transferred to the node/network.
        """
        super(Iota, self).__init__(adapter, testnet)

        self.seed = Seed(seed) if seed else Seed.random()
        self.helpers = Helpers(self)
    def test_happy_path(self):
        """
    Loading account data for an account.
    """

        # noinspection PyUnusedLocal
        def mock_iter_used_addresses(adapter, seed, start, security_level):
            """
      Mocks the ``iter_used_addresses`` function, so that we can
      simulate its functionality without actually connecting to the
      Tangle.

      References:
        - :py:func:`iota_async.commands.extended.utils.iter_used_addresses`
      """
            yield self.addy1, [self.hash1]
            yield self.addy2, [self.hash2]

        mock_get_balances = mock.Mock(return_value={'balances': [42, 0]})

        # Not particularly realistic, but good enough to prove that the
        # mocked function was invoked correctly.
        bundles = [Bundle(), Bundle()]
        mock_get_bundles_from_transaction_hashes = mock.Mock(
            return_value=bundles)

        with mock.patch(
                'iota_async.commands.extended.get_account_data.iter_used_addresses',
                mock_iter_used_addresses,
        ):
            with mock.patch(
                    'iota_async.commands.extended.get_account_data.get_bundles_from_transaction_hashes',
                    mock_get_bundles_from_transaction_hashes,
            ):
                with mock.patch(
                        'iota_async.commands.core.get_balances.GetBalancesCommand._execute',
                        mock_get_balances,
                ):
                    response = self.command(seed=Seed.random())

        self.assertDictEqual(
            response,
            {
                'addresses': [self.addy1, self.addy2],
                'balance': 42,
                'bundles': bundles,
            },
        )
  def test_generate_single_key(self):
    """
    Generating a single key.
    """
    keys = [PrivateKey(self.trytes1, 0)]

    mock_get_keys = mock.Mock(return_value=keys)
    with mock.patch('iota_async.crypto.signing.KeyGenerator.get_keys', mock_get_keys):
      result = self.command(seed=Seed.random(), securityLevel=2)

    self.assertDictEqual(result, {'keys': keys})
    mock_get_keys.assert_called_once_with(
      count       = 1,
      iterations  = 2,
      start       = 0,
    )
示例#10
0
    def test_start_stop(self):
        """
    Using ``start`` and ``stop`` at once.
    Checking if correct number of addresses is returned. Must be stop - start
    """

        # To keep the unit test nice and speedy, we will mock the address
        # generator.  We already have plenty of unit tests for that
        # functionality, so we can get away with mocking it here.
        # noinspection PyUnusedLocal

        def mock_address_generator(ag, start, step=1):
            # returning up to 3 addresses, depending on stop value
            for addy in [self.addy0, self.addy1, self.addy2][start::step]:
                yield addy

        self.adapter.seed_response('getBalances', {
            'balances': [11, 11],
        })

        with mock.patch(
                'iota_async.crypto.addresses.AddressGenerator.create_iterator',
                mock_address_generator,
        ):
            response = self.command(
                seed=Seed.random(),
                start=1,
                stop=3,
            )

        self.assertEqual(len(response['inputs']),
                         2)  # 3 - 1 = 2 addresses expected
        self.assertEqual(response['totalBalance'], 22)

        input0 = response['inputs'][0]
        self.assertIsInstance(input0, Address)
        self.assertEqual(input0, self.addy1)
        self.assertEqual(input0.balance, 11)
        self.assertEqual(input0.key_index, 1)

        input1 = response['inputs'][1]
        self.assertIsInstance(input1, Address)
        self.assertEqual(input1, self.addy2)
        self.assertEqual(input1.balance, 11)
        self.assertEqual(input1.key_index, 2)
    def test_no_transactions(self):
        """
    Loading account data for a seed that hasn't been used yet.
    """
        with mock.patch(
                'iota_async.commands.extended.get_account_data.iter_used_addresses',
                mock.Mock(return_value=[]),
        ):
            response = self.command(seed=Seed.random())

        self.assertDictEqual(
            response,
            {
                'addresses': [],
                'balance': 0,
                'bundles': [],
            },
        )
示例#12
0
    def test_security_level_1_with_stop(self):
        """
    Testing GetInputsCoommand:
      - with security_level = 1 (non default)
      - with `stop` parameter
    """

        # one address with index 0 for selected security levels for the random seed.
        # to check with respective outputs from command
        seed = Seed.random()
        address = AddressGenerator(seed, security_level=1).get_addresses(0)[0]

        self.adapter.seed_response('getBalances', {
            'balances': [86],
        })
        # ``getInputs`` uses ``findTransactions`` to identify unused
        # addresses.
        # noinspection SpellCheckingInspection
        self.adapter.seed_response(
            'findTransactions', {
                'hashes': [
                    TransactionHash(
                        b'TESTVALUE9DONTUSEINPRODUCTION99999YFXGOD'
                        b'GISBJAX9PDJIRDMDV9DCRDCAEG9FN9KECCBDDFZ9H'),
                ],
            })
        self.adapter.seed_response('findTransactions', {
            'hashes': [],
        })

        response = GetInputsCommand(self.adapter)(
            seed=seed,
            securityLevel=1,
            stop=1,  # <<<<< here
        )

        self.assertEqual(response['totalBalance'], 86)
        self.assertEqual(len(response['inputs']), 1)

        input0 = response['inputs'][0]
        self.assertIsInstance(input0, Address)
        self.assertEqual(input0, address)
        self.assertEqual(input0.balance, 86)
        self.assertEqual(input0.key_index, 0)
示例#13
0
    def test_random_seed_too_long(self):
        """
    Generating a random seed, which is too long.
    """

        with warnings.catch_warnings(record=True) as catched_warnings:

            # Cause seed related warnings to be triggered
            warnings.simplefilter("always", category=SeedWarning)

            seed = Seed.random(length=Hash.LEN + 1)

            # check attributes of warning
            self.assertEqual(len(catched_warnings), 1)
            self.assertIs(catched_warnings[-1].category, SeedWarning)
            self.assertIn(
                "inappropriate length",
                text_type(catched_warnings[-1].message),
            )

            self.assertEqual(len(seed), Hash.LEN + 1)
示例#14
0
    def test_random(self):
        """
    Generating a random seed.
    """

        with warnings.catch_warnings(record=True) as catched_warnings:

            # all warnings should be triggered
            warnings.simplefilter("always")

            seed = Seed.random()

            self.assertEqual(len(catched_warnings), 0)

        # Regression test: ``random`` MUST return a :py:class:`Seed`, NOT a
        # :py:class:`TryteString`!
        self.assertIsInstance(seed, Seed)

        # Regression test: Random seed must be exactly 81 trytes long.
        # https://github.com/iotaledger/iota.lib.py/issues/44
        self.assertEqual(len(seed), Hash.LEN)
示例#15
0
    def test_stop_no_threshold(self):
        """
    ``stop`` provided, no ``threshold``.
    """
        self.adapter.seed_response('getBalances', {
            'balances': [42, 29],
        })

        # To keep the unit test nice and speedy, we will mock the address
        # generator.  We already have plenty of unit tests for that
        # functionality, so we can get away with mocking it here.
        mock_address_generator = mock.Mock(
            return_value=[self.addy0, self.addy1])

        with mock.patch(
                'iota_async.crypto.addresses.AddressGenerator.get_addresses',
                mock_address_generator,
        ):
            response = self.command(
                seed=Seed.random(),
                start=0,
                stop=2,
            )

        self.assertEqual(response['totalBalance'], 71)
        self.assertEqual(len(response['inputs']), 2)

        input0 = response['inputs'][0]
        self.assertIsInstance(input0, Address)

        self.assertEqual(input0, self.addy0)
        self.assertEqual(input0.balance, 42)
        self.assertEqual(input0.key_index, 0)

        input1 = response['inputs'][1]
        self.assertIsInstance(input1, Address)

        self.assertEqual(input1, self.addy1)
        self.assertEqual(input1.balance, 29)
        self.assertEqual(input1.key_index, 1)
示例#16
0
    def test_stop_threshold_not_met(self):
        """
    ``stop`` provided, balance does not meet ``threshold``.
    """
        self.adapter.seed_response('getBalances', {
            'balances': [42, 29],
        })

        # To keep the unit test nice and speedy, we will mock the address
        # generator.  We already have plenty of unit tests for that
        # functionality, so we can get away with mocking it here.
        mock_address_generator = mock.Mock(
            return_value=[self.addy0, self.addy1])

        with mock.patch(
                'iota_async.crypto.addresses.AddressGenerator.get_addresses',
                mock_address_generator,
        ):
            with self.assertRaises(BadApiResponse):
                self.command(
                    seed=Seed.random(),
                    stop=2,
                    threshold=72,
                )
示例#17
0
    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_async.crypto.addresses.AddressGenerator.create_iterator',
                create_generator,
        ):
            with mock.patch(
                    'iota_async.commands.extended.get_bundles.GetBundlesCommand._execute',
                    mock_get_bundles,
            ):
                response = self.command(seed=Seed.random(), stop=1)

        self.assertDictEqual(
            response,
            {
                'bundles': [bundle],
            },
        )
示例#18
0
    def test_no_stop_no_threshold(self):
        """
    No ``stop`` provided, no ``threshold``.
    """
        self.adapter.seed_response('getBalances', {
            'balances': [42, 29],
        })

        # ``getInputs`` uses ``findTransactions`` to identify unused
        # addresses.
        # noinspection SpellCheckingInspection
        self.adapter.seed_response(
            'findTransactions', {
                'hashes': [
                    TransactionHash(
                        b'TESTVALUE9DONTUSEINPRODUCTION99999WBL9KD'
                        b'EIZDMEDFPEYDIIA9LEMEUCC9MFPBY9TEVCUGSEGGN'),
                ],
            })

        # noinspection SpellCheckingInspection
        self.adapter.seed_response(
            'findTransactions', {
                'hashes': [
                    TransactionHash(
                        b'TESTVALUE9DONTUSEINPRODUCTION99999YFXGOD'
                        b'GISBJAX9PDJIRDMDV9DCRDCAEG9FN9KECCBDDFZ9H'),
                ],
            })

        self.adapter.seed_response('findTransactions', {
            'hashes': [],
        })

        # To keep the unit test nice and speedy, we will mock the address
        # generator.  We already have plenty of unit tests for that
        # functionality, so we can get away with mocking it here.
        # noinspection PyUnusedLocal
        def mock_address_generator(ag, start, step=1):
            for addy in [self.addy0, self.addy1, self.addy2][start::step]:
                yield addy

        # When ``stop`` is None, the command uses a generator internally.
        with mock.patch(
                'iota_async.crypto.addresses.AddressGenerator.create_iterator',
                mock_address_generator,
        ):
            response = self.command(seed=Seed.random(), )

        self.assertEqual(response['totalBalance'], 71)
        self.assertEqual(len(response['inputs']), 2)

        input0 = response['inputs'][0]
        self.assertIsInstance(input0, Address)

        self.assertEqual(input0, self.addy0)
        self.assertEqual(input0.balance, 42)
        self.assertEqual(input0.key_index, 0)

        input1 = response['inputs'][1]
        self.assertIsInstance(input1, Address)

        self.assertEqual(input1, self.addy1)
        self.assertEqual(input1.balance, 29)
        self.assertEqual(input1.key_index, 1)
示例#19
0
    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_async.crypto.addresses.AddressGenerator.create_iterator',
                create_generator,
        ):
            with mock.patch(
                    'iota_async.commands.extended.get_bundles.GetBundlesCommand._execute',
                    mock_get_bundles,
            ):
                with mock.patch(
                        'iota_async.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)
示例#20
0
    def test_happy_path(self):
        """
    Sending a transfer successfully.
    """
        # noinspection SpellCheckingInspection
        transaction1 =\
          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'UCUEMD9M9SQJ999999999999999999999999999999999999999999999999999999'
            b'999999999999999999999999999999999'
          )

        mock_prepare_transfer =\
          mock.Mock(return_value={
            'trytes': [transaction1],
          })

        mock_send_trytes =\
          mock.Mock(return_value={
            'trytes': [transaction1],
          })

        with mock.patch(
                'iota_async.commands.extended.prepare_transfer.PrepareTransferCommand._execute',
                mock_prepare_transfer,
        ):
            with mock.patch(
                    'iota_async.commands.extended.send_trytes.SendTrytesCommand._execute',
                    mock_send_trytes,
            ):
                response = self.command(
                    depth=100,
                    minWeightMagnitude=18,
                    seed=Seed.random(),
                    transfers=[
                        ProposedTransaction(
                            address=Address(
                                b'9999999999999999999999999999999999999999'
                                b'99999999999999999999999999999999999999999'),
                            value=0,
                        ),
                    ],
                )

        bundle = response['bundle']  # type: Bundle
        self.assertEqual(len(bundle), 1)
        self.assertEqual(bundle[0].as_tryte_string(), transaction1)
示例#21
0
    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_async.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_async.crypto.addresses.AddressGenerator.create_iterator',
                create_generator,
        ):
            with mock.patch(
                    'iota_async.commands.extended.get_bundles.GetBundlesCommand._execute',
                    mock_get_bundles,
            ):
                response = self.command(seed=Seed.random())

        self.assertDictEqual(
            response,
            {
                'bundles': [bundle],
            },
        )