def test_bytes_index_event(self):
        context = ContextContainer._get_context()

        data = b'0123456789abc'

        # Tests simple event emit
        self._mock_score.BytesIndexEvent(data)
        self.assertEqual(len(context.event_logs), 1)
        event_log = context.event_logs[0]
        self.assertEqual(2, len(event_log.indexed))
        self.assertEqual(0, len(event_log.data))

        logs_bloom = IconServiceEngine._generate_logs_bloom(context.event_logs)

        # Asserts whether the SCORE address is included in the bloom
        self.assert_score_address_in_bloom(logs_bloom)

        event_bloom_data = \
            int(0).to_bytes(1, DATA_BYTE_ORDER) + \
            'BytesIndexEvent(bytes)'.encode('utf-8')
        self.assertIn(event_bloom_data, logs_bloom)

        indexed_bloom_data = \
            int(1).to_bytes(1, DATA_BYTE_ORDER) + data
        self.assertIn(indexed_bloom_data, logs_bloom)
    def test_reserved_event_log(self):
        context = ContextContainer._get_context()
        context.func_type = IconScoreFuncType.READONLY

        address = Address.from_data(AddressPrefix.EOA, os.urandom(20))
        with self.assertRaises(InvalidEventLogException):
            self._mock_score.ICXTransfer(address, address, 0)
    def test_address_index_event(self):
        context = ContextContainer._get_context()

        address = Address.from_data(AddressPrefix.EOA, os.urandom(20))

        # Tests simple event emit
        self._mock_score.AddressIndexEvent(address)
        self.assertEqual(1, len(context.event_logs))
        event_log = context.event_logs[0]
        self.assertEqual(2, len(event_log.indexed))
        self.assertEqual(0, len(event_log.data))

        logs_bloom = IconServiceEngine._generate_logs_bloom(context.event_logs)

        # Asserts whether the SCORE address is included in the bloom
        self.assert_score_address_in_bloom(logs_bloom)

        event_bloom_data = \
            int(0).to_bytes(1, DATA_BYTE_ORDER) + \
            'AddressIndexEvent(Address)'.encode('utf-8')
        self.assertIn(event_bloom_data, logs_bloom)

        indexed_bloom_data = int(1).to_bytes(1, DATA_BYTE_ORDER) + \
                             address.prefix.value.to_bytes(1, DATA_BYTE_ORDER) + address.body
        self.assertEqual(ICON_ADDRESS_BYTES_SIZE + 1, len(indexed_bloom_data))
        self.assertIn(indexed_bloom_data, logs_bloom)
    def test_icx_transfer_event(self):
        context = ContextContainer._get_context()

        address = Address.from_data(AddressPrefix.EOA, os.urandom(20))

        # Tests simple event emit
        self._mock_score.icx.send(address, 1)
        self.assertEqual(len(context.event_logs), 1)
        event_log = context.event_logs[0]
        self.assertEqual(4, len(event_log.indexed))
        self.assertEqual(ICX_TRANSFER_EVENT_LOG, event_log.indexed[0])
        self.assertEqual(0, len(event_log.data))
    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
    def test_interface_call(self, mapped_test_score):
        context = ContextContainer._get_context()
        score_address = Mock(spec=Address)
        to_ = Mock(spec=Address)
        amount = 100

        mapped_test_score.test_interface_call(score_address, to_, amount)
        context.traces.append.assert_called()
        trace = context.traces.append.call_args[0][0]

        assert trace.trace == TraceType.CALL
        assert trace.data[0] == score_address
        assert trace.data[1] == 'interfaceCall'
        assert trace.data[2][0] == to_
        assert trace.data[2][1] == amount
    def test_transfer_and_send_should_have_same_trace(self, mapped_test_score,
                                                      func_name):
        context = ContextContainer._get_context()
        context.type = IconScoreContextType.INVOKE
        to_ = create_address(AddressPrefix.EOA)
        amount = 100

        # Call send or transfer method
        func = getattr(mapped_test_score.icx, func_name)
        func(to_, amount)

        context.traces.append.assert_called()
        trace = context.traces.append.call_args[0][0]
        assert trace.trace == TraceType.CALL
        assert trace.data[0] == to_
        assert trace.data[3] == amount
    def test_call(self, mapped_test_score):
        context = ContextContainer._get_context()
        score_address = Mock(spec=Address)
        func_name = "testCall"
        to_ = Mock(spec=Address)
        amount = 100
        params = {'to': to_, 'amount': amount}

        mapped_test_score.call(score_address, func_name, params)
        context.traces.append.assert_called()
        trace = context.traces.append.call_args[0][0]
        assert trace.trace == TraceType.CALL
        assert trace.data[0] == score_address
        assert trace.data[1] == func_name
        assert trace.data[2][0] == params['to']
        assert trace.data[2][1] == params['amount']
    def test_to_dict_camel(self, mapped_test_score):
        context = ContextContainer._get_context()
        score_address = Mock(spec=Address)
        func_name = "testCall"
        to_ = Mock(spec=Address)
        amount = 100
        params = {'to': to_, 'amount': amount}

        mapped_test_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)
        assert 'scoreAddress' in camel_dict
        assert 'trace' in camel_dict
        assert 'data' in camel_dict
        assert TraceType.CALL.name == camel_dict['trace']
        assert 4 == len(camel_dict['data'])
    def test_to_dict_camel(self):
        context = ContextContainer._get_context()

        address = Address.from_data(AddressPrefix.EOA, os.urandom(20))
        age = 10
        data = b'0123456789abc'

        self._mock_score.MixedEvent(b'i_data', address, age, data, 'text')
        self.assertEqual(len(context.event_logs), 1)

        event_log = context.event_logs[0]

        camel_dict = event_log.to_dict(to_camel_case)
        self.assertIn('scoreAddress', camel_dict)
        self.assertIn('indexed', camel_dict)
        self.assertIn('data', camel_dict)
        self.assertEqual(3, len(camel_dict['indexed']))
        self.assertEqual(3, len(camel_dict['data']))
    def test_call_event(self):
        context = ContextContainer._get_context()

        name = "name"
        address = Address.from_data(AddressPrefix.EOA, os.urandom(20))
        age = 10
        phone_number = "000"

        # Tests simple event emit
        self._mock_score.ZeroIndexEvent(name, address, age)
        self.assertEqual(len(context.event_logs), 1)
        event_log = context.event_logs[0]
        self.assertEqual(1, len(event_log.indexed))
        self.assertEqual(3, len(event_log.data))

        # This event has a indexed parameter,
        # so the list of indexed Should have 2 items
        self._mock_score.OneIndexEvent(name, address, age)
        self.assertEqual(len(context.event_logs), 2)
        event_log = context.event_logs[1]
        self.assertEqual(2, len(event_log.indexed))
        self.assertEqual(2, len(event_log.data))

        logs_bloom = IconServiceEngine._generate_logs_bloom(context.event_logs)

        # Asserts whether the SCORE address is included in the bloom
        self.assert_score_address_in_bloom(logs_bloom)

        zero_event_bloom_data = \
            int(0).to_bytes(1, DATA_BYTE_ORDER) + \
            'ZeroIndexEvent(str,Address,int)'.encode('utf-8')
        self.assertIn(zero_event_bloom_data, logs_bloom)

        one_event_bloom_data = \
            int(0).to_bytes(1, DATA_BYTE_ORDER) + \
            'OneIndexEvent(str,Address,int)'.encode('utf-8')
        self.assertIn(one_event_bloom_data, logs_bloom)

        name_bloom_data = int(1).to_bytes(
            1, DATA_BYTE_ORDER) + name.encode('utf-8')
        self.assertIn(name_bloom_data, logs_bloom)
    def test_call_event_kwarg(self):
        context = ContextContainer._get_context()

        name = "name"
        address = Address.from_data(AddressPrefix.EOA, os.urandom(20))
        age = 10

        # Call with ordered arguments
        self._mock_score.OneIndexEvent(name, address, age)
        self.assertEqual(len(context.event_logs), 1)
        event_log_ordered_args = context.event_logs[0]

        # Call with ordered arguments and keyword arguments
        self._mock_score.OneIndexEvent(name, age=age, address=address)
        self.assertEqual(len(context.event_logs), 2)
        event_log_keyword_args = context.event_logs[1]

        self.assertEqual(event_log_ordered_args.score_address,
                         event_log_keyword_args.score_address)
        self.assertEqual(event_log_ordered_args.indexed,
                         event_log_keyword_args.indexed)
        self.assertEqual(event_log_ordered_args.data,
                         event_log_keyword_args.data)

        logs_bloom = IconServiceEngine._generate_logs_bloom(context.event_logs)

        # Asserts whether the SCORE address is included in the bloom
        self.assert_score_address_in_bloom(logs_bloom)

        one_event_bloom_data = \
            int(0).to_bytes(1, DATA_BYTE_ORDER) + \
            'OneIndexEvent(str,Address,int)'.encode('utf-8')
        self.assertIn(one_event_bloom_data, logs_bloom)

        name_bloom_data = int(1).to_bytes(
            1, DATA_BYTE_ORDER) + name.encode('utf-8')
        self.assertIn(name_bloom_data, logs_bloom)
    def test_call_event_mismatch_arg(self):
        context = ContextContainer._get_context()

        name = "name"
        address = Address.from_data(AddressPrefix.EOA, os.urandom(20))
        age = "10"
        # The hint of 'age' is int type but argument is str type

        self.assertRaises(InvalidEventLogException,
                          self._mock_score.OneIndexEvent, name, address, age)

        logs_bloom = IconServiceEngine._generate_logs_bloom(context.event_logs)

        # Asserts whether the SCORE address is not included in the bloom
        self.assert_score_address_not_in_bloom(logs_bloom)

        one_event_bloom_data = \
            int(0).to_bytes(1, DATA_BYTE_ORDER) + \
            'OneIndexEvent(str,Address,int)'.encode('utf-8')
        self.assertNotIn(one_event_bloom_data, logs_bloom)

        name_bloom_data = int(1).to_bytes(
            1, DATA_BYTE_ORDER) + name.encode('utf-8')
        self.assertNotIn(name_bloom_data, logs_bloom)
    def test_event_log_on_readonly_method(self):
        context = ContextContainer._get_context()
        context.func_type = IconScoreFuncType.READONLY

        with self.assertRaises(InvalidEventLogException):
            self._mock_score.BoolIndexEvent(False)