def test_batch_by_id_responder_handler(self): """ Test that the BatchByBatchIdResponderHandler correctly broadcasts a received request that the Responder cannot respond to, or sends a GossipBatchResponse back to the connection_id the handler received the request from. """ # The completer does not have the requested batch message = network_pb2.GossipBatchByBatchIdRequest( id="abc", nonce="1") self.batch_request_handler.handle( "Connection_1", message.SerializeToString()) # If we cannot respond to the request broadcast batch request and add # to pending request self.assert_message_was_broadcasted( message, validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST) self.assert_request_pending( requested_id="abc", connection_id="Connection_1") self.assert_message_not_sent(connection_id="Connection_1") # Add the batch to the completer and resend the BatchByBatchIdRequest message = network_pb2.GossipBatchByBatchIdRequest( id="abc", nonce="2") batch = batch_pb2.Batch(header_signature="abc") self.completer.add_batch(batch) self.batch_request_handler.handle( "Connection_1", message.SerializeToString()) # Check that the a Batch Response was sent back to "Connection_1" self.assert_message_sent( connection_id="Connection_1", message_type=validator_pb2.Message.GOSSIP_BATCH_RESPONSE )
def do_batch_by_id_responder_handler(): before_message = network_pb2.GossipBatchByBatchIdRequest( id="abc", nonce="1", time_to_live=1) after_message = network_pb2.GossipBatchByBatchIdRequest(id="abc", nonce="1", time_to_live=0) testResponder.batch_request_handler.handle( "Connection_1", before_message.SerializeToString()) # If we cannot respond to the request broadcast batch request and add # to pending request testResponder.assert_message_was_broadcasted( after_message, validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST) testResponder.assert_request_pending(requested_id="abc", connection_id="Connection_1") testResponder.assert_message_not_sent(connection_id="Connection_1") # Add the batch to the completer and resend the BatchByBatchIdRequest message = network_pb2.GossipBatchByBatchIdRequest(id="abc", nonce="2", time_to_live=1) batch = batch_pb2.Batch(header_signature="abc") testResponder.completer.add_batch(batch) testResponder.batch_request_handler.handle("Connection_1", message.SerializeToString()) # Check that the a Batch Response was sent back to "Connection_1" testResponder.assert_message_sent( connection_id="Connection_1", message_type=validator_pb2.Message.GOSSIP_BATCH_RESPONSE)
def test_batch_by_id_responder_handler_requested(): """ Test that the BatchByBatchIdResponderHandler correctly broadcasts a received request that the Responder cannot respond to, and does not rebroadcast the same request again. If we have already recieved the request, do nothing. """ # The completer does not have the requested batch testResponder = TestResponder() before_message = network_pb2.GossipBatchByBatchIdRequest(id="abc", nonce="1", time_to_live=1) after_message = network_pb2.GossipBatchByBatchIdRequest(id="abc", nonce="1", time_to_live=0) testResponder.batch_request_handler.handle( "Connection_1", before_message.SerializeToString()) # If we cannot respond to the request broadcast batch request and add # to pending request testResponder.gossip.clear() # Message should be dropped since the same message has already been # handled testResponder.batch_request_handler.handle( "Connection_2", before_message.SerializeToString()) message = network_pb2.GossipBatchByBatchIdRequest(id="abc", nonce="2", time_to_live=1) testResponder.batch_request_handler.handle("Connection_2", message.SerializeToString())
def test_batch_by_id_responder_handler(): """ Test that the BatchByBatchIdResponderHandler correctly broadcasts a received request that the Responder cannot respond to, or sends a GossipBatchResponse back to the connection_id the handler received the request from. """ # The completer does not have the requested batch testResponder = TestResponder() before_message = network_pb2.GossipBatchByBatchIdRequest(id="abc", nonce="1", time_to_live=1) after_message = network_pb2.GossipBatchByBatchIdRequest(id="abc", nonce="1", time_to_live=0) testResponder.batch_request_handler.handle( "Connection_1", before_message.SerializeToString()) # Add the batch to the completer and resend the BatchByBatchIdRequest message = network_pb2.GossipBatchByBatchIdRequest(id="abc", nonce="2", time_to_live=1) batch = batch_pb2.Batch(header_signature="abc") testResponder.completer.add_batch(batch) testResponder.batch_request_handler.handle("Connection_1", message.SerializeToString())
def test_batch_by_id_responder_handler_requested(self): """ Test that the BatchByBatchIdResponderHandler correctly broadcasts a received request that the Responder cannot respond to, and does not rebroadcast the same request again. If we have already recieved the request, do nothing. """ # The completer does not have the requested batch before_message = network_pb2.GossipBatchByBatchIdRequest( id="abc", nonce="1", time_to_live=1) after_message = network_pb2.GossipBatchByBatchIdRequest(id="abc", nonce="1", time_to_live=0) self.batch_request_handler.handle("Connection_1", before_message.SerializeToString()) # If we cannot respond to the request broadcast batch request and add # to pending request self.assert_message_was_broadcasted( after_message, validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST) self.assert_request_pending(requested_id="abc", connection_id="Connection_1") self.assert_message_not_sent(connection_id="Connection_1") self.gossip.clear() # Message should be dropped since the same message has already been # handled self.batch_request_handler.handle("Connection_2", before_message.SerializeToString()) self.assert_message_was_not_broadcasted( before_message, validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST) self.assert_request_not_pending(requested_id="abc", connection_id="Connection_2") message = network_pb2.GossipBatchByBatchIdRequest(id="abc", nonce="2", time_to_live=1) self.batch_request_handler.handle("Connection_2", message.SerializeToString()) self.assert_message_was_not_broadcasted( message, validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST) self.assert_request_pending(requested_id="abc", connection_id="Connection_2") self.assert_message_not_sent(connection_id="Connection_2")
def handle(self, connection_id, message_content): batch_request_message = network_pb2.GossipBatchByBatchIdRequest() batch_request_message.ParseFromString(message_content) batch = None batch = self._responder.check_for_batch(batch_request_message.id) node_id = batch_request_message.node_id if batch is None: # No batch found, broadcast original message to other peers # and add to pending requests self._responder.add_request(batch_request_message.id, connection_id) self._gossip.broadcast( batch_request_message, validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST, exclude=[connection_id]) else: 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 test_responder_batch_response_handler(): """ Test that the ResponderBatchResponseHandler, after receiving a Batch Response, checks to see if the responder has any pending request for that batch and forwards the response on to the connection_id that had requested it. """ # The Responder does not have any pending requests for block "ABC" testResponder = TestResponder() batch = batch_pb2.Batch(header_signature="abc") response_message = network_pb2.GossipBatchResponse( content=batch.SerializeToString()) testResponder.batch_response_handler.handle( "Connection_1", (batch, response_message.SerializeToString())) # request queue. request_message = \ network_pb2.GossipBatchByBatchIdRequest(id="abc", time_to_live=1) testResponder.batch_request_handler.handle( "Connection_2", request_message.SerializeToString()) # Handle the the BatchResponse Message. Since Connection_2 had # requested the batch but it could not be fulfilled at that time of the # request the received BatchResponse is forwarded to Connection_2 testResponder.batch_response_handler.handle( "Connection_1", (batch, response_message.SerializeToString()))
def do_batch_by_id_responder_handler_requested(): before_message = network_pb2.GossipBatchByBatchIdRequest( id="abc", nonce="1", time_to_live=1) after_message = network_pb2.GossipBatchByBatchIdRequest(id="abc", nonce="1", time_to_live=0) testResponder.batch_request_handler.handle( "Connection_1", before_message.SerializeToString()) # If we cannot respond to the request broadcast batch request and add # to pending request testResponder.assert_message_was_broadcasted( after_message, validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST) testResponder.assert_request_pending(requested_id="abc", connection_id="Connection_1") testResponder.assert_message_not_sent(connection_id="Connection_1") testResponder.gossip.clear() # Message should be dropped since the same message has already been # handled testResponder.batch_request_handler.handle( "Connection_2", before_message.SerializeToString()) testResponder.assert_message_was_not_broadcasted( before_message, validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST) testResponder.assert_request_not_pending(requested_id="abc", connection_id="Connection_2") message = network_pb2.GossipBatchByBatchIdRequest(id="abc", nonce="2", time_to_live=1) testResponder.batch_request_handler.handle("Connection_2", message.SerializeToString()) testResponder.assert_message_was_not_broadcasted( message, validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST) testResponder.assert_request_pending(requested_id="abc", connection_id="Connection_2") testResponder.assert_message_not_sent(connection_id="Connection_2")
def handle(self, connection_id, message_content): batch_request_message = network_pb2.GossipBatchByBatchIdRequest() batch_request_message.ParseFromString(message_content) if batch_request_message.nonce in self._seen_requests: LOGGER.debug("Received repeat GossipBatchByBatchIdRequest from %s", connection_id) ack = network_pb2.NetworkAcknowledgement() ack.status = ack.OK return HandlerResult( HandlerStatus.RETURN, message_out=ack, message_type=validator_pb2.Message.NETWORK_ACK) self._seen_requests[batch_request_message.nonce] = \ batch_request_message.id batch = None batch = self._responder.check_for_batch(batch_request_message.id) node_id = batch_request_message.node_id if batch is None: # No batch found, broadcast original message to other peers # and add to pending requests if not self._responder.already_requested(batch_request_message.id): self._gossip.broadcast( batch_request_message, validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST, exclude=[connection_id]) else: LOGGER.debug("Batch %s has already been requested", batch_request_message.id) self._responder.add_request(batch_request_message.id, connection_id) else: 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) ack = network_pb2.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): batch_request_message = network_pb2.GossipBatchByBatchIdRequest() batch_request_message.ParseFromString(message_content) if batch_request_message.nonce in self._seen_requests: LOGGER.debug("Received repeat GossipBatchByBatchIdRequest from %s", connection_id) return HandlerResult(HandlerStatus.DROP) batch = None batch = self._responder.check_for_batch(batch_request_message.id) if batch is None: # No batch found, broadcast original message to other peers # and add to pending requests if not self._responder.already_requested(batch_request_message.id): if batch_request_message.time_to_live > 0: time_to_live = batch_request_message.time_to_live batch_request_message.time_to_live = time_to_live - 1 self._gossip.broadcast( batch_request_message, validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST, exclude=[connection_id]) self._seen_requests[batch_request_message.nonce] = \ batch_request_message.id self._responder.add_request(batch_request_message.id, connection_id) else: LOGGER.debug("Batch %s has already been requested", batch_request_message.id) self._responder.add_request(batch_request_message.id, connection_id) else: LOGGER.debug("Responding to batch requests %s", batch.header_signature) batch_response = network_pb2.GossipBatchResponse( content=batch.SerializeToString(), ) self._gossip.send(validator_pb2.Message.GOSSIP_BATCH_RESPONSE, batch_response.SerializeToString(), connection_id) return HandlerResult(HandlerStatus.PASS)
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 test_responder_batch_response_handler(self): """ Test that the ResponderBatchResponseHandler, after receiving a Batch Response, checks to see if the responder has any pending request for that batch and forwards the response on to the connection_id that had requested it. """ # The Responder does not have any pending requests for block "ABC" batch = batch_pb2.Batch(header_signature="abc") response_message = network_pb2.GossipBatchResponse( content=batch.SerializeToString()) self.batch_response_handler.handle( "Connection_1", response_message.SerializeToString()) # ResponderBlockResponseHandler should not send any messages. self.assert_message_not_sent("Connection_1") self.assert_request_not_pending(requested_id="abc") # Handle a request message for batch "abc". This adds it to the pending # request queue. request_message = \ network_pb2.GossipBatchByBatchIdRequest(id="abc") self.batch_request_handler.handle( "Connection_2", request_message.SerializeToString()) self.assert_request_pending( requested_id="abc", connection_id="Connection_2") # Handle the the BatchResponse Message. Since Connection_2 had # requested the batch but it could not be fulfilled at that time of the # request the received BatchResponse is forwarded to Connection_2 self.batch_response_handler.handle( "Connection_1", response_message.SerializeToString()) self.assert_message_sent( connection_id="Connection_2", message_type=validator_pb2.Message.GOSSIP_BATCH_RESPONSE ) # The request for batch "abc" from "Connection_2" is no longer pending # it should be removed from the pending request cache. self.assert_request_not_pending(requested_id="abc")
def do_responder_batch_response_handler(): batch = batch_pb2.Batch(header_signature="abc") response_message = network_pb2.GossipBatchResponse( content=batch.SerializeToString()) testResponder.batch_response_handler.handle( "Connection_1", (batch, response_message.SerializeToString())) # ResponderBlockResponseHandler should not send any messages. testResponder.assert_message_not_sent("Connection_1") testResponder.assert_request_not_pending(requested_id="abc") # Handle a request message for batch "abc". This adds it to the pending # request queue. request_message = \ network_pb2.GossipBatchByBatchIdRequest(id="abc", time_to_live=1) testResponder.batch_request_handler.handle( "Connection_2", request_message.SerializeToString()) testResponder.assert_request_pending(requested_id="abc", connection_id="Connection_2") # Handle the the BatchResponse Message. Since Connection_2 had # requested the batch but it could not be fulfilled at that time of the # request the received BatchResponse is forwarded to Connection_2 testResponder.batch_response_handler.handle( "Connection_1", (batch, response_message.SerializeToString())) testResponder.assert_message_sent( connection_id="Connection_2", message_type=validator_pb2.Message.GOSSIP_BATCH_RESPONSE) # The request for batch "abc" from "Connection_2" is no longer pending # it should be removed from the pending request cache. testResponder.assert_request_not_pending(requested_id="abc")