Example #1
0
    async def _on_send(self, writer: 'StreamWriter'):
        Logger.info(tag=_TAG, msg="_on_send() start")

        while self._running:
            try:
                request: 'Request' = await self._queue.get()
                self._queue.task_done()

                if request.msg_type == MessageType.NONE:
                    # Stopping IPCServer
                    break

                data: bytes = request.to_bytes()
                Logger.debug(tag=_TAG, msg=f"on_send(): data({data.hex()}")
                Logger.info(tag=_TAG, msg=f"Sending Data : {request}")
                writer.write(data)
                await writer.drain()

            except asyncio.CancelledError:
                pass
            except BaseException as e:
                Logger.warning(tag=_TAG, msg=str(e))

        writer.close()

        Logger.info(tag=_TAG, msg="_on_send() end")
Example #2
0
    def invoke(self, context: 'IconScoreContext', to: 'Address',
               icon_score_address: 'Address', data: dict) -> None:
        """Handle data contained in icx_sendTransaction message
        :param context:
        :param to:
        :param icon_score_address:
            cx0000000000000000000000000000000000000000 on install
            otherwise score address to update
        :param data: SCORE deploy data
        """
        assert icon_score_address is not None
        assert icon_score_address != ZERO_SCORE_ADDRESS
        assert icon_score_address.is_contract

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

        try:
            IconScoreContextUtil.validate_deployer(context, context.tx.origin)

            deploy_type: 'DeployType' = \
                DeployType.INSTALL if to == ZERO_SCORE_ADDRESS else DeployType.UPDATE

            context.storage.deploy.put_deploy_info_and_tx_params(
                context, icon_score_address, deploy_type, context.tx.origin,
                context.tx.hash, data)

            if not self._is_audit_needed(context, icon_score_address):
                self.deploy(context, context.tx.hash)

        except BaseException as e:
            Logger.warning('Failed to write deploy info and tx params',
                           ICON_DEPLOY_LOG_TAG)
            raise e
Example #3
0
    def _invoke(self, context: "IconScoreContext", to: "Address",
                icon_score_address: "Address", data: dict) -> None:
        assert icon_score_address is not None
        assert icon_score_address != SYSTEM_SCORE_ADDRESS
        assert icon_score_address.is_contract

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

        try:
            deploy_type: 'DeployType' = \
                DeployType.INSTALL if to == SYSTEM_SCORE_ADDRESS else DeployType.UPDATE

            context.storage.deploy.put_deploy_info_and_tx_params(
                context, icon_score_address, deploy_type, context.tx.origin,
                context.tx.hash, data)

            if not self._is_audit_needed(context, icon_score_address):
                self.deploy(context, context.tx.hash)

        except BaseException as e:
            Logger.warning('Failed to write deploy info and tx params',
                           ICON_DEPLOY_LOG_TAG)
            raise e
