Skip to content
This repository has been archived by the owner on Dec 15, 2021. It is now read-only.

Commit

Permalink
Merge pull request #503 from icon-project/hotfix/1.7.4
Browse files Browse the repository at this point in the history
  • Loading branch information
goldworm-icon committed Aug 28, 2020
2 parents 3bef8ca + 6c2fb69 commit 6d1ca8f
Show file tree
Hide file tree
Showing 25 changed files with 911 additions and 28 deletions.
2 changes: 1 addition & 1 deletion iconservice/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.7.3'
__version__ = '1.7.6'
7 changes: 6 additions & 1 deletion iconservice/icon_constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,12 @@ class Revision(Enum):
FIX_COIN_PART_BYTES_ENCODING = 9
STRICT_SCORE_DECORATOR_CHECK = 9

LATEST = 9
FIX_UNSTAKE_BUG = 10
LOCK_ADDRESS = 10

FIX_BALANCE_BUG = 11

LATEST = 11


RC_DB_VERSION_0 = 0
Expand Down
7 changes: 4 additions & 3 deletions iconservice/icon_service_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import shutil
from copy import deepcopy
from enum import IntEnum
from typing import TYPE_CHECKING, List, Optional, Tuple, Dict, Union, Any

import os
import shutil
from iconcommons.logger import Logger
from typing import TYPE_CHECKING, List, Optional, Tuple, Dict, Union, Any

from iconservice.rollback import check_backup_exists
from iconservice.rollback.backup_cleaner import BackupCleaner
Expand Down Expand Up @@ -82,6 +82,7 @@
from .utils import to_camel_case, bytes_to_hex
from .utils.bloom import BloomFilter
from .utils.timer import Timer
from .utils.locked import is_address_locked

if TYPE_CHECKING:
from .iconscore.icon_score_event_log import EventLog
Expand Down
12 changes: 12 additions & 0 deletions iconservice/iconscore/icon_pre_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@

from iconcommons.logger import Logger

from .icon_score_context import IconScoreContextType
from .icon_score_step import get_input_data_size
from ..base.address import Address, SYSTEM_SCORE_ADDRESS, generate_score_address
from ..base.exception import InvalidRequestException, InvalidParamsException, OutOfBalanceException
from ..icon_constant import FIXED_FEE, MAX_DATA_SIZE, DEFAULT_BYTE_SIZE, DATA_BYTE_ORDER, Revision, DeployState
from ..utils import is_lowercase_hex_string
from ..utils.locked import is_address_locked

