Ejemplo n.º 1
0
    def test_is_removable_v1(self, unstake_patcher, index, unstakes_info,
                             result):
        stake_part = StakePart(0, 0, 0, unstakes_info)
        stake_part.set_complete(True)
        target = unstake_patcher._targets[index]

        assert unstake_patcher._is_removable_v1(stake_part, target) == result
Ejemplo n.º 2
0
    def test_is_removable_v0(self, unstake_patcher, index, unstake,
                             unstake_block_height, result):
        stake_part = StakePart(0, unstake, unstake_block_height)
        stake_part.set_complete(True)
        target = unstake_patcher._targets[index]

        assert unstake_patcher._is_removable_v0(stake_part, target) == result
Ejemplo n.º 3
0
    def test_stake_part_make_key(self):
        key = StakePart.make_key(create_address())
        self.assertEqual(
            ICON_EOA_ADDRESS_BYTES_SIZE + len(StakePart.PREFIX) + 1, len(key))

        key = StakePart.make_key(create_address(1))
        self.assertEqual(
            ICON_CONTRACT_ADDRESS_BYTES_SIZE + len(StakePart.PREFIX), len(key))
Ejemplo n.º 4
0
    def test_normalize(self, revision, block_height, unstakes_info,
                       expected_expired_unstake, expected_unstakes_info,
                       expected_dirty):
        stake = random.randint(0, 100)

        stake_part = StakePart(stake=stake,
                               unstakes_info=copy.deepcopy(unstakes_info))
        expired_unstake = stake_part.normalize(block_height, revision)
        assert expired_unstake == expected_expired_unstake
        assert stake_part.unstakes_info == expected_unstakes_info
        assert stake_part.is_dirty() == expected_dirty
Ejemplo n.º 5
0
    def test_stake_part_on_rev_8(self, block_height, params, expected):
        revision = 8
        stake_part = StakePart(**params)
        expired_unstake: int = stake_part.normalize(block_height=block_height,
                                                    revision=revision)

        assert expired_unstake == expected["expired_unstake"]
        assert stake_part.stake == expected["stake"]
        assert stake_part.total_stake == expected["stake"] + expected["unstake"]
        assert stake_part.unstake == expected["unstake"]
        assert stake_part.total_unstake == expected["unstake"]
        assert stake_part.unstake_block_height == expected[
            "unstake_block_height"]
Ejemplo n.º 6
0
    def test_normalize(self, context, mocker, revision, unstakes_info,
                       current_block_height, flag, expected_balance):
        unstakes_info = copy.deepcopy(unstakes_info)
        mocker.patch.object(IconScoreContext, "revision",
                            PropertyMock(return_value=revision))
        stake, balance = 100, 100

        coin_part = CoinPart(CoinPartType.GENERAL, flag, balance)
        stake_part = StakePart(stake=stake,
                               unstake=0,
                               unstake_block_height=0,
                               unstakes_info=unstakes_info)
        account = Account(ADDRESS,
                          current_block_height,
                          revision,
                          coin_part=coin_part,
                          stake_part=stake_part)

        if unstakes_info is None:
            remaining_unstakes = []
        else:
            remaining_unstakes = [
                unstake_info for unstake_info in unstakes_info
                if unstake_info[1] >= current_block_height
            ]

        account.normalize(revision)

        assert account.stake == stake
        assert account.balance == expected_balance
        assert account.unstakes_info == remaining_unstakes
Ejemplo n.º 7
0
    def test_account_stake(self):
        value: int = 0
        stake_part = StakePart(stake=value)
        stake_part.set_complete(True)
        account = Account(create_address(), 0, stake_part=stake_part)
        self.assertEqual(value, account.stake)

        value: int = 100
        stake_part = StakePart(stake=value)
        stake_part.set_complete(True)
        account = Account(create_address(), 0, stake_part=stake_part)
        self.assertEqual(value, account.stake)