Example #4
0
    def _on_deploy(self, context: 'IconScoreContext',
                   tx_params: 'IconScoreDeployTXParams') -> None:
        """
        Decompress a SCORE zip file and write them to file system
        Create a SCORE instance from SCORE class
        Call a SCORE initialization function (on_install or on_update)
        :param tx_params: use deploy_data, score_address, tx_hash, deploy_type from IconScoreDeployTxParams
        :return:
        """

        data = tx_params.deploy_data
        score_address = tx_params.score_address
        params: dict = data.get('params', {})

        deploy_info: 'IconScoreDeployInfo' = context.storage.deploy.get_deploy_info(
            context, tx_params.score_address)
        next_tx_hash: bytes = deploy_info.next_tx_hash

        self._write_score_to_filesystem(context, score_address, next_tx_hash,
                                        data)

        backup_msg = context.msg
        backup_tx = context.tx
        new_tx_score_mapper: dict = {}

        try:
            IconScoreContextUtil.validate_score_package(
                context, score_address, next_tx_hash)

            score_info: 'IconScoreInfo' =\
                self._create_score_info(context, score_address, next_tx_hash)

            if context.revision >= Revision.STRICT_SCORE_DECORATOR_CHECK.value:
                check_score_flag(score_info.score_class)

            # score_info.get_score() returns a cached or created score instance
            # according to context.revision.
            score: 'IconScoreBase' = score_info.get_score(context.revision)

            # check_on_deploy will be done by normalize_signature()
            # since Revision.THREE
            if context.revision < Revision.THREE.value:
                ScoreApiGenerator.check_on_deploy(context, score)

            # owner is set in IconScoreBase.__init__()
            context.msg = Message(sender=score.owner)
            context.tx = None

            self._initialize_score(context, tx_params.deploy_type, score,
                                   params)
            new_tx_score_mapper[score_address] = score_info
        except BaseException as e:
            Logger.warning(f'Failed to deploy a SCORE: {score_address}',
                           ICON_DEPLOY_LOG_TAG)
            raise e
        finally:
            context.msg = backup_msg
            context.tx = backup_tx
            self._update_new_score_mapper(context.new_icon_score_mapper,
                                          new_tx_score_mapper)
    def _remove_score_dir(cls, address: 'Address', converted_tx_hash: Optional[str] = None):
        if cls.icon_score_loader is None:
            return
        score_root_path = cls.icon_score_loader.score_root_path

        if converted_tx_hash is None:
            target_path = os.path.join(score_root_path, bytes.hex(address.to_bytes()))
        else:
            target_path = os.path.join(score_root_path, bytes.hex(address.to_bytes()), converted_tx_hash)

        try:
            rmtree(target_path)
        except Exception as e:
            Logger.warning(e)
    def commit(self, block: 'Block'):
        node = self._precommit_data_mapper.get(block.hash)
        if node is None:
            Logger.warning(
                tag=_TAG,
                msg=
                f"No precommit data: height={block.height} hash={bytes_to_hex(block.hash)}"
            )
            return

        if not node.parent.is_root() and self._root == node.parent:
            raise InternalServiceErrorException(f"Parent should be a root")

        self._remove_sibling_precommit_data(block)
        del self._precommit_data_mapper[self._root.block.hash]
        self._set_root(node)
    def _on_deploy_for_builtin(self, context: 'IconScoreContext',
                               score_address: 'Address',
                               src_score_path: str) -> None:
        """Install an icon score for builtin
        """

        score_root_path = context.icon_score_mapper.score_root_path
        target_path = path.join(score_root_path,
                                score_address.to_bytes().hex())
        makedirs(target_path, exist_ok=True)

        deploy_info = self._icon_score_deploy_storage.get_deploy_info(
            context, score_address)
        if deploy_info is None:
            next_tx_hash = None
        else:
            next_tx_hash = deploy_info.next_tx_hash
        if next_tx_hash is None:
            next_tx_hash = bytes(DEFAULT_BYTE_SIZE)

        converted_tx_hash: str = f'0x{bytes.hex(next_tx_hash)}'
        target_path = path.join(target_path, converted_tx_hash)

        try:
            copytree(src_score_path, target_path)
        except FileExistsError:
            pass

        try:
            score = context.icon_score_mapper.load_score(
                score_address, next_tx_hash)
            if score is None:
                raise InvalidParamsException(
                    f'score is None : {score_address}')

            self._initialize_score(on_deploy=score.on_install, params={})
        except BaseException as e:
            Logger.warning(
                f'load wait icon score fail!! address: {score_address}',
                ICON_DEPLOY_LOG_TAG)
            Logger.warning('revert to add wait icon score',
                           ICON_DEPLOY_LOG_TAG)
            raise e

        context.icon_score_mapper.put_score_info(score_address, score,
                                                 next_tx_hash)
Example #8
0
    async def _on_recv(self, reader: 'StreamReader'):
        Logger.info(tag=_TAG, msg="_on_recv() start")

        while self._running:
            try:
                data: bytes = await reader.read(1024)
                if not isinstance(data, bytes) or len(data) == 0:
                    break

                Logger.debug(tag=_TAG, msg=f"_on_recv(): data({data.hex()})")

                self._unpacker.feed(data)

                for response in self._unpacker:
                    Logger.info(tag=_TAG, msg=f"Received Data : {response}")
                    self._queue.message_handler(response)

            except asyncio.CancelledError:
                pass
            except BaseException as e:
                Logger.warning(tag=_TAG, msg=str(e))

        Logger.info(tag=_TAG, msg="_on_recv() end")
