light: tests for response module
This commit is contained in:
parent
887bcfb88a
commit
0d466fa8d0
@ -21,10 +21,10 @@ use std::fmt;
|
|||||||
use ethcore::header::Header;
|
use ethcore::header::Header;
|
||||||
use light::request::{HashOrNumber, Headers as HeadersRequest};
|
use light::request::{HashOrNumber, Headers as HeadersRequest};
|
||||||
use rlp::{DecoderError, UntrustedRlp, View};
|
use rlp::{DecoderError, UntrustedRlp, View};
|
||||||
use util::H256;
|
use util::{Bytes, H256};
|
||||||
|
|
||||||
/// Errors found when decoding headers and verifying with basic constraints.
|
/// Errors found when decoding headers and verifying with basic constraints.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum BasicError {
|
pub enum BasicError {
|
||||||
/// Wrong skip value: expected, found (if any).
|
/// Wrong skip value: expected, found (if any).
|
||||||
WrongSkip(u64, Option<u64>),
|
WrongSkip(u64, Option<u64>),
|
||||||
@ -46,7 +46,7 @@ impl From<DecoderError> for BasicError {
|
|||||||
|
|
||||||
impl fmt::Display for BasicError {
|
impl fmt::Display for BasicError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "Header response verification error: ");
|
try!(write!(f, "Header response verification error: "));
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
BasicError::WrongSkip(ref exp, ref got)
|
BasicError::WrongSkip(ref exp, ref got)
|
||||||
@ -58,7 +58,7 @@ impl fmt::Display for BasicError {
|
|||||||
BasicError::TooManyHeaders(ref max, ref got)
|
BasicError::TooManyHeaders(ref max, ref got)
|
||||||
=> write!(f, "too many headers (max {}, got {})", max, got),
|
=> write!(f, "too many headers (max {}, got {})", max, got),
|
||||||
BasicError::Decoder(ref err)
|
BasicError::Decoder(ref err)
|
||||||
=> write!(f, "invalid encoding ({})", err),
|
=> write!(f, "{}", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ pub trait Constraint {
|
|||||||
|
|
||||||
/// Decode a response and do basic verification against a request.
|
/// Decode a response and do basic verification against a request.
|
||||||
pub fn decode_and_verify(headers: &[Bytes], request: &HeadersRequest) -> Result<Vec<Header>, BasicError> {
|
pub fn decode_and_verify(headers: &[Bytes], request: &HeadersRequest) -> Result<Vec<Header>, BasicError> {
|
||||||
let headers: Vec<_> = try!!(headers.iter().map(|x| UntrustedRlp::new(&x).as_val()).collect());
|
let headers: Vec<_> = try!(headers.iter().map(|x| UntrustedRlp::new(&x).as_val()).collect());
|
||||||
|
|
||||||
let reverse = request.reverse;
|
let reverse = request.reverse;
|
||||||
|
|
||||||
@ -84,6 +84,8 @@ pub fn decode_and_verify(headers: &[Bytes], request: &HeadersRequest) -> Result<
|
|||||||
}
|
}
|
||||||
|
|
||||||
try!(SkipsBetween(request.skip).verify(&headers, reverse));
|
try!(SkipsBetween(request.skip).verify(&headers, reverse));
|
||||||
|
|
||||||
|
Ok(headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StartsAtNumber(u64);
|
struct StartsAtNumber(u64);
|
||||||
@ -150,3 +152,107 @@ impl Constraint for Max {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use ethcore::header::Header;
|
||||||
|
use light::request::Headers as HeadersRequest;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sequential_forward() {
|
||||||
|
let request = HeadersRequest {
|
||||||
|
start: 10.into(),
|
||||||
|
max: 30,
|
||||||
|
skip: 0,
|
||||||
|
reverse: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut parent_hash = None;
|
||||||
|
let headers: Vec<_> = (0..25).map(|x| x + 10).map(|x| {
|
||||||
|
let mut header = Header::default();
|
||||||
|
header.set_number(x);
|
||||||
|
|
||||||
|
if let Some(parent_hash) = parent_hash {
|
||||||
|
header.set_parent_hash(parent_hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent_hash = Some(header.hash());
|
||||||
|
|
||||||
|
::rlp::encode(&header).to_vec()
|
||||||
|
}).collect();
|
||||||
|
|
||||||
|
assert!(decode_and_verify(&headers, &request).is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sequential_backward() {
|
||||||
|
let request = HeadersRequest {
|
||||||
|
start: 10.into(),
|
||||||
|
max: 30,
|
||||||
|
skip: 0,
|
||||||
|
reverse: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut parent_hash = None;
|
||||||
|
let headers: Vec<_> = (0..25).map(|x| x + 10).rev().map(|x| {
|
||||||
|
let mut header = Header::default();
|
||||||
|
header.set_number(x);
|
||||||
|
|
||||||
|
if let Some(parent_hash) = parent_hash {
|
||||||
|
header.set_parent_hash(parent_hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent_hash = Some(header.hash());
|
||||||
|
|
||||||
|
::rlp::encode(&header).to_vec()
|
||||||
|
}).collect();
|
||||||
|
|
||||||
|
assert!(decode_and_verify(&headers, &request).is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn too_many() {
|
||||||
|
let request = HeadersRequest {
|
||||||
|
start: 10.into(),
|
||||||
|
max: 20,
|
||||||
|
skip: 0,
|
||||||
|
reverse: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut parent_hash = None;
|
||||||
|
let headers: Vec<_> = (0..25).map(|x| x + 10).map(|x| {
|
||||||
|
let mut header = Header::default();
|
||||||
|
header.set_number(x);
|
||||||
|
|
||||||
|
if let Some(parent_hash) = parent_hash {
|
||||||
|
header.set_parent_hash(parent_hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent_hash = Some(header.hash());
|
||||||
|
|
||||||
|
::rlp::encode(&header).to_vec()
|
||||||
|
}).collect();
|
||||||
|
|
||||||
|
assert_eq!(decode_and_verify(&headers, &request), Err(BasicError::TooManyHeaders(20, 25)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn wrong_skip() {
|
||||||
|
let request = HeadersRequest {
|
||||||
|
start: 10.into(),
|
||||||
|
max: 30,
|
||||||
|
skip: 5,
|
||||||
|
reverse: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let headers: Vec<_> = (0..25).map(|x| x * 3).map(|x| x + 10).map(|x| {
|
||||||
|
let mut header = Header::default();
|
||||||
|
header.set_number(x);
|
||||||
|
|
||||||
|
::rlp::encode(&header).to_vec()
|
||||||
|
}).collect();
|
||||||
|
|
||||||
|
assert_eq!(decode_and_verify(&headers, &request), Err(BasicError::WrongSkip(5, Some(2))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user