Esempio n. 1
0
    def setUp(self):
        super(GetNewAddressesCommandTestCase, self).setUp()

        self.adapter = MockAdapter()
        self.command = GetNewAddressesCommand(self.adapter)

        self.seed =\
          Seed(
            b'TESTVALUE9DONTUSEINPRODUCTION99999ZDCCUF'
            b'CBBIQCLGMEXAVFQEOF9DRAB9VCEBAGXAF9VF9FLHP',
          )

        self.addy_1 =\
          Address(
            b'NYMWLBUJEISSACZZBRENC9HEHYQXHCGQHSNHVCEA'
            b'ZDCTEVNGSDUEKTSYBSQGMVJRIEDHWDYSEYCFAZAH9',
          )

        self.addy_2 =\
          Address(
            b'NTPSEVZHQITARYWHIRTSIFSERINLRYVXLGIQKKHY'
            b'IWYTLQUUHDWSOVXLIKVJTYZBFKLABWRBFYVSMD9NB',
          )

        self.addy_1_checksum =\
          Address(
            b'NYMWLBUJEISSACZZBRENC9HEHYQXHCGQHSNHVCEA'
            b'ZDCTEVNGSDUEKTSYBSQGMVJRIEDHWDYSEYCFAZAH'
            b'9T9FPJROTW',
          )
Esempio n. 2
0
    def setUp(self):
        super(GetNewAddressesCommandTestCase, self).setUp()

        self.adapter = MockAdapter()
        self.command = GetNewAddressesCommand(self.adapter)

        # Create a few TryteStrings we can reuse across tests.
        self.addy1 =\
          Address(
            b'ADDYONE999AHHKVD9SBEYWQFNVQSNTGYQSQ9AGWD'
            b'JDZKBYCVTODUHFEVVMNMPQMIXOVXVCZRUENAWYNTO'
          )

        self.addy2 =\
          Address(
            b'ADDYTWO999AGAQKYXHRMSFAQNPWCIYUYTXPWUEUR'
            b'VNZTCTFUPQ9ESTKNSSLLIZWDQISJVEWIJDVGIECXF'
          )
    def setUp(self):
        super(GetNewAddressesCommandTestCase, self).setUp()

        self.adapter = MockAdapter()
        self.command = GetNewAddressesCommand(self.adapter)

        self.seed =\
          Seed(
            b'TESTVALUE9DONTUSEINPRODUCTION99999ZDCCUF'
            b'CBBIQCLGMEXAVFQEOF9DRAB9VCEBAGXAF9VF9FLHP',
          )

        self.addy_1 =\
          Address(
            b'ESCYAARULFBXJRETFWOFWGAURYZHTLYBLVJTNSTK'
            b'EPHCNLMLMHBPVBDRLYTMQOWPKCFMCQUFRCOVYRTQZ',
          )

        self.addy_2 =\
          Address(
            b'VWTLNSGVCDEGJKEFZOHTHZLUYEZGDDWZZWBJTAPE'
            b'WNOUOAKTEQHCVIMJGTOCDFCEQJTZ9LFIKEYFH9WFA',
          )
