def test_add_remove_subscriber(self): """Test adding and removing a subscriber.""" mock_service = Mock() mock_block_store = Mock() mock_receipt_store = Mock() event_broadcaster = EventBroadcaster(mock_service, mock_block_store, mock_receipt_store) subscriptions = [ EventSubscription( event_type="test_event", filters=[ FILTER_FACTORY.create(key="test", match_string="test") ], ) ] event_broadcaster.add_subscriber("test_conn_id", subscriptions, []) self.assertTrue( "test_conn_id" in event_broadcaster._subscribers.keys()) self.assertEqual( event_broadcaster._subscribers["test_conn_id"].subscriptions, subscriptions) event_broadcaster.remove_subscriber("test_conn_id") self.assertTrue( "test_conn_id" not in event_broadcaster._subscribers.keys())
def test_subscription(self): """Test that an event correctly matches against a subscription.""" self.assertIn( events_pb2.Event(event_type="test", attributes=[ events_pb2.Event.Attribute(key="test", value="test")]), EventSubscription( event_type="test", filters=[FILTER_FACTORY.create(key="test", match_string="test")]))
def do_tf_events(): gen_data = [ ["test1", "test2"], ["test3"], ["test4", "test5", "test6"], ] event_sets = [[Event(event_type=event_type) for event_type in events] for events in gen_data] receipts = [TransactionReceipt(events=events) for events in event_sets] extractor = ReceiptEventExtractor(receipts) events = extractor.extract([]) assert [] == events events = extractor.extract([ EventSubscription(event_type="test1"), EventSubscription(event_type="test5"), ]) assert events == [event_sets[0][0], event_sets[2][1]]
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 chain_update(self, block, receipts): """ Handles both "block_commit" Events and "identity_update" Events. For "block_commit", the last_block_num is updated or a fork is detected. For "identity_update", the corresponding cache entry will be updated. """ block_events = BlockEventExtractor(block).extract( [EventSubscription(event_type="block_commit")]) receipt_events = ReceiptEventExtractor(receipts).extract( [EventSubscription(event_type="identity_update")]) for event in block_events: forked = self._handle_block_commit(event) if forked: return for event in receipt_events: if event.event_type == "identity_update": self._handle_txn_commit(event)
def test_tf_events(self): """Test that tf events are generated correctly.""" gen_data = [ ["test1", "test2"], ["test3"], ["test4", "test5", "test6"], ] event_sets = [[Event(event_type=event_type) for event_type in events] for events in gen_data] receipts = [TransactionReceipt(events=events) for events in event_sets] extractor = ReceiptEventExtractor(receipts) events = extractor.extract([]) self.assertEqual([], events) events = extractor.extract([ EventSubscription(event_type="test1"), EventSubscription(event_type="test5"), ]) self.assertEqual(events, [event_sets[0][0], event_sets[2][1]])
def chain_update(self, block, receipts): # Check to see if there is an active engine at all: if not self._registry.has_active_engine(): self._update_active_engine(block) return # Otherwise, check to see if the settings changed, before updating # the active engine. receipt_events = ReceiptEventExtractor(receipts).extract( [EventSubscription(event_type="setting/update")]) for event in receipt_events: if self._is_consensus_algorithm_setting(event): self._update_active_engine(block) break
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 do_block_event_extractor(): block_header = BlockHeader(block_num=85, state_root_hash="0987654321fedcba", previous_block_id="0000000000000000") block = BlockWrapper( Block(header_signature="abcdef1234567890", header=block_header.SerializeToString())) extractor = BlockEventExtractor(block) events = extractor.extract( [EventSubscription(event_type="sawtooth/block-commit")]) assert events == [ Event(event_type="sawtooth/block-commit", attributes=[ Event.Attribute(key="block_id", value="abcdef1234567890"), Event.Attribute(key="block_num", value="85"), Event.Attribute(key="state_root_hash", value="0987654321fedcba"), Event.Attribute(key="previous_block_id", value="0000000000000000") ]) ]
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 test_block_event_extractor(self): """Test that a sawtooth/block-commit event is generated correctly.""" block_header = BlockHeader(block_num=85, state_root_hash="0987654321fedcba", previous_block_id="0000000000000000") block = BlockWrapper( Block(header_signature="abcdef1234567890", header=block_header.SerializeToString())) extractor = BlockEventExtractor(block) events = extractor.extract( [EventSubscription(event_type="sawtooth/block-commit")]) self.assertEqual(events, [ Event(event_type="sawtooth/block-commit", attributes=[ Event.Attribute(key="block_id", value="abcdef1234567890"), Event.Attribute(key="block_num", value="85"), Event.Attribute(key="state_root_hash", value="0987654321fedcba"), Event.Attribute(key="previous_block_id", value="0000000000000000") ]) ])
def test_subscribe(self): """Test that a subscriber is successfully validated and added to the event broadcaster. """ mock_event_broadcaster = Mock() mock_event_broadcaster.get_latest_known_block_id.return_value = \ "0" * 128 handler = \ ClientEventsSubscribeValidationHandler(mock_event_broadcaster) request = client_event_pb2.ClientEventsSubscribeRequest( subscriptions=[ events_pb2.EventSubscription( event_type="test_event", filters=[ events_pb2.EventFilter( key="test", match_string="test", filter_type=events_pb2.EventFilter.SIMPLE_ANY) ], ) ], last_known_block_ids=["0" * 128]).SerializeToString() response = handler.handle("test_conn_id", request) mock_event_broadcaster.add_subscriber.assert_called_with( "test_conn_id", [ EventSubscription(event_type="test_event", filters=[ FILTER_FACTORY.create( key="test", match_string="test") ]) ], "0" * 128) self.assertEqual(HandlerStatus.RETURN_AND_PASS, response.status) self.assertEqual(client_event_pb2.ClientEventsSubscribeResponse.OK, response.message_out.status)
def create_block_commit_subscription(): return EventSubscription(event_type="block_commit")
def create_block_commit_subscription(): return EventSubscription(event_type="sawtooth/block-commit")