def send_confirmation_block_history(*, block_identifier, ip_address, port,
                                    protocol):
    """
    Send historical confirmation blocks (starting with the block_identifier) to the confirmation validator
    """

    address = format_address(ip_address=ip_address,
                             port=port,
                             protocol=protocol)
    url = f'{address}/confirmation_blocks'

    valid_confirmation_block = get_valid_confirmation_block(
        block_identifier=block_identifier)

    while valid_confirmation_block:

        try:
            post(url=url, body=valid_confirmation_block)
        except Exception as e:
            capture_exception(e)
            logger.exception(e)

        block_identifier = get_message_hash(
            message=valid_confirmation_block['message'])
        valid_confirmation_block = get_valid_confirmation_block(
            block_identifier=block_identifier)
Esempio n. 2
0
def send_signed_block(*, block, ip_address, port, protocol, url_path):
    """
    Sign block and send to recipient
    """

    signing_key = get_signing_key()
    node_identifier = get_verify_key(signing_key=signing_key)
    node_identifier = encode_verify_key(verify_key=node_identifier)
    message = sort_and_encode(block)

    signed_block = {
        'block': block,
        'node_identifier': node_identifier,
        'signature': generate_signature(message=message,
                                        signing_key=signing_key)
    }
    node_address = format_address(ip_address=ip_address,
                                  port=port,
                                  protocol=protocol)
    url = f'{node_address}{url_path}'

    try:
        post(url=url, body=signed_block)
    except Exception as e:
        request_new_primary_validator()
        logger.exception(e)
def connect_to_primary_validator(*, primary_validator):
    """
    Connect to a validator

    - used in the syncing process
    """
    self_configuration = get_self_configuration(exception_class=RuntimeError)

    primary_validator_address = format_address(
        ip_address=primary_validator.ip_address,
        port=primary_validator.port,
        protocol=primary_validator.protocol,
    )

    if is_connected_to_primary_validator(
            primary_validator_address=primary_validator_address,
            self_configuration=self_configuration):
        return

    signed_request = generate_signed_request(data={
        'ip_address':
        self_configuration.ip_address,
        'port':
        self_configuration.port,
        'protocol':
        self_configuration.protocol
    },
                                             nid_signing_key=get_signing_key())
    url = f'{primary_validator_address}/connection_requests'

    try:
        post(url=url, body=signed_request)
    except Exception as e:
        logger.exception(e)
        raise e
Esempio n. 4
0
def send_primary_validator_updated_notices():
    """
    Send a notice to all validators that the banks primary validator has been updated

    - 200 response > validator is syncing to new primary validator
    - 400 response > validator is not syncing to new primary validator (can be deleted)
    """
    self_configuration = get_self_configuration(exception_class=RuntimeError)
    primary_validator = self_configuration.primary_validator
    confirmation_validators = Validator.objects.all().exclude(node_identifier=primary_validator.node_identifier)

    data = {
        'ip_address': primary_validator.ip_address,
        'port': primary_validator.port,
        'protocol': primary_validator.protocol
    }

    for confirmation_validator in confirmation_validators:
        signed_request = generate_signed_request(
            data=data,
            nid_signing_key=get_signing_key()
        )
        node_address = format_address(
            ip_address=confirmation_validator.ip_address,
            port=confirmation_validator.port,
            protocol=confirmation_validator.protocol,
        )
        url = f'{node_address}/primary_validator_updated'

        try:
            post(url=url, body=signed_request)
        except Exception as e:
            confirmation_validator.delete()
            logger.exception(e)
Esempio n. 5
0
def send_connection_request(*, node, self_configuration):
    """
    Send connection request to node
    """

    node_address = format_address(
        ip_address=node.ip_address,
        port=node.port,
        protocol=node.protocol,
    )

    signed_request = generate_signed_request(data={
        'ip_address':
        self_configuration.ip_address,
        'port':
        self_configuration.port,
        'protocol':
        self_configuration.protocol
    },
                                             nid_signing_key=get_signing_key())
    url = f'{node_address}/connection_requests'

    try:
        post(url=url, body=signed_request)
    except Exception as e:
        logger.exception(e)
        raise e
Esempio n. 6
0
def send_confirmation_block_history_request():
    """
    Request missing blocks from the primary validator
    """

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

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

    signed_request = generate_signed_request(
        data={
            'block_identifier': cache.get(HEAD_BLOCK_HASH)
        },
        nid_signing_key=get_signing_key()
    )

    try:
        post(url=url, body=signed_request)
    except Exception as e:
        capture_exception(e)
        logger.exception(e)