Esempio n. 4
0
    def _execute(self, request):
        # Required parameters.
        seed = request['seed']  # type: Seed
        bundle = ProposedBundle(request['transfers'])

        # Optional parameters.
        change_address = request.get(
            'changeAddress')  # type: Optional[Address]
        proposed_inputs = request.get(
            'inputs')  # type: Optional[List[Address]]

        want_to_spend = bundle.balance
        if want_to_spend > 0:
            # We are spending inputs, so we need to gather and sign them.
            if proposed_inputs is None:
                # No inputs provided.  Scan addresses for unspent inputs.
                gi_response = GetInputsCommand(self.adapter)(
                    seed=seed,
                    threshold=want_to_spend,
                )

                confirmed_inputs = gi_response['inputs']
            else:
                # Inputs provided.  Check to make sure we have sufficient
                # balance.
                available_to_spend = 0
                confirmed_inputs = []  # type: List[Address]

                gb_response = GetBalancesCommand(self.adapter)(
                    addresses=[i.address for i in proposed_inputs], )

                for i, balance in enumerate(gb_response.get('balances') or []):
                    input_ = proposed_inputs[i]

                    if balance > 0:
                        available_to_spend += balance

                        # Update the address balance from the API response, just in
                        # case somebody tried to cheat.
                        input_.balance = balance
                        confirmed_inputs.append(input_)

                if available_to_spend < want_to_spend:
                    raise with_context(
                        exc=BadApiResponse(
                            'Insufficient balance; found {found}, need {need} '
                            '(``exc.context`` has more info).'.format(
                                found=available_to_spend,
                                need=want_to_spend,
                            ), ),
                        context={
                            'available_to_spend': available_to_spend,
                            'confirmed_inputs': confirmed_inputs,
                            'request': request,
                            'want_to_spend': want_to_spend,
                        },
                    )

            bundle.add_inputs(confirmed_inputs)

            if bundle.balance < 0:
                if not change_address:
                    change_address =\
                      GetNewAddressesCommand(self.adapter)(seed=seed)['addresses'][0]

                bundle.send_unspent_inputs_to(change_address)

            bundle.finalize()

            if confirmed_inputs:
                bundle.sign_inputs(KeyGenerator(seed))
        else:
            bundle.finalize()

        return {
            'trytes': bundle.as_tryte_strings(),
        }
