Exemple #1
0
def test_successful_handshake_with_enr_update():
    initiator_private_key = PrivateKeyFactory().to_bytes()
    recipient_private_key = PrivateKeyFactory().to_bytes()
    old_initiator_enr = ENRFactory(private_key=initiator_private_key)
    new_initiator_enr = ENRFactory(
        private_key=initiator_private_key,
        sequence_number=old_initiator_enr.sequence_number + 1,
    )

    initiator = HandshakeInitiatorFactory(
        local_private_key=initiator_private_key,
        local_enr=new_initiator_enr,
        remote_private_key=recipient_private_key,
    )
    recipient = HandshakeRecipientFactory(
        local_private_key=recipient_private_key,
        remote_enr=old_initiator_enr,
        initiating_packet_auth_tag=initiator.first_packet_to_send.auth_tag)

    initiator_result = initiator.complete_handshake(
        recipient.first_packet_to_send)
    recipient_result = recipient.complete_handshake(
        initiator_result.auth_header_packet)

    assert initiator_result.enr is None
    assert recipient_result.enr == new_initiator_enr
Exemple #2
0
def test_successful_handshake():
    initiator_private_key = PrivateKeyFactory().to_bytes()
    recipient_private_key = PrivateKeyFactory().to_bytes()
    initiator_enr = ENRFactory(private_key=initiator_private_key)
    recipient_enr = ENRFactory(private_key=recipient_private_key)
    initial_message = PingMessageFactory()

    initiator = HandshakeInitiatorFactory(
        local_private_key=initiator_private_key,
        local_enr=initiator_enr,
        remote_enr=recipient_enr,
        initial_message=initial_message,
    )
    recipient = HandshakeRecipientFactory(
        local_private_key=recipient_private_key,
        local_enr=recipient_enr,
        remote_enr=initiator_enr,
        initiating_packet_auth_tag=initiator.first_packet_to_send.auth_tag)

    initiator_result = initiator.complete_handshake(
        recipient.first_packet_to_send)
    recipient_result = recipient.complete_handshake(
        initiator_result.auth_header_packet)

    assert_session_keys_equal(initiator_result.session_keys,
                              recipient_result.session_keys)

    assert initiator_result.message is None
    assert initiator_result.enr is None
    assert initiator_result.auth_header_packet is not None

    assert recipient_result.message == initial_message
    assert recipient_result.enr is None
    assert recipient_result.auth_header_packet is None
Exemple #3
0
def test_successful_handshake_with_new_enr():
    initiator_private_key = PrivateKeyFactory().to_bytes()
    recipient_private_key = PrivateKeyFactory().to_bytes()
    initiator_enr = ENRFactory(private_key=initiator_private_key)
    recipient_enr = ENRFactory(private_key=recipient_private_key)

    initiator = HandshakeInitiatorFactory(
        local_private_key=initiator_private_key,
        local_enr=initiator_enr,
        remote_enr=recipient_enr,
    )
    recipient = HandshakeRecipientFactory(
        local_private_key=recipient_private_key,
        local_enr=recipient_enr,
        remote_enr=None,
        remote_node_id=initiator_enr.node_id,
        initiating_packet_auth_tag=initiator.first_packet_to_send.auth_tag)

    initiator_result = initiator.complete_handshake(
        recipient.first_packet_to_send)
    recipient_result = recipient.complete_handshake(
        initiator_result.auth_header_packet)

    assert initiator_result.enr is None
    assert recipient_result.enr == initiator_enr
Exemple #4
0
def test_wait_time_full_queue_and_table(topic_table, max_queue_size,
                                        target_ad_lifetime):
    # fill one queue
    topic = TopicFactory()
    reg_time = 0
    oldest_queue_eol = reg_time + target_ad_lifetime
    while not topic_table.is_queue_full(topic):
        topic_table.register(topic, ENRFactory(), reg_time)
        reg_time += 1

    # fill the rest of the table
    oldest_table_eol = reg_time + target_ad_lifetime
    while not topic_table.is_full:
        topic_table.register(TopicFactory(), ENRFactory(), reg_time)
        reg_time += 1

    assert topic_table.get_wait_time(topic, 0) == oldest_queue_eol
    assert topic_table.get_wait_time(TopicFactory(), 0) == oldest_queue_eol

    # refill queue
    oldest_queue_eol = reg_time + target_ad_lifetime
    for _ in range(max_queue_size):
        topic_table.register(topic, ENRFactory(), reg_time)
        reg_time += 1

    assert topic_table.get_wait_time(topic, 0) == oldest_queue_eol
    assert topic_table.get_wait_time(TopicFactory(), 0) == oldest_table_eol
