From 2a50550b8738803fc99fd6d85b4102da5fb8ef2e Mon Sep 17 00:00:00 2001 From: Matt Garnett <14004106+c-o-l-o-r@users.noreply.github.com> Date: Sat, 22 Jun 2019 13:57:37 -0400 Subject: [PATCH 1/4] make `hashing` crate wasm compatible --- eth2/utils/hashing/.cargo/config | 2 ++ eth2/utils/hashing/Cargo.toml | 11 ++++++++++- eth2/utils/hashing/src/lib.rs | 33 +++++++++++++++++++++++++------- 3 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 eth2/utils/hashing/.cargo/config diff --git a/eth2/utils/hashing/.cargo/config b/eth2/utils/hashing/.cargo/config new file mode 100644 index 0000000000..4ec2f3b862 --- /dev/null +++ b/eth2/utils/hashing/.cargo/config @@ -0,0 +1,2 @@ +[target.wasm32-unknown-unknown] +runner = 'wasm-bindgen-test-runner' diff --git a/eth2/utils/hashing/Cargo.toml b/eth2/utils/hashing/Cargo.toml index 78dd70e43c..506b84a6b7 100644 --- a/eth2/utils/hashing/Cargo.toml +++ b/eth2/utils/hashing/Cargo.toml @@ -4,5 +4,14 @@ version = "0.1.0" authors = ["Paul Hauner "] edition = "2018" -[dependencies] +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] ring = "0.14.6" + +[target.'cfg(target_arch = "wasm32")'.dependencies] +sha2 = "0.8.0" + +[dev-dependencies] +rustc-hex = "2.0.1" + +[target.'cfg(target_arch = "wasm32")'.dev-dependencies] +wasm-bindgen-test = "0.2.47" diff --git a/eth2/utils/hashing/src/lib.rs b/eth2/utils/hashing/src/lib.rs index a9e286c39a..7214c7421a 100644 --- a/eth2/utils/hashing/src/lib.rs +++ b/eth2/utils/hashing/src/lib.rs @@ -1,7 +1,17 @@ +#[cfg(not(target_arch = "wasm32"))] use ring::digest::{digest, SHA256}; +#[cfg(target_arch = "wasm32")] +use sha2::{Digest, Sha256}; + pub fn hash(input: &[u8]) -> Vec { - digest(&SHA256, input).as_ref().into() + #[cfg(not(target_arch = "wasm32"))] + let h = digest(&SHA256, input).as_ref().into(); + + #[cfg(target_arch = "wasm32")] + let h = Sha256::digest(input).as_ref().into(); + + h } /// Get merkle root of some hashed values - the input leaf nodes is expected to already be hashed @@ -37,19 +47,24 @@ pub fn merkle_root(values: &[Vec]) -> Option> { #[cfg(test)] mod tests { use super::*; - use ring::test; + use rustc_hex::FromHex; - #[test] + #[cfg(target_arch = "wasm32")] + use wasm_bindgen_test::*; + + #[cfg_attr(not(target_arch = "wasm32"), test)] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_hashing() { let input: Vec = b"hello world".as_ref().into(); let output = hash(input.as_ref()); let expected_hex = "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"; - let expected: Vec = test::from_hex(expected_hex).unwrap(); + let expected: Vec = expected_hex.from_hex().unwrap(); assert_eq!(expected, output); } - #[test] + #[cfg_attr(not(target_arch = "wasm32"), test)] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_merkle_root() { // hash the leaf nodes let mut input = vec![ @@ -79,13 +94,17 @@ mod tests { assert_eq!(&expected[..], output.unwrap().as_slice()); } - #[test] + + #[cfg_attr(not(target_arch = "wasm32"), test)] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_empty_input_merkle_root() { let input = vec![]; let output = merkle_root(&input[..]); assert_eq!(None, output); } - #[test] + + #[cfg_attr(not(target_arch = "wasm32"), test)] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_odd_leaf_merkle_root() { let input = vec![ hash("a".as_bytes()), From 87e681c6175df08d529599e94b7bb5ec11bc584c Mon Sep 17 00:00:00 2001 From: Matt Garnett <14004106+c-o-l-o-r@users.noreply.github.com> Date: Sat, 22 Jun 2019 14:34:29 -0400 Subject: [PATCH 2/4] make `ssz` crate wasm compatible --- eth2/utils/ssz/src/decode/impls.rs | 5 +++++ eth2/utils/ssz/src/lib.rs | 2 ++ 2 files changed, 7 insertions(+) diff --git a/eth2/utils/ssz/src/decode/impls.rs b/eth2/utils/ssz/src/decode/impls.rs index 0965ee3e54..75dd5d444c 100644 --- a/eth2/utils/ssz/src/decode/impls.rs +++ b/eth2/utils/ssz/src/decode/impls.rs @@ -34,6 +34,11 @@ impl_decodable_for_uint!(u8, 8); impl_decodable_for_uint!(u16, 16); impl_decodable_for_uint!(u32, 32); impl_decodable_for_uint!(u64, 64); + +#[cfg(target_pointer_width = "32")] +impl_decodable_for_uint!(usize, 32); + +#[cfg(target_pointer_width = "64")] impl_decodable_for_uint!(usize, 64); impl Decode for bool { diff --git a/eth2/utils/ssz/src/lib.rs b/eth2/utils/ssz/src/lib.rs index fceebcc444..51bafa95ef 100644 --- a/eth2/utils/ssz/src/lib.rs +++ b/eth2/utils/ssz/src/lib.rs @@ -46,6 +46,8 @@ pub use encode::{Encode, SszEncoder}; /// The number of bytes used to represent an offset. pub const BYTES_PER_LENGTH_OFFSET: usize = 4; /// The maximum value that can be represented using `BYTES_PER_LENGTH_OFFSET`. +// allows overflow on 32-bit target +#[allow(const_err)] pub const MAX_LENGTH_VALUE: usize = (1 << (BYTES_PER_LENGTH_OFFSET * 8)) - 1; /// Convenience function to SSZ encode an object supporting ssz::Encode. From db9dd3dffe36711d3832e279e47b6402eca6a818 Mon Sep 17 00:00:00 2001 From: Matt Garnett <14004106+c-o-l-o-r@users.noreply.github.com> Date: Tue, 25 Jun 2019 09:59:50 -0400 Subject: [PATCH 3/4] fix encoding impl for usize on 32-bit architectures --- eth2/utils/ssz/src/encode/impls.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/eth2/utils/ssz/src/encode/impls.rs b/eth2/utils/ssz/src/encode/impls.rs index 04492a1f2d..e0e2d9dbc1 100644 --- a/eth2/utils/ssz/src/encode/impls.rs +++ b/eth2/utils/ssz/src/encode/impls.rs @@ -24,6 +24,11 @@ impl_encodable_for_uint!(u8, 8); impl_encodable_for_uint!(u16, 16); impl_encodable_for_uint!(u32, 32); impl_encodable_for_uint!(u64, 64); + +#[cfg(target_pointer_width = "32")] +impl_encodable_for_uint!(usize, 32); + +#[cfg(target_pointer_width = "64")] impl_encodable_for_uint!(usize, 64); /// The SSZ "union" type. From e93fb94e7ad61b497e66227c74ea39a228ec2241 Mon Sep 17 00:00:00 2001 From: Matt Garnett <14004106+c-o-l-o-r@users.noreply.github.com> Date: Tue, 25 Jun 2019 10:12:49 -0400 Subject: [PATCH 4/4] calculate MAX_LENGTH_VALUE for 32-bit and 64-bit targets --- eth2/utils/ssz/src/lib.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/eth2/utils/ssz/src/lib.rs b/eth2/utils/ssz/src/lib.rs index 51bafa95ef..51dd16523a 100644 --- a/eth2/utils/ssz/src/lib.rs +++ b/eth2/utils/ssz/src/lib.rs @@ -46,9 +46,10 @@ pub use encode::{Encode, SszEncoder}; /// The number of bytes used to represent an offset. pub const BYTES_PER_LENGTH_OFFSET: usize = 4; /// The maximum value that can be represented using `BYTES_PER_LENGTH_OFFSET`. -// allows overflow on 32-bit target -#[allow(const_err)] -pub const MAX_LENGTH_VALUE: usize = (1 << (BYTES_PER_LENGTH_OFFSET * 8)) - 1; +#[cfg(target_pointer_width = "32")] +pub const MAX_LENGTH_VALUE: usize = (std::u32::MAX >> 8 * (4 - BYTES_PER_LENGTH_OFFSET)) as usize; +#[cfg(target_pointer_width = "64")] +pub const MAX_LENGTH_VALUE: usize = (std::u64::MAX >> 8 * (8 - BYTES_PER_LENGTH_OFFSET)) as usize; /// Convenience function to SSZ encode an object supporting ssz::Encode. ///