Ejemplo n.º 1
0
def is_connected_to_primary_validator(*, primary_validator_address,
                                      self_configuration):
    """Return boolean to indicate if self is connected to primary validator"""
    url = f'{primary_validator_address}/validators/{self_configuration.node_identifier}'

    try:
        fetch(url=url, headers={})
        return True
    except Exception as e:
        capture_exception(e)
        logger.exception(e)

    return False
Ejemplo n.º 2
0
def create_validators(*, known_nodes, results):
    """
    For each unknown validator, attempt to:
    - fetch config data
    - create new Validator object
    """

    for validator in get_unknown_nodes(known_nodes=known_nodes,
                                       results=results):

        try:
            address = format_address(ip_address=validator.get('ip_address'),
                                     port=validator.get('port'),
                                     protocol=validator.get('protocol'))
            config_address = f'{address}/config'
            config_data = fetch(url=config_address, headers={})
            serializer = ValidatorConfigurationSerializer(data=config_data)

            if serializer.is_valid():
                create_validator_from_config_data(config_data=config_data)
                continue

            logger.exception(serializer.errors)
        except Exception as e:
            capture_exception(e)
            logger.exception(e)
Ejemplo n.º 3
0
def crawl_banks(*, primary_validator_address, self_node_identifier):
    """
    Crawl all banks from primary validator and create any new banks
    """

    known_nodes = get_known_nodes(node_class=Bank)
    next_url = f'{primary_validator_address}/banks'

    while next_url:

        if cache.get(CRAWL_STATUS) == CRAWL_STATUS_STOP_REQUESTED:
            break

        try:
            response = fetch(url=next_url, headers={})
            next_url = response.get('next')
            results = response.get('results')
            results = [
                i for i in results
                if i['node_identifier'] != self_node_identifier
            ]
            create_banks(known_nodes=known_nodes, results=results)
        except Exception as e:
            capture_exception(e)
            logger.exception(e)
            break
Ejemplo n.º 4
0
    def get_node_config(data):
        """
        Attempt to connect to node

        Return nodes config data after validation
        """
        ip_address = data['ip_address']
        protocol = data['protocol']

        try:
            address = format_address(
                ip_address=ip_address,
                port=data.get('port'),
                protocol=protocol
            )
            config_address = f'{address}/config'
            config_data = fetch(url=config_address, headers={})

            if config_data['node_type'] == BANK:
                config_serializer = BankConfigurationSerializer(data=config_data)
            elif config_data['node_type'] == CONFIRMATION_VALIDATOR:
                config_serializer = ValidatorConfigurationSerializer(data=config_data)
            elif config_data['node_type'] == PRIMARY_VALIDATOR:
                raise serializers.ValidationError('Unable to accept connection requests from primary validators')
            else:
                raise serializers.ValidationError('Invalid node_type')
        except Exception as e:
            logger.exception(e)
            raise e

        if config_serializer.is_valid():
            return config_data
        else:
            logger.exception(config_serializer.errors)
            raise serializers.ValidationError(config_serializer.errors)
Ejemplo n.º 5
0
def is_self_known_to_node(*, node, self_configuration):
    """Return boolean to indicate if self is known to node"""
    node_address = format_address(
        ip_address=node.ip_address,
        port=node.port,
        protocol=node.protocol,
    )
    url = f'{node_address}/banks/{self_configuration.node_identifier}'

    try:
        fetch(url=url, headers={})
        return True
    except Exception as e:
        logger.debug(e)

    return False
Ejemplo n.º 6
0
    def create(self, validated_data):
        """
        Handle banks primary validator updated notice

        A response of True indicates to the requesting bank that self (this validator) will remain on the same network
        Delete banks switching to different networks
        """
        bank = validated_data['node_identifier']
        ip_address = validated_data['ip_address']
        port = validated_data['port']
        protocol = validated_data['protocol']

        self_configuration = get_self_configuration(
            exception_class=RuntimeError)

        if self.primary_validator_synchronized(
                ip_address=ip_address, self_configuration=self_configuration):
            return True

        if (self_configuration.node_type == CONFIRMATION_VALIDATOR
                and bank == get_most_trusted_bank()):
            address = format_address(ip_address=ip_address,
                                     port=port,
                                     protocol=protocol)
            try:
                config = fetch(url=f'{address}/config', headers={})
            except Exception as e:
                capture_exception(e)
                logger.exception(e)
            else:
                sync_with_primary_validator.delay(config=config)
                return True

        bank.delete()
        raise serializers.ValidationError('Networks out of sync')
Ejemplo n.º 7
0
def get_confirmation_block(*, address, block_identifier):
    """
    Return confirmation block chain segment
    """

    url = f'{address}/confirmation_blocks/{block_identifier}'
    results = fetch(url=url, headers={})
    return results
Ejemplo n.º 8
0
    def get_validator_config(self):
        """
        Return config
        """

        address = self.get_primary_validator_address()
        url = f'{address}/config'
        results = fetch(url=url, headers={})
        return results
Ejemplo n.º 9
0
def get_account_balance_lock(*, account_number):
    """
    Return the balance lock for the given account
    """

    bank_address = format_address(ip_address='192.168.1.75',
                                  port=8000,
                                  protocol='http')
    url = f'{bank_address}/account_balance_lock/{account_number}'
    results = fetch(url=url, headers={})
    return results['balance_lock']
