diff --git a/Cargo.toml b/Cargo.toml index e721de1..0a3a7ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,14 +12,14 @@ license = "MIT" exclude = [".gitignore", ".github/*"] [dependencies] -alloy-rlp = "0.3.9" -base64 = "0.22" -bytes = "1" -hex = "0.4" -log = "0.4" -rand = "0.8" -zeroize = "1.8" -sha3 = "0.10" +alloy-rlp = { version = "0.3.9", default-features = false } +base64 = { version ="0.22", default-features = false } +bytes = { version = "1", default-features = false } +hex = { version = "0.4", default-features = false, features = ["alloc"] } +log = { version = "0.4", default-features = false } +rand = { version = "0.8", optional = true } +zeroize = { version = "1.8", default-features = false } +sha3 = { version = "0.10", default-features = false } k256 = { version = "0.13", features = ["ecdsa"], optional = true } serde = { version = "1.0", features = ["derive"], optional = true } ed25519-dalek = { version = "2.1", optional = true, features = ["rand_core"] } @@ -28,17 +28,30 @@ secp256k1 = { version = "0.30", optional = true, default-features = false, featu ] } [dev-dependencies] +rand = "0.8" alloy-rlp = { version = "0.3", features = ["derive"] } secp256k1 = { version = "0.30", features = ["rand"] } serde_json = "1.0" [features] -default = ["serde", "k256"] -serde = ["dep:serde"] -k256 = ["dep:k256"] +default = ["std", "serde", "k256"] +std = ["alloy-rlp/std", "bytes/std" ,"base64/std", "hex/std", "log/std", "sha3/std", "zeroize/std"] +serde = [ + "dep:serde", + "bytes/serde", + "ed25519-dalek?/serde", + "hex/serde", + "k256?/serde", + "log/serde", + "rand?/serde", + "secp256k1?/serde", + "zeroize/serde" +] +k256 = ["dep:k256", "rand"] ed25519 = ["dep:ed25519-dalek"] secp256k1 = ["rust-secp256k1"] rust-secp256k1 = ["dep:secp256k1"] +rand = ["dep:rand"] [lib] name = "enr" diff --git a/src/builder.rs b/src/builder.rs index 935df24..34d40d8 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -3,10 +3,13 @@ use crate::{ ENR_VERSION, ID_ENR_KEY, IP6_ENR_KEY, IP_ENR_KEY, TCP6_ENR_KEY, TCP_ENR_KEY, UDP6_ENR_KEY, UDP_ENR_KEY, }; +use alloc::collections::BTreeMap; +use alloc::string::String; +use alloc::vec; +use alloc::vec::Vec; use alloy_rlp::{Encodable, Header}; use bytes::{Bytes, BytesMut}; -use std::{ - collections::BTreeMap, +use core::{ marker::PhantomData, net::{IpAddr, Ipv4Addr, Ipv6Addr}, }; diff --git a/src/error.rs b/src/error.rs index 569614c..b90981f 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,6 +1,6 @@ //! The error type emitted for various ENR operations. -use std::fmt; +use core::fmt; #[derive(Clone, Debug, PartialEq, Eq)] /// An error type for handling various ENR operations. @@ -35,8 +35,8 @@ impl fmt::Display for Error { } } -impl std::error::Error for Error { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { +impl core::error::Error for Error { + fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { match self { Error::ExceedsMaxSize | Error::SequenceNumberTooHigh diff --git a/src/keys/mod.rs b/src/keys/mod.rs index 0c26b37..719073f 100644 --- a/src/keys/mod.rs +++ b/src/keys/mod.rs @@ -23,14 +23,16 @@ pub use k256; #[cfg(feature = "rust-secp256k1")] pub use secp256k1; +use crate::alloc::string::ToString; use crate::Key; +use alloc::boxed::Box; +use alloc::collections::BTreeMap; +use alloc::string::String; +use alloc::vec::Vec; use alloy_rlp::Error as DecoderError; use bytes::Bytes; -use std::{ - collections::BTreeMap, - error::Error, - fmt::{self, Debug, Display}, -}; +use core::error::Error; +use core::fmt::{self, Debug, Display}; /// The trait required for a key to sign and modify an ENR record. pub trait EnrKey: Send + Sync + Unpin + 'static { diff --git a/src/lib.rs b/src/lib.rs index 7e4761e..4be2417 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -172,6 +172,7 @@ //! [`insert`]: struct.Enr.html#method.insert //! [`get`]: struct.Enr.html#method.get +#![cfg_attr(not(feature = "std"), no_std)] #![warn(clippy::all, rustdoc::all)] #![allow( clippy::map_err_ignore, @@ -180,28 +181,34 @@ clippy::option_if_let_else )] +extern crate alloc; + mod builder; mod error; mod keys; mod node_id; use alloy_rlp::{Decodable, Encodable, Error as DecoderError, Header}; use bytes::{Buf, Bytes, BytesMut}; -use std::{ - collections::BTreeMap, +use core::{ hash::{Hash, Hasher}, net::{SocketAddrV4, SocketAddrV6}, }; +use alloc::collections::BTreeMap; +use alloc::format; +use alloc::string::String; +use alloc::string::ToString; +use alloc::vec; +use alloc::vec::Vec; use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _}; -#[cfg(feature = "serde")] -use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer}; -use sha3::{Digest, Keccak256}; -use std::{ +use core::{ net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}, str::FromStr, }; - pub use error::Error; +#[cfg(feature = "serde")] +use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer}; +use sha3::{Digest, Keccak256}; #[cfg(feature = "k256")] pub use keys::k256; @@ -211,9 +218,9 @@ pub use keys::secp256k1; pub use keys::{ed25519_dalek, CombinedKey, CombinedPublicKey}; pub use builder::Builder; +use core::marker::PhantomData; pub use keys::{EnrKey, EnrKeyUnambiguous, EnrPublicKey}; pub use node_id::NodeId; -use std::marker::PhantomData; /// The "key" in an ENR record can be arbitrary bytes. type Key = Vec; @@ -703,7 +710,7 @@ impl Enr { /// Unsets the `ip` and `udp` fields on the ENR. pub fn remove_udp_socket(&mut self, key: &K) -> Result<(), Error> { let keys_to_remove = [IP_ENR_KEY, UDP_ENR_KEY].iter(); - let keys_to_insert = std::iter::empty::<(Vec, &[u8])>(); + let keys_to_insert = core::iter::empty::<(Vec, &[u8])>(); self.remove_insert(keys_to_remove, keys_to_insert, key) .map(|_| ()) } @@ -711,7 +718,7 @@ impl Enr { /// Unsets the `ip6` and `udp6` fields on the ENR. pub fn remove_udp6_socket(&mut self, key: &K) -> Result<(), Error> { let keys_to_remove = [IP6_ENR_KEY, UDP6_ENR_KEY].iter(); - let keys_to_insert = std::iter::empty::<(Vec, &[u8])>(); + let keys_to_insert = core::iter::empty::<(Vec, &[u8])>(); self.remove_insert(keys_to_remove, keys_to_insert, key) .map(|_| ()) } @@ -724,7 +731,7 @@ impl Enr { /// Unsets the `ip` and `tcp` fields on the ENR. pub fn remove_tcp_socket(&mut self, key: &K) -> Result<(), Error> { let keys_to_remove = [IP_ENR_KEY, TCP_ENR_KEY].iter(); - let keys_to_insert = std::iter::empty::<(Vec, &[u8])>(); + let keys_to_insert = core::iter::empty::<(Vec, &[u8])>(); self.remove_insert(keys_to_remove, keys_to_insert, key) .map(|_| ()) } @@ -732,7 +739,7 @@ impl Enr { /// Unsets the `ip6` and `tcp6` fields on the ENR. pub fn remove_tcp6_socket(&mut self, key: &K) -> Result<(), Error> { let keys_to_remove = [IP6_ENR_KEY, TCP6_ENR_KEY].iter(); - let keys_to_insert = std::iter::empty::<(Vec, &[u8])>(); + let keys_to_insert = core::iter::empty::<(Vec, &[u8])>(); self.remove_insert(keys_to_remove, keys_to_insert, key) .map(|_| ()) } @@ -970,7 +977,7 @@ impl Enr { /// The previous signature is returned. fn sign(&mut self, key: &K) -> Result, Error> { let new_signature = self.compute_signature(key)?; - Ok(std::mem::replace(&mut self.signature, new_signature)) + Ok(core::mem::replace(&mut self.signature, new_signature)) } } @@ -988,7 +995,7 @@ impl Clone for Enr { } } -impl std::cmp::Eq for Enr {} +impl core::cmp::Eq for Enr {} impl PartialEq for Enr { fn eq(&self, other: &Self) -> bool { @@ -1006,19 +1013,19 @@ impl Hash for Enr { } } -impl std::fmt::Display for Enr { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl core::fmt::Display for Enr { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!(f, "{}", self.to_base64()) } } #[allow(clippy::missing_fields_in_debug)] -impl std::fmt::Debug for Enr { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl core::fmt::Debug for Enr { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { struct OtherPairs<'a>(&'a BTreeMap); - impl<'a> std::fmt::Debug for OtherPairs<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + impl<'a> core::fmt::Debug for OtherPairs<'a> { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { f.debug_list() .entries( self.0 @@ -2061,7 +2068,7 @@ mod tests { let key = k256::ecdsa::SigningKey::random(&mut rand::thread_rng()); let mut huge_enr = Enr::empty(&key).unwrap(); - let large_vec: Vec = std::iter::repeat(0).take(MAX_ENR_SIZE).collect(); + let large_vec: Vec = core::iter::repeat(0).take(MAX_ENR_SIZE).collect(); let large_vec_encoded = alloy_rlp::encode(large_vec); huge_enr diff --git a/src/node_id.rs b/src/node_id.rs index c9fdf6f..7864b44 100644 --- a/src/node_id.rs +++ b/src/node_id.rs @@ -29,12 +29,13 @@ impl NodeId { } let mut raw: RawNodeId = [0_u8; 32]; - raw[..std::cmp::min(32, raw_input.len())].copy_from_slice(raw_input); + raw[..core::cmp::min(32, raw_input.len())].copy_from_slice(raw_input); Ok(Self { raw }) } /// Generates a random `NodeId`. + #[cfg(feature = "rand")] #[must_use] pub fn random() -> Self { Self { @@ -86,8 +87,8 @@ impl From for NodeId { } } -impl std::fmt::Display for NodeId { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl core::fmt::Display for NodeId { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { let hex_encode = hex::encode(self.raw); write!( f, @@ -98,8 +99,8 @@ impl std::fmt::Display for NodeId { } } -impl std::fmt::Debug for NodeId { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl core::fmt::Debug for NodeId { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!(f, "0x{}", hex::encode(self.raw)) } } @@ -121,7 +122,7 @@ mod serde_hex_prfx { where D: serde::Deserializer<'de>, T: hex::FromHex, - ::Error: std::fmt::Display, + ::Error: core::fmt::Display, { /// Helper struct to obtain a owned string when necessary (using [`serde_json`], for /// example) or a borrowed string with the appropriate lifetime (most the time).