From fe3319d6d4ba8213e6e69b532192a71100438ace Mon Sep 17 00:00:00 2001 From: austinabell Date: Mon, 13 Jan 2020 15:53:16 -0500 Subject: [PATCH 01/17] Refactor cid, implement cbor deserialize, implement trait on Cid wrapper --- Cargo.toml | 3 +- Makefile | 2 + ipld/Cargo.toml | 10 +++ ipld/cid/Cargo.toml | 6 +- ipld/cid/src/lib.rs | 61 ++++++++++----- ipld/cid/src/to_cid.rs | 8 +- ipld/src/lib.rs | 159 +++++++++++++++++++++++++++++++++++++++ vm/actor/Cargo.toml | 2 +- vm/runtime/Cargo.toml | 2 +- vm/state_tree/Cargo.toml | 2 +- 10 files changed, 229 insertions(+), 26 deletions(-) create mode 100644 ipld/Cargo.toml create mode 100644 ipld/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 160143bf5a94..a9d510b058cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,5 +16,6 @@ members = [ "node/clock", "crypto", "encoding", - "ipld/cid" + "ipld/cid", + "ipld", ] diff --git a/Makefile b/Makefile index 886704ae928d..425b2358da8c 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,8 @@ clean: @cargo clean -p interpreter @cargo clean -p crypto @cargo clean -p encoding + @cargo clean -p ferret_cid + @cargo clean -p ferret_ipld @echo "Done cleaning." lint: clean license diff --git a/ipld/Cargo.toml b/ipld/Cargo.toml new file mode 100644 index 000000000000..7211378cb164 --- /dev/null +++ b/ipld/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "ferret_ipld" +version = "0.1.0" +authors = ["austinabell "] +edition = "2018" + +[dependencies] +serde = "1.0" +serde_bytes = "0.11.3" +serde_cbor = {version = "0.11.0", features = ["tags"]} diff --git a/ipld/cid/Cargo.toml b/ipld/cid/Cargo.toml index ebe680c35ab1..e788d463bb9f 100644 --- a/ipld/cid/Cargo.toml +++ b/ipld/cid/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "cid" +name = "ferret_cid" version = "0.1.0" authors = ["ChainSafe Systems "] edition = "2018" @@ -9,3 +9,7 @@ dep_cid = {package = "cid", version = "0.3.1"} multihash = "0.8.0" multibase = "0.6.0" integer-encoding = "1.0.3" + +serde = "1.0" +serde_bytes = "0.11.3" +serde_cbor = {version = "0.11.0", features = ["tags"]} \ No newline at end of file diff --git a/ipld/cid/src/lib.rs b/ipld/cid/src/lib.rs index c8a62aa810d2..b4109ad8fa50 100644 --- a/ipld/cid/src/lib.rs +++ b/ipld/cid/src/lib.rs @@ -5,8 +5,14 @@ mod to_cid; pub use self::to_cid::ToCid; pub use dep_cid::{Cid as BaseCid, Codec, Error, Prefix, Version}; +use serde::de; +use serde::ser; +use serde_bytes; +use serde_cbor::tags::Tagged; use std::ops::{Deref, DerefMut}; +const CBOR_TAG_CID: u64 = 42; + /// Representation of an IPLD Cid #[derive(PartialEq, Eq, Clone, Debug, Hash)] pub struct Cid { @@ -40,32 +46,50 @@ impl DerefMut for Cid { } } -impl Cid { - /// Cid constructor - pub fn new(cid: BaseCid) -> Self { - Self { cid } - } - /// Constructs a v0 cid with a given codec and bytes - pub fn from_bytes_v0(codec: Codec, bz: B) -> Self +impl ser::Serialize for Cid { + fn serialize(&self, s: S) -> Result where - B: AsRef<[u8]>, + S: ser::Serializer, { - Self { - cid: BaseCid::new(codec, Version::V0, bz.as_ref()), - } + let cid_bytes = self.cid.to_bytes(); + let value = serde_bytes::Bytes::new(&cid_bytes); + Tagged::new(Some(CBOR_TAG_CID), &value).serialize(s) } - /// Constructs a v1 cid with a given codec and bytes - pub fn from_bytes_v1(codec: Codec, bz: B) -> Self +} + +impl<'de> de::Deserialize<'de> for Cid { + fn deserialize(deserializer: D) -> Result where - B: AsRef<[u8]>, + D: de::Deserializer<'de>, { + let tagged = Tagged::::deserialize(deserializer)?; + match tagged.tag { + // TODO verify this + Some(CBOR_TAG_CID) | None => Ok(tagged + .value + .to_vec() + .to_cid() + .map_err(|e| de::Error::custom(e.to_string()))?), + Some(_) => Err(de::Error::custom("unexpected tag")), + } + } +} + +impl Cid { + /// Cid constructor + pub fn new(cid: BaseCid) -> Self { + Self { cid } + } + + /// Constructs a cid with bytes using default version and codec + pub fn from_bytes_default>(bz: B) -> Self { Self { - cid: BaseCid::new(codec, Version::V1, bz.as_ref()), + cid: BaseCid::new(Codec::DagCBOR, Version::V1, bz.as_ref()), } } /// Create a new CID from raw data (binary or multibase encoded string) - pub fn from(data: T) -> Result { + pub fn from_raw(data: T) -> Result { data.to_cid() } @@ -73,11 +97,10 @@ impl Cid { pub fn new_from_prefix(prefix: &Prefix, data: &[u8]) -> Cid { let mut hash = multihash::encode(prefix.mh_type.to_owned(), data).unwrap(); hash.truncate(prefix.mh_len + 2); - BaseCid { + Cid::from(BaseCid { version: prefix.version, codec: prefix.codec.to_owned(), hash, - } - .into() + }) } } diff --git a/ipld/cid/src/to_cid.rs b/ipld/cid/src/to_cid.rs index c1391c4eb96e..3d4ef88e5c5a 100644 --- a/ipld/cid/src/to_cid.rs +++ b/ipld/cid/src/to_cid.rs @@ -84,7 +84,11 @@ impl ToCid for [u8] { // Verify that hash can be decoded, this is very cheap multihash::decode(self)?; - Ok(BaseCid::new(Codec::DagProtobuf, Version::V0, self).into()) + Ok(Cid::from(BaseCid::new( + Codec::DagProtobuf, + Version::V0, + self, + ))) } else { let mut cur = Cursor::new(self); let raw_version = cur.read_varint()?; @@ -98,7 +102,7 @@ impl ToCid for [u8] { // Verify that hash can be decoded, this is very cheap multihash::decode(hash)?; - Ok(BaseCid::new(codec, version, hash).into()) + Ok(Cid::from(BaseCid::new(codec, version, hash))) } } } diff --git a/ipld/src/lib.rs b/ipld/src/lib.rs new file mode 100644 index 000000000000..47b03bcad956 --- /dev/null +++ b/ipld/src/lib.rs @@ -0,0 +1,159 @@ +// Copyright 2020 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0 + +use serde::de; +use serde::Deserialize; +use serde_cbor::tags::current_cbor_tag; +use std::collections::BTreeMap; +use std::fmt; + +#[derive(Debug, Clone)] +pub enum Ipld { + Null, + Bool(bool), + Integer(i128), + Float(f64), + String(String), + Bytes(Vec), + List(Vec), + Map(BTreeMap), + Link(Vec), +} + +pub struct IpldVisitor; + +impl<'de> de::Visitor<'de> for IpldVisitor { + type Value = Ipld; + + fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.write_str("any valid CBOR value") + } + + fn visit_str(self, value: &str) -> Result + where + E: de::Error, + { + self.visit_string(String::from(value)) + } + + fn visit_string(self, value: String) -> Result + where + E: de::Error, + { + Ok(Ipld::String(value)) + } + fn visit_bytes(self, v: &[u8]) -> Result + where + E: de::Error, + { + self.visit_byte_buf(v.to_owned()) + } + + fn visit_byte_buf(self, v: Vec) -> Result + where + E: de::Error, + { + Ok(Ipld::Bytes(v)) + } + + fn visit_u64(self, v: u64) -> Result + where + E: de::Error, + { + Ok(Ipld::Integer(v.into())) + } + + fn visit_i64(self, v: i64) -> Result + where + E: de::Error, + { + Ok(Ipld::Integer(v.into())) + } + + fn visit_i128(self, v: i128) -> Result + where + E: de::Error, + { + Ok(Ipld::Integer(v)) + } + + fn visit_bool(self, v: bool) -> Result + where + E: de::Error, + { + Ok(Ipld::Bool(v)) + } + + fn visit_none(self) -> Result + where + E: de::Error, + { + self.visit_unit() + } + + fn visit_unit(self) -> Result + where + E: de::Error, + { + Ok(Ipld::Null) + } + + fn visit_seq(self, mut visitor: V) -> Result + where + V: de::SeqAccess<'de>, + { + let mut vec = Vec::new(); + + while let Some(elem) = visitor.next_element()? { + vec.push(elem); + } + + Ok(Ipld::List(vec)) + } + + fn visit_map(self, mut visitor: V) -> Result + where + V: de::MapAccess<'de>, + { + let mut values = BTreeMap::new(); + + while let Some((key, value)) = visitor.next_entry()? { + values.insert(key, value); + } + + Ok(Ipld::Map(values)) + } + + fn visit_f64(self, v: f64) -> Result + where + E: de::Error, + { + Ok(Ipld::Float(v)) + } + + fn visit_newtype_struct(self, deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + match current_cbor_tag() { + Some(42) => { + let link = match Ipld::deserialize(deserializer) { + Ok(Ipld::Bytes(link)) => link, + _ => return Err(de::Error::custom("bytes expected")), + }; + Ok(Ipld::Link(link)) + } + Some(tag) => Err(de::Error::custom(format!("unexpected tag ({})", tag))), + _ => Err(de::Error::custom("tag expected")), + } + } +} + +impl<'de> de::Deserialize<'de> for Ipld { + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + deserializer.deserialize_any(IpldVisitor) + } +} diff --git a/vm/actor/Cargo.toml b/vm/actor/Cargo.toml index ef4d13472b07..2227137ad080 100644 --- a/vm/actor/Cargo.toml +++ b/vm/actor/Cargo.toml @@ -13,4 +13,4 @@ encoding = {path = "../../encoding"} num-traits = "0.2" num-derive = "0.2" clock = {path = "../../node/clock"} -cid = {path = "../../ipld/cid"} +cid = {package = "ferret_cid", path = "../../ipld/cid"} diff --git a/vm/runtime/Cargo.toml b/vm/runtime/Cargo.toml index 571d76e099e3..02e320988044 100644 --- a/vm/runtime/Cargo.toml +++ b/vm/runtime/Cargo.toml @@ -9,5 +9,5 @@ vm = {path = "../../vm"} crypto = {path = "../../crypto"} address = {path = "../address"} message = {path = "../message"} -cid = {path = "../../ipld/cid"} +cid = {package = "ferret_cid", path = "../../ipld/cid"} clock = {path = "../../node/clock"} diff --git a/vm/state_tree/Cargo.toml b/vm/state_tree/Cargo.toml index ef7748660c47..915f0ea518b5 100644 --- a/vm/state_tree/Cargo.toml +++ b/vm/state_tree/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" actor = {path = "../actor"} address = {path = "../address"} vm = {path = "../../vm"} -cid = {path = "../../ipld/cid"} +cid = {package = "ferret_cid", path = "../../ipld/cid"} [dev-dependencies] num-bigint = "0.2.3" From f3e18114bc7f58ae8600189af952c30106ae3f86 Mon Sep 17 00:00:00 2001 From: austinabell Date: Mon, 13 Jan 2020 17:14:51 -0500 Subject: [PATCH 02/17] implement cbor encoding for address --- encoding/Cargo.toml | 2 +- ipld/cid/src/to_cid.rs | 3 +-- vm/address/Cargo.toml | 4 +++- vm/address/src/lib.rs | 52 +++++++++++++++++++++++++++--------------- 4 files changed, 39 insertions(+), 22 deletions(-) diff --git a/encoding/Cargo.toml b/encoding/Cargo.toml index 8fd50e72ee7e..5ef9e483e93f 100644 --- a/encoding/Cargo.toml +++ b/encoding/Cargo.toml @@ -8,4 +8,4 @@ edition = "2018" [dependencies] blake2b_simd = "0.5.9" -serde_cbor = "0.10.2" +serde_cbor = "0.11.0" diff --git a/ipld/cid/src/to_cid.rs b/ipld/cid/src/to_cid.rs index 3d4ef88e5c5a..8bc1ce981325 100644 --- a/ipld/cid/src/to_cid.rs +++ b/ipld/cid/src/to_cid.rs @@ -1,14 +1,13 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0 +use crate::{BaseCid, Cid, Codec, Error, Version}; use integer_encoding::VarIntReader; use multibase; use multihash; use std::io::Cursor; use std::str::FromStr; -use crate::{BaseCid, Cid, Codec, Error, Version}; - pub trait ToCid { fn to_cid(&self) -> Result; } diff --git a/vm/address/Cargo.toml b/vm/address/Cargo.toml index 051bd0ebf64c..583674aa778a 100644 --- a/vm/address/Cargo.toml +++ b/vm/address/Cargo.toml @@ -11,4 +11,6 @@ data-encoding = "2.1.2" data-encoding-macro = "0.1.7" leb128 = "0.2.1" encoding = {path = "../../encoding"} -serde_cbor = "0.10.2" +serde = "1.0" +serde_bytes = "0.11.3" +serde_cbor = {version = "0.11.0", features = ["tags"]} \ No newline at end of file diff --git a/vm/address/src/lib.rs b/vm/address/src/lib.rs index a973e26b39f2..76ab730c3a8d 100644 --- a/vm/address/src/lib.rs +++ b/vm/address/src/lib.rs @@ -12,7 +12,9 @@ use data_encoding::Encoding; use data_encoding_macro::{internal_new_encoding, new_encoding}; use encoding::{blake2b_variable, Cbor, CodecProtocol, Error as EncodingError}; use leb128; -use serde_cbor::Value::Bytes; +use serde::{de, ser}; +use serde_bytes; +use serde_cbor::tags::Tagged; use serde_cbor::{from_slice, to_vec}; use std::hash::Hash; @@ -176,29 +178,43 @@ impl Address { } } +impl ser::Serialize for Address { + fn serialize(&self, s: S) -> Result + where + S: ser::Serializer, + { + let address_bytes = self.to_bytes(); + let value = serde_bytes::Bytes::new(&address_bytes); + Tagged::new(None, &value).serialize(s) + } +} + +impl<'de> de::Deserialize<'de> for Address { + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + let mut bz: Vec = serde_bytes::Deserialize::deserialize(deserializer)?; + // Remove protocol byte + let protocol = Protocol::from_byte(bz.remove(0)) + .ok_or(EncodingError::Unmarshalling { + description: format!("Invalid protocol byte: {}", bz[0]), + protocol: CodecProtocol::Cbor, + }) + .map_err(de::Error::custom)?; + // Create and return created address of unmarshalled bytes + Ok(Address::new(protocol, bz).map_err(de::Error::custom)?) + } +} + impl Cbor for Address { fn unmarshal_cbor(bz: &[u8]) -> Result { // Convert cbor encoded to bytes - let mut vec = match from_slice(bz) { - Ok(Bytes(v)) => v, - _ => { - return Err(EncodingError::Unmarshalling { - description: "Could not decode as bytes".to_owned(), - protocol: CodecProtocol::Cbor, - }); - } - }; - // Remove protocol byte - let protocol = Protocol::from_byte(vec.remove(0)).ok_or(EncodingError::Unmarshalling { - description: format!("Invalid protocol byte: {}", bz[0]), - protocol: CodecProtocol::Cbor, - })?; - // Create and return created address of unmarshalled bytes - Ok(Address::new(protocol, vec)?) + Ok(from_slice(bz)?) } fn marshal_cbor(&self) -> Result, EncodingError> { // encode bytes - Ok(to_vec(&Bytes(self.to_bytes()))?) + Ok(to_vec(&self)?) } } From 929b02c5a070f7c6236a7b2deb64116b8396a9e5 Mon Sep 17 00:00:00 2001 From: austinabell Date: Mon, 13 Jan 2020 19:52:11 -0500 Subject: [PATCH 03/17] Refactor and derive serialization traits on all necessary types --- encoding/Cargo.toml | 6 ++--- encoding/src/cbor.rs | 11 +++++--- encoding/src/lib.rs | 5 ++++ vm/Cargo.toml | 1 + vm/actor/Cargo.toml | 1 + vm/actor/src/builtin/init.rs | 4 +-- vm/actor/src/lib.rs | 22 +++------------- vm/address/src/lib.rs | 15 ++--------- vm/address/tests/address_test.rs | 4 +-- vm/message/Cargo.toml | 2 +- vm/message/src/lib.rs | 6 ++--- vm/message/src/signed_message.rs | 28 ++++++--------------- vm/message/src/unsigned_message.rs | 40 ++++++++++-------------------- vm/message/tests/builder_test.rs | 11 +++----- vm/src/method.rs | 21 +++++++--------- vm/src/token.rs | 22 ++++++++++++++++ vm/tests/params_test.rs | 4 +-- 17 files changed, 88 insertions(+), 115 deletions(-) diff --git a/encoding/Cargo.toml b/encoding/Cargo.toml index 5ef9e483e93f..2b2e214b3e22 100644 --- a/encoding/Cargo.toml +++ b/encoding/Cargo.toml @@ -4,8 +4,8 @@ version = "0.1.0" authors = ["ChainSafe Systems "] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] blake2b_simd = "0.5.9" -serde_cbor = "0.11.0" +serde = {version = "1.0", features = ["derive"]} +serde_bytes = "0.11.3" +serde_cbor = {version = "0.11.0", features = ["tags"]} diff --git a/encoding/src/cbor.rs b/encoding/src/cbor.rs index 05ce0405f4f9..c3eca8ed46e2 100644 --- a/encoding/src/cbor.rs +++ b/encoding/src/cbor.rs @@ -2,11 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 use super::errors::Error; +use crate::{ser, to_vec}; /// Implemented for types that are CBOR encodable -pub trait Cbor { - fn unmarshal_cbor(bz: &[u8]) -> Result +pub trait Cbor: ser::Serialize { + fn marshal_cbor(&self) -> Result, Error> where - Self: Sized; - fn marshal_cbor(&self) -> Result, Error>; + Self: ser::Serialize, + { + Ok(to_vec(&self)?) + } } diff --git a/encoding/src/lib.rs b/encoding/src/lib.rs index 0a59fd821139..fd276c3c4fbc 100644 --- a/encoding/src/lib.rs +++ b/encoding/src/lib.rs @@ -5,6 +5,11 @@ mod cbor; mod errors; mod hash; +pub use serde::{de, ser}; +pub use serde_bytes; +pub use serde_cbor::{from_reader, from_slice, to_vec, to_writer}; +// pub use serde_derive::*; + pub use self::cbor::*; pub use self::errors::*; pub use self::hash::*; diff --git a/vm/Cargo.toml b/vm/Cargo.toml index f5b6583f920f..f4678d9de1fd 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -8,3 +8,4 @@ edition = "2018" num-bigint = "0.2.3" address = {path = "./address"} encoding = {path = "../encoding"} +serde = {version = "1.0", features = ["derive"]} diff --git a/vm/actor/Cargo.toml b/vm/actor/Cargo.toml index 2227137ad080..eaa922ca35df 100644 --- a/vm/actor/Cargo.toml +++ b/vm/actor/Cargo.toml @@ -14,3 +14,4 @@ num-traits = "0.2" num-derive = "0.2" clock = {path = "../../node/clock"} cid = {package = "ferret_cid", path = "../../ipld/cid"} +serde = {version = "1.0", features = ["derive"]} diff --git a/vm/actor/src/builtin/init.rs b/vm/actor/src/builtin/init.rs index 11401e312013..d674b78fe620 100644 --- a/vm/actor/src/builtin/init.rs +++ b/vm/actor/src/builtin/init.rs @@ -7,7 +7,7 @@ use vm::{ }; use address::Address; -use encoding::Cbor; +use encoding::{from_slice, Cbor}; use num_derive::FromPrimitive; use num_traits::FromPrimitive; use runtime::{arg_end, arg_pop, check_args, ActorCode, Runtime}; @@ -87,7 +87,7 @@ impl ActorCode for InitActorCode { } Some(InitMethod::GetActorIDForAddress) => { // Pop and unmarshall address parameter - let addr_res = Address::unmarshal_cbor(&arg_pop(params, rt).bytes()); + let addr_res = from_slice(&arg_pop(params, rt).bytes()); // validate addr deserialization and parameters check_args(params, rt, addr_res.is_ok()); diff --git a/vm/actor/src/lib.rs b/vm/actor/src/lib.rs index f667c4159189..5a79f6743ea9 100644 --- a/vm/actor/src/lib.rs +++ b/vm/actor/src/lib.rs @@ -8,28 +8,14 @@ pub use self::builtin::*; pub use self::code::*; use cid::Cid; -use encoding::{Cbor, CodecProtocol, Error as EncodingError}; +use encoding::Cbor; use num_bigint::BigUint; +use serde::{Deserialize, Serialize}; -#[derive(PartialEq, Eq, Copy, Clone, Debug, Default)] +#[derive(PartialEq, Eq, Copy, Clone, Debug, Default, Serialize, Deserialize)] pub struct ActorID(u64); -impl Cbor for ActorID { - fn unmarshal_cbor(_bz: &[u8]) -> Result { - // TODO - Err(EncodingError::Unmarshalling { - description: "Not Implemented".to_string(), - protocol: CodecProtocol::Cbor, - }) - } - fn marshal_cbor(&self) -> Result, EncodingError> { - // TODO - Err(EncodingError::Marshalling { - description: format!("Not implemented, data: {:?}", self), - protocol: CodecProtocol::Cbor, - }) - } -} +impl Cbor for ActorID {} /// State of all actor implementations #[derive(PartialEq, Eq, Clone, Debug)] diff --git a/vm/address/src/lib.rs b/vm/address/src/lib.rs index 76ab730c3a8d..9c7522d91eb2 100644 --- a/vm/address/src/lib.rs +++ b/vm/address/src/lib.rs @@ -14,8 +14,6 @@ use encoding::{blake2b_variable, Cbor, CodecProtocol, Error as EncodingError}; use leb128; use serde::{de, ser}; use serde_bytes; -use serde_cbor::tags::Tagged; -use serde_cbor::{from_slice, to_vec}; use std::hash::Hash; /// defines the encoder for base32 encoding with the provided string with no padding @@ -185,7 +183,7 @@ impl ser::Serialize for Address { { let address_bytes = self.to_bytes(); let value = serde_bytes::Bytes::new(&address_bytes); - Tagged::new(None, &value).serialize(s) + serde_bytes::Serialize::serialize(value, s) } } @@ -207,16 +205,7 @@ impl<'de> de::Deserialize<'de> for Address { } } -impl Cbor for Address { - fn unmarshal_cbor(bz: &[u8]) -> Result { - // Convert cbor encoded to bytes - Ok(from_slice(bz)?) - } - fn marshal_cbor(&self) -> Result, EncodingError> { - // encode bytes - Ok(to_vec(&self)?) - } -} +impl Cbor for Address {} impl From for EncodingError { fn from(err: Error) -> EncodingError { diff --git a/vm/address/tests/address_test.rs b/vm/address/tests/address_test.rs index aeb49d6516ea..e7c5eb478411 100644 --- a/vm/address/tests/address_test.rs +++ b/vm/address/tests/address_test.rs @@ -4,7 +4,7 @@ use address::{ checksum, validate_checksum, Address, Error, Network, Protocol, BLS_PUB_LEN, PAYLOAD_HASH_LEN, }; -use encoding::Cbor; +use encoding::{from_slice, Cbor}; #[test] fn bytes() { @@ -495,7 +495,7 @@ fn cbor_encoding() { let encoded = res.marshal_cbor().unwrap(); // assert intermediate value is correct assert_eq!(encoded.clone(), t.encoded); - let rec = Address::unmarshal_cbor(encoded.as_ref()).unwrap(); + let rec: Address = from_slice(&encoded).unwrap(); // assert decoded Address is equal to initial one assert_eq!(rec, res); } diff --git a/vm/message/Cargo.toml b/vm/message/Cargo.toml index 73600a785150..6260c05433d4 100644 --- a/vm/message/Cargo.toml +++ b/vm/message/Cargo.toml @@ -11,4 +11,4 @@ num-bigint = "0.2.3" encoding = {path = "../../encoding"} crypto = {path = "../../crypto"} derive_builder = "0.9" - +serde = {version = "1.0", features = ["derive"]} diff --git a/vm/message/src/lib.rs b/vm/message/src/lib.rs index 976130894ae9..e41d47d95708 100644 --- a/vm/message/src/lib.rs +++ b/vm/message/src/lib.rs @@ -10,7 +10,6 @@ pub use signed_message::*; pub use unsigned_message::*; use address::Address; -use num_bigint::BigUint; use vm::{MethodNum, MethodParams, TokenAmount}; pub trait Message { @@ -27,7 +26,8 @@ pub trait Message { /// params returns the encoded parameters for the method call fn params(&self) -> MethodParams; /// gas_price returns gas price for the message - fn gas_price(&self) -> BigUint; + // TODO: change u128 to BigUint if needed in future + fn gas_price(&self) -> u128; /// gas_limit returns the gas limit for the message - fn gas_limit(&self) -> BigUint; + fn gas_limit(&self) -> u128; } diff --git a/vm/message/src/signed_message.rs b/vm/message/src/signed_message.rs index e5bd2ff6cc32..1b2c009c2e32 100644 --- a/vm/message/src/signed_message.rs +++ b/vm/message/src/signed_message.rs @@ -6,11 +6,11 @@ use vm::{MethodNum, MethodParams, TokenAmount}; use address::Address; use crypto::{Error as CryptoError, Signature, Signer}; -use encoding::{Cbor, CodecProtocol, Error as EncodingError}; -use num_bigint::BigUint; +use encoding::Cbor; +use serde::{Deserialize, Serialize}; /// SignedMessage represents a wrapped message with signature bytes -#[derive(PartialEq, Clone, Debug)] +#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] pub struct SignedMessage { message: UnsignedMessage, signature: Signature, @@ -61,28 +61,14 @@ impl Message for SignedMessage { self.message.params() } /// gas_price returns gas price for the message - fn gas_price(&self) -> BigUint { + fn gas_price(&self) -> u128 { self.message.gas_price() } /// gas_limit returns the gas limit for the message - fn gas_limit(&self) -> BigUint { + fn gas_limit(&self) -> u128 { self.message.gas_limit() } } -impl Cbor for SignedMessage { - fn unmarshal_cbor(_bz: &[u8]) -> Result { - // TODO - Err(EncodingError::Unmarshalling { - description: "Not Implemented".to_string(), - protocol: CodecProtocol::Cbor, - }) - } - fn marshal_cbor(&self) -> Result, EncodingError> { - // TODO - Err(EncodingError::Marshalling { - description: format!("Not implemented, data: {:?}", self), - protocol: CodecProtocol::Cbor, - }) - } -} +// TODO modify signed message encoding format when needed +impl Cbor for SignedMessage {} diff --git a/vm/message/src/unsigned_message.rs b/vm/message/src/unsigned_message.rs index bd5975392c63..e155b99ea818 100644 --- a/vm/message/src/unsigned_message.rs +++ b/vm/message/src/unsigned_message.rs @@ -7,8 +7,8 @@ use crate::{MethodNum, MethodParams}; use address::Address; use derive_builder::Builder; -use encoding::{Cbor, CodecProtocol, Error as EncodingError}; -use num_bigint::BigUint; +use encoding::Cbor; +use serde::{Deserialize, Serialize}; /// Default Unsigned VM message type which includes all data needed for a state transition /// @@ -27,8 +27,8 @@ use num_bigint::BigUint; /// .value(TokenAmount::new(0)) // optional /// .method_num(MethodNum::default()) // optional /// .params(MethodParams::default()) // optional -/// .gas_limit(BigUint::default()) // optional -/// .gas_price(BigUint::default()) // optional +/// .gas_limit(0) // optional +/// .gas_price(0) // optional /// .build() /// .unwrap(); /// @@ -40,7 +40,7 @@ use num_bigint::BigUint; /// let msg = message_builder.build().unwrap(); /// assert_eq!(msg.sequence(), 1); /// ``` -#[derive(PartialEq, Clone, Debug, Builder)] +#[derive(PartialEq, Clone, Debug, Builder, Serialize, Deserialize)] #[builder(name = "MessageBuilder")] pub struct UnsignedMessage { from: Address, @@ -54,9 +54,9 @@ pub struct UnsignedMessage { #[builder(default)] params: MethodParams, #[builder(default)] - gas_price: BigUint, + gas_price: u128, #[builder(default)] - gas_limit: BigUint, + gas_limit: u128, } impl UnsignedMessage { @@ -91,28 +91,14 @@ impl Message for UnsignedMessage { self.params.clone() } /// gas_price returns gas price for the message - fn gas_price(&self) -> BigUint { - self.gas_price.clone() + fn gas_price(&self) -> u128 { + self.gas_price } /// gas_limit returns the gas limit for the message - fn gas_limit(&self) -> BigUint { - self.gas_limit.clone() + fn gas_limit(&self) -> u128 { + self.gas_limit } } -impl Cbor for UnsignedMessage { - fn unmarshal_cbor(_bz: &[u8]) -> Result { - // TODO - Err(EncodingError::Unmarshalling { - description: "Not Implemented".to_string(), - protocol: CodecProtocol::Cbor, - }) - } - fn marshal_cbor(&self) -> Result, EncodingError> { - // TODO - Err(EncodingError::Marshalling { - description: format!("Not implemented, data: {:?}", self), - protocol: CodecProtocol::Cbor, - }) - } -} +// TODO modify unsigned message encoding format when needed +impl Cbor for UnsignedMessage {} diff --git a/vm/message/tests/builder_test.rs b/vm/message/tests/builder_test.rs index 22d956696ccc..8ae92d365cb1 100644 --- a/vm/message/tests/builder_test.rs +++ b/vm/message/tests/builder_test.rs @@ -4,7 +4,6 @@ use address::Address; use crypto::{Signature, Signer}; use message::{Message, SignedMessage, UnsignedMessage}; -use num_bigint::BigUint; use std::error::Error; use vm::{MethodNum, MethodParams, TokenAmount}; @@ -29,8 +28,8 @@ fn unsigned_message_builder() { .value(TokenAmount::new(0)) .method_num(MethodNum::default()) .params(MethodParams::default()) - .gas_limit(BigUint::default()) - .gas_price(BigUint::default()) + .gas_limit(0) + .gas_price(0) .build() .unwrap(); assert_eq!(message.from(), from_addr.clone()); @@ -39,8 +38,8 @@ fn unsigned_message_builder() { assert_eq!(message.method_num(), MethodNum::default()); assert_eq!(message.params(), MethodParams::default()); assert_eq!(message.value(), TokenAmount::new(0)); - assert_eq!(message.gas_price(), BigUint::default()); - assert_eq!(message.gas_limit(), BigUint::default()); + assert_eq!(message.gas_price(), 0); + assert_eq!(message.gas_limit(), 0); let mut mb = UnsignedMessage::builder(); mb.to(to_addr.clone()); mb.from(from_addr.clone()); @@ -56,8 +55,6 @@ fn unsigned_message_builder() { } #[test] -// TODO remove should_panic once cbor encoding unsigned message complete -#[should_panic] fn generate_signed_message() { let unsigned_msg = UnsignedMessage::builder() .to(Address::new_id(1).unwrap()) diff --git a/vm/src/method.rs b/vm/src/method.rs index b6dc9dfbf6c8..fffcd11e0efe 100644 --- a/vm/src/method.rs +++ b/vm/src/method.rs @@ -1,11 +1,12 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0 -use encoding::{Cbor, Error as EncodingError}; +use encoding::{ser, to_vec, Error as EncodingError}; +use serde::{Deserialize, Serialize}; use std::ops::{Deref, DerefMut}; /// Method number indicator for calling actor methods -#[derive(Default, Clone, PartialEq, Debug)] +#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)] pub struct MethodNum(i32); // TODO: add constraints to this impl MethodNum { @@ -33,7 +34,7 @@ pub const METHOD_CRON: isize = 2; pub const METHOD_PLACEHOLDER: isize = 3; /// Serialized bytes to be used as individual parameters into actor methods -#[derive(Default, Clone, PartialEq, Debug)] +#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)] pub struct Serialized { bytes: Vec, } @@ -47,21 +48,17 @@ impl Deref for Serialized { impl Serialized { /// Constructor if data is encoded already - /// - /// ### Arguments - /// * `bytes` - vector of bytes to use as serialized data pub fn new(bytes: Vec) -> Self { Self { bytes } } + /// Contructor for encoding Cbor encodable structure - /// - /// ### Arguments - /// * `obj` - Cbor encodable type - pub fn serialize(obj: impl Cbor) -> Result { + pub fn serialize(obj: O) -> Result { Ok(Self { - bytes: obj.marshal_cbor()?, + bytes: to_vec(&obj)?, }) } + /// Returns serialized bytes pub fn bytes(&self) -> Vec { self.bytes.clone() @@ -69,7 +66,7 @@ impl Serialized { } /// Method parameters used in Actor execution -#[derive(Default, Clone, PartialEq, Debug)] +#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)] pub struct MethodParams { params: Vec, } diff --git a/vm/src/token.rs b/vm/src/token.rs index c690f52bcc4a..1df6ec640761 100644 --- a/vm/src/token.rs +++ b/vm/src/token.rs @@ -1,6 +1,7 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0 +use encoding::{de, ser, serde_bytes}; use num_bigint::BigUint; /// Wrapper around a big int variable to handle token specific functionality @@ -13,3 +14,24 @@ impl TokenAmount { TokenAmount(BigUint::from(val)) } } + +impl ser::Serialize for TokenAmount { + fn serialize(&self, s: S) -> Result + where + S: ser::Serializer, + { + let bz = self.0.to_bytes_be(); + let value = serde_bytes::Bytes::new(&bz); + serde_bytes::Serialize::serialize(value, s) + } +} + +impl<'de> de::Deserialize<'de> for TokenAmount { + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + let bz: &[u8] = serde_bytes::Deserialize::deserialize(deserializer)?; + Ok(TokenAmount(BigUint::from_bytes_be(bz))) + } +} diff --git a/vm/tests/params_test.rs b/vm/tests/params_test.rs index 8ba8a628d2a4..af2ff7894ddd 100644 --- a/vm/tests/params_test.rs +++ b/vm/tests/params_test.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use address::Address; -use encoding::Cbor; +use encoding::from_slice; use vm::{MethodNum, MethodParams, Serialized}; #[test] @@ -20,7 +20,7 @@ fn cbor_params() { let addr = Address::new_id(1).unwrap(); params.insert(0, Serialized::serialize(addr.clone()).unwrap()); let encoded_addr = params.remove(0); - assert_eq!(Address::unmarshal_cbor(&encoded_addr).unwrap(), addr); + assert_eq!(from_slice::
(&encoded_addr).unwrap(), addr); } #[test] From b786e80709f6bb1662ca75d9cc15a9879db4f3a8 Mon Sep 17 00:00:00 2001 From: austinabell Date: Mon, 13 Jan 2020 20:08:51 -0500 Subject: [PATCH 04/17] refactor all crates using serde to point to encoding package --- encoding/src/lib.rs | 3 +-- ipld/Cargo.toml | 5 ++--- ipld/cid/Cargo.toml | 6 ++---- ipld/cid/src/lib.rs | 5 +---- ipld/src/lib.rs | 4 ++-- node/Cargo.toml | 4 +--- node/ferret-libp2p/Cargo.toml | 3 +-- node/ferret-libp2p/src/config.rs | 2 +- node/src/cli/config.rs | 3 +-- node/utils/Cargo.toml | 2 -- node/utils/src/lib.rs | 5 ++--- vm/address/Cargo.toml | 3 --- vm/address/src/lib.rs | 6 +++--- 13 files changed, 17 insertions(+), 34 deletions(-) diff --git a/encoding/src/lib.rs b/encoding/src/lib.rs index fd276c3c4fbc..6579eea1f06a 100644 --- a/encoding/src/lib.rs +++ b/encoding/src/lib.rs @@ -7,8 +7,7 @@ mod hash; pub use serde::{de, ser}; pub use serde_bytes; -pub use serde_cbor::{from_reader, from_slice, to_vec, to_writer}; -// pub use serde_derive::*; +pub use serde_cbor::{from_reader, from_slice, tags, to_vec, to_writer}; pub use self::cbor::*; pub use self::errors::*; diff --git a/ipld/Cargo.toml b/ipld/Cargo.toml index 7211378cb164..22e0fa1294d2 100644 --- a/ipld/Cargo.toml +++ b/ipld/Cargo.toml @@ -5,6 +5,5 @@ authors = ["austinabell "] edition = "2018" [dependencies] -serde = "1.0" -serde_bytes = "0.11.3" -serde_cbor = {version = "0.11.0", features = ["tags"]} +encoding = {path = "../encoding"} +serde = {version = "1.0", features = ["derive"]} diff --git a/ipld/cid/Cargo.toml b/ipld/cid/Cargo.toml index e788d463bb9f..a3219442a304 100644 --- a/ipld/cid/Cargo.toml +++ b/ipld/cid/Cargo.toml @@ -9,7 +9,5 @@ dep_cid = {package = "cid", version = "0.3.1"} multihash = "0.8.0" multibase = "0.6.0" integer-encoding = "1.0.3" - -serde = "1.0" -serde_bytes = "0.11.3" -serde_cbor = {version = "0.11.0", features = ["tags"]} \ No newline at end of file +encoding = {path = "../../encoding"} +serde = {version = "1.0", features = ["derive"]} \ No newline at end of file diff --git a/ipld/cid/src/lib.rs b/ipld/cid/src/lib.rs index b4109ad8fa50..a17ea81a7c40 100644 --- a/ipld/cid/src/lib.rs +++ b/ipld/cid/src/lib.rs @@ -5,10 +5,7 @@ mod to_cid; pub use self::to_cid::ToCid; pub use dep_cid::{Cid as BaseCid, Codec, Error, Prefix, Version}; -use serde::de; -use serde::ser; -use serde_bytes; -use serde_cbor::tags::Tagged; +use encoding::{de, ser, serde_bytes, tags::Tagged}; use std::ops::{Deref, DerefMut}; const CBOR_TAG_CID: u64 = 42; diff --git a/ipld/src/lib.rs b/ipld/src/lib.rs index 47b03bcad956..db02dc6744d6 100644 --- a/ipld/src/lib.rs +++ b/ipld/src/lib.rs @@ -1,9 +1,9 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0 -use serde::de; +use encoding::de; +use encoding::tags::current_cbor_tag; use serde::Deserialize; -use serde_cbor::tags::current_cbor_tag; use std::collections::BTreeMap; use std::fmt; diff --git a/node/Cargo.toml b/node/Cargo.toml index fa981a25c31a..1f89468e4df2 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -9,14 +9,12 @@ network = { path = "network" } ferret-libp2p = { path = "ferret-libp2p"} utils = { path = "utils" } db = { path = "db" } - libp2p = { git = "https://github.com/SigP/rust-libp2p", rev = "776d13ef046358964c7d64cda3295a3a3cb24743" } tokio = "0.1.22" futures = "0.1.29" clap = "2.33.0" -serde = "1.0" log = "0.4.8" slog = "2.5.2" slog-async = "2.3.0" slog-term = "2.4.2" -serde_derive = "1.0" +serde = {version = "1.0", features = ["derive"]} \ No newline at end of file diff --git a/node/ferret-libp2p/Cargo.toml b/node/ferret-libp2p/Cargo.toml index 28b6287a6495..071228d2d5c1 100644 --- a/node/ferret-libp2p/Cargo.toml +++ b/node/ferret-libp2p/Cargo.toml @@ -11,5 +11,4 @@ tokio = "0.1.22" futures = "0.1.29" log = "0.4.8" slog = "2.5.2" -serde = "1.0" -serde_derive = "1.0" +serde = {version = "1.0", features = ["derive"]} diff --git a/node/ferret-libp2p/src/config.rs b/node/ferret-libp2p/src/config.rs index 97862efb749f..f767637cb496 100644 --- a/node/ferret-libp2p/src/config.rs +++ b/node/ferret-libp2p/src/config.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use libp2p::gossipsub::Topic; -use serde_derive::Deserialize; +use serde::Deserialize; #[derive(Debug, Deserialize)] #[serde(default)] diff --git a/node/src/cli/config.rs b/node/src/cli/config.rs index 76326eaa1416..e3b523aeef7e 100644 --- a/node/src/cli/config.rs +++ b/node/src/cli/config.rs @@ -1,8 +1,7 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0 -use serde_derive::Deserialize; - +use serde::Deserialize; use ferret_libp2p::config::Libp2pConfig; #[derive(Debug, Deserialize, Default)] diff --git a/node/utils/Cargo.toml b/node/utils/Cargo.toml index 0a8d8877daa7..437c073561c3 100644 --- a/node/utils/Cargo.toml +++ b/node/utils/Cargo.toml @@ -4,8 +4,6 @@ version = "0.1.0" authors = ["ChainSafe Systems "] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] dirs = "2.0.2" toml = "0.5.5" diff --git a/node/utils/src/lib.rs b/node/utils/src/lib.rs index cc0d275fb29c..b7d84c58a67c 100644 --- a/node/utils/src/lib.rs +++ b/node/utils/src/lib.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 use dirs::home_dir; -use serde; use std::fs::{create_dir_all, File}; use std::io::{prelude::*, Result}; use std::path::Path; @@ -47,8 +46,8 @@ pub fn get_home_dir() -> String { /// Converts a toml file represented as a string to `S` /// /// # Example -///``` -/// use serde_derive::Deserialize; +/// ``` +/// use serde::Deserialize; /// use utils::read_toml; /// /// #[derive(Deserialize)] diff --git a/vm/address/Cargo.toml b/vm/address/Cargo.toml index 583674aa778a..baab98dc336c 100644 --- a/vm/address/Cargo.toml +++ b/vm/address/Cargo.toml @@ -11,6 +11,3 @@ data-encoding = "2.1.2" data-encoding-macro = "0.1.7" leb128 = "0.2.1" encoding = {path = "../../encoding"} -serde = "1.0" -serde_bytes = "0.11.3" -serde_cbor = {version = "0.11.0", features = ["tags"]} \ No newline at end of file diff --git a/vm/address/src/lib.rs b/vm/address/src/lib.rs index 9c7522d91eb2..28b993c9774c 100644 --- a/vm/address/src/lib.rs +++ b/vm/address/src/lib.rs @@ -10,10 +10,10 @@ pub use self::protocol::Protocol; use data_encoding::Encoding; use data_encoding_macro::{internal_new_encoding, new_encoding}; -use encoding::{blake2b_variable, Cbor, CodecProtocol, Error as EncodingError}; +use encoding::{ + blake2b_variable, de, ser, serde_bytes, Cbor, CodecProtocol, Error as EncodingError, +}; use leb128; -use serde::{de, ser}; -use serde_bytes; use std::hash::Hash; /// defines the encoder for base32 encoding with the provided string with no padding From 89cfeac8c7fcda0c3819adfbd84d85107685c4fd Mon Sep 17 00:00:00 2001 From: austinabell Date: Mon, 13 Jan 2020 20:12:15 -0500 Subject: [PATCH 05/17] update author to CS --- ipld/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipld/Cargo.toml b/ipld/Cargo.toml index 22e0fa1294d2..2d9a23b54775 100644 --- a/ipld/Cargo.toml +++ b/ipld/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ferret_ipld" version = "0.1.0" -authors = ["austinabell "] +authors = ["ChainSafe Systems "] edition = "2018" [dependencies] From 94c521215700f0b9bef62cb387848f238cd80bcf Mon Sep 17 00:00:00 2001 From: austinabell Date: Mon, 13 Jan 2020 21:31:53 -0500 Subject: [PATCH 06/17] lint --- node/src/cli/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/src/cli/config.rs b/node/src/cli/config.rs index e3b523aeef7e..b74efcfadc78 100644 --- a/node/src/cli/config.rs +++ b/node/src/cli/config.rs @@ -1,8 +1,8 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0 -use serde::Deserialize; use ferret_libp2p::config::Libp2pConfig; +use serde::Deserialize; #[derive(Debug, Deserialize, Default)] #[serde(default)] From 3a26a50cc49f56faad86d787f2d741c520637930 Mon Sep 17 00:00:00 2001 From: austinabell Date: Tue, 14 Jan 2020 11:57:22 -0500 Subject: [PATCH 07/17] refactor from using Cid dependency and update multihash --- blockchain/blocks/Cargo.toml | 2 +- blockchain/blocks/src/block.rs | 10 +- blockchain/blocks/src/tipset.rs | 6 +- blockchain/chain/Cargo.toml | 2 +- blockchain/chain/src/store/tip_index.rs | 3 +- blockchain/sync_manager/src/bucket.rs | 2 +- blockchain/sync_manager/tests/manager_test.rs | 2 +- encoding/src/cbor.rs | 5 +- ipld/cid/Cargo.toml | 3 +- ipld/cid/src/codec.rs | 56 +++++ ipld/cid/src/error.rs | 70 ++++++ ipld/cid/src/lib.rs | 201 ++++++++++++++---- ipld/cid/src/to_cid.rs | 15 +- ipld/cid/src/version.rs | 41 ++++ 14 files changed, 345 insertions(+), 73 deletions(-) create mode 100644 ipld/cid/src/codec.rs create mode 100644 ipld/cid/src/error.rs create mode 100644 ipld/cid/src/version.rs diff --git a/blockchain/blocks/Cargo.toml b/blockchain/blocks/Cargo.toml index 70c137ab8245..d0d0f65b59c5 100644 --- a/blockchain/blocks/Cargo.toml +++ b/blockchain/blocks/Cargo.toml @@ -10,6 +10,6 @@ crypto = {path = "../../crypto"} message = {path = "../../vm/message"} clock = {path = "../../node/clock"} cid = {package = "ferret_cid", path = "../../ipld/cid"} -multihash = "0.8.0" +multihash = "0.9.3" derive_builder = "0.9" serde_cbor = "0.11.0" diff --git a/blockchain/blocks/src/block.rs b/blockchain/blocks/src/block.rs index a7abd99b9c28..1f219ed8789a 100644 --- a/blockchain/blocks/src/block.rs +++ b/blockchain/blocks/src/block.rs @@ -6,7 +6,7 @@ use super::ticket::Ticket; use super::TipSetKeys; use address::Address; -use cid::{Cid, Codec, Prefix, Version}; +use cid::Cid; use clock::ChainEpoch; use crypto::Signature; use derive_builder::Builder; @@ -138,13 +138,7 @@ impl BlockHeader { // Change DEFAULT_HASH_FUNCTION to utilize blake2b // // Currently content id for headers will be incomplete until encoding and supporting libraries are completed - let c = Prefix { - version: Version::V1, - codec: Codec::DagCBOR, - mh_type: DEFAULT_HASH_FUNCTION, - mh_len: 8, - }; - let new_cid = Cid::new_from_prefix(&c, &self.cached_bytes); + let new_cid = Cid::from_bytes_default(&self.cached_bytes).unwrap(); self.cached_cid = new_cid; self.cached_cid.clone() } diff --git a/blockchain/blocks/src/tipset.rs b/blockchain/blocks/src/tipset.rs index 95ff01f0a760..15ca9eeb030e 100644 --- a/blockchain/blocks/src/tipset.rs +++ b/blockchain/blocks/src/tipset.rs @@ -106,7 +106,7 @@ impl Tipset { // break ticket ties with the header CIDs, which are distinct sorted_headers.sort_by_key(|header| { let mut h = header.clone(); - (h.ticket.vrfproof.clone(), h.cid().hash.clone()) + (h.ticket.vrfproof.clone(), h.cid().to_bytes()) }); // TODO @@ -183,9 +183,7 @@ mod tests { const CACHED_BYTES: [u8; 1] = [0]; fn template_key(data: &[u8]) -> Cid { - let h = multihash::encode(multihash::Hash::SHA2256, data).unwrap(); - let cid = Cid::from_bytes_default(h); - return cid; + Cid::from_bytes_default(data).unwrap() } // key_setup returns a vec of 4 distinct CIDs diff --git a/blockchain/chain/Cargo.toml b/blockchain/chain/Cargo.toml index 020b701eae33..ae3e56f500cd 100644 --- a/blockchain/chain/Cargo.toml +++ b/blockchain/chain/Cargo.toml @@ -14,4 +14,4 @@ num-bigint = "0.2.3" [dev-dependencies] address = {path = "../../vm/address"} crypto = {path = "../../crypto"} -multihash = "0.8.0" \ No newline at end of file +multihash = "0.9.3" diff --git a/blockchain/chain/src/store/tip_index.rs b/blockchain/chain/src/store/tip_index.rs index 76ecc8bbb2fe..64a8e57a0cb7 100644 --- a/blockchain/chain/src/store/tip_index.rs +++ b/blockchain/chain/src/store/tip_index.rs @@ -110,8 +110,7 @@ mod tests { const CACHED_BYTES: [u8; 1] = [0]; fn template_key(data: &[u8]) -> Cid { - let h = multihash::encode(multihash::Hash::SHA2256, data).unwrap(); - Cid::from_bytes_default(&h) + Cid::from_bytes_default(data).unwrap() } // key_setup returns a vec of distinct CIDs diff --git a/blockchain/sync_manager/src/bucket.rs b/blockchain/sync_manager/src/bucket.rs index 9fd796955ed2..377cd8300109 100644 --- a/blockchain/sync_manager/src/bucket.rs +++ b/blockchain/sync_manager/src/bucket.rs @@ -78,7 +78,7 @@ mod tests { fn create_header(weight: u64, parent_bz: &[u8], cached_bytes: &[u8]) -> BlockHeader { let x = TipSetKeys { - cids: vec![Cid::from_bytes_default(parent_bz)], + cids: vec![Cid::from_bytes_default(parent_bz).unwrap()], }; BlockHeader::builder() .parents(x) diff --git a/blockchain/sync_manager/tests/manager_test.rs b/blockchain/sync_manager/tests/manager_test.rs index 1e2af75cdc96..a1a257ba037c 100644 --- a/blockchain/sync_manager/tests/manager_test.rs +++ b/blockchain/sync_manager/tests/manager_test.rs @@ -8,7 +8,7 @@ use sync_manager::SyncManager; fn create_header(weight: u64, parent_bz: &[u8], cached_bytes: &[u8]) -> BlockHeader { let x = TipSetKeys { - cids: vec![Cid::from_bytes_default(parent_bz)], + cids: vec![Cid::from_bytes_default(parent_bz).unwrap()], }; BlockHeader::builder() .parents(x) diff --git a/encoding/src/cbor.rs b/encoding/src/cbor.rs index c3eca8ed46e2..52683f6a7413 100644 --- a/encoding/src/cbor.rs +++ b/encoding/src/cbor.rs @@ -6,10 +6,7 @@ use crate::{ser, to_vec}; /// Implemented for types that are CBOR encodable pub trait Cbor: ser::Serialize { - fn marshal_cbor(&self) -> Result, Error> - where - Self: ser::Serialize, - { + fn marshal_cbor(&self) -> Result, Error> { Ok(to_vec(&self)?) } } diff --git a/ipld/cid/Cargo.toml b/ipld/cid/Cargo.toml index a3219442a304..fb40a2cd11e7 100644 --- a/ipld/cid/Cargo.toml +++ b/ipld/cid/Cargo.toml @@ -5,8 +5,7 @@ authors = ["ChainSafe Systems "] edition = "2018" [dependencies] -dep_cid = {package = "cid", version = "0.3.1"} -multihash = "0.8.0" +multihash = "0.9.3" multibase = "0.6.0" integer-encoding = "1.0.3" encoding = {path = "../../encoding"} diff --git a/ipld/cid/src/codec.rs b/ipld/cid/src/codec.rs new file mode 100644 index 000000000000..1823faf0fe02 --- /dev/null +++ b/ipld/cid/src/codec.rs @@ -0,0 +1,56 @@ +// Copyright 2020 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0 + +use crate::Error; + +macro_rules! build_codec_enum { + {$( $val:expr => $var:ident, )*} => { + #[derive(PartialEq, Eq, Clone, Copy, Debug)] + pub enum Codec { + $( $var, )* + } + + use Codec::*; + + impl Codec { + /// Convert a number to the matching codec + pub fn from(raw: u64) -> Result { + match raw { + $( $val => Ok($var), )* + _ => Err(Error::UnknownCodec), + } + } + } + + impl From for u64 { + /// Convert to the matching integer code + fn from(codec: Codec) -> u64 { + match codec { + $( $var => $val, )* + + } + } + } + } +} + +build_codec_enum! { + 0x55 => Raw, + 0x70 => DagProtobuf, + 0x71 => DagCBOR, + 0x78 => GitRaw, + 0x90 => EthereumBlock, + 0x91 => EthereumBlockList, + 0x92 => EthereumTxTrie, + 0x93 => EthereumTx, + 0x94 => EthereumTxReceiptTrie, + 0x95 => EthereumTxReceipt, + 0x96 => EthereumStateTrie, + 0x97 => EthereumAccountSnapshot, + 0x98 => EthereumStorageTrie, + 0xb0 => BitcoinBlock, + 0xb1 => BitcoinTx, + 0xc0 => ZcashBlock, + 0xc1 => ZcashTx, + 0x0129 => DagJSON, +} diff --git a/ipld/cid/src/error.rs b/ipld/cid/src/error.rs new file mode 100644 index 000000000000..b8319633bca0 --- /dev/null +++ b/ipld/cid/src/error.rs @@ -0,0 +1,70 @@ +// Copyright 2020 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0 + +use multibase; +use multihash; +use std::{error, fmt, io}; + +/// Error types +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub enum Error { + UnknownCodec, + InputTooShort, + ParsingError, + InvalidCidVersion, +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(error::Error::description(self)) + } +} + +impl error::Error for Error { + fn description(&self) -> &str { + use self::Error::*; + + match *self { + UnknownCodec => "Unknown codec", + InputTooShort => "Input too short", + ParsingError => "Failed to parse multihash", + InvalidCidVersion => "Unrecognized CID version", + } + } +} + +impl From for Error { + fn from(_: io::Error) -> Error { + Error::ParsingError + } +} + +impl From for Error { + fn from(_: multibase::Error) -> Error { + Error::ParsingError + } +} + +impl From for Error { + fn from(_: multihash::DecodeOwnedError) -> Error { + Error::ParsingError + } +} + +impl From for Error { + fn from(_: multihash::EncodeError) -> Error { + Error::ParsingError + } +} + +impl From for Error { + fn from(_: multihash::DecodeError) -> Error { + Error::ParsingError + } +} + +impl From for fmt::Error { + fn from(_: Error) -> fmt::Error { + fmt::Error {} + } +} diff --git a/ipld/cid/src/lib.rs b/ipld/cid/src/lib.rs index a17ea81a7c40..730677b4a074 100644 --- a/ipld/cid/src/lib.rs +++ b/ipld/cid/src/lib.rs @@ -1,45 +1,47 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0 +mod codec; +mod error; mod to_cid; +mod version; +pub use self::codec::Codec; +pub use self::error::Error; pub use self::to_cid::ToCid; -pub use dep_cid::{Cid as BaseCid, Codec, Error, Prefix, Version}; -use encoding::{de, ser, serde_bytes, tags::Tagged}; -use std::ops::{Deref, DerefMut}; +pub use self::version::Version; +use encoding::{de, ser, serde_bytes, tags::Tagged, Cbor}; +use integer_encoding::{VarIntReader, VarIntWriter}; +use multihash::Multihash; +use std::fmt; +use std::io::Cursor; const CBOR_TAG_CID: u64 = 42; -/// Representation of an IPLD Cid -#[derive(PartialEq, Eq, Clone, Debug, Hash)] -pub struct Cid { - cid: BaseCid, +/// Prefix represents all metadata of a CID, without the actual content. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct Prefix { + pub version: Version, + pub codec: Codec, + pub mh_type: multihash::Hash, + pub mh_len: usize, } -impl From for Cid { - fn from(cid: BaseCid) -> Self { - Self { cid } - } +/// Representation of a IPLD CID. +#[derive(Eq, Clone, Debug)] +pub struct Cid { + pub version: Version, + pub codec: Codec, + pub hash: Multihash, } impl Default for Cid { fn default() -> Self { - Self { - cid: BaseCid::new(Codec::Raw, Version::V0, &[]), - } - } -} - -impl Deref for Cid { - type Target = BaseCid; - fn deref(&self) -> &Self::Target { - &self.cid - } -} - -impl DerefMut for Cid { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.cid + Self::new( + Codec::Raw, + Version::V0, + multihash::encode(multihash::Hash::Blake2b512, &[]).unwrap(), + ) } } @@ -48,7 +50,7 @@ impl ser::Serialize for Cid { where S: ser::Serializer, { - let cid_bytes = self.cid.to_bytes(); + let cid_bytes = self.to_bytes(); let value = serde_bytes::Bytes::new(&cid_bytes); Tagged::new(Some(CBOR_TAG_CID), &value).serialize(s) } @@ -73,31 +75,150 @@ impl<'de> de::Deserialize<'de> for Cid { } impl Cid { - /// Cid constructor - pub fn new(cid: BaseCid) -> Self { - Self { cid } + /// Create a new CID. + fn new(codec: Codec, version: Version, hash: Multihash) -> Cid { + Cid { + version, + codec, + hash, + } } /// Constructs a cid with bytes using default version and codec - pub fn from_bytes_default>(bz: B) -> Self { - Self { - cid: BaseCid::new(Codec::DagCBOR, Version::V1, bz.as_ref()), - } + pub fn from_bytes_default(bz: &[u8]) -> Result { + let prefix = Prefix { + version: Version::V1, + codec: Codec::DagCBOR, + mh_type: multihash::Hash::Blake2b512, + mh_len: 64, // TODO verify cid hash length and type + }; + Ok(Self::new_from_prefix(&prefix, bz)?) + } + + /// Constructs a cid with a CBOR encodable structure + pub fn from_cbor_default(bz: B) -> Result { + Ok(Self::from_bytes_default( + &bz.marshal_cbor().map_err(|_| Error::ParsingError)?, + )?) } /// Create a new CID from raw data (binary or multibase encoded string) - pub fn from_raw(data: T) -> Result { + pub fn from_raw_cid(data: T) -> Result { data.to_cid() } /// Create a new CID from a prefix and some data. - pub fn new_from_prefix(prefix: &Prefix, data: &[u8]) -> Cid { - let mut hash = multihash::encode(prefix.mh_type.to_owned(), data).unwrap(); - hash.truncate(prefix.mh_len + 2); - Cid::from(BaseCid { + pub fn new_from_prefix(prefix: &Prefix, data: &[u8]) -> Result { + let hash = multihash::encode(prefix.mh_type.to_owned(), data)?; + Ok(Cid { version: prefix.version, codec: prefix.codec.to_owned(), hash, }) } + + fn to_string_v0(&self) -> String { + use multibase::{encode, Base}; + + let mut string = encode(Base::Base58btc, self.hash.clone()); + + // Drop the first character as v0 does not know + // about multibase + string.remove(0); + + string + } + + fn to_string_v1(&self) -> String { + use multibase::{encode, Base}; + + encode(Base::Base58btc, self.to_bytes().as_slice()) + } + + fn to_bytes_v0(&self) -> Vec { + self.hash.clone().into_bytes() + } + + fn to_bytes_v1(&self) -> Vec { + let mut res = Vec::with_capacity(16); + res.write_varint(u64::from(self.version)).unwrap(); + res.write_varint(u64::from(self.codec)).unwrap(); + res.extend_from_slice(self.hash.as_bytes()); + + res + } + + pub fn to_bytes(&self) -> Vec { + match self.version { + Version::V0 => self.to_bytes_v0(), + Version::V1 => self.to_bytes_v1(), + } + } + + pub fn prefix(&self) -> Prefix { + Prefix { + version: self.version, + codec: self.codec.to_owned(), + mh_type: self.hash.algorithm(), + mh_len: self.hash.as_bytes().len(), + } + } +} + +impl std::hash::Hash for Cid { + fn hash(&self, state: &mut H) { + self.to_bytes().hash(state); + } +} + +impl PartialEq for Cid { + fn eq(&self, other: &Self) -> bool { + self.to_bytes() == other.to_bytes() + } +} + +impl fmt::Display for Cid { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let encoded = match self.version { + Version::V0 => self.to_string_v0(), + Version::V1 => self.to_string_v1(), + }; + write!(f, "{}", encoded) + } +} + +impl Prefix { + pub fn new_from_bytes(data: &[u8]) -> Result { + let mut cur = Cursor::new(data); + + let raw_version = cur.read_varint()?; + let raw_codec = cur.read_varint()?; + let raw_mh_type: u64 = cur.read_varint()?; + + let version = Version::from(raw_version)?; + let codec = Codec::from(raw_codec)?; + + let mh_type = multihash::Hash::from_code(raw_mh_type as u16).ok_or(Error::ParsingError)?; + + let mh_len = cur.read_varint()?; + + Ok(Prefix { + version, + codec, + mh_type, + mh_len, + }) + } + + pub fn as_bytes(&self) -> Vec { + let mut res = Vec::with_capacity(4); + + // io can't fail on Vec + res.write_varint(u64::from(self.version)).unwrap(); + res.write_varint(u64::from(self.codec)).unwrap(); + res.write_varint(self.mh_type.code() as u64).unwrap(); + res.write_varint(self.mh_len as u64).unwrap(); + + res + } } diff --git a/ipld/cid/src/to_cid.rs b/ipld/cid/src/to_cid.rs index 8bc1ce981325..4caab3eb5a75 100644 --- a/ipld/cid/src/to_cid.rs +++ b/ipld/cid/src/to_cid.rs @@ -1,7 +1,7 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0 -use crate::{BaseCid, Cid, Codec, Error, Version}; +use crate::{Cid, Codec, Error, Version}; use integer_encoding::VarIntReader; use multibase; use multihash; @@ -81,13 +81,9 @@ impl ToCid for [u8] { fn to_cid(&self) -> Result { if Version::is_v0_binary(self) { // Verify that hash can be decoded, this is very cheap - multihash::decode(self)?; + let hash = multihash::Multihash::from_bytes(self.to_vec())?; - Ok(Cid::from(BaseCid::new( - Codec::DagProtobuf, - Version::V0, - self, - ))) + Ok(Cid::new(Codec::DagProtobuf, Version::V0, hash)) } else { let mut cur = Cursor::new(self); let raw_version = cur.read_varint()?; @@ -99,9 +95,10 @@ impl ToCid for [u8] { let hash = &self[cur.position() as usize..]; // Verify that hash can be decoded, this is very cheap - multihash::decode(hash)?; + // TODO verify this (was previously using all bytes) + let hash = multihash::Multihash::from_bytes(hash.to_vec())?; - Ok(Cid::from(BaseCid::new(codec, version, hash))) + Ok(Cid::new(codec, version, hash)) } } } diff --git a/ipld/cid/src/version.rs b/ipld/cid/src/version.rs new file mode 100644 index 000000000000..65c8d9fee8d6 --- /dev/null +++ b/ipld/cid/src/version.rs @@ -0,0 +1,41 @@ +// Copyright 2020 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0 + +use crate::Error; + +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub enum Version { + V0, + V1, +} + +use Version::*; + +impl Version { + pub fn from(raw: u64) -> Result { + match raw { + 0 => Ok(V0), + 1 => Ok(V1), + _ => Err(Error::InvalidCidVersion), + } + } + + pub fn is_v0_str(data: &str) -> bool { + // v0 is a base58btc encoded sha hash, so it has + // fixed length and always begins with "Qm" + data.len() == 46 && data.starts_with("Qm") + } + + pub fn is_v0_binary(data: &[u8]) -> bool { + data.len() == 34 && data.starts_with(&[0x12, 0x20]) + } +} + +impl From for u64 { + fn from(ver: Version) -> u64 { + match ver { + V0 => 0, + V1 => 1, + } + } +} From 0b94436ee264a7cabef1efa6b85b44bbafc258dc Mon Sep 17 00:00:00 2001 From: austinabell Date: Tue, 14 Jan 2020 13:47:58 -0500 Subject: [PATCH 08/17] add basic ipld test --- ipld/Cargo.toml | 4 ++++ ipld/src/lib.rs | 2 +- ipld/tests/ipld_test.rs | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 ipld/tests/ipld_test.rs diff --git a/ipld/Cargo.toml b/ipld/Cargo.toml index 2d9a23b54775..489a7004b601 100644 --- a/ipld/Cargo.toml +++ b/ipld/Cargo.toml @@ -7,3 +7,7 @@ edition = "2018" [dependencies] encoding = {path = "../encoding"} serde = {version = "1.0", features = ["derive"]} + +[dev-dependencies] +cid = {package = "ferret_cid", path = "../ipld/cid"} +encoding = {path = "../encoding"} diff --git a/ipld/src/lib.rs b/ipld/src/lib.rs index db02dc6744d6..8ad822604174 100644 --- a/ipld/src/lib.rs +++ b/ipld/src/lib.rs @@ -7,7 +7,7 @@ use serde::Deserialize; use std::collections::BTreeMap; use std::fmt; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum Ipld { Null, Bool(bool), diff --git a/ipld/tests/ipld_test.rs b/ipld/tests/ipld_test.rs new file mode 100644 index 000000000000..16b0b1dbf49e --- /dev/null +++ b/ipld/tests/ipld_test.rs @@ -0,0 +1,37 @@ +// Copyright 2020 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0 + +use cid::Cid; +use encoding::{from_slice, to_vec}; +use ferret_ipld::Ipld; +use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; + +#[derive(Serialize, Deserialize, Clone)] +struct TestStruct { + name: String, + details: Cid, +} + +#[test] +fn encode_new_type() { + let details = Cid::from_bytes_default(&[1, 2, 3]).unwrap(); + let name = "Test".to_string(); + let t_struct = TestStruct { + name: name.clone(), + details: details.clone(), + }; + let struct_encoded = to_vec(&t_struct).unwrap(); + + // Test to make sure struct can be encoded and decoded without IPLD + let struct_decoded: TestStruct = from_slice(&struct_encoded).unwrap(); + assert_eq!(&struct_decoded.name, &name); + assert_eq!(&struct_decoded.details, &details.clone()); + + // Test ipld decoding + let ipld_decoded: Ipld = from_slice(&struct_encoded).unwrap(); + let mut e_map = BTreeMap::::new(); + e_map.insert("details".to_string(), Ipld::Link(details.to_bytes())); + e_map.insert("name".to_string(), Ipld::String(name)); + assert_eq!(&ipld_decoded, &Ipld::Map(e_map)); +} From c057da818206f94132bcef09ef4644727aa7afbf Mon Sep 17 00:00:00 2001 From: austinabell Date: Tue, 14 Jan 2020 13:55:47 -0500 Subject: [PATCH 09/17] port existing cid tests --- ipld/cid/src/lib.rs | 2 +- ipld/cid/tests/base_cid_tests.rs | 103 +++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 ipld/cid/tests/base_cid_tests.rs diff --git a/ipld/cid/src/lib.rs b/ipld/cid/src/lib.rs index 730677b4a074..7cce95df3349 100644 --- a/ipld/cid/src/lib.rs +++ b/ipld/cid/src/lib.rs @@ -76,7 +76,7 @@ impl<'de> de::Deserialize<'de> for Cid { impl Cid { /// Create a new CID. - fn new(codec: Codec, version: Version, hash: Multihash) -> Cid { + pub fn new(codec: Codec, version: Version, hash: Multihash) -> Cid { Cid { version, codec, diff --git a/ipld/cid/tests/base_cid_tests.rs b/ipld/cid/tests/base_cid_tests.rs new file mode 100644 index 000000000000..09a5366e64cd --- /dev/null +++ b/ipld/cid/tests/base_cid_tests.rs @@ -0,0 +1,103 @@ +// Copyright 2020 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0 + +use ferret_cid::{Cid, Codec, Error, Prefix, Version}; +use std::collections::HashMap; + +#[test] +fn basic_marshalling() { + let h = multihash::encode(multihash::Hash::SHA2256, b"beep boop").unwrap(); + + let cid = Cid::new(Codec::DagProtobuf, Version::V1, h); + + let data = cid.to_bytes(); + let out = Cid::from_raw_cid(data).unwrap(); + + assert_eq!(cid, out); + + let s = cid.to_string(); + let out2 = Cid::from_raw_cid(&s[..]).unwrap(); + + assert_eq!(cid, out2); +} + +#[test] +fn empty_string() { + assert_eq!(Cid::from_raw_cid(""), Err(Error::InputTooShort)); +} + +#[test] +fn v0_handling() { + let old = "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n"; + let cid = Cid::from_raw_cid(old).unwrap(); + + assert_eq!(cid.version, Version::V0); + assert_eq!(cid.to_string(), old); +} + +#[test] +fn from_str() { + let cid: Cid = "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n" + .parse() + .unwrap(); + assert_eq!(cid.version, Version::V0); + + let bad = "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zIII".parse::(); + assert_eq!(bad, Err(Error::ParsingError)); +} + +#[test] +fn v0_error() { + let bad = "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zIII"; + assert_eq!(Cid::from_raw_cid(bad), Err(Error::ParsingError)); +} + +#[test] +fn prefix_roundtrip() { + let data = b"awesome test content"; + let h = multihash::encode(multihash::Hash::SHA2256, data).unwrap(); + + let cid = Cid::new(Codec::DagProtobuf, Version::V1, h); + let prefix = cid.prefix(); + + let cid2 = Cid::new_from_prefix(&prefix, data).unwrap(); + + assert_eq!(cid, cid2); + + let prefix_bytes = prefix.as_bytes(); + let prefix2 = Prefix::new_from_bytes(&prefix_bytes).unwrap(); + + assert_eq!(prefix, prefix2); +} + +#[test] +fn from() { + let the_hash = "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n"; + + let cases = vec![ + format!("/ipfs/{:}", &the_hash), + format!("https://ipfs.io/ipfs/{:}", &the_hash), + format!("http://localhost:8080/ipfs/{:}", &the_hash), + ]; + + for case in cases { + let cid = Cid::from_raw_cid(case).unwrap(); + assert_eq!(cid.version, Version::V0); + assert_eq!(cid.to_string(), the_hash); + } +} + +#[test] +fn test_hash() { + let data: Vec = vec![1, 2, 3]; + let prefix = Prefix { + version: Version::V0, + codec: Codec::DagProtobuf, + mh_type: multihash::Hash::SHA2256, + mh_len: 32, + }; + let mut map = HashMap::new(); + let cid = Cid::new_from_prefix(&prefix, &data).unwrap(); + map.insert(cid.clone(), data.clone()); + assert_eq!(&data, map.get(&cid).unwrap()); +} From 56000984f2f8db204ac899d16354a3d686cc24e3 Mon Sep 17 00:00:00 2001 From: austinabell Date: Tue, 14 Jan 2020 14:21:45 -0500 Subject: [PATCH 10/17] Add default tests --- ipld/cid/tests/base_cid_tests.rs | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/ipld/cid/tests/base_cid_tests.rs b/ipld/cid/tests/base_cid_tests.rs index 09a5366e64cd..8c1607c6728f 100644 --- a/ipld/cid/tests/base_cid_tests.rs +++ b/ipld/cid/tests/base_cid_tests.rs @@ -1,7 +1,11 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0 +use encoding::Cbor; use ferret_cid::{Cid, Codec, Error, Prefix, Version}; +use multihash; +use multihash::Hash::Blake2b512; +use serde::Serialize; use std::collections::HashMap; #[test] @@ -101,3 +105,35 @@ fn test_hash() { map.insert(cid.clone(), data.clone()); assert_eq!(&data, map.get(&cid).unwrap()); } + +#[test] +fn test_default() { + let data: Vec = vec![1, 2, 3]; + + let cid = Cid::from_bytes_default(&data).unwrap(); + + let prefix = cid.prefix(); + assert_eq!(prefix.version, Version::V1); + assert_eq!(prefix.codec, Codec::DagCBOR); + assert_eq!(prefix.mh_type, Blake2b512); + assert_eq!( + prefix.mh_len, + // 4 is Blake2b512 code length (3) + 1, change if default changes + (Blake2b512.size() + 4) as usize + ); +} + +#[derive(Serialize, Copy, Clone)] +struct TestCborStruct { + name: &'static str, +} +impl Cbor for TestCborStruct {} + +#[test] +fn test_cbor_to_cid() { + let obj = TestCborStruct { name: "test" }; + + let enc = Cid::from_cbor_default(obj).unwrap(); + let bz_enc = Cid::from_bytes_default(&obj.marshal_cbor().unwrap()).unwrap(); + assert_eq!(enc, bz_enc); +} From c50d545285daffd5cc7287182a22dc5dc0e5756e Mon Sep 17 00:00:00 2001 From: austinabell Date: Tue, 14 Jan 2020 20:37:56 -0500 Subject: [PATCH 11/17] consistent toml spacing for affected files --- blockchain/blocks/Cargo.toml | 10 +++++----- blockchain/chain/Cargo.toml | 12 ++++++------ blockchain/sync_manager/Cargo.toml | 6 +++--- encoding/Cargo.toml | 4 ++-- ipld/Cargo.toml | 8 ++++---- ipld/cid/Cargo.toml | 4 ++-- node/Cargo.toml | 4 ++-- vm/actor/Cargo.toml | 14 +++++++------- vm/address/Cargo.toml | 2 +- vm/message/Cargo.toml | 10 +++++----- 10 files changed, 37 insertions(+), 37 deletions(-) diff --git a/blockchain/blocks/Cargo.toml b/blockchain/blocks/Cargo.toml index d0d0f65b59c5..09494f89b96e 100644 --- a/blockchain/blocks/Cargo.toml +++ b/blockchain/blocks/Cargo.toml @@ -5,11 +5,11 @@ authors = ["ChainSafe Systems "] edition = "2018" [dependencies] -address = {path = "../../vm/address"} -crypto = {path = "../../crypto"} -message = {path = "../../vm/message"} -clock = {path = "../../node/clock"} -cid = {package = "ferret_cid", path = "../../ipld/cid"} +address = { path = "../../vm/address" } +crypto = { path = "../../crypto" } +message = { path = "../../vm/message" } +clock = { path = "../../node/clock" } +cid = { package = "ferret_cid", path = "../../ipld/cid" } multihash = "0.9.3" derive_builder = "0.9" serde_cbor = "0.11.0" diff --git a/blockchain/chain/Cargo.toml b/blockchain/chain/Cargo.toml index ae3e56f500cd..ada47e0299f8 100644 --- a/blockchain/chain/Cargo.toml +++ b/blockchain/chain/Cargo.toml @@ -5,13 +5,13 @@ authors = ["ChainSafe Systems "] edition = "2018" [dependencies] -blocks = {path = "../blocks"} -network = {path = "../../node/network"} -cid = {package = "ferret_cid", path = "../../ipld/cid"} -clock = {path = "../../node/clock"} +blocks = { path = "../blocks" } +network = { path = "../../node/network" } +cid = { package = "ferret_cid", path = "../../ipld/cid" } +clock = { path = "../../node/clock" } num-bigint = "0.2.3" [dev-dependencies] -address = {path = "../../vm/address"} -crypto = {path = "../../crypto"} +address = { path = "../../vm/address" } +crypto = { path = "../../crypto" } multihash = "0.9.3" diff --git a/blockchain/sync_manager/Cargo.toml b/blockchain/sync_manager/Cargo.toml index f80db6abbce5..effdf9597128 100644 --- a/blockchain/sync_manager/Cargo.toml +++ b/blockchain/sync_manager/Cargo.toml @@ -5,8 +5,8 @@ authors = ["ChainSafe Systems "] edition = "2018" [dependencies] -address = {path = "../../vm/address"} -blocks = {path = "../blocks"} +address = { path = "../../vm/address" } +blocks = { path = "../blocks" } [dev-dependencies] -cid = {package = "ferret_cid", path = "../../ipld/cid"} +cid = { package = "ferret_cid", path = "../../ipld/cid" } diff --git a/encoding/Cargo.toml b/encoding/Cargo.toml index 2b2e214b3e22..1ba79802456e 100644 --- a/encoding/Cargo.toml +++ b/encoding/Cargo.toml @@ -6,6 +6,6 @@ edition = "2018" [dependencies] blake2b_simd = "0.5.9" -serde = {version = "1.0", features = ["derive"]} +serde = { version = "1.0", features = ["derive"] } serde_bytes = "0.11.3" -serde_cbor = {version = "0.11.0", features = ["tags"]} +serde_cbor = { version = "0.11.0", features = ["tags"] } diff --git a/ipld/Cargo.toml b/ipld/Cargo.toml index 489a7004b601..82c7b6044eb3 100644 --- a/ipld/Cargo.toml +++ b/ipld/Cargo.toml @@ -5,9 +5,9 @@ authors = ["ChainSafe Systems "] edition = "2018" [dependencies] -encoding = {path = "../encoding"} -serde = {version = "1.0", features = ["derive"]} +encoding = { path = "../encoding" } +serde = { version = "1.0", features = ["derive"] } [dev-dependencies] -cid = {package = "ferret_cid", path = "../ipld/cid"} -encoding = {path = "../encoding"} +cid = { package = "ferret_cid", path = "../ipld/cid" } +encoding = { path = "../encoding" } diff --git a/ipld/cid/Cargo.toml b/ipld/cid/Cargo.toml index fb40a2cd11e7..9f13ae95574a 100644 --- a/ipld/cid/Cargo.toml +++ b/ipld/cid/Cargo.toml @@ -8,5 +8,5 @@ edition = "2018" multihash = "0.9.3" multibase = "0.6.0" integer-encoding = "1.0.3" -encoding = {path = "../../encoding"} -serde = {version = "1.0", features = ["derive"]} \ No newline at end of file +encoding = { path = "../../encoding" } +serde = { version = "1.0", features = ["derive"] } diff --git a/node/Cargo.toml b/node/Cargo.toml index 1f89468e4df2..fc9bd9f5be91 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] network = { path = "network" } -ferret-libp2p = { path = "ferret-libp2p"} +ferret-libp2p = { path = "ferret-libp2p" } utils = { path = "utils" } db = { path = "db" } libp2p = { git = "https://github.com/SigP/rust-libp2p", rev = "776d13ef046358964c7d64cda3295a3a3cb24743" } @@ -17,4 +17,4 @@ log = "0.4.8" slog = "2.5.2" slog-async = "2.3.0" slog-term = "2.4.2" -serde = {version = "1.0", features = ["derive"]} \ No newline at end of file +serde = { version = "1.0", features = ["derive"] } diff --git a/vm/actor/Cargo.toml b/vm/actor/Cargo.toml index eaa922ca35df..f347519f17d0 100644 --- a/vm/actor/Cargo.toml +++ b/vm/actor/Cargo.toml @@ -5,13 +5,13 @@ authors = ["ChainSafe Systems "] edition = "2018" [dependencies] -vm = {path = "../../vm"} -address = {path = "../address"} -runtime = {path = "../runtime"} +vm = { path = "../../vm" } +address = { path = "../address" } +runtime = { path = "../runtime" } num-bigint = "0.2.3" -encoding = {path = "../../encoding"} +encoding = { path = "../../encoding" } num-traits = "0.2" num-derive = "0.2" -clock = {path = "../../node/clock"} -cid = {package = "ferret_cid", path = "../../ipld/cid"} -serde = {version = "1.0", features = ["derive"]} +clock = { path = "../../node/clock" } +cid = { package = "ferret_cid", path = "../../ipld/cid" } +serde = { version = "1.0", features = ["derive"] } diff --git a/vm/address/Cargo.toml b/vm/address/Cargo.toml index baab98dc336c..c959d2a1630a 100644 --- a/vm/address/Cargo.toml +++ b/vm/address/Cargo.toml @@ -10,4 +10,4 @@ num-derive = "0.2" data-encoding = "2.1.2" data-encoding-macro = "0.1.7" leb128 = "0.2.1" -encoding = {path = "../../encoding"} +encoding = { path = "../../encoding" } diff --git a/vm/message/Cargo.toml b/vm/message/Cargo.toml index 6260c05433d4..74e7e8e40684 100644 --- a/vm/message/Cargo.toml +++ b/vm/message/Cargo.toml @@ -5,10 +5,10 @@ authors = ["ChainSafe Systems "] edition = "2018" [dependencies] -vm = {path = "../../vm"} -address = {path = "../address"} +vm = { path = "../../vm" } +address = { path = "../address" } num-bigint = "0.2.3" -encoding = {path = "../../encoding"} -crypto = {path = "../../crypto"} +encoding = { path = "../../encoding" } +crypto = { path = "../../crypto" } derive_builder = "0.9" -serde = {version = "1.0", features = ["derive"]} +serde = { version = "1.0", features = ["derive"] } From e2f6cf2845f79ad92169766025879f0978642bb2 Mon Sep 17 00:00:00 2001 From: austinabell Date: Wed, 15 Jan 2020 12:46:00 -0500 Subject: [PATCH 12/17] switch gas values back to serializable bigints --- vm/message/Cargo.toml | 2 +- vm/message/src/lib.rs | 6 +++--- vm/message/src/signed_message.rs | 6 +++--- vm/message/src/unsigned_message.rs | 17 +++++++++-------- vm/message/tests/builder_test.rs | 9 +++++---- 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/vm/message/Cargo.toml b/vm/message/Cargo.toml index 74e7e8e40684..b492f6f622fa 100644 --- a/vm/message/Cargo.toml +++ b/vm/message/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [dependencies] vm = { path = "../../vm" } address = { path = "../address" } -num-bigint = "0.2.3" +num-bigint = { version = "0.2.3", features = ["serde"] } encoding = { path = "../../encoding" } crypto = { path = "../../crypto" } derive_builder = "0.9" diff --git a/vm/message/src/lib.rs b/vm/message/src/lib.rs index e41d47d95708..976130894ae9 100644 --- a/vm/message/src/lib.rs +++ b/vm/message/src/lib.rs @@ -10,6 +10,7 @@ pub use signed_message::*; pub use unsigned_message::*; use address::Address; +use num_bigint::BigUint; use vm::{MethodNum, MethodParams, TokenAmount}; pub trait Message { @@ -26,8 +27,7 @@ pub trait Message { /// params returns the encoded parameters for the method call fn params(&self) -> MethodParams; /// gas_price returns gas price for the message - // TODO: change u128 to BigUint if needed in future - fn gas_price(&self) -> u128; + fn gas_price(&self) -> BigUint; /// gas_limit returns the gas limit for the message - fn gas_limit(&self) -> u128; + fn gas_limit(&self) -> BigUint; } diff --git a/vm/message/src/signed_message.rs b/vm/message/src/signed_message.rs index 1b2c009c2e32..9fd5195aad8a 100644 --- a/vm/message/src/signed_message.rs +++ b/vm/message/src/signed_message.rs @@ -3,7 +3,7 @@ use super::{Message, UnsignedMessage}; use vm::{MethodNum, MethodParams, TokenAmount}; - +use num_bigint::BigUint; use address::Address; use crypto::{Error as CryptoError, Signature, Signer}; use encoding::Cbor; @@ -61,11 +61,11 @@ impl Message for SignedMessage { self.message.params() } /// gas_price returns gas price for the message - fn gas_price(&self) -> u128 { + fn gas_price(&self) -> BigUint { self.message.gas_price() } /// gas_limit returns the gas limit for the message - fn gas_limit(&self) -> u128 { + fn gas_limit(&self) -> BigUint { self.message.gas_limit() } } diff --git a/vm/message/src/unsigned_message.rs b/vm/message/src/unsigned_message.rs index e155b99ea818..9ea09da1e0fd 100644 --- a/vm/message/src/unsigned_message.rs +++ b/vm/message/src/unsigned_message.rs @@ -8,6 +8,7 @@ use crate::{MethodNum, MethodParams}; use address::Address; use derive_builder::Builder; use encoding::Cbor; +use num_bigint::BigUint; use serde::{Deserialize, Serialize}; /// Default Unsigned VM message type which includes all data needed for a state transition @@ -27,8 +28,8 @@ use serde::{Deserialize, Serialize}; /// .value(TokenAmount::new(0)) // optional /// .method_num(MethodNum::default()) // optional /// .params(MethodParams::default()) // optional -/// .gas_limit(0) // optional -/// .gas_price(0) // optional +/// .gas_limit(BigUint::default()) // optional +/// .gas_price(BigUint::default()) // optional /// .build() /// .unwrap(); /// @@ -54,9 +55,9 @@ pub struct UnsignedMessage { #[builder(default)] params: MethodParams, #[builder(default)] - gas_price: u128, + gas_price: BigUint, #[builder(default)] - gas_limit: u128, + gas_limit: BigUint, } impl UnsignedMessage { @@ -91,12 +92,12 @@ impl Message for UnsignedMessage { self.params.clone() } /// gas_price returns gas price for the message - fn gas_price(&self) -> u128 { - self.gas_price + fn gas_price(&self) -> BigUint { + self.gas_price.clone() } /// gas_limit returns the gas limit for the message - fn gas_limit(&self) -> u128 { - self.gas_limit + fn gas_limit(&self) -> BigUint { + self.gas_limit.clone() } } diff --git a/vm/message/tests/builder_test.rs b/vm/message/tests/builder_test.rs index 8ae92d365cb1..34f4eb700fa6 100644 --- a/vm/message/tests/builder_test.rs +++ b/vm/message/tests/builder_test.rs @@ -4,6 +4,7 @@ use address::Address; use crypto::{Signature, Signer}; use message::{Message, SignedMessage, UnsignedMessage}; +use num_bigint::BigUint; use std::error::Error; use vm::{MethodNum, MethodParams, TokenAmount}; @@ -28,8 +29,8 @@ fn unsigned_message_builder() { .value(TokenAmount::new(0)) .method_num(MethodNum::default()) .params(MethodParams::default()) - .gas_limit(0) - .gas_price(0) + .gas_limit(BigUint::default()) + .gas_price(BigUint::default()) .build() .unwrap(); assert_eq!(message.from(), from_addr.clone()); @@ -38,8 +39,8 @@ fn unsigned_message_builder() { assert_eq!(message.method_num(), MethodNum::default()); assert_eq!(message.params(), MethodParams::default()); assert_eq!(message.value(), TokenAmount::new(0)); - assert_eq!(message.gas_price(), 0); - assert_eq!(message.gas_limit(), 0); + assert_eq!(message.gas_price(), BigUint::default()); + assert_eq!(message.gas_limit(), BigUint::default()); let mut mb = UnsignedMessage::builder(); mb.to(to_addr.clone()); mb.from(from_addr.clone()); From f38074efc497e3ec4247a064de66d409a98c239e Mon Sep 17 00:00:00 2001 From: austinabell Date: Wed, 15 Jan 2020 12:46:34 -0500 Subject: [PATCH 13/17] lint --- vm/message/src/signed_message.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/message/src/signed_message.rs b/vm/message/src/signed_message.rs index 9fd5195aad8a..1db8003552c5 100644 --- a/vm/message/src/signed_message.rs +++ b/vm/message/src/signed_message.rs @@ -2,12 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 use super::{Message, UnsignedMessage}; -use vm::{MethodNum, MethodParams, TokenAmount}; -use num_bigint::BigUint; use address::Address; use crypto::{Error as CryptoError, Signature, Signer}; use encoding::Cbor; +use num_bigint::BigUint; use serde::{Deserialize, Serialize}; +use vm::{MethodNum, MethodParams, TokenAmount}; /// SignedMessage represents a wrapped message with signature bytes #[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] From 6daa3dd8e66acbbe0bb2f097c1fb9d18b60df151 Mon Sep 17 00:00:00 2001 From: austinabell Date: Wed, 15 Jan 2020 13:28:36 -0500 Subject: [PATCH 14/17] change imports to more specific (readability) --- ipld/cid/src/lib.rs | 10 +++++----- ipld/cid/src/to_cid.rs | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ipld/cid/src/lib.rs b/ipld/cid/src/lib.rs index 7cce95df3349..2641a3957b58 100644 --- a/ipld/cid/src/lib.rs +++ b/ipld/cid/src/lib.rs @@ -12,7 +12,7 @@ pub use self::to_cid::ToCid; pub use self::version::Version; use encoding::{de, ser, serde_bytes, tags::Tagged, Cbor}; use integer_encoding::{VarIntReader, VarIntWriter}; -use multihash::Multihash; +use multihash::{Hash, Multihash}; use std::fmt; use std::io::Cursor; @@ -23,7 +23,7 @@ const CBOR_TAG_CID: u64 = 42; pub struct Prefix { pub version: Version, pub codec: Codec, - pub mh_type: multihash::Hash, + pub mh_type: Hash, pub mh_len: usize, } @@ -40,7 +40,7 @@ impl Default for Cid { Self::new( Codec::Raw, Version::V0, - multihash::encode(multihash::Hash::Blake2b512, &[]).unwrap(), + multihash::encode(Hash::Blake2b512, &[]).unwrap(), ) } } @@ -89,7 +89,7 @@ impl Cid { let prefix = Prefix { version: Version::V1, codec: Codec::DagCBOR, - mh_type: multihash::Hash::Blake2b512, + mh_type: Hash::Blake2b512, mh_len: 64, // TODO verify cid hash length and type }; Ok(Self::new_from_prefix(&prefix, bz)?) @@ -198,7 +198,7 @@ impl Prefix { let version = Version::from(raw_version)?; let codec = Codec::from(raw_codec)?; - let mh_type = multihash::Hash::from_code(raw_mh_type as u16).ok_or(Error::ParsingError)?; + let mh_type = Hash::from_code(raw_mh_type as u16).ok_or(Error::ParsingError)?; let mh_len = cur.read_varint()?; diff --git a/ipld/cid/src/to_cid.rs b/ipld/cid/src/to_cid.rs index 4caab3eb5a75..399f51516147 100644 --- a/ipld/cid/src/to_cid.rs +++ b/ipld/cid/src/to_cid.rs @@ -4,7 +4,7 @@ use crate::{Cid, Codec, Error, Version}; use integer_encoding::VarIntReader; use multibase; -use multihash; +use multihash::Multihash; use std::io::Cursor; use std::str::FromStr; @@ -81,7 +81,7 @@ impl ToCid for [u8] { fn to_cid(&self) -> Result { if Version::is_v0_binary(self) { // Verify that hash can be decoded, this is very cheap - let hash = multihash::Multihash::from_bytes(self.to_vec())?; + let hash = Multihash::from_bytes(self.to_vec())?; Ok(Cid::new(Codec::DagProtobuf, Version::V0, hash)) } else { @@ -96,7 +96,7 @@ impl ToCid for [u8] { // Verify that hash can be decoded, this is very cheap // TODO verify this (was previously using all bytes) - let hash = multihash::Multihash::from_bytes(hash.to_vec())?; + let hash = Multihash::from_bytes(hash.to_vec())?; Ok(Cid::new(codec, version, hash)) } From 6e23b6618db38b99203e9786ba5f918bb2326d65 Mon Sep 17 00:00:00 2001 From: austinabell Date: Wed, 15 Jan 2020 13:41:58 -0500 Subject: [PATCH 15/17] cbor vector serialization round trip test and implement default cbor trait for Cid --- ipld/cid/src/lib.rs | 2 ++ ipld/cid/tests/base_cid_tests.rs | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ipld/cid/src/lib.rs b/ipld/cid/src/lib.rs index 2641a3957b58..01890d435bce 100644 --- a/ipld/cid/src/lib.rs +++ b/ipld/cid/src/lib.rs @@ -45,6 +45,8 @@ impl Default for Cid { } } +impl Cbor for Cid {} + impl ser::Serialize for Cid { fn serialize(&self, s: S) -> Result where diff --git a/ipld/cid/tests/base_cid_tests.rs b/ipld/cid/tests/base_cid_tests.rs index 8c1607c6728f..b18e2df76e06 100644 --- a/ipld/cid/tests/base_cid_tests.rs +++ b/ipld/cid/tests/base_cid_tests.rs @@ -1,7 +1,7 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0 -use encoding::Cbor; +use encoding::{from_slice, to_vec, Cbor}; use ferret_cid::{Cid, Codec, Error, Prefix, Version}; use multihash; use multihash::Hash::Blake2b512; @@ -137,3 +137,20 @@ fn test_cbor_to_cid() { let bz_enc = Cid::from_bytes_default(&obj.marshal_cbor().unwrap()).unwrap(); assert_eq!(enc, bz_enc); } + +#[test] +fn vector_cid_serialize_round() { + let cids = vec![ + Cid::from_bytes_default(&[0, 1]).unwrap(), + Cid::from_bytes_default(&[1, 2]).unwrap(), + Cid::from_bytes_default(&[3, 2]).unwrap(), + ]; + + // Serialize cids with cbor + let enc = to_vec(&cids).unwrap(); + + // decode cbor bytes to vector again + let dec: Vec = from_slice(&enc).unwrap(); + + assert_eq!(cids, dec); +} From 11f003daca30bcef6b3c4d828d9a5f6892ac3085 Mon Sep 17 00:00:00 2001 From: austinabell Date: Wed, 15 Jan 2020 13:55:57 -0500 Subject: [PATCH 16/17] addr comments --- ipld/cid/src/lib.rs | 4 ++-- ipld/cid/src/to_cid.rs | 2 +- vm/runtime/Cargo.toml | 12 ++++++------ vm/state_tree/Cargo.toml | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ipld/cid/src/lib.rs b/ipld/cid/src/lib.rs index 01890d435bce..34b929b43d75 100644 --- a/ipld/cid/src/lib.rs +++ b/ipld/cid/src/lib.rs @@ -39,7 +39,7 @@ impl Default for Cid { fn default() -> Self { Self::new( Codec::Raw, - Version::V0, + Version::V1, multihash::encode(Hash::Blake2b512, &[]).unwrap(), ) } @@ -92,7 +92,7 @@ impl Cid { version: Version::V1, codec: Codec::DagCBOR, mh_type: Hash::Blake2b512, - mh_len: 64, // TODO verify cid hash length and type + mh_len: 64 - 1, // TODO verify cid hash length and type }; Ok(Self::new_from_prefix(&prefix, bz)?) } diff --git a/ipld/cid/src/to_cid.rs b/ipld/cid/src/to_cid.rs index 399f51516147..c328a3e17a48 100644 --- a/ipld/cid/src/to_cid.rs +++ b/ipld/cid/src/to_cid.rs @@ -83,7 +83,7 @@ impl ToCid for [u8] { // Verify that hash can be decoded, this is very cheap let hash = Multihash::from_bytes(self.to_vec())?; - Ok(Cid::new(Codec::DagProtobuf, Version::V0, hash)) + Ok(Cid::new(Codec::DagCBOR, Version::V0, hash)) } else { let mut cur = Cursor::new(self); let raw_version = cur.read_varint()?; diff --git a/vm/runtime/Cargo.toml b/vm/runtime/Cargo.toml index 02e320988044..1c47d98ac6a7 100644 --- a/vm/runtime/Cargo.toml +++ b/vm/runtime/Cargo.toml @@ -5,9 +5,9 @@ authors = ["ChainSafe Systems "] edition = "2018" [dependencies] -vm = {path = "../../vm"} -crypto = {path = "../../crypto"} -address = {path = "../address"} -message = {path = "../message"} -cid = {package = "ferret_cid", path = "../../ipld/cid"} -clock = {path = "../../node/clock"} +vm = { path = "../../vm" } +crypto = { path = "../../crypto" } +address = { path = "../address" } +message = { path = "../message" } +cid = { package = "ferret_cid", path = "../../ipld/cid" } +clock = { path = "../../node/clock" } diff --git a/vm/state_tree/Cargo.toml b/vm/state_tree/Cargo.toml index 915f0ea518b5..b39e65e44b79 100644 --- a/vm/state_tree/Cargo.toml +++ b/vm/state_tree/Cargo.toml @@ -5,10 +5,10 @@ authors = ["ChainSafe Systems "] edition = "2018" [dependencies] -actor = {path = "../actor"} -address = {path = "../address"} -vm = {path = "../../vm"} -cid = {package = "ferret_cid", path = "../../ipld/cid"} +actor = { path = "../actor" } +address = { path = "../address" } +vm = { path = "../../vm" } +cid = { package = "ferret_cid", path = "../../ipld/cid" } [dev-dependencies] num-bigint = "0.2.3" From 860c081721e398f5ecb2e629adb84f8ec34f3aca Mon Sep 17 00:00:00 2001 From: austinabell Date: Wed, 15 Jan 2020 14:04:59 -0500 Subject: [PATCH 17/17] Add documentation --- ipld/cid/src/lib.rs | 4 ++++ ipld/cid/src/to_cid.rs | 1 + ipld/cid/src/version.rs | 4 ++++ ipld/src/lib.rs | 3 +++ vm/actor/src/lib.rs | 1 + 5 files changed, 13 insertions(+) diff --git a/ipld/cid/src/lib.rs b/ipld/cid/src/lib.rs index 34b929b43d75..782d373b3ebf 100644 --- a/ipld/cid/src/lib.rs +++ b/ipld/cid/src/lib.rs @@ -150,6 +150,7 @@ impl Cid { res } + /// Returns encoded bytes of a cid pub fn to_bytes(&self) -> Vec { match self.version { Version::V0 => self.to_bytes_v0(), @@ -157,6 +158,7 @@ impl Cid { } } + /// Returns prefix for Cid format pub fn prefix(&self) -> Prefix { Prefix { version: self.version, @@ -190,6 +192,7 @@ impl fmt::Display for Cid { } impl Prefix { + /// Generate new prefix from encoded bytes pub fn new_from_bytes(data: &[u8]) -> Result { let mut cur = Cursor::new(data); @@ -212,6 +215,7 @@ impl Prefix { }) } + /// Encodes prefix to bytes pub fn as_bytes(&self) -> Vec { let mut res = Vec::with_capacity(4); diff --git a/ipld/cid/src/to_cid.rs b/ipld/cid/src/to_cid.rs index c328a3e17a48..bca9107e2a3d 100644 --- a/ipld/cid/src/to_cid.rs +++ b/ipld/cid/src/to_cid.rs @@ -8,6 +8,7 @@ use multihash::Multihash; use std::io::Cursor; use std::str::FromStr; +/// Trait used to convert objects to Cid (Currently not necessary, but keeping in line with dep) pub trait ToCid { fn to_cid(&self) -> Result; } diff --git a/ipld/cid/src/version.rs b/ipld/cid/src/version.rs index 65c8d9fee8d6..b8e4beab2ff0 100644 --- a/ipld/cid/src/version.rs +++ b/ipld/cid/src/version.rs @@ -3,6 +3,7 @@ use crate::Error; +/// Cid protocol version #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub enum Version { V0, @@ -12,6 +13,7 @@ pub enum Version { use Version::*; impl Version { + /// Generates version from integer value pub fn from(raw: u64) -> Result { match raw { 0 => Ok(V0), @@ -20,12 +22,14 @@ impl Version { } } + /// Returns true if string is version 0 pub fn is_v0_str(data: &str) -> bool { // v0 is a base58btc encoded sha hash, so it has // fixed length and always begins with "Qm" data.len() == 46 && data.starts_with("Qm") } + /// Returns true if bytes is version 0 pub fn is_v0_binary(data: &[u8]) -> bool { data.len() == 34 && data.starts_with(&[0x12, 0x20]) } diff --git a/ipld/src/lib.rs b/ipld/src/lib.rs index 8ad822604174..7c7cf3e00177 100644 --- a/ipld/src/lib.rs +++ b/ipld/src/lib.rs @@ -7,6 +7,7 @@ use serde::Deserialize; use std::collections::BTreeMap; use std::fmt; +/// Represents IPLD data structure used when serializing and deserializing data #[derive(Debug, Clone, PartialEq)] pub enum Ipld { Null, @@ -20,6 +21,8 @@ pub enum Ipld { Link(Vec), } +/// Struct used in deserialization to decode cbor encoded data (including Cid tagged) +/// values to Ipld data type pub struct IpldVisitor; impl<'de> de::Visitor<'de> for IpldVisitor { diff --git a/vm/actor/src/lib.rs b/vm/actor/src/lib.rs index 5a79f6743ea9..5868cac2c46c 100644 --- a/vm/actor/src/lib.rs +++ b/vm/actor/src/lib.rs @@ -12,6 +12,7 @@ use encoding::Cbor; use num_bigint::BigUint; use serde::{Deserialize, Serialize}; +/// Identifier for Actors, includes builtin and initialized actors #[derive(PartialEq, Eq, Copy, Clone, Debug, Default, Serialize, Deserialize)] pub struct ActorID(u64);