Exemple #5
0
def test_registration_single_queue(topic_table, max_queue_size):
    topic = TopicFactory()
    enr = ENRFactory()
    other_enr = ENRFactory()

    topic_table.get_enrs_for_topic(topic) == ()
    topic_table.register(topic, enr, 0)
    assert topic_table.get_enrs_for_topic(topic) == (enr, )
    topic_table.register(topic, other_enr, 0)
    assert topic_table.get_enrs_for_topic(topic) == (other_enr, enr)

    with pytest.raises(ValueError):
        topic_table.register(topic, enr, 0)

    while not topic_table.is_queue_full(topic):
        topic_table.register(topic, ENRFactory(), 0)

    with pytest.raises(ValueError):
        topic_table.register(topic, ENRFactory(), 0)

    enrs_before = topic_table.get_enrs_for_topic(topic)
    new_enr = ENRFactory()
    topic_table.register(topic, new_enr, topic_table.get_wait_time(topic, 0))
    enrs_after = topic_table.get_enrs_for_topic(topic)
    assert enrs_after == (new_enr, ) + enrs_before[:-1]
Exemple #6
0
def test_wait_time_full_table(topic_table, target_ad_lifetime):
    # fill one queue
    reg_time = 0
    oldest_table_eol = reg_time + target_ad_lifetime
    while not topic_table.is_full:
        assert topic_table.get_wait_time(TopicFactory(), 0) == 0
        topic_table.register(TopicFactory(), ENRFactory(), reg_time)
        reg_time += 1

    assert topic_table.get_wait_time(TopicFactory(), 0) == oldest_table_eol
    topic_table.register(TopicFactory(), ENRFactory(), reg_time)
    assert topic_table.get_wait_time(TopicFactory(), 0) == oldest_table_eol + 1
async def test_insert_or_update(db):
    private_key = PrivateKeyFactory().to_bytes()
    enr = ENRFactory(private_key=private_key)

    await db.insert_or_update(enr)
    assert await db.get(enr.node_id) == enr

    await db.insert_or_update(enr)
    assert await db.get(enr.node_id) == enr

    updated_enr = ENRFactory(private_key=private_key,
                             sequence_number=enr.sequence_number + 1)
    await db.insert_or_update(updated_enr)
    assert await db.get(enr.node_id) == updated_enr
Exemple #8
0
def test_registration_two_queues(topic_table, max_queue_size):
    topic1 = TopicFactory()
    topic2 = TopicFactory()
    enr = ENRFactory()

    topic_table.register(topic1, enr, 0)
    while not topic_table.is_queue_full(topic1):
        topic_table.register(topic1, ENRFactory(), 0)

    topic_table.register(topic2, enr, 1)
    while not topic_table.is_queue_full(topic2):
        topic_table.register(topic2, ENRFactory(), 1)

    with pytest.raises(ValueError):
        topic_table.register(topic1, ENRFactory(), 1)
    with pytest.raises(ValueError):
        topic_table.register(topic2, ENRFactory(), 1)
    with pytest.raises(ValueError):
        topic_table.register(topic2, ENRFactory(),
                             topic_table.get_wait_time(topic1, 0))

    enrs_topic1_before = topic_table.get_enrs_for_topic(topic1)
    enrs_topic2_before = topic_table.get_enrs_for_topic(topic2)
    new_enr_topic1 = ENRFactory()
    new_enr_topic2 = ENRFactory()

    topic_table.register(topic1, new_enr_topic1,
                         topic_table.get_wait_time(topic1, 0))
    topic_table.register(topic2, new_enr_topic2,
                         topic_table.get_wait_time(topic2, 0))

    enrs_topic1_after = topic_table.get_enrs_for_topic(topic1)
    enrs_topic2_after = topic_table.get_enrs_for_topic(topic2)
    assert enrs_topic1_after == (new_enr_topic1, ) + enrs_topic1_before[:-1]
    assert enrs_topic2_after == (new_enr_topic2, ) + enrs_topic2_before[:-1]
async def test_insert(db):
    private_key = PrivateKeyFactory().to_bytes()
    enr = ENRFactory(private_key=private_key)

    await db.insert(enr)
    assert await db.contains(enr.node_id)
    assert await db.get(enr.node_id) == enr

    with pytest.raises(ValueError):
        await db.insert(enr)

    updated_enr = ENRFactory(private_key=private_key,
                             sequence_number=enr.sequence_number + 1)
    with pytest.raises(ValueError):
        await db.insert(updated_enr)
def remote_enr(remote_endpoint):
    return ENRFactory(
        custom_kv_pairs={
            b"ip": remote_endpoint.ip_address,
            b"udp": remote_endpoint.port,
        },
    )
async def test_update(db):
    private_key = PrivateKeyFactory().to_bytes()
    enr = ENRFactory(private_key=private_key)

    with pytest.raises(KeyError):
        await db.update(enr)

    await db.insert(enr)

    await db.update(enr)
    assert await db.get(enr.node_id) == enr

    updated_enr = ENRFactory(private_key=private_key,
                             sequence_number=enr.sequence_number + 1)
    await db.update(updated_enr)
    assert await db.get(enr.node_id) == updated_enr
