コード例 #1
0
    def test_z_policy(self, mock_utils, mock_validator_registry_view,
                      mock_consensus_state, mock_poet_enclave_factory,
                      mock_poet_settings_view, mock_block_wrapper,
                      mock_consensus_state_store):
        """ Test verifies the Z Policy: that PoET Block Verifier fails
        if a validator attempts to claim more blocks frequently than is allowed
        """

        # create a mock_validator_registry_view that does nothing
        # in get_validator_info
        mock_validator_registry_view.return_value.get_validator_info. \
            return_value = \
            ValidatorInfo(
                name='validator_001',
                id='validator_deadbeef',
                signup_info=SignUpInfo(
                    poet_public_key='00112233445566778899aabbccddeeff'))

        # create a mock_wait_certificate that does nothing in check_valid
        mock_wait_certificate = mock.Mock()
        mock_wait_certificate.check_valid.return_value = None

        mock_utils.deserialize_wait_certificate.return_value = \
            mock_wait_certificate

        # create a mock_consensus_state that returns a mock with
        # the following settings:
        mock_state = MockConsensusState.create_mock_consensus_state(
            claiming_too_frequently=True)

        mock_consensus_state.consensus_state_for_block_id.return_value = \
            mock_state

        # check test
        mock_block_cache = mock.MagicMock()
        mock_state_view_factory = mock.Mock()
        mock_block = mock.Mock(identifier='0123456789abcdefedcba9876543210')

        with mock.patch('sawtooth_poet.poet_consensus.poet_block_verifier.'
                        'LOGGER') as mock_logger:

            block_verifier = \
                PoetBlockVerifier(
                    block_cache=mock_block_cache,
                    state_view_factory=mock_state_view_factory,
                    data_dir=self._temp_dir,
                    config_dir=self._temp_dir,
                    validator_id='validator_deadbeef')
            self.assertFalse(
                block_verifier.verify_block(block_wrapper=mock_block))

            # Could be a hack, but verify that the appropriate log message is
            # generated - so we at least have some faith that the failure was
            # because of what we are testing and not something else.  I know
            # that this is fragile if the log message is changed, so would
            # accept any suggestions on a better way to verify that the
            # function fails for the reason we expect.
            (message, *_), _ = mock_logger.error.call_args
            self.assertTrue('Validator is claiming blocks too '
                            'frequently' in message)
コード例 #2
0
    def test_non_poet_block(self,
                            mock_utils,
                            mock_validator_registry_view,
                            mock_consensus_state,
                            mock_poet_enclave_factory,
                            mock_poet_config_view,
                            mock_block_wrapper,
                            mock_consensus_state_store):
        """Verify that the PoET block verifier indicates failure if the block
        is not a PoET block (i.e., the consensus field in the block header
        is not a serialized wait certificate).
        """

        # Ensure that the consensus state does not generate failures that would
        # allow this test to pass
        mock_state = mock.Mock()
        mock_state.validator_signup_was_committed_too_late.return_value = False
        mock_state.validator_has_claimed_block_limit.return_value = False
        mock_state.validator_is_claiming_too_early.return_value = False
        mock_state.validator_is_claiming_too_frequently.return_value = False

        mock_consensus_state.consensus_state_for_block_id.return_value = \
            mock_state

        # Make utils pretend it cannot deserialize the wait certificate
        mock_utils.deserialize_wait_certificate.return_value = None

        mock_block_cache = mock.MagicMock()
        mock_state_view_factory = mock.Mock()
        mock_block = mock.Mock(identifier='0123456789abcdefedcba9876543210')

        mock_validator_registry_view.return_value.get_validator_info.\
            return_value = \
            ValidatorInfo(
                name='validator_001',
                id='validator_deadbeef',
                signup_info=SignUpInfo(
                    poet_public_key='00112233445566778899aabbccddeeff'))

        with mock.patch('sawtooth_poet.poet_consensus.poet_block_verifier.'
                        'LOGGER') as mock_logger:
            block_verifier = \
                PoetBlockVerifier(
                    block_cache=mock_block_cache,
                    state_view_factory=mock_state_view_factory,
                    data_dir=self._temp_dir,
                    validator_id='validator_deadbeef')
            self.assertFalse(
                block_verifier.verify_block(
                    block_wrapper=mock_block))

            # Could be a hack, but verify that the appropriate log message is
            # generated - so we at least have some faith that the failure was
            # because of what we are testing and not something else.  I know
            # that this is fragile if the log message is changed, so would
            # accept any suggestions on a better way to verify that the
            # function fails for the reason we expect.
            (message, *_), _ = mock_logger.error.call_args
            self.assertTrue(
                'was not created by PoET consensus module' in message)