Ejemplo n.º 8
0
    def test_account_unstake_block_height(self):
        value: int = 0
        stake_part = StakePart(unstake_block_height=value)
        stake_part.set_complete(True)
        account = Account(create_address(), 0, stake_part=stake_part)
        self.assertEqual(0, account.unstake_block_height)

        value: int = 300
        stake_part = StakePart(unstake_block_height=value)
        stake_part.set_complete(True)
        account = Account(create_address(), 0, stake_part=stake_part)
        self.assertEqual(value, account.unstake_block_height)
Ejemplo n.º 9
0
    def test_stake_part_add_stake(self):
        part = StakePart()
        part.set_complete(True)

        stake = 100
        part.add_stake(100)
        self.assertEqual(stake, part.stake)
        self.assertTrue(
            part.is_set(BasePartState.DIRTY | BasePartState.COMPLETE))
Ejemplo n.º 10
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)
Ejemplo n.º 11
0
    def test_account_for_stake_rev_multiple_unstake1(self):
        address: 'Address' = create_address()
        context: 'IconScoreContext' = Mock(spec=IconScoreContext)
        unstake_slot_max = 10
        context.configure_mock(unstake_slot_max=unstake_slot_max)
        context.configure_mock(revision=Revision.MULTIPLE_UNSTAKE.value)

        coin_part: 'CoinPart' = CoinPart()
        stake_part: 'StakePart' = StakePart()
        account = Account(address,
                          0,
                          Revision.MULTIPLE_UNSTAKE.value,
                          coin_part=coin_part,
                          stake_part=stake_part)

        balance = 1000
        account.deposit(balance)

        stake1 = 500
        unstake_block_height = 0
        remain_balance = balance - stake1

        account.set_stake(context, stake1, 0)

        self.assertEqual(stake1, account.stake)
        self.assertEqual(0, account.unstake)
        self.assertEqual(unstake_block_height, account.unstake_block_height)
        self.assertEqual(remain_balance, account.balance)

        stake2 = 100
        block_height = 10
        unstake = stake1 - stake2
        remain_balance = balance - stake1
        account.set_stake(context, stake2, block_height)
        expected_unstake_info = [[unstake, block_height]]

        self.assertEqual(stake2, account.stake)
        self.assertEqual(0, account.unstake)
        self.assertEqual(0, account.unstake_block_height)
        self.assertEqual(expected_unstake_info, account.unstakes_info)
        self.assertEqual(remain_balance, account.balance)

        stake3 = 600
        block_height = 15
        account.set_stake(context, stake3, block_height)
        expected_unstake_info = []
        expected_balance = 400

        self.assertEqual(stake3, account.stake)
        self.assertEqual(expected_unstake_info, account.unstakes_info)
        self.assertEqual(expected_balance, account.balance)
Ejemplo n.º 12
0
    def test_remove_invalid_expired_unstakes_v1(self, unstake_patcher,
                                                unstakes_info, index):
        stake = random.randint(0, 1000)
        stake_part = StakePart(stake, 0, 0, copy.deepcopy(unstakes_info))
        stake_part.set_complete(True)
        target = unstake_patcher._targets[index]

        stake_part = unstake_patcher._remove_invalid_expired_unstakes_v1(
            stake_part, target)
        assert stake_part.is_dirty()
        assert stake_part.stake == stake
        assert stake_part.unstake == 0
        assert stake_part.unstake_block_height == 0

        size = len(stake_part.unstakes_info)
        target_size = len(target.unstakes)
        assert size == len(unstakes_info) - target_size

        for i in range(size):
            index = target_size + i
            assert stake_part.unstakes_info[i] == unstakes_info[index]
            assert stake_part.total_unstake == unstakes_info[index][0]
            assert stake_part.total_stake == unstakes_info[index][0] + stake
