Exemple #1
0
    def test_calc_delegations(self):
        cached_accounts: Dict['Address', Tuple['Account', int]] = OrderedDict()
        context = Mock()
        context.storage.icx.get_account = Mock(side_effect=get_account)

        new_delegations: List[Tuple['Address', int]] = []
        for i in range(10):
            value: int = i + 11
            address = Address.from_prefix_and_int(AddressPrefix.EOA, value)
            new_delegations.append((address, value))

        sender_account = context.storage.icx.get_account(context, SENDER_ADDRESS, Intent.ALL)
        cached_accounts[SENDER_ADDRESS] = sender_account, 0

        # Prepare old delegations
        for i in range(10):
            value: int = i + 1
            address = Address.from_prefix_and_int(AddressPrefix.EOA, value)
            account = context.storage.icx.get_account(context, address, Intent.DELEGATED)
            cached_accounts[address] = account, -value

        IISSEngine._calc_delegations(context, new_delegations, cached_accounts)
        # 0: sender_account, 1~10: old_accounts 11~20: new_accounts

        for i, address in enumerate(cached_accounts):
            account, delegated_offset = cached_accounts[address]
            assert account.address == address

            if i == 0:
                assert address == SENDER_ADDRESS
                assert delegated_offset == 0
            elif 1 <= i <= 10:
                assert delegated_offset == -i
            else:  # 11 <= i <= 20
                assert delegated_offset == i
Exemple #2
0
    def test_get_old_delegations_from_sender_account(self):
        cached_accounts: Dict['Address', Tuple['Account', int]] = {}
        context = Mock()
        context.storage.icx.get_account = Mock(side_effect=get_account)

        sender_account = context.storage.icx.get_account(context, SENDER_ADDRESS, Intent.ALL)
        cached_accounts[SENDER_ADDRESS] = sender_account, 0

        # Get old delegations from delegating accounts
        IISSEngine._get_old_delegations_from_sender_account(context, SENDER_ADDRESS, cached_accounts)
        assert len(cached_accounts) == 11  # sender_account(1) + old delegated_accounts(10)

        for i, address in enumerate(cached_accounts):
            item: Tuple['Account', int] = cached_accounts[address]
            account = item[0]
            delegated_offset = item[1]

            assert address == account.address

            if i == 0:
                assert delegated_offset == 0
            else:
                delegation: Tuple['Account', int] = sender_account.delegations[i - 1]
                assert address == delegation[0]
                assert delegated_offset == -delegation[1]
Exemple #3
0
    def test_convert_params_of_set_delegation_with_duplicate_address(self, context):
        delegations = []

        for i in range(2):
            address = Address.from_prefix_and_int(AddressPrefix.EOA, 1)
            value = random.randint(1, 100)

            delegations.append({"address": address, "value": value})

        with pytest.raises(InvalidParamsException):
            IISSEngine._convert_params_of_set_delegation(context, delegations)
Exemple #4
0
    def test_convert_params_of_set_delegation_with_value_less_than_0(self, context):
        delegations = []

        values = [1, 2, 3, 4, -100]

        for i in range(5):
            address = Address.from_prefix_and_int(AddressPrefix.EOA, i + 1)
            value = values[i]

            delegations.append({"address": address, "value": value})

        with pytest.raises(InvalidParamsException):
            IISSEngine._convert_params_of_set_delegation(context, delegations)
Exemple #5
0
    def test_check_voting_power_is_enough_with_not_enough_stake(self):
        def _get_account(_context: 'IconScoreContext',
                         _address: 'Address',
                         _intent: 'Intent' = Intent.TRANSFER) -> 'Account':
            return create_sender_account(stake=100)

        cached_accounts: Dict['Address', Tuple['Account', int]] = {}
        context = Mock()
        context.storage.icx.get_account = Mock(side_effect=_get_account)
        total_delegating = sum(range(11, 21))  # new_delegations

        with pytest.raises(InvalidRequestException):
            IISSEngine._check_voting_power_is_enough(
                context, SENDER_ADDRESS, total_delegating, cached_accounts)
Exemple #6
0
    def test_convert_params_of_set_delegation_with_too_many_delegations(self, context):
        max_delegations: int = self._get_expected_max_delegations(context)
        delegations = []

        for i in range(max_delegations + 1):
            address = Address.from_prefix_and_int(AddressPrefix.EOA, i + 1)
            value = random.randint(1, 10_000)

            delegations.append({
                "address": str(address),
                "value": hex(value)
            })

        with pytest.raises(InvalidParamsException):
            IISSEngine._convert_params_of_set_delegation(context, delegations)