コード例 #3
0
    def test_block_claimed_by_unknown_validator(
            self, mock_utils, mock_validator_registry_view,
            mock_consensus_state, mock_poet_enclave_factory,
            mock_poet_config_view, mock_block_wrapper,
            mock_consensus_state_store):
        """ Test verifies that PoET Block Verifier fails if a block is
        claimed by an unknown validator (the validator is not listed
        in the validator registry)
        """

        # create a mock_validator_registry_view that throws KeyError
        mock_validator_registry_view.return_value.get_validator_info.\
            side_effect = KeyError('Non-existent validator')

        # create a mock_wait_certificate that does nothing in check_valid
        mock_wait_certificate = mock.Mock()
        mock_wait_certificate.check_valid.return_value = None

        mock_utils.deserialize_wait_certificate.return_value = \
            mock_wait_certificate

        # create a mock_consensus_state that returns a mock with
        # the following settings:
        mock_state = mock.Mock()
        mock_state.validator_signup_was_committed_too_late.return_value = False
        mock_state.validator_has_claimed_block_limit.return_value = False
        mock_state.validator_is_claiming_too_early.return_value = False
        mock_state.validator_is_claiming_too_frequently.return_value = False

        mock_consensus_state.consensus_state_for_block_id.return_value = \
            mock_state

        # check test
        mock_block_cache = mock.MagicMock()
        mock_state_view_factory = mock.Mock()
        mock_block = mock.Mock(identifier='0123456789abcdefedcba9876543210')
        mock_block.header.signer_pubkey = '90834587139405781349807435098745'

        with mock.patch('sawtooth_poet.poet_consensus.poet_block_verifier.'
                        'LOGGER') as mock_logger:

            block_verifier = \
                PoetBlockVerifier(
                    block_cache=mock_block_cache,
                    state_view_factory=mock_state_view_factory,
                    data_dir=self._temp_dir,
                    validator_id='validator_deadbeef')
            self.assertFalse(
                block_verifier.verify_block(block_wrapper=mock_block))

            # Could be a hack, but verify that the appropriate log message is
            # generated - so we at least have some faith that the failure was
            # because of what we are testing and not something else.  I know
            # that this is fragile if the log message is changed, so would
            # accept any suggestions on a better way to verify that the
            # function fails for the reason we expect.
            (message, *_), _ = mock_logger.error.call_args
            self.assertTrue('Received block from an unregistered '
                            'validator' in message)