Ejemplo n.º 13
0
    def test_get_account(self, storage, context, mocker, flag, unstakes_info,
                         current_block_height, expected_balance):
        unstakes_info = copy.deepcopy(unstakes_info)

        # test whether the `Account` saved in the wrong format is properly got on revision11.
        revision = Revision.FIX_BALANCE_BUG.value
        mocker.patch.object(IconScoreContext, "revision",
                            PropertyMock(return_value=revision))

        stake, balance = 100, 100
        coin_part = CoinPart(CoinPartType.GENERAL, flag, balance)
        coin_part.set_dirty(True)
        stake_part = StakePart(stake=stake,
                               unstake=0,
                               unstake_block_height=0,
                               unstakes_info=unstakes_info)
        stake_part.set_dirty(True)
        account = Account(ADDRESS,
                          current_block_height,
                          revision,
                          coin_part=coin_part,
                          stake_part=stake_part)
        account.coin_part._flags = flag
        context.block._height = current_block_height
        storage.put_account(context, account)

        if unstakes_info is None:
            remaining_unstakes = []
        else:
            remaining_unstakes = [
                unstake_info for unstake_info in unstakes_info
                if unstake_info[1] >= current_block_height
            ]

        account = storage.get_account(context, ADDRESS)
        assert account.balance == expected_balance
        assert account.unstakes_info == remaining_unstakes
Ejemplo n.º 14
0
    def test_account_unstakes_info(self):
        value: int = 0
        stake_part = StakePart(unstake=value)
        stake_part.set_complete(True)
        account = Account(create_address(),
                          0,
                          Revision.MULTIPLE_UNSTAKE.value,
                          stake_part=stake_part)
        self.assertEqual([], account.unstakes_info)

        info = [(10, 1), (20, 5)]
        stake_part = StakePart(unstakes_info=info)
        stake_part.set_complete(True)
        account = Account(create_address(),
                          0,
                          Revision.MULTIPLE_UNSTAKE.value,
                          stake_part=stake_part)
        self.assertEqual(info, account.unstakes_info)
Ejemplo n.º 15
0
    def test_account_for_unstake_slot_max_case_1(self):
        address: 'Address' = create_address()
        context: 'IconScoreContext' = Mock(spec=IconScoreContext)
        unstake_slot_max = 10
        context.configure_mock(unstake_slot_max=unstake_slot_max)
        context.configure_mock(revision=Revision.MULTIPLE_UNSTAKE.value)

        coin_part: 'CoinPart' = CoinPart()
        stake_part: 'StakePart' = StakePart()
        account = Account(address,
                          0,
                          Revision.MULTIPLE_UNSTAKE.value,
                          coin_part=coin_part,
                          stake_part=stake_part)

        balance = 2000
        account.deposit(balance)

        stake = 2000
        unstake_block_height = 0
        remain_balance = balance - stake

        account.set_stake(context, stake, 0)

        self.assertEqual(stake, account.stake)
        self.assertEqual(0, account.unstake)
        self.assertEqual(unstake_block_height, account.unstake_block_height)
        self.assertEqual(remain_balance, account.balance)

        unstake = 1
        total_unstake = 0
        expected_unstake_info = []
        for i in range(unstake_slot_max):
            expected_unstake_info.append([unstake, unstake_slot_max + i])
            stake -= unstake
            total_unstake += unstake
            account.set_stake(context, account.stake - unstake,
                              unstake_slot_max + i)
            self.assertEqual(stake, account.stake)
            self.assertEqual(total_unstake, account.stake_part.total_unstake)
            self.assertEqual(remain_balance, account.balance)
            self.assertEqual(expected_unstake_info, account.unstakes_info)
        last_unstake = 100
        account.set_stake(context, account.stake - last_unstake,
                          unstake_slot_max + 2)
        expected_unstake_info[-1] = [101, unstake_slot_max * 2 - 1]
        self.assertEqual(expected_unstake_info, account.unstakes_info)
Ejemplo n.º 16
0
    def test_account_unstake(self):
        value: int = 0
        stake_part = StakePart(unstake=value)
        stake_part.set_complete(True)
        account = Account(create_address(),
                          0,
                          Revision.IISS.value,
                          stake_part=stake_part)
        self.assertEqual(0, account.unstake)

        value: int = 200
        stake_part = StakePart(unstake=value)
        stake_part.set_complete(True)
        account = Account(create_address(),
                          0,
                          Revision.IISS.value,
                          stake_part=stake_part)
        self.assertEqual(value, account.unstake)
