Tweak some checks. (#4633)

* Tweak some checks.

* Fixed build and added a difficulty test
This commit is contained in:
Gav Wood 2017-02-22 18:24:22 +01:00 committed by GitHub
parent f3b5e2074b
commit 3182540d9f
4 changed files with 28 additions and 8 deletions

View File

@ -835,4 +835,22 @@ mod tests {
ethash.populate_from_parent(&mut header, &parent, U256::from(150_000), U256::from(150_002)); ethash.populate_from_parent(&mut header, &parent, U256::from(150_000), U256::from(150_002));
assert_eq!(*header.gas_limit(), U256::from(150_002)); assert_eq!(*header.gas_limit(), U256::from(150_002));
} }
#[test]
fn difficulty_max_timestamp() {
let spec = new_homestead_test();
let ethparams = get_default_ethash_params();
let ethash = Ethash::new(spec.params, ethparams, BTreeMap::new());
let mut parent_header = Header::default();
parent_header.set_number(1000000);
parent_header.set_difficulty(U256::from_str("b69de81a22b").unwrap());
parent_header.set_timestamp(1455404053);
let mut header = Header::default();
header.set_number(parent_header.number() + 1);
header.set_timestamp(u64::max_value());
let difficulty = ethash.calculate_difficulty(&header, &parent_header);
assert_eq!(U256::from(12543204905719u64), difficulty);
}
} }

View File

@ -276,7 +276,7 @@ impl Decodable for Header {
number: r.val_at(8)?, number: r.val_at(8)?,
gas_limit: r.val_at(9)?, gas_limit: r.val_at(9)?,
gas_used: r.val_at(10)?, gas_used: r.val_at(10)?,
timestamp: r.val_at(11)?, timestamp: min(r.val_at::<U256>(11)?, u64::max_value().into()).as_u64(),
extra_data: r.val_at(12)?, extra_data: r.val_at(12)?,
seal: vec![], seal: vec![],
hash: RefCell::new(Some(r.as_raw().sha3())), hash: RefCell::new(Some(r.as_raw().sha3())),

View File

@ -185,7 +185,7 @@ pub mod headers {
type Verified = Header; type Verified = Header;
fn create(input: Self::Input, engine: &Engine) -> Result<Self::Unverified, Error> { fn create(input: Self::Input, engine: &Engine) -> Result<Self::Unverified, Error> {
verify_header_params(&input, engine).map(|_| input) verify_header_params(&input, engine, true).map(|_| input)
} }
fn verify(unverified: Self::Unverified, engine: &Engine, check_seal: bool) -> Result<Self::Verified, Error> { fn verify(unverified: Self::Unverified, engine: &Engine, check_seal: bool) -> Result<Self::Verified, Error> {

View File

@ -51,12 +51,12 @@ impl HeapSizeOf for PreverifiedBlock {
/// Phase 1 quick block verification. Only does checks that are cheap. Operates on a single block /// Phase 1 quick block verification. Only does checks that are cheap. Operates on a single block
pub fn verify_block_basic(header: &Header, bytes: &[u8], engine: &Engine) -> Result<(), Error> { pub fn verify_block_basic(header: &Header, bytes: &[u8], engine: &Engine) -> Result<(), Error> {
verify_header_params(&header, engine)?; verify_header_params(&header, engine, true)?;
verify_block_integrity(bytes, &header.transactions_root(), &header.uncles_hash())?; verify_block_integrity(bytes, &header.transactions_root(), &header.uncles_hash())?;
engine.verify_block_basic(&header, Some(bytes))?; engine.verify_block_basic(&header, Some(bytes))?;
for u in UntrustedRlp::new(bytes).at(2)?.iter().map(|rlp| rlp.as_val::<Header>()) { for u in UntrustedRlp::new(bytes).at(2)?.iter().map(|rlp| rlp.as_val::<Header>()) {
let u = u?; let u = u?;
verify_header_params(&u, engine)?; verify_header_params(&u, engine, false)?;
engine.verify_block_basic(&u, None)?; engine.verify_block_basic(&u, None)?;
} }
// Verify transactions. // Verify transactions.
@ -195,7 +195,7 @@ pub fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error>
} }
/// Check basic header parameters. /// Check basic header parameters.
pub fn verify_header_params(header: &Header, engine: &Engine) -> Result<(), Error> { pub fn verify_header_params(header: &Header, engine: &Engine, is_full: bool) -> Result<(), Error> {
if header.number() >= From::from(BlockNumber::max_value()) { if header.number() >= From::from(BlockNumber::max_value()) {
return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { max: Some(From::from(BlockNumber::max_value())), min: None, found: header.number() }))) return Err(From::from(BlockError::RidiculousNumber(OutOfBounds { max: Some(From::from(BlockNumber::max_value())), min: None, found: header.number() })))
} }
@ -210,9 +210,11 @@ pub fn verify_header_params(header: &Header, engine: &Engine) -> Result<(), Erro
if header.number() != 0 && header.extra_data().len() > maximum_extra_data_size { if header.number() != 0 && header.extra_data().len() > maximum_extra_data_size {
return Err(From::from(BlockError::ExtraDataOutOfBounds(OutOfBounds { min: None, max: Some(maximum_extra_data_size), found: header.extra_data().len() }))); return Err(From::from(BlockError::ExtraDataOutOfBounds(OutOfBounds { min: None, max: Some(maximum_extra_data_size), found: header.extra_data().len() })));
} }
let max_time = get_time().sec as u64 + 30; if is_full {
if header.timestamp() > max_time { let max_time = get_time().sec as u64 + 30;
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: header.timestamp() }))) if header.timestamp() > max_time {
return Err(From::from(BlockError::InvalidTimestamp(OutOfBounds { max: Some(max_time), min: None, found: header.timestamp() })))
}
} }
Ok(()) Ok(())
} }