コード例 #1
0
    def test_convert_for_internal(self):
        min_return = 10
        amount_to_convert = 5
        convert_result_amount = 10
        for_address = Address.from_string("hx" + "a" * 40)

        icx_token_score_interface = \
            self.network_score.create_interface_score(self.icx_token, ProxyScore(ABCIcxToken))
        icx_token_score_interface.withdrawTo = PropertyMock()

        irc_token_score_interface = \
            self.network_score.create_interface_score(self.connector_token_list[0], ProxyScore(ABCIRCToken))
        irc_token_score_interface.transfer = PropertyMock()

        # success case: finally converted token is Icx token ( Icx token SCORE's 'withdrawTo' method should be called )
        converted_path = [
            self.connector_token_list[0], self.flexible_token_address_list[0],
            self.icx_token
        ]
        # '_convert_by_path' method returns 'to' token Address, and converted amount
        with MultiPatch([
                patch_property(IconScoreBase, 'msg',
                               Message(self.network_owner)),
                patch.object(Network,
                             '_convert_by_path',
                             return_value=(self.icx_token,
                                           convert_result_amount)),
                patch.object(Network,
                             'create_interface_score',
                             return_value=icx_token_score_interface)
        ]):
            # register icx_token
            self.network_score._icx_tokens[self.icx_token] = True

            self.network_score._convert_for_internal(converted_path,
                                                     amount_to_convert,
                                                     min_return, for_address)
            icx_token_score_interface.withdrawTo.assert_called_with(
                convert_result_amount, for_address)

        # success case: finally converted token is irc token ( token SCORE's 'transfer' method should be called )
        converted_path = [
            self.icx_token, self.flexible_token_address_list[0],
            self.connector_token_list[1]
        ]
        # '_convert_by_path' method returns 'to' token Address, and converted amount
        with MultiPatch([
                patch_property(IconScoreBase, 'msg',
                               Message(self.network_owner)),
                patch.object(Network,
                             '_convert_by_path',
                             return_value=(self.connector_token_list[1],
                                           convert_result_amount)),
                patch.object(Network,
                             'create_interface_score',
                             return_value=irc_token_score_interface)
        ]):
            self.network_score._convert_for_internal(converted_path,
                                                     amount_to_convert,
                                                     min_return, for_address)
            irc_token_score_interface.transfer.assert_called_with(
                for_address, convert_result_amount, b'None')
コード例 #2
0
    def test_check_valid_path(self):
        # success case: input the valid path
        path = [
            self.connector_token_list[0], self.flexible_token_address_list[0],
            self.connector_token_list[1]
        ]
        self.network_score._require_valid_path(path)

        # failure case: input path whose length under 3
        invalid_path = [
            self.connector_token_list[0], self.flexible_token_address_list[0]
        ]
        self.assertRaises(RevertException,
                          self.network_score._require_valid_path, invalid_path)

        # failure case: input path whose length is more than 21
        random = SystemRandom()
        # use random data to avoid same address is made
        invalid_path = [
            Address.from_string("cx" + str(random.randrange(10)) +
                                str(random.randrange(10)) * 39)
            in range(0, 22)
        ]
        self.assertRaises(RevertException,
                          self.network_score._require_valid_path, invalid_path)

        # failure case: input path whose length is even
        invalid_path = [
            self.connector_token_list[0], self.flexible_token_address_list[0],
            self.connector_token_list[1], self.flexible_token_address_list[1]
        ]
        self.assertRaises(RevertException,
                          self.network_score._require_valid_path, invalid_path)

        # failure case: input path which has the same flexible token address in it
        invalid_path = [
            self.connector_token_list[0], self.flexible_token_address_list[0],
            self.connector_token_list[1], self.flexible_token_address_list[0],
            self.connector_token_list[1]
        ]
        self.assertRaises(RevertException,
                          self.network_score._require_valid_path, invalid_path)

        # success case: input path which has the same flexible token address in the 'from' or 'to' position in it
        # path: [connector0 - flexible token0 - flexible token1 - flexible token2, flexible token0]
        path = [
            self.connector_token_list[0], self.flexible_token_address_list[0],
            self.flexible_token_address_list[1],
            self.flexible_token_address_list[2],
            self.flexible_token_address_list[0]
        ]
        self.network_score._require_valid_path(path)

        # success case: input path which has the same flexible tokens that only exist in 'from' or 'to' in it
        path = [
            self.flexible_token_address_list[0],
            self.flexible_token_address_list[1], self.connector_token_list[0],
            self.flexible_token_address_list[2],
            self.flexible_token_address_list[0]
        ]
        self.network_score._require_valid_path(path)