Ejemplo n.º 17
0
    def test_stake_part_update(self):
        stake: int = 10
        unstake: int = 0
        unstake_block_height: int = 0
        part1 = StakePart(stake, unstake, unstake_block_height)
        part1.normalize(0, Revision.IISS.value)
        self.assertEqual(stake, part1.stake)
        self.assertEqual(unstake, part1.unstake)
        self.assertEqual(unstake_block_height, part1.unstake_block_height)

        stake: int = 5
        unstake: int = 5
        unstake_block_height: int = 3
        part2 = StakePart(stake, unstake, unstake_block_height)
        part2.normalize(unstake_block_height + 1, Revision.IISS.value)
        self.assertEqual(stake, part2.stake)
        self.assertEqual(0, part2.unstake)
        self.assertEqual(0, part2.unstake_block_height)
Ejemplo n.º 18
0
    def test_account_flag(self):
        address: 'Address' = create_address()

        account: 'Account' = Account(address, 0, Revision.IISS.value)
        self.assertIsNone(account.coin_part)
        self.assertIsNone(account.stake_part)
        self.assertIsNone(account.delegation_part)

        coin_part: 'CoinPart' = CoinPart()
        account: 'Account' = Account(address,
                                     0,
                                     Revision.IISS.value,
                                     coin_part=coin_part)
        self.assertIsNotNone(account.coin_part)
        self.assertIsNone(account.stake_part)
        self.assertIsNone(account.delegation_part)

        stake_part: 'StakePart' = StakePart()
        account: 'Account' = Account(address,
                                     0,
                                     Revision.IISS.value,
                                     stake_part=stake_part)
        self.assertIsNone(account.coin_part)
        self.assertIsNotNone(account.stake_part)
        self.assertIsNone(account.delegation_part)

        delegation_part: 'DelegationPart' = DelegationPart()
        account: 'Account' = Account(address,
                                     0,
                                     Revision.IISS.value,
                                     delegation_part=delegation_part)
        self.assertIsNone(account.coin_part)
        self.assertIsNone(account.stake_part)
        self.assertIsNotNone(account.delegation_part)

        account: 'Account' = Account(address,
                                     0,
                                     Revision.IISS.value,
                                     coin_part=coin_part,
                                     stake_part=stake_part,
                                     delegation_part=delegation_part)
        self.assertIsNotNone(account.coin_part)
        self.assertIsNotNone(account.stake_part)
        self.assertIsNotNone(account.delegation_part)
Ejemplo n.º 19
0
    def test_account_for_stake(self):
        address: 'Address' = create_address()
        context: 'IconScoreContext' = IconScoreContext()

        coin_part: 'CoinPart' = CoinPart()
        stake_part: 'StakePart' = StakePart()
        account = Account(address,
                          0,
                          Revision.IISS.value,
                          coin_part=coin_part,
                          stake_part=stake_part)

        balance = 1000
        account.deposit(balance)

        stake1 = 500
        unstake_block_height = 0
        remain_balance = balance - stake1

        account.set_stake(context, stake1, 0)

        self.assertEqual(stake1, account.stake)
        self.assertEqual(0, account.unstake)
        self.assertEqual(unstake_block_height, account.unstake_block_height)
        self.assertEqual(remain_balance, account.balance)

        stake2 = 100
        block_height = 10
        unstake = stake1 - stake2
        remain_balance = balance - stake1
        account.set_stake(context, stake2, block_height)

        self.assertEqual(stake2, account.stake)
        self.assertEqual(unstake, account.unstake)
        self.assertEqual(block_height, account.unstake_block_height)
        self.assertEqual(remain_balance, account.balance)

        remain_balance = remain_balance + unstake
        account._current_block_height += 11
        account.normalize(Revision.IISS.value)
        self.assertEqual(remain_balance, account.balance)
Ejemplo n.º 20
0
    def test_stake_part(self):
        stake = 500
        unstake = 0
        unstake_block_height = 0

        stake_part: 'StakePart' = StakePart()
        stake_part.normalize(0, Revision.IISS.value)
        stake_part.add_stake(stake)

        self.assertEqual(stake, stake_part.stake)
        self.assertEqual(unstake, stake_part.unstake)
        self.assertEqual(unstake_block_height, stake_part.unstake_block_height)

        unstake = 100
        block_height = 10
        remain_stake = stake - unstake
        stake_part.set_unstake(block_height, unstake)

        self.assertEqual(remain_stake, stake_part.stake)
        self.assertEqual(unstake, stake_part.unstake)
        self.assertEqual(block_height, stake_part.unstake_block_height)