コード例 #4
0
    def test_block_verifier_valid_block_claim(
            self,
            mock_utils,
            mock_validator_registry_view,
            mock_consensus_state,
            mock_poet_enclave_factory,
            mock_poet_config_view,
            mock_block_wrapper,
            mock_consensus_state_store):

        """ Test verifies that PoET Block Verifier succeeds if
        a validator successfully passes all criteria necessary
        to claim a block
        """

        # create a mock_validator_registry_view with
        # get_validator_info that does nothing
        mock_validator_registry_view.return_value.get_validator_info. \
            return_value = \
            ValidatorInfo(
                name='validator_001',
                id='validator_deadbeef',
                signup_info=SignUpInfo(
                    poet_public_key='00112233445566778899aabbccddeeff'))

        # create a mock_wait_certificate that does nothing in check_valid
        mock_wait_certificate = mock.Mock()
        mock_wait_certificate.check_valid.return_value = None

        mock_utils.deserialize_wait_certificate.return_value = \
            mock_wait_certificate

        # create a mock_consensus_state that returns a mock with
        # the following settings:
        mock_state = mock.Mock()
        mock_state.validator_signup_was_committed_too_late.return_value = False
        mock_state.validator_has_claimed_block_limit.return_value = False
        mock_state.validator_is_claiming_too_early.return_value = False
        mock_state.validator_is_claiming_too_frequently.return_value = False

        mock_consensus_state.consensus_state_for_block_id.return_value = \
            mock_state

        # check test
        mock_block_cache = mock.MagicMock()
        mock_state_view_factory = mock.Mock()
        mock_block = mock.Mock(identifier='0123456789abcdefedcba9876543210')

        block_verifier = \
            PoetBlockVerifier(
                block_cache=mock_block_cache,
                state_view_factory=mock_state_view_factory,
                data_dir=self._temp_dir,
                config_dir=self._temp_dir,
                validator_id='validator_deadbeef')
        self.assertTrue(
            block_verifier.verify_block(
                block_wrapper=mock_block))
コード例 #5
0
    def verify_block(self, block):
        verifier = PoetBlockVerifier(
            block_cache=self._block_cache,
            state_view_factory=self._state_view_factory,
            data_dir=self._data_dir,
            config_dir=self._config_dir,
            validator_id=self._validator_id)

        return verifier.verify_block(block)
コード例 #6
0
    def test_non_poet_block(self,
                            mock_utils,
                            mock_validator_registry_view,
                            mock_consensus_state,
                            mock_poet_enclave_factory,
                            mock_poet_settings_view,
                            mock_block_wrapper,
                            mock_consensus_state_store):
        """Verify that the PoET block verifier indicates failure if the block
        is not a PoET block (i.e., the consensus field in the block header
        is not a serialized wait certificate).
        """

        # Ensure that the consensus state does not generate failures that would
        # allow this test to pass
        mock_state = MockConsensusState.create_mock_consensus_state()

        mock_consensus_state.consensus_state_for_block_id.return_value = \
            mock_state

        # Make utils pretend it cannot deserialize the wait certificate
        mock_utils.deserialize_wait_certificate.return_value = None

        mock_block_cache = mock.MagicMock()
        mock_state_view_factory = mock.Mock()
        mock_block = mock.Mock(identifier='0123456789abcdefedcba9876543210')

        mock_validator_registry_view.return_value.get_validator_info.\
            return_value = \
            ValidatorInfo(
                name='validator_001',
                id='validator_deadbeef',
                signup_info=SignUpInfo(
                    poet_public_key='00112233445566778899aabbccddeeff'))

        with mock.patch('sawtooth_poet.poet_consensus.poet_block_verifier.'
                        'LOGGER') as mock_logger:
            block_verifier = \
                PoetBlockVerifier(
                    block_cache=mock_block_cache,
                    state_view_factory=mock_state_view_factory,
                    data_dir=self._temp_dir,
                    config_dir=self._temp_dir,
                    validator_id='validator_deadbeef')
            self.assertFalse(
                block_verifier.verify_block(
                    block_wrapper=mock_block))

            # Could be a hack, but verify that the appropriate log message is
            # generated - so we at least have some faith that the failure was
            # because of what we are testing and not something else.  I know
            # that this is fragile if the log message is changed, so would
            # accept any suggestions on a better way to verify that the
            # function fails for the reason we expect.
            (message, *_), _ = mock_logger.error.call_args
            self.assertTrue(
                'was not created by PoET consensus module' in message)
