refactor: don't depend on multihash features

All we need from the multihash is for it to be a data structure that we pass around. We only ever use the identity "hasher" and the sha256 hasher. Those are easily implemented without depending the (fairly heavy) machinery in `multihash`.

Unfortunately, this patch by itself does not yet lighten our dependency tree because `multiaddr` activates those features unconditionally. I opened a companion PR for this: https://github.com/multiformats/rust-multiaddr/pull/77.

https://github.com/multiformats/rust-multiaddr/pull/77 is another breaking change and we are trying to delay those at the moment. However, it will (hopefully) land eventually which should then be much easier to implement.

Fixes #3276.

Pull-Request: #3514.
This commit is contained in:
Thomas Eizinger
2023-03-30 19:47:35 +02:00
committed by GitHub
parent 75f967f4da
commit dfa7bd6b57
14 changed files with 71 additions and 54 deletions

View File

@ -110,6 +110,7 @@ impl Keypair {
#[cfg(feature = "ed25519")]
pub fn into_ed25519(self) -> Option<ed25519::Keypair> {
#[allow(deprecated)]
#[allow(unreachable_patterns)]
match self {
Keypair::Ed25519(inner) => Some(inner),
_ => None,
@ -119,6 +120,7 @@ impl Keypair {
#[cfg(feature = "secp256k1")]
pub fn into_secp256k1(self) -> Option<secp256k1::Keypair> {
#[allow(deprecated)]
#[allow(unreachable_patterns)]
match self {
Keypair::Secp256k1(inner) => Some(inner),
_ => None,
@ -128,6 +130,7 @@ impl Keypair {
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
pub fn into_rsa(self) -> Option<rsa::Keypair> {
#[allow(deprecated)]
#[allow(unreachable_patterns)]
match self {
Keypair::Rsa(inner) => Some(inner),
_ => None,
@ -137,6 +140,7 @@ impl Keypair {
#[cfg(feature = "ecdsa")]
pub fn into_ecdsa(self) -> Option<ecdsa::Keypair> {
#[allow(deprecated)]
#[allow(unreachable_patterns)]
match self {
Keypair::Ecdsa(inner) => Some(inner),
_ => None,
@ -354,6 +358,7 @@ impl PublicKey {
#[cfg(feature = "ed25519")]
pub fn into_ed25519(self) -> Option<ed25519::PublicKey> {
#[allow(deprecated)]
#[allow(unreachable_patterns)]
match self {
PublicKey::Ed25519(inner) => Some(inner),
_ => None,
@ -363,6 +368,7 @@ impl PublicKey {
#[cfg(feature = "secp256k1")]
pub fn into_secp256k1(self) -> Option<secp256k1::PublicKey> {
#[allow(deprecated)]
#[allow(unreachable_patterns)]
match self {
PublicKey::Secp256k1(inner) => Some(inner),
_ => None,
@ -372,6 +378,7 @@ impl PublicKey {
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
pub fn into_rsa(self) -> Option<rsa::PublicKey> {
#[allow(deprecated)]
#[allow(unreachable_patterns)]
match self {
PublicKey::Rsa(inner) => Some(inner),
_ => None,
@ -381,6 +388,7 @@ impl PublicKey {
#[cfg(feature = "ecdsa")]
pub fn into_ecdsa(self) -> Option<ecdsa::PublicKey> {
#[allow(deprecated)]
#[allow(unreachable_patterns)]
match self {
PublicKey::Ecdsa(inner) => Some(inner),
_ => None,

View File

@ -19,11 +19,19 @@
// DEALINGS IN THE SOFTWARE.
use multiaddr::{Multiaddr, Protocol};
use multihash::{Code, Error, Multihash};
use multihash::{Code, Error, MultihashGeneric};
use rand::Rng;
use sha2::Digest as _;
use std::{convert::TryFrom, fmt, str::FromStr};
use thiserror::Error;
/// Local type-alias for multihash.
///
/// Must be big enough to accommodate for `MAX_INLINE_KEY_LENGTH`.
/// 64 satisfies that and can hold 512 bit hashes which is what the ecosystem typically uses.
/// Given that this appears in our type-signature, using a "common" number here makes us more compatible.
type Multihash = MultihashGeneric<64>;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
@ -31,6 +39,9 @@ use serde::{Deserialize, Serialize};
/// automatically used as the peer id using an identity multihash.
const MAX_INLINE_KEY_LENGTH: usize = 42;
const MULTIHASH_IDENTITY_CODE: u64 = 0;
const MULTIHASH_SHA256_CODE: u64 = 0x12;
/// Identifier of a peer of the network.
///
/// The data is a CIDv0 compatible multihash of the protobuf encoded public key of the peer
@ -55,18 +66,16 @@ impl fmt::Display for PeerId {
impl PeerId {
/// Builds a `PeerId` from a public key.
pub fn from_public_key(key: &crate::keypair::PublicKey) -> PeerId {
use multihash::MultihashDigest as _;
let key_enc = key.to_protobuf_encoding();
let hash_algorithm = if key_enc.len() <= MAX_INLINE_KEY_LENGTH {
Code::Identity
let multihash = if key_enc.len() <= MAX_INLINE_KEY_LENGTH {
Multihash::wrap(MULTIHASH_IDENTITY_CODE, &key_enc)
.expect("64 byte multihash provides sufficient space")
} else {
Code::Sha2_256
Multihash::wrap(MULTIHASH_SHA256_CODE, &sha2::Sha256::digest(key_enc))
.expect("64 byte multihash provides sufficient space")
};
let multihash = hash_algorithm.digest(&key_enc);
PeerId { multihash }
}
@ -82,9 +91,9 @@ impl PeerId {
/// or the hash value does not satisfy the constraints for a hashed
/// peer ID, it is returned as an `Err`.
pub fn from_multihash(multihash: Multihash) -> Result<PeerId, Multihash> {
match Code::try_from(multihash.code()) {
Ok(Code::Sha2_256) => Ok(PeerId { multihash }),
Ok(Code::Identity) if multihash.digest().len() <= MAX_INLINE_KEY_LENGTH => {
match multihash.code() {
MULTIHASH_SHA256_CODE => Ok(PeerId { multihash }),
MULTIHASH_IDENTITY_CODE if multihash.digest().len() <= MAX_INLINE_KEY_LENGTH => {
Ok(PeerId { multihash })
}
_ => Err(multihash),