def query(self, *constraints: ConstraintAPI) -> Iterable[ENRAPI]: """ Query the database for records that match the given constraints. Support constraints: - :class:`~eth_enr.constraints.KeyExists` - :class:`~eth_enr.constraints.HasTCPIPv4Endpoint` - :class:`~eth_enr.constraints.HasUDPIPv4Endpoint` - :class:`~eth_enr.constraints.HasTCPIPv6Endpoint` - :class:`~eth_enr.constraints.HasUDPIPv6Endpoint` Return an iterator of matching ENR records. Only returns the record with the highest sequence number for each node_id. """ required_keys = _get_required_keys(*constraints) order_closest_to = _get_order_closest_to(*constraints) records_iter = query_records( self.connection, required_keys=required_keys, order_closest_to=order_closest_to, ) for record in records_iter: yield record.to_enr()
def test_record_query_with_multi_key_constraint(conn): record_a = Record.from_enr( ENRFactory(custom_kv_pairs={b"test-a": b"value-A"}, )) record_b = Record.from_enr( ENRFactory(custom_kv_pairs={ b"test-a": b"value-A", b"test-b": b"value-B" }, )) record_c = Record.from_enr( ENRFactory(custom_kv_pairs={b"test-b": b"value-B"}, )) record_d = Record.from_enr(ENRFactory()) record_e = Record.from_enr( ENRFactory(custom_kv_pairs={ b"test-a": b"value-A", b"test-b": b"value-B" }, )) insert_record(conn, record_a) insert_record(conn, record_b) insert_record(conn, record_c) insert_record(conn, record_d) insert_record(conn, record_e) matched_records = tuple( query_records(conn, required_keys=(b"test-a", b"test-b"))) assert len(matched_records) == 2 assert set(matched_records) == {record_b, record_e}
def test_record_query_with_no_constraints(conn): record_a = Record.from_enr(ENRFactory()) record_b = Record.from_enr(ENRFactory()) insert_record(conn, record_a) insert_record(conn, record_b) all_records = tuple(query_records(conn)) assert set(all_records) == {record_a, record_b}
def test_record_query_with_enr_sequence_zero(conn): # This is more of a regression test. Previously the SQL query used a # HAVING clause which didn't work correctly when the only record had a # sequence number of 0. enr = ENR.from_repr( "enr:-Ji4QEdP7fMAICGFlUAxY2cbTYXbPImZzMoKHFyssXNz7zWRNkFZ7Q4EJo3rZsDUVbyo5e_d-zBIDCUHgq72oEIokSaAgmlkgnY0gmlwhMCzfZuJc2VjcDI1NmsxoQNCiVGdz4CJY3sD7bHTrhPcgOu18gfMuyc6kgicqYR_0YN0Y3CC192EdGVzdId2YWx1ZS1Bg3VkcIK0fw" # noqa: E501 ) record = Record.from_enr(enr) insert_record(conn, record) assert get_record(conn, record.node_id) == record assert b"test" in enr results = tuple(query_records(conn, required_keys=(b"test", ))) assert len(results) == 1 assert results[0] == record
def test_record_query_with_key_present_in_earlier_record(conn): # Demonstrate that when we have an *outdated* record with the given key # that it doesn't get returned in the query enr_0 = ENR.from_repr( "enr:-Ji4QP4nHj12UZ8um1c9pplfNYzD7tmDKm5zjWXAQbtvaHQGHYfgHPBNMqPrKjkw1vPnzhxTxYvKxQaYsTsr8tXuG-aAgmlkgnY0gmlwhFIKDgiJc2VjcDI1NmsxoQLBnsAJ3ol6-WoC_oldxmv85K9CVaIxFD1U1qY5ik9-7YN0Y3CCme-EdGVzdId2YWx1ZS1Bg3VkcILjVw" # noqa: E501 ) enr_7 = ENR.from_repr( "enr:-Iu4QAEoWs6MtSYdWONcnR7ekG2lunNxxVlg_xgTKzAUTJDLeqQo06oKbnesHUBl77IFzlnj_GcoYNVnM13ap0i3GAYHgmlkgnY0gmlwhDN7BECJc2VjcDI1NmsxoQLBnsAJ3ol6-WoC_oldxmv85K9CVaIxFD1U1qY5ik9-7YN0Y3CCxMGDdWRwguHh" # noqa: E501 ) assert enr_0.node_id == enr_7.node_id assert enr_0.sequence_number == 0 assert enr_7.sequence_number == 7 assert b"test" in enr_0 assert b"test" not in enr_7 insert_record(conn, Record.from_enr(enr_0)) insert_record(conn, Record.from_enr(enr_7)) results = tuple(query_records(conn, required_keys=(b"test", ))) assert len(results) == 0