def _register(self): LOG.debug(f"Register handlers") self._stream.wait_for_ready() future = self._stream.send( message_type=Message.CLIENT_EVENTS_SUBSCRIBE_REQUEST, content=ClientEventsSubscribeRequest( last_known_block_ids=[NULL_BLOCK_ID], subscriptions=[ EventSubscription(event_type="sawtooth/block-commit"), EventSubscription( event_type="sawtooth/state-delta", filters=[ EventFilter( key="address", match_string=f"^{Namespaces.GA_NAMESPACE}.*", filter_type=EventFilter.REGEX_ANY, ) ], ), ], ).SerializeToString(), ) resp = TpRegisterResponse() try: resp.ParseFromString(future.result().content) LOG.info("Register response: %s", TpRegisterResponse.Status.Name(resp.status)) except ValidatorConnectionError as vce: LOG.info("During waiting for response on registration: %s", vce) except Exception as e: LOG.info("During waiting for response on registration: %s", e)
def start(self, known_ids=None): """Subscribes to state delta events, and then waits to receive deltas. Sends any events received to delta handlers. """ if not known_ids: known_ids = [NULL_BLOCK_ID] self._stream.wait_for_ready() LOGGER.debug('Subscribing to state delta events') block_sub = EventSubscription(event_type='sawtooth/block-commit') delta_sub = EventSubscription( event_type='sawtooth/state-delta', filters=[ EventFilter(key='address', match_string='^{}.*'.format(NAMESPACE), filter_type=EventFilter.REGEX_ANY) ]) request = ClientEventsSubscribeRequest( last_known_block_ids=known_ids, subscriptions=[block_sub, delta_sub]) response_future = self._stream.send( Message.CLIENT_EVENTS_SUBSCRIBE_REQUEST, request.SerializeToString()) response = ClientEventsSubscribeResponse() response.ParseFromString(response_future.result().content) # Forked all the way back to genesis, restart with no known_ids if (response.status == ClientEventsSubscribeResponse.UNKNOWN_BLOCK and known_ids): return self.start() if response.status != ClientEventsSubscribeResponse.OK: raise RuntimeError('Subscription failed with status: {}'.format( ClientEventsSubscribeResponse.Status.Name(response.status))) self._is_active = True LOGGER.debug('Successfully subscribed to state delta events') while self._is_active: message_future = self._stream.receive() event_list = EventList() event_list.ParseFromString(message_future.result().content) for handler in self._event_handlers: handler(event_list.events)
def subscribe_to_event(self): LOGGER.info("Subscribing to event {}".format(self._event)) done_sub = EventSubscription(event_type=self._event) request = ClientEventsSubscribeRequest(subscriptions=[done_sub]) response_future = self._stream.send( Message.CLIENT_EVENTS_SUBSCRIBE_REQUEST, request.SerializeToString()) sub_response = ClientEventsSubscribeResponse() sub_response.ParseFromString(response_future.result().content) if sub_response.status == ClientEventsSubscribeResponse.OK: self._is_active = True LOGGER.info('Subscription with response {}'.format( sub_response.status)) else: LOGGER.error('Could not Subscribe to event') raise SubscriberError()
def listen_to_event(self): self._stream.wait_for_ready() # Step 1: Construct a Subscription block_sub = EventSubscription(event_type='sawtooth/block-commit') # Step 2: Submit the Event Subscription request = ClientEventsSubscribeRequest(subscriptions=[block_sub]) response_future = self._stream.send( Message.CLIENT_EVENTS_SUBSCRIBE_REQUEST, request.SerializeToString()) response = ClientEventsSubscribeResponse() response.ParseFromString(response_future.result().content) # Listen for events in an infinite loop LOGGER.warning("Listening to events.") while True: msg = self._stream.receive() event_list = EventList() event_list.ParseFromString(msg.result().content) for handler in self._event_handlers: handler(event_list.events)
async def subscribe_events(self, web_sock, last_known_block_id=None): # Setup a connection to the validator LOGGER.debug(f"Subscription started") request = ClientEventsSubscribeRequest( subscriptions=self._make_subscriptions(), last_known_block_ids=[last_known_block_id] if last_known_block_id else []).SerializeToString() # Construct the message wrapper correlation_id = generate_random_key( ) # This must be unique for all in-process requests msg = Message(correlation_id=correlation_id, message_type=Message.CLIENT_EVENTS_SUBSCRIBE_REQUEST, content=request) # Send the request LOGGER.debug(f"Sending subscription request.") await self._loop.run_in_executor( None, lambda: self._socket.send_multipart([msg.SerializeToString()])) LOGGER.debug(f"Subscription request is sent") msg = await self._event_queue[Message.CLIENT_EVENTS_SUBSCRIBE_RESPONSE ].get() LOGGER.info(f"message type {msg.message_type}") # Validate the response type if msg.message_type != Message.CLIENT_EVENTS_SUBSCRIBE_RESPONSE: LOGGER.error(f"Skip unexpected message type") return # Parse the response response = ClientEventsSubscribeResponse() response.ParseFromString(msg.content) # Validate the response status if response.status != ClientEventsSubscribeResponse.OK: if response.status == ClientEventsSubscribeResponse.UNKNOWN_BLOCK: raise SocketException( web_sock, Status.UNKNOWN_BLOCK, f"Uknown block in: {last_known_block_id}") raise SocketException( web_sock, 0, "Subscription failed: Couldn't send multipart") LOGGER.debug(f"Successfully subscribed")
def set_up_zmq_subscription(): """ This sends a subscription request to ZMQ. See: https://sawtooth.hyperledger.org/docs/core/ releases/latest/app_developers_guide/zmq_event_subscription.html """ subscription = EventSubscription( event_type="sawtooth/state-delta", filters=[ EventFilter( key="address", match_string="b89bcb.*", filter_type=EventFilter.REGEX_ANY) ]) request = ClientEventsSubscribeRequest( subscriptions=[subscription] ).SerializeToString() correlation_id = "123" # This must be unique for all in-process requests msg = Message( correlation_id=correlation_id, message_type=Message.MessageType.CLIENT_EVENTS_SUBSCRIBE_REQUEST, content=request ) socket.send_multipart([msg.SerializeToString()]) resp = socket.recv_multipart()[-1] msg = Message() msg.ParseFromString(resp) if msg.message_type != \ Message.MessageType.CLIENT_EVENTS_SUBSCRIBE_RESPONSE: print("Unexpected message type") exit(1) response = ClientEventsSubscribeResponse() response.ParseFromString(msg.content) if response.status != ClientEventsSubscribeResponse.OK: print("Subscription failed: {}".format(response.response_message)) exit(1) LOGGER.debug("Setting up ZMQ subscription successful")
def subscribe(self, event_name: str, is_write_to_file=False, file_name='certificate.pem'): subscription = EventSubscription(event_type="ca_1/{}".format(event_name)) # Setup a connection to the validator ctx = zmq.Context() socket = ctx.socket(zmq.DEALER) socket.connect('tcp://127.0.0.1:4004') # Construct the request request = ClientEventsSubscribeRequest( subscriptions=[subscription]).SerializeToString() # Construct the message wrapper correlation_id = "123" # This must be unique for all in-process requests msg = Message( correlation_id=correlation_id, message_type=Message.CLIENT_EVENTS_SUBSCRIBE_REQUEST, content=request) # Send the request socket.send_multipart([msg.SerializeToString()]) # Receive the response resp = socket.recv_multipart()[-1] # Parse the message wrapper msg = Message() msg.ParseFromString(resp) # Validate the response type if msg.message_type != Message.CLIENT_EVENTS_SUBSCRIBE_RESPONSE: print("Unexpected message type") return # Parse the response response = ClientEventsSubscribeResponse() response.ParseFromString(msg.content) # Validate the response status if response.status != ClientEventsSubscribeResponse.OK: print("Subscription failed: {}".format(response.response_message)) return resp = socket.recv_multipart()[-1] # Parse the message wrapper msg = Message() msg.ParseFromString(resp) # Validate the response type if msg.message_type != Message.CLIENT_EVENTS: print("Unexpected message type") return # Parse the response events = EventList() events.ParseFromString(msg.content) for event in events.events: if event.data is not None: if is_write_to_file: write_to_file(file_name, event.data) else: print(event.data) # Construct the request request = ClientEventsUnsubscribeRequest().SerializeToString() # Construct the message wrapper correlation_id = "124" # This must be unique for all in-process requests msg = Message( correlation_id=correlation_id, message_type=Message.CLIENT_EVENTS_UNSUBSCRIBE_REQUEST, content=request) # Send the request socket.send_multipart([msg.SerializeToString()]) # Receive the response resp = socket.recv_multipart()[-1] # Parse the message wrapper msg = Message() msg.ParseFromString(resp) # Validate the response type if msg.message_type != Message.CLIENT_EVENTS_UNSUBSCRIBE_RESPONSE: print("Unexpected message type") # Parse the response response = ClientEventsUnsubscribeResponse() response.ParseFromString(msg.content) # Validate the response status if response.status != ClientEventsUnsubscribeResponse.OK: print("Unsubscription failed: {}".format(response.response_message)) # Close the connection to the validator socket.close()
def subscribe_event(): """ A custom management command to store block information of each block data by event subscription. this command is calling from docker-compose file """ logger.info("event function start..") # Setup a connection to the validator ctx = zmq.Context() socket = ctx.socket(zmq.DEALER) socket.connect(validator_url) # -------------------------------# # Submit the Event Subscription # # -------------------------------# # subscribe both both "block commit" and "state-delta" event block_sub = EventSubscription(event_type='sawtooth/block-commit') delta_sub = EventSubscription( event_type='sawtooth/state-delta', filters=[ EventFilter(key='address', match_string='^{}.*'.format(NAMESPACE), filter_type=EventFilter.REGEX_ANY) ]) # Construct the request request = ClientEventsSubscribeRequest( subscriptions=[block_sub, delta_sub]).SerializeToString() # Construct the message wrapper correlation_id = "123" # This must be unique for all in-process requests msg = Message(correlation_id=correlation_id, message_type=Message.CLIENT_EVENTS_SUBSCRIBE_REQUEST, content=request) # Send the request socket.send_multipart([msg.SerializeToString()]) # # -------------------------------# # Receive the response # # -------------------------------# resp = socket.recv_multipart()[-1] # Parse the message wrapper msg = Message() msg.ParseFromString(resp) # Validate the response type if msg.message_type != Message.CLIENT_EVENTS_SUBSCRIBE_RESPONSE: logger.error("Unexpected message type") return # Parse the response response = ClientEventsSubscribeResponse() response.ParseFromString(msg.content) # Validate the response status if response.status != ClientEventsSubscribeResponse.OK: return while True: resp = socket.recv_multipart()[-1] # Parse the message wrapper msg = Message() msg.ParseFromString(resp) # Validate the response type if msg.message_type != Message.CLIENT_EVENTS: return # Parse the response events = EventList() events.ParseFromString(msg.content) block_info = {"address": []} event_data = MessageToDict(events) events_list = event_data["events"] for event in events_list: attributes = event["attributes"] for attr in attributes: key = attr["key"] value = attr["value"] if key == 'address': block_info["address"].append(value) else: block_info[key] = value address_list = block_info["address"] for address in address_list: BlockInfo.objects.create( block_num=block_info["block_num"], block_id=block_info["block_id"], state_root_hash=block_info["state_root_hash"], previous_block_id=block_info["previous_block_id"], address=address, ) logger.info("blockinfo subscription created..")
def _create_subscribe_request(cls, event_types, last_known_block_ids): return ClientEventsSubscribeRequest( subscriptions=cls._create_subscriptions(event_types), last_known_block_ids=last_known_block_ids)