Esempio n. 1
0
def test_repr(mock_identity_scheme, identity_scheme_registry):
    unsigned_enr = UnsignedENR(0, {b"id": b"mock"}, identity_scheme_registry)
    enr = unsigned_enr.to_signed_enr(b"\x00" * 32)
    base64_encoded_enr = base64.urlsafe_b64encode(rlp.encode(enr))
    represented_enr = repr(enr)

    assert represented_enr.startswith("enr:")
    assert base64_encoded_enr.rstrip(b"=").decode() == represented_enr[4:]

    assert ENR.from_repr(represented_enr, identity_scheme_registry) == enr
Esempio n. 2
0
def test_signing(mock_identity_scheme, identity_scheme_registry):
    unsigned_enr = UnsignedENR(
        sequence_number=0,
        kv_pairs={b"id": b"mock"},
        identity_scheme_registry=identity_scheme_registry,
    )
    private_key = b"\x00" * 32
    enr = unsigned_enr.to_signed_enr(private_key)
    assert enr.signature == mock_identity_scheme.create_enr_signature(
        enr, private_key)
Esempio n. 3
0
def test_official_test_vector():
    enr = ENR.from_repr(
        OFFICIAL_TEST_DATA["repr"])  # use default identity scheme registry

    assert enr.sequence_number == OFFICIAL_TEST_DATA["sequence_number"]
    assert dict(enr) == OFFICIAL_TEST_DATA["kv_pairs"]
    assert enr.public_key == OFFICIAL_TEST_DATA["public_key"]
    assert enr.node_id == OFFICIAL_TEST_DATA["node_id"]
    assert enr.identity_scheme is OFFICIAL_TEST_DATA["identity_scheme"]
    assert repr(enr) == OFFICIAL_TEST_DATA["repr"]

    unsigned_enr = UnsignedENR(enr.sequence_number, dict(enr))
    reconstructed_enr = unsigned_enr.to_signed_enr(
        OFFICIAL_TEST_DATA["private_key"])
    assert reconstructed_enr == enr
Esempio n. 4
0
    def update(self, *kv_pairs: ENR_KV) -> None:
        if not kv_pairs:
            return
        keys, values = tuple(zip(*kv_pairs))
        if len(keys) != len(set(keys)):
            raise ValidationError("Duplicate keys found in: %s", keys)

        needs_update = any(
            (
                # key needs to be deleted
                (value is None and key in self._enr)
                # key is not present or does not match the provided value
                or (
                    value is not None
                    and (key not in self._enr or self._enr[key] != value)
                )
            )
            for key, value in kv_pairs
        )
        if needs_update:
            merged_kv_pairs = {
                key: value
                for key, value in merge(dict(self._enr), dict(kv_pairs)).items()
                if value is not None
            }
            self._enr = UnsignedENR(
                sequence_number=self._enr.sequence_number + 1,
                kv_pairs=merged_kv_pairs,
                identity_scheme_registry=self._identity_scheme_registry,
            ).to_signed_enr(self._private_key.to_bytes())
            self._enr_db.set_enr(self._enr)
            self.logger.info(
                "ENR Updated: seq=%d  enr=%r", self.enr.sequence_number, self.enr
            )
Esempio n. 5
0
class ENRFactory(factory.Factory):  # type: ignore
    class Meta:
        model = ENR

    sequence_number = factory.Faker("pyint", min_value=0, max_value=100)
    kv_pairs = factory.LazyAttribute(
        lambda o: merge(
            {
                b"id": b"v4",
                b"secp256k1": keys.PrivateKey(
                    o.private_key
                ).public_key.to_compressed_bytes(),
                b"ip": o.address.ip_packed,
                b"udp": o.address.udp_port,
                b"tcp": o.address.tcp_port,
            },
            o.custom_kv_pairs,
        )
    )
    signature = factory.LazyAttribute(
        lambda o: UnsignedENR(o.sequence_number, o.kv_pairs)
        .to_signed_enr(o.private_key)
        .signature
    )

    class Params:
        private_key = factory.Faker("binary", length=V4IdentityScheme.private_key_size)
        address = factory.SubFactory(AddressFactory)
        custom_kv_pairs: Dict[bytes, Any] = {}
Esempio n. 6
0
def test_v4_structure_validation(invalid_kv_pairs, identity_scheme_registry):
    with pytest.raises(ValidationError):
        UnsignedENR(
            sequence_number=0,
            kv_pairs=invalid_kv_pairs,
            identity_scheme_registry=identity_scheme_registry,
        )
