def handle(self, connection_id, message_content): request = ClientEventsUnsubscribeRequest() request.ParseFromString(message_content) ack = ClientEventsUnsubscribeResponse() self._event_broadcaster.disable_subscriber(connection_id) self._event_broadcaster.remove_subscriber(connection_id) ack.status = ack.OK return HandlerResult(HandlerStatus.RETURN, message_out=ack, message_type=self._msg_type)
def _wrap_result(self, response): """Wraps child's response in a HandlerResult to be sent back to client. Args: response (enum or dict): Either an integer status enum, or a dict of attributes to be added to the protobuf response. """ if isinstance(response, int): response = self._wrap_response(response) return HandlerResult(status=HandlerStatus.RETURN, message_out=self._response_proto(**response), message_type=self._response_type)
def handle(self, connection_id, message_content): request = PeerUnregisterRequest() request.ParseFromString(message_content) LOGGER.debug("got peer unregister message " "from %s. sending ack", connection_id) self._gossip.unregister_peer(connection_id) ack = NetworkAcknowledgement() ack.status = ack.OK return HandlerResult( HandlerStatus.RETURN, message_out=ack, message_type=validator_pb2.Message.NETWORK_ACK)
def handle(self, connection_id, message_content): """ If an AuthorizationViolation is recieved, the connection has decided that this validator is no longer permitted to be connected. Remove the connection preemptively. """ LOGGER.warning("Received AuthorizationViolation from %s", connection_id) # Close the connection endpoint = self._network.connection_id_to_endpoint(connection_id) self._network.remove_connection(connection_id) self._gossip.remove_temp_endpoint(endpoint) return HandlerResult(HandlerStatus.DROP)
def handle(self, connection_id, message_content): message = DisconnectMessage() message.ParseFromString(message_content) LOGGER.debug("got disconnect message from %s. sending ack", connection_id) ack = NetworkAcknowledgement() ack.status = ack.OK self._network.remove_connection(connection_id) return HandlerResult(HandlerStatus.RETURN, message_out=ack, message_type=validator_pb2.Message.NETWORK_ACK)
def handle(self, connection_id, message_content): request = PingRequest() request.ParseFromString(message_content) #LOGGER.debug("PingHandler PingRequest %s(%s)",connection_id[:8],self._network.connection_id_to_endpoint(connection_id)) ack = PingResponse() if self._network.get_connection_status( connection_id) == ConnectionStatus.CONNECTED: if connection_id in self._last_message: del self._last_message[connection_id] """ Here we can ask SYNC with this peer -in case we have no sync yet """ #LOGGER.debug("PingRequest from CONNECTED %s(%s)",connection_id[:8],self._network.connection_id_to_endpoint(connection_id)) return HandlerResult( HandlerStatus.RETURN, message_out=ack, message_type=validator_pb2.Message.PING_RESPONSE) if connection_id in self._last_message: if time.time( ) - self._last_message[connection_id] < self._allowed_frequency: LOGGER.debug( "Too many Pings in %s seconds before authorization is complete: %s", self._allowed_frequency, connection_id) violation = AuthorizationViolation( violation=RoleType.Value("NETWORK")) return HandlerResult( HandlerStatus.RETURN_AND_CLOSE, message_out=violation, message_type=validator_pb2.Message.AUTHORIZATION_VIOLATION) self._last_message[connection_id] = time.time() return HandlerResult(HandlerStatus.RETURN, message_out=ack, message_type=validator_pb2.Message.PING_RESPONSE)
def handle(self, connection_id, message_content): block, message_content = message_content open_request = self._responder.get_request(block.header_signature) if open_request is None: return HandlerResult(status=HandlerStatus.PASS) for connection in open_request: LOGGER.debug("Responding to block request: Send %s to %s", block.header_signature, connection) try: self._gossip.send(validator_pb2.Message.GOSSIP_BLOCK_RESPONSE, message_content, connection) except ValueError: LOGGER.debug( "Can't send block response %s to closed " "connection %s", block.header_signature, connection) self._responder.remove_request(block.header_signature) return HandlerResult(HandlerStatus.PASS)
def handle(self, connection_id, message_content): # If this is the configured consensus engine, make it active. This is # necessary for setting the active engine when the configured engine is # changed to an engine that is not registered yet request = consensus_pb2.ConsensusRegisterRequest() try: request.ParseFromString(message_content) except DecodeError: LOGGER.exception("Unable to decode ConsensusRegisterRequest") return HandlerResult(status=HandlerResult.DROP) if request.additional_protocols is not None: additional_protocols = \ [(p.name, p.version) for p in request.additional_protocols] else: additional_protocols = [] self._proxy.activate_if_configured(request.name, request.version, additional_protocols) return HandlerResult(status=HandlerStatus.PASS)
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 handle(self, connection_id, message_content): if not self._can_accept(): if not self._applying_backpressure: self._applying_backpressure = True LOGGER.info( 'Applying back pressure on client submitted batches: ' 'current depth: %s, limit: %s', *self._queue_info()) response = ClientBatchSubmitResponse( status=ClientBatchSubmitResponse.QUEUE_FULL) return HandlerResult( status=HandlerStatus.RETURN, message_out=response, message_type=Message.CLIENT_BATCH_SUBMIT_RESPONSE) else: if self._applying_backpressure: self._applying_backpressure = False LOGGER.info( 'Ending back pressure on client submitted batches: ' 'current depth: %s, limit: %s', *self._queue_info()) return HandlerResult(status=HandlerStatus.PASS)
def handle(self, connection_id, message_content): """ If the connection wants to take on a role that requires a challenge to be signed, it will request the challenge by sending an AuthorizationChallengeRequest to the validator it wishes to connect to. The validator will send back a random payload that must be signed. If the connection has not sent a ConnectionRequest or the connection has already recieved an AuthorizationChallengeResponse, an AuthorizationViolation will be returned and the connection will be closed. """ if self._network.get_connection_status(connection_id) != \ ConnectionStatus.CONNECTION_REQUEST: LOGGER.debug("Connection's previous message was not a" " ConnectionRequest, Remove connection to %s", connection_id) violation = AuthorizationViolation( violation=RoleType.Value("NETWORK")) return HandlerResult( HandlerStatus.RETURN_AND_CLOSE, message_out=violation, message_type=validator_pb2.Message .AUTHORIZATION_VIOLATION) random_payload = os.urandom(PAYLOAD_LENGTH) self._challenge_payload_cache[connection_id] = random_payload auth_challenge_response = AuthorizationChallengeResponse( payload=random_payload) self._network.update_connection_status( connection_id, ConnectionStatus.AUTH_CHALLENGE_REQUEST) return HandlerResult( HandlerStatus.RETURN, message_out=auth_challenge_response, message_type=validator_pb2.Message. AUTHORIZATION_CHALLENGE_RESPONSE)
def handle(self, connection_id, message_content): request = PingRequest() request.ParseFromString(message_content) ack = PingResponse() if self._network.get_connection_status(connection_id) == \ ConnectionStatus.CONNECTED: if connection_id in self._last_message: del self._last_message[connection_id] return HandlerResult( HandlerStatus.RETURN, message_out=ack, message_type=validator_pb2.Message.PING_RESPONSE) if connection_id in self._last_message: ping_frequency = time.time() - self._last_message[connection_id] if ping_frequency < self._allowed_frequency: LOGGER.warning( "Too many Pings (%s) in %s seconds before " "authorization is complete: %s", ping_frequency, self._allowed_frequency, connection_id) violation = AuthorizationViolation( violation=RoleType.Value("NETWORK")) return HandlerResult( HandlerStatus.RETURN_AND_CLOSE, message_out=violation, message_type=validator_pb2.Message.AUTHORIZATION_VIOLATION) self._last_message[connection_id] = time.time() return HandlerResult(HandlerStatus.RETURN, message_out=ack, message_type=validator_pb2.Message.PING_RESPONSE)
def handle(self, connection_id, message_content): LOGGER.debug("ClientBatchSubmitBackpressureHandler:handle .. ") batch_header = BatchHeader() for batch in message_content.batches: batch_header.ParseFromString(batch.header) if batch_header.signer_public_key == self._whitelist_public_key: # There is a whitelisted batch, so allow it to continue return HandlerResult(status=HandlerStatus.PASS) batch_header.Clear() pending, limit = self._queue_info() if pending >= limit: if not self._applying_backpressure: self._applying_backpressure = True LOGGER.info( 'Applying back pressure on client submitted batches: ' 'current depth: %s, limit: %s', pending, limit) self._batches_rejected_count.inc() self._batches_rejected_gauge.set_value( self._batches_rejected_gauge.get_value() + 1) response = ClientBatchSubmitResponse( status=ClientBatchSubmitResponse.QUEUE_FULL) return HandlerResult( status=HandlerStatus.RETURN, message_out=response, message_type=Message.CLIENT_BATCH_SUBMIT_RESPONSE) if self._applying_backpressure: self._applying_backpressure = False self._batches_rejected_gauge.set_value(0) LOGGER.info( 'Ending back pressure on client submitted batches: ' 'current depth: %s, limit: %s', pending, limit) return HandlerResult(status=HandlerStatus.PASS)
def handle(self, connection_id, message_content): request = PingRequest() request.ParseFromString(message_content) ack = NetworkAcknowledgement() ack.status = ack.OK if self._network.get_connection_status(connection_id) == \ ConnectionStatus.CONNECTED: if connection_id in self._last_message: del self._last_message[connection_id] return HandlerResult( HandlerStatus.RETURN, message_out=ack, message_type=validator_pb2.Message.NETWORK_ACK) if connection_id in self._last_message: if time.time() - self._last_message[connection_id] < \ self._allowed_frequency: LOGGER.debug( "Too many Pings in %s seconds before" "authorization is complete: %s", self._allowed_frequency, connection_id) violation = AuthorizationViolation( violation=RoleType.Value("NETWORK")) return HandlerResult( HandlerStatus.RETURN_AND_CLOSE, message_out=violation, message_type=validator_pb2.Message.AUTHORIZATION_VIOLATION) self._last_message[connection_id] = time.time() return HandlerResult(HandlerStatus.RETURN, message_out=ack, message_type=validator_pb2.Message.NETWORK_ACK)
def handle(self, connection_id, message_content): request = GetPeersRequest() request.ParseFromString(message_content) LOGGER.debug("Got peers request message from %s", connection_id) self._gossip.send_peers(connection_id) ack = NetworkAcknowledgement() ack.status = ack.OK return HandlerResult(HandlerStatus.RETURN, message_out=ack, message_type=validator_pb2.Message.NETWORK_ACK)
def handle(self, identity, message_content): get_request = state_context_pb2.TpStateGetRequest() get_request.ParseFromString(message_content) return_values = self._context_manager.get(get_request.context_id, get_request.addresses) return_list = return_values if return_values is not None else [] LOGGER.debug("GET: %s", return_list) entry_list = [ state_context_pb2.Entry(address=a, data=d) for a, d in return_list ] response = state_context_pb2.TpStateGetResponse() response.entries.extend(entry_list) return HandlerResult(HandlerStatus.RETURN, response, validator_pb2.Message.TP_STATE_GET_RESPONSE)
def handle(self, connection_id, message_content): batch_request_message = network_pb2.GossipBatchByTransactionIdRequest() batch_request_message.ParseFromString(message_content) node_id = batch_request_message.node_id batch = None batches = [] unfound_txn_ids = [] for txn_id in batch_request_message.ids: batch = self._responder.check_for_batch_by_transaction(txn_id) # The txn_id was not found. if batch is None: unfound_txn_ids.append(txn_id) # Check to see if a previous txn was in the same batch. elif batch not in batches: batches.append(batch) batch = None if batches == []: for txn_id in batch_request_message.ids: self._responder.add_request(txn_id, connection_id) self._gossip.broadcast( batch_request_message, validator_pb2.Message.GOSSIP_BATCH_BY_TRANSACTION_ID_REQUEST) elif unfound_txn_ids != []: new_request = network_pb2.GossipBatchByTransactionIdRequest() new_request.ids.extend(unfound_txn_ids) new_request.node_id = batch_request_message.node_id for txn_id in unfound_txn_ids: self._responder.add_request(txn_id, connection_id) self._gossip.broadcast( new_request, validator_pb2.Message.GOSSIP_BATCH_BY_TRANSACTION_ID_REQUEST) if batches != []: for batch in batches: LOGGER.debug("Responding to batch requests %s", batch.header_signature) batch_response = network_pb2.GossipBatchResponse( content=batch.SerializeToString(), node_id=node_id) self._gossip.send(validator_pb2.Message.GOSSIP_BATCH_RESPONSE, batch_response.SerializeToString(), connection_id) return HandlerResult(status=HandlerStatus.PASS)
def handle(self, connection_id, message_content): gossip_message = network_pb2.GossipMessage() gossip_message.ParseFromString(message_content) if gossip_message.content_type == network_pb2.GossipMessage.BLOCK: block = Block() block.ParseFromString(gossip_message.content) if not is_valid_block(block): LOGGER.debug("block's batches structure is invalid: %s", block.header_signature) return HandlerResult(status=HandlerStatus.DROP) return HandlerResult(status=HandlerStatus.PASS) elif gossip_message.content_type == network_pb2.GossipMessage.BATCH: batch = Batch() batch.ParseFromString(gossip_message.content) if not is_valid_batch(batch): LOGGER.debug("batch structure is invalid: %s", batch.header_signature) return HandlerResult(status=HandlerStatus.DROP) return HandlerResult(status=HandlerStatus.PASS) return HandlerResult(status=HandlerStatus.PASS)
def handle(self, connection_id, message_content): request = self._request_class() response = self._response_class() response.status = response.OK try: request.ParseFromString(message_content) except DecodeError: response.status = response.BAD_REQUEST else: self.handle_request(request, response) return HandlerResult(status=self._handler_status, message_out=response, message_type=self._response_type)
def handle(self, connection_id, message_content): delete_request = state_context_pb2.TpStateDeleteRequest() delete_request.ParseFromString(message_content) try: return_values = self._context_manager.delete( delete_request.context_id, list(delete_request.addresses)) except AuthorizationException: response = \ state_context_pb2.TpStateDeleteResponse( status=state_context_pb2. TpStateDeleteResponse.AUTHORIZATION_ERROR) return HandlerResult( HandlerStatus.RETURN, response, validator_pb2.Message.TP_STATE_DEL_RESPONSE) LOGGER.debug("DELETE: %s", return_values) response = state_context_pb2.TpStateDeleteResponse( addresses=delete_request.addresses, status=state_context_pb2.TpStateDeleteResponse.OK) return HandlerResult( HandlerStatus.RETURN, response, validator_pb2.Message.TP_STATE_DEL_RESPONSE)
def handle(self, identity, message_content): gossip_message = GossipMessage() gossip_message.ParseFromString(message_content) if gossip_message.content_type == "BATCH": batch = Batch() batch.ParseFromString(gossip_message.content) self._gossip.broadcast_batch(batch) elif gossip_message.content_type == "BLOCK": block = Block() block.ParseFromString(gossip_message.content) self._gossip.broadcast_block(block) else: LOGGER.info("received %s, not BATCH or BLOCK", gossip_message.content_type) return HandlerResult(status=HandlerStatus.PASS)
def handle(self, connection_id, message_content): get_request = state_context_pb2.TpStateGetRequest() get_request.ParseFromString(message_content) try: return_values = self._context_manager.get( get_request.context_id, list(get_request.addresses)) except AuthorizationException: response = \ state_context_pb2.TpStateGetResponse( status=state_context_pb2. TpStateGetResponse.AUTHORIZATION_ERROR) return HandlerResult(HandlerStatus.RETURN, response, validator_pb2.Message.TP_STATE_GET_RESPONSE) return_list = return_values if return_values is not None else [] LOGGER.debug("GET: %s", return_list) entry_list = [ state_context_pb2.Entry(address=a, data=d) for a, d in return_list ] response = state_context_pb2.TpStateGetResponse( status=state_context_pb2.TpStateGetResponse.OK) response.entries.extend(entry_list) return HandlerResult(HandlerStatus.RETURN, response, validator_pb2.Message.TP_STATE_GET_RESPONSE)
def handle(self, connection_id, message_content): request = RegisterStateDeltaSubscriberRequest() request.ParseFromString(message_content) ack = RegisterStateDeltaSubscriberResponse() try: self._delta_processor.add_subscriber(connection_id, request.last_known_block_ids, request.address_prefixes) ack.status = ack.OK except NoKnownBlockError: ack.status = ack.UNKNOWN_BLOCK return HandlerResult(HandlerStatus.RETURN, message_out=ack, message_type=self._msg_type)
def handle(self, connection_id, message_content): response = GetPeersResponse() response.ParseFromString(message_content) LOGGER.debug("got peers response message " "from %s. sending ack", connection_id) LOGGER.debug("PEERS RESPONSE ENDPOINTS: %s", response.peer_endpoints) self._gossip.add_candidate_peer_endpoints(response.peer_endpoints) ack = NetworkAcknowledgement() ack.status = ack.OK return HandlerResult(HandlerStatus.RETURN, message_out=ack, message_type=validator_pb2.Message.NETWORK_ACK)
def handle(self, connection_id, message_content): request = PeerRegisterRequest() request.ParseFromString(message_content) LOGGER.debug("Got peer register message from %s", connection_id) ack = NetworkAcknowledgement() try: self._gossip.register_peer(connection_id, request.endpoint) ack.status = ack.OK except PeeringException: ack.status = ack.ERROR return HandlerResult(HandlerStatus.RETURN, message_out=ack, message_type=validator_pb2.Message.NETWORK_ACK)
def handle(self, connection_id, message_content): request = processor_pb2.TpUnregisterRequest() request.ParseFromString(message_content) LOGGER.info("try to unregister all transaction processor " "capabilities for connection_id %s", connection_id) self._collection.remove(processor_identity=connection_id) ack = processor_pb2.TpUnregisterResponse() ack.status = ack.OK return HandlerResult( status=HandlerStatus.RETURN, message_out=ack, message_type=validator_pb2.Message.TP_UNREGISTER_RESPONSE)
def handle(self, identity, message_content): set_request = state_context_pb2.TpStateSetRequest() set_request.ParseFromString(message_content) set_values_list = [{e.address: e.data} for e in set_request.entries] return_value = self._context_manager.set(set_request.context_id, set_values_list) response = state_context_pb2.TpStateSetResponse() if return_value is True: address_list = [e.address for e in set_request.entries] LOGGER.debug("SET: %s", address_list) response.addresses.extend(address_list) else: LOGGER.debug("SET: No Values Set") response.addresses.extend([]) return HandlerResult(HandlerStatus.RETURN, response, validator_pb2.Message.TP_STATE_SET_RESPONSE)
def handle(self, connection_id, message_content): add_event_request = state_context_pb2.TpEventAddRequest() add_event_request.ParseFromString(message_content) success = self._context_manager.add_execution_event( add_event_request.context_id, add_event_request.event) ack = state_context_pb2.TpEventAddResponse() if success: ack.status = ack.OK else: ack.status = ack.ERROR return HandlerResult( status=HandlerStatus.RETURN, message_out=ack, message_type=validator_pb2.Message.TP_EVENT_ADD_RESPONSE)
def handle(self, connection_id, message_content): gossip_message = network_pb2.GossipBatchByBatchIdRequest() gossip_message.ParseFromString(message_content) batch = None batch = self._responder.check_for_batch(gossip_message.id) if batch is None: self._gossip.broadcast( gossip_message, validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST) else: LOGGER.debug("Responding to batch requests %s", batch.header_signature) self._gossip.broadcast_batch(batch) return HandlerResult(status=HandlerStatus.PASS)
def handle(self, connection_id, message_content): add_receipt_data_request = state_context_pb2.TpReceiptAddDataRequest() add_receipt_data_request.ParseFromString(message_content) success = self._context_manager.add_execution_data( add_receipt_data_request.context_id, add_receipt_data_request.data) ack = state_context_pb2.TpReceiptAddDataResponse() if success: ack.status = ack.OK else: ack.status = ack.ERROR return HandlerResult( status=HandlerStatus.RETURN, message_out=ack, message_type=validator_pb2.Message.TP_RECEIPT_ADD_DATA_RESPONSE)