コード例 #3
0
ファイル: test_db.py プロジェクト: iconbetdev1/icon-service
class TestIconScoreDatabase:

    @classmethod
    def _init_context(cls, context, address: 'Address'):
        context.current_address = address
        context._inv_container = Mock()

    @classmethod
    def _set_revision(cls, context, revision: int):
        context._inv_container.revision_code = revision

    @pytest.mark.parametrize(
        "values,value_type",
        [
            ((0, 100, 200, 300), int),
            (("aa", "b", "ccc", "dddd"), str),
            ((b"aa", b"b", b"ccc", b"dddd"), bytes),
            ((True, False, True, False), bool),
            ([Address(AddressPrefix.EOA, os.urandom(20)) for _ in range(4)], Address),
        ]
    )
    def test_array_db(self, context, key_value_db, values, value_type):
        context_db = ContextDatabase(key_value_db, is_shared=False)
        address = Address(AddressPrefix.CONTRACT, os.urandom(20))
        score_db = IconScoreDatabase(address, context_db)

        self._init_context(context, score_db.address)
        self._set_revision(context, Revision.USE_RLP.value - 1)

        name = "array_db"
        array_db = ArrayDB(name, score_db, value_type)

        for i in range(2):
            array_db.put(values[i])
        assert len(array_db) == 2

        self._set_revision(context, Revision.USE_RLP.value)

        array_db.put(values[2])
        array_db.put(values[3])
        assert len(array_db) == 4

        for i, value in enumerate(array_db):
            assert value == values[i]

        final_key: bytes = _get_final_key(address, ContainerTag.ARRAY, name.encode(), use_rlp=True)
        assert key_value_db.get(final_key) == int_to_bytes(len(array_db))

        for i, use_rlp in enumerate((False, False, True, True)):
            key = _get_final_key(
                address.to_bytes(),
                ContainerTag.ARRAY.value,
                name.encode(),
                int_to_bytes(i),
                use_rlp=use_rlp,
            )
            assert key_value_db.get(key) == ContainerUtil.encode_value(values[i])

        for v in reversed(values):
            assert v == array_db.pop()
        assert len(array_db) == 0

        # 2 values for array_db size still remain
        # even though all items in array_db have been popped.
        assert len(key_value_db) == 2

    @pytest.mark.parametrize(
        "old_value,new_value,value_type",
        [
            (300, 500, int),
            ("old string", "new string", str),
            (b"old", b"new", bytes),
            (False, True, bool),
            (
                Address(AddressPrefix.EOA, os.urandom(20)),
                Address(AddressPrefix.CONTRACT, os.urandom(20)),
                Address,
            ),
        ]
    )
    def test_var_db(self, context, key_value_db, old_value, new_value, value_type):
        context_db = ContextDatabase(key_value_db, is_shared=False)
        address = Address(AddressPrefix.CONTRACT, os.urandom(20))
        score_db = IconScoreDatabase(address, context_db)

        self._init_context(context, address)
        self._set_revision(context, Revision.USE_RLP.value - 1)

        name = "var_db"

        var_db = VarDB(name, score_db, value_type)
        var_db.set(old_value)
        assert var_db.get() == old_value

        key = _get_final_key(address, ContainerTag.VAR, name.encode(), use_rlp=False)
        assert key_value_db.get(key) == ContainerUtil.encode_value(old_value)

        self._set_revision(context, Revision.USE_RLP.value)
        assert key_value_db.get(key) == ContainerUtil.encode_value(old_value)

        var_db.set(new_value)
        assert var_db.get() == new_value
        assert var_db.get() != old_value

        key = _get_final_key(address, ContainerTag.VAR, name.encode(), use_rlp=True)
        assert key_value_db.get(key) == ContainerUtil.encode_value(new_value)

        var_db.remove()
        assert var_db.get() == get_default_value(value_type)
        assert len(key_value_db) == 0

    @pytest.mark.parametrize(
        "keys",
        [
            (b"hello", 1234, "world", Address(AddressPrefix.EOA, os.urandom(20))),
        ]
    )
    @pytest.mark.parametrize(
        "old_values, new_values, value_type",
        [
            ((False, True, False, True), (True, False, True, False), bool),
            ((b"a", b"b", b"c", b"d"), (b"A", b"B", b"C", b"D"), bytes),
            ((10, 20, 30, 40), (100, 200, 300, 400), int),
            (("aa", "bb", "cc", "dd"), ("AA", "BB", "CC", "DD"), str),
            (
                [Address(AddressPrefix.EOA, os.urandom(20)) for _ in range(4)],
                [Address(AddressPrefix.CONTRACT, os.urandom(20)) for _ in range(4)],
                Address
            ),
        ]
    )
    def test_1_depth_dict_db(self, context, key_value_db, keys, old_values, new_values, value_type):
        context_db = ContextDatabase(key_value_db, is_shared=False)
        score_address = Address(AddressPrefix.CONTRACT, os.urandom(20))
        score_db = IconScoreDatabase(score_address, context_db)

        self._init_context(context, score_address)
        self._set_revision(context, Revision.USE_RLP.value - 1)

        name = "dict_db_depth_1"
        dict_db = DictDB(name, score_db, depth=1, value_type=value_type)

        # Put two items to dict_db
        for i in range(2):
            k, v = keys[i], old_values[i]

            dict_db[k] = v
            assert dict_db[k] == v

            key = _get_final_key(
                score_address, ContainerTag.DICT, name.encode(), ContainerUtil.encode_key(k),
                use_rlp=False
            )
            assert key_value_db.get(key) == ContainerUtil.encode_value(v)

        self._set_revision(context, Revision.USE_RLP.value)

        # Read old-formatted data on Revision.USE_RLP
        for i in range(2):
            k, v = keys[i], old_values[i]
            assert dict_db[k] == v

            key = _get_final_key(
                score_address, ContainerTag.DICT, name.encode(), ContainerUtil.encode_key(k),
                use_rlp=False
            )
            assert key_value_db.get(key) == ContainerUtil.encode_value(v)

        # Put 4 items to dict_db
        for i, k in enumerate(keys):
            old_v = old_values[i]
            new_v = new_values[i]
            dict_db[k] = new_v
            assert dict_db[k] == new_v
            assert dict_db[k] != old_v

            key = _get_final_key(
                score_address, ContainerTag.DICT, name.encode(), ContainerUtil.encode_key(k),
                use_rlp=True
            )
            assert key_value_db.get(key) == ContainerUtil.encode_value(new_v)

        # If there is no value for a given key, default value is returned
        for k in keys:
            del dict_db[k]
            assert dict_db[k] == get_default_value(value_type)

        assert len(key_value_db) == 0

    @pytest.mark.parametrize(
        "keys1",
        [
            (b"hello", 1234, "world", Address(AddressPrefix.EOA, os.urandom(20))),
        ]
    )
    @pytest.mark.parametrize(
        "keys2",
        [
            (b"hello2", 12345, "world2", Address(AddressPrefix.CONTRACT, os.urandom(20))),
        ]
    )
    @pytest.mark.parametrize(
        "old_values, new_values, value_type",
        [
            ((False, True, False, True), (True, False, True, False), bool),
            ((b"a", b"b", b"c", b"d"), (b"A", b"B", b"C", b"D"), bytes),
            ((10, 20, 30, 40), (100, 200, 300, 400), int),
            (("aa", "bb", "cc", "dd"), ("AA", "BB", "CC", "DD"), str),
            (
                [Address(AddressPrefix.EOA, os.urandom(20)) for _ in range(4)],
                [Address(AddressPrefix.CONTRACT, os.urandom(20)) for _ in range(4)],
                Address
            ),
        ]
    )
    def test_2_depth_dict_db(self, context, key_value_db, keys1, keys2, old_values, new_values, value_type):
        context_db = ContextDatabase(key_value_db, is_shared=False)
        score_address = Address(AddressPrefix.CONTRACT, os.urandom(20))
        score_db = IconScoreDatabase(score_address, context_db)

        self._init_context(context, score_address)
        self._set_revision(context, Revision.USE_RLP.value - 1)

        name = "dict_db_depth_2"
        dict_db = DictDB(name, score_db, depth=2, value_type=value_type)

        # To assign a value to middle-layer dict_db is forbidden
        for k1, v in zip(keys1, old_values):
            with pytest.raises(InvalidContainerAccessException):
                dict_db[k1] = v

        # Assign values to dict_db on Revision.USE_RLP - 1
        for k1 in keys1:
            for k2, v in zip(keys2, old_values):
                dict_db[k1][k2] = v

        assert len(key_value_db) == len(keys1) * len(keys2)

        for k1 in keys1:
            for k2, v in zip(keys2, old_values):
                assert dict_db[k1][k2] == v

                key: bytes = _get_final_key(
                    score_address,
                    ContainerTag.DICT, name.encode(),
                    ContainerTag.DICT, ContainerUtil.encode_key(k1),
                    ContainerUtil.encode_key(k2),
                    use_rlp=False
                )
                assert key_value_db.get(key) == ContainerUtil.encode_value(v)

        self._set_revision(context, Revision.USE_RLP.value)

        # Check if reading old-formatted key:value data works on Revision.USE_RLP
        for k1 in keys1:
            for k2, v in zip(keys2, old_values):
                assert dict_db[k1][k2] == v

        # Replace all old_values with new_values on Revision.USE_RLP
        for k1 in keys1:
            for k2, v in zip(keys2, new_values):
                dict_db[k1][k2] = v

        # old_values + new_values
        assert len(key_value_db) == len(keys1) * len(keys2) * 2

        for k1 in keys1:
            for k2, v in zip(keys2, new_values):
                assert dict_db[k1][k2] == v

                key: bytes = _get_final_key(
                    score_address,
                    ContainerTag.DICT, name.encode(),
                    ContainerUtil.encode_key(k1),
                    ContainerUtil.encode_key(k2),
                    use_rlp=True
                )
                assert key_value_db.get(key) == ContainerUtil.encode_value(v)

        for k1 in keys1:
            for k2 in keys2:
                del dict_db[k1][k2]
                assert dict_db[k1][k2] == get_default_value(value_type)

        assert len(key_value_db) == 0

    @pytest.mark.parametrize(
        "prefixes", [
            (),
            (b"prefix0",),
            (b"prefix0", b"prefix1"),
            (b"prefix0", b"prefix1", b"prefix2"),
        ]
    )
    @pytest.mark.parametrize(
        "old_values,new_values", [
            (
                (True, b"hello", 100, "world", Address(AddressPrefix.EOA, os.urandom(20))),
                (False, b"world", 1234, "helloworld", Address(AddressPrefix.CONTRACT, os.urandom(20))),
            )
        ],
    )
    def test_score_db(self, context, key_value_db, prefixes, old_values, new_values):
        context_db = ContextDatabase(key_value_db, is_shared=False)
        score_address = Address(AddressPrefix.CONTRACT, os.urandom(20))
        score_db = IconScoreDatabase(score_address, context_db)
        args = [score_address]

        self._init_context(context, score_address)
        self._set_revision(context, Revision.USE_RLP.value - 1)

        for prefix in prefixes:
            score_db = score_db.get_sub_db(prefix)
            args.append(prefix)

        for i, value in enumerate(old_values):
            key: bytes = f"key{i}".encode()
            encoded_value: bytes = ContainerUtil.encode_value(value)
            score_db.put(key, encoded_value)
            assert score_db.get(key) == encoded_value

            final_key: bytes = _get_final_key(*args, key, use_rlp=False)
            assert key_value_db.get(final_key) == encoded_value

        self._set_revision(context, Revision.USE_RLP.value)

        for i, value in enumerate(old_values):
            key: bytes = f"key{i}".encode()
            encoded_value: bytes = ContainerUtil.encode_value(value)
            assert score_db.get(key) == encoded_value

            final_key: bytes = _get_final_key(*args, key, use_rlp=False)
            assert key_value_db.get(final_key) == encoded_value

        for i, value in enumerate(new_values):
            key: bytes = f"key{i}".encode()
            encoded_value: bytes = ContainerUtil.encode_value(value)
            score_db.put(key, encoded_value)

            assert score_db.get(key) == encoded_value

            final_key: bytes = _get_final_key(*args, key, use_rlp=True)
            assert key_value_db.get(final_key) == encoded_value

            score_db.delete(key)
            assert score_db.get(key) is None
            assert key_value_db.get(final_key) is None