Example #9
0
    def invoke(self, context: 'IconScoreContext', to: 'Address',
               icon_score_address: 'Address', data: dict) -> None:
        """Handle calldata contained in icx_sendTransaction message

        :param context:
        :param to:
        :param icon_score_address:
            cx0000000000000000000000000000000000000000 on install
            otherwise score address to update
        :param data: calldata
        """
        assert icon_score_address is not None
        assert icon_score_address != ZERO_SCORE_ADDRESS
        assert icon_score_address.is_contract

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

        deploy_type: 'DeployType' = \
            DeployType.INSTALL if to == ZERO_SCORE_ADDRESS else DeployType.UPDATE

        try:
            context.validate_score_blacklist(icon_score_address)

            if self._is_flag_on(IconDeployFlag.ENABLE_DEPLOY_WHITELIST):
                context.validate_deployer(context.tx.origin)

            self.write_deploy_info_and_tx_params(context, deploy_type,
                                                 icon_score_address, data)

            if self._check_audit_ignore(context, icon_score_address):
                self.deploy(context, context.tx.hash)
        except BaseException as e:
            Logger.warning('Failed to write deploy info and tx params',
                           ICON_DEPLOY_LOG_TAG)
            raise e
Example #10
0
    def _on_deploy(self, context: 'IconScoreContext',
                   tx_params: 'IconScoreDeployTXParams') -> None:
        """
        load score on memory
        write file system
        call on_deploy(install, update)

        :param tx_params: use deploy_data, score_address, tx_hash, deploy_type from IconScoreDeployTxParams
        :return:
        """

        data = tx_params.deploy_data
        score_address = tx_params.score_address
        content_type: str = data.get('contentType')
        content: bytes = data.get('content')
        params: dict = data.get('params', {})

        _, next_tx_hash =\
            self._icon_score_deploy_storage.get_tx_hashes_by_score_address(context, tx_params.score_address)

        if next_tx_hash is None:
            next_tx_hash = bytes(DEFAULT_BYTE_SIZE)

        if content_type == 'application/tbears':
            score_root_path = context.icon_score_mapper.score_root_path
            target_path = path.join(score_root_path,
                                    score_address.to_bytes().hex())
            makedirs(target_path, exist_ok=True)
            converted_tx_hash: str = f'0x{bytes.hex(next_tx_hash)}'
            target_path = path.join(target_path, converted_tx_hash)
            try:
                symlink(content, target_path, target_is_directory=True)
            except FileExistsError:
                pass
        else:
            self._icon_score_deployer.deploy(address=score_address,
                                             data=content,
                                             tx_hash=next_tx_hash)

        backup_msg = context.msg
        backup_tx = context.tx

        try:
            score = context.new_icon_score_mapper.load_score(
                score_address, next_tx_hash)
            if score is None:
                raise InvalidParamsException(
                    f'score is None : {score_address}')

            deploy_type = tx_params.deploy_type
            if deploy_type == DeployType.INSTALL:
                on_deploy = score.on_install
            elif deploy_type == DeployType.UPDATE:
                on_deploy = score.on_update
            else:
                on_deploy = None

            context.msg = Message(sender=score.owner)
            context.tx = None

            self._initialize_score(on_deploy=on_deploy, params=params)
        except BaseException as e:
            Logger.warning(
                f'load wait icon score fail!! address: {score_address}',
                ICON_DEPLOY_LOG_TAG)
            Logger.warning('revert to add wait icon score',
                           ICON_DEPLOY_LOG_TAG)
            raise e
        finally:
            context.msg = backup_msg
            context.tx = backup_tx

        context.icon_score_mapper.put_score_info(score_address, score,
                                                 next_tx_hash)
 def test_warning(self):
     Logger.warning(TAG, 'warning log')