コード例 #7
0
    def test_block_verifier_valid_block_claim(
            self,
            mock_utils,
            mock_validator_registry_view,
            mock_consensus_state,
            mock_poet_enclave_factory,
            mock_poet_settings_view,
            mock_block_wrapper,
            mock_consensus_state_store):

        """ Test verifies that PoET Block Verifier succeeds if
        a validator successfully passes all criteria necessary
        to claim a block
        """

        # create a mock_validator_registry_view with
        # get_validator_info that does nothing
        mock_validator_registry_view.return_value.get_validator_info. \
            return_value = \
            ValidatorInfo(
                name='validator_001',
                id='validator_deadbeef',
                signup_info=SignUpInfo(
                    poet_public_key='00112233445566778899aabbccddeeff'))

        # create a mock_wait_certificate that does nothing in check_valid
        mock_wait_certificate = mock.Mock()
        mock_wait_certificate.check_valid.return_value = None

        mock_utils.deserialize_wait_certificate.return_value = \
            mock_wait_certificate

        # create a mock_consensus_state that returns a mock with
        # the following settings:
        mock_state = MockConsensusState.create_mock_consensus_state()

        mock_consensus_state.consensus_state_for_block_id.return_value = \
            mock_state

        # check test
        mock_block_cache = mock.MagicMock()
        mock_state_view_factory = mock.Mock()
        mock_block = mock.Mock(identifier='0123456789abcdefedcba9876543210')

        block_verifier = \
            PoetBlockVerifier(
                block_cache=mock_block_cache,
                state_view_factory=mock_state_view_factory,
                data_dir=self._temp_dir,
                config_dir=self._temp_dir,
                validator_id='validator_deadbeef')
        self.assertTrue(
            block_verifier.verify_block(
                block_wrapper=mock_block))
コード例 #8
0
    def test_invalid_wait_certificate(
            self, mock_utils, mock_validator_registry_view,
            mock_consensus_state, mock_poet_enclave_factory,
            mock_poet_settings_view, mock_block_wrapper,
            mock_consensus_state_store):

        # Ensure that the consensus state does not generate failures that would
        # allow this test to pass
        mock_state = MockConsensusState.create_mock_consensus_state()

        mock_consensus_state.consensus_state_for_block_id.return_value = \
            mock_state

        # Make the certificate's check_valid pretend it failed
        mock_wait_certificate = mock.Mock()
        mock_wait_certificate.check_valid.side_effect = \
            ValueError('Unit test fake failure')

        mock_utils.deserialize_wait_certificate.return_value = \
            mock_wait_certificate

        mock_block_cache = mock.MagicMock()
        mock_state_view_factory = mock.Mock()
        mock_block = mock.Mock(identifier='0123456789abcdefedcba9876543210')

        mock_validator_registry_view.return_value.get_validator_info.\
            return_value = \
            ValidatorInfo(
                name='validator_001',
                id='validator_deadbeef',
                signup_info=SignUpInfo(
                    poet_public_key='00112233445566778899aabbccddeeff'))

        with mock.patch('sawtooth_poet.poet_consensus.poet_block_verifier.'
                        'LOGGER') as mock_logger:
            block_verifier = \
                PoetBlockVerifier(
                    block_cache=mock_block_cache,
                    state_view_factory=mock_state_view_factory,
                    data_dir=self._temp_dir,
                    config_dir=self._temp_dir,
                    validator_id='validator_deadbeef')
            self.assertFalse(
                block_verifier.verify_block(block_wrapper=mock_block))

            # Could be a hack, but verify that the appropriate log message is
            # generated - so we at least have some faith that the failure was
            # because of what we are testing and not something else.  I know
            # that this is fragile if the log message is changed, so would
            # accept any suggestions on a better way to verify that the
            # function fails for the reason we expect.
            (message, *_), _ = mock_logger.error.call_args
            self.assertTrue('Wait certificate check failed' in message)