async def test_file_db_saves_enrs(file_db_dir, file_db):
    enr = ENRFactory()
    await file_db.insert(enr)
    filename = get_enr_filename(enr)
    assert (file_db_dir / filename).exists()
    assert (file_db_dir / filename).is_file()
    assert ENR.from_repr((file_db_dir / filename).read_text()) == enr
async def filled_routing_table(routing_table, node_db):
    # add entries until the first bucket is full
    while len(routing_table.get_nodes_at_log_distance(255)) < routing_table.bucket_size:
        enr = ENRFactory()
        routing_table.update(enr.node_id)
        node_db.set_enr(enr)
    return routing_table
Exemple #14
0
def enr(private_key, endpoint):
    return ENRFactory(
        private_key=private_key,
        custom_kv_pairs={
            b"ip": endpoint.ip_address,
            b"udp": endpoint.port,
        }
    )
Exemple #15
0
def remote_enr(remote_private_key, remote_endpoint):
    return ENRFactory(
        private_key=remote_private_key,
        custom_kv_pairs={
            b"ip": remote_endpoint.ip_address,
            b"udp": remote_endpoint.port,
        }
    )
Exemple #16
0
def test_wait_time_full_queue(topic_table, max_total_size, target_ad_lifetime):
    topic = TopicFactory()
    different_topic = TopicFactory()

    reg_time = 0
    oldest_queue_eol = reg_time + target_ad_lifetime
    while not topic_table.is_queue_full(topic):
        assert topic_table.get_wait_time(topic, 0) == 0
        assert topic_table.get_wait_time(different_topic, 0) == 0
        topic_table.register(topic, ENRFactory(), reg_time)
        reg_time += 1

    assert topic_table.get_wait_time(topic, 0) == oldest_queue_eol
    assert topic_table.get_wait_time(different_topic, 0) == 0
    topic_table.register(topic, ENRFactory(), reg_time)
    assert topic_table.get_wait_time(topic, 0) == oldest_queue_eol + 1
    assert topic_table.get_wait_time(different_topic, 0) == 0
async def test_get(db):
    enr = ENRFactory()

    with pytest.raises(KeyError):
        await db.get(enr.node_id)

    await db.insert(enr)
    assert await db.get(enr.node_id) == enr
Exemple #18
0
def test_get_and_set_enr(node_db):
    private_key = PrivateKeyFactory().to_bytes()
    db = node_db
    enr = ENRFactory(private_key=private_key)

    with pytest.raises(KeyError):
        db.get_enr(enr.node_id)

    db.set_enr(enr)
    assert db.get_enr(enr.node_id) == enr

    updated_enr = ENRFactory(private_key=private_key, sequence_number=enr.sequence_number + 1)
    db.set_enr(updated_enr)
    assert db.get_enr(enr.node_id) == updated_enr

    with pytest.raises(ValueError):
        db.set_enr(enr)
async def test_memory_checks_identity_scheme():
    empty_identity_scheme_registry = IdentitySchemeRegistry()
    memory_db = MemoryEnrDb(empty_identity_scheme_registry)
    enr = ENRFactory()

    with pytest.raises(ValueError):
        await memory_db.insert(enr)
    with pytest.raises(ValueError):
        await memory_db.insert_or_update(enr)
async def test_memory_remove(memory_db):
    enr = ENRFactory()

    with pytest.raises(KeyError):
        await memory_db.remove(enr.node_id)

    await memory_db.insert(enr)
    await memory_db.remove(enr.node_id)

    assert not await memory_db.contains(enr.node_id)
async def test_generate_eth_cap_enr_field():
    base_db = AtomicDB()
    ChainDB(base_db).persist_header(ROPSTEN_GENESIS_HEADER)

    enr_field = await generate_eth_cap_enr_field(ROPSTEN_VM_CONFIGURATION,
                                                 AsyncHeaderDB(base_db))

    enr = ENRFactory(custom_kv_pairs={enr_field[0]: enr_field[1]})
    assert extract_forkid(enr) == ForkID(hash=to_bytes(hexstr='0x30c7ddbc'),
                                         next=10)
Exemple #22
0
def test_table_size(topic_table, max_queue_size, target_ad_lifetime):
    assert len(topic_table) == 0

    topic = TopicFactory()
    topic_table.register(topic, ENRFactory(), 0)
    assert len(topic_table) == 1

    topic_table.register(topic, ENRFactory(), 0)
    assert len(topic_table) == 2

    topic2 = TopicFactory()
    topic_table.register(topic2, ENRFactory(), 0)
    assert len(topic_table) == 3

    topic3 = TopicFactory()
    for _ in range(max_queue_size):
        topic_table.register(topic3, ENRFactory(), 0)
    assert len(topic_table) == 3 + max_queue_size
    topic_table.register(topic3, ENRFactory(), target_ad_lifetime)
    assert len(topic_table) == 3 + max_queue_size
