示例#1
0
    def _load_score(context: 'IconScoreContext', score_address: 'Address',
                    builtin_score_owner: 'Address'):
        score: 'IconScoreBase' = IconScoreContextUtil.get_icon_score(
            context, score_address)
        assert score is not None

        if score.owner != builtin_score_owner:
            raise AccessDeniedException(
                f'score.owner({score.owner}) != builtin_score_owner({builtin_score_owner})'
            )
示例#2
0
    def load_builtin_scores(context: 'IconScoreContext',
                            builtin_score_owner: 'Address'):
        for score_name, value in BUILTIN_SCORE_ADDRESS_MAPPER.items():
            score_address = Address.from_string(value)

            # If builtin score has been already deployed, exit.
            if IconScoreContextUtil.is_score_active(context, score_address):
                IconBuiltinScoreLoader._load_score(context, score_address,
                                                   builtin_score_owner)
            else:
                IconBuiltinScoreLoader._deploy_score(context, score_name,
                                                     score_address,
                                                     builtin_score_owner)
示例#3
0
    def _deploy_score(context: 'IconScoreContext', score_name: str,
                      score_address: 'Address',
                      builtin_score_owner: 'Address'):

        score_source_path_in_iconservice: str = os.path.join(
            IconBuiltinScoreLoader._pre_builtin_score_root_path(), score_name)

        # Save deploy_info for a builtin score to storage.
        deploy_info = IconScoreDeployInfo(score_address=score_address,
                                          deploy_state=DeployState.ACTIVE,
                                          owner=builtin_score_owner,
                                          current_tx_hash=ZERO_TX_HASH,
                                          next_tx_hash=ZERO_TX_HASH)
        context.storage.deploy.put_deploy_info(context, deploy_info)

        tx_hash: bytes = deploy_info.current_tx_hash

        # score_path is score_root_path/score_address/ directory.
        score_path: str = os.path.join(context.score_root_path,
                                       score_address.to_bytes().hex())

        # Make a directory for a builtin score with a given score_address.
        os.makedirs(score_path, exist_ok=True)

        try:
            score_deploy_path: str = os.path.join(score_path,
                                                  f'0x{tx_hash.hex()}')

            # remove_path() supports directory as well as file.
            remove_path(score_deploy_path)
            # Copy builtin score source files from iconservice package to score_deploy_path.
            copytree(score_source_path_in_iconservice, score_deploy_path)
        except FileExistsError:
            pass

        try:
            # Import score class from deployed builtin score sources
            score_info: 'IconScoreInfo' =\
                IconScoreContextUtil.create_score_info(context, score_address, tx_hash)

            # Create a score instance from the imported score class.
            score = score_info.create_score()

            # Call on_install() to initialize the score database of the builtin score.
            score.on_install()
        except BaseException as e:
            Logger.exception(
                f'Failed to deploy a builtin score: {score_address}\n{str(e)}',
                ICON_DEPLOY_LOG_TAG)
            raise e
示例#4
0
    def test_score_invoke_with_revert(self):

        table = {ConfigKey.SERVICE_FEE: True,
                 ConfigKey.SERVICE_AUDIT: False,
                 ConfigKey.SERVICE_DEPLOYER_WHITE_LIST: False,
                 ConfigKey.SERVICE_SCORE_PACKAGE_VALIDATOR: False}
        # TODO: must apply the service flags to the engine
        # self._engine._flag = self._engine._make_service_flag(table)

        block_height = 1
        block_hash = create_block_hash(b'block')
        block_timestamp = 0
        tx_hash = create_tx_hash()
        value = 1 * 10 ** 18

        self._to = create_address(AddressPrefix.CONTRACT)

        tx_v3 = {
            'method': 'icx_sendTransaction',
            'params': {
                'version': 3,
                'from': self._genesis_address,
                'to': self._to,
                'value': value,
                'stepLimit': 20000,
                'timestamp': 1234567890,
                'txHash': tx_hash
            }
        }

        block = Block(block_height,
                      block_hash,
                      block_timestamp,
                      self.genesis_block.hash,
                      0)

        context = _create_context(IconScoreContextType.QUERY)
        before_from_balance: int = \
            IconScoreContext.engine.icx.get_balance(context, self.from_)

        self._engine._handle_score_invoke = \
            Mock(return_value=None, side_effect=IconScoreException("force revert"))

        raise_exception_start_tag("test_score_invoke_with_revert")
        tx_results, state_root_hash, _, _ = self._engine.invoke(block, [tx_v3])
        raise_exception_end_tag("test_score_invoke_with_revert")
        self.assertIsInstance(state_root_hash, bytes)
        self.assertEqual(len(state_root_hash), 32)

        self.assertEqual(len(tx_results), 1)

        tx_result: 'TransactionResult' = tx_results[0]
        self.assertIsNotNone(tx_result.failure)
        self.assertIsNone(tx_result.score_address)
        self.assertEqual(tx_result.status, 0)
        self.assertEqual(tx_result.block_height, block_height)
        self.assertEqual(tx_result.block_hash, block_hash)
        self.assertEqual(tx_result.tx_index, 0)
        self.assertEqual(tx_result.tx_hash, tx_hash)

        # step_used MUST BE 10**6 on protocol v2
        step_unit = self._engine._step_counter_factory.get_step_cost(
            StepType.DEFAULT)

        self.assertEqual(tx_result.step_used, step_unit)

        step_price = self._engine._step_counter_factory.get_step_price()
        if IconScoreContextUtil._is_flag_on(IconScoreContext.icon_service_flag, IconServiceFlag.FEE):
            # step_price MUST BE 10**10 on protocol v2
            self.assertEqual(
                step_price, self._engine._step_counter_factory.get_step_price())
        else:
            self.assertEqual(step_price, 0)
        self.assertEqual(tx_result.step_price, step_price)

        self._engine.commit(block.height, block.hash, None)

        # Check whether fee charging works well
        context = _create_context(IconScoreContextType.QUERY)
        after_from_balance: int = \
            IconScoreContext.engine.icx.get_balance(context, self.from_)

        fee = tx_result.step_price * tx_result.step_used
        self.assertEqual(after_from_balance, before_from_balance - fee)
