Ejemplo n.º 1
0
 def setUp(self):
     self.completer = MockCompleter()
     self.chain = MockChainController()
     self.publisher = MockPublisher()
     self.handler = GossipMessageDuplicateHandler(self.completer,
                                                  self.chain.has_block,
                                                  self.publisher.has_batch)
Ejemplo n.º 2
0
class TestDuplicateHandler(unittest.TestCase):
    def setUp(self):
        self.completer = MockCompleter()
        self.chain = MockChainController()
        self.publisher = MockPublisher()
        self.handler = GossipMessageDuplicateHandler()

    def test_no_block(self):
        """
        Test that if the block has not been received recently,
        the gossip message is passed.
        """
        block = Block(header_signature="Block1")
        handler_status = self.handler.handle("connection_id",
                                             (block, GossipMessage.BLOCK, 2))
        self.assertEqual(handler_status.status, HandlerStatus.PASS)

    def test_no_batch(self):
        """
        Test that if the batch has not been received recently,
        the gossip message is passed.
        """
        batch = Batch(header_signature="Batch1")
        handler_status = self.handler.handle("connection_id",
                                             (batch, GossipMessage.BATCH, 2))
        self.assertEqual(handler_status.status, HandlerStatus.PASS)

    def test_recent_block(self):
        """
        Test that if the block has been received recently,
        the gossip message is dropped.
        """
        block = Block(header_signature="Block1")
        handler_status = self.handler.handle("connection_id",
                                             (block, GossipMessage.BLOCK, 2))
        handler_status = self.handler.handle("connection_id",
                                             (block, GossipMessage.BLOCK, 2))
        self.assertEqual(handler_status.status, HandlerStatus.DROP)

    def test_recent_batch(self):
        """
        Test that if the batch has been received recently,
        the gossip message is dropped.
        """
        batch = Batch(header_signature="Batch1")
        handler_status = self.handler.handle("connection_id",
                                             (batch, GossipMessage.BATCH, 2))
        handler_status = self.handler.handle("connection_id",
                                             (batch, GossipMessage.BATCH, 2))
        self.assertEqual(handler_status.status, HandlerStatus.DROP)
