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 #131 from icon-project/release-1.2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
Chiwon Cho committed Apr 30, 2019
2 parents ce8ce33 + 20283fd commit ef6217c
Show file tree
Hide file tree
Showing 83 changed files with 3,097 additions and 818 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.2.0
1.2.3
14 changes: 7 additions & 7 deletions iconservice/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@
# limitations under the License.
"""Package for objects which are related with Icon Services"""

from .base.address import Address, ZERO_SCORE_ADDRESS
from abc import ABCMeta, abstractmethod, ABC
from functools import wraps
from inspect import isfunction

from iconcommons.logger import Logger

from .base.address import Address, AddressPrefix, ZERO_SCORE_ADDRESS
from .base.exception import IconScoreException
from .icon_constant import IconServiceFlag
from .iconscore.icon_container_db import VarDB, DictDB, ArrayDB
from .iconscore.icon_score_base import interface, eventlog, external, payable, IconScoreBase, IconScoreDatabase
from .iconscore.icon_score_base2 import InterfaceScore, revert, sha3_256, json_loads, json_dumps
from .iconscore.icon_score_base2 import recover_key, create_address_with_key
from .iconscore.icon_system_score_base import IconSystemScoreBase

from iconcommons.logger import Logger

from inspect import isfunction
from functools import wraps
from abc import ABCMeta, abstractmethod, ABC
161 changes: 76 additions & 85 deletions iconservice/base/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,37 @@
# limitations under the License.

from enum import IntEnum, unique
from functools import wraps

from ..icon_constant import ICON_EXCEPTION_LOG_TAG
from iconcommons.logger import Logger

from typing import Optional, Union
from typing import Optional


@unique
class ExceptionCode(IntEnum):
"""Result code enumeration
Refer to http://www.simple-is-better.org/json-rpc/jsonrpc20.html#examples
"""
OK = 0

# 32000 ~ 32099: Server error
SERVER_ERROR = 32000
SCORE_ERROR = 32100
INVALID_REQUEST = 32600
METHOD_NOT_FOUND = 32601
INVALID_PARAMS = 32602
INTERNAL_ERROR = 32603

# for inner handle consensus #33000
SYSTEM_ERROR = 1
CONTRACT_NOT_FOUND = 2
METHOD_NOT_FOUND = 3
METHOD_NOT_PAYABLE = 4
ILLEGAL_FORMAT = 5
INVALID_PARAMETER = 6
INVALID_INSTANCE = 7
INVALID_CONTAINER_ACCESS = 8
ACCESS_DENIED = 9
OUT_OF_STEP = 10
OUT_OF_BALANCE = 11
TIMEOUT_ERROR = 12
STACK_OVERFLOW = 13
INVALID_PACKAGE = 14

# Caused by revert call or user-defined exception.
SCORE_ERROR = 32
END = 99

def __str__(self) -> str:
if self.value == self.INVALID_REQUEST:
return "Invalid Request"
else:
return str(self.name).capitalize().replace('_', ' ')
return str(self.name).capitalize().replace('_', ' ')