示例#5
0
    def test_invoke_v3_with_fee(self):

        table = {ConfigKey.SERVICE_FEE: True,
                 ConfigKey.SERVICE_AUDIT: False,
                 ConfigKey.SERVICE_DEPLOYER_WHITE_LIST: False,
                 ConfigKey.SERVICE_SCORE_PACKAGE_VALIDATOR: False}
        # TODO: must apply the service flags to the engine
        # self._engine._flag = self._engine._make_service_flag(table)

        block_height = 1
        block_hash = create_block_hash()
        block_timestamp = 0
        tx_hash = create_tx_hash()
        value = 1 * 10 ** 18
        step_limit = 1000000

        tx_v3 = {
            'method': 'icx_sendTransaction',
            'params': {
                'nid': 3,
                'version': 3,
                'from': self._genesis_address,
                'to': self._to,
                'value': value,
                'stepLimit': step_limit,
                'timestamp': 1234567890,
                'txHash': tx_hash
            }
        }

        block = Block(block_height,
                      block_hash,
                      block_timestamp,
                      self.genesis_block.hash,
                      0)

        context = _create_context(IconScoreContextType.DIRECT)
        before_from_balance: int = \
            IconScoreContext.engine.icx.get_balance(context, self.from_)

        tx_results, state_root_hash, _, _ = self._engine.invoke(block, [tx_v3])
        self.assertIsInstance(state_root_hash, bytes)
        self.assertEqual(len(state_root_hash), 32)

        self.assertEqual(len(tx_results), 1)

        tx_result: 'TransactionResult' = tx_results[0]
        self.assertIsNone(tx_result.failure)
        self.assertIsNone(tx_result.score_address)
        self.assertEqual(tx_result.status, 1)
        self.assertEqual(tx_result.block_height, block_height)
        self.assertEqual(tx_result.block_hash, block_hash)
        self.assertEqual(tx_result.tx_index, 0)
        self.assertEqual(tx_result.tx_hash, tx_hash)

        # step_used MUST BE 10**6 on protocol v2
        step_cost = self._engine._step_counter_factory.get_step_cost(
            StepType.DEFAULT)

        self.assertEqual(tx_result.step_used, step_cost)

        step_price = self._engine._step_counter_factory.get_step_price()
        if IconScoreContextUtil._is_flag_on(IconScoreContext.icon_service_flag, IconServiceFlag.FEE):
            # step_price MUST BE 10**10 on protocol v2
            self.assertEqual(
                step_price, self._engine._step_counter_factory.get_step_price())
        else:
            self.assertEqual(step_price, 0)
        self.assertEqual(tx_result.step_price, step_price)

        self._engine.commit(block.height, block.hash, None)

        # Check whether fee charging works well
        after_from_balance: int = \
            IconScoreContext.engine.icx.get_balance(context, self.from_)
        fee = tx_result.step_price * tx_result.step_used
        value = value if tx_result.status == TransactionResult.SUCCESS else 0
        self.assertEqual(after_from_balance, before_from_balance - value - fee)
