示例#1
0
    def __init__(self, state_view):
        """Initialize a PbftSettingsView object.

        Args:
            state_view (StateView): The current state view.

        Returns:
            None
        """

        self._settings_view = SettingsView(state_view)

        self._max_log_size = None
        self._enclave_module_name = None
        self._signup_commit_maximum_delay = 2
        self._key_block_claim_limit = 2
        self._block_claim_delay = 2
    def __init__(self, state_view):
        """Initialize a PbftSettingsView object.
        Args:
            state_view (StateView): The current state view.
        Returns:
            None
        """

        self._settings_view = SettingsView(state_view)
        self._node = None
        self._nodes = None
        self._max_log_size = None
        self._block_duration = None
        self._checkpoint_period = None
        self._view_change_timeout = None
        self._signup_commit_maximum_delay = 2
        self._key_block_claim_limit = 2
        self._block_claim_delay = 2
示例#3
0
class PbftSettingsView:
    """A class to wrap the retrieval of PBFT configuration settings from the
    configuration view.  For values that are not in the current state view
    or that are invalid, default values are returned.
    """

    _MAX_LOG_SIZE_ = 1000
    _ENCLAVE_MODULE_NAME_ = 'bgx_pbft.enclave.pbft_enclave'

    def __init__(self, state_view):
        """Initialize a PbftSettingsView object.

        Args:
            state_view (StateView): The current state view.

        Returns:
            None
        """

        self._settings_view = SettingsView(state_view)

        self._max_log_size = None
        self._enclave_module_name = None
        self._signup_commit_maximum_delay = 2
        self._key_block_claim_limit = 2
        self._block_claim_delay = 2

    def _get_config_setting(self,
                            name,
                            value_type,
                            default_value,
                            validate_function=None):
        """Retrieves a value from the config view, returning the default value
        if does not exist in the current state view or if the value is
        invalid.

        Args:
            name (str): The config setting to return.
            value_type (type): The value type, for example, int, float, etc.,
                of config value.
            default_value (object): The default value to be used if no value
                found or if value in config is invalid, for example, a
                non-integer value for an int config setting.
            validate_function (function): An optional function that can be
                applied to the setting to determine validity.  The function
                should return True if setting is valid, False otherwise.

        Returns:
            The value for the config setting.
        """

        try:
            value = \
                self._settings_view.get_setting(
                    key=name,
                    default_value=default_value,
                    value_type=value_type)

            if validate_function is not None:
                if not validate_function(value):
                    raise \
                        ValueError(
                            'Value ({}) for {} is not valid'.format(
                                value,
                                name))
        except ValueError:
            value = default_value

        return value

    @property
    def pbft_max_log_size(self):
        """Return the max log size if config setting exists and is valid, otherwise return the default.
        """
        if self._max_log_size is None:
            self._max_log_size = self._get_config_setting(
                name='sawtooth.consensus.pbft.max_log_size',
                value_type=int,
                default_value=PbftSettingsView._MAX_LOG_SIZE_,
                validate_function=lambda value: value >= 0)

        return self._max_log_size

    @property
    def enclave_module_name(self):
        """Return the enclave module name if config setting exists and is
        valid, otherwise return the default.

        The enclave module name is the name of the Python module containing the
        implementation of the underlying PBFT enclave.
        """
        if self._enclave_module_name is None:
            self._enclave_module_name = \
                self._get_config_setting(
                    name='sawtooth.consensus.pbft.enclave_module_name',
                    value_type=str,
                    default_value=PbftSettingsView._ENCLAVE_MODULE_NAME_,
                    # function should return true if value is nonempty
                    validate_function=lambda value: value)

        return self._enclave_module_name

    @property
    def signup_commit_maximum_delay(self):
        return self._signup_commit_maximum_delay

    @property
    def key_block_claim_limit(self):
        return self._key_block_claim_limit

    @property
    def block_claim_delay(self):
        return self._block_claim_delay
