API

Abstract Base Classes

class eth_enr.abc.CommonENRAPI

Bases: collections.abc.Mapping, typing.Generic, abc.ABC

get_signing_message() → bytes
identity_scheme
node_id
public_key
sequence_number
class eth_enr.abc.UnsignedENRAPI

Bases: eth_enr.abc.CommonENRAPI

to_signed_enr(private_key: bytes) → eth_enr.abc.ENRAPI
class eth_enr.abc.ENRAPI

Bases: eth_enr.abc.CommonENRAPI

classmethod from_repr(representation: str, identity_scheme_registry: collections.UserDict) → eth_enr.abc.ENRAPI
signature
validate_signature() → None
class eth_enr.abc.ENRManagerAPI

Bases: abc.ABC

enr
update(*kv_pairs) → None

Update the ENR record with the provided key/value pairs. Providing None for a value will result in the associated key being removed from the ENR.

class eth_enr.abc.IdentitySchemeAPI

Bases: abc.ABC

classmethod create_enr_signature(enr: eth_enr.abc.CommonENRAPI, private_key: bytes) → bytes

Create and return the signature for an ENR.

classmethod extract_node_id(enr: eth_enr.abc.CommonENRAPI) → NewType.<locals>.new_type

Retrieve the node id from an ENR.

classmethod extract_public_key(enr: eth_enr.abc.CommonENRAPI) → bytes

Retrieve the public key from an ENR.

classmethod validate_enr_signature(enr: eth_enr.abc.ENRAPI) → None

Validate the signature of an ENR.

classmethod validate_enr_structure(enr: eth_enr.abc.CommonENRAPI) → None

Validate that the data required by the identity scheme is present and valid in an ENR.

eth_enr.abc.IdentitySchemeRegistryAPI

alias of collections.UserDict

class eth_enr.abc.ENRDatabaseAPI

Bases: abc.ABC

delete_enr(node_id: NewType.<locals>.new_type) → None
get_enr(node_id: NewType.<locals>.new_type) → eth_enr.abc.ENRAPI
set_enr(enr: eth_enr.abc.ENRAPI, raise_on_error: bool = False) → None
class eth_enr.abc.QueryableENRDatabaseAPI

Bases: eth_enr.abc.ENRDatabaseAPI

query(*constraints) → Iterable[eth_enr.abc.ENRAPI]

Classes

class eth_enr.enr.ENR(sequence_number: int, kv_pairs: Mapping[bytes, Any], signature: bytes, identity_scheme_registry: collections.UserDict = {b'v4': <class 'eth_enr.identity_schemes.V4IdentityScheme'>, b'v4-compat': <class 'eth_enr.identity_schemes.V4CompatIdentityScheme'>})

Bases: eth_enr.enr.ENRCommon, eth_enr.sedes.ENRSedes, eth_enr.abc.ENRAPI

classmethod from_repr(representation: str, identity_scheme_registry: collections.UserDict = {b'v4': <class 'eth_enr.identity_schemes.V4IdentityScheme'>, b'v4-compat': <class 'eth_enr.identity_schemes.V4CompatIdentityScheme'>}) → eth_enr.enr.ENR
signature
validate_signature() → None
class eth_enr.enr.UnsignedENR(sequence_number: int, kv_pairs: Mapping[bytes, Any], identity_scheme_registry: collections.UserDict = {b'v4': <class 'eth_enr.identity_schemes.V4IdentityScheme'>, b'v4-compat': <class 'eth_enr.identity_schemes.V4CompatIdentityScheme'>})

Bases: eth_enr.enr.ENRCommon, eth_enr.abc.UnsignedENRAPI

to_signed_enr(private_key: bytes) → eth_enr.enr.ENR
class eth_enr.enr_manager.ENRManager(private_key: eth_keys.datatypes.PrivateKey, enr_db: eth_enr.abc.ENRDatabaseAPI, kv_pairs: Optional[Mapping[bytes, bytes]] = None, identity_scheme_registry: collections.UserDict = {b'v4': <class 'eth_enr.identity_schemes.V4IdentityScheme'>, b'v4-compat': <class 'eth_enr.identity_schemes.V4CompatIdentityScheme'>})

