def test_revert(self, mocker): mocker.patch.object(IconServiceEngine, "_charge_transaction_fee") mocker.patch.object(IconScoreEngine, "invoke") context = ContextContainer._get_context() icon_service_engine = IconServiceEngine() icon_service_engine._icx_engine = Mock(spec=IcxEngine) icon_service_engine._icon_score_deploy_engine = \ Mock(spec=DeployEngine) icon_service_engine._icon_pre_validator = Mock(spec=IconPreValidator) context.tx_batch = TransactionBatch() context.clear_batch = Mock() context.update_batch = Mock() from_ = Address.from_data(AddressPrefix.EOA, os.urandom(20)) to_ = Address.from_data(AddressPrefix.CONTRACT, os.urandom(20)) tx_index = randrange(0, 100) context.tx = Transaction(os.urandom(32), tx_index, from_, 0) context.msg = Message(from_) def intercept_charge_transaction_fee(*args, **kwargs): return {}, Mock(spec=int) IconServiceEngine._charge_transaction_fee.side_effect = \ intercept_charge_transaction_fee icon_service_engine._icon_score_deploy_engine.attach_mock( Mock(return_value=False), 'is_data_type_supported') reason = Mock(spec=str) code = ExceptionCode.SCORE_ERROR mock_revert = Mock(side_effect=IconScoreException(reason)) IconScoreEngine.invoke.side_effect = mock_revert raise_exception_start_tag("test_revert") tx_result = icon_service_engine._handle_icx_send_transaction( context, { 'version': 3, 'from': from_, 'to': to_ }) raise_exception_end_tag("test_revert") assert tx_result.status == 0 IconServiceEngine._charge_transaction_fee.assert_called() context.traces.append.assert_called() trace = context.traces.append.call_args[0][0] assert trace.trace == TraceType.REVERT assert trace.data[0] == code assert trace.data[1] == reason
class TestTrace(unittest.TestCase): def setUp(self): db = Mock(spec=IconScoreDatabase) db.address = create_address(AddressPrefix.CONTRACT) context = IconScoreContext() traces = Mock(spec=list) context.tx = Mock(spec=Transaction) context.block = Mock(spec=Block) context.cumulative_step_used = Mock(spec=int) context.cumulative_step_used.attach_mock(Mock(), '__add__') context.step_counter = Mock(spec=IconScoreStepCounter) context.event_logs = Mock(spec=list) context.logs_bloom = Mock(spec=BloomFilter) context.traces = traces ContextContainer._push_context(context) context.icon_score_manager = Mock() context.icon_score_manager.get_owner = Mock(return_value=None) context.icon_score_manager.get_tx_hashes_by_score_address = \ Mock(return_value=(create_tx_hash(), create_tx_hash())) context.internal_call = InternalCall(context) context.internal_call._other_score_call = Mock() context.internal_call.icx_engine = Mock(spec=IcxEngine) context.icon_score_mapper = Mock() context.icon_score_mapper.get_icon_score = Mock( return_value=TestScore(db)) context.internal_call._validate_score_blacklist = Mock( return_value=False) self._score = TestScore(db) def tearDown(self): ContextContainer._clear_context() self._mock_icon_score = None def test_transfer(self): context = ContextContainer._get_context() context.type = IconScoreContextType.INVOKE to_ = create_address(AddressPrefix.EOA) context.internal_call.icx_engine = Mock(spec=IcxEngine) amount = 100 self._score.icx.transfer(to_, amount) context.traces.append.assert_called() trace = context.traces.append.call_args[0][0] self.assertEqual(TraceType.CALL, trace.trace) self.assertEqual(to_, trace.data[0]) self.assertEqual(amount, trace.data[3]) def test_send(self): context = ContextContainer._get_context() context.type = IconScoreContextType.INVOKE to_ = create_address(AddressPrefix.EOA) amount = 100 self._score.icx.send(to_, amount) context.traces.append.assert_called() trace = context.traces.append.call_args[0][0] self.assertEqual(TraceType.CALL, trace.trace) self.assertEqual(to_, trace.data[0]) self.assertEqual(amount, trace.data[3]) def test_call(self): context = ContextContainer._get_context() score_address = Mock(spec=Address) func_name = "testCall" to_ = Mock(spec=Address) amount = 100 params = {'to': to_, 'amount': amount} self._score.call(score_address, func_name, params) context.traces.append.assert_called() trace = context.traces.append.call_args[0][0] self.assertEqual(TraceType.CALL, trace.trace) self.assertEqual(score_address, trace.data[0]) self.assertEqual(func_name, trace.data[1]) self.assertEqual(params['to'], trace.data[2][0]) self.assertEqual(params['amount'], trace.data[2][1]) def test_interface_call(self): context = ContextContainer._get_context() score_address = Mock(spec=Address) to_ = Mock(spec=Address) amount = 100 self._score.test_interface_call(score_address, to_, amount) context.traces.append.assert_called() trace = context.traces.append.call_args[0][0] self.assertEqual(TraceType.CALL, trace.trace) self.assertEqual(score_address, trace.data[0]) self.assertEqual('interfaceCall', trace.data[1]) self.assertEqual(to_, trace.data[2][0]) self.assertEqual(amount, trace.data[2][1]) @patch('iconservice.icon_service_engine.IconServiceEngine.' '_charge_transaction_fee') def test_revert(self, IconServiceEngine_charge_transaction_fee): context = ContextContainer._get_context() self._icon_service_engine = IconServiceEngine() self._icon_service_engine._flag = 0 self._icon_service_engine._icx_engine = Mock(spec=IcxEngine) self._icon_service_engine._icon_score_deploy_engine = \ Mock(spec=IconScoreDeployEngine) self._icon_service_engine._icon_score_engine = Mock( spec=IconScoreEngine) self._icon_service_engine._icon_pre_validator = Mock( spec=IconPreValidator) context.tx_batch = TransactionBatch() from_ = Mock(spec=Address) to_ = Mock(spec=Address) def intercept_charge_transaction_fee(*args, **kwargs): return Mock(spec=int), Mock(spec=int) IconServiceEngine_charge_transaction_fee.side_effect = \ intercept_charge_transaction_fee self._icon_service_engine._icon_score_deploy_engine.attach_mock( Mock(return_value=False), 'is_data_type_supported') reason = Mock(spec=str) code = ExceptionCode.SCORE_ERROR mock_revert = Mock(side_effect=RevertException(reason)) self._icon_service_engine._icon_score_engine.attach_mock( mock_revert, "invoke") raise_exception_start_tag("test_revert") tx_result = self._icon_service_engine._handle_icx_send_transaction( context, { 'version': 3, 'from': from_, 'to': to_ }) raise_exception_end_tag("test_revert") self.assertEqual(0, tx_result.status) IconServiceEngine_charge_transaction_fee.assert_called() context.traces.append.assert_called() trace = context.traces.append.call_args[0][0] self.assertEqual(TraceType.REVERT, trace.trace) self.assertEqual(code, trace.data[0]) self.assertEqual(reason, trace.data[1]) @patch('iconservice.icon_service_engine.IconServiceEngine.' '_charge_transaction_fee') def test_throw(self, IconServiceEngine_charge_transaction_fee): context = ContextContainer._get_context() self._icon_service_engine = IconServiceEngine() self._icon_service_engine._flag = 0 self._icon_service_engine._icx_engine = Mock(spec=IcxEngine) self._icon_service_engine._icon_score_deploy_engine = \ Mock(spec=IconScoreDeployEngine) self._icon_service_engine._icon_score_engine = Mock( spec=IconScoreEngine) self._icon_service_engine._icon_pre_validator = Mock( spec=IconPreValidator) context.tx_batch = TransactionBatch() from_ = Mock(spec=Address) to_ = Mock(spec=Address) def intercept_charge_transaction_fee(*args, **kwargs): return Mock(spec=int), Mock(spec=int) IconServiceEngine_charge_transaction_fee.side_effect = \ intercept_charge_transaction_fee self._icon_service_engine._icon_score_deploy_engine.attach_mock( Mock(return_value=False), 'is_data_type_supported') error = Mock(spec=str) code = ExceptionCode.SCORE_ERROR mock_exception = Mock(side_effect=IconScoreException(error, code)) self._icon_service_engine._icon_score_engine.attach_mock( mock_exception, "invoke") raise_exception_start_tag("test_throw") tx_result = self._icon_service_engine._handle_icx_send_transaction( context, { 'version': 3, 'from': from_, 'to': to_ }) raise_exception_end_tag("test_throw") self.assertEqual(0, tx_result.status) IconServiceEngine_charge_transaction_fee.assert_called() context.traces.append.assert_called() trace = context.traces.append.call_args[0][0] self.assertEqual(TraceType.THROW, trace.trace) self.assertEqual(code, trace.data[0]) self.assertEqual(error, trace.data[1]) def test_to_dict_camel(self): context = ContextContainer._get_context() score_address = Mock(spec=Address) func_name = "testCall" to_ = Mock(spec=Address) amount = 100 params = {'to': to_, 'amount': amount} self._score.call(score_address, func_name, params) context.traces.append.assert_called() trace = context.traces.append.call_args[0][0] camel_dict = trace.to_dict(to_camel_case) self.assertIn('scoreAddress', camel_dict) self.assertIn('trace', camel_dict) self.assertIn('data', camel_dict) self.assertEqual(TraceType.CALL.name, camel_dict['trace']) self.assertEqual(4, len(camel_dict['data']))
class TestTrace(unittest.TestCase): def setUp(self): db = Mock(spec=IconScoreDatabase) db.address = create_address(AddressPrefix.CONTRACT) context = IconScoreContext() context.icon_score_deploy_engine = Mock() traces = Mock(spec=list) context.tx = Mock(spec=Transaction) context.block = Mock(spec=Block) context.cumulative_step_used = Mock(spec=int) context.cumulative_step_used.attach_mock(Mock(), '__add__') context.step_counter = Mock(spec=IconScoreStepCounter) context.event_logs = [] context.traces = traces context.tx_batch = TransactionBatch() ContextContainer._push_context(context) InternalCall._other_score_call = Mock() IconScoreContext.engine = ContextEngine( icx=Mock(spec=IcxEngine), 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 ) context.icon_score_mapper = Mock() context.icon_score_mapper.get_icon_score = Mock(return_value=TestScore(db)) self._score = TestScore(db) def tearDown(self): InternalCall._other_score_call = OTHER_CALL ContextContainer._clear_context() self._mock_icon_score = None def test_transfer(self): context = ContextContainer._get_context() context.type = IconScoreContextType.INVOKE to_ = create_address(AddressPrefix.EOA) amount = 100 self._score.icx.transfer(to_, amount) context.traces.append.assert_called() trace = context.traces.append.call_args[0][0] self.assertEqual(TraceType.CALL, trace.trace) self.assertEqual(to_, trace.data[0]) self.assertEqual(amount, trace.data[3]) def test_send(self): context = ContextContainer._get_context() context.type = IconScoreContextType.INVOKE to_ = create_address(AddressPrefix.EOA) amount = 100 self._score.icx.send(to_, amount) context.traces.append.assert_called() trace = context.traces.append.call_args[0][0] self.assertEqual(TraceType.CALL, trace.trace) self.assertEqual(to_, trace.data[0]) self.assertEqual(amount, trace.data[3]) def test_call(self): context = ContextContainer._get_context() score_address = Mock(spec=Address) func_name = "testCall" to_ = Mock(spec=Address) amount = 100 params = {'to': to_, 'amount': amount} self._score.call(score_address, func_name, params) context.traces.append.assert_called() trace = context.traces.append.call_args[0][0] self.assertEqual(TraceType.CALL, trace.trace) self.assertEqual(score_address, trace.data[0]) self.assertEqual(func_name, trace.data[1]) self.assertEqual(params['to'], trace.data[2][0]) self.assertEqual(params['amount'], trace.data[2][1]) def test_interface_call(self): context = ContextContainer._get_context() score_address = Mock(spec=Address) to_ = Mock(spec=Address) amount = 100 self._score.test_interface_call(score_address, to_, amount) context.traces.append.assert_called() trace = context.traces.append.call_args[0][0] self.assertEqual(TraceType.CALL, trace.trace) self.assertEqual(score_address, trace.data[0]) self.assertEqual('interfaceCall', trace.data[1]) self.assertEqual(to_, trace.data[2][0]) self.assertEqual(amount, trace.data[2][1]) @patch('iconservice.icon_service_engine.IconServiceEngine.' '_charge_transaction_fee') @patch('iconservice.iconscore.icon_score_engine.IconScoreEngine.invoke') def test_revert(self, score_invoke, IconServiceEngine_charge_transaction_fee): context = ContextContainer._get_context() self._icon_service_engine = IconServiceEngine() self._icon_service_engine._icx_engine = Mock(spec=IcxEngine) self._icon_service_engine._icon_score_deploy_engine = \ Mock(spec=DeployEngine) self._icon_service_engine._icon_pre_validator = Mock( spec=IconPreValidator) context.tx_batch = TransactionBatch() context.clear_batch = Mock() context.update_batch = Mock() from_ = Address.from_data(AddressPrefix.EOA, os.urandom(20)) to_ = Address.from_data(AddressPrefix.CONTRACT, os.urandom(20)) tx_index = randrange(0, 100) context.tx = Transaction(os.urandom(32), tx_index, from_, 0) context.msg = Message(from_) def intercept_charge_transaction_fee(*args, **kwargs): return {}, Mock(spec=int) IconServiceEngine_charge_transaction_fee.side_effect = \ intercept_charge_transaction_fee self._icon_service_engine._icon_score_deploy_engine.attach_mock( Mock(return_value=False), 'is_data_type_supported') reason = Mock(spec=str) code = ExceptionCode.SCORE_ERROR mock_revert = Mock(side_effect=IconScoreException(reason)) score_invoke.side_effect = mock_revert raise_exception_start_tag("test_revert") tx_result = self._icon_service_engine._handle_icx_send_transaction( context, {'version': 3, 'from': from_, 'to': to_}) raise_exception_end_tag("test_revert") self.assertEqual(0, tx_result.status) IconServiceEngine_charge_transaction_fee.assert_called() context.traces.append.assert_called() trace = context.traces.append.call_args[0][0] self.assertEqual(TraceType.REVERT, trace.trace) self.assertEqual(code, trace.data[0]) self.assertEqual(reason, trace.data[1]) @patch('iconservice.icon_service_engine.IconServiceEngine.' '_charge_transaction_fee') @patch('iconservice.iconscore.icon_score_engine.IconScoreEngine.invoke') def test_throw(self, score_invoke, IconServiceEngine_charge_transaction_fee): context = ContextContainer._get_context() self._icon_service_engine = IconServiceEngine() self._icon_service_engine._icx_engine = Mock(spec=IcxEngine) self._icon_service_engine._icon_score_deploy_engine = \ Mock(spec=DeployEngine) self._icon_service_engine._icon_pre_validator = Mock( spec=IconPreValidator) context.tx_batch = TransactionBatch() context.clear_batch = Mock() context.update_batch = Mock() from_ = Address.from_data(AddressPrefix.EOA, os.urandom(20)) to_ = Address.from_data(AddressPrefix.CONTRACT, os.urandom(20)) tx_index = randrange(0, 100) context.tx = Transaction(os.urandom(32), tx_index, from_, 0) context.msg = Message(from_) def intercept_charge_transaction_fee(*args, **kwargs): return {}, Mock(spec=int) IconServiceEngine_charge_transaction_fee.side_effect = \ intercept_charge_transaction_fee self._icon_service_engine._icon_score_deploy_engine.attach_mock( Mock(return_value=False), 'is_data_type_supported') error = Mock(spec=str) code = ExceptionCode.INVALID_PARAMETER mock_exception = Mock(side_effect=InvalidParamsException(error)) score_invoke.side_effect = mock_exception raise_exception_start_tag("test_throw") tx_result = self._icon_service_engine._handle_icx_send_transaction( context, {'version': 3, 'from': from_, 'to': to_}) raise_exception_end_tag("test_throw") self.assertEqual(0, tx_result.status) IconServiceEngine_charge_transaction_fee.assert_called() context.traces.append.assert_called() trace = context.traces.append.call_args[0][0] self.assertEqual(TraceType.THROW, trace.trace) self.assertEqual(code, trace.data[0]) self.assertEqual(error, trace.data[1]) def test_to_dict_camel(self): context = ContextContainer._get_context() score_address = Mock(spec=Address) func_name = "testCall" to_ = Mock(spec=Address) amount = 100 params = {'to': to_, 'amount': amount} self._score.call(score_address, func_name, params) context.traces.append.assert_called() trace = context.traces.append.call_args[0][0] camel_dict = trace.to_dict(to_camel_case) self.assertIn('scoreAddress', camel_dict) self.assertIn('trace', camel_dict) self.assertIn('data', camel_dict) self.assertEqual(TraceType.CALL.name, camel_dict['trace']) self.assertEqual(4, len(camel_dict['data']))