Exemple #1
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)
Exemple #2
0
def test_invalid_account_number(client, account, self_configuration):
    client.patch_json(
        reverse('account-detail', args=[account.account_number + 'abcdef']),
        generate_signed_request(data={'trust': 100},
                                nid_signing_key=get_signing_key()),
        expected=HTTP_404_NOT_FOUND,
    )
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)
Exemple #4
0
async def test_crawl_status_async(client, confirmation_validator_configuration, celery_worker):

    communicator = WebsocketCommunicator(
        CrawlStatusConsumer,
        'ws/crawl_status'
    )
    connected, subprotocol = await communicator.connect()
    assert connected

    await sync_to_async(
        client.post_json
    )(
        reverse('crawl-list'),
        generate_signed_request(
            data={
                'crawl': CRAWL_COMMAND_START
            },
            nid_signing_key=get_signing_key()
        ),
        expected=HTTP_200_OK
    )
    async_response = await communicator.receive_json_from(timeout=3)
    await communicator.disconnect()
    crawl_status = async_response['payload']

    assert async_response['notification_type'] == CRAWL_STATUS_NOTIFICATION
    assert crawl_status['crawl_last_completed']
    assert crawl_status['crawl_status'] == CRAWL_STATUS_NOT_CRAWLING
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
def run(send_to_node=False):
    """
    Generate signed PATCH request
    """

    # Signed request
    sk = read_signing_key_file(os.path.join(SIGNING_KEY_DIR, 'bank_nid'))

    payload = {
        'trust': 76.26
    }

    target_nid = BANK_NID_ACCOUNT_NUMBER

    signed_request = generate_signed_request(
        data=payload,
        nid_signing_key=sk
    )

    if send_to_node:
        send_request_to_node(signed_request, target_nid)

    write_json(
        os.path.join(SIGNED_REQUESTS_DIR, 'bank-patch-request.json'),
        signed_request
    )
Exemple #7
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
Exemple #8
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)
Exemple #9
0
def run(send_to_cv=False):
    """
    Generate primary validator updated notice (from bank)
    """

    # Signed request
    sk = read_signing_key_file(os.path.join(SIGNING_KEY_DIR, 'bank_nid'))

    new_pv_data = {
        'ip_address': '192.168.1.20',
        'port': '8000',
        'protocol': 'http'
    }

    signed_request = generate_signed_request(
        data=new_pv_data,
        nid_signing_key=sk
    )

    if send_to_cv:
        send_request_to_cv(signed_request)

    write_json(
        os.path.join(SIGNED_REQUESTS_DIR, 'primary-validator-updated-request.json'),
        signed_request
    )
Exemple #10
0
def validator_connection_requests_signed_request(validator, signing_key):
    yield generate_signed_request(data={
        'ip_address': validator.ip_address,
        'port': validator.port,
        'protocol': validator.protocol,
    },
                                  nid_signing_key=signing_key)
Exemple #11
0
def bank_connection_requests_signed_request(bank, signing_key):
    yield generate_signed_request(data={
        'ip_address': bank.ip_address,
        'port': bank.port,
        'protocol': bank.protocol,
    },
                                  nid_signing_key=signing_key)
async def test_validator_confirmation_service_post_async(
        client, validator, signing_key):
    communicator = WebsocketCommunicator(ValidatorConfirmationServiceConsumer,
                                         'ws/validator_confirmation_services')
    connected, subprotocol = await communicator.connect()
    assert connected

    start = datetime.now().isoformat()
    end = (datetime.now() + timedelta(days=2)).isoformat()

    payload = generate_signed_request(data={
        'start': start,
        'end': end
    },
                                      nid_signing_key=signing_key)

    response = await sync_to_async(client.post_json)(
        reverse('validatorconfirmationservice-list'),
        payload,
        expected=HTTP_201_CREATED)
    communicator_response = await communicator.receive_json_from()

    assert response['end'][:-1] == end
    assert response['start'][:-1] == start
    assert response['validator'] == str(validator.pk)

    assert communicator_response == {
        'notification_type': VALIDATOR_CONFIRMATION_SERVICE_NOTIFICATION,
        'payload': {
            'bank_node_identifier': validator.node_identifier,
            'validator_confirmation_service': response
        }
    }

    await communicator.disconnect()
