fixed verify_uncles error type (#11276)
* fixed verify_uncles error type * cleanup and document fn verify_uncles bounds checking * find_uncle_headers and find_uncle_hashes take u64 instead of u32 as an input param * Update ethcore/verification/src/verification.rs Co-Authored-By: David <dvdplm@gmail.com>
This commit is contained in:
parent
df1c5ac616
commit
1986c4ee79
@ -1323,13 +1323,14 @@ impl BlockChain {
|
||||
}
|
||||
|
||||
/// Given a block's `parent`, find every block header which represents a valid possible uncle.
|
||||
pub fn find_uncle_headers(&self, parent: &H256, uncle_generations: usize) -> Option<Vec<encoded::Header>> {
|
||||
pub fn find_uncle_headers(&self, parent: &H256, uncle_generations: u64) -> Option<Vec<encoded::Header>> {
|
||||
self.find_uncle_hashes(parent, uncle_generations)
|
||||
.map(|v| v.into_iter().filter_map(|h| self.block_header_data(&h)).collect())
|
||||
}
|
||||
|
||||
/// Given a block's `parent`, find every block hash which represents a valid possible uncle.
|
||||
pub fn find_uncle_hashes(&self, parent: &H256, uncle_generations: usize) -> Option<Vec<H256>> {
|
||||
pub fn find_uncle_hashes(&self, parent: &H256, uncle_generations: u64) -> Option<Vec<H256>> {
|
||||
let uncle_generations = uncle_generations as usize;
|
||||
if !self.is_known(parent) {
|
||||
return None;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ pub enum SealingState {
|
||||
}
|
||||
|
||||
/// The number of generations back that uncles can be.
|
||||
pub const MAX_UNCLE_AGE: usize = 6;
|
||||
pub const MAX_UNCLE_AGE: u64 = 6;
|
||||
|
||||
/// Default EIP-210 contract code.
|
||||
/// As defined in https://github.com/ethereum/EIPs/pull/210
|
||||
|
@ -44,12 +44,9 @@ pub enum BlockError {
|
||||
/// Uncles hash in header is invalid.
|
||||
#[display(fmt = "Block has invalid uncles hash: {}", _0)]
|
||||
InvalidUnclesHash(Mismatch<H256>),
|
||||
/// An uncle is from a generation too old.
|
||||
/// An uncle is from a wrong generation.
|
||||
#[display(fmt = "Uncle block is too old. {}", _0)]
|
||||
UncleTooOld(OutOfBounds<BlockNumber>),
|
||||
/// An uncle is from the same generation as the block.
|
||||
#[display(fmt = "Uncle from same generation as block. {}", _0)]
|
||||
UncleIsBrother(OutOfBounds<BlockNumber>),
|
||||
UncleOutOfBounds(OutOfBounds<BlockNumber>),
|
||||
/// An uncle is already in the chain.
|
||||
#[display(fmt = "Uncle {} already in chain", _0)]
|
||||
UncleInChain(H256),
|
||||
|
@ -179,30 +179,22 @@ fn verify_uncles(block: &PreverifiedBlock, bc: &dyn BlockProvider, engine: &dyn
|
||||
return Err(From::from(BlockError::DuplicateUncle(uncle.hash())))
|
||||
}
|
||||
|
||||
// m_currentBlock.number() - uncle.number() m_cB.n - uP.n()
|
||||
// 1 2
|
||||
// 2
|
||||
// 3
|
||||
// 4
|
||||
// 5
|
||||
// 6 7
|
||||
// (8 Invalid)
|
||||
|
||||
let depth = if header.number() > uncle.number() { header.number() - uncle.number() } else { 0 };
|
||||
if depth > MAX_UNCLE_AGE as u64 {
|
||||
return Err(From::from(BlockError::UncleTooOld(OutOfBounds {
|
||||
min: Some(header.number() - depth),
|
||||
// uncle.number() needs to be within specific number range which is
|
||||
// [header.number() - MAX_UNCLE_AGE, header.number() - 1]
|
||||
//
|
||||
// depth is the difference between uncle.number() and header.number()
|
||||
// and the previous condition implies that it is always in range
|
||||
// [1, MAX_UNCLE_AGE]
|
||||
let depth = if header.number() > uncle.number() &&
|
||||
uncle.number() + MAX_UNCLE_AGE >= header.number() {
|
||||
header.number() - uncle.number()
|
||||
} else {
|
||||
return Err(BlockError::UncleOutOfBounds(OutOfBounds {
|
||||
min: Some(header.number() - MAX_UNCLE_AGE),
|
||||
max: Some(header.number() - 1),
|
||||
found: uncle.number()
|
||||
})));
|
||||
}
|
||||
else if depth < 1 {
|
||||
return Err(From::from(BlockError::UncleIsBrother(OutOfBounds {
|
||||
min: Some(header.number() - depth),
|
||||
max: Some(header.number() - 1),
|
||||
found: uncle.number()
|
||||
})));
|
||||
}
|
||||
}).into());
|
||||
};
|
||||
|
||||
// cB
|
||||
// cB.p^1 1 depth, valid uncle
|
||||
@ -215,7 +207,7 @@ fn verify_uncles(block: &PreverifiedBlock, bc: &dyn BlockProvider, engine: &dyn
|
||||
// cB.p^8
|
||||
let mut expected_uncle_parent = header.parent_hash().clone();
|
||||
let uncle_parent = bc.block_header_data(&uncle.parent_hash())
|
||||
.ok_or_else(|| Error::from(BlockError::UnknownUncleParent(*uncle.parent_hash())))?;
|
||||
.ok_or_else(|| BlockError::UnknownUncleParent(*uncle.parent_hash()))?;
|
||||
for _ in 0..depth {
|
||||
match bc.block_details(&expected_uncle_parent) {
|
||||
Some(details) => {
|
||||
|
Loading…
Reference in New Issue
Block a user