示例#4
0
class PbftSettingsView:
    """A class to wrap the retrieval of PBFT configuration settings from the
    configuration view.  For values that are not in the current state view
    or that are invalid, default values are returned.
    """
    _NODE_ = 'plink' 
    _NODES_ = "{\"0281e398fc978e8d36d6b2244c71e140f3ee464cb4c0371a193bb0a5c6574810ba\": \"leader\",\"028c7e06db3af50a9958390e3e29f166b1cf6198586acf37cde46c8ea54e4a79ef\": \"plink\"}"
    _MAX_LOG_SIZE_ = 1000
    _BLOCK_DURATION_ = 200
    _CHECKPOINT_PERIOD_ = 100
    _VIEW_CHANGE_TIMEOUT_ = 4000
    _DAG_STEP_ = 3
    _IS_PBFT_FULL_ = False
    _IS_LEADER_SHIFT_ = False
    _BLOCK_TIMEOUT_ = 0.5
    _MAX_BRANCH_ = 6
    _MAX_FEDER_PEER_ = 6
    BLOCK_TIMEOUT = 'bgx.consensus.block_timeout'
    LEADER_SHIFT = 'bgx.fbft.leader_shift'
    MAX_FEDER_PEER = 'bgx.fbft.max_feder_peer'
    PBFT_FULL    = 'bgx.consensus.pbft.full'
    MAX_BRANCH = 'bgx.dag.max_branch'
    DAG_STEP = 'bgx.dag.step'

    def __init__(self, state_view):
        """Initialize a PbftSettingsView object.
        Args:
            state_view (StateView): The current state view.
        Returns:
            None
        """

        self._settings_view = SettingsView(state_view)
        self._node = None
        self._nodes = None
        self._max_log_size = None
        self._block_duration = None
        self._checkpoint_period = None
        self._view_change_timeout = None
        self._signup_commit_maximum_delay = 2
        self._key_block_claim_limit = 2
        self._block_claim_delay = 2
        self._params = {}
        self._max_branch = None
        self._send_batches = None
        

    def _get_config_setting(self,
                            name,
                            value_type,
                            default_value,
                            validate_function=None):
        """Retrieves a value from the config view, returning the default value
        if does not exist in the current state view or if the value is
        invalid.

        Args:
            name (str): The config setting to return.
            value_type (type): The value type, for example, int, float, etc.,
                of config value.
            default_value (object): The default value to be used if no value
                found or if value in config is invalid, for example, a
                non-integer value for an int config setting.
            validate_function (function): An optional function that can be
                applied to the setting to determine validity.  The function
                should return True if setting is valid, False otherwise.

        Returns:
            The value for the config setting.
        """

        try:
            value = \
                self._settings_view.get_setting(
                    key=name,
                    default_value=default_value,
                    value_type=value_type)

            if validate_function is not None:
                if not validate_function(value):
                    raise ValueError('Value ({}) for {} is not valid'.format(value,name))
        except ValueError:
            value = default_value
            LOGGER.debug('use default for %s=%s',name,value)

        return value

    def update_param(self,pname):
        if pname in self._params:
            del self._params[pname]
            LOGGER.debug('CLEAR PARAM %s',pname)
            return True
        return False

    @property
    def pbft_max_log_size(self):
        """Return the max log size if config setting exists and is valid, otherwise return the default.
        """
        if self._max_log_size is None:
            self._max_log_size = self._get_config_setting(
                    name='bgx.consensus.pbft.max_log_size',
                    value_type=int,
                    default_value=PbftSettingsView._MAX_LOG_SIZE_,
                    validate_function=lambda value: value >= 0)

        return self._max_log_size

    @property
    def pbft_block_duration(self):
        """Return the block_duration if config setting exists and is valid, otherwise return the default.
        """
        if self._block_duration is None:
            self._block_duration = self._get_config_setting(
                    name='bgx.consensus.pbft.block_duration',
                    value_type=int,
                    default_value=PbftSettingsView._BLOCK_DURATION_,
                    validate_function=lambda value: value >= 0)

        return self._block_duration


    @property
    def pbft_checkpoint_period(self):
        """Return the checkpoint_period if config setting exists and is valid, otherwise return the default.
        """
        if self._checkpoint_period is None:
            self._block_duration = self._get_config_setting(
                    name='bgx.consensus.pbft.checkpoint_period',
                    value_type=int,
                    default_value=PbftSettingsView._CHECKPOINT_PERIOD_,
                    validate_function=lambda value: value >= 0)

        return self._checkpoint_period
    

    @property
    def pbft_view_change_timeout(self):
        """Return the view_change_timeout if config setting exists and is valid, otherwise return the default.
        """
        if self._view_change_timeout is None:
            self._view_change_timeout = self._get_config_setting(
                    name='bgx.consensus.pbft.view_change_timeout',
                    value_type=int,
                    default_value=PbftSettingsView._VIEW_CHANGE_TIMEOUT_,
                    validate_function=lambda value: value >= 0)

        return self._view_change_timeout
    @property
    def authorized_keys(self):
        """Return node type.
        """
        if self._node is None:
            self._node = self._get_config_setting(
                    name='sawtooth.settings.vote.authorized_keys',
                    value_type=str,
                    default_value=None,
                    validate_function=lambda value: value)

        return self._node


    @property
    def pbft_node(self):
        """Return node type.
        """
        if self._node is None:
            self._node = self._get_config_setting(
                    name='bgx.consensus.pbft.node',
                    value_type=str,
                    default_value=PbftSettingsView._NODE_,
                    validate_function=lambda value: value)

        return self._node

    @property
    def pbft_nodes(self):
        """Return nodes list.
        """
        if TOPOLOGY_SET_NM not in self._params:
            #self._settings_view.get_setting.cache_clear()
            #self._settings_view.get_setting.cache_info()
            self._params[TOPOLOGY_SET_NM] = self._get_config_setting(
                    name=TOPOLOGY_SET_NM,
                    value_type=str,
                    default_value=PbftSettingsView._NODES_,
                    validate_function=lambda value: value)

        return self._params[TOPOLOGY_SET_NM]

    @property
    def dag_step(self):
        if PbftSettingsView.DAG_STEP not in self._params :
            self._params[PbftSettingsView.DAG_STEP] = self._get_config_setting(
                    name='bgx.dag.step',
                    value_type=int,
                    default_value=PbftSettingsView._DAG_STEP_,
                    validate_function=lambda value: value)

        return self._params[PbftSettingsView.DAG_STEP]
    @property
    def max_branch(self):
        if PbftSettingsView.MAX_BRANCH not in self._params:                                 
            self._params[PbftSettingsView.MAX_BRANCH] = self._get_config_setting(             
                    name=PbftSettingsView.MAX_BRANCH,                           
                    value_type=int,                                
                    default_value=PbftSettingsView._MAX_BRANCH_,     
                    validate_function=lambda value: value)         
                                                                   
        return self._params[PbftSettingsView.MAX_BRANCH] 
    @property
    def is_pbft_full(self):
        if PbftSettingsView.PBFT_FULL not in self._params :
            val = self._get_config_setting(
                    name=PbftSettingsView.PBFT_FULL,
                    value_type=int,
                    default_value=PbftSettingsView._IS_PBFT_FULL_,
                    validate_function=lambda value: value==0 or value==1)

            self._params[PbftSettingsView.PBFT_FULL] = bool(val)

        return self._params[PbftSettingsView.PBFT_FULL]

    
    @property                                                                                         
    def is_leader_shift(self):                                                                           
        if PbftSettingsView.LEADER_SHIFT not in self._params:                                                                
            val = self._get_config_setting(                                                           
                    name=PbftSettingsView.LEADER_SHIFT,                                                   
                    value_type=int,                                                                   
                    default_value=PbftSettingsView._IS_LEADER_SHIFT_,                                    
                    validate_function=lambda value: value==0 or value==1) 
            
            self._params[PbftSettingsView.LEADER_SHIFT] = bool(val)                                                            
                                                                                                      
        return self._params[PbftSettingsView.LEADER_SHIFT]                                                                     


    @property                                                                                         
    def max_feder_peer(self):                                                                           
        if PbftSettingsView.MAX_FEDER_PEER not in self._params:                                                                
            self._params[PbftSettingsView.MAX_FEDER_PEER] = self._get_config_setting(                                                           
                    name=PbftSettingsView.MAX_FEDER_PEER,                                                   
                    value_type=int,                                                                   
                    default_value=PbftSettingsView._MAX_FEDER_PEER_,                                    
                    validate_function=lambda value: value==0 or value==1) 

            

        return self._params[PbftSettingsView.MAX_FEDER_PEER]                                                                     

    @property
    def send_batches(self):
        if self._send_batches is None:
            val = self._get_config_setting(
                    name='bgx.publisher.send_batches',
                    value_type=int,
                    default_value=1,
                    validate_function=lambda value: value==0 or value==1)
            self._send_batches = bool(val)

        return self._send_batches
    # bgx.consensus.block_timeout
    @property
    def block_timeout(self):
        if PbftSettingsView.BLOCK_TIMEOUT not in self._params :
            val = self._get_config_setting(
                    name=PbftSettingsView.BLOCK_TIMEOUT,
                    value_type=float,
                    default_value=PbftSettingsView._BLOCK_TIMEOUT_,
                    validate_function=lambda value: value)
            self._params[PbftSettingsView.BLOCK_TIMEOUT] = val
            LOGGER.debug('block_timeout  new=%s',val)
        return self._params[PbftSettingsView.BLOCK_TIMEOUT] 

    @property
    def signup_commit_maximum_delay(self):
        return self._signup_commit_maximum_delay

    @property
    def key_block_claim_limit(self):
        return self._key_block_claim_limit

    @property
    def block_claim_delay(self):
        return self._block_claim_delay