class IconServiceBaseException(BaseException):
"""All custom exceptions used in ICONService SHOULD inherit from IconServiceBaseException
"""All custom exceptions used in IconService should inherit from this
"""

def __init__(self, message: Optional[str], code: ExceptionCode = ExceptionCode.OK):
Expand All @@ -70,104 +66,99 @@ def __str__(self):
return f'{self.message} ({self.code})'


class IconTypeError(IconServiceBaseException):
def __init__(self, message: str):
super().__init__(message)


class InvalidParamsException(IconServiceBaseException):
class ScoreNotFoundException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.INVALID_PARAMS)
super().__init__(message, ExceptionCode.CONTRACT_NOT_FOUND)


class MethodNotFoundException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.METHOD_NOT_FOUND)


class ServerErrorException(IconServiceBaseException):
class MethodNotPayableException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.SERVER_ERROR)
super().__init__(message, ExceptionCode.METHOD_NOT_PAYABLE)


class ScoreErrorException(IconServiceBaseException):
def __init__(self, message: Optional[str], code: ExceptionCode = ExceptionCode.SCORE_ERROR):
super().__init__(message, code)
class InvalidParamsException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.INVALID_PARAMETER)


class InvalidRequestException(IconServiceBaseException):
class AccessDeniedException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.INVALID_REQUEST)
super().__init__(message, ExceptionCode.ACCESS_DENIED)


class DatabaseException(IconServiceBaseException):
def __init__(self, message: Optional[str], code: ExceptionCode = ExceptionCode.SERVER_ERROR):
super().__init__(message, code)
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.ACCESS_DENIED)


class IconScoreException(IconServiceBaseException):
def __init__(self,
message: Optional[str],
code: ExceptionCode = ExceptionCode.SERVER_ERROR):
super().__init__(message, code)
class InvalidInstanceException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.INVALID_INSTANCE)


class APIIconScoreBaseException(IconScoreException):
def __init__(self, message: Optional[str], func_name: str, cls_name: str,
code: ExceptionCode = ExceptionCode.SCORE_ERROR):
super().__init__(message, code)
self.__func_name = func_name
self.__cls_name = cls_name
class InvalidContainerAccessException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.INVALID_CONTAINER_ACCESS)

@property
def func_name(self):
return self.__func_name

@property
def cls_name(self):
return self.__cls_name
class IllegalFormatException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.ILLEGAL_FORMAT)

def __str__(self):
return f'msg: {self.message}, func: {self.func_name}, cls: {self.cls_name} ({self.code})'

class InvalidRequestException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.ILLEGAL_FORMAT)


class ExternalException(APIIconScoreBaseException):
def __init__(self, message: Optional[str], func_name: str, cls_name: str,
code: ExceptionCode = ExceptionCode.SCORE_ERROR):
super().__init__(message, func_name, cls_name, code)
class InvalidExternalException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.ILLEGAL_FORMAT)


class PayableException(APIIconScoreBaseException):
def __init__(self, message: Optional[str], func_name: str, cls_name: str,
code: ExceptionCode = ExceptionCode.SCORE_ERROR):
super().__init__(message, func_name, cls_name, code)
class InvalidPayableException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.ILLEGAL_FORMAT)


class RevertException(ScoreErrorException):
def __init__(self, message: Optional[str], code: Union[ExceptionCode, int] = ExceptionCode.SCORE_ERROR):
super().__init__(message, code)
class InvalidEventLogException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.ILLEGAL_FORMAT)


class InterfaceException(ScoreErrorException):
def __init__(self, message: Optional[str], code: ExceptionCode = ExceptionCode.SCORE_ERROR):
super().__init__(message, code)
class InvalidInterfaceException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.ILLEGAL_FORMAT)


class EventLogException(ScoreErrorException):
def __init__(self, message: Optional[str], code: ExceptionCode = ExceptionCode.SCORE_ERROR):
super().__init__(message, code)
class OutOfBalanceException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.OUT_OF_BALANCE)


class ContainerDBException(ScoreErrorException):
def __init__(self, message: Optional[str], code: ExceptionCode = ExceptionCode.SCORE_ERROR):
super().__init__(message, code)
class StackOverflowException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.STACK_OVERFLOW)


class ScoreInstallException(IconScoreException):
def __init__(self, message: Optional[str], code: ExceptionCode = ExceptionCode.INVALID_PARAMS):
super().__init__(message, code)
class InvalidPackageException(IconServiceBaseException):
def __init__(self, message: Optional[str]):
super().__init__(message, ExceptionCode.INVALID_PACKAGE)


class ScoreInstallExtractException(IconScoreException):
def __init__(self, message: Optional[str], code: ExceptionCode = ExceptionCode.INVALID_PARAMS):
class IconScoreException(IconServiceBaseException):
# All the user-defined exceptions should inherit from this exception including revert call
def __init__(self, message: Optional[str], index: int = 0):
if not isinstance(index, int):
raise InvalidParamsException('Invalid index type: not an integer')
code = ExceptionCode.SCORE_ERROR + index
if code < ExceptionCode.SCORE_ERROR:
code = ExceptionCode.SCORE_ERROR
elif code > ExceptionCode.END:
code = ExceptionCode.END
super().__init__(message, code)
6 changes: 3 additions & 3 deletions iconservice/database/batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from typing import TYPE_CHECKING, Optional
from collections.abc import MutableMapping

from ..base.exception import ServerErrorException
from ..base.exception import DatabaseException

if TYPE_CHECKING:
from ..base.block import Block
Expand Down Expand Up @@ -87,7 +87,7 @@ def __setitem__(self, key, value):
call_batch[key] = value

def __delitem__(self, key):
raise ServerErrorException('To delete item is not allowed')
raise DatabaseException('delete item is not allowed')

def __contains__(self, item):
for call_batch in self._call_batches:
Expand Down Expand Up @@ -124,7 +124,7 @@ def leave_call(self):

def digest(self) -> bytes:
if len(self._call_batches) != 1:
raise ServerErrorException(f'Wrong call_batch count: {len(self._call_batches)}')
raise DatabaseException(f'Wrong call_batch count: {len(self._call_batches)}')

return digest(self._call_batches[0])

Expand Down
21 changes: 10 additions & 11 deletions iconservice/database/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
import plyvel

from iconcommons.logger import Logger
from iconservice.base.exception import DatabaseException
from iconservice.icon_constant import ICON_DB_LOG_TAG
from iconservice.iconscore.icon_score_context import ContextGetter
from iconservice.iconscore.icon_score_context import IconScoreContextType
from ..base.exception import DatabaseException, InvalidParamsException
from ..icon_constant import ICON_DB_LOG_TAG
from ..iconscore.icon_score_context import ContextGetter
from ..iconscore.icon_score_context import IconScoreContextType

if TYPE_CHECKING:
from iconservice.iconscore.icon_score_context import IconScoreContext
from iconservice.base.address import Address
from ..base.address import Address
from ..iconscore.icon_score_context import IconScoreContext


def _get_context_type(context: 'IconScoreContext') -> 'IconScoreContextType':
Expand Down Expand Up @@ -249,7 +249,7 @@ def put(self,
:param value:
"""
if not _is_db_writable_on_context(context):
raise DatabaseException('put is not allowed')
raise DatabaseException('No permission to write')