Bases: eth_enr.abc.ENRManagerAPI

enr
logger = <Logger eth_enr.ENRManager (WARNING)>
update(*kv_pairs) → None

Update the ENR record with the provided key/value pairs. Providing None for a value will result in the associated key being removed from the ENR.

class eth_enr.identity_schemes.IdentitySchemeRegistry(**kwargs)

Bases: collections.UserDict

register(identity_scheme_class: Type[IdentitySchemeAPI]) → Type[eth_enr.abc.IdentitySchemeAPI]

Class decorator to register identity schemes.

class eth_enr.identity_schemes.V4IdentityScheme

Bases: eth_enr.abc.IdentitySchemeAPI

classmethod create_enr_signature(enr: eth_enr.abc.CommonENRAPI, private_key: bytes) → bytes

Create and return the signature for an ENR.

classmethod extract_node_id(enr: eth_enr.abc.CommonENRAPI) → NewType.<locals>.new_type

Retrieve the node id from an ENR.

classmethod extract_public_key(enr: eth_enr.abc.CommonENRAPI) → bytes

Retrieve the public key from an ENR.

id = b'v4'
private_key_size = 32
public_key_enr_key = b'secp256k1'
classmethod validate_compressed_public_key(public_key: bytes) → None
classmethod validate_enr_signature(enr: eth_enr.abc.ENRAPI) → None

Validate the signature of an ENR.

classmethod validate_enr_structure(enr: eth_enr.abc.CommonENRAPI) → None

Validate that the data required by the identity scheme is present and valid in an ENR.

classmethod validate_signature(*, message_hash: bytes, signature: bytes, public_key: bytes) → None
classmethod validate_uncompressed_public_key(public_key: bytes) → None
class eth_enr.identity_schemes.V4CompatIdentityScheme

Bases: eth_enr.identity_schemes.V4IdentityScheme

An identity scheme to be used for locally crafted ENRs representing remote nodes that don’t support the ENR extension.

ENRs using this identity scheme have a zero-length signature.

classmethod create_enr_signature(enr: eth_enr.abc.CommonENRAPI, private_key: bytes) → bytes

Create and return the signature for an ENR.

id = b'v4-compat'
classmethod validate_enr_signature(enr: eth_enr.abc.ENRAPI) → None

Validate the signature of an ENR.

class eth_enr.enr_db.ENRDB(db: MutableMapping[bytes, bytes], identity_scheme_registry: collections.UserDict = {b'v4': <class 'eth_enr.identity_schemes.V4IdentityScheme'>, b'v4-compat': <class 'eth_enr.identity_schemes.V4CompatIdentityScheme'>})

Bases: eth_enr.abc.ENRDatabaseAPI

delete_enr(node_id: NewType.<locals>.new_type) → None
get_enr(node_id: NewType.<locals>.new_type) → eth_enr.abc.ENRAPI
identity_scheme_registry
logger = <Logger eth_enr.ENRDB (WARNING)>
set_enr(enr: eth_enr.abc.ENRAPI, raise_on_error: bool = False) → None
class eth_enr.query_db.QueryableENRDB(connection: sqlite3.Connection, identity_scheme_registry: collections.UserDict = {b'v4': <class 'eth_enr.identity_schemes.V4IdentityScheme'>, b'v4-compat': <class 'eth_enr.identity_schemes.V4CompatIdentityScheme'>})

Bases: eth_enr.abc.QueryableENRDatabaseAPI

An implementation of eth_enr.abc.QueryableENRDatabaseAPI on top of the sqlite3 module from the standard library.

For use with an in-memory database:

>>> connection = sqlite3.connect(":memory:")
>>> enr_db = QueryableENRDB(connection)
...

Or use with an on-disk database:

>>> connection = sqlite3.connect("/path/to/db.sqlite3")
>>> enr_db = QueryableENRDB(connection)
...