コード例 #4
0
    def test_tokenFallback(self):
        # success case: input 'conversionResult' to _data ( convert_for_internal should not be called )
        from_address = Address.from_string("hx" + "a" * 40)
        for_address = Address.from_string("hx" + "b" * 40)
        value = 10
        min_return = 5
        path = "{0},{1},{2}".format(str(self.connector_token_list[0]),
                                    str(self.flexible_token_address_list[0]),
                                    str(self.connector_token_list[1]))
        converted_path = [
            Address.from_string(address) for address in path.split(",")
        ]

        data = dict()
        data["path"] = path
        data["minReturn"] = min_return
        data["for"] = str(for_address)
        stringed_data = json.dumps(data)
        decoded_data = stringed_data.encode(encoding='utf-8')

        with MultiPatch([
                patch_property(IconScoreBase, 'msg',
                               Message(self.connector_token_list[0])),
                patch.object(Network, '_convert_for_internal')
        ]):
            self.network_score.tokenFallback(from_address, value,
                                             b'conversionResult')
            self.network_score._convert_for_internal.assert_not_called()

        # failure case: input None data to the _data
        with MultiPatch([
                patch_property(IconScoreBase, 'msg',
                               Message(self.connector_token_list[0])),
                patch.object(Network, '_convert_for_internal')
        ]):
            self.assertRaises(RevertException,
                              self.network_score.tokenFallback, from_address,
                              value, b'None')

            self.assertRaises(RevertException,
                              self.network_score.tokenFallback, from_address,
                              value, None)

        # failure case: msg.sender is not equal to path[0] ( should be equal )
        msg_sender = Address.from_string("cx" + "c" * 40)
        with MultiPatch([
                patch_property(IconScoreBase, 'msg', Message(msg_sender)),
                patch.object(Network, '_convert_for_internal')
        ]):
            self.assertRaises(RevertException,
                              self.network_score.tokenFallback, from_address,
                              value, decoded_data)

        # success case: input valid data
        with MultiPatch([
                patch_property(IconScoreBase, 'msg',
                               Message(self.connector_token_list[0])),
                patch.object(Network, '_convert_for_internal'),
                patch.object(Network, '_require_valid_path'),
                patch('contracts.network.network.require_positive_value'),
                patch('contracts.network.network.require_valid_address'),
        ]) as mocks:
            self.network_score.tokenFallback(from_address, value, decoded_data)
            mocks[3].assert_called()  # patched mock of require_positive_value
            mocks[4].assert_called()  # patched mock of require_valid_address
            self.network_score._require_valid_path.assert_called_with(
                converted_path)
            self.network_score._convert_for_internal. \
                assert_called_with(converted_path, value, min_return, for_address)
