diff --git a/.travis.yml b/.travis.yml index bb07838aa..6d189fe3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,7 @@ script: - if [ "$TRAVIS_RUST_VERSION" == "nightly" ]; then cd parity-bytes/ && cargo build --no-default-features && cd ..; cd fixed-hash/ && cargo test --no-default-features --features="rustc-hex,byteorder" && cd..; + cd rlp/ && cargo test --no-default-features && cd ..; fi - cd fixed-hash/ && cargo test --all-features && cd .. - cd uint/ && cargo test --features=std,quickcheck --release && cd .. diff --git a/rlp/Cargo.toml b/rlp/Cargo.toml index 380387d01..f60edd99b 100644 --- a/rlp/Cargo.toml +++ b/rlp/Cargo.toml @@ -8,10 +8,12 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -byteorder = "1.0" -rustc-hex = {version = "2.0", default-features = false } - -[dev-dependencies] -hex-literal = "0.2" -primitive-types = { path = "../primitive-types", version = "0.4", features = ["impl-rlp"] } +byteorder = { version = "1", default-features = false } +rustc-hex = { version = "2.0", default-features = false } +[features] +default = ["std"] +std = [ + "byteorder/std", + "rustc-hex/std", +] diff --git a/rlp/benches/rlp.rs b/rlp/benches/rlp.rs index 606f20a4d..3a2b3b10d 100644 --- a/rlp/benches/rlp.rs +++ b/rlp/benches/rlp.rs @@ -17,7 +17,6 @@ // TODO: get rid of this one fine day: https://doc.rust-lang.org/nightly/edition-guide/rust-2018/module-system/path-clarity.html#an-exception extern crate test; -use primitive_types::U256; use rlp::{RlpStream, Rlp}; use test::Bencher; @@ -41,29 +40,6 @@ fn bench_decode_u64_value(b: &mut Bencher) { }); } -#[bench] -fn bench_stream_u256_value(b: &mut Bencher) { - b.iter(|| { - // u256 - let mut stream = RlpStream::new(); - let uint: U256 = "8090a0b0c0d0e0f00910203040506077000000000000000100000000000012f0".into(); - stream.append(&uint); - let _ = stream.out(); - }); -} - -#[bench] -fn bench_decode_u256_value(b: &mut Bencher) { - b.iter(|| { - // u256 - let data = vec![0xa0, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0x09, 0x10, 0x20, - 0x30, 0x40, 0x50, 0x60, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xf0]; - let rlp = Rlp::new(&data); - let _ : U256 = rlp.as_val().unwrap(); - }); -} - #[bench] fn bench_stream_nested_empty_lists(b: &mut Bencher) { b.iter(|| { @@ -105,13 +81,13 @@ fn bench_stream_1000_empty_lists(b: &mut Bencher) { fn bench_decode_1000_values(b: &mut Bencher) { let mut stream = RlpStream::new_list(1000); for _ in 0..1000 { - stream.append(&U256::from(1)); + stream.append(&1u64); } let data= stream.out(); b.iter(|| { let rlp = Rlp::new(&data); for i in 0..1000 { - let _: U256 = rlp.val_at(i).unwrap(); + let _: u64 = rlp.val_at(i).unwrap(); } }); } diff --git a/rlp/src/error.rs b/rlp/src/error.rs index 7aef6cfbf..d810130b0 100644 --- a/rlp/src/error.rs +++ b/rlp/src/error.rs @@ -6,7 +6,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::fmt; +use core::fmt; +#[cfg(feature = "std")] use std::error::Error as StdError; #[derive(Debug, PartialEq, Eq, Clone)] @@ -36,6 +37,7 @@ pub enum DecoderError { Custom(&'static str), } +#[cfg(feature = "std")] impl StdError for DecoderError { fn description(&self) -> &str { "builder error" diff --git a/rlp/src/impls.rs b/rlp/src/impls.rs index 71fd8a30d..d3d5c8ff1 100644 --- a/rlp/src/impls.rs +++ b/rlp/src/impls.rs @@ -6,12 +6,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::{mem, str}; -use std::iter::{once, empty}; +#[cfg(not(feature = "std"))] +use alloc::{borrow::ToOwned, vec::Vec, string::String}; +use core::{mem, str}; +use core::iter::{once, empty}; + use byteorder::{ByteOrder, BigEndian}; -use crate::traits::{Encodable, Decodable}; -use crate::stream::RlpStream; -use crate::{Rlp, DecoderError}; + +use crate::{ + error::DecoderError, + rlpin::Rlp, + stream::RlpStream, + traits::{Encodable, Decodable}, +}; pub fn decode_usize(bytes: &[u8]) -> Result { match bytes.len() { diff --git a/rlp/src/lib.rs b/rlp/src/lib.rs index e85c1a0db..1baa52c2f 100644 --- a/rlp/src/lib.rs +++ b/rlp/src/lib.rs @@ -32,7 +32,10 @@ //! * You want to get view onto rlp-slice. //! * You don't want to decode whole rlp at once. -use std::borrow::Borrow; +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(not(feature = "std"))] +extern crate alloc; mod traits; mod error; @@ -40,10 +43,14 @@ mod rlpin; mod stream; mod impls; -pub use crate::error::DecoderError; -pub use crate::traits::{Decodable, Encodable}; -pub use crate::rlpin::{Rlp, RlpIterator, PayloadInfo, Prototype}; -pub use crate::stream::RlpStream; +#[cfg(not(feature = "std"))] +use alloc::vec::Vec; +use core::borrow::Borrow; + +pub use self::error::DecoderError; +pub use self::rlpin::{Rlp, RlpIterator, PayloadInfo, Prototype}; +pub use self::stream::RlpStream; +pub use self::traits::{Decodable, Encodable}; /// The RLP encoded empty data (used to mean "null value"). pub const NULL_RLP: [u8; 1] = [0x80; 1]; diff --git a/rlp/src/rlpin.rs b/rlp/src/rlpin.rs index e4a05c76c..e45c0c21a 100644 --- a/rlp/src/rlpin.rs +++ b/rlp/src/rlpin.rs @@ -6,11 +6,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::cell::Cell; -use std::fmt; +#[cfg(not(feature = "std"))] +use alloc::{string::String, vec::Vec}; +use core::cell::Cell; +use core::fmt; + use rustc_hex::ToHex; -use crate::impls::decode_usize; -use crate::{Decodable, DecoderError}; + +use crate::{ + error::DecoderError, + impls::decode_usize, + traits::Decodable, +}; /// rlp offset #[derive(Copy, Clone, Debug)] @@ -384,24 +391,3 @@ impl<'a> BasicDecoder<'a> { } } } - -#[cfg(test)] -mod tests { - use crate::{Rlp, DecoderError}; - use hex_literal::hex; - - #[test] - fn test_rlp_display() { - let data = hex!("f84d0589010efbef67941f79b2a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"); - let rlp = Rlp::new(&data); - assert_eq!(format!("{}", rlp), "[\"0x05\", \"0x010efbef67941f79b2\", \"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\", \"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\"]"); - } - - #[test] - fn length_overflow() { - let bs = [0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe5]; - let rlp = Rlp::new(&bs); - let res: Result = rlp.as_val(); - assert_eq!(Err(DecoderError::RlpInvalidLength), res); - } -} diff --git a/rlp/src/stream.rs b/rlp/src/stream.rs index 47862667f..d478f46c0 100644 --- a/rlp/src/stream.rs +++ b/rlp/src/stream.rs @@ -6,8 +6,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::borrow::Borrow; +#[cfg(not(feature = "std"))] +use alloc::vec::Vec; +use core::borrow::Borrow; + use byteorder::{ByteOrder, BigEndian}; + use crate::traits::Encodable; #[derive(Debug, Copy, Clone)] diff --git a/rlp/src/traits.rs b/rlp/src/traits.rs index b5502bb15..b3187fc8b 100644 --- a/rlp/src/traits.rs +++ b/rlp/src/traits.rs @@ -7,7 +7,14 @@ // except according to those terms. //! Common RLP traits -use crate::{DecoderError, Rlp, RlpStream}; +#[cfg(not(feature = "std"))] +use alloc::vec::Vec; + +use crate::{ + error::DecoderError, + rlpin::Rlp, + stream::RlpStream, +}; /// RLP decodable trait pub trait Decodable: Sized { diff --git a/rlp/tests/tests.rs b/rlp/tests/tests.rs index 9022451af..089406707 100644 --- a/rlp/tests/tests.rs +++ b/rlp/tests/tests.rs @@ -6,10 +6,32 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use primitive_types::{H160, U256}; -use std::{fmt, cmp}; +#[cfg(not(feature = "std"))] +extern crate alloc; +#[cfg(not(feature = "std"))] +use alloc::{format, string::String, vec::Vec}; +use core::{fmt, cmp}; + use rlp::{Encodable, Decodable, Rlp, RlpStream, DecoderError}; -use hex_literal::hex; + +fn hex(s: &str) -> Vec { + rustc_hex::FromHex::from_hex(s).unwrap() +} + +#[test] +fn test_rlp_display() { + let data = hex("f84d0589010efbef67941f79b2a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"); + let rlp = Rlp::new(&data); + assert_eq!(format!("{}", rlp), "[\"0x05\", \"0x010efbef67941f79b2\", \"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\", \"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\"]"); +} + +#[test] +fn length_overflow() { + let bs = [0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe5]; + let rlp = Rlp::new(&bs); + let res: Result = rlp.as_val(); + assert_eq!(Err(DecoderError::RlpInvalidLength), res); +} #[test] fn rlp_at() { @@ -128,21 +150,6 @@ fn encode_u64() { run_encode_tests(tests); } -#[test] -fn encode_u256() { - let tests = vec![ETestPair(U256::from(0u64), vec![0x80u8]), - ETestPair(U256::from(0x1000000u64), vec![0x84, 0x01, 0x00, 0x00, 0x00]), - ETestPair(U256::from(0xffffffffu64), - vec![0x84, 0xff, 0xff, 0xff, 0xff]), - ETestPair(("8090a0b0c0d0e0f00910203040506077000000000000\ - 000100000000000012f0").into(), - vec![0xa0, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, - 0x09, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x77, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x12, 0xf0])]; - run_encode_tests(tests); -} - #[test] fn encode_str() { let tests = vec![ETestPair("cat", vec![0x83, b'c', b'a', b't']), @@ -160,17 +167,6 @@ fn encode_str() { run_encode_tests(tests); } -#[test] -fn encode_address() { - let tests = vec![ - ETestPair(H160::from(hex!("ef2d6d194084c2de36e0dabfce45d046b37d1106")), - vec![0x94, 0xef, 0x2d, 0x6d, 0x19, 0x40, 0x84, 0xc2, 0xde, - 0x36, 0xe0, 0xda, 0xbf, 0xce, 0x45, 0xd0, 0x46, - 0xb3, 0x7d, 0x11, 0x06]) - ]; - run_encode_tests(tests); -} - /// Vec (Bytes) is treated as a single value #[test] fn encode_vector_u8() { @@ -270,21 +266,6 @@ fn decode_untrusted_u64() { run_decode_tests(tests); } -#[test] -fn decode_untrusted_u256() { - let tests = vec![DTestPair(U256::from(0u64), vec![0x80u8]), - DTestPair(U256::from(0x1000000u64), vec![0x84, 0x01, 0x00, 0x00, 0x00]), - DTestPair(U256::from(0xffffffffu64), - vec![0x84, 0xff, 0xff, 0xff, 0xff]), - DTestPair(("8090a0b0c0d0e0f00910203040506077000000000000\ - 000100000000000012f0").into(), - vec![0xa0, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, - 0x09, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x77, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x12, 0xf0])]; - run_decode_tests(tests); -} - #[test] fn decode_untrusted_str() { let tests = vec![DTestPair("cat".to_owned(), vec![0x83, b'c', b'a', b't']), @@ -304,17 +285,6 @@ fn decode_untrusted_str() { run_decode_tests(tests); } -#[test] -fn decode_untrusted_address() { - let tests = vec![ - DTestPair(H160::from(hex!("ef2d6d194084c2de36e0dabfce45d046b37d1106")), - vec![0x94, 0xef, 0x2d, 0x6d, 0x19, 0x40, 0x84, 0xc2, 0xde, - 0x36, 0xe0, 0xda, 0xbf, 0xce, 0x45, 0xd0, 0x46, - 0xb3, 0x7d, 0x11, 0x06]) - ]; - run_decode_tests(tests); -} - #[test] fn decode_untrusted_vector_u64() { let tests = vec![ @@ -480,7 +450,7 @@ fn test_inner_length_capping_for_short_lists() { // https://github.com/paritytech/parity-ethereum/pull/9663 #[test] fn test_list_at() { - let raw = hex!("f83e82022bd79020010db83c4d001500000000abcdef12820cfa8215a8d79020010db885a308d313198a2e037073488208ae82823a8443b9a355c5010203040531b9019afde696e582a78fa8d95ea13ce3297d4afb8ba6433e4154caa5ac6431af1b80ba76023fa4090c408f6b4bc3701562c031041d4702971d102c9ab7fa5eed4cd6bab8f7af956f7d565ee1917084a95398b6a21eac920fe3dd1345ec0a7ef39367ee69ddf092cbfe5b93e5e568ebc491983c09c76d922dc3"); + let raw = hex("f83e82022bd79020010db83c4d001500000000abcdef12820cfa8215a8d79020010db885a308d313198a2e037073488208ae82823a8443b9a355c5010203040531b9019afde696e582a78fa8d95ea13ce3297d4afb8ba6433e4154caa5ac6431af1b80ba76023fa4090c408f6b4bc3701562c031041d4702971d102c9ab7fa5eed4cd6bab8f7af956f7d565ee1917084a95398b6a21eac920fe3dd1345ec0a7ef39367ee69ddf092cbfe5b93e5e568ebc491983c09c76d922dc3"); let rlp = Rlp::new(&raw); let _rlp1 = rlp.at(1).unwrap();