The database tables will lazily be created upon class instantiation if they are missing.

delete_enr(node_id: NewType.<locals>.new_type) → None

Delete ENR records with the given node_id

Raisees KeyError if there are no records with the given node_id

get_enr(node_id: NewType.<locals>.new_type) → eth_enr.abc.ENRAPI

Retrieve the ENR record with the highest sequence number for the given node_id

Raises KeyError if there are no records with the geven node_id

identity_scheme_registry
logger = <Logger eth_enr.ENRDB (WARNING)>
query(*constraints) → Iterable[eth_enr.abc.ENRAPI]

Query the database for records that match the given constraints.

Support constraints:

Return an iterator of matching ENR records. Only returns the record with the highest sequence number for each node_id.

set_enr(enr: eth_enr.abc.ENRAPI, raise_on_error: bool = False) → None

Write a record to the database.

Raise eth_enr.exceptions.DuplicateRecord if there is an different existing record with the same sequence number.

Constraints

class eth_enr.constraints.KeyExists(key: bytes)

Bases: eth_enr.abc.ConstraintAPI

Constrains ENR database queries to records which have a specified key.

>>> enr_db = ...
>>> from eth_enr.constraints import KeyExists
>>> for enr in enr_db.query(KeyExists(b"some-key")):
...     print("ENR: ", enr)
class eth_enr.constraints.HasUDPIPv4Endpoint

Bases: eth_enr.abc.ConstraintAPI

Constrains ENR database queries to records which have both the "ip" and "udp" keys.

>>> enr_db = ...
>>> from eth_enr.constraints import has_udp_ipv4_endpoint
>>> for enr in enr_db.query(has_udp_ipv4_endpoint):
...     print("ENR: ", enr)
class eth_enr.constraints.HasUDPIPv6Endpoint

Bases: eth_enr.abc.ConstraintAPI

Constrains ENR database queries to records which have both the "ip6" and "udp6" keys.

>>> enr_db = ...
>>> from eth_enr.constraints import has_udp_ipv6_endpoint
>>> for enr in enr_db.query(has_udp_ipv6_endpoint):
...     print("ENR: ", enr)
class eth_enr.constraints.HasTCPIPv4Endpoint

Bases: eth_enr.abc.ConstraintAPI

Constrains ENR database queries to records which have both the "ip" and "tcp" keys.

>>> enr_db = ...
>>> from eth_enr.constraints import has_tcp_ipv4_endpoint
>>> for enr in enr_db.query(has_tcp_ipv4_endpoint):
...     print("ENR: ", enr)
class eth_enr.constraints.HasTCPIPv6Endpoint

Bases: eth_enr.abc.ConstraintAPI

Constrains ENR database queries to records which have both the "ip6" and "tcp6" keys.

>>> enr_db = ...
>>> from eth_enr.constraints import has_tcp_ipv6_endpoint
>>> for enr in enr_db.query(has_tcp_ipv6_endpoint):
...     print("ENR: ", enr)
class eth_enr.constraints.ClosestTo(node_id: NewType.<locals>.new_type)

Bases: eth_enr.abc.ConstraintAPI

Constrains ENR database queries to return records proximate to a specific node_id

>>> enr_db = ...
>>> node_id = ...
>>> from eth_enr.constraints import ClosestTo
>>> for enr in enr_db.query(ClosestTo(node_id)):
...     print("ENR: ", enr)

Exceptions

class eth_enr.exceptions.OldSequenceNumber

Bases: eth_enr.exceptions.BaseENRException

Raised when trying to update an ENR record with a sequence number that is older than the latest sequence number we have seen

class eth_enr.exceptions.DuplicateRecord

Bases: eth_enr.exceptions.BaseENRException

Raised when trying to set an ENR record to a database that already has a different record with the same sequence number.

class eth_enr.exceptions.UnknownIdentityScheme

Bases: eth_enr.exceptions.BaseENRException

Raised when trying to instantiate an ENR with an unknown identity scheme