예제 #1
0
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)
예제 #2
0
    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(),
            )
        ])
예제 #3
0
    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(),
        )])
예제 #4
0
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)
예제 #5
0
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)
예제 #6
0
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(
예제 #7
0
 def __init__(self, event_broadcaster):
     self._event_broadcaster = event_broadcaster
     self._filter_factory = EventFilterFactory()
예제 #8
0
 def __init__(self, event_broadcaster):
     self._event_broadcaster = event_broadcaster
     self._filter_factory = EventFilterFactory()
예제 #9
0
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)