Example #1
0
    def test_broadcast_events(self):
        """Test that broadcast_events works with a single subscriber to the
        sawtooth/block-commit event type and that the subscriber does not receive events
        until it is enabled.
        """
        mock_service = Mock()
        mock_block_store = Mock()
        mock_receipt_store = Mock()
        event_broadcaster = EventBroadcaster(mock_service, mock_block_store,
                                             mock_receipt_store)
        block = create_block()

        event_broadcaster.chain_update(block, [])
        mock_service.send.assert_not_called()

        event_broadcaster.add_subscriber("test_conn_id",
                                         [create_block_commit_subscription()],
                                         [])

        event_broadcaster.chain_update(block, [])
        mock_service.send.assert_not_called()

        event_broadcaster.enable_subscriber("test_conn_id")
        event_broadcaster.chain_update(block, [])

        event_list = events_pb2.EventList(
            events=BlockEventExtractor(block).extract(
                [create_block_commit_subscription()])).SerializeToString()
        mock_service.send.assert_called_with(
            validator_pb2.Message.CLIENT_EVENTS,
            event_list,
            connection_id="test_conn_id")
Example #2
0
    def chain_update(self, block, receipts):
        """
        Handles both "sawtooth/block-commit" Events and "settings/update"
        Events. For "sawtooth/block-commit", the last_block_num is updated or a
        fork is detected. For "settings/update", the corresponding cache entry
        will be updated.
        """

        block_events = BlockEventExtractor(block).extract(
            [EventSubscription(event_type="sawtooth/block-commit")])
        receipt_events = ReceiptEventExtractor(receipts).extract(
            [EventSubscription(event_type="settings/update")])
        LOGGER.debug('SettingsObserver: chain_update receipt_events=%s',
                     receipt_events)
        values = {}
        topology_update = False
        for event in receipt_events:
            if event.event_type == "settings/update":
                updated = event.attributes[0].value
                if updated not in values:
                    if updated == 'bgx.consensus.pbft.nodes':
                        topology_update = True
                    values[updated] = True
                    self._handle_txn_commit(event, updated)

        for event in block_events:
            forked = self._handle_block_commit(event)
            if forked:
                return topology_update
        return topology_update
Example #3
0
    def test_catchup_subscriber(self):
        """Test that catch subscriber handles the case of:
        - no blocks (i.e. the genesis block has not been produced or received
        - a block that has some receipts exists and sends results
        """
        mock_service = Mock()
        mock_block_store = MagicMock()
        mock_block_store.chain_head = None
        mock_block_store.get_predecessor_iter.return_value = []
        mock_receipt_store = Mock()

        event_broadcaster = EventBroadcaster(mock_service,
                                             mock_block_store,
                                             mock_receipt_store)

        event_broadcaster.add_subscriber(
            "test_conn_id", [create_block_commit_subscription()], [])

        event_broadcaster.catchup_subscriber("test_conn_id")

        mock_service.send.assert_not_called()

        block = create_block()
        mock_block_store.chain_head = block
        mock_block_store.get_predecessor_iter.return_value = [block]
        mock_block_store.__getitem__.return_value = block

        event_broadcaster.catchup_subscriber("test_conn_id")
        event_list = events_pb2.EventList(
            events=BlockEventExtractor(block).extract(
                [create_block_commit_subscription()])).SerializeToString()
        mock_service.send.assert_called_with(
            validator_pb2.Message.CLIENT_EVENTS,
            event_list, connection_id="test_conn_id", one_way=True)
 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 get_events_for_block(self, blkw, subscriptions):
        receipts = []
        for batch in blkw.block.batches:
            for txn in batch.transactions:
                try:
                    receipts.append(
                        self._receipt_store.get(txn.header_signature))
                except KeyError:
                    LOGGER.warning(
                        "Transaction id %s not found in receipt store "
                        " while looking"
                        " up events for block id %s",
                        txn.header_signature[:10], blkw.identifier[:10])

        block_event_extractor = BlockEventExtractor(blkw)
        receipt_event_extractor = ReceiptEventExtractor(receipts=receipts)

        events = []
        events.extend(block_event_extractor.extract(subscriptions))
        events.extend(receipt_event_extractor.extract(subscriptions))

        return events
Example #6
0
 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")])])
Example #7
0
    def get_events_for_block(self, blkw, subscriptions):
        receipts = []
        for batch in blkw.block.batches:
            for txn in batch.transactions:
                try:
                    receipts.append(self._receipt_store.get(
                        txn.header_signature))
                except KeyError:
                    LOGGER.warning(
                        "Transaction id %s not found in receipt store "
                        " while looking"
                        " up events for block id %s",
                        txn.header_signature[:10],
                        blkw.identifier[:10])

        block_event_extractor = BlockEventExtractor(blkw)
        receipt_event_extractor = ReceiptEventExtractor(receipts=receipts)

        events = []
        events.extend(block_event_extractor.extract(subscriptions))
        events.extend(receipt_event_extractor.extract(subscriptions))

        return events
Example #8
0
 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 chain_update(self, block, receipts):
        extractors = [
            BlockEventExtractor(block),
            ReceiptEventExtractor(receipts),
        ]

        subscriptions = []
        for subscriber in self._subscribers.values():
            for subscription in subscriber.subscriptions:
                if subscription not in subscriptions:
                    subscriptions.append(subscription)

        events = []
        for extractor in extractors:
            extracted_events = extractor.extract(subscriptions)
            if extracted_events:
                events.extend(extracted_events)

        if events:
            self.broadcast_events(events)
Example #10
0
    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)
Example #11
0
    def get_events_for_block_ids(self, block_ids, subscriptions):
        """Get a list of events associated with all the block ids.

        Args:
            block_ids (list of str): The block ids to search for events that
                match each subscription.
            subscriptions (list of EventSubscriptions): EventFilter and
                event type to filter events.

        Returns (list of Events): The Events associated which each block id.

        Raises: KeyError A block id isn't found within the block store.

        """

        events = []

        extractors = []
        for block_id in block_ids:
            blk_w = self._block_store[block_id]
            extractors.append(BlockEventExtractor(blk_w))
            receipts = []
            for batch in blk_w.block.batches:
                for txn in batch.transactions:
                    try:
                        receipts.append(
                            self._receipt_store.get(txn.header_signature))
                    except KeyError:
                        LOGGER.warning(
                            "Transaction id %s not found in receipt store "
                            " while looking"
                            " up events for block id %s",
                            txn.header_signature[:10], block_id[:10])
            extractors.append(ReceiptEventExtractor(receipts=receipts))

        for extractor in extractors:
            events.extend(extractor.extract(subscriptions))
        return events