Exemple #7
0
    def test_handle_set_delegation_with_1_account(self):
        context = Mock()
        context.revision = Revision.DECENTRALIZATION.value
        context.tx.origin = SENDER_ADDRESS
        context.msg = Message(SENDER_ADDRESS, 0)
        context.storage.icx.get_account = Mock(side_effect=get_account)

        new_delegations = [{
            "address": Address.from_prefix_and_int(AddressPrefix.EOA, 1),
            "value": 100
        }]

        class IISSEngineListenerImpl(IISSEngineListener):
            def on_set_stake(self, _context: 'IconScoreContext', account: 'Account'):
                assert False

            def on_set_delegation(self, _context: 'IconScoreContext', updated_accounts: List['Account']):
                # sender_account(1) + updated_delegated_account(10)
                assert len(updated_accounts) == 11

                delegated_address = Address.from_prefix_and_int(AddressPrefix.EOA, 1)

                for i, account in enumerate(updated_accounts):
                    assert isinstance(account, Account)
                    address = account.address

                    if i == 0:
                        # sender_account
                        assert account.delegated_amount == 0
                        assert len(account.delegations) == 1
                        assert account.delegation_part.delegations_amount == 100

                        item = account.delegations[0]
                        assert item[0] == Address.from_prefix_and_int(AddressPrefix.EOA, 1)
                        assert item[1] == 100
                    else:
                        assert account.delegations_amount == 0

                        if address == delegated_address:
                            assert account.delegated_amount == 100
                        else:
                            assert account.delegated_amount == 0

        engine = IISSEngine()
        engine.add_listener(IISSEngineListenerImpl())
        engine.handle_set_delegation(context, new_delegations)
Exemple #8
0
 def test_calculate_unstake_lock_period(self):
     lmin = IISS_DAY_BLOCK * 5
     lmax = IISS_DAY_BLOCK * 20
     rpoint = 7000
     for x in range(0, 100):
         ret = IISSEngine._calculate_unstake_lock_period(lmin, lmax, rpoint, x, 100)
         diff = abs(ret - EXPECTED_LOCK_PERIOD_PRE_STAKE_PERCENT[x])
         assert diff <= 1
Exemple #9
0
    def test_handle_set_delegation_with_21_accounts(self):
        context = Mock()
        context.revision = Revision.DECENTRALIZATION.value
        context.tx.origin = SENDER_ADDRESS
        context.msg = Message(SENDER_ADDRESS, 0)
        context.storage.icx.get_account = Mock(side_effect=get_account)
        total_delegating, delegations = create_delegations_param()

        class IISSEngineListenerImpl(IISSEngineListener):
            def on_set_stake(self, _context: 'IconScoreContext', account: 'Account'):
                assert False

            def on_set_delegation(self, _context: 'IconScoreContext', updated_accounts: List['Account']):
                assert len(updated_accounts) == 21

                for i, account in enumerate(updated_accounts):
                    assert isinstance(account, Account)
                    address = account.address
                    assert address == Address.from_prefix_and_int(AddressPrefix.EOA, i)

                    if i == 0:
                        # sender_account
                        assert account.delegated_amount == 0
                        assert len(account.delegations) == 10
                        assert account.delegation_part.delegations_amount == sum(range(11, 21))

                        for j, item in enumerate(account.delegations):
                            address: 'Address' = item[0]
                            value: int = item[1]

                            _id = j + 11
                            assert address == Address.from_prefix_and_int(AddressPrefix.EOA, _id)
                            assert value == _id
                    else:
                        assert account.delegations_amount == 0

                        if i <= 10:
                            assert account.delegated_amount == 0
                        else:
                            assert account.delegated_amount == i

        engine = IISSEngine()
        engine.add_listener(IISSEngineListenerImpl())
        engine.handle_set_delegation(context, delegations)