def test_get_and_set_last_pong_time(node_db):
    db = node_db
    enr = ENRFactory()

    with pytest.raises(KeyError):
        db.get_last_pong_time(enr.node_id)

    pong_time = int(time.monotonic())
    db.set_last_pong_time(enr.node_id, pong_time)

    assert db.get_last_pong_time(enr.node_id) == pong_time
def test_delete_enr(node_db):
    db = node_db
    enr = ENRFactory()

    with pytest.raises(KeyError):
        db.delete_enr(enr.node_id)

    db.set_enr(enr)
    db.delete_enr(enr.node_id)

    with pytest.raises(KeyError):
        db.get_enr(enr.node_id)
Exemple #25
0
def _make_node_with_enr_and_forkid(genesis_hash, head, vm_config):
    fork_blocks = forkid.extract_fork_blocks(vm_config)
    node_forkid = forkid.make_forkid(genesis_hash, head, fork_blocks)
    ip = socket.inet_aton(IPAddressFactory.generate())
    udp_port = 30304
    enr = ENRFactory(
        custom_kv_pairs={
            b'eth': sedes.List([forkid.ForkID]).serialize([node_forkid]),
            IP_V4_ADDRESS_ENR_KEY: ip,
            UDP_PORT_ENR_KEY: udp_port,
            TCP_PORT_ENR_KEY: udp_port,
        })
    return Node(enr)
def test_delete_last_pong_time(node_db):
    db = node_db
    enr = ENRFactory()

    with pytest.raises(KeyError):
        db.delete_last_pong_time(enr.node_id)

    pong_time = int(time.monotonic())
    db.set_last_pong_time(enr.node_id, pong_time)

    db.delete_last_pong_time(enr.node_id)

    with pytest.raises(KeyError):
        db.get_last_pong_time(enr.node_id)
async def test_request_nodes(message_dispatcher, remote_enr, remote_endpoint,
                             incoming_message_channels,
                             outgoing_message_channels, nursery):
    request_id = message_dispatcher.get_free_request_id(remote_enr.node_id)
    request = FindNodeMessage(
        request_id=request_id,
        distance=3,
    )
    enrs_per_message = [[ENRFactory() for _ in range(2)] for _ in range(3)]
    response_messages = [
        NodesMessage(request_id=request_id,
                     total=len(enrs_per_message),
                     enrs=enrs) for enrs in enrs_per_message
    ]

    async def handle_request_on_remote():
        async for outgoing_message in outgoing_message_channels[1]:
            assert outgoing_message.message == request
            assert outgoing_message.receiver_endpoint == remote_endpoint
            assert outgoing_message.receiver_node_id == remote_enr.node_id

            for response in response_messages:
                await incoming_message_channels[0].send(
                    IncomingMessage(
                        message=response,
                        sender_endpoint=remote_endpoint,
                        sender_node_id=remote_enr.node_id,
                    ))

    nursery.start_soon(handle_request_on_remote)

    with trio.fail_after(3):
        received_responses = await message_dispatcher.request_nodes(
            remote_enr.node_id, request)
    assert len(received_responses) == len(response_messages)
    for received_response, expected_response_message in zip(
            received_responses, response_messages):
        assert received_response.sender_endpoint == remote_endpoint
        assert received_response.sender_node_id == remote_enr.node_id
        assert received_response.message == expected_response_message
Exemple #28
0
def test_registration_full_table(topic_table, max_queue_size, max_total_size):
    for _ in range(max_total_size):
        topic_table.register(TopicFactory(), ENRFactory(), 0)
    assert topic_table.is_full

    with pytest.raises(ValueError):
        topic_table.register(TopicFactory(), ENRFactory(), 0)
    wait_time = topic_table.get_wait_time(TopicFactory(), 0)
    topic_table.register(TopicFactory(), ENRFactory(), wait_time)

    topic = TopicFactory()
    assert not topic_table.is_queue_full(topic)
    while not topic_table.is_queue_full(topic):
        topic_table.register(topic, ENRFactory(),
                             topic_table.get_wait_time(topic, 0))

    with pytest.raises(ValueError):
        topic_table.register(TopicFactory(), ENRFactory(), 0)
    wait_time = topic_table.get_wait_time(TopicFactory(), 0)
    topic_table.register(TopicFactory(), ENRFactory(), wait_time)
Exemple #29
0
def remote_enr(remote_private_key):
    return ENRFactory(private_key=remote_private_key)
def initial_enr(private_key):
    return ENRFactory(private_key=private_key, )