Esempio n. 7
0
def test_inititialization(identity_scheme_registry):
    valid_sequence_number = 0
    valid_kv_pairs = {b"id": b"mock"}
    valid_signature = b""  # signature is not validated during initialization

    assert UnsignedENR(
        sequence_number=valid_sequence_number,
        kv_pairs=valid_kv_pairs,
        identity_scheme_registry=identity_scheme_registry,
    )
    assert ENR(
        sequence_number=valid_sequence_number,
        kv_pairs=valid_kv_pairs,
        signature=valid_signature,
        identity_scheme_registry=identity_scheme_registry,
    )

    with pytest.raises(ValidationError):
        UnsignedENR(
            sequence_number=valid_sequence_number,
            kv_pairs={b"no-id": b""},
            identity_scheme_registry=identity_scheme_registry,
        )
    with pytest.raises(ValidationError):
        ENR(
            sequence_number=valid_sequence_number,
            kv_pairs={b"no-id": b""},
            signature=valid_signature,
            identity_scheme_registry=identity_scheme_registry,
        )

    with pytest.raises(ValidationError):
        UnsignedENR(
            sequence_number=-1,
            kv_pairs=valid_kv_pairs,
            identity_scheme_registry=identity_scheme_registry,
        )
    with pytest.raises(ValidationError):
        ENR(
            sequence_number=-1,
            kv_pairs=valid_kv_pairs,
            signature=valid_signature,
            identity_scheme_registry=identity_scheme_registry,
        )
Esempio n. 8
0
    def deserialize(
        cls,
        serialized_enr: Sequence[bytes],
        identity_scheme_registry:
        IdentitySchemeRegistryAPI = default_id_scheme_registry,
    ) -> UnsignedENRAPI:
        from eth_enr.enr import UnsignedENR  # noqa: F811

        cls._validate_serialized_length(serialized_enr)
        sequence_number = big_endian_int.deserialize(serialized_enr[0])
        kv_pairs = cls._deserialize_kv_pairs(serialized_enr)
        return UnsignedENR(sequence_number, kv_pairs, identity_scheme_registry)
Esempio n. 9
0
def test_signature_validation(mock_identity_scheme, identity_scheme_registry):
    unsigned_enr = UnsignedENR(0, {b"id": b"mock"}, identity_scheme_registry)
    private_key = b"\x00" * 32
    enr = unsigned_enr.to_signed_enr(private_key)
    enr.validate_signature()

    invalid_signature = b"\xff" * 64
    invalid_enr = ENR(
        enr.sequence_number,
        dict(enr),
        invalid_signature,
        identity_scheme_registry=identity_scheme_registry,
    )
    with pytest.raises(ValidationError):
        invalid_enr.validate_signature()

    with pytest.raises(UnknownIdentityScheme):
        ENR(
            0,
            {b"id": b"unknown"},
            b"",
            identity_scheme_registry=identity_scheme_registry,
        )
Esempio n. 10
0
    def __init__(
        self,
        private_key: keys.PrivateKey,
        enr_db: ENRDatabaseAPI,
        kv_pairs: Optional[Mapping[bytes, bytes]] = None,
        identity_scheme_registry: IdentitySchemeRegistryAPI = default_identity_scheme_registry,  # noqa: E501
    ) -> None:
        self._identity_scheme_registry = identity_scheme_registry
        self._private_key = private_key
        self._enr_db = enr_db

        if kv_pairs is None:
            kv_pairs = {}

        if b"id" in kv_pairs:
            identity_kv_pairs = {}
        else:
            identity_kv_pairs = {
                b"id": b"v4",
                b"secp256k1": self._private_key.public_key.to_compressed_bytes(),
            }

        minimal_enr = UnsignedENR(
            sequence_number=1,
            kv_pairs=merge(identity_kv_pairs, kv_pairs),
            identity_scheme_registry=self._identity_scheme_registry,
        ).to_signed_enr(self._private_key.to_bytes())
        self._node_id = minimal_enr.node_id

        try:
            base_enr = self._enr_db.get_enr(minimal_enr.node_id)
        except KeyError:
            self.logger.info(
                "ENR created: seq=%d  enr=%r",
                minimal_enr.sequence_number,
                minimal_enr,
            )
            self._enr = minimal_enr
            self._enr_db.set_enr(self._enr)
        else:
            self._enr = base_enr
            self.update(*tuple(kv_pairs.items()))
Esempio n. 11
0
def test_node_id(mock_identity_scheme, identity_scheme_registry):
    unsigned_enr = UnsignedENR(0, {b"id": b"mock"}, identity_scheme_registry)
    private_key = b"\x00" * 32
    enr = unsigned_enr.to_signed_enr(private_key)
    assert enr.node_id == private_key
Esempio n. 12
0
def test_public_key(mock_identity_scheme, identity_scheme_registry):
    unsigned_enr = UnsignedENR(0, {b"id": b"mock"}, identity_scheme_registry)
    private_key = b"\x00" * 32
    enr = unsigned_enr.to_signed_enr(private_key)
    assert enr.public_key == mock_identity_scheme.extract_public_key(enr)