Exemple #10
0
    def test_put_delegation_to_state_db(self):
        cached_accounts: Dict['Address', Tuple['Account', int]] = OrderedDict()
        context = Mock()
        context.revision = Revision.DECENTRALIZATION.value
        context.storage.icx.get_account = Mock(side_effect=get_account)

        total_delegating = 0
        new_delegations: List[Tuple['Address', int]] = []
        for i in range(10):
            value: int = i + 11
            address = Address.from_prefix_and_int(AddressPrefix.EOA, value)
            new_delegations.append((address, value))
            total_delegating += value

        sender_account = context.storage.icx.get_account(context, SENDER_ADDRESS, Intent.ALL)
        cached_accounts[SENDER_ADDRESS] = sender_account, 0

        # Put old delegations to cached_accounts
        for address, value in sender_account.delegations:
            account = context.storage.icx.get_account(context, address, Intent.DELEGATED)
            cached_accounts[address] = account, -value

        # Put new delegations to cached_accounts
        for i in range(10):
            value: int = i + 11
            address = Address.from_prefix_and_int(AddressPrefix.EOA, value)
            account = context.storage.icx.get_account(context, address, Intent.DELEGATED)
            cached_accounts[address] = account, value

        updated_accounts: List['Account'] = IISSEngine._put_delegation_to_state_db(
            context, SENDER_ADDRESS, new_delegations, cached_accounts)

        # sender_account(1) + old_delegated_accounts(10) + new_delegated_accounts(10)
        assert len(updated_accounts) == len(cached_accounts) == 21
        assert len(context.storage.icx.put_account.call_args_list) == len(cached_accounts)

        for i, address in enumerate(cached_accounts):
            call_args = context.storage.icx.put_account.call_args_list[i]
            account = call_args[0][1]
            assert isinstance(account, Account)
            assert address == account.address
            assert account == updated_accounts[i]

            if i == 0:
                assert account.address == SENDER_ADDRESS
                assert account.delegated_amount == 0
                assert account.delegations == new_delegations
                assert account.delegations_amount == total_delegating
            else:
                # Assume that all delegated accounts do not delegate any other accounts
                assert account.delegations_amount == 0

                if i <= 10:  # old delegations
                    assert account.delegated_amount == 0
                else:
                    assert account.delegated_amount == cached_accounts[address][1]
def unlock_period(total_stake, total_supply):
    p = Engine._calculate_unstake_lock_period(
        default_icon_config[ConfigKey.IISS_META_DATA][
            ConfigKey.UN_STAKE_LOCK_MIN],
        default_icon_config[ConfigKey.IISS_META_DATA][
            ConfigKey.UN_STAKE_LOCK_MAX],
        default_icon_config[ConfigKey.IISS_META_DATA][ConfigKey.REWARD_POINT],
        total_stake,
        total_supply,
    )

    return p
Exemple #12
0
    def test_check_voting_power_is_enough(self):
        def _get_account(_context: 'IconScoreContext',
                         _address: 'Address',
                         _intent: 'Intent' = Intent.TRANSFER) -> 'Account':
            return create_sender_account(stake=155)

        cached_accounts: Dict['Address', Tuple['Account', int]] = {}
        context = Mock()
        context.storage.icx.get_account = Mock(side_effect=_get_account)
        total_delegating = sum(range(11, 21))  # new_delegations

        IISSEngine._check_voting_power_is_enough(
            context, SENDER_ADDRESS, total_delegating, cached_accounts)

        sender_item: Tuple['Account', int] = cached_accounts[SENDER_ADDRESS]

        assert len(cached_accounts) == 1
        assert sender_item[0] == _get_account(context, SENDER_ADDRESS, Intent.ALL)
        assert sender_item[1] == 0  # delegated_amount_offset
        assert sender_item[0].delegations_amount == sum(range(1, 11))  # old delegations
        assert sender_item[0].stake >= total_delegating
Exemple #13
0
    def test_convert_params_of_set_delegation_ok(self, context):
        max_delegations: int = self._get_expected_max_delegations(context)
        delegations = []
        total_delegating = 0

        for i in range(max_delegations):
            address = Address.from_prefix_and_int(AddressPrefix.EOA, i + 1)
            value = random.randint(1, 10_000)

            delegations.append({"address": address, "value": value})
            total_delegating += value

        ret_total_delegating, ret_delegations = IISSEngine._convert_params_of_set_delegation(context, delegations)
        assert ret_total_delegating == total_delegating

        for i in range(len(delegations)):
            item: Tuple['Address', int] = ret_delegations[i]
            address: 'Address' = item[0]
            value: int = item[1]

            assert address == delegations[i]["address"]
            assert value == delegations[i]["value"]
