Merge pull request #22 from paritytech/refactor/rlp-optionally-independent-of-ethereum-types
[rlp] make it possible to use rlp without pulling in ethereum-types
This commit is contained in:
commit
abe18ea03c
|
@ -3,11 +3,18 @@ description = "Recursive-length prefix encoding, decoding, and compression"
|
||||||
repository = "https://github.com/paritytech/parity"
|
repository = "https://github.com/paritytech/parity"
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
name = "rlp"
|
name = "rlp"
|
||||||
version = "0.2.1"
|
version = "0.2.2"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "1.0"
|
byteorder = "1.0"
|
||||||
elastic-array = "0.10"
|
elastic-array = "0.10"
|
||||||
ethereum-types = "0.3"
|
ethereum-types = { version = "0.3", optional = true }
|
||||||
rustc-hex = "1.0"
|
rustc-hex = {version = "2.0", default-features = false }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
hex-literal = "0.1"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["ethereum"]
|
||||||
|
ethereum = ["ethereum-types"]
|
138
rlp/src/impls.rs
138
rlp/src/impls.rs
|
@ -6,9 +6,8 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use std::{cmp, mem, str};
|
use std::{mem, str};
|
||||||
use byteorder::{ByteOrder, BigEndian};
|
use byteorder::{ByteOrder, BigEndian};
|
||||||
use bigint::{U128, U256, H64, H128, H160, H256, H512, H520, Bloom};
|
|
||||||
use traits::{Encodable, Decodable};
|
use traits::{Encodable, Decodable};
|
||||||
use stream::RlpStream;
|
use stream::RlpStream;
|
||||||
use {Rlp, DecoderError};
|
use {Rlp, DecoderError};
|
||||||
|
@ -179,87 +178,94 @@ impl Decodable for usize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_encodable_for_hash {
|
#[cfg(feature = "ethereum")]
|
||||||
($name: ident) => {
|
mod ethereum_traits {
|
||||||
impl Encodable for $name {
|
use super::*;
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
use std::cmp;
|
||||||
s.encoder().encode_value(self);
|
use ethereum_types::{U128, U256, H64, H128, H160, H256, H512, H520, Bloom};
|
||||||
|
|
||||||
|
macro_rules! impl_encodable_for_hash {
|
||||||
|
($name: ident) => {
|
||||||
|
impl Encodable for $name {
|
||||||
|
fn rlp_append(&self, s: &mut RlpStream) {
|
||||||
|
s.encoder().encode_value(self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_decodable_for_hash {
|
macro_rules! impl_decodable_for_hash {
|
||||||
($name: ident, $size: expr) => {
|
($name: ident, $size: expr) => {
|
||||||
impl Decodable for $name {
|
impl Decodable for $name {
|
||||||
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
|
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
|
||||||
rlp.decoder().decode_value(|bytes| match bytes.len().cmp(&$size) {
|
rlp.decoder().decode_value(|bytes| match bytes.len().cmp(&$size) {
|
||||||
cmp::Ordering::Less => Err(DecoderError::RlpIsTooShort),
|
cmp::Ordering::Less => Err(DecoderError::RlpIsTooShort),
|
||||||
cmp::Ordering::Greater => Err(DecoderError::RlpIsTooBig),
|
cmp::Ordering::Greater => Err(DecoderError::RlpIsTooBig),
|
||||||
cmp::Ordering::Equal => {
|
cmp::Ordering::Equal => {
|
||||||
let mut t = [0u8; $size];
|
let mut t = [0u8; $size];
|
||||||
t.copy_from_slice(bytes);
|
t.copy_from_slice(bytes);
|
||||||
Ok($name(t))
|
Ok($name(t))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl_encodable_for_hash!(H64);
|
macro_rules! impl_encodable_for_uint {
|
||||||
impl_encodable_for_hash!(H128);
|
($name: ident, $size: expr) => {
|
||||||
impl_encodable_for_hash!(H160);
|
impl Encodable for $name {
|
||||||
impl_encodable_for_hash!(H256);
|
fn rlp_append(&self, s: &mut RlpStream) {
|
||||||
impl_encodable_for_hash!(H512);
|
let leading_empty_bytes = $size - (self.bits() + 7) / 8;
|
||||||
impl_encodable_for_hash!(H520);
|
let mut buffer = [0u8; $size];
|
||||||
impl_encodable_for_hash!(Bloom);
|
self.to_big_endian(&mut buffer);
|
||||||
|
s.encoder().encode_value(&buffer[leading_empty_bytes..]);
|
||||||
impl_decodable_for_hash!(H64, 8);
|
}
|
||||||
impl_decodable_for_hash!(H128, 16);
|
|
||||||
impl_decodable_for_hash!(H160, 20);
|
|
||||||
impl_decodable_for_hash!(H256, 32);
|
|
||||||
impl_decodable_for_hash!(H512, 64);
|
|
||||||
impl_decodable_for_hash!(H520, 65);
|
|
||||||
impl_decodable_for_hash!(Bloom, 256);
|
|
||||||
|
|
||||||
macro_rules! impl_encodable_for_uint {
|
|
||||||
($name: ident, $size: expr) => {
|
|
||||||
impl Encodable for $name {
|
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
|
||||||
let leading_empty_bytes = $size - (self.bits() + 7) / 8;
|
|
||||||
let mut buffer = [0u8; $size];
|
|
||||||
self.to_big_endian(&mut buffer);
|
|
||||||
s.encoder().encode_value(&buffer[leading_empty_bytes..]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_decodable_for_uint {
|
macro_rules! impl_decodable_for_uint {
|
||||||
($name: ident, $size: expr) => {
|
($name: ident, $size: expr) => {
|
||||||
impl Decodable for $name {
|
impl Decodable for $name {
|
||||||
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
|
fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
|
||||||
rlp.decoder().decode_value(|bytes| {
|
rlp.decoder().decode_value(|bytes| {
|
||||||
if !bytes.is_empty() && bytes[0] == 0 {
|
if !bytes.is_empty() && bytes[0] == 0 {
|
||||||
Err(DecoderError::RlpInvalidIndirection)
|
Err(DecoderError::RlpInvalidIndirection)
|
||||||
} else if bytes.len() <= $size {
|
} else if bytes.len() <= $size {
|
||||||
Ok($name::from(bytes))
|
Ok($name::from(bytes))
|
||||||
} else {
|
} else {
|
||||||
Err(DecoderError::RlpIsTooBig)
|
Err(DecoderError::RlpIsTooBig)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_encodable_for_hash!(H64);
|
||||||
|
impl_encodable_for_hash!(H128);
|
||||||
|
impl_encodable_for_hash!(H160);
|
||||||
|
impl_encodable_for_hash!(H256);
|
||||||
|
impl_encodable_for_hash!(H512);
|
||||||
|
impl_encodable_for_hash!(H520);
|
||||||
|
impl_encodable_for_hash!(Bloom);
|
||||||
|
|
||||||
|
impl_decodable_for_hash!(H64, 8);
|
||||||
|
impl_decodable_for_hash!(H128, 16);
|
||||||
|
impl_decodable_for_hash!(H160, 20);
|
||||||
|
impl_decodable_for_hash!(H256, 32);
|
||||||
|
impl_decodable_for_hash!(H512, 64);
|
||||||
|
impl_decodable_for_hash!(H520, 65);
|
||||||
|
impl_decodable_for_hash!(Bloom, 256);
|
||||||
|
|
||||||
|
impl_encodable_for_uint!(U256, 32);
|
||||||
|
impl_encodable_for_uint!(U128, 16);
|
||||||
|
|
||||||
|
impl_decodable_for_uint!(U256, 32);
|
||||||
|
impl_decodable_for_uint!(U128, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_encodable_for_uint!(U256, 32);
|
|
||||||
impl_encodable_for_uint!(U128, 16);
|
|
||||||
|
|
||||||
impl_decodable_for_uint!(U256, 32);
|
|
||||||
impl_decodable_for_uint!(U128, 16);
|
|
||||||
|
|
||||||
impl<'a> Encodable for &'a str {
|
impl<'a> Encodable for &'a str {
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
fn rlp_append(&self, s: &mut RlpStream) {
|
||||||
s.encoder().encode_value(self.as_bytes());
|
s.encoder().encode_value(self.as_bytes());
|
||||||
|
|
|
@ -33,9 +33,13 @@
|
||||||
//! * You don't want to decode whole rlp at once.
|
//! * You don't want to decode whole rlp at once.
|
||||||
|
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
extern crate ethereum_types as bigint;
|
#[cfg(feature = "ethereum")]
|
||||||
|
extern crate ethereum_types;
|
||||||
extern crate elastic_array;
|
extern crate elastic_array;
|
||||||
extern crate rustc_hex;
|
extern crate rustc_hex;
|
||||||
|
#[cfg(test)]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate hex_literal;
|
||||||
|
|
||||||
mod traits;
|
mod traits;
|
||||||
mod error;
|
mod error;
|
||||||
|
|
|
@ -118,7 +118,7 @@ impl<'a> fmt::Display for Rlp<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
match self.prototype() {
|
match self.prototype() {
|
||||||
Ok(Prototype::Null) => write!(f, "null"),
|
Ok(Prototype::Null) => write!(f, "null"),
|
||||||
Ok(Prototype::Data(_)) => write!(f, "\"0x{}\"", self.data().unwrap().to_hex()),
|
Ok(Prototype::Data(_)) => write!(f, "\"0x{}\"", self.data().unwrap().to_hex::<String>()),
|
||||||
Ok(Prototype::List(len)) => {
|
Ok(Prototype::List(len)) => {
|
||||||
write!(f, "[")?;
|
write!(f, "[")?;
|
||||||
for i in 0..len-1 {
|
for i in 0..len-1 {
|
||||||
|
@ -389,8 +389,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rlp_display() {
|
fn test_rlp_display() {
|
||||||
use rustc_hex::FromHex;
|
let data = hex!("f84d0589010efbef67941f79b2a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470");
|
||||||
let data = "f84d0589010efbef67941f79b2a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470".from_hex().unwrap();
|
|
||||||
let rlp = Rlp::new(&data);
|
let rlp = Rlp::new(&data);
|
||||||
assert_eq!(format!("{}", rlp), "[\"0x05\", \"0x010efbef67941f79b2\", \"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\", \"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\"]");
|
assert_eq!(format!("{}", rlp), "[\"0x05\", \"0x010efbef67941f79b2\", \"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\", \"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\"]");
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,13 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
extern crate ethereum_types as bigint;
|
#[cfg(feature = "ethereum")]
|
||||||
|
extern crate ethereum_types;
|
||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
|
|
||||||
use std::{fmt, cmp};
|
use std::{fmt, cmp};
|
||||||
use bigint::{U256, H160};
|
#[cfg(feature = "ethereum")]
|
||||||
|
use ethereum_types::{U256, H160};
|
||||||
use rlp::{Encodable, Decodable, Rlp, RlpStream, DecoderError};
|
use rlp::{Encodable, Decodable, Rlp, RlpStream, DecoderError};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -130,6 +132,7 @@ fn encode_u64() {
|
||||||
run_encode_tests(tests);
|
run_encode_tests(tests);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ethereum")]
|
||||||
#[test]
|
#[test]
|
||||||
fn encode_u256() {
|
fn encode_u256() {
|
||||||
let tests = vec![ETestPair(U256::from(0u64), vec![0x80u8]),
|
let tests = vec![ETestPair(U256::from(0u64), vec![0x80u8]),
|
||||||
|
@ -162,6 +165,7 @@ fn encode_str() {
|
||||||
run_encode_tests(tests);
|
run_encode_tests(tests);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ethereum")]
|
||||||
#[test]
|
#[test]
|
||||||
fn encode_address() {
|
fn encode_address() {
|
||||||
let tests = vec![
|
let tests = vec![
|
||||||
|
@ -272,6 +276,7 @@ fn decode_untrusted_u64() {
|
||||||
run_decode_tests(tests);
|
run_decode_tests(tests);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ethereum")]
|
||||||
#[test]
|
#[test]
|
||||||
fn decode_untrusted_u256() {
|
fn decode_untrusted_u256() {
|
||||||
let tests = vec![DTestPair(U256::from(0u64), vec![0x80u8]),
|
let tests = vec![DTestPair(U256::from(0u64), vec![0x80u8]),
|
||||||
|
@ -306,6 +311,7 @@ fn decode_untrusted_str() {
|
||||||
run_decode_tests(tests);
|
run_decode_tests(tests);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ethereum")]
|
||||||
#[test]
|
#[test]
|
||||||
fn decode_untrusted_address() {
|
fn decode_untrusted_address() {
|
||||||
let tests = vec![
|
let tests = vec![
|
||||||
|
|
|
@ -8,8 +8,8 @@ license = "GPL-3.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
elastic-array = "0.10"
|
elastic-array = "0.10"
|
||||||
hashdb = { version = "0.2", path = "../hashdb" }
|
hashdb = { version = "0.2", path = "../hashdb", default_features = false }
|
||||||
rlp = { version = "0.2.1", path = "../rlp" }
|
rlp = { version = "0.2", path = "../rlp", default_features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
trie-standardmap = { version = "0.1", path = "../trie-standardmap" }
|
trie-standardmap = { version = "0.1", path = "../trie-standardmap" }
|
||||||
|
|
Loading…
Reference in New Issue