コード例 #5
0
 def test_address_from_to_bytes_EOA(self):
     addr1 = create_address()
     buf = addr1.to_bytes()
     addr2 = Address.from_bytes(buf)
     self.assertEqual(addr1, addr2)
コード例 #6
0
 def test_address_from_to_string_EOA(self):
     addr1 = create_address()
     buf = str(addr1)
     addr2 = Address.from_string(buf)
     self.assertEqual(addr1, addr2)
コード例 #7
0
 def test_from_string_invalid(self, address):
     with pytest.raises(BaseException) as e:
         Address.from_string(address)
     assert e.value.code == ExceptionCode.INVALID_PARAMETER
     assert e.value.message == "Invalid address"
コード例 #8
0
 def test_address_from_to_string_CONTRACT(self):
     addr1 = create_address(prefix=1)
     buf = str(addr1)
     addr2 = Address.from_string(buf)
     self.assertEqual(addr1, addr2)
コード例 #9
0
 def test_address_from_to_bytes(self, prefix):
     addr1 = create_address(prefix)
     buf = addr1.to_bytes()
     addr2 = Address.from_bytes(buf)
     assert addr1 == addr2
コード例 #10
0
 def test_address_from_to_string(self, prefix):
     addr1 = create_address(prefix=prefix)
     buf = str(addr1)
     addr2 = Address.from_string(buf)
     assert addr1 == addr2
コード例 #11
0
 def test_prefix_and_int(self):
     assert Address.from_prefix_and_int(AddressPrefix.CONTRACT, 0) == ZERO_SCORE_ADDRESS
     assert Address.from_prefix_and_int(AddressPrefix.CONTRACT, 1) == GOVERNANCE_SCORE_ADDRESS
     assert str(Address.from_prefix_and_int(AddressPrefix.EOA, 10)) == "hx000000000000000000000000000000000000000a"
     assert str(Address.from_prefix_and_int(AddressPrefix.CONTRACT, 1024)) == \
            "cx0000000000000000000000000000000000000400"
