Пример #1
0
    async def __run_score_container(self):
        if not conf.USE_EXTERNAL_SCORE or conf.EXTERNAL_SCORE_RUN_IN_LAUNCHER:
            process_args = [
                'python3', '-m', 'loopchain', 'score', '--channel',
                ChannelProperty().name, '--score_package',
                ChannelProperty().score_package
            ]
            process_args += command_arguments.get_raw_commands_by_filter(
                command_arguments.Type.AMQPTarget,
                command_arguments.Type.AMQPKey, command_arguments.Type.Develop,
                command_arguments.Type.ConfigurationFilePath)
            self.__score_container = CommonSubprocess(process_args)

        if util.channel_use_icx(ChannelProperty().name):
            await StubCollection().create_icon_score_stub(
                ChannelProperty().name)
            await StubCollection().icon_score_stubs[ChannelProperty().name
                                                    ].connect()
            await StubCollection().icon_score_stubs[ChannelProperty().name
                                                    ].async_task().hello()
            return None
        else:
            await StubCollection().create_score_stub(
                ChannelProperty().name,
                ChannelProperty().score_package)
            await StubCollection().score_stubs[ChannelProperty().name
                                               ].connect()
            await StubCollection().score_stubs[ChannelProperty().name
                                               ].async_task().hello()

            return await self.__load_score()
Пример #2
0
    def score_change_block_hash(self, block_height, old_block_hash, new_block_hash):
        change_hash_info = json.dumps({"block_height": block_height, "old_block_hash": old_block_hash,
                                       "new_block_hash": new_block_hash})

        if not util.channel_use_icx(ChannelProperty().name):
            stub = StubCollection().score_stubs[ChannelProperty().name]
            stub.sync_task().change_block_hash(change_hash_info)
Пример #3
0
    def verify_through_score_invoke(self, is_leader: bool=False):
        # Block에 속한 tx목록을 순회하면서 Invoke 실행
        is_verified = True
        invoke_results = {}

        if ObjectManager().channel_service is None:
            # all results to success
            success_result = dict(code=int(message_code.Response.success))
            invoke_results = util.create_invoke_result_specific_case(self.confirmed_transaction_list, success_result)
        else:
            try:
                origin_commit_state = copy.deepcopy(self.commit_state)
                invoke_results = ObjectManager().channel_service.score_invoke(self)

                if is_leader:
                    # set commit state as a leader while do nothing, block commit_state set by score_invoke
                    util.logger.spam(f"verify_through_score_invoke commit_state({self.commit_state})")
                else:
                    # verify commit state with leader's(origin_commit_state)
                    # this block must have leader's commit state
                    if origin_commit_state != self.commit_state:
                        logging.warning(f"block:verify_through_score_invoke fail commit state integrity!!")
                        is_verified = False
                    else:
                        util.logger.spam(f"verify_through_score_invoke commit state verified.")

                    # peer have to restore origin_commit_state.
                    # And when receive block confirm message check again origin and peer's commit state.
                    self.commit_state = copy.deepcopy(origin_commit_state)

            except Exception as e:
                # When Grpc Connection Raise Exception
                # save all result{'code': ScoreResponse.SCORE_CONTAINER_EXCEPTION, 'message': str(e)}
                logging.error(f'This error occurred while Score_invoke has failed in verify block : {e}')
                invoke_results = {}

        # util.logger.spam(f'Block::verify_through_score_invoke >>>>> invoke_results :: {invoke_results}')

        need_rebuild = False
        if not util.channel_use_icx(self.__channel_name):
            fail_list = [tx_hash for tx_hash, invoke_result in invoke_results.items()
                         if invoke_result["code"] != message_code.Response.success]

            need_rebuild = len(fail_list) > 0
            if is_leader:
                if need_rebuild:
                    for tx_hash in fail_list:
                        tx = self.find_tx_by_hash(tx_hash)
                        self.confirmed_transaction_list.discard(tx)

                    is_verified = self.confirmed_tx_len > 0
                elif conf.ALLOW_MAKE_EMPTY_BLOCK and not need_rebuild:
                    is_verified = True
            else:
                is_verified = not need_rebuild

        return is_verified, need_rebuild, invoke_results