def crawl_request(client, command, status):
    return client.post_json(
        reverse('crawl-list'),
        generate_signed_request(data={'crawl': command},
                                nid_signing_key=get_signing_key()),
        expected=status,
    )
Exemple #14
0
def test_banks_post_201_confirmation_validator(
        client, validator_connection_request_data, signing_key,
        self_configuration, requests_mock):
    primary_validator = PrimaryValidatorConfigurationSerializer(
        self_configuration.primary_validator)

    validator_connection_request_data[
        'primary_validator'] = primary_validator.data
    address = format_address(
        ip_address=validator_connection_request_data['ip_address'],
        port=validator_connection_request_data.get('port'),
        protocol=validator_connection_request_data['protocol'])
    requests_mock.get(f'{address}/config',
                      json=validator_connection_request_data)

    response = client.post_json(reverse('connection_requests-list'),
                                generate_signed_request(
                                    data=validator_connection_request_data,
                                    nid_signing_key=signing_key,
                                ),
                                expected=status.HTTP_201_CREATED)

    assert response == {}
    assert Validator.objects.get(
        ip_address=validator_connection_request_data['ip_address'])
def sign_block_to_confirm_and_update_head_block_hash(*, block, existing_accounts, new_accounts):
    """
    Sign block to confirm validity
    Update HEAD_BLOCK_HASH
    """

    try:
        head_block_hash = cache.get(HEAD_BLOCK_HASH)

        message = {
            'block': block,
            'block_identifier': head_block_hash,
            'updated_balances': format_updated_balances(existing_accounts, new_accounts)
        }
        confirmation_block = generate_signed_request(
            data=message,
            nid_signing_key=get_signing_key()
        )

        message_hash = get_message_hash(message=message)
        cache.set(HEAD_BLOCK_HASH, message_hash, None)

        return confirmation_block, message_hash
    except Exception as e:
        capture_exception(e)
        logger.exception(e)
Exemple #16
0
def set_primary_validator(client, self_configuration, signing_key, status):

    return client.post_json(
        reverse('upgrade_notice-list'),
        generate_signed_request(
            data={'bank_node_identifier': self_configuration.node_identifier},
            nid_signing_key=signing_key),
        expected=status)
Exemple #17
0
def bank_connection_requests_signed_request_new_node_identifier(bank):
    signing_key, _ = create_account()
    yield generate_signed_request(data={
        'ip_address': bank.ip_address,
        'port': bank.port,
        'protocol': bank.protocol,
    },
                                  nid_signing_key=signing_key)
Exemple #18
0
def confirmation_block_data(block_data, signing_key, confirmation_block_fake_data):
    yield generate_signed_request(
        data={
            'block': block_data,
            'block_identifier': confirmation_block_fake_data['block_identifier'],
            'updated_balances': [],
        },
        nid_signing_key=signing_key
    )
Exemple #19
0
def test_bank_account_number_trust(client, account, self_configuration, trust,
                                   response_msg):
    response = client.patch_json(
        reverse('account-detail', args=[account.account_number]),
        generate_signed_request(data={'trust': trust},
                                nid_signing_key=get_signing_key()),
        expected=HTTP_400_BAD_REQUEST,
    )
    assert response['trust'] == [response_msg]
Exemple #20
0
def test_banks_post(client, bank_fake_data, self_configuration):
    response = client.post_json(reverse('bank-list'),
                                generate_signed_request(
                                    data=bank_fake_data,
                                    nid_signing_key=get_signing_key(),
                                ),
                                expected=status.HTTP_201_CREATED)
    bank_fake_data['trust'] = f'{bank_fake_data["trust"]:.2f}'
    assert response == bank_fake_data