コード例 #12
0
    def test_install_step(self):
        # Ignores deploy
        deploy_engine_invoke = Mock()
        IconScoreContext.engine.deploy.invoke = deploy_engine_invoke

        tx_hash1: str = bytes.hex(create_tx_hash())
        from_ = create_address(AddressPrefix.EOA)
        to_ = Address.from_string('cx0000000000000000000000000000000000000000')
        content_type = 'application/zip'
        data = {
            'contentType': content_type,
            'content': '0x1867291283973610982301923812873419826abcdef9182731',
        }

        request1 = create_request([
            ReqData(tx_hash1, from_, to_, 0, 'deploy', data),
        ])

        # for StepType.CONTRACT_CREATE
        result = self._inner_task_invoke(request1)
        self.assertEqual(result['txResults'][tx_hash1]['status'], '0x1')

        # for StepType.CONTRACT_UPDATE
        to_ = result['txResults'][tx_hash1]['scoreAddress']
        tx_hash2: str = bytes.hex(create_tx_hash())

        request2 = create_request([
            ReqData(tx_hash2, from_, to_, 0, 'deploy', data),
        ])

        result = self._inner_task_invoke(request2)
        self.assertEqual(result['txResults'][tx_hash2]['status'], '0x1')

        deploy_engine_invoke.assert_called()

        input_length = (len(content_type.encode('utf-8')) + 25)

        call_args_for_apply_step = self.step_counter.apply_step.call_args_list

        self.assertEqual((StepType.DEFAULT, 1), call_args_for_apply_step[0][0])
        self.assertEqual((StepType.INPUT, input_length),
                         call_args_for_apply_step[1][0])
        self.assertEqual((StepType.CONTRACT_CREATE, 1),
                         call_args_for_apply_step[2][0])
        self.assertEqual((StepType.CONTRACT_SET, 25),
                         call_args_for_apply_step[3][0])
        self.assertEqual((StepType.DEFAULT, 1), call_args_for_apply_step[4][0])
        self.assertEqual((StepType.INPUT, input_length),
                         call_args_for_apply_step[5][0])
        self.assertEqual((StepType.CONTRACT_UPDATE, 1),
                         call_args_for_apply_step[6][0])
        self.assertEqual((StepType.CONTRACT_SET, 25),
                         call_args_for_apply_step[7][0])
        self.assertEqual(8, len(call_args_for_apply_step))

        step_used_create = self._calc_step_used(0, 4)
        step_used_update = self._calc_step_used(4, 4)

        # check SCORE install stepUsed value
        self._assert_step_used(step_used_create, request1, tx_hash1)

        # check SCORE update stepUsed value
        self._assert_step_used(step_used_update, request2, tx_hash2)
コード例 #13
0
ファイル: test_db.py プロジェクト: iconbetdev1/icon-service
    def test_2_depth_dict_db(self, context, key_value_db, keys1, keys2, old_values, new_values, value_type):
        context_db = ContextDatabase(key_value_db, is_shared=False)
        score_address = Address(AddressPrefix.CONTRACT, os.urandom(20))
        score_db = IconScoreDatabase(score_address, context_db)

        self._init_context(context, score_address)
        self._set_revision(context, Revision.USE_RLP.value - 1)

        name = "dict_db_depth_2"
        dict_db = DictDB(name, score_db, depth=2, value_type=value_type)

        # To assign a value to middle-layer dict_db is forbidden
        for k1, v in zip(keys1, old_values):
            with pytest.raises(InvalidContainerAccessException):
                dict_db[k1] = v

        # Assign values to dict_db on Revision.USE_RLP - 1
        for k1 in keys1:
            for k2, v in zip(keys2, old_values):
                dict_db[k1][k2] = v

        assert len(key_value_db) == len(keys1) * len(keys2)

        for k1 in keys1:
            for k2, v in zip(keys2, old_values):
                assert dict_db[k1][k2] == v

                key: bytes = _get_final_key(
                    score_address,
                    ContainerTag.DICT, name.encode(),
                    ContainerTag.DICT, ContainerUtil.encode_key(k1),
                    ContainerUtil.encode_key(k2),
                    use_rlp=False
                )
                assert key_value_db.get(key) == ContainerUtil.encode_value(v)

        self._set_revision(context, Revision.USE_RLP.value)

        # Check if reading old-formatted key:value data works on Revision.USE_RLP
        for k1 in keys1:
            for k2, v in zip(keys2, old_values):
                assert dict_db[k1][k2] == v

        # Replace all old_values with new_values on Revision.USE_RLP
        for k1 in keys1:
            for k2, v in zip(keys2, new_values):
                dict_db[k1][k2] = v

        # old_values + new_values
        assert len(key_value_db) == len(keys1) * len(keys2) * 2

        for k1 in keys1:
            for k2, v in zip(keys2, new_values):
                assert dict_db[k1][k2] == v

                key: bytes = _get_final_key(
                    score_address,
                    ContainerTag.DICT, name.encode(),
                    ContainerUtil.encode_key(k1),
                    ContainerUtil.encode_key(k2),
                    use_rlp=True
                )
                assert key_value_db.get(key) == ContainerUtil.encode_value(v)

        for k1 in keys1:
            for k2 in keys2:
                del dict_db[k1][k2]
                assert dict_db[k1][k2] == get_default_value(value_type)

        assert len(key_value_db) == 0