Exemple #14
0
    def test_convert_params_of_set_delegation_with_value_0(self, context):
        max_delegations: int = self._get_expected_max_delegations(context)
        delegations = []
        total_delegating = 0
        zero_value_cnt: int = 5

        for i in range(max_delegations):
            address = Address.from_prefix_and_int(AddressPrefix.EOA, i + 1)
            value = 0 if i < zero_value_cnt else i + 1

            delegations.append({"address": address, "value": value})
            total_delegating += value

        ret_total_delegating, ret_delegations = IISSEngine._convert_params_of_set_delegation(context, delegations)
        assert ret_total_delegating == total_delegating == sum([i + 1 for i in range(5, max_delegations)])
        assert len(ret_delegations) == max_delegations - zero_value_cnt

        i = zero_value_cnt
        # 5 delegations including 0 value were dropped.
        for address, value in ret_delegations:
            delegation: Dict[str, Optional[str, int]] = delegations[i]
            assert address == delegation["address"]
            assert value == delegation["value"]
            i += 1
Exemple #15
0
 def test_invoke(self):
     context = Mock(revision=Revision.IISS.value - 1)
     engine = IISSEngine()
     with pytest.raises(InvalidParamsException):
         engine.invoke(context, "stake", {})
Exemple #16
0
    def test_internal_handle_set_delegation(self):
        """Test case
        old_delegations: 1 ~ 10 delegated amount
        new_delegations: 101 ~ 110 delegated amount
        sender_account does not delegate to itself

        :return:
        """
        context = Mock()
        context.revision = Revision.DECENTRALIZATION.value
        context.storage.icx.get_account = Mock(side_effect=get_account)

        total_delegating, delegations = create_delegations_param()

        ret_total_delegating, ret_delegations = IISSEngine._convert_params_of_set_delegation(context, delegations)
        assert ret_total_delegating == total_delegating

        for i in range(len(delegations)):
            item: Tuple['Address', int] = ret_delegations[i]
            address: 'Address' = item[0]
            value: int = item[1]

            assert address, value == delegations[i]["address"]
            assert value == delegations[i]["value"]

        # IISSEngine._check_voting_power_is_enough()
        cached_accounts: Dict['Address', Tuple['Account', int]] = {}
        IISSEngine._check_voting_power_is_enough(
            context, SENDER_ADDRESS, total_delegating, cached_accounts)

        assert len(cached_accounts) == 1
        assert cached_accounts[SENDER_ADDRESS][0] == create_sender_account(stake=10_000)
        assert cached_accounts[SENDER_ADDRESS][1] == 0  # delegated_amount

        sender_account: 'Account' = cached_accounts[SENDER_ADDRESS][0]

        # Get old delegations from delegating accounts
        IISSEngine._get_old_delegations_from_sender_account(context, SENDER_ADDRESS, cached_accounts)
        assert len(cached_accounts) == 11  # sender_account(1) + old delegated_accounts(10)

        for i, address in enumerate(cached_accounts):
            item: Tuple['Account', int] = cached_accounts[address]
            account = item[0]
            delegated_offset = item[1]

            assert address == account.address

            if i > 0:
                delegation: Tuple['Account', int] = sender_account.delegations[i - 1]
                assert address == delegation[0]
                assert delegated_offset == -delegation[1]

        IISSEngine._calc_delegations(context, ret_delegations, cached_accounts)
        # 0: sender_account, 1~10: old_accounts 11~20: new_accounts

        for i, address in enumerate(cached_accounts):
            account, delegated_offset = cached_accounts[address]
            assert account.address == address

            if i == 0:
                assert address == SENDER_ADDRESS
                assert delegated_offset == 0
            elif 1 <= i <= 10:
                assert delegated_offset == -i
            else:  # 11 <= i <= 20
                assert delegated_offset == i

        updated_accounts: List['Account'] = \
            IISSEngine._put_delegation_to_state_db(context, SENDER_ADDRESS, ret_delegations, cached_accounts)
        # sender_account(1) + old_delegated_accounts(10) + new_delegated_accounts(10)
        assert len(updated_accounts) == len(cached_accounts) == 21
        assert len(context.storage.icx.put_account.call_args_list) == len(cached_accounts)

        for i, address in enumerate(cached_accounts):
            call_args = context.storage.icx.put_account.call_args_list[i]
            account = call_args[0][1]
            assert isinstance(account, Account)
            assert address == account.address
            assert account == updated_accounts[i]

            if i == 0:
                assert account.address == SENDER_ADDRESS
                assert account.delegated_amount == 0
            elif 1 <= i <= 10:  # old delegations
                assert account.delegated_amount == 0
            else:
                assert account.delegated_amount == cached_accounts[address][1]