class PbftSettingsView:
    """A class to wrap the retrieval of PBFT configuration settings from the
    configuration view.  For values that are not in the current state view
    or that are invalid, default values are returned.
    """
    _NODE_ = 'plink'
    _NODES_ = "{\"0281e398fc978e8d36d6b2244c71e140f3ee464cb4c0371a193bb0a5c6574810ba\": \"leader\",\"028c7e06db3af50a9958390e3e29f166b1cf6198586acf37cde46c8ea54e4a79ef\": \"plink\"}"
    _MAX_LOG_SIZE_ = 1000
    _BLOCK_DURATION_ = 200
    _CHECKPOINT_PERIOD_ = 100
    _VIEW_CHANGE_TIMEOUT_ = 4000

    def __init__(self, state_view):
        """Initialize a PbftSettingsView object.
        Args:
            state_view (StateView): The current state view.
        Returns:
            None
        """

        self._settings_view = SettingsView(state_view)
        self._node = None
        self._nodes = None
        self._max_log_size = None
        self._block_duration = None
        self._checkpoint_period = None
        self._view_change_timeout = None
        self._signup_commit_maximum_delay = 2
        self._key_block_claim_limit = 2
        self._block_claim_delay = 2

    def _get_config_setting(self,
                            name,
                            value_type,
                            default_value,
                            validate_function=None):
        """Retrieves a value from the config view, returning the default value
        if does not exist in the current state view or if the value is
        invalid.

        Args:
            name (str): The config setting to return.
            value_type (type): The value type, for example, int, float, etc.,
                of config value.
            default_value (object): The default value to be used if no value
                found or if value in config is invalid, for example, a
                non-integer value for an int config setting.
            validate_function (function): An optional function that can be
                applied to the setting to determine validity.  The function
                should return True if setting is valid, False otherwise.

        Returns:
            The value for the config setting.
        """

        try:
            value = \
                self._settings_view.get_setting(
                    key=name,
                    default_value=default_value,
                    value_type=value_type)

            if validate_function is not None:
                if not validate_function(value):
                    raise \
                        ValueError(
                            'Value ({}) for {} is not valid'.format(
                                value,
                                name))
        except ValueError:
            value = default_value

        return value

    @property
    def pbft_max_log_size(self):
        """Return the max log size if config setting exists and is valid, otherwise return the default.
        """
        if self._max_log_size is None:
            self._max_log_size = self._get_config_setting(
                name='sawtooth.consensus.pbft.max_log_size',
                value_type=int,
                default_value=PbftSettingsView._MAX_LOG_SIZE_,
                validate_function=lambda value: value >= 0)

        return self._max_log_size

    @property
    def pbft_block_duration(self):
        """Return the block_duration if config setting exists and is valid, otherwise return the default.
        """
        if self._block_duration is None:
            self._block_duration = self._get_config_setting(
                name='sawtooth.consensus.pbft.block_duration',
                value_type=int,
                default_value=PbftSettingsView._BLOCK_DURATION_,
                validate_function=lambda value: value >= 0)

        return self._block_duration

    @property
    def pbft_checkpoint_period(self):
        """Return the checkpoint_period if config setting exists and is valid, otherwise return the default.
        """
        if self._checkpoint_period is None:
            self._block_duration = self._get_config_setting(
                name='sawtooth.consensus.pbft.checkpoint_period',
                value_type=int,
                default_value=PbftSettingsView._CHECKPOINT_PERIOD_,
                validate_function=lambda value: value >= 0)

        return self._checkpoint_period

    @property
    def pbft_view_change_timeout(self):
        """Return the view_change_timeout if config setting exists and is valid, otherwise return the default.
        """
        if self._view_change_timeout is None:
            self._view_change_timeout = self._get_config_setting(
                name='sawtooth.consensus.pbft.view_change_timeout',
                value_type=int,
                default_value=PbftSettingsView._VIEW_CHANGE_TIMEOUT_,
                validate_function=lambda value: value >= 0)

        return self._view_change_timeout

    @property
    def pbft_node(self):
        """Return node type.
        """
        if self._node is None:
            self._node = self._get_config_setting(
                name='sawtooth.consensus.pbft.node',
                value_type=str,
                default_value=PbftSettingsView._NODE_,
                validate_function=lambda value: value)

        return self._node

    @property
    def pbft_nodes(self):
        """Return nodes list.
        """
        if self._nodes is None:
            self._nodes = self._get_config_setting(
                name='sawtooth.consensus.pbft.nodes',
                value_type=str,
                default_value=PbftSettingsView._NODES_,
                validate_function=lambda value: value)

        return self._nodes

    @property
    def signup_commit_maximum_delay(self):
        return self._signup_commit_maximum_delay

    @property
    def key_block_claim_limit(self):
        return self._key_block_claim_limit

    @property
    def block_claim_delay(self):
        return self._block_claim_delay