コード例 #14
0
    def test_handle_get_prep_term_with_penalized_preps(self):
        block_height = 200
        sequence = 78
        period = 43120
        start_block_height = 200
        end_block_height = 200 + period - 1
        irep = icx_to_loop(40000)
        total_supply = icx_to_loop(800_460_000)
        total_delegated = icx_to_loop(1000)

        params = {}

        context = Mock()
        context.block.height = block_height

        main_prep_count = 22
        elected_prep_count = 100
        total_prep_count = 106

        term = Term(sequence=sequence,
                    start_block_height=start_block_height,
                    period=period,
                    irep=irep,
                    total_supply=total_supply,
                    total_delegated=total_delegated)

        preps = PRepContainer()
        for i in range(total_prep_count):
            address = Address.from_prefix_and_int(AddressPrefix.EOA, i)
            delegated = icx_to_loop(1000 - i)
            penalty = PenaltyReason.NONE
            status = PRepStatus.ACTIVE

            if 0 <= i <= 4:
                # block validation penalty preps: 5
                penalty: 'PenaltyReason' = PenaltyReason.BLOCK_VALIDATION
            elif i == 5:
                # unregistered preps: 1
                status = PRepStatus.UNREGISTERED
            elif 6 <= i <= 7:
                # low productivity preps: 2
                status = PRepStatus.DISQUALIFIED
                penalty = PenaltyReason.LOW_PRODUCTIVITY
            elif 8 <= i <= 10:
                # disqualified preps: 3
                status = PRepStatus.DISQUALIFIED
                penalty = PenaltyReason.PREP_DISQUALIFICATION

            prep = PRep(address,
                        block_height=i,
                        delegated=delegated,
                        penalty=penalty,
                        status=status)
            prep.freeze()
            preps.add(prep)

        preps.freeze()
        assert preps.size(active_prep_only=False) == total_prep_count

        electable_preps = filter(lambda x: x.is_electable(), preps)
        term.set_preps(electable_preps,
                       main_prep_count=main_prep_count,
                       elected_prep_count=elected_prep_count)

        engine = PRepEngine()
        engine.term = term
        engine.preps = preps

        ret: dict = engine.handle_get_prep_term(context, params)

        assert ret["blockHeight"] == block_height
        assert ret["sequence"] == sequence
        assert ret["startBlockHeight"] == start_block_height
        assert ret["endBlockHeight"] == end_block_height
        assert ret["totalSupply"] == total_supply
        assert ret["totalDelegated"] == total_delegated
        assert ret["irep"] == irep

        prep_list: List[Dict[str, Union[int, str, 'Address']]] = ret["preps"]
        assert len(prep_list) == elected_prep_count

        for i, prep_snapshot in enumerate(term.preps):
            prep_item: Dict[str, Union[int, str, 'Address']] = prep_list[i]
            assert prep_item["address"] == prep_snapshot.address
            assert prep_item["status"] == PRepStatus.ACTIVE.value
            assert prep_item["penalty"] == PenaltyReason.NONE.value

        # The P-Reps which got penalized for consecutive 660 block validation failure
        # are located at the end of the P-Rep list
        prev_delegated = -1
        for i, prep_item in enumerate(prep_list[-5:]):
            assert prep_item["address"] == Address.from_prefix_and_int(
                AddressPrefix.EOA, i)
            assert prep_item["status"] == PRepStatus.ACTIVE.value
            assert prep_item["penalty"] == PenaltyReason.BLOCK_VALIDATION.value

            delegated: int = prep_item["delegated"]
            if prev_delegated >= 0:
                assert prev_delegated >= delegated

            prev_delegated = delegated
コード例 #15
0
def create_address(prefix: AddressPrefix = AddressPrefix.EOA) -> 'Address':
    return Address.from_bytes(prefix.to_bytes(1, 'big') + os.urandom(20))
コード例 #16
0
ファイル: __init__.py プロジェクト: stjordanis/icon-service
def create_address(prefix: int = 0, data: bytes=None) -> 'Address':
    if data is None:
        data = create_tx_hash()
    hash_value = hashlib.sha3_256(data).digest()
    return Address(AddressPrefix(prefix), hash_value[-20:])
コード例 #17
0
    def __init__(self, wallet: 'KeyWallet', balance: int = 0):
        self._wallet: 'KeyWallet' = wallet
        self.balance: int = balance

        self._address: 'Address' = Address.from_string(self._wallet.get_address())
コード例 #18
0
 def test_invalid_address(self):
     address: str = "hx123456"
     with self.assertRaises(BaseException) as e:
         Address.from_string(address)
     self.assertEqual(e.exception.code, ExceptionCode.INVALID_PARAMETER)
     self.assertEqual(e.exception.message, "Invalid address")
