From ad4b4946219ef92726e15954c9af1fdec23610a1 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 24 Nov 2017 12:12:04 +0100 Subject: [PATCH] Remove custom multihash library --- Cargo.toml | 1 - README.md | 3 - multihash/Cargo.toml | 8 -- multihash/src/lib.rs | 241 ------------------------------------------- 4 files changed, 253 deletions(-) delete mode 100644 multihash/Cargo.toml delete mode 100644 multihash/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 800cca3d..42db7aa5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,5 @@ [workspace] members = [ - "multihash", "multistream-select", "datastore", "example", diff --git a/README.md b/README.md index eb0d0316..e389a7c8 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,6 @@ Architecture of the crates of this repository: `ConnectionUpgrade` trait of `libp2p-swarm`. - `libp2p-swarm`: Core library that contains all the traits of *libp2p* and plugs things together. - `libp2p-tcp-transport`: Implementation of the `Transport` trait of `libp2p-swarm` for TCP/IP. -- `multihash`: Utility library that allows one to represent and manipulate - [*multihashes*](https://github.com/multiformats/multihash). A *multihash* is a combination of a - hash and its hashing algorithm. - `multistream-select`: Implementation of the `multistream-select` protocol, which is used to negotiate a protocol over a newly-established connection with a peer, or after a connection upgrade. diff --git a/multihash/Cargo.toml b/multihash/Cargo.toml deleted file mode 100644 index faa281f0..00000000 --- a/multihash/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "multihash" -version = "0.1.0" -authors = ["Parity Technologies "] - -[dependencies] -hex = "0.2" -byteorder = "1.1" diff --git a/multihash/src/lib.rs b/multihash/src/lib.rs deleted file mode 100644 index e801074e..00000000 --- a/multihash/src/lib.rs +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2017 Parity Technologies (UK) Ltd. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -extern crate hex; -extern crate byteorder; - -use std::fmt; -use std::collections::HashSet; -use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; -use hex::FromHex; - -const ID: u64 = 0x00; -const SHA1: u64 = 0x11; -const SHA2_256: u64 = 0x12; -const SHA2_512: u64 = 0x13; -const SHA3_224: u64 = 0x17; -const SHA3_256: u64 = 0x16; -const SHA3_384: u64 = 0x15; -const SHA3_512: u64 = 0x14; -const SHA3: u64 = SHA3_512; -const KECCAK_224: u64 = 0x1A; -const KECCAK_256: u64 = 0x1B; -const KECCAK_384: u64 = 0x1C; -const KECCAK_512: u64 = 0x1D; -const SHAKE_128: u64 = 0x18; -const SHAKE_256: u64 = 0x19; -const DBL_SHA2_256: u64 = 0x56; -const MURMUR3: u64 = 0x22; - -const BLAKE2B_MIN: u64 = 0xb201; -const BLAKE2B_MAX: u64 = 0xb240; -const BLAKE2S_MIN: u64 = 0xb241; -const BLAKE2S_MAX: u64 = 0xb260; - -thread_local! { - // Create a static set of CODES that we are willing to accept - static CODES: HashSet = { - let mut set = HashSet::new(); - set.insert(ID); - set.insert(SHA1); - set.insert(SHA2_256); - set.insert(SHA2_512); - set.insert(SHA3_224); - set.insert(SHA3_256); - set.insert(SHA3_384); - set.insert(SHA3_512); - set.insert(SHA3); - set.insert(KECCAK_224); - set.insert(KECCAK_256); - set.insert(KECCAK_384); - set.insert(KECCAK_512); - set.insert(SHAKE_128); - set.insert(SHAKE_256); - set.insert(DBL_SHA2_256); - set.insert(MURMUR3); - for c in BLAKE2B_MIN..BLAKE2B_MAX { set.insert(c); } - for c in BLAKE2S_MIN..BLAKE2S_MAX { set.insert(c); } - set - }; -} - -/// Error type for Multihash represents all possible decoding errors from hex string or bytes -#[derive(Debug)] -pub enum Error { - /// Got invalid input hex - FromHexError, - /// Couldn't parse the code from bytes - UnreadableCode, - /// The code parsed (given in argument) isn't a known code for any hash - UnknownCode(u64), - /// Couldn't parse the length from bytes - UnreadableLength, - /// The length provided (found in first argument) doesn't match the actual - /// length of the input digest (given in second argument). - InvalidLength(u64, usize), -} - -/// Multihash is a structure for tagging a hash with some meta data, -/// such as its type and length. This facilitiates reading them over -/// (for instance) a network stream. The format is as follows: -/// -/// See the spec for more information. -#[derive(Debug, PartialEq, Eq, Clone, Hash)] -pub struct Multihash { - /// The code of the hash algorithm in question - code: u64, - /// Length of the digest byte vector - length: u64, - /// Raw bytes of the hash digest - digest: Vec, -} - -/// Display of a Multihash prints the "raw" hex string, including code and length -impl fmt::Display for Multihash { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:016x}{:016x}", self.code, self.length)?; - for x in &self.digest { - write!(f, "{:02x}", x)?; - } - Ok(()) - } -} - -/// FromHex implementation is provided along with `Multihash::decode_hex_string` in case -/// someone already has FromHex imported and they would prefer to use that for some reason -impl FromHex for Multihash { - type Error = Error; - fn from_hex>(s: T) -> Result { - let bs = Vec::from_hex(s).map_err(|_| Error::FromHexError)?; - Self::decode_bytes(bs) - } -} - -impl Multihash { - /// Returns a byte vec representing the encoded multihash - pub fn to_bytes(&self) -> Vec { - let mut v = Vec::new(); - v.write_u64::(self.code).expect("writing to a locally owned vec should never yield I/O errors"); - v.write_u64::(self.length).expect("writing to a locally owned vec should never yield I/O errors"); - v.extend_from_slice(&self.digest); - v - } - - /// Takes a code for a digest type and a vec of bytes of the digest and returns a Multihash - pub fn encode_bytes(code: u64, bytes: Vec) -> Result { - if !Multihash::valid_code(&code) { - return Err(Error::UnknownCode(code)); - } - Ok(Multihash { - code: code, - length: bytes.len() as u64, - digest: bytes - }) - } - - /// Takes a code for a digest type and a hex string of the digest and returns a Multihash - pub fn encode_hex_string(code: u64, hex: String) -> Result { - let bytes = Vec::from_hex(&hex).map_err(|_| Error::FromHexError)?; - Self::encode_bytes(code, bytes) - } - - /// Decode a vec of bytes into a Multihash, consuming the vec in the process - pub fn decode_bytes(bytes: Vec) -> Result { - let mut rdr = bytes.as_slice(); - let code = rdr.read_u64::().map_err(|_| Error::UnreadableCode)?; - let length = rdr.read_u64::().map_err(|_| Error::UnreadableLength)?; - let bytes = rdr.to_vec(); - - if !Multihash::valid_code(&code) { - return Err(Error::UnknownCode(code)); - } - if bytes.len() != length as usize { - return Err(Error::InvalidLength(length, bytes.len())); - } - - Ok(Multihash { - code: code, - length: length, - digest: bytes - }) - } - - /// Convert a hex string to a Multihash - pub fn decode_hex_string>(s: T) -> Result { - /// Using this here to not have to reexport the hex::FromHex trait - Multihash::from_hex(s) - } - - /// Checks if the given code is a valid code for multihash - pub fn valid_code(c: &u64) -> bool { - CODES.with(|codes| codes.contains(c)) - } -} - - -#[cfg(test)] -mod tests { - use super::{Multihash}; - - #[test] - fn multihash_can_be_displayed() { - let hash = Multihash { code: 0x11, length: 3, digest: vec![42, 0, 255]}; - assert_eq!(format!("{}", hash), "000000000000001100000000000000032a00ff"); - } - - #[test] - fn produces_correct_vec_of_bytes() { - let digest_bytes = vec![44, 38, 180, 107, 104, 255, 198, 143, 249, 155, 69, 60, 29, 48, 65, 52, 19, 66, 45, 112, 100, 131, 191, 160, 249, 138, 94, 136, 98, 102, 231, 174]; - let hash = Multihash { - code: 0x00, - length: digest_bytes.len() as u64, - digest: digest_bytes - }; - let expected_bytes = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 44, 38, 180, 107, 104, 255, 198, 143, 249, 155, 69, 60, 29, 48, 65, 52, 19, 66, 45, 112, 100, 131, 191, 160, 249, 138, 94, 136, 98, 102, 231, 174]; - - assert_eq!(hash.to_bytes(), expected_bytes); - - assert_eq!(Multihash::decode_bytes(expected_bytes).unwrap(), hash); - } - - #[test] - fn encoding_hashes() { - let hex_string = "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"; - let hash = Multihash::encode_hex_string(0x00, hex_string.to_owned()).unwrap(); - let expected_bytes = vec![44,38,180,107,104,255,198,143,249,155,69,60,29,48,65,52,19,66,45,112,100,131,191,160,249,138,94,136,98,102,231,174]; - assert_eq!(hash, Multihash { - code: 0x00, - length: expected_bytes.len() as u64, - digest: expected_bytes - }); - } - - #[test] - fn decoding_hashes() { - let hex_string = "000000000000000000000000000000202c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"; - let hash = Multihash::decode_hex_string(hex_string).unwrap(); - let expected_bytes = vec![44,38,180,107,104,255,198,143,249,155,69,60,29,48,65,52,19,66,45,112,100,131,191,160,249,138,94,136,98,102,231,174]; - assert_eq!(hash, Multihash { - code: 0x00, - length: expected_bytes.len() as u64, - digest: expected_bytes - }); - } -}