if TYPE_CHECKING:
from ..deploy.storage import IconScoreDeployInfo
Expand Down Expand Up @@ -318,6 +320,16 @@ def _validate_new_score_address_on_deploy_transaction(cls, context: 'IconScoreCo
def _check_balance(cls, context: 'IconScoreContext', from_: 'Address', value: int, fee: int):
balance = context.engine.icx.get_balance(context, from_)

if is_address_locked(from_) and (
context.type == IconScoreContextType.QUERY or
(context.type == IconScoreContextType.INVOKE and
context.revision == Revision.LOCK_ADDRESS.value)):
Logger.warning(
tag="LOCK",
msg=f"Address is locked: balance={balance} from={str(from_)} value={value} fee={fee}"
)
raise InvalidRequestException(f"Address is locked: {from_}")

if balance < value + fee:
msg = f"Out of balance: from={from_} balance={balance} value={value} fee={fee}"
if balance == 0:
Expand Down
8 changes: 6 additions & 2 deletions iconservice/icx/coin_part.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def __str__(self) -> str:

class CoinPartFlag(Flag):
NONE = 0
HAS_UNSTAKE = 1
HAS_UNSTAKE = 1 # deprecated


class CoinPart(BasePart):
Expand Down Expand Up @@ -130,7 +130,11 @@ def flags(self) -> 'CoinPartFlag':
"""
return self._flags

def toggle_has_unstake(self, on: bool):
def toggle_has_unstake(self, on: bool, revision: int):
# deprecated flag
if revision >= Revision.FIX_BALANCE_BUG.value:
return

new_flags = set_flag(self._flags, CoinPartFlag.HAS_UNSTAKE, on)

if self._flags != new_flags:
Expand Down
12 changes: 6 additions & 6 deletions iconservice/icx/icx_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,13 @@ def normalize(self, revision: int):
if self.coin_part is None or self.stake_part is None:
return

balance: int = self.stake_part.normalize(self._current_block_height, revision)
if balance > 0:
expired_unstaked_balance: int = self.stake_part.normalize(self._current_block_height, revision)
if expired_unstaked_balance > 0:
if self.coin_part is None:
raise InvalidParamsException('Failed to normalize: no coin part')

self.coin_part.toggle_has_unstake(False)
self.coin_part.deposit(balance)
self.coin_part.toggle_has_unstake(False, revision)
self.coin_part.deposit(expired_unstaked_balance)

def set_stake(self, context: "IconScoreContext", value: int, unstake_lock_period: int):
if self.coin_part is None or self.stake_part is None:
Expand All @@ -168,12 +168,12 @@ def set_stake(self, context: "IconScoreContext", value: int, unstake_lock_period
self.stake_part.reset_unstake()
else:
unlock_block_height: int = self._current_block_height + unstake_lock_period
self.coin_part.toggle_has_unstake(True)
self.coin_part.toggle_has_unstake(True, context.revision)
if context.revision >= Revision.MULTIPLE_UNSTAKE.value:
self.stake_part.set_unstakes_info(unlock_block_height,
-offset, context.unstake_slot_max)
else:
self.stake_part.set_unstake(unlock_block_height, -offset)
self.stake_part.set_unstake(unlock_block_height, -offset)

def update_delegated_amount(self, offset: int):
if self.delegation_part is None:
Expand Down
24 changes: 15 additions & 9 deletions iconservice/icx/stake_part.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,15 +175,21 @@ def normalize(self, block_height: int, revision: int) -> int:
size = len(self._unstakes_info)
for i in range(size):
info = self._unstakes_info[0]
if info[1] >= block_height:
if i > 0:
state |= BasePartState.DIRTY
break

# Remove unstatke_info of which lock period is already expired
self._unstakes_info.pop(0)
unstake += info[0]

if revision >= Revision.FIX_UNSTAKE_BUG.value:
if info[1] >= block_height:
break
# Remove unstake_info of which lock period is already expired
self._unstakes_info.pop(0)
unstake += info[0]
state |= BasePartState.DIRTY
else:
if info[1] >= block_height:
if i > 0:
state |= BasePartState.DIRTY
break
# Remove unstake_info of which lock period is already expired
self._unstakes_info.pop(0)
unstake += info[0]
else:
if 0 < self._unstake_block_height < block_height:
unstake: int = self._unstake
Expand Down
24 changes: 22 additions & 2 deletions iconservice/icx/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
from ..base.ComponentBase import StorageBase
from ..base.address import Address
from ..base.block import Block, NULL_BLOCK
from ..icon_constant import DEFAULT_BYTE_SIZE, DATA_BYTE_ORDER, ICX_LOG_TAG, ROLLBACK_LOG_TAG, IconScoreContextType
from ..icon_constant import DEFAULT_BYTE_SIZE, DATA_BYTE_ORDER, ICX_LOG_TAG, ROLLBACK_LOG_TAG, IconScoreContextType, \
Revision
from ..utils import bytes_to_hex

if TYPE_CHECKING:
Expand Down Expand Up @@ -269,7 +270,26 @@ def get_account(self,
if AccountPartFlag.COIN in part_flags:
coin_part: 'CoinPart' = self._get_part(context, CoinPart, address)

if CoinPartFlag.HAS_UNSTAKE in coin_part.flags:
"""
Ref IS-1208.
Mismatch has_unstake flag and actual unstake info below rev 10.
The reason that branch logic by revision is backward compatibility process on transfer ICX logic.
The below code is a logic that determines in advance whether it is possible or not before ICX transfer.
### _process_transaction in icon_service_engine.py ###
# Checks the balance only on the invoke context(skip estimate context)
if context.type == IconScoreContextType.INVOKE:
tmp_context: 'IconScoreContext' = IconScoreContext(IconScoreContextType.QUERY)
tmp_context.block = self._get_last_block()
# Check if from account can charge a tx fee
self._icon_pre_validator.execute_to_check_out_of_balance(
context if context.revision >= Revision.THREE.value else tmp_context,
params,
step_price=context.step_counter.step_price)
"""
if context.revision >= Revision.FIX_BALANCE_BUG.value or \
CoinPartFlag.HAS_UNSTAKE in coin_part.flags:
part_flags |= AccountPartFlag.STAKE

if AccountPartFlag.STAKE in part_flags:
Expand Down
6 changes: 3 additions & 3 deletions iconservice/iiss/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import time
from collections import OrderedDict
from typing import TYPE_CHECKING, Any, Optional, List, Dict, Tuple

import time
from iconcommons.logger import Logger

from iconservice.iiss.listener import EngineListener as IISSEngineListener
Expand All @@ -28,8 +28,8 @@
from ..base.address import Address
from ..base.address import SYSTEM_SCORE_ADDRESS
from ..base.exception import (
InvalidParamsException, InvalidRequestException,
OutOfBalanceException, FatalException, InternalServiceErrorException
InvalidParamsException, InvalidRequestException, OutOfBalanceException, FatalException,
InternalServiceErrorException
)
from ..icon_constant import ISCORE_EXCHANGE_RATE, IISS_MAX_REWARD_RATE, \
IconScoreContextType, IISS_LOG_TAG, ROLLBACK_LOG_TAG, RCCalculateResult, INVALID_CLAIM_TX, Revision, \
Expand Down
38 changes: 38 additions & 0 deletions iconservice/utils/locked.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-

from ..base.address import Address


LOCKED_ADDRESSES = (
"hx76dcc464a27d74ca7798dd789d2e1da8193219b4",
"hxac5c6e6f7a6e8ae1baba5f0cb512f7596b95f1fe",
"hx966f5f9e2ab5b80a0f2125378e85d17a661352f4",
"hxad2bc6446ee3ae23228889d21f1871ed182ca2ca",
"hxc39a4c8438abbcb6b49de4691f07ee9b24968a1b",
"hx96505aac67c4f9033e4bac47397d760f121bcc44",
"hxf5bbebeb7a7d37d2aee5d93a8459e182cbeb725d",
"hx3f472b9f22a165b02da1544004e177d168d19eaf",
"hx4602589eb91cf99b27296e5bd712387a23dd8ce5",
"hxa67e30ec59e73b9e15c7f2c4ddc42a13b44b2097",
"hx52c32d0b82f46596f697d8ba2afb39105f3a6360",
"hx985cf67b563fb908543385da806f297482f517b4",
"hxc0567bbcba511b84012103a2360825fddcd058ab",
"hx52c32d0b82f46596f697d8ba2afb39105f3a6360",
"hx20be21b8afbbc0ba46f0671508cfe797c7bb91be",
"hx19e551eae80f9b9dcfed1554192c91c96a9c71d1",

"hx0607341382dee5e039a87562dcb966e71881f336",
"hxdea6fe8d6811ec28db095b97762fdd78b48c291f",

"hxaf3a561e3888a2b497941e464f82fd4456db3ebf",
"hx061b01c59bd9fc1282e7494ff03d75d0e7187f47",
"hx10d12d5726f50e4cf92c5fad090637b403516a41",
"hx10e8a7289c3989eac07828a840905344d8ed559b",
)


_locked_addresses = set(Address.from_string(address) for address in LOCKED_ADDRESSES)


def is_address_locked(address: 'Address') -> bool:
return address in _locked_addresses

0 comments on commit 6d1ca8f

Please sign in to comment.