コード例 #19
0
    def test_check_and_convert_bytes_data(self):
        # failure case: input invalid JSON format data
        invalid_json_format = dict()
        invalid_json_format["path"] = "{0},{1},{2}".format(
            str(self.connector_token_list[0]),
            str(self.flexible_token_address_list[0]),
            str(self.connector_token_list[1]))
        invalid_json_format["for"] = str(self.network_owner)
        invalid_json_format["minReturn"] = 10
        stringed_invalid_json_format = "[" + json.dumps(
            invalid_json_format) + "}"
        encoded_invalid_json_format = stringed_invalid_json_format.encode(
            encoding="utf-8")
        self.assertRaises(RevertException,
                          self.network_score._convert_bytes_data,
                          encoded_invalid_json_format, self.network_owner)

        # failure case: input data which is not decoded to utf-8
        valid_json_format = dict()
        valid_json_format["path"] = "{0},{1},{2}".format(
            str(self.connector_token_list[0]),
            str(self.flexible_token_address_list[0]),
            str(self.connector_token_list[1]))

        valid_json_format["for"] = str(self.network_owner)
        valid_json_format["minReturn"] = 10
        stringed_valid_json_format = json.dumps(valid_json_format)
        cp037_encoded_valid_json_format = stringed_valid_json_format.encode(
            encoding='cp037')
        self.assertRaises(RevertException,
                          self.network_score._convert_bytes_data,
                          cp037_encoded_valid_json_format, self.network_owner)

        # failure case: input invalid path data (associated with '/')
        json_format = dict()
        json_format["path"] = "{0}/{1}/{2}".format(
            str(self.connector_token_list[0]),
            str(self.flexible_token_address_list[0]),
            str(self.connector_token_list[1]))
        json_format["for"] = str(self.network_owner)
        json_format["minReturn"] = 10
        stringed_valid_json_format = json.dumps(json_format)
        encoded_valid_json_format = stringed_valid_json_format.encode(
            encoding='utf-8')
        self.assertRaises(InvalidParamsException,
                          self.network_score._convert_bytes_data,
                          encoded_valid_json_format, self.network_owner)

        # failure case: input invalid path data ( has an invalid address as an element )
        json_format = dict()
        json_format["path"] = "{0},{1},{2}".format(
            str(self.connector_token_list[0]), str("invalid_address"),
            str(self.connector_token_list[1]))
        json_format["for"] = str(self.network_owner)
        json_format["minReturn"] = 10
        stringed_valid_json_format = json.dumps(json_format)
        encoded_valid_json_format = stringed_valid_json_format.encode(
            encoding='utf-8')
        self.assertRaises(InvalidParamsException,
                          self.network_score._convert_bytes_data,
                          encoded_valid_json_format, self.network_owner)

        # failure case: input string type minReturn
        json_format = dict()
        json_format["path"] = "{0},{1},{2}".format(
            str(self.connector_token_list[0]),
            str(self.flexible_token_address_list[0]),
            str(self.connector_token_list[1]))
        json_format["for"] = str(self.network_owner)
        json_format["minReturn"] = "10"
        stringed_valid_json_format = json.dumps(json_format)
        encoded_valid_json_format = stringed_valid_json_format.encode(
            encoding='utf-8')
        self.assertRaises(RevertException,
                          self.network_score._convert_bytes_data,
                          encoded_valid_json_format, self.network_owner)

        # success case: "for" key is not in the data
        # ( returned data should have token sender address as a "for" key's value )
        token_sender = Address.from_string("hx" + "a" * 40)
        json_format = dict()
        json_format["path"] = "{0},{1},{2}".format(
            str(self.connector_token_list[0]),
            str(self.flexible_token_address_list[0]),
            str(self.connector_token_list[1]))
        json_format["minReturn"] = 10
        stringed_valid_json_format = json.dumps(json_format)
        encoded_valid_json_format = stringed_valid_json_format.encode(
            encoding='utf-8')
        result_data = self.network_score._convert_bytes_data(
            encoded_valid_json_format, token_sender)
        self.assertEqual(token_sender, result_data["for"])

        # success case: "for" key is exist but value is None
        # ( returned dict data should have token sender address as a "for" key's value )
        json_format["for"] = None
        stringed_valid_json_format = json.dumps(json_format)
        encoded_valid_json_format = stringed_valid_json_format.encode(
            encoding='utf-8')
        result_data = self.network_score._convert_bytes_data(
            encoded_valid_json_format, token_sender)
        self.assertEqual(token_sender, result_data["for"])

        # success case: input data which has "for" key and it's value
        for_address = Address.from_string("hx" + "b" * 40)
        json_format["for"] = str(for_address)
        stringed_valid_json_format = json.dumps(json_format)
        encoded_valid_json_format = stringed_valid_json_format.encode(
            encoding='utf-8')
        result_data = self.network_score._convert_bytes_data(
            encoded_valid_json_format, token_sender)
        self.assertEqual(for_address, result_data["for"])
コード例 #20
0
 def test_address_from_to_bytes_CONTRACT(self):
     addr1 = create_address(prefix=1)
     buf = addr1.to_bytes()
     addr2 = Address.from_bytes(buf)
     self.assertEqual(addr1, addr2)
コード例 #21
0
    def test_convertFor(self):
        icx_amount = 10

        # failure case: input wrong path format
        min_return = 10
        for_address = Address.from_string("hx" + "a" * 40)
        invalid_path = "{0}/{1}/{2}".format(
            str(self.icx_token), str(self.flexible_token_address_list[0]),
            str(self.connector_token_list[0]))
        with patch_property(IconScoreBase, 'msg',
                            Message(self.network_owner, value=icx_amount)):
            self.assertRaises(InvalidParamsException,
                              self.network_score.convertFor, invalid_path,
                              min_return, for_address)

        # failure case: input path whose has invalid address as an element
        min_return = 10
        for_address = Address.from_string("hx" + "a" * 40)
        invalid_path = "{0},{1},{2}".format(str(self.icx_token),
                                            str("invalid_address"),
                                            str(self.connector_token_list[1]))
        with patch_property(IconScoreBase, 'msg',
                            Message(self.network_owner, value=icx_amount)):
            self.assertRaises(InvalidParamsException,
                              self.network_score.convertFor, invalid_path,
                              min_return, for_address)

        # failure case: input min return less than 0
        invalid_min_return = -1
        for_address = Address.from_string("hx" + "a" * 40)
        path = "{0},{1},{2}".format(str(self.icx_token),
                                    str(self.flexible_token_address_list[0]),
                                    str(self.connector_token_list[0]))
        with patch_property(IconScoreBase, 'msg',
                            Message(self.network_owner, value=icx_amount)):
            self.assertRaises(RevertException, self.network_score.convertFor,
                              path, invalid_min_return, for_address)

        # failure case: input path whose first address is not Icx token address
        min_return = 10
        for_address = Address.from_string("hx" + "a" * 40)
        invalid_path = "{0},{1},{2}".format(
            str(self.connector_token_list[0]),
            str(self.flexible_token_address_list[0]),
            str(self.connector_token_list[1]))
        with patch_property(IconScoreBase, 'msg',
                            Message(self.network_owner, value=icx_amount)):
            self.assertRaises(RevertException, self.network_score.convertFor,
                              invalid_path, min_return, for_address)

        # success case: input valid path
        min_return = 10
        for_address = Address.from_string("hx" + "a" * 40)
        path = "{0},{1},{2}".format(str(self.icx_token),
                                    str(self.flexible_token_address_list[0]),
                                    str(self.connector_token_list[1]))
        self.network_score._icx_tokens[self.icx_token] = True
        with MultiPatch([
                patch_property(IconScoreBase, 'msg',
                               Message(self.network_owner, value=icx_amount)),
                patch.object(Network, '_convert_for_internal')
        ]):
            self.network_score.convertFor(path, min_return, for_address)
            self.network_score.icx.transfer.assert_called_with(
                self.icx_token, icx_amount)
            converted_path = [
                self.icx_token, self.flexible_token_address_list[0],
                self.connector_token_list[1]
            ]
            self.network_score._convert_for_internal.assert_called_with(
                converted_path, icx_amount, min_return, for_address)
