fixed encoding of bytes in rlp, fixed encoding of long lists, triehash + basic tests... more tests todo
This commit is contained in:
parent
d23b8d9a74
commit
0c9ef317b2
39
src/rlp.rs
39
src/rlp.rs
@ -456,9 +456,8 @@ impl RlpStream {
|
||||
}
|
||||
|
||||
/// Apends value to the end of stream, chainable.
|
||||
pub fn append<'a, E>(&'a mut self, object: &E) -> &'a mut RlpStream
|
||||
where E: Encodable
|
||||
{
|
||||
pub fn append<'a, E>(&'a mut self, object: &E) -> &'a mut RlpStream where E: Encodable + fmt::Debug {
|
||||
//println!("append: {:?}", object);
|
||||
// encode given value and add it at the end of the stream
|
||||
object.encode(&mut self.encoder);
|
||||
|
||||
@ -471,6 +470,7 @@ impl RlpStream {
|
||||
|
||||
/// Declare appending the list of given size, chainable.
|
||||
pub fn append_list<'a>(&'a mut self, len: usize) -> &'a mut RlpStream {
|
||||
//println!("append_list: {}", len);
|
||||
// push new list
|
||||
let position = self.encoder.bytes.len();
|
||||
match len {
|
||||
@ -488,6 +488,7 @@ impl RlpStream {
|
||||
|
||||
/// Appends raw (pre-serialised) RLP data. Use with caution. Chainable.
|
||||
pub fn append_raw<'a>(&'a mut self, bytes: &[u8], item_count: usize) -> &'a mut RlpStream {
|
||||
//println!("append_raw: {:?} len: {}, count: {}", bytes, bytes.len(), item_count);
|
||||
// push raw items
|
||||
self.encoder.bytes.extend(bytes);
|
||||
|
||||
@ -623,7 +624,7 @@ impl BasicEncoder {
|
||||
match len {
|
||||
0...55 => res.push(0xc0u8 + len as u8),
|
||||
_ => {
|
||||
res.push(0x7fu8 + len.to_bytes_len() as u8);
|
||||
res.push(0xf7u8 + len.to_bytes_len() as u8);
|
||||
res.extend(len.to_bytes());
|
||||
}
|
||||
};
|
||||
@ -658,8 +659,7 @@ impl Encoder for BasicEncoder {
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_list<F>(&mut self, f: F) -> ()
|
||||
where F: FnOnce(&mut Self) -> ()
|
||||
fn emit_list<F>(&mut self, f: F) -> () where F: FnOnce(&mut Self) -> ()
|
||||
{
|
||||
// get len before inserting a list
|
||||
let before_len = self.bytes.len();
|
||||
@ -891,6 +891,33 @@ mod tests {
|
||||
assert_eq!(out, vec![0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rlp_stream_list2() {
|
||||
let mut stream = RlpStream::new();
|
||||
stream.append_list(17);
|
||||
for _ in 0..17 {
|
||||
stream.append(&"");
|
||||
}
|
||||
let out = stream.out().unwrap();
|
||||
assert_eq!(out, vec![0xd1, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rlp_stream_list3() {
|
||||
let mut stream = RlpStream::new();
|
||||
stream.append_list(17);
|
||||
|
||||
let mut res = vec![0xf8, 0x44];
|
||||
for _ in 0..17 {
|
||||
stream.append(&"aaa");
|
||||
res.extend(vec![0x83, b'a', b'a', b'a']);
|
||||
}
|
||||
let out = stream.out().unwrap();
|
||||
assert_eq!(out, res);
|
||||
}
|
||||
|
||||
struct DTestPair<T>(T, Vec<u8>) where T: rlp::Decodable + fmt::Debug + cmp::Eq;
|
||||
|
||||
fn run_decode_tests<T>(tests: Vec<DTestPair<T>>) where T: rlp::Decodable + fmt::Debug + cmp::Eq {
|
||||
|
136
src/triehash.rs
136
src/triehash.rs
@ -139,6 +139,20 @@ impl NibblePair {
|
||||
}
|
||||
}
|
||||
|
||||
fn shared_nibble_prefix_len(vec: &[NibblePair]) -> usize {
|
||||
if vec.len() == 0 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
vec.iter()
|
||||
// skip first element
|
||||
.skip(1)
|
||||
// get minimum number of shared nibbles between first and each successive
|
||||
.fold(vec[0].nibble.len(), | acc, pair | {
|
||||
cmp::min(vec[0].nibble.shared_prefix_len(&pair.nibble), acc)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn ordered_trie_root(data: Vec<Vec<u8>>) -> H256 {
|
||||
let vec: Vec<NibblePair> = data
|
||||
// first put elements into btree to sort them by nibbles
|
||||
@ -167,7 +181,6 @@ pub fn hash256(vec: &[NibblePair]) -> H256 {
|
||||
}
|
||||
};
|
||||
|
||||
println!("out: {:?}", out);
|
||||
out.sha3()
|
||||
}
|
||||
|
||||
@ -182,13 +195,7 @@ fn hash256rlp(vec: &[NibblePair], pre_len: usize, stream: &mut RlpStream) {
|
||||
stream.append(&vec[0].data);
|
||||
},
|
||||
_ => {
|
||||
let shared_prefix = vec.iter()
|
||||
// skip first element
|
||||
.skip(1)
|
||||
// get minimum number of shared nibbles between first and each successive
|
||||
.fold(usize::max_value(), | acc, pair | {
|
||||
cmp::min(vec[0].nibble.shared_prefix_len(&pair.nibble), acc)
|
||||
});
|
||||
let shared_prefix = shared_nibble_prefix_len(vec);
|
||||
|
||||
match shared_prefix > pre_len {
|
||||
true => {
|
||||
@ -199,12 +206,12 @@ fn hash256rlp(vec: &[NibblePair], pre_len: usize, stream: &mut RlpStream) {
|
||||
false => {
|
||||
stream.append_list(17);
|
||||
|
||||
// every nibble is longer then previous one
|
||||
let iter = vec.iter()
|
||||
// move to first element with len different then pre_len
|
||||
.take_while(| pair | { pair.nibble.len() == pre_len });
|
||||
|
||||
let mut begin = iter.count();
|
||||
// if first nibble len is equal to pre_len
|
||||
// move forward
|
||||
let mut begin = match pre_len == vec[0].nibble.len() {
|
||||
true => 1,
|
||||
false => 0
|
||||
};
|
||||
|
||||
for i in 0..16 {
|
||||
// cout how many successive elements have same next nibble
|
||||
@ -214,14 +221,14 @@ fn hash256rlp(vec: &[NibblePair], pre_len: usize, stream: &mut RlpStream) {
|
||||
|
||||
match len {
|
||||
0 => { stream.append(&""); },
|
||||
_ => hash256aux(&vec[begin..begin + len], pre_len + 1, stream)
|
||||
_ => hash256aux(&vec[begin..(begin + len)], pre_len + 1, stream)
|
||||
}
|
||||
begin += len;
|
||||
}
|
||||
|
||||
match pre_len == vec[0].nibble.len() {
|
||||
true => stream.append(&vec[0].data),
|
||||
false => stream.append(&"")
|
||||
true => { stream.append(&vec[0].data); } ,
|
||||
false => { stream.append(&""); }
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -239,6 +246,39 @@ fn hash256aux(vec: &[NibblePair], pre_len: usize, stream: &mut RlpStream) {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_shared_nibble_len() {
|
||||
let len = shared_nibble_prefix_len(&vec![
|
||||
NibblePair::new(vec![0, 1, 2, 3, 4, 5, 6], vec![]),
|
||||
NibblePair::new(vec![0, 1, 2, 3, 4, 5, 6], vec![]),
|
||||
]);
|
||||
|
||||
assert_eq!(len , 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shared_nibble_len2() {
|
||||
let len = shared_nibble_prefix_len(&vec![
|
||||
NibblePair::new(vec![0, 1, 2, 3, 4, 5, 6], vec![]),
|
||||
NibblePair::new(vec![0, 1, 2, 3, 4, 5, 6], vec![]),
|
||||
NibblePair::new(vec![4, 1, 2, 3, 4, 5, 6], vec![])
|
||||
]);
|
||||
|
||||
assert_eq!(len , 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shared_nibble_len3() {
|
||||
let len = shared_nibble_prefix_len(&vec![
|
||||
NibblePair::new(vec![0, 1, 2, 3, 4, 5, 6], vec![]),
|
||||
NibblePair::new(vec![0, 1, 2, 3, 4, 5, 6], vec![]),
|
||||
NibblePair::new(vec![0, 1, 2, 4, 4, 5, 6], vec![])
|
||||
]);
|
||||
|
||||
assert_eq!(len , 3);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
@ -246,6 +286,8 @@ mod tests {
|
||||
use hash::*;
|
||||
use triehash::*;
|
||||
|
||||
|
||||
|
||||
#[test]
|
||||
fn empty_trie_root() {
|
||||
assert_eq!(hash256(&vec![]), H256::from_str("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").unwrap());
|
||||
@ -262,9 +304,60 @@ mod tests {
|
||||
assert_eq!(hash256(&v), H256::from_str("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn foo_trie_item() {
|
||||
|
||||
let v = vec![
|
||||
NibblePair::new_raw(From::from("foo"),
|
||||
From::from("bar")),
|
||||
NibblePair::new_raw(From::from("food"),
|
||||
From::from("bass"))
|
||||
];
|
||||
|
||||
assert_eq!(hash256(&v), H256::from_str("17beaa1648bafa633cda809c90c04af50fc8aed3cb40d16efbddee6fdf63c4c3").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dogs_trie_item() {
|
||||
|
||||
let v = vec![
|
||||
NibblePair::new_raw(From::from("doe"),
|
||||
From::from("reindeer")),
|
||||
|
||||
NibblePair::new_raw(From::from("dog"),
|
||||
From::from("puppy")),
|
||||
|
||||
NibblePair::new_raw(From::from("dogglesworth"),
|
||||
From::from("cat")),
|
||||
];
|
||||
|
||||
assert_eq!(hash256(&v), H256::from_str("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn puppy_trie_items() {
|
||||
|
||||
let v = vec![
|
||||
NibblePair::new_raw(From::from("do"),
|
||||
From::from("verb")),
|
||||
|
||||
NibblePair::new_raw(From::from("dog"),
|
||||
From::from("puppy")),
|
||||
|
||||
NibblePair::new_raw(From::from("doge"),
|
||||
From::from("coin")),
|
||||
|
||||
NibblePair::new_raw(From::from("horse"),
|
||||
From::from("stallion")),
|
||||
|
||||
];
|
||||
|
||||
assert_eq!(hash256(&v), H256::from_str("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trie_root() {
|
||||
let _v = vec![
|
||||
let v = vec![
|
||||
NibblePair::new_raw("0000000000000000000000000000000000000000000000000000000000000045".from_hex().unwrap(),
|
||||
"22b224a1420a802ab51d326e29fa98e34c4f24ea".from_hex().unwrap()),
|
||||
|
||||
@ -290,10 +383,9 @@ mod tests {
|
||||
"697c7b8c961b56f675d570498424ac8de1a918f6".from_hex().unwrap())
|
||||
];
|
||||
|
||||
let _root = H256::from_str("9f6221ebb8efe7cff60a716ecb886e67dd042014be444669f0159d8e68b42100").unwrap();
|
||||
let root = H256::from_str("9f6221ebb8efe7cff60a716ecb886e67dd042014be444669f0159d8e68b42100").unwrap();
|
||||
|
||||
//let res = hash256(&v);
|
||||
//println!("{:?}", res);
|
||||
//assert_eq!(res, root);
|
||||
let res = hash256(&v);
|
||||
assert_eq!(res, root);
|
||||
}
|
||||
}
|
||||
|
@ -64,8 +64,22 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_shared_prefix() {
|
||||
let a = vec![1,2,3,4,5,6];
|
||||
let b = vec![4,2,3,4,5,6];
|
||||
assert_eq!(a.shared_prefix_len(&b), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shared_prefix2() {
|
||||
let a = vec![1,2,3,3,5];
|
||||
let b = vec![1,2,3];
|
||||
assert_eq!(a.shared_prefix_len(&b), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shared_prefix3() {
|
||||
let a = vec![1,2,3,4,5,6];
|
||||
let b = vec![1,2,3,4,5,6];
|
||||
assert_eq!(a.shared_prefix_len(&b), 6);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user