Ejemplo n.º 21
0
    def test_withdraw_unstake(self, stake, unstakes_info, amount,
                              expected_unstakes_info):
        expected_total_unstake = sum(unstake
                                     for unstake, _ in expected_unstakes_info)

        stake_part = StakePart(stake=stake, unstakes_info=unstakes_info)
        stake_part.normalize(block_height=500,
                             revision=Revision.FIX_UNSTAKE_BUG.value)

        # withdraw() assumes that amount is less than total_stake
        assert stake_part.total_unstake > amount
        stake_part.withdraw_unstake(amount)

        assert stake_part.stake == stake
        assert stake_part.unstakes_info == expected_unstakes_info
        assert stake_part.total_unstake == expected_total_unstake
Ejemplo n.º 22
0
def get_account(context: 'IconScoreContext',
                address: 'Address',
                intent: 'Intent' = Intent.TRANSFER) -> 'Account':

    """Returns the account indicated by address.

    :param context:
    :param address: account address
    :param intent:
    :return: (Account)
        If the account indicated by address is not present,
        create a new account.
    """
    if address == SENDER_ADDRESS:
        return create_sender_account(stake=10_000)

    coin_part: Optional['CoinPart'] = None
    stake_part: Optional['StakePart'] = None
    delegation_part: Optional['DelegationPart'] = None

    part_flags: 'AccountPartFlag' = AccountPartFlag(intent)

    if AccountPartFlag.COIN in part_flags:
        coin_part: 'CoinPart' = CoinPart(balance=0)

    if AccountPartFlag.STAKE in part_flags:
        stake_part = StakePart(0, 0, 0)

    if AccountPartFlag.DELEGATION in part_flags:
        value: int = int.from_bytes(address.body, "big")
        delegated_amount = value if 1 <= value <= 10 else 0
        delegation_part = DelegationPart(delegated_amount=delegated_amount)

    return Account(address, context.block.height,
                   coin_part=coin_part,
                   stake_part=stake_part,
                   delegation_part=delegation_part)
Ejemplo n.º 23
0
    def test_set_unstakes_info(self, unstakes_info, new_total_unstake,
                               unstake_block_height, expected_unstakes_info):
        old_total_unsake: int = sum(
            info[0] for info in unstakes_info) if unstakes_info else 0
        assert new_total_unstake != old_total_unsake

        stake = random.randint(0, 100)
        slot_max = 3
        revision = Revision.FIX_UNSTAKE_BUG.value
        block_height = 500

        stake_part = StakePart(stake=stake, unstakes_info=unstakes_info)
        stake_part.normalize(block_height, revision)

        unstake_delta: int = new_total_unstake - old_total_unsake
        stake_part.set_unstakes_info(unstake_block_height, new_total_unstake,
                                     slot_max)
        assert stake_part.is_dirty()
        assert stake_part.stake == stake - unstake_delta
        assert stake_part.unstakes_info == expected_unstakes_info
        assert stake_part.total_unstake == new_total_unstake
        assert stake_part.total_stake == stake_part.stake + stake_part.total_unstake
Ejemplo n.º 24
0
    def test_remove_invalid_expired_unstakes_v0(self, unstake_patcher, index,
                                                unstake, unstake_block_height):
        stake = random.randint(0, 1000)
        stake_part = StakePart(stake, unstake, unstake_block_height)
        stake_part.set_complete(True)
        target = unstake_patcher._targets[index]

        assert stake_part.stake == stake
        assert stake_part.unstake == unstake
        assert stake_part.unstake_block_height == unstake_block_height
        assert not stake_part.is_dirty()

        stake_part = unstake_patcher._remove_invalid_expired_unstakes_v0(
            stake_part, target)
        assert stake_part.is_dirty()
        assert len(stake_part.unstakes_info) == 0
        assert stake_part.stake == stake
        assert stake_part.unstake == 0
        assert stake_part.unstake_block_height == 0
