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

Release 1.5.20 #397

Merged
merged 36 commits into from
Dec 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ec47abc
IS-915: Fix infinite loop on ipc_server termination
Nov 12, 2019
793b529
Merge pull request #387 from icon-project/IS-915-bugfix-ipc-channel-t…
Nov 18, 2019
7a1fd7a
IS-922-fix-field-on-getPRepTerm
cow-hs Nov 21, 2019
2fca8b5
Merge pull request #388 from icon-project/IS-922-fix-field-on-getPRep…
Nov 21, 2019
10a2c22
Merge branch 'release-1.5.18' into develop
Nov 21, 2019
698996a
IS-925: Add p2pEndpoint to the result of getPReps API
cow-hs Nov 22, 2019
1757a71
Add P-Rep candidates to the result of getPRepTerm API
boyeon555 Nov 22, 2019
cc14eda
Add integration-test for modified getPRepTerm API
boyeon555 Nov 26, 2019
33e7686
Update PRepContainer.get_inactive_preps()
Nov 27, 2019
91c3335
Update PRepEngine.handle_get_prep_term()
Nov 27, 2019
02512b0
Merge pull request #389 from icon-project/IS-923-add-candidates-to-pr…
boyeon555 Nov 28, 2019
daf8a68
Impose low productivity penalty when prep get block validation and lo…
soobokjin Nov 28, 2019
c89d89d
Merge pull request #390 from icon-project/IS-932-impose-low-productiv…
Nov 28, 2019
591cc66
IS-931: Implement get inactive p reps api (#391)
boyeon555 Dec 2, 2019
3bc25c4
IS-929: Fix a bug on PRepEngine._reset_block_validation_penalty (#392)
Dec 2, 2019
077a92c
IS-913: Transfer main_preps to loopchain on change endpoint
cow-hs Nov 12, 2019
52d6a20
IS-913: Transfer Endpoint to loopchain in term.
cow-hs Nov 14, 2019
8ea123a
Under development
Nov 15, 2019
4ec05f0
refector TermFlag
cow-hs Nov 18, 2019
68f378f
fix integrate test for revision
cow-hs Nov 18, 2019
8a76d19
Refactor Revision class
Nov 20, 2019
bc9c6c5
Refactor PRep class
Nov 25, 2019
ef0eb03
Update Term class
goldworm-icon Nov 26, 2019
9d9ce02
Optimize IconScoreContext.put_dirty_prep()
Dec 3, 2019
59d17b0
Update TermFlag
Dec 3, 2019
2974dee
Merge pull request #386 from icon-project/IS-913-transfer-endpoint-to…
Dec 4, 2019
67c1f33
Fix score data corruption on score query call
Dec 5, 2019
c60ba0a
Merge pull request #393 from icon-project/IS-936-fix-global-score-dat…
Dec 5, 2019
39941f5
Add tx_index and tx_hash to ClaimRequest and ClaimResponse
Nov 20, 2019
8b0f6b4
Add tx_index and tx_hash to CommitClaimRequest
Nov 20, 2019
36a0db0
Add InitRequest and InitResponse to RewardCalcProxy
Dec 6, 2019
b0918da
Add block_hash field to ReadyNotification class
Dec 6, 2019
752b5a5
Implement RewardCalcProxy.init_reward_calculator()
Dec 6, 2019
03641a5
Commit out to call IISSEngine.init_reward_calculator() in IconService…
Dec 8, 2019
068b35e
Merge pull request #395 from icon-project/IS-942-improve-to-sync-stat…
Dec 8, 2019
cc880e0
VERSION: 1.5.20
Dec 8, 2019
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.18
1.5.20
68 changes: 54 additions & 14 deletions iconservice/icon_constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from enum import IntFlag, unique, IntEnum, Enum, auto
from enum import IntFlag, unique, IntEnum, Enum, auto, Flag

GOVERNANCE_ADDRESS = "cx0000000000000000000000000000000000000001"

Expand Down Expand Up @@ -104,20 +104,18 @@ class IssueDataKey:


class Revision(Enum):
def _generate_next_value_(self, start, count, last_values):
if self != 'LATEST':
return start + count + 1
TWO = 2
THREE = 3
FOUR = 4
IISS = 5
DECENTRALIZATION = 6
FIX_TOTAL_ELECTED_PREP_DELEGATED = 7

return last_values[-1]
# Revision 8
REALTIME_P2P_ENDPOINT_UPDATE = 8
OPTIMIZE_DIRTY_PREP_UPDATE = 8

TWO = auto()
THREE = auto()
FOUR = auto()
IISS = auto()
DECENTRALIZATION = auto()
IS_1_5_16 = auto()

LATEST = auto()
LATEST = 8


RC_DB_VERSION_0 = 0
Expand Down Expand Up @@ -165,7 +163,7 @@ class ConfigKey:
STEP_TRACE_FLAG = 'stepTraceFlag'
PRECOMMIT_DATA_LOG_FLAG = 'precommitDataLogFlag'

#icon rc
# Reward calculator executable path
ICON_RC_DIR_PATH = 'iconRcPath'

# IISS meta data
Expand Down Expand Up @@ -344,3 +342,45 @@ class BlockVoteStatus(Enum):
NONE = 0
TRUE = 1
FALSE = 2


class PRepFlag(Flag):
"""Setting flags to True means that PRep fields specified by the flags has been changed

"""
NONE = 0
STATUS = auto()
NAME = auto()
COUNTRY = auto()
CITY = auto()
EMAIL = auto()
WEBSITE = auto()
DETAILS = auto()
P2P_ENDPOINT = auto()
PENALTY = auto()
GRADE = auto()
STAKE = auto()
DELEGATED = auto()
LAST_GENERATE_BLOCK_HEIGHT = auto()
TOTAL_BLOCKS = auto()
VALIDATED_BLOCKS = auto()
UNVALIDATED_SEQUENCE_BLOCKS = auto()
IREP = auto() # irep, irep_block_height
IREP_BLOCK_HEIGHT = auto()

BLOCK_STATISTICS = TOTAL_BLOCKS | VALIDATED_BLOCKS | UNVALIDATED_SEQUENCE_BLOCKS
ALL = 0xFFFFFFFF


class PRepContainerFlag(Flag):
NONE = 0
DIRTY = auto()


class TermFlag(Flag):
NONE = 0
MAIN_PREPS = auto()
SUB_PREPS = auto()
MAIN_PREP_P2P_ENDPOINT = auto()

ALL = 0xFFFFFFFF
31 changes: 20 additions & 11 deletions iconservice/icon_inner_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from asyncio import get_event_loop
import asyncio
from concurrent.futures.thread import ThreadPoolExecutor
from typing import Any, TYPE_CHECKING, Optional, Tuple

from earlgrey import message_queue_task, MessageQueueStub, MessageQueueService

from iconcommons.logger import Logger

from iconservice.base.address import Address
from iconservice.base.block import Block
from iconservice.base.exception import ExceptionCode, IconServiceBaseException, InvalidBaseTransactionException, \
FatalException, ServiceNotReadyException
from iconservice.base.type_converter import TypeConverter, ParamType
from iconservice.base.type_converter_templates import ConstantKeys
from iconservice.icon_constant import ICON_INNER_LOG_TAG, ICON_SERVICE_LOG_TAG, \
EnableThreadFlag, ENABLE_THREAD_FLAG, ConfigKey, RCStatus
EnableThreadFlag, ENABLE_THREAD_FLAG
from iconservice.icon_service_engine import IconServiceEngine
from iconservice.utils import check_error_response, to_camel_case

Expand All @@ -39,6 +39,9 @@
THREAD_VALIDATE = 'validate'


_TAG = "IIS"


class IconScoreInnerTask(object):
def __init__(self, conf: 'IconConfig'):
self._conf = conf
Expand Down Expand Up @@ -75,7 +78,7 @@ async def hello(self):
await ready_future

if self._is_thread_flag_on(EnableThreadFlag.INVOKE):
loop = get_event_loop()
loop = asyncio.get_event_loop()
ret = await loop.run_in_executor(self._thread_pool[THREAD_INVOKE], self._hello)
else:
ret = self._hello()
Expand All @@ -88,25 +91,31 @@ def _hello(self):
return self._icon_service_engine.hello()

def _close(self):
Logger.info("icon_score_service close", ICON_INNER_LOG_TAG)
Logger.info(tag=_TAG, msg="_close() start")

if self._icon_service_engine:
self._icon_service_engine.close()
self._icon_service_engine = None
MessageQueueService.loop.stop()

Logger.info(tag=_TAG, msg="_close() end")

@message_queue_task
async def close(self):
Logger.info(tag=_TAG, msg="close() start")

self._close()

Logger.info(tag=_TAG, msg="close() end")

@message_queue_task
async def invoke(self, request: dict):
Logger.info(f'invoke request with {request}', ICON_INNER_LOG_TAG)

self._check_icon_service_ready()

if self._is_thread_flag_on(EnableThreadFlag.INVOKE):
loop = get_event_loop()
loop = asyncio.get_event_loop()
return await loop.run_in_executor(self._thread_pool[THREAD_INVOKE],
self._invoke, request)
else:
Expand Down Expand Up @@ -184,7 +193,7 @@ async def query(self, request: dict):
self._check_icon_service_ready()

if self._is_thread_flag_on(EnableThreadFlag.QUERY):
loop = get_event_loop()
loop = asyncio.get_event_loop()
return await loop.run_in_executor(self._thread_pool[THREAD_QUERY],
self._query, request)
else:
Expand Down Expand Up @@ -227,7 +236,7 @@ async def call(self, request: dict):
self._check_icon_service_ready()

if self._is_thread_flag_on(EnableThreadFlag.QUERY):
loop = get_event_loop()
loop = asyncio.get_event_loop()
return await loop.run_in_executor(self._thread_pool[THREAD_QUERY],
self._call, request)
else:
Expand Down Expand Up @@ -261,7 +270,7 @@ async def write_precommit_state(self, request: dict):
self._check_icon_service_ready()

if self._is_thread_flag_on(EnableThreadFlag.INVOKE):
loop = get_event_loop()
loop = asyncio.get_event_loop()
return await loop.run_in_executor(self._thread_pool[THREAD_INVOKE],
self._write_precommit_state, request)
else:
Expand Down Expand Up @@ -309,7 +318,7 @@ async def remove_precommit_state(self, request: dict):
self._check_icon_service_ready()

if self._is_thread_flag_on(EnableThreadFlag.INVOKE):
loop = get_event_loop()
loop = asyncio.get_event_loop()
return await loop.run_in_executor(self._thread_pool[THREAD_INVOKE],
self._remove_precommit_state, request)
else:
Expand Down Expand Up @@ -345,7 +354,7 @@ async def validate_transaction(self, request: dict):
self._check_icon_service_ready()

if self._is_thread_flag_on(EnableThreadFlag.VALIDATE):
loop = get_event_loop()
loop = asyncio.get_event_loop()
return await loop.run_in_executor(self._thread_pool[THREAD_VALIDATE],
self._validate_transaction, request)
else:
Expand Down
10 changes: 9 additions & 1 deletion iconservice/icon_service_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -2129,18 +2129,26 @@ def hello(self) -> dict:
"""
Logger.debug(tag=self.TAG, msg="hello() start")

iiss_engine: 'IISSEngine' = IconScoreContext.engine.iiss

last_block: 'Block' = self._get_last_block()

if isinstance(self._wal_reader, WriteAheadLogReader):
wal_state = WALState(self._wal_reader.state)

# If only writing rc_db is done on commit without sending COMMIT_BLOCK to rc,
# send COMMIT_BLOCK to rc prior to invoking a block
if not (wal_state & WALState.SEND_COMMIT_BLOCK):
IconScoreContext.engine.iiss.send_commit(
iiss_engine.send_commit(
self._wal_reader.block.height, self._wal_reader.instant_block_hash)

assert last_block == self._wal_reader.block

# No need to use
self._wal_reader = None

# iiss_engine.init_reward_calculator(last_block)

Logger.debug(tag=self.TAG, msg="hello() end")

return {}
1 change: 0 additions & 1 deletion iconservice/iconscore/icon_score_base2.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,6 @@ def get_main_prep_info() -> Tuple[List[PRepInfo], int]:
context = ContextContainer._get_context()
assert context

# TODO: Fix an error on unittest first before removing the commit below (goldworm)
term = context.term
if term is None:
return [], -1
Expand Down
50 changes: 35 additions & 15 deletions iconservice/iconscore/icon_score_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from typing import TYPE_CHECKING, Optional, List

from iconcommons.logger import Logger
from iconservice.icx.issue.regulator import Regulator

from .icon_score_mapper import IconScoreMapper
from .icon_score_trace import Trace
from ..base.block import Block
Expand All @@ -29,8 +29,9 @@
from ..base.transaction import Transaction
from ..database.batch import BlockBatch, TransactionBatch
from ..icon_constant import (
IconScoreContextType, IconScoreFuncType, TERM_PERIOD, PRepGrade, PREP_MAIN_PREPS, PREP_MAIN_AND_SUB_PREPS
)
IconScoreContextType, IconScoreFuncType, TERM_PERIOD, PRepGrade, PREP_MAIN_PREPS, PREP_MAIN_AND_SUB_PREPS,
Revision, PRepFlag)
from ..icx.issue.regulator import Regulator

if TYPE_CHECKING:
from .icon_score_base import IconScoreBase
Expand Down Expand Up @@ -185,13 +186,6 @@ def preps(self) -> Optional['PRepContainer']:
def term(self) -> Optional['Term']:
return self._term

def is_term_updated(self) -> bool:
"""Returns whether info in self._term is changed

:return:
"""
return self._term and self._term.is_dirty()

def is_decentralized(self) -> bool:
return self.engine.prep.term is not None

Expand Down Expand Up @@ -231,7 +225,7 @@ def update_rc_db_batch(self):
self.rc_tx_batch.clear()

def update_dirty_prep_batch(self):
"""Update context.preps when a tx is done
"""Apply updated P-Rep data to context.preps every time when a tx is done

Caution: call update_dirty_prep_batch before update_state_db_batch()
"""
Expand All @@ -240,6 +234,9 @@ def update_dirty_prep_batch(self):
# we should update P-Reps in this term
self._update_elected_preps_in_term(dirty_prep)

if self.revision >= Revision.REALTIME_P2P_ENDPOINT_UPDATE.value:
self._update_main_preps_in_term(dirty_prep)

self._preps.replace(dirty_prep)
# Write serialized dirty_prep data into tx_batch
self.storage.prep.put_prep(self, dirty_prep)
Expand All @@ -266,10 +263,24 @@ def _update_elected_preps_in_term(self, dirty_prep: 'PRep'):
# Just in case, reset the P-Rep grade one to CANDIDATE
dirty_prep.grade = PRepGrade.CANDIDATE

self._term.update_preps(self.revision, [dirty_prep])
self._term.update_invalid_elected_preps([dirty_prep])

Logger.info(tag=self.TAG, msg=f"Invalid main and sub prep: {dirty_prep}")

def _update_main_preps_in_term(self, dirty_prep: 'PRep'):
"""

:param dirty_prep: dirty prep
"""
if self._term is None:
return

if dirty_prep.is_flags_on(PRepFlag.P2P_ENDPOINT) and \
self._term.is_main_prep(dirty_prep.address):
self._term.on_main_prep_p2p_endpoint_updated()

Logger.info(tag=self.TAG, msg=f"_update_main_prep_endpoint_in_term: {dirty_prep}")

def clear_batch(self):
if self.tx_batch:
self.tx_batch.clear()
Expand All @@ -295,10 +306,19 @@ def get_prep(self, address: 'Address', mutable: bool = False) -> Optional['PRep'
def put_dirty_prep(self, prep: 'PRep'):
Logger.debug(tag=self.TAG, msg=f"put_dirty_prep() start: {prep}")

if self._tx_dirty_preps is not None:
self._tx_dirty_preps[prep.address] = prep
if self._tx_dirty_preps is None:
Logger.warning(tag=self.TAG, msg="self._tx_dirty_preps is None")
Logger.debug(tag=self.TAG, msg="put_dirty_prep() end")
return

if not prep.is_dirty() and self.revision >= Revision.OPTIMIZE_DIRTY_PREP_UPDATE.value:
Logger.info(tag=self.TAG, msg=f"No need to update an unchanged P-Rep: revision={self.revision}")
Logger.debug(tag=self.TAG, msg="put_dirty_prep() end")
return

self._tx_dirty_preps[prep.address] = prep

Logger.debug(tag=self.TAG, msg=f"put_dirty_prep() end")
Logger.debug(tag=self.TAG, msg="put_dirty_prep() end")


class IconScoreContextFactory(object):
Expand Down
5 changes: 4 additions & 1 deletion iconservice/iconscore/icon_score_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ def _call(context: 'IconScoreContext',
context.current_address: 'Address' = icon_score_address

score_func = getattr(icon_score, ATTR_SCORE_CALL)
return score_func(func_name=func_name, kw_params=converted_params)
ret = score_func(func_name=func_name, kw_params=converted_params)

# No problem even though ret is None
return deepcopy(ret)

@staticmethod
def _convert_score_params_by_annotations(icon_score: 'IconScoreBase', func_name: str, kw_params: dict) -> dict:
Expand Down
Loading