Esempio n. 5
0
class GetNewAddressesRequestFilterTestCase(BaseFilterTestCase):
    filter_type = GetNewAddressesCommand(MockAdapter()).get_request_filter
    skip_value_check = True

    # noinspection SpellCheckingInspection
    def setUp(self):
        super(GetNewAddressesRequestFilterTestCase, self).setUp()

        # Define a few tryte sequences that we can re-use between tests.
        self.seed = 'HELLOIOTA'

    def test_pass_happy_path(self):
        """
    Request is valid.
    """
        request = {
            'seed': Seed(self.seed),
            'index': 1,
            'count': 1,
            'securityLevel': 2,
            'checksum': False,
        }

        filter_ = self._filter(request)

        self.assertFilterPasses(filter_)
        self.assertDictEqual(filter_.cleaned_data, request)

    def test_pass_optional_parameters_excluded(self):
        """
    Request omits optional parameters.
    """
        filter_ = self._filter({
            'seed': Seed(self.seed),
        })

        self.assertFilterPasses(filter_)
        self.assertDictEqual(
            filter_.cleaned_data,
            {
                'seed': Seed(self.seed),
                'index': 0,
                'count': None,
                'securityLevel': AddressGenerator.DEFAULT_SECURITY_LEVEL,
                'checksum': False,
            },
        )

    def test_pass_compatible_types(self):
        """
    Request contains values that can be converted to the expected
    types.
    """
        filter_ = self._filter({
            # ``seed`` can be any TrytesCompatible value.
            'seed': bytearray(self.seed.encode('ascii')),

            # These values must be integers, however.
            'index': 100,
            'count': 8,
            'securityLevel': 2,

            # ``checksum`` must be boolean.
            'checksum': False,
        })

        self.assertFilterPasses(filter_)
        self.assertDictEqual(
            filter_.cleaned_data,
            {
                'seed': Seed(self.seed),
                'index': 100,
                'count': 8,
                'securityLevel': 2,
                'checksum': False,
            },
        )

    def test_fail_empty(self):
        """
    Request is empty.
    """
        self.assertFilterErrors(
            {},
            {
                'seed': [f.FilterMapper.CODE_MISSING_KEY],
            },
        )

    def test_fail_unexpected_parameters(self):
        """
    Request contains unexpected parameters.
    """
        self.assertFilterErrors(
            {
                'seed': Seed(self.seed),
                'index': None,
                'count': 1,
                'securityLevel': 2,
                'checksum': False,

                # Some men just want to watch the world burn.
                'foo': 'bar',
            },
            {
                'foo': [f.FilterMapper.CODE_EXTRA_KEY],
            },
        )

    def test_fail_seed_null(self):
        """
    ``seed`` is null.
    """
        self.assertFilterErrors(
            {
                'seed': None,
            },
            {
                'seed': [f.Required.CODE_EMPTY],
            },
        )

    def test_fail_seed_wrong_type(self):
        """
    ``seed`` cannot be converted into a TryteString.
    """
        self.assertFilterErrors(
            {
                'seed': 42,
            },
            {
                'seed': [f.Type.CODE_WRONG_TYPE],
            },
        )

    def test_fail_seed_malformed(self):
        """
    ``seed`` has an allowed type, but it contains invalid characters.
    """
        self.assertFilterErrors(
            {
                'seed':
                b'not valid; seeds can only contain uppercase and "9".',
            },
            {
                'seed': [Trytes.CODE_NOT_TRYTES],
            },
        )

    def test_fail_count_string(self):
        """
    ``count`` is a string value.
    """
        self.assertFilterErrors(
            {
                # Not valid; it must be an int.
                'count': '42',
                'seed': Seed(self.seed),
            },
            {
                'count': [f.Type.CODE_WRONG_TYPE],
            },
        )

    def test_fail_count_float(self):
        """
    ``count`` is a float value.
    """
        self.assertFilterErrors(
            {
                # Not valid, even with an empty fpart; it must be an int.
                'count': 42.0,
                'seed': Seed(self.seed),
            },
            {
                'count': [f.Type.CODE_WRONG_TYPE],
            },
        )

    def test_fail_count_too_small(self):
        """
    ``count`` is less than 1.
    """
        self.assertFilterErrors(
            {
                'count': 0,
                'seed': Seed(self.seed),
            },
            {
                'count': [f.Min.CODE_TOO_SMALL],
            },
        )

    def test_fail_index_string(self):
        """
    ``index`` is a string value.
    """
        self.assertFilterErrors(
            {
                # Not valid; it must be an int.
                'index': '42',
                'seed': Seed(self.seed),
            },
            {
                'index': [f.Type.CODE_WRONG_TYPE],
            },
        )

    def test_fail_index_float(self):
        """
    ``index`` is a float value.
    """
        self.assertFilterErrors(
            {
                # Not valid, even with an empty fpart; it must be an int.
                'index': 42.0,
                'seed': Seed(self.seed),
            },
            {
                'index': [f.Type.CODE_WRONG_TYPE],
            },
        )

    def test_fail_index_too_small(self):
        """
    ``index`` is less than 0.
    """
        self.assertFilterErrors(
            {
                'index': -1,
                'seed': Seed(self.seed),
            },
            {
                'index': [f.Min.CODE_TOO_SMALL],
            },
        )

    def test_fail_security_level_too_small(self):
        """
    ``securityLevel`` is < 1.
    """
        self.assertFilterErrors(
            {
                'securityLevel': 0,
                'seed': Seed(self.seed),
            },
            {
                'securityLevel': [f.Min.CODE_TOO_SMALL],
            },
        )

    def test_fail_security_level_too_big(self):
        """
    ``securityLevel`` is > 3.
    """
        self.assertFilterErrors(
            {
                'securityLevel': 4,
                'seed': Seed(self.seed),
            },
            {
                'securityLevel': [f.Max.CODE_TOO_BIG],
            },
        )

    def test_fail_security_level_wrong_type(self):
        """
    ``securityLevel`` is not an int.
    """
        self.assertFilterErrors(
            {
                'securityLevel': '2',
                'seed': Seed(self.seed),
            },
            {
                'securityLevel': [f.Type.CODE_WRONG_TYPE],
            },
        )

    def test_fail_checksum_wrong_type(self):
        """
    ``checksum`` is not a boolean.
    """
        self.assertFilterErrors(
            {
                'checksum': '2',
                'seed': Seed(self.seed),
            },
            {
                'checksum': [f.Type.CODE_WRONG_TYPE],
            },
        )