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)