コード例 #22
0
    335020, 327218, 319680, 312407, 305398,
    298653, 292173, 285958, 280007, 274320,
    268898, 263740, 258847, 254219, 249855,
    245755, 241920, 238349, 235043, 232002,
    229224, 226712, 224464, 222480, 220761,
    219306, 218116, 217190, 216529, 216132,
    216000, 216000, 216000, 216000, 216000,
    216000, 216000, 216000, 216000, 216000,
    216000, 216000, 216000, 216000, 216000,
    216000, 216000, 216000, 216000, 216000,
    216000, 216000, 216000, 216000, 216000,
    216000, 216000, 216000, 216000, 216000
]


SENDER_ADDRESS = Address.from_prefix_and_int(AddressPrefix.EOA, 0)


def create_account(
        address: 'Address', balance: int,
        stake: int, unstake: int, unstake_block_height: int,
        delegated_amount: int, delegations: List[Tuple[Address, int]]) -> 'Account':
    coin_part = CoinPart(balance=balance)
    stake_part = StakePart(stake, unstake, unstake_block_height)
    delegation_part = DelegationPart(delegated_amount, delegations)

    return Account(
        address, 1024,
        coin_part=coin_part,
        stake_part=stake_part,
        delegation_part=delegation_part)
コード例 #23
0
class TestEventLog:
    def test_parse_signature(self):
        signature = "Transfer(Address,Address,int)"
        name, types = EventLog.parse_signature(signature)
        assert name == "Transfer"
        assert types == ["Address", "Address", "int"]

    def test_from_dict_with_transfer_event_log(self):
        signature = "Transfer(Address,Address,int)"
        score_address = Address.from_string(
            "cx4d6f646441a3f9c9b91019c9b98e3c342cceb114"
        )
        indexed_address_0 = Address.from_data(AddressPrefix.EOA, b"address0")
        indexed_address_1 = Address.from_data(AddressPrefix.EOA, b"address1")
        value = 0x8AC7230489E80000

        event_log_data = {
            "scoreAddress": str(score_address),
            "indexed": [
                signature,
                str(indexed_address_0),
                str(indexed_address_1),
                hex(value),
            ],
            "data": [],
        }

        event_log = EventLog.from_dict(event_log_data)
        assert event_log.signature == signature
        assert event_log.score_address == score_address
        assert event_log.indexed[0] == signature
        assert len(event_log.indexed) == 4
        assert event_log.indexed[1] == indexed_address_0
        assert event_log.indexed[2] == indexed_address_1
        assert event_log.indexed[3] == value
        assert len(event_log.data) == 0

    def test_from_dict_with_iscore_claimed_log(self):
        signature = "IScoreClaimed(int,int)"
        score_address = Address.from_string(
            "cx0000000000000000000000000000000000000000"
        )
        iscore = 0x186A0  # unit: iscore
        icx = 0x64  # unit: loop

        event_log_data = {
            "scoreAddress": str(score_address),
            "indexed": [signature],
            "data": [hex(iscore), hex(icx)],
        }

        event_log = EventLog.from_dict(event_log_data)
        assert event_log.signature == signature
        assert event_log.score_address == score_address
        assert len(event_log.indexed) == 1
        assert event_log.indexed[0] == signature
        assert len(event_log.data) == 2
        assert event_log.data[0] == iscore
        assert event_log.data[1] == icx

    @pytest.mark.parametrize(
        "indexed,data",
        [
            (
                [
                    "Transfer(Address,Address,int)",
                    Address.from_prefix_and_int(AddressPrefix.EOA, 0),
                    Address.from_prefix_and_int(AddressPrefix.EOA, 1),
                ],
                [random.randint(0, 99999)],
            ),
            (["IScoreClaimed(int,int)"], [10_000, 10],),
        ],
    )
    def test_serializable(self, indexed, data):
        score_address = Address(AddressPrefix.CONTRACT, os.urandom(20))

        expected = EventLog(score_address, indexed, data)
        event_log = EventLog.from_bytes(expected.to_bytes())
        assert event_log == expected
        assert event_log.indexed == indexed
        assert event_log.data == data