Ejemplo n.º 25
0
 def test_stake_part_update_multiple_unstake(self):
     stake: int = 5
     block_height = 3
     unstake_info1 = [10, 1]
     unstake_info2 = [20, 2]
     unstake_info3 = [40, 3]
     unstake_info4 = [30, 5]
     unstake_info5 = [100, 5]
     unstakes_info = [
         unstake_info1, unstake_info2, unstake_info3, unstake_info4,
         unstake_info5
     ]
     part = StakePart(stake=stake, unstakes_info=unstakes_info)
     part.set_complete(True)
     part.normalize(block_height, Revision.MULTIPLE_UNSTAKE.value)
     self.assertEqual(stake, part.stake)
     self.assertEqual(0, part.unstake)
     self.assertEqual(0, part.unstake_block_height)
     expected_info = [[40, 3], [30, 5], [100, 5]]
     self.assertEqual(expected_info, part.unstakes_info)
Ejemplo n.º 26
0
 def test_stake_part_total_unstake2(self):
     unstakes_info = [(10, 1), (20, 1)]
     part = StakePart(unstakes_info=unstakes_info)
     part.set_complete(True)
     self.assertEqual(30, part.total_unstake)
Ejemplo n.º 27
0
    def test_stake_part_set_unstake_update(self):
        part = StakePart()
        part.set_complete(True)

        stake = 100
        block_height = 10
        part.add_stake(100)
        unstake = stake
        part.set_unstake(block_height, unstake)

        self.assertEqual(0, part.stake)
        self.assertEqual(stake, part.unstake)
        self.assertEqual(block_height, part.unstake_block_height)
        self.assertTrue(
            part.is_set(BasePartState.DIRTY | BasePartState.COMPLETE))

        block_height += block_height
        unstake = 10
        part.set_unstake(block_height, unstake)
        self.assertEqual(stake - unstake, part.stake)
        self.assertEqual(unstake, part.unstake)
        self.assertEqual(block_height, part.unstake_block_height)
        self.assertTrue(
            part.is_set(BasePartState.DIRTY | BasePartState.COMPLETE))

        refund_unstake = part.normalize(block_height + 1, Revision.IISS.value)
        self.assertEqual(unstake, refund_unstake)
Ejemplo n.º 28
0
 def _convert_stake_parts(cls, key: bytes, value: bytes):
     ret = StakePart.from_bytes(value)
     return str(Address.from_bytes(key[len(StakePart.PREFIX):])), str(ret)
Ejemplo n.º 29
0
    def test_delegation_part_equal(self):
        part1 = StakePart()
        part1.normalize(0, Revision.IISS.value)
        part2 = StakePart()
        part2.normalize(1, Revision.IISS.value)
        self.assertEqual(part1, part2)

        offset = 100
        part1.add_stake(offset)

        part3 = StakePart(stake=offset)
        part3.normalize(100, Revision.IISS.value)
        self.assertEqual(part1, part3)
Ejemplo n.º 30
0
    def test_stake_part_from_bytes_to_bytes_multiple_unstake(self):
        part1 = StakePart()
        part1.normalize(0, Revision.IISS.value)
        data = part1.to_bytes(Revision.MULTIPLE_UNSTAKE.value)
        self.assertTrue(isinstance(data, bytes))
        self.assertEqual(6, len(data))

        part2 = StakePart.from_bytes(data)
        part2.normalize(0, Revision.IISS.value)
        self.assertEqual(part1.stake, part2.stake)
        self.assertEqual(part1.unstake, part2.unstake)
        self.assertEqual(part1.unstake_block_height,
                         part2.unstake_block_height)
        self.assertEqual(part1.unstakes_info, part2.unstakes_info)

        part3 = StakePart(10, 20, 30)
        part3.normalize(0, Revision.IISS.value)
        part4 = StakePart.from_bytes(
            part3.to_bytes(Revision.MULTIPLE_UNSTAKE.value))
        part4.normalize(0, Revision.IISS.value)
        self.assertEqual(part3.stake, part4.stake)
        self.assertEqual(part3.unstake, part4.unstake)
        self.assertEqual(part3.unstakes_info, part4.unstakes_info)