class ClientEventsSubscribeValidationHandler(Handler): """Handles validating an EventSubscriptionRequest. This must be done separately from adding the subscriber to the EventBroadcaster so that the subscriber does not receive events before the EventSubscribeResponse. """ _msg_type = validator_pb2.Message.CLIENT_EVENTS_SUBSCRIBE_RESPONSE def __init__(self, event_broadcaster): self._event_broadcaster = event_broadcaster self._filter_factory = EventFilterFactory() def handle(self, connection_id, message_content): request = ClientEventsSubscribeRequest() request.ParseFromString(message_content) ack = ClientEventsSubscribeResponse() try: subscriptions = [ EventSubscription( event_type=sub.event_type, filters=[ self._filter_factory.create(f.key, f.match_string, f.filter_type) for f in sub.filters ], ) for sub in request.subscriptions ] except InvalidFilterError as err: LOGGER.warning("Invalid Filter Error: %s", err) ack.status = ack.INVALID_FILTER ack.response_message = str(err) return HandlerResult(HandlerStatus.RETURN, message_out=ack, message_type=self._msg_type) last_known_block_ids = list(request.last_known_block_ids) last_known_block_id = None if last_known_block_ids: try: last_known_block_id = \ self._event_broadcaster.get_latest_known_block_id( last_known_block_ids) except NoKnownBlockError as err: ack.status = ack.UNKNOWN_BLOCK ack.response_message = str(err) return HandlerResult(HandlerStatus.RETURN, message_out=ack, message_type=self._msg_type) self._event_broadcaster.add_subscriber(connection_id, subscriptions, last_known_block_id) ack.status = ack.OK return HandlerResult(HandlerStatus.RETURN_AND_PASS, message_out=ack, message_type=self._msg_type)
def test_state_delta_events(self): """Test that sawtooth/state-delta events are generated correctly.""" gen_data = [ [("a", b"a", StateChange.SET), ("b", b"b", StateChange.DELETE)], [("a", b"a", StateChange.DELETE), ("d", b"d", StateChange.SET)], [("e", b"e", StateChange.SET)], ] change_sets = [[ StateChange(address=address, value=value, type=change_type) for address, value, change_type in state_changes ] for state_changes in gen_data] receipts = [ TransactionReceipt(state_changes=state_changes) for state_changes in change_sets ] extractor = ReceiptEventExtractor(receipts) factory = EventFilterFactory() events = extractor.extract([ EventSubscription(event_type="sawtooth/state-delta", filters=[factory.create("address", "a")]), EventSubscription( event_type="sawtooth/state-delta", filters=[ factory.create("address", "[ce]", EventFilter.REGEX_ANY) ], ) ]) self.assertEqual(events, [ Event( event_type="sawtooth/state-delta", attributes=[ Event.Attribute(key="address", value=address) for address in ["e", "d", "a", "b"] ], data=StateChangeList(state_changes=[ change_sets[2][0], change_sets[1][1], change_sets[1][0], change_sets[0][1], ]).SerializeToString(), ) ])
def test_state_delta_events(self): """Test that sawtooth/state-delta events are generated correctly.""" gen_data = [ [("a", b"a", StateChange.SET), ("b", b"b", StateChange.DELETE)], [("a", b"a", StateChange.DELETE), ("d", b"d", StateChange.SET)], [("e", b"e", StateChange.SET)], ] change_sets = [ [ StateChange(address=address, value=value, type=change_type) for address, value, change_type in state_changes ] for state_changes in gen_data ] receipts = [ TransactionReceipt(state_changes=state_changes) for state_changes in change_sets ] extractor = ReceiptEventExtractor(receipts) factory = EventFilterFactory() events = extractor.extract([ EventSubscription( event_type="sawtooth/state-delta", filters=[factory.create("address", "a")]), EventSubscription( event_type="sawtooth/state-delta", filters=[factory.create( "address", "[ce]", EventFilter.REGEX_ANY)], ) ]) self.assertEqual(events, [Event( event_type="sawtooth/state-delta", attributes=[ Event.Attribute(key="address", value=address) for address in ["e", "d", "a", "b"] ], data=StateChangeList(state_changes=[ change_sets[2][0], change_sets[1][1], change_sets[1][0], change_sets[0][1], ]).SerializeToString(), )])
class ClientEventsGetRequestHandler(Handler): def __init__(self, event_broadcaster): self._event_broadcaster = event_broadcaster self._filter_factory = EventFilterFactory() def handle(self, connection_id, message_content): request = ClientEventsGetRequest() request.ParseFromString(message_content) resp = ClientEventsGetResponse() try: subscriptions = [ EventSubscription( event_type=sub.event_type, filters=[ self._filter_factory.create( f.key, f.match_string, f.filter_type) for f in sub.filters ], ) for sub in request.subscriptions ] except InvalidFilterError as err: LOGGER.warning("Invalid Filter Error: %s", err) resp.status = resp.INVALID_FILTER return HandlerResult( HandlerStatus.RETURN, message_out=resp, message_type=validator_pb2.Message.CLIENT_EVENTS_GET_RESPONSE) try: events = self._event_broadcaster.get_events_for_block_ids( request.block_ids, subscriptions) except KeyError: resp.status = resp.UNKNOWN_BLOCK return HandlerResult( HandlerStatus.RETURN, message_out=resp, message_type=validator_pb2.Message.CLIENT_EVENTS_GET_RESPONSE) resp.events.extend(events) resp.status = resp.OK return HandlerResult( HandlerStatus.RETURN, message_out=resp, message_type=validator_pb2.Message.CLIENT_EVENTS_GET_RESPONSE)
class ClientEventsGetRequestHandler(Handler): def __init__(self, event_broadcaster): self._event_broadcaster = event_broadcaster self._filter_factory = EventFilterFactory() def handle(self, connection_id, message_content): request = ClientEventsGetRequest() request.ParseFromString(message_content) resp = ClientEventsGetResponse() try: subscriptions = [ EventSubscription( event_type=sub.event_type, filters=[ self._filter_factory.create(f.key, f.match_string, f.filter_type) for f in sub.filters ], ) for sub in request.subscriptions ] except InvalidFilterError as err: LOGGER.warning("Invalid Filter Error: %s", err) resp.status = resp.INVALID_FILTER return HandlerResult( HandlerStatus.RETURN, message_out=resp, message_type=validator_pb2.Message.CLIENT_EVENTS_GET_RESPONSE) try: events = self._event_broadcaster.get_events_for_block_ids( request.block_ids, subscriptions) except KeyError: resp.status = resp.UNKNOWN_BLOCK return HandlerResult( HandlerStatus.RETURN, message_out=resp, message_type=validator_pb2.Message.CLIENT_EVENTS_GET_RESPONSE) resp.events.extend(events) resp.status = resp.OK return HandlerResult( HandlerStatus.RETURN, message_out=resp, message_type=validator_pb2.Message.CLIENT_EVENTS_GET_RESPONSE)
def create_block(): block_header = block_pb2.BlockHeader(block_num=85, state_root_hash="0987654321fedcba", previous_block_id="0000000000000000") block = BlockWrapper( block_pb2.Block(header_signature="abcdef1234567890", header=block_header.SerializeToString())) return block def create_block_commit_subscription(): return EventSubscription(event_type="block_commit") FILTER_FACTORY = EventFilterFactory() class EventSubscriptionTest(unittest.TestCase): def test_filter(self): """Test that a regex filter matches properly against an event.""" self.assertIn( events_pb2.Event(attributes=[ events_pb2.Event.Attribute(key="address", value="000000" + "f" * 64) ]), FILTER_FACTORY.create(key="address", match_string="000000.*", filter_type=EventFilterType.regex_any)) self.assertIn(
def __init__(self, event_broadcaster): self._event_broadcaster = event_broadcaster self._filter_factory = EventFilterFactory()
def __init__(self, event_broadcaster): self._event_broadcaster = event_broadcaster self._filter_factory = EventFilterFactory()
class ClientEventsSubscribeValidationHandler(Handler): """Handles validating an EventSubscriptionRequest. This must be done separately from adding the subscriber to the EventBroadcaster so that the subscriber does not receive events before the EventSubscribeResponse. """ _msg_type = validator_pb2.Message.CLIENT_EVENTS_SUBSCRIBE_RESPONSE def __init__(self, event_broadcaster): self._event_broadcaster = event_broadcaster self._filter_factory = EventFilterFactory() def handle(self, connection_id, message_content): request = ClientEventsSubscribeRequest() request.ParseFromString(message_content) ack = ClientEventsSubscribeResponse() try: subscriptions = [ EventSubscription( event_type=sub.event_type, filters=[ self._filter_factory.create( f.key, f.match_string, f.filter_type) for f in sub.filters ], ) for sub in request.subscriptions ] except InvalidFilterError as err: LOGGER.warning("Invalid Filter Error: %s", err) ack.status = ack.INVALID_FILTER ack.response_message = str(err) return HandlerResult( HandlerStatus.RETURN, message_out=ack, message_type=self._msg_type) last_known_block_ids = list(request.last_known_block_ids) last_known_block_id = None if last_known_block_ids: try: last_known_block_id = \ self._event_broadcaster.get_latest_known_block_id( last_known_block_ids) except NoKnownBlockError as err: ack.status = ack.UNKNOWN_BLOCK ack.response_message = str(err) return HandlerResult( HandlerStatus.RETURN, message_out=ack, message_type=self._msg_type) self._event_broadcaster.add_subscriber( connection_id, subscriptions, last_known_block_id) ack.status = ack.OK return HandlerResult( HandlerStatus.RETURN_AND_PASS, message_out=ack, message_type=self._msg_type)