Пример #4
0
    def __init_peer_auth(self):
        try:
            channel_authorization = IcxAuthorization if util.channel_use_icx(ChannelProperty().name) \
                else PeerAuthorization

            self.__peer_auth = channel_authorization(ChannelProperty().name)

        except Exception as e:
            logging.exception(f"peer auth init fail cause : {e}")
            util.exit_and_msg(f"peer auth init fail cause : {e}")
Пример #5
0
    def score_remove_precommit_state(self, block: Block):
        if not util.channel_use_icx(ChannelProperty().name):
            request = {
                "blockHeight": block.height,
                "blockHash": block.block_hash,
            }
            request = convert_params(request, ParamType.remove_precommit_state)

            stub = StubCollection().icon_score_stubs[ChannelProperty().name]
            stub.sync_task().remove_precommit_state(request)

            return True
        else:
            invoke_fail_info = json.dumps({"block_height": block.height, "block_hash": block.block_hash})
            stub = StubCollection().score_stubs[ChannelProperty().name]
            stub.sync_task().remove_precommit_state(invoke_fail_info)
            return True
Пример #6
0
def start_as_score(args):
    # apply default configure values
    channel = args.channel or conf.LOOPCHAIN_DEFAULT_CHANNEL
    score_package = args.score_package or conf.DEFAULT_SCORE_PACKAGE
    amqp_target = args.amqp_target or conf.AMQP_TARGET
    amqp_key = args.amqp_key or conf.AMQP_KEY

    if util.channel_use_icx(channel) and conf.USE_EXTERNAL_SCORE:
        if conf.EXTERNAL_SCORE_RUN_IN_LAUNCHER:
            from iconservice.icon_service import IconService
            from iconservice.icon_config import default_icon_config
            from iconcommons.icon_config import IconConfig
            from iconcommons.logger import Logger

            additional_conf = {
                "log": {
                    "logger": "iconservice",
                    "colorLog": True,
                    "level": "info",
                    "filePath": f"./log/icon_service_{channel}.log",
                    "outputType": "console|file"
                },
                "scoreRootPath": f".storage/.score{amqp_key}_{channel}",
                "stateDbRootPath": f".storage/.statedb{amqp_key}_{channel}",
                "channel": channel,
                "amqpKey": amqp_key,
                "service": {
                    "fee": True,
                    "audit": True,
                    "deployerWhiteList": False,
                    "scorePackageValidator": False
                }
            }

            icon_conf = IconConfig("", default_icon_config)
            icon_conf.load()
            icon_conf.update(additional_conf)
            Logger.load_config(icon_conf)

            icon_service = IconService()
            icon_service.serve(config=icon_conf)
            Logger.info(f'==========IconService Done==========',
                        'IconServiceStandAlone')
    else:
        ScoreService(channel, score_package, amqp_target, amqp_key).serve()
Пример #7
0
    def score_write_precommit_state(self, block: Block):
        logging.debug(f"call score commit {ChannelProperty().name} {block.height} {block.block_hash}")

        if util.channel_use_icx(ChannelProperty().name):
            request = {
                "blockHeight": block.height,
                "blockHash": block.block_hash,
            }
            request = convert_params(request, ParamType.write_precommit_state)

            stub = StubCollection().icon_score_stubs[ChannelProperty().name]
            stub.sync_task().write_precommit_state(request)
            return True
        else:
            block_commit_info = json.dumps({"block_height": block.height, "block_hash": block.block_hash})
            stub = StubCollection().score_stubs[ChannelProperty().name]
            response = stub.sync_task().write_precommit_state(block_commit_info)

            if response.code == message_code.Response.success:
                return True
            else:
                logging.error(f"score db commit fail cause {response.message}")
                return False
Пример #8
0
def start_as_score(args):
    # apply default configure values
    channel = args.channel or conf.LOOPCHAIN_DEFAULT_CHANNEL
    score_package = args.score_package or conf.DEFAULT_SCORE_PACKAGE
    amqp_target = args.amqp_target or conf.AMQP_TARGET
    amqp_key = args.amqp_key or conf.AMQP_KEY

    if util.channel_use_icx(channel) and conf.USE_EXTERNAL_SCORE:
        if conf.EXTERNAL_SCORE_RUN_IN_LAUNCHER:
            from iconservice.icon_service import IconService
            from iconservice.icon_config import default_icon_config
            from iconcommons.icon_config import IconConfig
            from iconcommons.logger import Logger

            with open(conf.DEFAULT_SCORE_CONF_PATH) as file:
                load_conf = json.load(file)

            additional_conf = {
                "log": load_conf.get("log"),
                "scoreRootPath": f".storage/.score{amqp_key}_{channel}",
                "stateDbRootPath": f".storage/.statedb{amqp_key}_{channel}",
                "channel": channel,
                "amqpKey": amqp_key,
                "builtinScoreOwner": load_conf.get("builtinScoreOwner"),
                "service": load_conf.get("service")
            }

            icon_conf = IconConfig("", default_icon_config)
            icon_conf.load()
            icon_conf.update(additional_conf)
            Logger.load_config(icon_conf)

            icon_service = IconService()
            icon_service.serve(config=icon_conf)
            Logger.info(f'==========IconService Done==========', 'IconServiceStandAlone')
    else:
        ScoreService(channel, score_package, amqp_target, amqp_key).serve()