Exemple #21
0
def test_accounts_patch(client, account, account_fake_data,
                        self_configuration):
    response = client.patch_json(
        reverse('account-detail', args=[account.account_number]),
        generate_signed_request(data=account_fake_data,
                                nid_signing_key=get_signing_key()),
        expected=HTTP_200_OK,
    )
    assert response['account_number'] != account_fake_data['account_number']
    assert float(response['trust']) == account_fake_data['trust']
Exemple #22
0
def invalid_block_data(block_data, signing_key, invalid_block_fake_data):
    yield generate_signed_request(data={
        'block':
        block_data,
        'block_identifier':
        invalid_block_fake_data['block_identifier'],
        'primary_validator_node_identifier':
        get_primary_validator().node_identifier,
    },
                                  nid_signing_key=signing_key)
Exemple #23
0
def test_banks_patch(client, bank, bank_fake_data, self_configuration):
    response = client.patch_json(
        reverse('bank-detail', args=[bank.node_identifier]),
        generate_signed_request(
            data=bank_fake_data,
            nid_signing_key=get_signing_key(),
        ),
        expected=status.HTTP_200_OK,
    )
    assert response['trust'] == f'{bank_fake_data["trust"]:.2f}'
def test_crawl_start_200(client, primary_validator_configuration):
    client.post_json(
        reverse('crawl-list'),
        generate_signed_request(
            data={'crawl': CRAWL_COMMAND_START},
            nid_signing_key=get_signing_key(),
        ),
        expected=HTTP_404_NOT_FOUND,
    )
    assert cache.get(CRAWL_STATUS) is None
Exemple #25
0
def primary_validator_updated(client, signing_key, validator, status):
    return client.post_json(reverse('primary_validator_updated-list'),
                            generate_signed_request(
                                data={
                                    'ip_address': validator.ip_address,
                                    'port': validator.port,
                                    'protocol': validator.protocol,
                                },
                                nid_signing_key=signing_key),
                            expected=status)
Exemple #26
0
def test_validator_patch(client, primary_validator_configuration, validator,
                         validator_fake_data):
    response = client.patch_json(
        reverse('validator-detail', args=[validator.node_identifier]),
        generate_signed_request(
            data=validator_fake_data,
            nid_signing_key=get_signing_key(),
        ),
        expected=HTTP_200_OK,
    )
    assert float(response['trust']) == validator_fake_data['trust']
Exemple #27
0
def test_banks_post(client, primary_validator_configuration, bank, bank_fake_data):
    response = client.post_json(
        reverse('bank-list'),
        generate_signed_request(
            data=bank_fake_data,
            nid_signing_key=get_signing_key(),
        ),
        expected=HTTP_200_OK,
    )

    assert float(response['trust']) == bank_fake_data['trust']
Exemple #28
0
def validator_connection_requests_signed_request_connect_to_itself(
        primary_validator_configuration):
    signing_key, _ = create_account()
    yield generate_signed_request(data={
        'ip_address':
        primary_validator_configuration.ip_address,
        'port':
        primary_validator_configuration.port,
        'protocol':
        primary_validator_configuration.protocol,
    },
                                  nid_signing_key=signing_key)
Exemple #29
0
def test_update_bank_with_invalid_trust_value(client, bank, self_configuration,
                                              trust, response_msg):
    response = client.patch_json(
        reverse('bank-detail', args=[bank.node_identifier]),
        generate_signed_request(
            data={'trust': trust},
            nid_signing_key=get_signing_key(),
        ),
        expected=status.HTTP_400_BAD_REQUEST,
    )

    assert response['trust'] == [response_msg]
Exemple #30
0
def test_banks_post_400_connect_to_self(client, bank_connection_request_data,
                                        signing_key, self_configuration):
    bank_connection_request_data['ip_address'] = self_configuration.ip_address
    bank_connection_request_data['protocol'] = self_configuration.protocol

    response = client.post_json(
        reverse('connection_requests-list'),
        generate_signed_request(
            data=bank_connection_request_data,
            nid_signing_key=signing_key,
        ),
        expected=HTTP_400_BAD_REQUEST,
    )
    assert response == {'non_field_errors': ['Unable to connect to self']}