def send_invalid_block_to_banks(*, confirmation_block):
    """
    Send invalid block to banks
    This function is called by the confirmation validators only
    """

    block = confirmation_block['block']
    block_identifier = confirmation_block['block_identifier']

    self_configuration = get_self_configuration(exception_class=RuntimeError)
    primary_validator_node_identifier = self_configuration.primary_validator.node_identifier
    self_configuration.primary_validator = None
    self_configuration.save()

    invalid_block = generate_signed_request(data={
        'block':
        block,
        'block_identifier':
        block_identifier,
        'primary_validator_node_identifier':
        primary_validator_node_identifier
    },
                                            nid_signing_key=get_signing_key())

    for bank in get_banks_with_active_confirmation_services():
        address = format_address(ip_address=bank.ip_address,
                                 port=bank.port,
                                 protocol=bank.protocol)
        url = f'{address}/invalid_blocks'

        try:
            post(url=url, body=invalid_block)
        except Exception as e:
            logger.exception(e)
Esempio n. 8
0
def send_signed_block(*, block, ip_address, port, protocol, url_path):
    """
    Sign block and send to recipient
    """

    network_signing_key = get_environment_variable('NETWORK_SIGNING_KEY')
    signing_key = SigningKey(network_signing_key, encoder=HexEncoder)
    node_identifier = get_verify_key(signing_key=signing_key)
    node_identifier = encode_verify_key(verify_key=node_identifier)
    message = sort_and_encode(block)

    signed_block = {
        'block': block,
        'node_identifier': node_identifier,
        'signature': generate_signature(message=message,
                                        signing_key=signing_key)
    }

    node_address = format_address(ip_address=ip_address,
                                  port=port,
                                  protocol=protocol)
    url = f'{node_address}{url_path}'

    try:
        post(url=url, body=signed_block)
    except Exception as e:
        logger.exception(e)
Esempio n. 9
0
def send_signed_post_request(*, data, ip_address, port, protocol, url_path):
    """Sign data and send to recipient"""
    signed_request = generate_signed_request(data=data,
                                             nid_signing_key=get_signing_key())

    node_address = format_address(ip_address=ip_address,
                                  port=port,
                                  protocol=protocol)
    url = f'{node_address}{url_path}'

    try:
        post(url=url, body=signed_request)
    except Exception as e:
        capture_exception(e)
        logger.exception(e)
def send_confirmation_block_to_individual_confirmation_validator(
        *, confirmation_block, confirmation_validator_id,
        confirmation_validator_url):
    """
    Send a confirmed block to a confirmation validator

    If NetworkException then delete that confirmation validator
    - occurs when the confirmation validator has gone offline or is not configured properly
    """
    try:
        post(url=confirmation_validator_url, body=confirmation_block)
    except Exception as e:
        Validator.objects.filter(id=confirmation_validator_id).delete()
        capture_exception(e)
        logger.exception(e)
def send_confirmation_block_to_banks(*, confirmation_block):
    """
    Send confirmed block to banks with active confirmation services
    This function is called by the confirmation validators only
    - primary validators send their confirmation blocks to the confirmation validators
    """

    for bank in get_banks_with_active_confirmation_services():
        address = format_address(ip_address=bank.ip_address,
                                 port=bank.port,
                                 protocol=bank.protocol)
        url = f'{address}/confirmation_blocks'

        try:
            post(url=url, body=confirmation_block)
        except Exception as e:
            logger.exception(e)
Esempio n. 12
0
def send_signed_post_request(*, data, ip_address, port, protocol, url_path):
    """
    Sign data and send to recipient
    """

    network_signing_key = get_environment_variable('NETWORK_SIGNING_KEY')
    signing_key = SigningKey(network_signing_key, encoder=HexEncoder)

    signed_request = generate_signed_request(
        data=data,
        nid_signing_key=signing_key
    )

    node_address = format_address(ip_address=ip_address, port=port, protocol=protocol)
    url = f'{node_address}{url_path}'

    try:
        post(url=url, body=signed_request)
    except Exception as e:
        logger.exception(e)
def send_upgrade_notices(*, requesting_banks_node_identifier):
    """
    Description:

    - notice from a previous confirmation validator that they are now a primary validator
    - triggered from an /upgrade_request from the validators most trusted bank
    - banks that trust self more than their existing primary validator will set self as new primary validator
    - banks that do not trust self more than their existing primary validator will remain on their existing network and
      can therefore be deleted

    Responses:
    - 200 response > bank set self as new primary validator
    - 400 response > bank is remaining on their existing network (can be deleted)

    Notes:
        The requesting (most trusted) bank may be excluded from notice recipients since it will already receive the
        updated information from the /upgrade_request response
    """
    banks = Bank.objects.all().exclude(node_identifier=requesting_banks_node_identifier)

    for bank in banks:
        signed_request = generate_signed_request(
            data={
                'bank_node_identifier': bank.node_identifier
            },
            nid_signing_key=get_signing_key()
        )
        node_address = format_address(
            ip_address=bank.ip_address,
            port=bank.port,
            protocol=bank.protocol,
        )
        url = f'{node_address}/upgrade_notice'

        try:
            post(url=url, body=signed_request)
        except Exception as e:
            bank.delete()
            capture_exception(e)
            logger.exception(e)