Пример #9
0
    def score_invoke(self, _block: Block) -> dict or None:
        if util.channel_use_icx(ChannelProperty().name):
            method = "icx_sendTransaction"
            transactions = []
            for tx in _block.confirmed_transaction_list:
                data = tx.icx_origin_data
                transaction = {
                    "method": method,
                    "params": data
                }
                transactions.append(transaction)

            request = {
                'block': {
                    'blockHeight': _block.height,
                    'blockHash': _block.block_hash,
                    'prevBlockHash': _block.prev_block_hash,
                    'timestamp': _block.time_stamp
                },
                'transactions': transactions
            }
            request = convert_params(request, ParamType.invoke)
            stub = StubCollection().icon_score_stubs[ChannelProperty().name]
            response = stub.sync_task().invoke(request)
            response_to_json_query(response)
            _block.commit_state[ChannelProperty().name] = response['stateRootHash']
            return response["txResults"]
        else:
            stub = StubCollection().score_stubs[ChannelProperty().name]
            response = stub.sync_task().score_invoke(_block)

            if response.code == message_code.Response.success:
                commit_state = pickle.loads(response.object)
                _block.commit_state = commit_state
                return json.loads(response.meta)

        return None
Пример #10
0
    def __prevent_next_block_mismatch(
            self, next_block: Block, is_commit_state_validation: bool) -> bool:
        logging.debug(f"prevent_block_mismatch...")
        if util.channel_use_icx(self.__channel_name):
            score_stub = StubCollection().icon_score_stubs[self.__channel_name]
            request = {
                "method": "ise_getStatus",
                "params": {
                    "filter": ["lastBlock"]
                }
            }

            response = score_stub.sync_task().query(request)
            score_last_block_height = int(response['lastBlock']['blockHeight'],
                                          16)

            if score_last_block_height == next_block.height:
                logging.debug(f"already invoked block in score...")
                return False
            elif score_last_block_height < next_block.height:
                for invoke_block_height in range(score_last_block_height + 1,
                                                 next_block.height):
                    logging.debug(
                        f"mismatch invoke_block_height({invoke_block_height}) "
                        f"score_last_block_height({score_last_block_height}) "
                        f"next_block_height({next_block.height})")

                    invoke_block = self.find_block_by_height(
                        invoke_block_height)
                    if invoke_block is None:
                        raise RuntimeError(
                            "Error raised during prevent mismatch block, "
                            f"Cannot find block({invoke_block_height}")

                    invoke_block_result = self.__score_invoke_with_state_integrity(
                        invoke_block, is_commit_state_validation)

                    self.__add_tx_to_block_db(invoke_block,
                                              invoke_block_result)
                    ObjectManager(
                    ).channel_service.score_write_precommit_state(invoke_block)

                return True
            else:
                if score_last_block_height == next_block.height + 1:
                    try:
                        invoke_result_block_height_bytes = \
                            self.__confirmed_block_db.Get(BlockChain.INVOKE_RESULT_BLOCK_HEIGHT_KEY)
                        invoke_result_block_height = int.from_bytes(
                            invoke_result_block_height_bytes, byteorder='big')

                        if invoke_result_block_height == next_block.height:
                            logging.debug(f"already saved invoke result...")
                            return False
                    except KeyError:
                        logging.debug(
                            f"There is no invoke result height in db.")
                else:
                    util.exit_and_msg(
                        "Too many different(over 2) of block height between the loopchain and score. "
                        "Peer will be down. : "
                        f"loopchain({next_block.height})/score({score_last_block_height})"
                    )

                return True