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

Release 1.6.0 #405

Merged
merged 43 commits into from
Jan 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
45dea3a
Add rollback message handler to IconInnerService
Oct 28, 2019
345aa97
Apply backup_manager to IconServiceEngine
Oct 29, 2019
6b7f808
Implement rollback() in IconServiceEngine and PRepEngine
Nov 7, 2019
8ea17e9
Implement IconServiceEngine.rollback()
Nov 8, 2019
a917545
Fix unittest errors after rebasing
Nov 8, 2019
acb37ba
Implement ROLLBACK procotol between IS and RC
Nov 8, 2019
4c0b83a
Fix minor type hint bugs on RewardProxyCalc class
Nov 12, 2019
be25485
Before implementing IconServiceEngine.rollback()
Nov 14, 2019
ef170bc
Implement IconServiceEngine.rollback()
Nov 18, 2019
73f9cf4
Add block_hash to ReadyNotification
Nov 18, 2019
b064b15
Unittest for BackupManager is under development
goldworm-icon Nov 18, 2019
d04434a
Update test_message_unpacker.py
Nov 19, 2019
45344cb
Implement an unitest for BackupManager
Nov 19, 2019
17b3ee1
Refactor RollbackManager
Nov 20, 2019
294d1e9
Fix minor bugs on rollback
Nov 21, 2019
7781afa
Improve unittest for rollback
Nov 22, 2019
2c0f9bb
Fix a minor bug in IconInnerService.rollback()
Dec 4, 2019
8e65485
Implement BackupCleaner
Dec 10, 2019
3cd060f
Minor update
Dec 10, 2019
36c0ab1
Add more detail logs to RollbackManager
Dec 11, 2019
1e7b5bb
Fix a crash on RCStorage.get_total_elected_prep_delegated_snapshot()
Dec 11, 2019
0ff42fe
Implement multi block rollback
Dec 11, 2019
b8a4675
Add "getInactivePReps" on PREP_METHOD_TABLE
boyeon555 Dec 16, 2019
4c9914f
Merge pull request #396 from icon-project/IS-946-bugfix-getInactivePR…
Dec 17, 2019
0da1a31
Apply write_batch to RollbackManager
goldworm-icon Dec 16, 2019
c96946b
Remove rc_version from iiss_rc_db name
Dec 18, 2019
683489d
Implement rollback recovery
Dec 19, 2019
7cbbe62
Merge branch 'IS-950-rollback-recovery' into IS-948-change-iiss-db-name
Dec 19, 2019
6c328a4
Remove ROLLBACK_METADATA file after rollback is done
Dec 19, 2019
df2d403
Merge branch 'IS-948-change-iiss-db-name' into IS-945-multi-block-rol…
Dec 20, 2019
91808b8
Remove trailing "_" from rc_db_name prefixes in RewardCalcStorage
Dec 20, 2019
9741bda
Refactor WAL recovery
Dec 20, 2019
e5aa538
Implement to recover rollback
Dec 23, 2019
f35f03d
Correct some logging message typos on rollback.Metadata
Dec 23, 2019
7fbec9b
Make rollback state rocovery robust
Dec 24, 2019
8fcc9d8
Change old-fashioned iiss_db_name
Dec 24, 2019
e2638c2
Change block backup filename format
Jan 2, 2020
718e20a
Merge branch 'IS-945-multi-block-rollback' into IS-894-prev-state-rol…
Jan 2, 2020
346432d
Update BackupCleaner
Jan 2, 2020
0a1f613
Merge branch 'IS-955-remove-obsolete-backup-files' into IS-894-prev-s…
Jan 2, 2020
063660b
Merge pull request #398 from icon-project/IS-894-prev-state-rollback-…
Jan 3, 2020
3056ce7
VERSION: 1.6.0
Jan 3, 2020
4d06ea5
Merge branch 'master' into release-1.6.0
Jan 20, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.5.20
1.6.0
6 changes: 6 additions & 0 deletions iconservice/base/ComponentBase.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ def open(self, *args, **kwargs):
def close(self):
pass

def rollback(self, context: 'IconScoreContext', block_height: int, block_hash: bytes):
pass


class StorageBase(ABC):

Expand All @@ -54,3 +57,6 @@ def close(self, context: 'IconScoreContext'):
if self._db:
self._db.close(context)
self._db = None

def rollback(self, context: 'IconScoreContext', block_height: int, block_hash: bytes):
pass
6 changes: 6 additions & 0 deletions iconservice/base/type_converter_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class ParamType(IntEnum):

WRITE_PRECOMMIT = 400
REMOVE_PRECOMMIT = 500
ROLLBACK = 501

VALIDATE_TRANSACTION = 600

Expand Down Expand Up @@ -325,6 +326,11 @@ class ConstantKeys:

