def test_get_score_api(self, mocked_icon_score_engine_validate_score_blacklist, mocked_score_context_util_get_icon_score): context = IconScoreContext(IconScoreContextType.INVOKE) context.new_icon_score_mapper = IconScoreMapper() # failure case: should raise error if there is no SCORE score_address = create_address(AddressPrefix.CONTRACT) mocked_score_context_util_get_icon_score.return_value = None self.assertRaises(ScoreNotFoundException, IconScoreEngine.get_score_api, context, score_address) mocked_icon_score_engine_validate_score_blacklist.assert_called_with( context, score_address) # reset mock mocked_icon_score_engine_validate_score_blacklist.reset_mock( return_value=None) # success case: if SCORE exists, getattr(score, "__get_api") method should be called score_object = Mock(spec=IconScoreBase) mocked_score_context_util_get_icon_score.return_value = score_object IconScoreEngine.get_score_api(context, score_address) mocked_icon_score_engine_validate_score_blacklist.assert_called_with( context, score_address) get_api = getattr(score_object, ATTR_SCORE_GET_API) get_api.assert_called()
def make_and_req_block_for_2_depth_invocation( self, tx_list: list, prev_block: 'Block', prev_block_generator: Optional['Address'] = None, prev_block_validators: Optional[List['Address']] = None, prev_block_votes: Optional[List[Tuple['Address', int]]] = None, ) -> Tuple['Block', List[bytes]]: block_height: int = prev_block.height + 1 block_hash = create_block_hash() timestamp_us = create_timestamp() block = Block(block_height, block_hash, timestamp_us, prev_block.hash, 0) context = IconScoreContext(IconScoreContextType.DIRECT) is_block_editable = False if context.is_decentralized(): is_block_editable = True tx_results, state_root_hash, added_transactions, next_preps = \ self.icon_service_engine.invoke(block=block, tx_requests=tx_list, prev_block_generator=prev_block_generator, prev_block_validators=prev_block_validators, prev_block_votes=prev_block_votes, is_block_editable=is_block_editable) self.add_tx_result(tx_results) return block, self.get_hash_list_from_tx_list(tx_list)
def debug_make_and_req_block(self, tx_list: list, prev_block_generator: Optional['Address'] = None, prev_block_validators: Optional[List['Address']] = None, prev_block_votes: Optional[List[Tuple['Address', int]]] = None, block: 'Block' = None) -> tuple: # Prevent a base transaction from being added to the original tx_list tx_list = copy.copy(tx_list) if block is None: block_height: int = self._block_height + 1 block_hash = create_block_hash() timestamp_us = create_timestamp() block = Block(block_height, block_hash, timestamp_us, self._prev_block_hash, 0) context = IconScoreContext(IconScoreContextType.DIRECT) is_block_editable = False self.icon_service_engine._set_revision_to_context(context) if context.is_decentralized(): is_block_editable = True tx_results, state_root_hash, added_transactions, main_prep_as_dict = \ self.icon_service_engine.invoke(block=block, tx_requests=tx_list, prev_block_generator=prev_block_generator, prev_block_validators=prev_block_validators, prev_block_votes=prev_block_votes, is_block_editable=is_block_editable) return block, tx_results, state_root_hash, added_transactions, main_prep_as_dict
def make_and_req_block(self, tx_list: list, block_height: int = None, prev_block_generator: Optional['Address'] = None, prev_block_validators: Optional[List['Address']] = None, prev_block_votes: Optional[List[Tuple['Address', int]]] = None, block_hash: bytes = None) \ -> Tuple['Block', List[bytes]]: if block_height is None: block_height: int = self._block_height + 1 if block_hash is None: block_hash = create_block_hash() timestamp_us = create_timestamp() block = Block(block_height, block_hash, timestamp_us, self._prev_block_hash, 0) context = IconScoreContext(IconScoreContextType.DIRECT) is_block_editable = False self.icon_service_engine._set_revision_to_context(context) if context.is_decentralized(): is_block_editable = True tx_results, state_root_hash, added_transactions, main_prep_as_dict = \ self.icon_service_engine.invoke(block=block, tx_requests=tx_list, prev_block_generator=prev_block_generator, prev_block_validators=prev_block_validators, prev_block_votes=prev_block_votes, is_block_editable=is_block_editable) self.add_tx_result(tx_results) return block, self.get_hash_list_from_tx_list(tx_list)
def context(): ctx = IconScoreContext(IconScoreContextType.DIRECT) block = Block(0, None, 0, None, 0) ctx.block = block ContextContainer._push_context(ctx) yield ctx ContextContainer._pop_context()
def setUp(self): empty_address = MalformedAddress.from_string('') short_address_without_hx = MalformedAddress.from_string('12341234') short_address = MalformedAddress.from_string('hx1234512345') long_address_without_hx = MalformedAddress.from_string( 'cf85fac2d0b507a2db9ce9526e6d01476f16a2d269f51636f9c4b2d512017faf') long_address = MalformedAddress.from_string( 'hxcf85fac2d0b507a2db9ce9526e6d01476f16a2d269f51636f9c4b2d512017faf' ) self.addresses = [ empty_address, short_address_without_hx, short_address, long_address_without_hx, long_address ] self.db_name = 'icx.db' db = ContextDatabase.from_path(self.db_name) self.assertIsNotNone(db) self.storage = IcxStorage(db) context = IconScoreContext(IconScoreContextType.DIRECT) mock_block: 'Mock' = Mock(spec=Block) mock_block.attach_mock(Mock(return_value=0), 'height') context.block = mock_block self.context = context
def context(score_db): context = IconScoreContext(IconScoreContextType.DIRECT) context.current_address = score_db.address ContextContainer._push_context(context) yield context ContextContainer._clear_context()
def test_call(self, mocked_score_engine_get_icon_score, mocked_score_engine_convert_score_params_by_annotations): context = IconScoreContext(IconScoreContextType.INVOKE) context.new_icon_score_mapper = IconScoreMapper() def intercept_score_base_call(func_name: str, kw_params: dict): self.assertEqual(func_name, 'score_method') # should be equal to converted_params self.assertEqual(kw_params, converted_params) return "__call method called" score_address = Mock(spec=Address) score_object = Mock(spec=IconScoreBase) mocked_score_engine_get_icon_score.return_value = score_object primitive_params = {"address": str(create_address(AddressPrefix.EOA)), "integer": "0x10"} converted_params = {"address": create_address(AddressPrefix.EOA), "integer": 10} mocked_score_engine_convert_score_params_by_annotations.return_value = converted_params context.set_func_type_by_icon_score = Mock() setattr(score_object, ATTR_SCORE_CALL, Mock(side_effect=intercept_score_base_call)) # set method, and params, method cannot be None as pre-validate it data = {'method': 'score_method', 'params': primitive_params} result = IconScoreEngine._call(context, score_address, data) self.assertEqual(result, "__call method called") IconScoreEngine._get_icon_score.assert_called() IconScoreEngine._convert_score_params_by_annotations.assert_called() context.set_func_type_by_icon_score.assert_called() call = getattr(score_object, ATTR_SCORE_CALL) call.assert_called()
def context(): context = IconScoreContext(IconScoreContextType.DIRECT) context.tx_batch = TransactionBatch() context.block_batch = BlockBatch() ContextContainer._push_context(context) yield context ContextContainer._pop_context()
def _create_context(context_type: IconScoreContextType) -> IconScoreContext: context = IconScoreContext(context_type) if context.type == IconScoreContextType.INVOKE: context.block_batch = BlockBatch() context.tx_batch = TransactionBatch() return context
def setUp(self): address = Address.from_data(AddressPrefix.CONTRACT, os.urandom(20)) db = Mock(spec=IconScoreDatabase) db.attach_mock(address, 'address') context = IconScoreContext() traces = Mock(spec=list) step_counter = Mock(spec=IconScoreStepCounter) IconScoreContext.engine = ContextEngine(icx=Mock(IcxEngine), deploy=Mock(DeployEngine), fee=None, iiss=None, prep=None, issue=None) IconScoreContext.storage = ContextStorage(icx=Mock(IcxStorage), deploy=Mock(DeployStorage), fee=None, iiss=None, prep=None, issue=None, rc=None, meta=None) IconScoreContext.icx_engine = Mock(spec=IcxEngine) context.type = IconScoreContextType.INVOKE context.func_type = IconScoreFuncType.WRITABLE context.tx_batch = TransactionBatch() context.event_logs = [] context.traces = traces context.step_counter = step_counter context.get_owner = Mock() ContextContainer._push_context(context) self._mock_score = EventlogScore(db)
def _create_base_transaction(self): context = IconScoreContext(IconScoreContextType.DIRECT) context._preps = context.engine.prep.preps.copy(mutable=True) context._term = context.engine.prep.term.copy() block_height: int = self._block_height block_hash = create_block_hash() timestamp_us = create_timestamp() block = Block(block_height, block_hash, timestamp_us, self._prev_block_hash, 0) context.block = block transaction = BaseTransactionCreator.create_base_transaction(context) return transaction
def _create_context(context_type: IconScoreContextType) -> IconScoreContext: context = IconScoreContext(context_type) if context.type == IconScoreContextType.INVOKE: context.block_batch = BlockBatch() context.tx_batch = TransactionBatch() mock_block: 'Mock' = Mock(spec=Block) mock_block.attach_mock(Mock(return_value=0), 'height') context.block = mock_block return context
def _create_context(self): context = IconScoreContext(IconScoreContextType.INVOKE) step_counter_factory = self._create_step_counter_factory() step_counter = step_counter_factory.create(context.type) step_counter.reset(self.step_limit) context.step_counter = step_counter context.revision = REVISION_3 return context
def test_create_and_destroy(self): for _ in range(3): context = IconScoreContext(IconScoreContextType.QUERY) self.assertTrue(isinstance(context, IconScoreContext)) self.assertTrue(context.readonly) context = IconScoreContext(IconScoreContextType.INVOKE) self.assertEqual(IconScoreContextType.INVOKE, context.type) context = IconScoreContext(IconScoreContextType.DIRECT) self.assertEqual(IconScoreContextType.DIRECT, context.type)
def _check_calculation_block(self, block: "Block") -> bool: """check calculation block""" context = IconScoreContext(IconScoreContextType.DIRECT) revision = self._engine._get_revision_from_rc(context) context.block = block if revision < Revision.IISS.value: return False start_block = context.engine.iiss.get_start_block_of_calc(context) return start_block == block.height
def setUp(self): self.db_name = 'fee.db' self.address = create_address(AddressPrefix.EOA) db = ContextDatabase.from_path(self.db_name) self.assertIsNotNone(db) self.storage = FeeStorage(db) context = IconScoreContext(IconScoreContextType.DIRECT) context.tx_batch = TransactionBatch() context.block_batch = BlockBatch() self.context = context
def test_install(self): # mock context context = IconScoreContext(IconScoreContextType.INVOKE) IconScoreContextFactory._create_context = mock.Mock( return_value=context) # 1. deploy (wait audit) prev_block, tx_results = self._deploy_score() tx_hash1: bytes = tx_results[0].tx_hash self.assertEqual(True, context.step_trace_flag) steps = context.step_counter.step_tracer.steps self.assertEqual(StepType.DEFAULT, steps[0][0]) self.assertEqual(StepType.INPUT, steps[1][0]) self.assertEqual(StepType.CONTRACT_CREATE, steps[2][0]) self.assertEqual(StepType.CONTRACT_SET, steps[3][0]) self._write_precommit_state(prev_block) # mock context context = IconScoreContext(IconScoreContextType.INVOKE) IconScoreContextFactory._create_context = mock.Mock( return_value=context) # 2. accpt SCORE : tx_hash1 tx_results: List['TransactionResult'] = self.accept_score(tx_hash1) tx_hash2 = tx_results[0].tx_hash steps = context.step_counter.step_tracer.steps index = 0 self.assertEqual(StepType.DEFAULT, steps[index][0]) index += 1 self.assertEqual(StepType.INPUT, steps[index][0]) index += 1 self.assertEqual(StepType.CONTRACT_CALL, steps[index][0]) index += 1 for i in range(10): self.assertEqual(StepType.GET, steps[index][0]) index += 1 for i in range(3): self.assertEqual(StepType.SET, steps[index][0]) index += 1 self.assertEqual(StepType.EVENT_LOG, steps[index][0]) index += 1 for i in range(28): self.assertEqual(StepType.GET, steps[index][0]) index += 1
def setUp(self): self.db_name = 'icx.db' db = ContextDatabase.from_path(self.db_name) self.assertIsNotNone(db) self.storage = IcxStorage(db) context = IconScoreContext(IconScoreContextType.DIRECT) context.tx_batch = TransactionBatch() mock_block: 'Mock' = Mock(spec=Block) mock_block.attach_mock(Mock(return_value=0), 'height') context.block = mock_block context.block_batch = BlockBatch() self.context = context
def test_service_configuration_audit_setting(self): self.config.update_conf({ConfigKey.SERVICE: {ConfigKey.SERVICE_AUDIT: True}}) self.icon_service_engine = IconServiceEngine() self.icon_service_engine.open(self.config) context = IconScoreContext(IconScoreContextType.INVOKE) self.assertEqual(context.icon_service_flag, IconServiceFlag.AUDIT)
def setUp(self, _, mocked_rc_db_from_path, mocked_supplement_db) -> None: context: 'IconScoreContext' = IconScoreContext() context.revision = Revision.DECENTRALIZATION.value self.path = "" mocked_rc_db_from_path.side_effect = MockIissDataBase.from_path self.rc_data_storage = RewardCalcStorage() self.rc_data_storage.open(context, self.path) dummy_block_height = 1 self.dummy_header = Header() self.dummy_header.block_height = dummy_block_height self.dummy_header.version = RC_DB_VERSION_0 self.dummy_gv = GovernanceVariable() self.dummy_gv.block_height = dummy_block_height self.dummy_gv.config_main_prep_count = 22 self.dummy_gv.config_sub_prep_count = 78 self.dummy_gv.calculated_irep = 1 self.dummy_gv.reward_rep = 1000 self.dummy_prep = PRepsData() self.dummy_prep.block_height = dummy_block_height self.dummy_prep.total_delegation = 10 self.dummy_prep.prep_list = [] self.dummy_tx = TxData() self.dummy_tx.address = create_address() self.dummy_tx.block_height = dummy_block_height self.dummy_tx.type = TxType.PREP_REGISTER self.dummy_tx.data = PRepRegisterTx()
def test_open(self, mocked_path_exists, mocked_rc_db_from_path, mocked_supplement_db): # success case: when input existing path, make path of current_db and iiss_rc_db # and generate current level db(if not exist) context: 'IconScoreContext' = IconScoreContext() context.revision = Revision.DECENTRALIZATION.value rc_data_storage = RewardCalcStorage() test_db_path: str = os.path.join(os.getcwd(), ".storage_test_db") expected_current_db_path = os.path.join(test_db_path, RewardCalcStorage.CURRENT_IISS_DB_NAME) def from_path(path: str, create_if_missing: bool = True) -> 'MockIissDataBase': """ :param path: db path :param create_if_missing: :return: KeyValueDatabase instance """ assert expected_current_db_path, path assert True, create_if_missing db = MockPlyvelDB(MockPlyvelDB.make_db()) return MockIissDataBase(db) mocked_rc_db_from_path.side_effect = from_path rc_data_storage.open(context, test_db_path) mocked_path_exists.assert_called() expected_tx_index = -1 actual_tx_index = rc_data_storage._db_iiss_tx_index self.assertEqual(expected_tx_index, actual_tx_index)
def test_validate_score_blacklist( self, mocked_score_context_util_validate_score_blacklist): context = IconScoreContext(IconScoreContextType.INVOKE) # failure case: should not accept ZERO_SCORE_ADDRESS as SCORE address self.assertRaises(InvalidParamsException, IconScoreEngine._validate_score_blacklist, context, ZERO_SCORE_ADDRESS) mocked_score_context_util_validate_score_blacklist.assert_not_called() # failure case: should not accept EOA as SCORE address eoa_address = create_address(AddressPrefix.EOA) self.assertRaises(InvalidParamsException, IconScoreEngine._validate_score_blacklist, context, eoa_address) mocked_score_context_util_validate_score_blacklist.assert_not_called() # failure case: should not accept None type as SCORE address none_address = None self.assertRaises(InvalidParamsException, IconScoreEngine._validate_score_blacklist, context, none_address) mocked_score_context_util_validate_score_blacklist.assert_not_called() # success case: valid SCORE address should be passed contract_address = create_address(AddressPrefix.CONTRACT) IconScoreEngine._validate_score_blacklist(context, contract_address) mocked_score_context_util_validate_score_blacklist.assert_called_with( context, contract_address)
def setUp(self): empty_address = MalformedAddress.from_string('') short_address_without_hx = MalformedAddress.from_string('12341234') short_address = MalformedAddress.from_string('hx1234512345') long_address_without_hx = MalformedAddress.from_string( 'cf85fac2d0b507a2db9ce9526e6d01476f16a2d269f51636f9c4b2d512017faf') long_address = MalformedAddress.from_string( 'hxdf85fac2d0b507a2db9ce9526e6d01476f16a2d269f51636f9c4b2d512017faf' ) self.malformed_addresses = [ empty_address, short_address_without_hx, short_address, long_address_without_hx, long_address ] self.db_name = 'engine.db' db = ContextDatabase.from_path(self.db_name) self.engine = IcxEngine() self._from = Address.from_string('hx' + 'a' * 40) self.to = Address.from_string('hx' + 'b' * 40) self.genesis_address = Address.from_string('hx' + '0' * 40) self.fee_treasury_address = Address.from_string('hx' + '1' * 40) self.total_supply = 10**20 # 100 icx self.context = IconScoreContext(IconScoreContextType.DIRECT) icx_storage = IcxStorage(db) self.engine.open(icx_storage) self.engine.init_account(self.context, AccountType.GENESIS, 'genesis', self.genesis_address, self.total_supply) self.engine.init_account(self.context, AccountType.TREASURY, 'treasury', self.fee_treasury_address, 0)
def _make_issue_info(self) -> tuple: context = IconScoreContext(IconScoreContextType.DIRECT) context._preps = context.engine.prep.preps.copy(mutable=True) context._term = context.engine.prep.term.copy() block_height: int = self._block_height block_hash = create_block_hash() timestamp_us = create_timestamp() block = Block(block_height, block_hash, timestamp_us, self._prev_block_hash, 0) context.block = block issue_data = IconScoreContext.engine.issue.create_icx_issue_info(context) total_issue_amount = 0 for group_dict in issue_data.values(): if "value" in group_dict: total_issue_amount += group_dict["value"] return issue_data, total_issue_amount
def test_invoke(self, mocked_score_engine_call, mocked_score_engine_fallback, mocked_score_engine_validate_score_blacklist): # success case: valid score. if data type is 'call', _call method should be called context = IconScoreContext(IconScoreContextType.INVOKE) data_type = 'call' data = {} mocked_score_engine_call.return_value = None mocked_score_engine_fallback.return_value = None contract_address = create_address(AddressPrefix.CONTRACT) IconScoreEngine.invoke(context, contract_address, data_type, data) mocked_score_engine_validate_score_blacklist.assert_called_with( context, contract_address) mocked_score_engine_call.assert_called() mocked_score_engine_fallback.assert_not_called() # reset mock mocked_score_engine_validate_score_blacklist.reset_mock( return_value=None) mocked_score_engine_call.reset_mock(return_value=None) mocked_score_engine_fallback.reset_mock(return_value=None) # success case: valid score. if data type is not 'call', fallback method should be called data_type = '' IconScoreEngine.invoke(context, contract_address, data_type, data) mocked_score_engine_call.assert_not_called() mocked_score_engine_fallback.assert_called()
def setUp(self): self._score_root_path = self._SCORE_ROOT_PATH sys.path.append(self._score_root_path) IconScoreContext.engine = ContextEngine( icx=None, deploy=Mock(spec=DeployEngine), fee=None, iiss=None, prep=None, issue=None ) IconScoreContext.storage = ContextStorage( icx=None, deploy=Mock(spec=DeployStorage), fee=None, iiss=None, prep=None, issue=None, rc=None, meta=None ) self._context = IconScoreContext(IconScoreContextType.DIRECT) ContextContainer._push_context(self._context)
def test_query(self, mocked_score_engine_call, mocked_score_engine_validate_score_blacklist): # success case: valid score. if data type is 'call', _call method should be called context = IconScoreContext(IconScoreContextType.QUERY) data_type = 'call' data = {} mocked_score_engine_call.return_value = "_call_method_return_data" contract_address = create_address(AddressPrefix.CONTRACT) result = IconScoreEngine.query(context, contract_address, data_type, data) self.assertEqual(result, "_call_method_return_data") mocked_score_engine_validate_score_blacklist.assert_called_with( context, contract_address) mocked_score_engine_call.assert_called() # reset mock mocked_score_engine_validate_score_blacklist.reset_mock( return_value=None) mocked_score_engine_call.reset_mock(return_value=None) # failure case: valid score. if data type is not 'call', exception should be raised data_type = '' self.assertRaises(InvalidParamsException, IconScoreEngine.query, context, contract_address, data_type, data) mocked_score_engine_validate_score_blacklist.assert_called() mocked_score_engine_call.assert_not_called()
def setUp(self): self.db = self.create_db() self._context = IconScoreContext(IconScoreContextType.DIRECT) self._context.current_address = self.db.address ContextContainer._push_context(self._context) pass
def test_service_configuration_score_package_validiator_setting(self): self.config.update_conf({ConfigKey.SERVICE: {ConfigKey.SERVICE_SCORE_PACKAGE_VALIDATOR: True}}) self.icon_service_engine = IconServiceEngine() self.icon_service_engine.open(self.config) context = IconScoreContext(IconScoreContextType.INVOKE) self.assertEqual(context.icon_service_flag, IconServiceFlag.SCORE_PACKAGE_VALIDATOR)