Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more useful ENR.__str__ implementation #14

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions eth_enr/constants.py
Expand Up @@ -2,8 +2,12 @@
ENR_REPR_PREFIX = "enr:" # prefix used when printing an ENR
MAX_ENR_SIZE = 300 # maximum allowed size of an ENR
IP_V4_ADDRESS_ENR_KEY = b"ip"
IP_V6_ADDRESS_ENR_KEY = b"ip6"
UDP_PORT_ENR_KEY = b"udp"
TCP_PORT_ENR_KEY = b"tcp"

V4 = b"v4"
V4_SIGNATURE_KEY = b"secp256k1"

IP_V4_SIZE = 4 # size of an IPv4 address
IP_V6_SIZE = 16 # size of an IPv6 address
48 changes: 45 additions & 3 deletions eth_enr/enr.py
@@ -1,9 +1,10 @@
import base64
import ipaddress
import operator
from typing import AbstractSet, Any, Iterator, Mapping, Tuple, Type, ValuesView
from typing import AbstractSet, Any, Iterator, Mapping, Tuple, Type, Union, ValuesView

from eth_typing import NodeID
from eth_utils import ValidationError
from eth_utils import ValidationError, encode_hex
import rlp

from eth_enr.abc import (
Expand All @@ -13,7 +14,13 @@
IdentitySchemeRegistryAPI,
UnsignedENRAPI,
)
from eth_enr.constants import ENR_REPR_PREFIX, IDENTITY_SCHEME_ENR_KEY
from eth_enr.constants import (
ENR_REPR_PREFIX,
IDENTITY_SCHEME_ENR_KEY,
IP_V4_ADDRESS_ENR_KEY,
IP_V6_ADDRESS_ENR_KEY,
V4_SIGNATURE_KEY,
)
from eth_enr.exceptions import UnknownIdentityScheme
from eth_enr.identity_schemes import (
default_identity_scheme_registry as default_id_scheme_registry,
Expand Down Expand Up @@ -136,6 +143,32 @@ def __hash__(self) -> int:
return hash((self.sequence_number, sorted_key_value_pairs))


def _get_display_str(item: Union[int, bytes]) -> str:
if isinstance(item, bytes):
try:
return item.decode("ascii")
except UnicodeDecodeError:
return encode_hex(item)
elif isinstance(item, int):
return str(item)
else:
raise Exception("Unreachable")


def pretty_print_enr_item(key: bytes, value: Union[int, bytes]) -> str:
if key == IDENTITY_SCHEME_ENR_KEY:
return f"id={_get_display_str(value)}"
elif key == V4_SIGNATURE_KEY:
return f"secp256k1={encode_hex(value)}" # type: ignore
elif key == IP_V4_ADDRESS_ENR_KEY and isinstance(value, bytes) and len(value) == 4:
return f"ip={ipaddress.ip_address(value)}"
elif key == IP_V6_ADDRESS_ENR_KEY and isinstance(value, bytes) and len(value) == 16:
return f"ip={ipaddress.ip_address(value)}"

# final fallback if none of the *fancy* display options work.
return f"{_get_display_str(key)}={_get_display_str(value)}"


class ENR(ENRCommon, ENRSedes, ENRAPI):
def __init__(
self,
Expand Down Expand Up @@ -182,6 +215,15 @@ def __hash__(self) -> int:
sorted_key_value_pairs = tuple(sorted(self.items(), key=operator.itemgetter(0)))
return hash((self.signature, self.sequence_number, sorted_key_value_pairs))

def __str__(self) -> str:
kv_pairs = " ".join(
(pretty_print_enr_item(key, value) for key, value in sorted(self.items()))
)
return (
f"ENR: seq={self.sequence_number} node_id={self.node_id.hex()} "
f"sig={self.signature.hex()} KV: {kv_pairs}"
)

def __repr__(self) -> str:
base64_rlp = base64.urlsafe_b64encode(rlp.encode(self))
unpadded_base64_rlp = base64_rlp.rstrip(b"=")
Expand Down
5 changes: 3 additions & 2 deletions eth_enr/identity_schemes.py
Expand Up @@ -12,6 +12,7 @@
IdentitySchemeAPI,
IdentitySchemeRegistryAPI,
)
from eth_enr.constants import V4, V4_SIGNATURE_KEY


class IdentitySchemeRegistry(IdentitySchemeRegistryAPI):
Expand Down Expand Up @@ -40,8 +41,8 @@ def register(
@discv4_identity_scheme_registry.register
class V4IdentityScheme(IdentitySchemeAPI):

id = b"v4"
public_key_enr_key = b"secp256k1"
id = V4
public_key_enr_key = V4_SIGNATURE_KEY

private_key_size = 32

Expand Down