type_convert_templates[ParamType.REMOVE_PRECOMMIT] = type_convert_templates[ParamType.WRITE_PRECOMMIT]

type_convert_templates[ParamType.ROLLBACK] = {
ConstantKeys.BLOCK_HEIGHT: ValueType.INT,
ConstantKeys.BLOCK_HASH: ValueType.BYTES
}

type_convert_templates[ParamType.VALIDATE_TRANSACTION] = {
ConstantKeys.METHOD: ValueType.STRING,
ConstantKeys.PARAMS: type_convert_templates[ParamType.TRANSACTION_PARAMS_DATA]
Expand Down
13 changes: 12 additions & 1 deletion iconservice/database/wal.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@
from ..iiss.reward_calc.storage import Storage, get_rc_version
from ..utils.msgpack_for_db import MsgPackForDB

__all__ = ("WriteAheadLogWriter", "WriteAheadLogReader", "WALogable", "StateWAL", "IissWAL", "WALState")
__all__ = (
"WriteAheadLogWriter", "WriteAheadLogReader", "WALogable", "StateWAL", "IissWAL", "WALState", "WALDBType"
)

import struct
from abc import ABCMeta
from typing import Optional, Tuple, Iterable, List
import os
from enum import Enum

import msgpack
from iconcommons.logger import Logger
Expand Down Expand Up @@ -52,6 +55,11 @@
_OFFSET_LOG_START_OFFSETS = _OFFSET_LOG_COUNT + 4


class WALDBType(Enum):
RC = 0
STATE = 1


class WALState(Flag):
CALC_PERIOD_START_BLOCK = auto()
# Write WAL to rc_db
Expand All @@ -63,6 +71,9 @@ class WALState(Flag):
# Send CALCULATE message to rc
SEND_CALCULATE = auto()

# Means All flags are on
ALL = 0xFFFFFFFF


def tx_batch_value_to_bytes(tx_batch_value: 'TransactionBatchValue') -> Optional[bytes]:
if not isinstance(tx_batch_value, TransactionBatchValue):
Expand Down
10 changes: 7 additions & 3 deletions iconservice/icon_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from .icon_constant import ConfigKey, ICX_IN_LOOP, TERM_PERIOD, IISS_DAY_BLOCK, PREP_MAIN_PREPS, \
PREP_MAIN_AND_SUB_PREPS, PENALTY_GRACE_PERIOD, LOW_PRODUCTIVITY_PENALTY_THRESHOLD, BLOCK_VALIDATION_PENALTY_THRESHOLD
from .icon_constant import (
ConfigKey, ICX_IN_LOOP, TERM_PERIOD, IISS_DAY_BLOCK, PREP_MAIN_PREPS,
PREP_MAIN_AND_SUB_PREPS, PENALTY_GRACE_PERIOD, LOW_PRODUCTIVITY_PENALTY_THRESHOLD,
BLOCK_VALIDATION_PENALTY_THRESHOLD, BACKUP_FILES
)

default_icon_config = {
"log": {
Expand Down Expand Up @@ -57,5 +60,6 @@
ConfigKey.LOW_PRODUCTIVITY_PENALTY_THRESHOLD: LOW_PRODUCTIVITY_PENALTY_THRESHOLD,
ConfigKey.BLOCK_VALIDATION_PENALTY_THRESHOLD: BLOCK_VALIDATION_PENALTY_THRESHOLD,
ConfigKey.STEP_TRACE_FLAG: False,
ConfigKey.PRECOMMIT_DATA_LOG_FLAG: False
ConfigKey.PRECOMMIT_DATA_LOG_FLAG: False,
ConfigKey.BACKUP_FILES: BACKUP_FILES
}
15 changes: 11 additions & 4 deletions iconservice/icon_constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
IISS_LOG_TAG = "IISS"
STEP_LOG_TAG = "STEP"
WAL_LOG_TAG = "WAL"
ROLLBACK_LOG_TAG = "ROLLBACK"
BACKUP_LOG_TAG = "BACKUP"

JSONRPC_VERSION = '2.0'
CHARSET_ENCODING = 'utf-8'
Expand Down Expand Up @@ -121,7 +123,6 @@ class Revision(Enum):
RC_DB_VERSION_0 = 0
RC_DB_VERSION_2 = 2


# The case that version is updated but not revision, set the version to the current revision
# The case that both version and revision is updated, add revision field to the version table
# The case that only revision is changed, do not update this table
Expand Down Expand Up @@ -181,6 +182,9 @@ class ConfigKey:
LOW_PRODUCTIVITY_PENALTY_THRESHOLD = "lowProductivityPenaltyThreshold"
BLOCK_VALIDATION_PENALTY_THRESHOLD = "blockValidationPenaltyThreshold"

# The maximum number of backup files for rollback
BACKUP_FILES = "backupFiles"


class EnableThreadFlag(IntFlag):
INVOKE = 1
Expand Down Expand Up @@ -252,7 +256,8 @@ class DeployState(IntEnum):
"getMainPReps",
"getSubPReps",
"getPReps",
"getPRepTerm"
"getPRepTerm",
"getInactivePReps"
]

DEBUG_METHOD_TABLE = [
Expand Down Expand Up @@ -292,13 +297,15 @@ class DeployState(IntEnum):

PENALTY_GRACE_PERIOD = IISS_DAY_BLOCK * 2

LOW_PRODUCTIVITY_PENALTY_THRESHOLD = 85 # Unit: Percent
BLOCK_VALIDATION_PENALTY_THRESHOLD = 660 # Unit: Blocks
LOW_PRODUCTIVITY_PENALTY_THRESHOLD = 85 # Unit: Percent
BLOCK_VALIDATION_PENALTY_THRESHOLD = 660 # Unit: Blocks

BASE_TRANSACTION_VERSION = 3

PREP_PENALTY_SIGNATURE = "PenaltyImposed(Address,int,int)"

BACKUP_FILES = 10


class RCStatus(IntEnum):
NOT_READY = 0
Expand Down
55 changes: 51 additions & 4 deletions iconservice/icon_inner_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ def _check_icon_service_ready(self):

@staticmethod
def _log_exception(e: BaseException, tag: str = ICON_INNER_LOG_TAG) -> None:
Logger.exception(e, tag)
Logger.error(e, tag)
Logger.exception(str(e), tag)
Logger.error(str(e), tag)

@message_queue_task
async def hello(self):
Expand Down Expand Up @@ -331,7 +331,7 @@ def _remove_precommit_state(self, request: dict):
block_height, instant_block_hash, _ = \
self._get_block_info_for_precommit_state(converted_block_params)

self._icon_service_engine.rollback(block_height, instant_block_hash)
self._icon_service_engine.remove_precommit_state(block_height, instant_block_hash)
response = MakeResponse.make_response(ExceptionCode.OK)
except FatalException as e:
self._log_exception(e, ICON_SERVICE_LOG_TAG)
Expand All @@ -347,6 +347,53 @@ def _remove_precommit_state(self, request: dict):
Logger.info(f'remove_precommit_state response with {response}', ICON_INNER_LOG_TAG)
return response

@message_queue_task
async def rollback(self, request: dict):
"""Go back to the state of the given previous block

:param request:
:return:
"""

Logger.info(tag=ICON_INNER_LOG_TAG, msg=f"rollback() start: {request}")

self._check_icon_service_ready()

if self._is_thread_flag_on(EnableThreadFlag.INVOKE):
loop = asyncio.get_event_loop()
response = await loop.run_in_executor(self._thread_pool[THREAD_INVOKE], self._rollback, request)
else:
response = self._rollback(request)

Logger.info(tag=ICON_INNER_LOG_TAG, msg=f"rollback() end: {response}")

return response

def _rollback(self, request: dict) -> dict:
Logger.info(tag=ICON_INNER_LOG_TAG, msg=f"_rollback() start: {request}")

response = {}
try:
converted_params = TypeConverter.convert(request, ParamType.ROLLBACK)
block_height: int = converted_params[ConstantKeys.BLOCK_HEIGHT]
block_hash: bytes = converted_params[ConstantKeys.BLOCK_HASH]

response: dict = self._icon_service_engine.rollback(block_height, block_hash)
response = MakeResponse.make_response(response)
except FatalException as e:
self._log_exception(e, ICON_SERVICE_LOG_TAG)
response = MakeResponse.make_error_response(ExceptionCode.SYSTEM_ERROR, str(e))
self._close()
except IconServiceBaseException as icon_e:
self._log_exception(icon_e, ICON_SERVICE_LOG_TAG)
response = MakeResponse.make_error_response(icon_e.code, icon_e.message)
except BaseException as e:
self._log_exception(e, ICON_SERVICE_LOG_TAG)
response = MakeResponse.make_error_response(ExceptionCode.SYSTEM_ERROR, str(e))
finally:
Logger.info(tag=ICON_INNER_LOG_TAG, msg=f"_rollback() end: {response}")
return response

@message_queue_task
async def validate_transaction(self, request: dict):
Logger.debug(f'pre_validate_check request with {request}', ICON_INNER_LOG_TAG)
Expand Down Expand Up @@ -382,7 +429,7 @@ def _validate_transaction(self, request: dict):
return response

@message_queue_task
async def change_block_hash(self, params):
async def change_block_hash(self, _params):

self._check_icon_service_ready()

Expand Down
Loading