Ejemplo n.º 3
0
def add(
    dispatcher,
    interconnect,
    gossip,
    completer,
    responder,
    thread_pool,
    sig_pool,
    has_block,
    has_batch,
    permission_verifier,
    consensus_notifier,
):

    # -- Basic Networking -- #
    dispatcher.add_handler(validator_pb2.Message.PING_REQUEST,
                           PingRequestHandler(network=interconnect),
                           thread_pool,
                           priority=Priority.HIGH)

    dispatcher.add_handler(validator_pb2.Message.PING_RESPONSE,
                           PingResponseHandler(), thread_pool)

    dispatcher.add_handler(validator_pb2.Message.NETWORK_CONNECT,
                           ConnectHandler(network=interconnect), thread_pool)

    dispatcher.add_handler(validator_pb2.Message.NETWORK_DISCONNECT,
                           DisconnectHandler(network=interconnect),
                           thread_pool)

    # -- Authorization -- #
    dispatcher.set_message_priority(
        validator_pb2.Message.AUTHORIZATION_CONNECTION_RESPONSE,
        Priority.MEDIUM)

    dispatcher.add_handler(
        validator_pb2.Message.AUTHORIZATION_VIOLATION,
        AuthorizationViolationHandler(network=interconnect, gossip=gossip),
        thread_pool)

    dispatcher.add_handler(validator_pb2.Message.AUTHORIZATION_TRUST_REQUEST,
                           AuthorizationTrustRequestHandler(
                               network=interconnect,
                               permission_verifier=permission_verifier,
                               gossip=gossip),
                           thread_pool,
                           priority=Priority.MEDIUM)

    challenge_request_handler = AuthorizationChallengeRequestHandler(
        network=interconnect)
    dispatcher.add_handler(
        validator_pb2.Message.AUTHORIZATION_CHALLENGE_REQUEST,
        challenge_request_handler,
        thread_pool,
        priority=Priority.MEDIUM)

    dispatcher.add_handler(
        validator_pb2.Message.AUTHORIZATION_CHALLENGE_SUBMIT,
        AuthorizationChallengeSubmitHandler(
            network=interconnect,
            permission_verifier=permission_verifier,
            gossip=gossip,
            cache=challenge_request_handler.get_challenge_payload_cache()),
        thread_pool,
        priority=Priority.MEDIUM)

    # -- Gossip -- #
    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_GET_PEERS_REQUEST,
        NetworkPermissionHandler(network=interconnect,
                                 permission_verifier=permission_verifier,
                                 gossip=gossip), thread_pool)

    dispatcher.add_handler(validator_pb2.Message.GOSSIP_GET_PEERS_REQUEST,
                           GetPeersRequestHandler(gossip=gossip), thread_pool)

    dispatcher.set_message_priority(
        validator_pb2.Message.GOSSIP_GET_PEERS_REQUEST, Priority.MEDIUM)

    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_GET_PEERS_RESPONSE,
        NetworkPermissionHandler(network=interconnect,
                                 permission_verifier=permission_verifier,
                                 gossip=gossip), thread_pool)

    dispatcher.add_handler(validator_pb2.Message.GOSSIP_GET_PEERS_RESPONSE,
                           GetPeersResponseHandler(gossip=gossip), thread_pool)

    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_REGISTER,
        NetworkPermissionHandler(network=interconnect,
                                 permission_verifier=permission_verifier,
                                 gossip=gossip), thread_pool)

    dispatcher.add_handler(validator_pb2.Message.GOSSIP_REGISTER,
                           PeerRegisterHandler(gossip=gossip), thread_pool)

    dispatcher.set_message_priority(validator_pb2.Message.GOSSIP_REGISTER,
                                    Priority.MEDIUM)

    dispatcher.add_handler(validator_pb2.Message.GOSSIP_UNREGISTER,
                           PeerUnregisterHandler(gossip=gossip), thread_pool)

    # GOSSIP_MESSAGE ) Check if this is a block and if we already have it

    dispatcher.set_preprocessor(validator_pb2.Message.GOSSIP_MESSAGE,
                                gossip_message_preprocessor, thread_pool)

    dispatcher.add_handler(validator_pb2.Message.GOSSIP_MESSAGE,
                           GossipMessageDuplicateHandler(), thread_pool)

    # GOSSIP_MESSAGE ) Verify Network Permissions
    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_MESSAGE,
        NetworkPermissionHandler(network=interconnect,
                                 permission_verifier=permission_verifier,
                                 gossip=gossip), thread_pool)

    # GOSSIP_MESSAGE ) Verifies signature
    dispatcher.add_handler(validator_pb2.Message.GOSSIP_MESSAGE,
                           signature_verifier.GossipMessageSignatureVerifier(),
                           sig_pool)

    # GOSSIP_MESSAGE ) Verifies batch structure
    dispatcher.add_handler(validator_pb2.Message.GOSSIP_MESSAGE,
                           structure_verifier.GossipHandlerStructureVerifier(),
                           thread_pool)

    # GOSSIP_MESSAGE ) Verifies that the node is allowed to publish a
    # block
    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_MESSAGE,
        NetworkConsensusPermissionHandler(
            network=interconnect,
            permission_verifier=permission_verifier,
            gossip=gossip), thread_pool)

    # GOSSIP_MESSAGE ) Determines if this is a consensus message and notifies
    # the consensus engine if it is
    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_MESSAGE,
        GossipConsensusHandler(gossip=gossip, notifier=consensus_notifier),
        thread_pool)

    # GOSSIP_MESSAGE ) Determines if we should broadcast the
    # message to our peers. It is important that this occur prior
    # to the sending of the message to the completer, as this step
    # relies on whether the  gossip message has previously been
    # seen by the validator to determine whether or not forwarding
    # should occur
    dispatcher.add_handler(validator_pb2.Message.GOSSIP_MESSAGE,
                           GossipBroadcastHandler(gossip=gossip), thread_pool)

    # GOSSIP_MESSAGE ) Send message to completer
    dispatcher.add_handler(validator_pb2.Message.GOSSIP_MESSAGE,
                           CompleterGossipHandler(completer), thread_pool)

    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_BLOCK_REQUEST,
        NetworkPermissionHandler(network=interconnect,
                                 permission_verifier=permission_verifier,
                                 gossip=gossip), thread_pool)

    dispatcher.add_handler(validator_pb2.Message.GOSSIP_BLOCK_REQUEST,
                           BlockResponderHandler(responder, gossip),
                           thread_pool)

    dispatcher.set_preprocessor(validator_pb2.Message.GOSSIP_BLOCK_RESPONSE,
                                gossip_block_response_preprocessor,
                                thread_pool)

    # GOSSIP_BLOCK_RESPONSE 1) Check for duplicate responses
    dispatcher.add_handler(validator_pb2.Message.GOSSIP_BLOCK_RESPONSE,
                           GossipBlockResponseHandler(completer, responder),
                           thread_pool)

    # GOSSIP_MESSAGE 2) Verify Network Permissions
    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_BLOCK_RESPONSE,
        NetworkPermissionHandler(network=interconnect,
                                 permission_verifier=permission_verifier,
                                 gossip=gossip), thread_pool)

    # GOSSIP_BLOCK_RESPONSE 3) Verifies signature
    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_BLOCK_RESPONSE,
        signature_verifier.GossipBlockResponseSignatureVerifier(), sig_pool)

    # GOSSIP_BLOCK_RESPONSE 4) Check batch structure
    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_BLOCK_RESPONSE,
        structure_verifier.GossipBlockResponseStructureVerifier(), thread_pool)

    # GOSSIP_BLOCK_RESPONSE 5) Send message to completer
    dispatcher.add_handler(validator_pb2.Message.GOSSIP_BLOCK_RESPONSE,
                           CompleterGossipBlockResponseHandler(completer),
                           thread_pool)

    dispatcher.add_handler(validator_pb2.Message.GOSSIP_BLOCK_RESPONSE,
                           ResponderBlockResponseHandler(responder, gossip),
                           thread_pool)

    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST,
        NetworkPermissionHandler(network=interconnect,
                                 permission_verifier=permission_verifier,
                                 gossip=gossip), thread_pool)

    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST,
        BatchByBatchIdResponderHandler(responder, gossip), thread_pool)

    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_BATCH_BY_TRANSACTION_ID_REQUEST,
        NetworkPermissionHandler(network=interconnect,
                                 permission_verifier=permission_verifier,
                                 gossip=gossip), thread_pool)

    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_BATCH_BY_TRANSACTION_ID_REQUEST,
        BatchByTransactionIdResponderHandler(responder, gossip), thread_pool)

    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
        NetworkPermissionHandler(network=interconnect,
                                 permission_verifier=permission_verifier,
                                 gossip=gossip), thread_pool)

    dispatcher.set_preprocessor(validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
                                gossip_batch_response_preprocessor,
                                thread_pool)

    # GOSSIP_BATCH_RESPONSE 1) Check for duplicate responses
    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
        GossipBatchResponseHandler(completer, responder, has_batch),
        thread_pool)

    # GOSSIP_BATCH_RESPONSE 2) Verifies signature
    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
        signature_verifier.GossipBatchResponseSignatureVerifier(), sig_pool)

    # GOSSIP_BATCH_RESPONSE 3) Check batch structure
    dispatcher.add_handler(
        validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
        structure_verifier.GossipBatchResponseStructureVerifier(), thread_pool)

    # GOSSIP_BATCH_RESPONSE 4) Send message to completer
    dispatcher.add_handler(validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
                           CompleterGossipBatchResponseHandler(completer),
                           thread_pool)

    dispatcher.add_handler(validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
                           ResponderBatchResponseHandler(responder, gossip),
                           thread_pool)
