Merge branch 'master' into gav
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
//! Rlp serialization module
|
||||
//!
|
||||
//! Allows encoding, decoding, and view onto rlp-slice
|
||||
//! Rlp serialization module
|
||||
//!
|
||||
//! Allows encoding, decoding, and view onto rlp-slice
|
||||
//!
|
||||
//!# What should you use when?
|
||||
//!
|
||||
//!### Use `encode` function when:
|
||||
//!### Use `encode` function when:
|
||||
//! * You want to encode something inline.
|
||||
//! * You do not work on big set of data.
|
||||
//! * You want to encode whole data structure at once.
|
||||
@@ -23,7 +23,7 @@
|
||||
//! * You want to get view onto rlp-slice.
|
||||
//! * You don't want to decode whole rlp at once.
|
||||
//!
|
||||
//!### Use `UntrustedRlp` when:
|
||||
//!### Use `UntrustedRlp` when:
|
||||
//! * You are working on untrusted data (~corrupted).
|
||||
//! * You need to handle data corruption errors.
|
||||
//! * You are working on input data.
|
||||
@@ -47,14 +47,16 @@ pub use self::rlpstream::{RlpStream};
|
||||
use super::hash::H256;
|
||||
|
||||
pub const NULL_RLP: [u8; 1] = [0x80; 1];
|
||||
pub const EMPTY_LIST_RLP: [u8; 1] = [0xC0; 1];
|
||||
pub const SHA3_NULL_RLP: H256 = H256( [0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21] );
|
||||
pub const SHA3_EMPTY_LIST_RLP: H256 = H256( [0x1d, 0xcc, 0x4d, 0xe8, 0xde, 0xc7, 0x5d, 0x7a, 0xab, 0x85, 0xb5, 0x67, 0xb6, 0xcc, 0xd4, 0x1a, 0xd3, 0x12, 0x45, 0x1b, 0x94, 0x8a, 0x74, 0x13, 0xf0, 0xa1, 0x42, 0xfd, 0x40, 0xd4, 0x93, 0x47] );
|
||||
|
||||
/// Shortcut function to decode trusted rlp
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
|
||||
/// let animals: Vec<String> = decode(&data);
|
||||
@@ -71,7 +73,7 @@ pub fn decode<T>(bytes: &[u8]) -> T where T: Decodable {
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let animals = vec!["cat", "dog"];
|
||||
/// let out = encode(&animals);
|
||||
|
||||
@@ -29,8 +29,8 @@ impl<'a, 'view> View<'a, 'view> for Rlp<'a> where 'a: 'view {
|
||||
}
|
||||
}
|
||||
|
||||
fn raw(&'view self) -> &'a [u8] {
|
||||
self.rlp.raw()
|
||||
fn as_raw(&'view self) -> &'a [u8] {
|
||||
self.rlp.as_raw()
|
||||
}
|
||||
|
||||
fn prototype(&self) -> Self::Prototype {
|
||||
|
||||
@@ -26,7 +26,7 @@ pub struct RlpStream {
|
||||
}
|
||||
|
||||
impl Stream for RlpStream {
|
||||
fn new() -> Self {
|
||||
fn new() -> Self {
|
||||
RlpStream {
|
||||
unfinished_lists: ElasticArray16::new(),
|
||||
encoder: BasicEncoder::new(),
|
||||
@@ -57,7 +57,7 @@ impl Stream for RlpStream {
|
||||
self.encoder.bytes.push(0xc0u8);
|
||||
self.note_appended(1);
|
||||
},
|
||||
_ => {
|
||||
_ => {
|
||||
let position = self.encoder.bytes.len();
|
||||
self.unfinished_lists.push(ListInfo::new(position, len));
|
||||
},
|
||||
@@ -66,7 +66,7 @@ impl Stream for RlpStream {
|
||||
// return chainable self
|
||||
self
|
||||
}
|
||||
|
||||
|
||||
fn append_empty_data<'a>(&'a mut self) -> &'a mut RlpStream {
|
||||
// self push raw item
|
||||
self.encoder.bytes.push(0x80);
|
||||
@@ -80,7 +80,7 @@ impl Stream for RlpStream {
|
||||
|
||||
fn append_raw<'a>(&'a mut self, bytes: &[u8], item_count: usize) -> &'a mut RlpStream {
|
||||
// push raw items
|
||||
self.encoder.bytes.append_slice(bytes);
|
||||
self.encoder.bytes.append_slice(bytes);
|
||||
|
||||
// try to finish and prepend the length
|
||||
self.note_appended(item_count);
|
||||
@@ -101,7 +101,7 @@ impl Stream for RlpStream {
|
||||
self.unfinished_lists.len() == 0
|
||||
}
|
||||
|
||||
fn raw(&self) -> &[u8] {
|
||||
fn as_raw(&self) -> &[u8] {
|
||||
&self.encoder.bytes
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use rlp::DecoderError;
|
||||
use rlp::{DecoderError, UntrustedRlp};
|
||||
|
||||
pub trait Decoder: Sized {
|
||||
fn read_value<T, F>(&self, f: F) -> Result<T, DecoderError>
|
||||
where F: FnOnce(&[u8]) -> Result<T, DecoderError>;
|
||||
|
||||
fn as_list(&self) -> Result<Vec<Self>, DecoderError>;
|
||||
|
||||
fn as_rlp<'a>(&'a self) -> &'a UntrustedRlp<'a>;
|
||||
fn as_raw(&self) -> &[u8];
|
||||
}
|
||||
|
||||
@@ -24,19 +24,19 @@ pub trait View<'a, 'view>: Sized {
|
||||
fn new(bytes: &'a [u8]) -> Self;
|
||||
|
||||
/// The raw data of the RLP.
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
|
||||
/// let rlp = Rlp::new(&data);
|
||||
/// let dog = rlp.at(1).raw();
|
||||
/// let dog = rlp.at(1).as_raw();
|
||||
/// assert_eq!(dog, &[0x83, b'd', b'o', b'g']);
|
||||
/// }
|
||||
/// ```
|
||||
fn raw(&'view self) -> &'a [u8];
|
||||
fn as_raw(&'view self) -> &'a [u8];
|
||||
|
||||
/// Get the prototype of the RLP.
|
||||
fn prototype(&self) -> Self::Prototype;
|
||||
@@ -46,11 +46,11 @@ pub trait View<'a, 'view>: Sized {
|
||||
fn data(&'view self) -> Self::Data;
|
||||
|
||||
/// Returns number of RLP items.
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
|
||||
/// let rlp = Rlp::new(&data);
|
||||
@@ -62,11 +62,11 @@ pub trait View<'a, 'view>: Sized {
|
||||
fn item_count(&self) -> usize;
|
||||
|
||||
/// Returns the number of bytes in the data, or zero if it isn't data.
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
|
||||
/// let rlp = Rlp::new(&data);
|
||||
@@ -78,14 +78,14 @@ pub trait View<'a, 'view>: Sized {
|
||||
fn size(&self) -> usize;
|
||||
|
||||
/// Get view onto RLP-slice at index.
|
||||
///
|
||||
///
|
||||
/// Caches offset to given index, so access to successive
|
||||
/// slices is faster.
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
|
||||
/// let rlp = Rlp::new(&data);
|
||||
@@ -95,11 +95,11 @@ pub trait View<'a, 'view>: Sized {
|
||||
fn at(&'view self, index: usize) -> Self::Item;
|
||||
|
||||
/// No value
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let data = vec![];
|
||||
/// let rlp = Rlp::new(&data);
|
||||
@@ -109,11 +109,11 @@ pub trait View<'a, 'view>: Sized {
|
||||
fn is_null(&self) -> bool;
|
||||
|
||||
/// Contains a zero-length string or zero-length list.
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let data = vec![0xc0];
|
||||
/// let rlp = Rlp::new(&data);
|
||||
@@ -123,11 +123,11 @@ pub trait View<'a, 'view>: Sized {
|
||||
fn is_empty(&self) -> bool;
|
||||
|
||||
/// List value
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
|
||||
/// let rlp = Rlp::new(&data);
|
||||
@@ -137,11 +137,11 @@ pub trait View<'a, 'view>: Sized {
|
||||
fn is_list(&self) -> bool;
|
||||
|
||||
/// String value
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
|
||||
/// let rlp = Rlp::new(&data);
|
||||
@@ -151,11 +151,11 @@ pub trait View<'a, 'view>: Sized {
|
||||
fn is_data(&self) -> bool;
|
||||
|
||||
/// Int value
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let data = vec![0xc1, 0x10];
|
||||
/// let rlp = Rlp::new(&data);
|
||||
@@ -166,11 +166,11 @@ pub trait View<'a, 'view>: Sized {
|
||||
fn is_int(&self) -> bool;
|
||||
|
||||
/// Get iterator over rlp-slices
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
|
||||
/// let rlp = Rlp::new(&data);
|
||||
@@ -207,7 +207,7 @@ pub trait Stream: Sized {
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let mut stream = RlpStream::new_list(2);
|
||||
/// stream.append(&"cat").append(&"dog");
|
||||
@@ -222,11 +222,11 @@ pub trait Stream: Sized {
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let mut stream = RlpStream::new_list(2);
|
||||
/// stream.append_list(2).append(&"cat").append(&"dog");
|
||||
/// stream.append(&"");
|
||||
/// stream.append(&"");
|
||||
/// let out = stream.out();
|
||||
/// assert_eq!(out, vec![0xca, 0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g', 0x80]);
|
||||
/// }
|
||||
@@ -238,7 +238,7 @@ pub trait Stream: Sized {
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let mut stream = RlpStream::new_list(2);
|
||||
/// stream.append_empty_data().append_empty_data();
|
||||
@@ -252,11 +252,11 @@ pub trait Stream: Sized {
|
||||
fn append_raw<'a>(&'a mut self, bytes: &[u8], item_count: usize) -> &'a mut Self;
|
||||
|
||||
/// Clear the output stream so far.
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let mut stream = RlpStream::new_list(3);
|
||||
/// stream.append(&"cat");
|
||||
@@ -272,7 +272,7 @@ pub trait Stream: Sized {
|
||||
/// ```rust
|
||||
/// extern crate ethcore_util as util;
|
||||
/// use util::rlp::*;
|
||||
///
|
||||
///
|
||||
/// fn main () {
|
||||
/// let mut stream = RlpStream::new_list(2);
|
||||
/// stream.append(&"cat");
|
||||
@@ -284,10 +284,10 @@ pub trait Stream: Sized {
|
||||
/// }
|
||||
fn is_finished(&self) -> bool;
|
||||
|
||||
fn raw(&self) -> &[u8];
|
||||
fn as_raw(&self) -> &[u8];
|
||||
|
||||
/// Streams out encoded bytes.
|
||||
///
|
||||
///
|
||||
/// panic! if stream is not finished.
|
||||
fn out(self) -> Vec<u8>;
|
||||
}
|
||||
|
||||
@@ -19,19 +19,19 @@ fn rlp_at() {
|
||||
|
||||
let cat = rlp.at(0).unwrap();
|
||||
assert!(cat.is_data());
|
||||
assert_eq!(cat.raw(), &[0x83, b'c', b'a', b't']);
|
||||
assert_eq!(cat.as_raw(), &[0x83, b'c', b'a', b't']);
|
||||
//assert_eq!(String::decode_untrusted(&cat).unwrap(), "cat".to_string());
|
||||
assert_eq!(cat.as_val::<String>().unwrap(), "cat".to_string());
|
||||
|
||||
let dog = rlp.at(1).unwrap();
|
||||
assert!(dog.is_data());
|
||||
assert_eq!(dog.raw(), &[0x83, b'd', b'o', b'g']);
|
||||
assert_eq!(dog.as_raw(), &[0x83, b'd', b'o', b'g']);
|
||||
//assert_eq!(String::decode_untrusted(&dog).unwrap(), "dog".to_string());
|
||||
assert_eq!(dog.as_val::<String>().unwrap(), "dog".to_string());
|
||||
|
||||
let cat_again = rlp.at(0).unwrap();
|
||||
assert!(cat_again.is_data());
|
||||
assert_eq!(cat_again.raw(), &[0x83, b'c', b'a', b't']);
|
||||
assert_eq!(cat_again.as_raw(), &[0x83, b'c', b'a', b't']);
|
||||
//assert_eq!(String::decode_untrusted(&cat_again).unwrap(), "cat".to_string());
|
||||
assert_eq!(cat_again.as_val::<String>().unwrap(), "cat".to_string());
|
||||
}
|
||||
@@ -61,18 +61,18 @@ fn rlp_iter() {
|
||||
|
||||
let cat = iter.next().unwrap();
|
||||
assert!(cat.is_data());
|
||||
assert_eq!(cat.raw(), &[0x83, b'c', b'a', b't']);
|
||||
assert_eq!(cat.as_raw(), &[0x83, b'c', b'a', b't']);
|
||||
|
||||
let dog = iter.next().unwrap();
|
||||
assert!(dog.is_data());
|
||||
assert_eq!(dog.raw(), &[0x83, b'd', b'o', b'g']);
|
||||
assert_eq!(dog.as_raw(), &[0x83, b'd', b'o', b'g']);
|
||||
|
||||
let none = iter.next();
|
||||
assert!(none.is_none());
|
||||
|
||||
let cat_again = rlp.at(0).unwrap();
|
||||
assert!(cat_again.is_data());
|
||||
assert_eq!(cat_again.raw(), &[0x83, b'c', b'a', b't']);
|
||||
assert_eq!(cat_again.as_raw(), &[0x83, b'c', b'a', b't']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ fn encode_address() {
|
||||
use hash::*;
|
||||
|
||||
let tests = vec![
|
||||
ETestPair(Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap(),
|
||||
ETestPair(Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap(),
|
||||
vec![0x94, 0xef, 0x2d, 0x6d, 0x19, 0x40, 0x84, 0xc2, 0xde,
|
||||
0x36, 0xe0, 0xda, 0xbf, 0xce, 0x45, 0xd0, 0x46,
|
||||
0xb3, 0x7d, 0x11, 0x06])
|
||||
@@ -290,7 +290,7 @@ fn decode_untrusted_address() {
|
||||
use hash::*;
|
||||
|
||||
let tests = vec![
|
||||
DTestPair(Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap(),
|
||||
DTestPair(Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap(),
|
||||
vec![0x94, 0xef, 0x2d, 0x6d, 0x19, 0x40, 0x84, 0xc2, 0xde,
|
||||
0x36, 0xe0, 0xda, 0xbf, 0xce, 0x45, 0xd0, 0x46,
|
||||
0xb3, 0x7d, 0x11, 0x06])
|
||||
|
||||
@@ -41,22 +41,24 @@ impl PayloadInfo {
|
||||
}
|
||||
|
||||
/// Data-oriented view onto rlp-slice.
|
||||
///
|
||||
///
|
||||
/// This is immutable structere. No operations change it.
|
||||
///
|
||||
///
|
||||
/// Should be used in places where, error handling is required,
|
||||
/// eg. on input
|
||||
#[derive(Debug)]
|
||||
pub struct UntrustedRlp<'a> {
|
||||
bytes: &'a [u8],
|
||||
cache: Cell<OffsetCache>,
|
||||
offset_cache: Cell<OffsetCache>,
|
||||
count_cache: Cell<Option<usize>>,
|
||||
}
|
||||
|
||||
impl<'a> Clone for UntrustedRlp<'a> {
|
||||
fn clone(&self) -> UntrustedRlp<'a> {
|
||||
UntrustedRlp {
|
||||
bytes: self.bytes,
|
||||
cache: Cell::new(OffsetCache::new(usize::max_value(), 0))
|
||||
offset_cache: self.offset_cache.clone(),
|
||||
count_cache: self.count_cache.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,11 +74,12 @@ impl<'a, 'view> View<'a, 'view> for UntrustedRlp<'a> where 'a: 'view {
|
||||
fn new(bytes: &'a [u8]) -> UntrustedRlp<'a> {
|
||||
UntrustedRlp {
|
||||
bytes: bytes,
|
||||
cache: Cell::new(OffsetCache::new(usize::max_value(), 0)),
|
||||
offset_cache: Cell::new(OffsetCache::new(usize::max_value(), 0)),
|
||||
count_cache: Cell::new(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn raw(&'view self) -> &'a [u8] {
|
||||
|
||||
fn as_raw(&'view self) -> &'a [u8] {
|
||||
self.bytes
|
||||
}
|
||||
|
||||
@@ -102,7 +105,14 @@ impl<'a, 'view> View<'a, 'view> for UntrustedRlp<'a> where 'a: 'view {
|
||||
|
||||
fn item_count(&self) -> usize {
|
||||
match self.is_list() {
|
||||
true => self.iter().count(),
|
||||
true => match self.count_cache.get() {
|
||||
Some(c) => c,
|
||||
None => {
|
||||
let c = self.iter().count();
|
||||
self.count_cache.set(Some(c));
|
||||
c
|
||||
}
|
||||
},
|
||||
false => 0
|
||||
}
|
||||
}
|
||||
@@ -122,7 +132,7 @@ impl<'a, 'view> View<'a, 'view> for UntrustedRlp<'a> where 'a: 'view {
|
||||
|
||||
// move to cached position if it's index is less or equal to
|
||||
// current search index, otherwise move to beginning of list
|
||||
let c = self.cache.get();
|
||||
let c = self.offset_cache.get();
|
||||
let (mut bytes, to_skip) = match c.index <= index {
|
||||
true => (try!(UntrustedRlp::consume(self.bytes, c.offset)), index - c.index),
|
||||
false => (try!(self.consume_list_prefix()), index),
|
||||
@@ -132,7 +142,7 @@ impl<'a, 'view> View<'a, 'view> for UntrustedRlp<'a> where 'a: 'view {
|
||||
bytes = try!(UntrustedRlp::consume_items(bytes, to_skip));
|
||||
|
||||
// update the cache
|
||||
self.cache.set(OffsetCache::new(index, self.bytes.len() - bytes.len()));
|
||||
self.offset_cache.set(OffsetCache::new(index, self.bytes.len() - bytes.len()));
|
||||
|
||||
// construct new rlp
|
||||
let found = try!(BasicDecoder::payload_info(bytes));
|
||||
@@ -284,7 +294,7 @@ impl<'a> Decoder for BasicDecoder<'a> {
|
||||
fn read_value<T, F>(&self, f: F) -> Result<T, DecoderError>
|
||||
where F: FnOnce(&[u8]) -> Result<T, DecoderError> {
|
||||
|
||||
let bytes = self.rlp.raw();
|
||||
let bytes = self.rlp.as_raw();
|
||||
|
||||
match bytes.first().map(|&x| x) {
|
||||
// rlp is too short
|
||||
@@ -306,7 +316,7 @@ impl<'a> Decoder for BasicDecoder<'a> {
|
||||
}
|
||||
|
||||
fn as_raw(&self) -> &[u8] {
|
||||
self.rlp.raw()
|
||||
self.rlp.as_raw()
|
||||
}
|
||||
|
||||
fn as_list(&self) -> Result<Vec<Self>, DecoderError> {
|
||||
@@ -315,6 +325,10 @@ impl<'a> Decoder for BasicDecoder<'a> {
|
||||
.collect();
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
fn as_rlp<'s>(&'s self) -> &'s UntrustedRlp<'s> {
|
||||
&self.rlp
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Decodable for T where T: FromBytes {
|
||||
@@ -364,7 +378,7 @@ macro_rules! impl_array_decodable {
|
||||
if decoders.len() != $len {
|
||||
return Err(DecoderError::RlpIncorrectListLen);
|
||||
}
|
||||
|
||||
|
||||
for i in 0..decoders.len() {
|
||||
result[i] = try!(T::decode(&decoders[i]));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user