示例#6
0
    def test_invoke_v3_without_fee(self):
        block_height = 1
        block_hash = create_block_hash()
        block_timestamp = 0
        tx_hash = create_tx_hash()
        value = 1 * 10 ** 18

        tx_v3 = {
            'method': 'icx_sendTransaction',
            'params': {
                'nid': 3,
                'version': 3,
                'from': self._genesis_address,
                'to': self._to,
                'value': value,
                'stepLimit': 1000000,
                'timestamp': 1234567890,
                'txHash': tx_hash
            }
        }

        block = Block(block_height,
                      block_hash,
                      block_timestamp,
                      self.genesis_block.hash,
                      0)

        tx_results, state_root_hash, _, _ = self._engine.invoke(block, [tx_v3])
        self.assertIsInstance(state_root_hash, bytes)
        self.assertEqual(len(state_root_hash), 32)

        self.assertEqual(len(tx_results), 1)

        tx_result: 'TransactionResult' = tx_results[0]
        self.assertIsNone(tx_result.failure)
        self.assertIsNone(tx_result.score_address)
        self.assertEqual(tx_result.status, 1)
        self.assertEqual(tx_result.block_height, block_height)
        self.assertEqual(tx_result.block_hash, block_hash)
        self.assertEqual(tx_result.tx_index, 0)
        self.assertEqual(tx_result.tx_hash, tx_hash)

        # step_used MUST BE 10**6 on protocol v2
        step_unit = self._engine._step_counter_factory.get_step_cost(
            StepType.DEFAULT)

        self.assertEqual(tx_result.step_used, step_unit)

        step_price = self._engine._step_counter_factory.get_step_price()
        if IconScoreContextUtil._is_flag_on(IconScoreContext.icon_service_flag, IconServiceFlag.FEE):
            # step_used MUST BE 10**10 on protocol v2
            self.assertEqual(step_price, 10 ** 10)
        else:
            self.assertEqual(step_price, 0)
        self.assertEqual(tx_result.step_price, step_price)

        self._engine.commit(block.height, block.hash, None)

        # Check whether fee charging works well
        context = _create_context(IconScoreContextType.DIRECT)
        from_balance: int = \
            IconScoreContext.engine.icx.get_balance(context, self.from_)
        fee = tx_result.step_price * tx_result.step_used
        self.assertEqual(fee, 0)
        self.assertEqual(from_balance, self._total_supply - value - fee)
示例#7
0
    def test_invoke(self):
        block_height = 1
        block_hash = create_block_hash()
        block_timestamp = 0
        tx_hash = create_tx_hash()
        value = 1 * 10 ** 18

        step_limit = 200000000000000
        tx_v3 = {
            'method': 'icx_sendTransaction',
            'params': {
                'version': 3,
                'from': self._genesis_address,
                'to': self._to,
                'value': value,
                'stepLimit': step_limit,
                'timestamp': 1234567890,
                'txHash': tx_hash
            }
        }

        block = Block(block_height,
                      block_hash,
                      block_timestamp,
                      self.genesis_block.hash,
                      0)

        original_invoke_request = self._engine._invoke_request

        # noinspection PyUnusedLocal
        def intercept_invoke_req(*args, **kwargs):
            context: 'IconScoreContext' = args[0]
            request: dict = args[1]
            index: int = args[2]
            ret = original_invoke_request(context, request, index)

            # Requesting the very big number of step limit,
            # but there's a max step limit,
            # asserts max step limit is applied to step counting.
            self.assertNotEqual(step_limit, context.step_counter.step_limit)
            self.assertEqual(
                self._engine._step_counter_factory.get_max_step_limit(
                    context.type),
                context.step_counter.step_limit)
            return ret

        self._engine._invoke_request = Mock(side_effect=intercept_invoke_req)
        tx_results, state_root_hash, _, _ = self._engine.invoke(block, [tx_v3])
        self.assertIsInstance(state_root_hash, bytes)
        self.assertEqual(len(state_root_hash), 32)

        self.assertEqual(len(tx_results), 1)

        tx_result: 'TransactionResult' = tx_results[0]
        self.assertIsNone(tx_result.failure)
        self.assertIsNone(tx_result.score_address)
        self.assertEqual(tx_result.status, 1)
        self.assertEqual(tx_result.block_height, block_height)
        self.assertEqual(tx_result.block_hash, block_hash)
        self.assertEqual(tx_result.tx_index, 0)
        self.assertEqual(tx_result.tx_hash, tx_hash)

        # step_used MUST BE 10**6 on protocol v2
        step_unit = self._engine._step_counter_factory.get_step_cost(
            StepType.DEFAULT)

        self.assertEqual(tx_result.step_used, step_unit)

        step_price = self._engine._step_counter_factory.get_step_price()

        if IconScoreContextUtil._is_flag_on(IconScoreContext.icon_service_flag, IconServiceFlag.FEE):
            # step_price MUST BE 10**10 on protocol v2
            self.assertEqual(step_price, 10 ** 10)
        else:
            self.assertEqual(step_price, 0)
        self.assertEqual(tx_result.step_price, step_price)

        self._engine.commit(block.height, block_hash, None)

        # Check whether fee charging works well
        context = _create_context(IconScoreContextType.DIRECT)
        from_balance: int = \
            IconScoreContext.engine.icx.get_balance(context, self.from_)
        fee = tx_result.step_price * tx_result.step_used
        self.assertEqual(fee, 0)
        self.assertEqual(from_balance, self._total_supply - value - fee)