Ejemplo n.º 10
0
def get_confirmation_block_chain_segment(*, address, block_identifier):
    """
    Return confirmation block chain segment
    """

    url = f'{address}/confirmation_block_chain_segment/{block_identifier}'

    try:
        results = fetch(url=url, headers={})
        return results
    except JSONDecodeError:
        return []
    except Exception as e:
        print(e)
        return []
Ejemplo n.º 11
0
def fetch_valid_confirmation_block(*, primary_validator, block_identifier):
    """
    Return valid confirmation block
    """

    address = format_address(ip_address=primary_validator.ip_address,
                             port=primary_validator.port,
                             protocol=primary_validator.protocol)
    url = f'{address}/valid_confirmation_blocks/{block_identifier}'

    try:
        results = fetch(url=url, headers={})
        return results
    except Exception as e:
        logger.exception(e)
Ejemplo n.º 12
0
def crawl_validators(*, primary_validator_address):
    """Crawl all validators from primary validator and create any new validators"""
    known_nodes = get_known_nodes(node_class=Validator)
    next_url = f'{primary_validator_address}/validators'

    while next_url:

        if cache.get(CRAWL_STATUS) == CRAWL_STATUS_STOP_REQUESTED:
            break

        try:
            response = fetch(url=next_url, headers={})
            next_url = response.get('next')
            results = response.get('results')
            create_validators(known_nodes=known_nodes, results=results)
        except Exception as e:
            logger.exception(e)
            break
Ejemplo n.º 13
0
def fetch_account_data():
    """
    Fetch all account data from primary validator
    Return list of accounts
    """

    results = []

    next_url = f'http://{PRIMARY_VALIDATOR_IP}/accounts'

    while next_url:
        print(next_url)
        data = fetch(url=next_url, headers={})
        accounts = data['results']
        results += accounts
        next_url = data['next']

    return results
Ejemplo n.º 14
0
def get_account_balance_lock(*, account_number, live_pv=False):
    """
    Return the balance lock for the given account
    """

    if live_pv:
        pv_address = format_address(
            ip_address='64.225.47.205',
            port=None,
            protocol='http'
        )
    else:
        pv_address = format_address(
            ip_address='192.168.1.75',
            port=8000,
            protocol='http'
        )

    url = f'{pv_address}/account_balance_lock/{account_number}'
    results = fetch(url=url, headers={})
    return results['balance_lock']
Ejemplo n.º 15
0
def create_banks(*, known_nodes, results):
    """
    For each unknown bank, attempt to:

    - fetch config data
    - create new Bank object
    """
    for bank in get_unknown_nodes(known_nodes=known_nodes, results=results):

        try:
            address = format_address(ip_address=bank.get('ip_address'),
                                     port=bank.get('port'),
                                     protocol=bank.get('protocol'))
            config_address = f'{address}/config'
            config_data = fetch(url=config_address, headers={})
            serializer = BankConfigurationSerializer(data=config_data)

            if serializer.is_valid():
                create_bank_from_config_data(config_data=config_data)
                continue

            logger.exception(serializer.errors)
        except Exception as e:
            logger.exception(e)
Ejemplo n.º 16
0
def clean_nodes(*, nodes_type):
    """
    Clean nodes: delete or update nodes of type BANK or CONFIRMATION_VALIDATOR
    """

    self_configuration = get_self_configuration(exception_class=RuntimeError)
    primary_validator = self_configuration.primary_validator

    excluded_node_identifiers = [
        self_configuration.node_identifier, primary_validator.node_identifier
    ]

    if nodes_type == BANK:
        model = Bank
    elif nodes_type == CONFIRMATION_VALIDATOR:
        model = Validator
    else:
        raise RuntimeError(f'Invalid nodes_type of {nodes_type}')

    nodes = model.objects.all().exclude(
        node_identifier__in=excluded_node_identifiers)
    nodes_to_delete = []

    for node in nodes:

        if cache.get(CLEAN_STATUS) == CLEAN_STATUS_STOP_REQUESTED:
            break

        try:
            address = format_address(ip_address=node.ip_address,
                                     port=node.port,
                                     protocol=node.protocol)
            config_address = f'{address}/config'
            config_data = fetch(url=config_address, headers={})
        except Exception as e:
            capture_exception(e)
            logger.exception(e)
            nodes_to_delete.append(node.id)
            continue

        for field in ['ip_address', 'port', 'protocol', 'node_identifier']:

            if config_data.get(field) != getattr(node, field):
                nodes_to_delete.append(node.id)
                continue

        if nodes_type == BANK:
            serializer = BankConfigurationSerializer(data=config_data)

            if serializer.is_valid():
                update_bank_from_config_data(bank=node,
                                             config_data=config_data)
            else:
                logger.exception(serializer.errors)
                nodes_to_delete.append(node.id)
                continue

        if nodes_type == CONFIRMATION_VALIDATOR:
            serializer = ValidatorConfigurationSerializer(data=config_data)

            if serializer.is_valid():
                update_validator_from_config_data(validator=node,
                                                  config_data=config_data)
            else:
                logger.exception(serializer.errors)
                nodes_to_delete.append(node.id)
                continue

    nodes.filter(id__in=nodes_to_delete).delete()