mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-29 01:31:33 +00:00
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:
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -2945,6 +2945,7 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
"rcgen 0.9.3",
|
||||
"serde",
|
||||
"sha2 0.10.6",
|
||||
"stun",
|
||||
"thiserror",
|
||||
"tinytemplate",
|
||||
@ -3214,13 +3215,11 @@ checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"core2",
|
||||
"digest 0.10.6",
|
||||
"multihash-derive",
|
||||
"quickcheck",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde-big-array",
|
||||
"sha2 0.10.6",
|
||||
"unsigned-varint",
|
||||
]
|
||||
|
||||
|
@ -19,7 +19,7 @@ instant = "0.1.11"
|
||||
libp2p-identity = { version = "0.1", path = "../identity", features = ["peerid", "ed25519"] }
|
||||
log = "0.4"
|
||||
multiaddr = { version = "0.17.0" }
|
||||
multihash = { version = "0.17.0", default-features = false, features = ["std", "multihash-impl", "identity", "sha2"] }
|
||||
multihash = { version = "0.17.0", default-features = false, features = ["std"] }
|
||||
multistream-select = { version = "0.12.1", path = "../misc/multistream-select" }
|
||||
once_cell = "1.17.1"
|
||||
parking_lot = "0.12.0"
|
||||
|
@ -18,7 +18,7 @@ ed25519-dalek = { version = "1.0.1", optional = true }
|
||||
libsecp256k1 = { version = "0.7.0", optional = true }
|
||||
log = "0.4"
|
||||
multiaddr = { version = "0.17.0", optional = true }
|
||||
multihash = { version = "0.17.0", default-features = false, features = ["std", "multihash-impl", "identity", "sha2"], optional = true }
|
||||
multihash = { version = "0.17.0", default-features = false, features = ["std"], optional = true }
|
||||
p256 = { version = "0.12", default-features = false, features = ["ecdsa", "std"], optional = true }
|
||||
prost = { version = "0.11", optional = true }
|
||||
quick-protobuf = "0.8.1"
|
||||
@ -38,7 +38,7 @@ secp256k1 = [ "libsecp256k1", "asn1_der", "prost", "rand", "sha2", "zeroize" ]
|
||||
ecdsa = [ "p256", "prost", "rand", "void", "zeroize", "sec1" ]
|
||||
rsa = [ "dep:ring", "asn1_der", "prost", "rand", "zeroize" ]
|
||||
ed25519 = [ "ed25519-dalek", "prost", "rand", "zeroize" ]
|
||||
peerid = [ "multihash", "multiaddr", "bs58", "rand", "thiserror" ]
|
||||
peerid = [ "multihash", "multiaddr", "bs58", "rand", "thiserror", "sha2" ]
|
||||
|
||||
[dev-dependencies]
|
||||
quickcheck = { package = "quickcheck-ext", path = "../misc/quickcheck-ext" }
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -24,13 +24,13 @@ use super::*;
|
||||
|
||||
use crate::kbucket::Distance;
|
||||
use crate::record::{store::MemoryStore, Key};
|
||||
use crate::K_VALUE;
|
||||
use crate::{K_VALUE, SHA_256_MH};
|
||||
use futures::{executor::block_on, future::poll_fn, prelude::*};
|
||||
use futures_timer::Delay;
|
||||
use libp2p_core::{
|
||||
connection::ConnectedPoint,
|
||||
multiaddr::{multiaddr, Multiaddr, Protocol},
|
||||
multihash::{Code, Multihash, MultihashDigest},
|
||||
multihash::Multihash,
|
||||
transport::MemoryTransport,
|
||||
upgrade, Endpoint, Transport,
|
||||
};
|
||||
@ -138,7 +138,7 @@ fn build_fully_connected_nodes_with_config(
|
||||
}
|
||||
|
||||
fn random_multihash() -> Multihash {
|
||||
Multihash::wrap(Code::Sha2_256.into(), &thread_rng().gen::<[u8; 32]>()).unwrap()
|
||||
Multihash::wrap(SHA_256_MH, &thread_rng().gen::<[u8; 32]>()).unwrap()
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -1100,7 +1100,10 @@ fn disjoint_query_does_not_finish_before_all_paths_did() {
|
||||
let mut trudy = build_node(); // Trudy the intrudor, an adversary.
|
||||
let mut bob = build_node();
|
||||
|
||||
let key = Key::from(Code::Sha2_256.digest(&thread_rng().gen::<[u8; 32]>()));
|
||||
let key = Key::from(
|
||||
Multihash::wrap(SHA_256_MH, &thread_rng().gen::<[u8; 32]>())
|
||||
.expect("32 array to fit into 64 byte multihash"),
|
||||
);
|
||||
let record_bob = Record::new(key.clone(), b"bob".to_vec());
|
||||
let record_trudy = Record::new(key.clone(), b"trudy".to_vec());
|
||||
|
||||
|
@ -196,7 +196,7 @@ impl Distance {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use libp2p_core::multihash::Code;
|
||||
use crate::SHA_256_MH;
|
||||
use quickcheck::*;
|
||||
|
||||
impl Arbitrary for Key<PeerId> {
|
||||
@ -208,7 +208,7 @@ mod tests {
|
||||
impl Arbitrary for Key<Multihash> {
|
||||
fn arbitrary(g: &mut Gen) -> Key<Multihash> {
|
||||
let hash: [u8; 32] = core::array::from_fn(|_| u8::arbitrary(g));
|
||||
Key::from(Multihash::wrap(Code::Sha2_256.into(), &hash).unwrap())
|
||||
Key::from(Multihash::wrap(SHA_256_MH, &hash).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,3 +100,7 @@ pub const K_VALUE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(20) };
|
||||
///
|
||||
/// The current value is `3`.
|
||||
pub const ALPHA_VALUE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(3) };
|
||||
|
||||
/// Constant shared across tests for the [`Multihash`](libp2p_core::multihash::Multihash) type.
|
||||
#[cfg(test)]
|
||||
const SHA_256_MH: u64 = 0x12;
|
||||
|
@ -475,7 +475,8 @@ enum PeerState {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use libp2p_core::multihash::{Code, Multihash};
|
||||
use crate::SHA_256_MH;
|
||||
use libp2p_core::multihash::Multihash;
|
||||
use libp2p_identity::PeerId;
|
||||
use quickcheck::*;
|
||||
use rand::{rngs::StdRng, Rng, SeedableRng};
|
||||
@ -484,10 +485,8 @@ mod tests {
|
||||
fn random_peers<R: Rng>(n: usize, g: &mut R) -> Vec<PeerId> {
|
||||
(0..n)
|
||||
.map(|_| {
|
||||
PeerId::from_multihash(
|
||||
Multihash::wrap(Code::Sha2_256.into(), &g.gen::<[u8; 32]>()).unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
PeerId::from_multihash(Multihash::wrap(SHA_256_MH, &g.gen::<[u8; 32]>()).unwrap())
|
||||
.unwrap()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@ -505,8 +504,7 @@ mod tests {
|
||||
fn arbitrary(g: &mut Gen) -> ArbitraryPeerId {
|
||||
let hash: [u8; 32] = core::array::from_fn(|_| u8::arbitrary(g));
|
||||
let peer_id =
|
||||
PeerId::from_multihash(Multihash::wrap(Code::Sha2_256.into(), &hash).unwrap())
|
||||
.unwrap();
|
||||
PeerId::from_multihash(Multihash::wrap(SHA_256_MH, &hash).unwrap()).unwrap();
|
||||
ArbitraryPeerId(peer_id)
|
||||
}
|
||||
}
|
||||
|
@ -444,8 +444,8 @@ impl<I: Iterator<Item = Key<PeerId>>> Iterator for ResultIter<I> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::K_VALUE;
|
||||
use libp2p_core::multihash::{Code, Multihash};
|
||||
use crate::{K_VALUE, SHA_256_MH};
|
||||
use libp2p_core::multihash::Multihash;
|
||||
use quickcheck::*;
|
||||
use std::collections::HashSet;
|
||||
use std::iter;
|
||||
@ -531,8 +531,7 @@ mod tests {
|
||||
fn arbitrary(g: &mut Gen) -> ArbitraryPeerId {
|
||||
let hash: [u8; 32] = core::array::from_fn(|_| u8::arbitrary(g));
|
||||
let peer_id =
|
||||
PeerId::from_multihash(Multihash::wrap(Code::Sha2_256.into(), &hash).unwrap())
|
||||
.unwrap();
|
||||
PeerId::from_multihash(Multihash::wrap(SHA_256_MH, &hash).unwrap()).unwrap();
|
||||
ArbitraryPeerId(peer_id)
|
||||
}
|
||||
}
|
||||
|
@ -161,14 +161,14 @@ impl ProviderRecord {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use libp2p_core::multihash::Code;
|
||||
use crate::SHA_256_MH;
|
||||
use quickcheck::*;
|
||||
use std::time::Duration;
|
||||
|
||||
impl Arbitrary for Key {
|
||||
fn arbitrary(g: &mut Gen) -> Key {
|
||||
let hash: [u8; 32] = core::array::from_fn(|_| u8::arbitrary(g));
|
||||
Key::from(Multihash::wrap(Code::Sha2_256.into(), &hash).unwrap())
|
||||
Key::from(Multihash::wrap(SHA_256_MH, &hash).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -216,12 +216,13 @@ impl RecordStore for MemoryStore {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use libp2p_core::multihash::{Code, Multihash};
|
||||
use crate::SHA_256_MH;
|
||||
use libp2p_core::multihash::Multihash;
|
||||
use quickcheck::*;
|
||||
use rand::Rng;
|
||||
|
||||
fn random_multihash() -> Multihash {
|
||||
Multihash::wrap(Code::Sha2_256.into(), &rand::thread_rng().gen::<[u8; 32]>()).unwrap()
|
||||
Multihash::wrap(SHA_256_MH, &rand::thread_rng().gen::<[u8; 32]>()).unwrap()
|
||||
}
|
||||
|
||||
fn distance(r: &ProviderRecord) -> kbucket::Distance {
|
||||
|
@ -22,7 +22,8 @@ libp2p-core = { version = "0.39.0", path = "../../core" }
|
||||
libp2p-noise = { version = "0.42.0", path = "../../transports/noise" }
|
||||
libp2p-identity = { version = "0.1.0", path = "../../identity" }
|
||||
log = "0.4"
|
||||
multihash = { version = "0.17.0", default-features = false, features = ["sha2"] }
|
||||
sha2 = "0.10.6"
|
||||
multihash = { version = "0.17.0", default-features = false }
|
||||
quick-protobuf = "0.8"
|
||||
quick-protobuf-codec = { version = "0.1", path = "../../misc/quick-protobuf-codec" }
|
||||
rand = "0.8"
|
||||
|
@ -18,12 +18,15 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use multihash::{Code, Hasher, Multihash, MultihashDigest};
|
||||
use multihash::MultihashGeneric;
|
||||
use sha2::Digest as _;
|
||||
use std::fmt;
|
||||
use webrtc::dtls_transport::dtls_fingerprint::RTCDtlsFingerprint;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
const SHA256: &str = "sha-256";
|
||||
const MULTIHASH_SHA256_CODE: u64 = 0x12;
|
||||
|
||||
type Multihash = MultihashGeneric<64>;
|
||||
|
||||
/// A certificate fingerprint that is assumed to be created using the SHA256 hash algorithm.
|
||||
#[derive(Eq, PartialEq, Copy, Clone)]
|
||||
@ -39,13 +42,7 @@ impl Fingerprint {
|
||||
|
||||
/// Creates a fingerprint from a raw certificate.
|
||||
pub fn from_certificate(bytes: &[u8]) -> Self {
|
||||
let mut h = multihash::Sha2_256::default();
|
||||
h.update(bytes);
|
||||
|
||||
let mut bytes: [u8; 32] = [0; 32];
|
||||
bytes.copy_from_slice(h.finalize());
|
||||
|
||||
Fingerprint(bytes)
|
||||
Fingerprint(sha2::Sha256::digest(bytes).into())
|
||||
}
|
||||
|
||||
/// Converts [`RTCDtlsFingerprint`] to [`Fingerprint`].
|
||||
@ -60,9 +57,9 @@ impl Fingerprint {
|
||||
Some(Self(buf))
|
||||
}
|
||||
|
||||
/// Converts [`type@Multihash`] to [`Fingerprint`].
|
||||
/// Converts [`Multihash`](MultihashGeneric) to [`Fingerprint`].
|
||||
pub fn try_from_multihash(hash: Multihash) -> Option<Self> {
|
||||
if hash.code() != u64::from(Code::Sha2_256) {
|
||||
if hash.code() != MULTIHASH_SHA256_CODE {
|
||||
// Only support SHA256 for now.
|
||||
return None;
|
||||
}
|
||||
@ -72,11 +69,9 @@ impl Fingerprint {
|
||||
Some(Self(bytes))
|
||||
}
|
||||
|
||||
/// Converts this fingerprint to [`type@Multihash`].
|
||||
/// Converts this fingerprint to [`Multihash`](MultihashGeneric).
|
||||
pub fn to_multihash(self) -> Multihash {
|
||||
Code::Sha2_256
|
||||
.wrap(&self.0)
|
||||
.expect("fingerprint's len to be 32 bytes")
|
||||
Multihash::wrap(MULTIHASH_SHA256_CODE, &self.0).expect("fingerprint's len to be 32 bytes")
|
||||
}
|
||||
|
||||
/// Formats this fingerprint as uppercase hex, separated by colons (`:`).
|
||||
|
Reference in New Issue
Block a user