diff --git a/common/eth2/src/types.rs b/common/eth2/src/types.rs index 83c97b36719..43bd0419c9c 100644 --- a/common/eth2/src/types.rs +++ b/common/eth2/src/types.rs @@ -144,13 +144,13 @@ impl FromStr for ValidatorId { fn from_str(s: &str) -> Result { if s.starts_with("0x") { - serde_json::from_str(&format!("\"{}\"", s)) + PublicKeyBytes::from_str(s) .map(ValidatorId::PublicKey) - .map_err(|_| format!("{} cannot be parsed as a public key", s)) + .map_err(|e| format!("{} cannot be parsed as a public key: {}", s, e)) } else { u64::from_str(s) .map(ValidatorId::Index) - .map_err(|_| format!("{} cannot be parsed as a slot", s)) + .map_err(|e| format!("{} cannot be parsed as a slot: {}", s, e)) } } } diff --git a/crypto/bls/src/generic_aggregate_signature.rs b/crypto/bls/src/generic_aggregate_signature.rs index d0bcd38d2bd..417f5a264bc 100644 --- a/crypto/bls/src/generic_aggregate_signature.rs +++ b/crypto/bls/src/generic_aggregate_signature.rs @@ -245,6 +245,23 @@ where impl_tree_hash!(SIGNATURE_BYTES_LEN); } +impl fmt::Display for GenericAggregateSignature +where + Sig: TSignature, + AggSig: TAggregateSignature, +{ + impl_display!(); +} + +impl std::str::FromStr + for GenericAggregateSignature +where + Sig: TSignature, + AggSig: TAggregateSignature, +{ + impl_from_str!(); +} + impl Serialize for GenericAggregateSignature where Sig: TSignature, diff --git a/crypto/bls/src/generic_public_key.rs b/crypto/bls/src/generic_public_key.rs index fe3c573f7e5..4c97b88b940 100644 --- a/crypto/bls/src/generic_public_key.rs +++ b/crypto/bls/src/generic_public_key.rs @@ -97,6 +97,14 @@ impl TreeHash for GenericPublicKey { impl_tree_hash!(PUBLIC_KEY_BYTES_LEN); } +impl fmt::Display for GenericPublicKey { + impl_display!(); +} + +impl std::str::FromStr for GenericPublicKey { + impl_from_str!(); +} + impl Serialize for GenericPublicKey { impl_serde_serialize!(); } diff --git a/crypto/bls/src/generic_public_key_bytes.rs b/crypto/bls/src/generic_public_key_bytes.rs index 824eafb4d6c..d3e68b7f17f 100644 --- a/crypto/bls/src/generic_public_key_bytes.rs +++ b/crypto/bls/src/generic_public_key_bytes.rs @@ -132,6 +132,14 @@ impl TreeHash for GenericPublicKeyBytes { impl_tree_hash!(PUBLIC_KEY_BYTES_LEN); } +impl fmt::Display for GenericPublicKeyBytes { + impl_display!(); +} + +impl std::str::FromStr for GenericPublicKeyBytes { + impl_from_str!(); +} + impl Serialize for GenericPublicKeyBytes { impl_serde_serialize!(); } diff --git a/crypto/bls/src/generic_signature.rs b/crypto/bls/src/generic_signature.rs index 159b69d0c94..a658190c1e3 100644 --- a/crypto/bls/src/generic_signature.rs +++ b/crypto/bls/src/generic_signature.rs @@ -149,6 +149,14 @@ impl> TreeHash for GenericSignature> fmt::Display for GenericSignature { + impl_display!(); +} + +impl> std::str::FromStr for GenericSignature { + impl_from_str!(); +} + impl> Serialize for GenericSignature { impl_serde_serialize!(); } diff --git a/crypto/bls/src/generic_signature_bytes.rs b/crypto/bls/src/generic_signature_bytes.rs index ee4299320e5..21162fcada8 100644 --- a/crypto/bls/src/generic_signature_bytes.rs +++ b/crypto/bls/src/generic_signature_bytes.rs @@ -124,6 +124,14 @@ impl TreeHash for GenericSignatureBytes { impl_tree_hash!(SIGNATURE_BYTES_LEN); } +impl fmt::Display for GenericSignatureBytes { + impl_display!(); +} + +impl std::str::FromStr for GenericSignatureBytes { + impl_from_str!(); +} + impl Serialize for GenericSignatureBytes { impl_serde_serialize!(); } diff --git a/crypto/bls/src/macros.rs b/crypto/bls/src/macros.rs index ca103da6da4..915cfe4c6db 100644 --- a/crypto/bls/src/macros.rs +++ b/crypto/bls/src/macros.rs @@ -76,6 +76,35 @@ macro_rules! impl_ssz_decode { }; } +/// Contains the functions required for a `fmt::Display` implementation. +/// +/// Does not include the `Impl` section since it gets very complicated when it comes to generics. +macro_rules! impl_display { + () => { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", hex_encode(self.serialize().to_vec())) + } + }; +} + +/// Contains the functions required for a `fmt::Display` implementation. +/// +/// Does not include the `Impl` section since it gets very complicated when it comes to generics. +macro_rules! impl_from_str { + () => { + type Err = String; + + fn from_str(s: &str) -> Result { + if s.starts_with("0x") { + let bytes = hex::decode(&s[2..]).map_err(|e| e.to_string())?; + Self::deserialize(&bytes[..]).map_err(|e| format!("{:?}", e)) + } else { + Err("must start with 0x".to_string()) + } + } + }; +} + /// Contains the functions required for a `serde::Serialize` implementation. /// /// Does not include the `Impl` section since it gets very complicated when it comes to generics. @@ -85,7 +114,7 @@ macro_rules! impl_serde_serialize { where S: Serializer, { - serializer.serialize_str(&hex_encode(self.serialize().to_vec())) + serializer.serialize_str(&self.to_string()) } }; }