context_type = _get_context_type(context)

Expand All @@ -265,7 +265,7 @@ def delete(self, context: Optional['IconScoreContext'], key: bytes):
:param key: key to delete from db
"""
if not _is_db_writable_on_context(context):
raise DatabaseException('delete is not allowed')
raise DatabaseException('No permission to delete')

context_type = _get_context_type(context)

Expand All @@ -280,8 +280,7 @@ def close(self, context: 'IconScoreContext') -> None:
:param context:
"""
if not _is_db_writable_on_context(context):
raise DatabaseException(
'close is not allowed on readonly context')
raise DatabaseException('No permission to close')

if not self._is_shared:
return self.key_value_db.close()
Expand Down Expand Up @@ -361,7 +360,7 @@ def get_sub_db(self, prefix: bytes) -> 'IconScoreDatabase':
:return: sub db
"""
if prefix is None:
raise DatabaseException(
raise InvalidParamsException(
'Invalid params: '
'prefix is None in IconScoreDatabase.get_sub_db()')

Expand Down
4 changes: 2 additions & 2 deletions iconservice/deploy/icon_builtin_score_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from .icon_score_deploy_storage import IconScoreDeployInfo, DeployState
from .utils import remove_path
from ..base.address import Address
from ..base.exception import ServerErrorException
from ..base.exception import AccessDeniedException
from ..icon_constant import BUILTIN_SCORE_ADDRESS_MAPPER, ZERO_TX_HASH, ICON_DEPLOY_LOG_TAG
from ..iconscore.icon_score_context_util import IconScoreContextUtil

Expand Down Expand Up @@ -61,7 +61,7 @@ def _load_score(context: 'IconScoreContext',
assert score is not None

if score.owner != builtin_score_owner:
raise ServerErrorException(
raise AccessDeniedException(
f'score.owner({score.owner}) != builtin_score_owner({builtin_score_owner})')

@staticmethod
Expand Down
8 changes: 5 additions & 3 deletions iconservice/deploy/icon_score_deploy_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@
from .utils import remove_path, get_score_deploy_path, get_score_path
from ..base.address import Address
from ..base.address import ZERO_SCORE_ADDRESS
from ..base.exception import InvalidParamsException, ServerErrorException
from ..base.exception import InvalidParamsException
from ..base.message import Message
from ..base.type_converter import TypeConverter
from ..icon_constant import IconServiceFlag, ICON_DEPLOY_LOG_TAG, REVISION_2, REVISION_3
from ..iconscore.icon_score_context_util import IconScoreContextUtil
from ..iconscore.icon_score_mapper_object import IconScoreInfo
from ..iconscore.icon_score_api_generator import ScoreApiGenerator
from ..utils import is_builtin_score

if TYPE_CHECKING:
Expand Down Expand Up @@ -76,7 +77,7 @@ def invoke(self,
assert icon_score_address.is_contract

if icon_score_address in (None, ZERO_SCORE_ADDRESS):
raise ServerErrorException(f'Invalid SCORE address: {icon_score_address}')
raise InvalidParamsException(f'Invalid SCORE address: {icon_score_address}')

try:
IconScoreContextUtil.validate_score_blacklist(context, icon_score_address)
Expand Down Expand Up @@ -188,6 +189,7 @@ def _on_deploy(self,
# score_info.get_score() returns a cached or created score instance
# according to context.revision.
score: 'IconScoreBase' = score_info.get_score(context.revision)
ScoreApiGenerator.check_on_deploy(context, score)

# owner is set in IconScoreBase.__init__()
context.msg = Message(sender=score.owner)
Expand Down Expand Up @@ -291,7 +293,7 @@ def _initialize_score(deploy_type: DeployType, score: 'IconScoreBase', params: d
elif deploy_type == DeployType.UPDATE:
on_init = score.on_update
else:
raise ServerErrorException(f'Invalid deployType: {deploy_type}')
raise InvalidParamsException(f'Invalid deployType: {deploy_type}')

annotations = TypeConverter.make_annotations_from_method(on_init)
TypeConverter.convert_data_params(annotations, params)
Expand Down

0 comments on commit ef6217c

Please sign in to comment.