Esempio n. 14
0
def send_confirmation_block_to_confirmation_validators(*, confirmation_block):
    """
    Send confirmed block to confirmation validators
    This function is called by the primary validator only
    - confirmation validators send their confirmation blocks to their banks
    """

    # TODO: Optimize
    self_configuration = get_self_configuration(exception_class=RuntimeError)
    confirmation_validators = Validator.objects.exclude(
        node_identifier=self_configuration.node_identifier)

    for validator in confirmation_validators:
        address = format_address(ip_address=validator.ip_address,
                                 port=validator.port,
                                 protocol=validator.protocol)
        url = f'{address}/confirmation_blocks'

        try:
            post(url=url, body=confirmation_block)
        except Exception as e:
            logger.exception(e)
def send_request_to_node(signed_request):
    """
    Send connection request to node
    """

    node_address = format_address(ip_address='64.225.47.205',
                                  port=80,
                                  protocol='http')
    url = f'{node_address}/connection_requests'
    results = post(url=url, body=signed_request)

    if isinstance(results, dict):
        for k, v in results.items():
            print(f'{k}: {v}')

    print(results)
Esempio n. 16
0
def send_request_to_pv(signed_request):
    """
    Send request to PV
    """

    node_address = format_address(ip_address='64.225.47.205',
                                  port=None,
                                  protocol='http')
    url = f'{node_address}/bank_blocks'
    results = post(url=url, body=signed_request)

    if isinstance(results, dict):
        for k, v in results.items():
            print(f'{k}: {v}')

    print(results)

    write_json(os.path.join(BLOCKS_DIR, 'bank-blocks-response.json'), results)
Esempio n. 17
0
def send_block_to_bank(block):
    """
    Send block to bank
    """

    next_balance_lock = get_message_hash(message=block['message'])
    print(f'\nNext balance lock will be: {next_balance_lock}\n')

    bank_address = format_address(ip_address='167.99.173.247',
                                  port=None,
                                  protocol='http')
    url = f'{bank_address}/blocks'
    results = post(url=url, body=block)

    if isinstance(results, dict):
        for k, v in results.items():
            print(f'{k}: {v}')

    write_json(os.path.join(BLOCKS_DIR, 'blocks-response.json'), results)
def send_request_to_cv(signed_request):
    """
    Send request to CV
    """

    node_address = format_address(ip_address='192.168.1.232',
                                  port=8000,
                                  protocol='http')
    url = f'{node_address}/upgrade_request'
    results = post(url=url, body=signed_request)

    if isinstance(results, dict):
        for k, v in results.items():
            print(f'{k}: {v}')

    print(results)

    write_json(
        os.path.join(SIGNED_REQUESTS_DIR, 'upgrade-request-response.json'),
        results)
def send_request_to_bank(signed_request):
    """
    Send request to bank
    """

    node_address = format_address(ip_address='192.168.1.232',
                                  port=8000,
                                  protocol='http')
    url = f'{node_address}/validator_confirmation_services'
    results = post(url=url, body=signed_request)

    if isinstance(results, dict):
        for k, v in results.items():
            print(f'{k}: {v}')

    print(results)

    write_json(
        os.path.join(SIGNED_REQUESTS_DIR,
                     'signed-validator-confirmation-services-response.json'),
        results)
Esempio n. 20
0
def set_primary_validator():
    """
    Set the primary validator to the validator that is the:

    - most trusted
    - online
    - configured as a primary validator
    """
    self_configuration = get_self_configuration(exception_class=RuntimeError)
    primary_validator = self_configuration.primary_validator
    primary_validator_candidates = get_primary_validator_candidates(current_primary_validator=primary_validator)

    for validator in primary_validator_candidates:
        signed_request = generate_signed_request(
            data={
                'validator_node_identifier': validator.node_identifier
            },
            nid_signing_key=get_signing_key()
        )
        node_address = format_address(
            ip_address=validator.ip_address,
            port=validator.port,
            protocol=validator.protocol,
        )
        url = f'{node_address}/upgrade_request'

        try:
            validator_config = post(url=url, body=signed_request)

            if validator_config['node_type'] != PRIMARY_VALIDATOR:
                continue

            self_configuration.primary_validator = validator
            self_configuration.save()

            send_primary_validator_updated_notices.delay()
            send_primary_validator_updated_notification()
            return
        except Exception as e:
            logger.exception(e)