openethereum/util/rlp/tests/tests.rs

427 lines
12 KiB
Rust
Raw Normal View History

2017-05-10 12:52:09 +02:00
// Copyright 2015-2017 Parity Technologies
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
2016-02-05 13:40:41 +01:00
extern crate ethereum_types as bigint;
extern crate rlp;
2015-12-08 12:59:19 +01:00
use std::{fmt, cmp};
use bigint::{U256, H160};
use rlp::{Encodable, Decodable, Rlp, RlpStream, DecoderError};
2015-12-08 12:59:19 +01:00
#[test]
fn rlp_at() {
let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
{
let rlp = Rlp::new(&data);
2015-12-08 12:59:19 +01:00
assert!(rlp.is_list());
let animals: Vec<String> = rlp.as_list().unwrap();
2016-01-19 13:47:30 +01:00
assert_eq!(animals, vec!["cat".to_owned(), "dog".to_owned()]);
2015-12-08 12:59:19 +01:00
let cat = rlp.at(0).unwrap();
assert!(cat.is_data());
2016-01-08 15:52:43 +01:00
assert_eq!(cat.as_raw(), &[0x83, b'c', b'a', b't']);
2016-01-19 13:47:30 +01:00
assert_eq!(cat.as_val::<String>().unwrap(), "cat".to_owned());
2015-12-08 12:59:19 +01:00
let dog = rlp.at(1).unwrap();
assert!(dog.is_data());
2016-01-08 15:52:43 +01:00
assert_eq!(dog.as_raw(), &[0x83, b'd', b'o', b'g']);
2016-01-19 13:47:30 +01:00
assert_eq!(dog.as_val::<String>().unwrap(), "dog".to_owned());
2015-12-08 12:59:19 +01:00
let cat_again = rlp.at(0).unwrap();
assert!(cat_again.is_data());
2016-01-08 15:52:43 +01:00
assert_eq!(cat_again.as_raw(), &[0x83, b'c', b'a', b't']);
2016-01-19 13:47:30 +01:00
assert_eq!(cat_again.as_val::<String>().unwrap(), "cat".to_owned());
2015-12-08 12:59:19 +01:00
}
}
#[test]
fn rlp_at_err() {
let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o'];
{
let rlp = Rlp::new(&data);
2015-12-08 12:59:19 +01:00
assert!(rlp.is_list());
let cat_err = rlp.at(0).unwrap_err();
assert_eq!(cat_err, DecoderError::RlpIsTooShort);
2015-12-08 12:59:19 +01:00
let dog_err = rlp.at(1).unwrap_err();
assert_eq!(dog_err, DecoderError::RlpIsTooShort);
2015-12-08 12:59:19 +01:00
}
}
#[test]
fn rlp_iter() {
let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
{
let rlp = Rlp::new(&data);
2015-12-08 12:59:19 +01:00
let mut iter = rlp.iter();
let cat = iter.next().unwrap();
assert!(cat.is_data());
2016-01-08 15:52:43 +01:00
assert_eq!(cat.as_raw(), &[0x83, b'c', b'a', b't']);
2015-12-08 12:59:19 +01:00
let dog = iter.next().unwrap();
assert!(dog.is_data());
2016-01-08 15:52:43 +01:00
assert_eq!(dog.as_raw(), &[0x83, b'd', b'o', b'g']);
2015-12-08 12:59:19 +01:00
let none = iter.next();
assert!(none.is_none());
let cat_again = rlp.at(0).unwrap();
assert!(cat_again.is_data());
2016-01-08 15:52:43 +01:00
assert_eq!(cat_again.as_raw(), &[0x83, b'c', b'a', b't']);
2015-12-08 12:59:19 +01:00
}
}
struct ETestPair<T>(T, Vec<u8>) where T: Encodable;
2015-12-08 12:59:19 +01:00
fn run_encode_tests<T>(tests: Vec<ETestPair<T>>)
where T: Encodable
2015-12-08 12:59:19 +01:00
{
for t in &tests {
let res = rlp::encode(&t.0);
2016-01-27 12:14:57 +01:00
assert_eq!(&res[..], &t.1[..]);
}
}
struct VETestPair<T>(Vec<T>, Vec<u8>) where T: Encodable;
fn run_encode_tests_list<T>(tests: Vec<VETestPair<T>>)
where T: Encodable
{
for t in &tests {
let res = rlp::encode_list(&t.0);
assert_eq!(&res[..], &t.1[..]);
}
}
2015-12-08 12:59:19 +01:00
#[test]
fn encode_u16() {
let tests = vec![
ETestPair(0u16, vec![0x80u8]),
ETestPair(0x100, vec![0x82, 0x01, 0x00]),
ETestPair(0xffff, vec![0x82, 0xff, 0xff]),
];
run_encode_tests(tests);
}
#[test]
fn encode_u32() {
let tests = vec![
ETestPair(0u32, vec![0x80u8]),
ETestPair(0x10000, vec![0x83, 0x01, 0x00, 0x00]),
ETestPair(0xffffff, vec![0x83, 0xff, 0xff, 0xff]),
];
run_encode_tests(tests);
}
#[test]
fn encode_u64() {
let tests = vec![
ETestPair(0u64, vec![0x80u8]),
ETestPair(0x1000000, vec![0x84, 0x01, 0x00, 0x00, 0x00]),
ETestPair(0xFFFFFFFF, vec![0x84, 0xff, 0xff, 0xff, 0xff]),
];
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(),
2015-12-08 12:59:19 +01:00
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']),
ETestPair("dog", vec![0x83, b'd', b'o', b'g']),
ETestPair("Marek", vec![0x85, b'M', b'a', b'r', b'e', b'k']),
ETestPair("", vec![0x80]),
ETestPair("Lorem ipsum dolor sit amet, consectetur adipisicing elit",
vec![0xb8, 0x38, b'L', b'o', b'r', b'e', b'm', b' ', b'i',
b'p', b's', b'u', b'm', b' ', b'd', b'o', b'l', b'o',
b'r', b' ', b's', b'i', b't', b' ', b'a', b'm', b'e',
b't', b',', b' ', b'c', b'o', b'n', b's', b'e', b'c',
b't', b'e', b't', b'u', b'r', b' ', b'a', b'd', b'i',
b'p', b'i', b's', b'i', b'c', b'i', b'n', b'g', b' ',
b'e', b'l', b'i', b't'])];
run_encode_tests(tests);
}
#[test]
fn encode_address() {
let tests = vec![
ETestPair(H160::from("ef2d6d194084c2de36e0dabfce45d046b37d1106"),
2015-12-08 12:59:19 +01:00
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<u8> (Bytes) is treated as a single value
#[test]
fn encode_vector_u8() {
let tests = vec![
ETestPair(vec![], vec![0x80]),
ETestPair(vec![0u8], vec![0]),
ETestPair(vec![0x15], vec![0x15]),
ETestPair(vec![0x40, 0x00], vec![0x82, 0x40, 0x00]),
];
run_encode_tests(tests);
}
#[test]
fn encode_vector_u64() {
let tests = vec![
VETestPair(vec![], vec![0xc0]),
VETestPair(vec![15u64], vec![0xc1, 0x0f]),
VETestPair(vec![1, 2, 3, 7, 0xff], vec![0xc6, 1, 2, 3, 7, 0x81, 0xff]),
VETestPair(vec![0xffffffff, 1, 2, 3, 7, 0xff], vec![0xcb, 0x84, 0xff, 0xff, 0xff, 0xff, 1, 2, 3, 7, 0x81, 0xff]),
2015-12-08 12:59:19 +01:00
];
run_encode_tests_list(tests);
2015-12-08 12:59:19 +01:00
}
#[test]
fn encode_vector_str() {
let tests = vec![VETestPair(vec!["cat", "dog"],
2015-12-08 12:59:19 +01:00
vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'])];
run_encode_tests_list(tests);
2015-12-08 12:59:19 +01:00
}
struct DTestPair<T>(T, Vec<u8>) where T: Decodable + fmt::Debug + cmp::Eq;
struct VDTestPair<T>(Vec<T>, Vec<u8>) where T: Decodable + fmt::Debug + cmp::Eq;
fn run_decode_tests<T>(tests: Vec<DTestPair<T>>) where T: Decodable + fmt::Debug + cmp::Eq {
for t in &tests {
[beta] Backports (#8624) * Trace precompiled contracts when the transfer value is not zero (#8486) * Trace precompiled contracts when the transfer value is not zero * Add tests for precompiled CALL tracing * Use byzantium test machine for the new test * Add notes in comments on why we don't trace all precompileds * Use is_transferred instead of transferred * Return error if RLP size of transaction exceeds the limit (#8473) * Return error if RLP size of transaction exceeds the limit * Review comments fixed * RLP check moved to verifier, corresponding pool test added * Don't block sync when importing old blocks (#8530) * Alter IO queueing. * Don't require IoMessages to be Clone * Ancient blocks imported via IoChannel. * Get rid of private transactions io message. * Get rid of deadlock and fix disconnected handler. * Revert to old disconnect condition. * Fix tests. * Fix deadlock. * Refactoring `ethcore-sync` - Fixing warp-sync barrier (#8543) * Start dividing sync chain : first supplier method * WIP - updated chain sync supplier * Finish refactoring the Chain Sync Supplier * Create Chain Sync Requester * Add Propagator for Chain Sync * Add the Chain Sync Handler * Move tests from mod -> handler * Move tests to propagator * Refactor SyncRequester arguments * Refactoring peer fork header handler * Fix wrong highest block number in snapshot sync * Small refactor... * Address PR grumbles * Retry failed CI job * Fix tests * PR Grumbles * Handle socket address parsing errors (#8545) Unpack errors and check for io::ErrorKind::InvalidInput and return our own AddressParse error. Remove the foreign link to std::net::AddrParseError and add an `impl From` for that error. Test parsing properly. * Fix packet count when talking with PAR2 peers (#8555) * Support diferent packet counts in different protocol versions. * Fix light timeouts and eclipse protection. * Fix devp2p tests. * Fix whisper-cli compilation. * Fix compilation. * Fix ethcore-sync tests. * Revert "Fix light timeouts and eclipse protection." This reverts commit 06285ea8c1d9d184d809f64b5507aece633da6cc. * Increase timeouts. * Add whisper CLI to the pipelines (#8578) * Add whisper CLI to the pipelines * Address todo, ref #8579 * Rename `whisper-cli binary` to `whisper` (#8579) * rename whisper-cli binary to whisper * fix tests * Remove manually added text to the errors (#8595) These messages were confusing for the users especially the help message. * Fix account list double 0x display (#8596) * Remove unused self import * Fix account list double 0x display * Fix BlockReward contract "arithmetic operation overflow" (#8611) * Fix BlockReward contract "arithmetic operation overflow" * Add docs on how execute_as_system works * Fix typo * Rlp decode returns Result (#8527) rlp::decode returns Result Make a best effort to handle decoding errors gracefully throughout the code, using `expect` where the value is guaranteed to be valid (and in other places where it makes sense). * Remove expect (#8536) * Remove expect and propagate rlp::DecoderErrors as TrieErrors * Decoding headers can fail (#8570) * rlp::decode returns Result * Fix journaldb to handle rlp::decode Result * Fix ethcore to work with rlp::decode returning Result * Light client handles rlp::decode returning Result * Fix tests in rlp_derive * Fix tests * Cleanup * cleanup * Allow panic rather than breaking out of iterator * Let decoding failures when reading from disk blow up * syntax * Fix the trivial grumbles * Fix failing tests * Make Account::from_rlp return Result * Syntx, sigh * Temp-fix for decoding failures * Header::decode returns Result Handle new return type throughout the code base. * Do not continue reading from the DB when a value could not be read * Fix tests * Handle header decoding in light_sync * Handling header decoding errors * Let the DecodeError bubble up unchanged * Remove redundant error conversion * fix compiler warning (#8590) * Attempt to fix intermittent test failures (#8584) Occasionally should_return_correct_nonces_when_dropped_because_of_limit fails, possibly because of multiple threads competing to finish. See CI logs here for an example: https://gitlab.parity.io/parity/parity/-/jobs/86738 * block_header can fail so return Result (#8581) * block_header can fail so return Result * Restore previous return type based on feedback * Fix failing doc tests running on non-code * Block::decode() returns Result (#8586) * Gitlab test script fixes (#8573) * Exclude /docs from modified files. * Ensure all references in the working tree are available * Remove duplicated line from test script
2018-05-15 07:41:30 +02:00
let res : Result<T, DecoderError> = rlp::decode(&t.1);
assert!(res.is_ok());
let res = res.unwrap();
assert_eq!(&res, &t.0);
}
}
2015-12-08 12:59:19 +01:00
fn run_decode_tests_list<T>(tests: Vec<VDTestPair<T>>) where T: Decodable + fmt::Debug + cmp::Eq {
2015-12-08 12:59:19 +01:00
for t in &tests {
let res: Vec<T> = rlp::decode_list(&t.1);
2015-12-08 12:59:19 +01:00
assert_eq!(res, t.0);
}
}
/// Vec<u8> (Bytes) is treated as a single value
#[test]
fn decode_vector_u8() {
let tests = vec![
DTestPair(vec![], vec![0x80]),
DTestPair(vec![0u8], vec![0]),
DTestPair(vec![0x15], vec![0x15]),
DTestPair(vec![0x40, 0x00], vec![0x82, 0x40, 0x00]),
];
run_decode_tests(tests);
}
2016-01-29 13:59:29 +01:00
#[test]
fn decode_untrusted_u8() {
let tests = vec![
DTestPair(0x0u8, vec![0x80]),
DTestPair(0x77u8, vec![0x77]),
DTestPair(0xccu8, vec![0x81, 0xcc]),
];
run_decode_tests(tests);
}
2015-12-08 12:59:19 +01:00
#[test]
fn decode_untrusted_u16() {
let tests = vec![
2016-01-28 20:13:05 +01:00
DTestPair(0x100u16, vec![0x82, 0x01, 0x00]),
DTestPair(0xffffu16, vec![0x82, 0xff, 0xff]),
2015-12-08 12:59:19 +01:00
];
run_decode_tests(tests);
}
#[test]
fn decode_untrusted_u32() {
let tests = vec![
2016-01-28 20:13:05 +01:00
DTestPair(0x10000u32, vec![0x83, 0x01, 0x00, 0x00]),
DTestPair(0xffffffu32, vec![0x83, 0xff, 0xff, 0xff]),
2015-12-08 12:59:19 +01:00
];
run_decode_tests(tests);
}
#[test]
fn decode_untrusted_u64() {
let tests = vec![
2016-01-28 20:13:05 +01:00
DTestPair(0x1000000u64, vec![0x84, 0x01, 0x00, 0x00, 0x00]),
DTestPair(0xFFFFFFFFu64, vec![0x84, 0xff, 0xff, 0xff, 0xff]),
2015-12-08 12:59:19 +01:00
];
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(),
2015-12-08 12:59:19 +01:00
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() {
2016-01-19 13:47:30 +01:00
let tests = vec![DTestPair("cat".to_owned(), vec![0x83, b'c', b'a', b't']),
DTestPair("dog".to_owned(), vec![0x83, b'd', b'o', b'g']),
DTestPair("Marek".to_owned(),
2015-12-08 12:59:19 +01:00
vec![0x85, b'M', b'a', b'r', b'e', b'k']),
2016-01-19 13:47:30 +01:00
DTestPair("".to_owned(), vec![0x80]),
2015-12-08 12:59:19 +01:00
DTestPair("Lorem ipsum dolor sit amet, consectetur adipisicing elit"
2016-01-19 13:47:30 +01:00
.to_owned(),
2015-12-08 12:59:19 +01:00
vec![0xb8, 0x38, b'L', b'o', b'r', b'e', b'm', b' ', b'i',
b'p', b's', b'u', b'm', b' ', b'd', b'o', b'l', b'o',
b'r', b' ', b's', b'i', b't', b' ', b'a', b'm', b'e',
b't', b',', b' ', b'c', b'o', b'n', b's', b'e', b'c',
b't', b'e', b't', b'u', b'r', b' ', b'a', b'd', b'i',
b'p', b'i', b's', b'i', b'c', b'i', b'n', b'g', b' ',
b'e', b'l', b'i', b't'])];
run_decode_tests(tests);
}
#[test]
fn decode_untrusted_address() {
let tests = vec![
DTestPair(H160::from("ef2d6d194084c2de36e0dabfce45d046b37d1106"),
2015-12-08 12:59:19 +01:00
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![
VDTestPair(vec![], vec![0xc0]),
VDTestPair(vec![15u64], vec![0xc1, 0x0f]),
VDTestPair(vec![1, 2, 3, 7, 0xff], vec![0xc6, 1, 2, 3, 7, 0x81, 0xff]),
VDTestPair(vec![0xffffffff, 1, 2, 3, 7, 0xff], vec![0xcb, 0x84, 0xff, 0xff, 0xff, 0xff, 1, 2, 3, 7, 0x81, 0xff]),
2015-12-08 12:59:19 +01:00
];
run_decode_tests_list(tests);
2015-12-08 12:59:19 +01:00
}
#[test]
fn decode_untrusted_vector_str() {
let tests = vec![VDTestPair(vec!["cat".to_owned(), "dog".to_owned()],
2015-12-08 12:59:19 +01:00
vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'])];
run_decode_tests_list(tests);
2015-12-14 11:56:11 +01:00
}
2016-01-25 13:23:05 +01:00
#[test]
fn test_rlp_data_length_check()
{
let data = vec![0x84, b'c', b'a', b't'];
let rlp = Rlp::new(&data);
2016-01-25 13:23:05 +01:00
2016-01-25 14:27:11 +01:00
let as_val: Result<String, DecoderError> = rlp.as_val();
assert_eq!(Err(DecoderError::RlpInconsistentLengthAndData), as_val);
}
#[test]
fn test_rlp_long_data_length_check()
{
let mut data: Vec<u8> = vec![0xb8, 255];
for _ in 0..253 {
data.push(b'c');
}
let rlp = Rlp::new(&data);
2016-01-25 14:27:11 +01:00
2016-01-25 13:23:05 +01:00
let as_val: Result<String, DecoderError> = rlp.as_val();
assert_eq!(Err(DecoderError::RlpInconsistentLengthAndData), as_val);
2016-01-25 15:47:13 +01:00
}
#[test]
fn test_the_exact_long_string()
{
let mut data: Vec<u8> = vec![0xb8, 255];
for _ in 0..255 {
data.push(b'c');
}
let rlp = Rlp::new(&data);
2016-01-25 15:47:13 +01:00
let as_val: Result<String, DecoderError> = rlp.as_val();
assert!(as_val.is_ok());
2016-01-25 16:13:36 +01:00
}
#[test]
fn test_rlp_2bytes_data_length_check()
{
let mut data: Vec<u8> = vec![0xb9, 2, 255]; // 512+255
for _ in 0..700 {
data.push(b'c');
}
let rlp = Rlp::new(&data);
2016-01-25 16:13:36 +01:00
let as_val: Result<String, DecoderError> = rlp.as_val();
assert_eq!(Err(DecoderError::RlpInconsistentLengthAndData), as_val);
}
2016-02-01 01:06:21 +01:00
#[test]
fn test_rlp_nested_empty_list_encode() {
let mut stream = RlpStream::new_list(2);
stream.append_list(&(Vec::new() as Vec<u32>));
2016-02-01 01:06:21 +01:00
stream.append(&40u32);
assert_eq!(stream.drain()[..], [0xc2u8, 0xc0u8, 40u8][..]);
}
#[test]
fn test_rlp_list_length_overflow() {
let data: Vec<u8> = vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00];
let rlp = Rlp::new(&data);
let as_val: Result<String, DecoderError> = rlp.val_at(0);
assert_eq!(Err(DecoderError::RlpIsTooShort), as_val);
}
2017-03-28 16:23:09 +02:00
#[test]
fn test_rlp_stream_size_limit() {
for limit in 40 .. 270 {
let item = [0u8; 1];
let mut stream = RlpStream::new();
while stream.append_raw_checked(&item, 1, limit) {}
assert_eq!(stream.drain().len(), limit);
}
}
#[test]
fn test_rlp_stream_unbounded_list() {
let mut stream = RlpStream::new();
stream.begin_unbounded_list();
stream.append(&40u32);
stream.append(&41u32);
assert!(!stream.is_finished());
stream.complete_unbounded_list();
assert!(stream.is_finished());
}