Ejemplo n.º 4
0
class TestDuplicateHandler(unittest.TestCase):
    def setUp(self):
        self.completer = MockCompleter()
        self.chain = MockChainController()
        self.publisher = MockPublisher()
        self.handler = GossipMessageDuplicateHandler(self.completer,
                                                     self.chain.has_block,
                                                     self.publisher.has_batch)

    def test_no_block(self):
        """
        Test that if the block does not exist yet in the completer or the
        chain controller, the gossip message is passed.
        """
        block = Block(header_signature="Block1")
        handler_status = self.handler.handle("connection_id",
                                             (block, GossipMessage.BLOCK, 2))
        self.assertEqual(handler_status.status, HandlerStatus.PASS)

    def test_no_batch(self):
        """
        Test that if the block does not exist yet in the completer or the
        chain controller, the gossip message is passed.
        """
        batch = Batch(header_signature="Batch1")
        handler_status = self.handler.handle("connection_id",
                                             (batch, GossipMessage.BATCH, 2))
        self.assertEqual(handler_status.status, HandlerStatus.PASS)

    def test_completer_has_block(self):
        """
        Test that if the block does not exist yet in the completer or the
        chain controller, the gossip message is passed.
        """
        block = Block(header_signature="Block1")
        self.completer.add_block("Block1")
        handler_status = self.handler.handle("connection_id",
                                             (block, GossipMessage.BLOCK, 2))
        self.assertEqual(handler_status.status, HandlerStatus.DROP)

    def test_completer_has_batch(self):
        """
        Test that if the block does not exist yet in the completer or the
        chain controller, the gossip message is passed.
        """
        batch = Batch(header_signature="Batch1")
        self.completer.add_batch("Batch1")
        handler_status = self.handler.handle("connection_id",
                                             (batch, GossipMessage.BATCH, 2))
        self.assertEqual(handler_status.status, HandlerStatus.DROP)

    def test_chain_has_block(self):
        """
        Test that if the block does not exist yet in the completer or the
        chain controller, the gossip message is passed.
        """
        block = Block(header_signature="Block1")
        self.chain.add_block("Block1")
        handler_status = self.handler.handle("connection_id",
                                             (block, GossipMessage.BLOCK, 2))
        self.assertEqual(handler_status.status, HandlerStatus.DROP)

    def test_publisher_has_block(self):
        """
        Test that if the block does not exist yet in the completer or the
        chain controller, the gossip message is passed.
        """
        batch = Batch(header_signature="Batch1")
        self.publisher.add_batch("Batch1")
        handler_status = self.handler.handle("connection_id",
                                             (batch, GossipMessage.BATCH, 2))
        self.assertEqual(handler_status.status, HandlerStatus.DROP)