コード例 #9
0
    def test_z_policy(self,
                      mock_utils,
                      mock_validator_registry_view,
                      mock_consensus_state,
                      mock_poet_enclave_factory,
                      mock_poet_settings_view,
                      mock_block_wrapper,
                      mock_consensus_state_store):
        """ Test verifies the Z Policy: that PoET Block Verifier fails
        if a validator attempts to claim more blocks frequently than is allowed
        """

        # create a mock_validator_registry_view that does nothing
        # in get_validator_info
        mock_validator_registry_view.return_value.get_validator_info. \
            return_value = \
            ValidatorInfo(
                name='validator_001',
                id='validator_deadbeef',
                signup_info=SignUpInfo(
                    poet_public_key='00112233445566778899aabbccddeeff'))

        # create a mock_wait_certificate that does nothing in check_valid
        mock_wait_certificate = mock.Mock()
        mock_wait_certificate.check_valid.return_value = None

        mock_utils.deserialize_wait_certificate.return_value = \
            mock_wait_certificate

        # create a mock_consensus_state that returns a mock with
        # the following settings:
        mock_state = MockConsensusState.create_mock_consensus_state(
            claiming_too_frequently=True)

        mock_consensus_state.consensus_state_for_block_id.return_value = \
            mock_state

        # check test
        mock_block_cache = mock.MagicMock()
        mock_state_view_factory = mock.Mock()
        mock_block = mock.Mock(identifier='0123456789abcdefedcba9876543210')

        with mock.patch('sawtooth_poet.poet_consensus.poet_block_verifier.'
                        'LOGGER') as mock_logger:

            block_verifier = \
                PoetBlockVerifier(
                    block_cache=mock_block_cache,
                    state_view_factory=mock_state_view_factory,
                    data_dir=self._temp_dir,
                    config_dir=self._temp_dir,
                    validator_id='validator_deadbeef')
            self.assertFalse(
                block_verifier.verify_block(
                    block_wrapper=mock_block))

            # Could be a hack, but verify that the appropriate log message is
            # generated - so we at least have some faith that the failure was
            # because of what we are testing and not something else.  I know
            # that this is fragile if the log message is changed, so would
            # accept any suggestions on a better way to verify that the
            # function fails for the reason we expect.
            (message, *_), _ = mock_logger.error.call_args
            self.assertTrue('Validator is claiming blocks too '
                            'frequently' in message)
コード例 #10
0
    def test_block_claimed_by_unknown_validator(self,
                                                mock_utils,
                                                mock_validator_registry_view,
                                                mock_consensus_state,
                                                mock_poet_enclave_factory,
                                                mock_poet_settings_view,
                                                mock_block_wrapper,
                                                mock_consensus_state_store):
        """ Test verifies that PoET Block Verifier fails if a block is
        claimed by an unknown validator (the validator is not listed
        in the validator registry)
        """

        # create a mock_validator_registry_view that throws KeyError
        mock_validator_registry_view.return_value.get_validator_info.\
            side_effect = KeyError('Non-existent validator')

        # create a mock_wait_certificate that does nothing in check_valid
        mock_wait_certificate = mock.Mock()
        mock_wait_certificate.check_valid.return_value = None

        mock_utils.deserialize_wait_certificate.return_value = \
            mock_wait_certificate

        # create a mock_consensus_state that returns a mock with
        # the following settings:
        mock_state = MockConsensusState.create_mock_consensus_state()

        mock_consensus_state.consensus_state_for_block_id.return_value = \
            mock_state

        # check test
        mock_block_cache = mock.MagicMock()
        mock_state_view_factory = mock.Mock()
        mock_block = mock.Mock(identifier='0123456789abcdefedcba9876543210')
        mock_block.header.signer_public_key = \
            '90834587139405781349807435098745'

        with mock.patch('sawtooth_poet.poet_consensus.poet_block_verifier.'
                        'LOGGER') as mock_logger:

            block_verifier = \
                PoetBlockVerifier(
                    block_cache=mock_block_cache,
                    state_view_factory=mock_state_view_factory,
                    data_dir=self._temp_dir,
                    config_dir=self._temp_dir,
                    validator_id='validator_deadbeef')
            self.assertFalse(
                block_verifier.verify_block(
                    block_wrapper=mock_block))

            # Could be a hack, but verify that the appropriate log message is
            # generated - so we at least have some faith that the failure was
            # because of what we are testing and not something else.  I know
            # that this is fragile if the log message is changed, so would
            # accept any suggestions on a better way to verify that the
            # function fails for the reason we expect.
            (message, *_), _ = mock_logger.error.call_args
            self.assertTrue('Received block from an unregistered '
                            'validator' in message)