示例#6
0
    def _register_signup_information(self,
                                     block_header,
                                     pbft_enclave_module=None):
        # Create signup information for this validator, putting the block ID
        # of the block previous to the block referenced by block_header in the
        # nonce.  Block ID is better than wait certificate ID for testing
        # freshness as we need to account for non-BGT blocks.
        LOGGER.debug('_register_signup_information: TRY to REGISTER')
        public_key_hash = hashlib.sha256(
            block_header.signer_public_key.encode()).hexdigest()
        nonce = SignupInfo.block_id_to_nonce(block_header.previous_block_id)
        pbft_public_key = self._validator_id
        anti_sybil_id = hashlib.sha256(pbft_public_key.encode()).hexdigest()
        signup_data = {
            'pbft_public_key': pbft_public_key,
        }
        sealed_signup_data = base64.b64encode(
            dict2json(signup_data).encode()).decode('utf-8')
        """
        signup_info = SignupInfo.create_signup_info(
                pbft_enclave_module=pbft_enclave_module,
                originator_public_key_hash=public_key_hash,
                nonce=nonce)
        """
        # Create the validator registry payload
        payload = vr_pb.BgxValidatorRegistryPayload(
            verb='register',
            name='validator-{}'.format(block_header.signer_public_key[:8]),
            id=block_header.signer_public_key,
            node=self._node,
            signup_info=vr_pb.BgxSignUpInfo(
                pbft_public_key=pbft_public_key,  # signup_info.pbft_public_key,
                anti_sybil_id=anti_sybil_id,  # signup_info.anti_sybil_id,
                nonce=nonce),
        )
        serialized = payload.SerializeToString()

        # Create the address that will be used to look up this validator
        # registry transaction.  Seems like a potential for refactoring..
        validator_entry_address = PbftBlockPublisher._validator_registry_namespace + hashlib.sha256(
            block_header.signer_public_key.encode()).hexdigest()

        # Create a transaction header and transaction for the validator
        # registry update amd then hand it off to the batch publisher to
        # send out.
        output_addresses = [
            validator_entry_address, PbftBlockPublisher._validator_map_address
        ]
        input_addresses = output_addresses + \
            [SettingsView.setting_address('sawtooth.bgt.report_public_key_pem'),
             SettingsView.setting_address('sawtooth.bgt.valid_enclave_measurements'),
             SettingsView.setting_address('sawtooth.bgt.valid_enclave_basenames')
            ]

        header = txn_pb.TransactionHeader(
            signer_public_key=block_header.signer_public_key,
            family_name='bgx_validator_registry',
            family_version='1.0',
            inputs=input_addresses,
            outputs=output_addresses,
            dependencies=[],
            payload_sha512=hashlib.sha512(serialized).hexdigest(),
            batcher_public_key=block_header.signer_public_key,
            nonce=hex(random.randint(0, 2**64))).SerializeToString()

        signature = self._batch_publisher.identity_signer.sign(header)

        transaction = txn_pb.Transaction(header=header,
                                         payload=serialized,
                                         header_signature=signature)

        LOGGER.info('Register Validator Name=%s, ID=%s...%s,Nonce=%s',
                    payload.name, payload.id[:8], payload.id[-8:], nonce)

        self._batch_publisher.send([transaction])

        # Store the key state so that we can look it up later if need be and
        # set the new key as our active key
        self._pbft_key_state_store[pbft_public_key] = PbftKeyState(
            sealed_signup_data=sealed_signup_data,
            has_been_refreshed=False,
            signup_nonce=nonce)
        self._pbft_key_state_store.active_key = pbft_public_key
        LOGGER.debug('_register_signup_information: REGISTER DONE')