Handle attempts to get block headers at invalid heights (#3683)

* handle attempts to get block headers at invalid heights

* compare requested height against header pmmr size

* gte
This commit is contained in:
Yeastplume 2021-12-31 09:47:04 +00:00 committed by GitHub
parent 382e914c50
commit 2237f42144
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 3 deletions

View file

@ -135,6 +135,10 @@ pub enum ErrorKind {
/// Error from underlying block handling /// Error from underlying block handling
#[fail(display = "Block Validation Error: {:?}", _0)] #[fail(display = "Block Validation Error: {:?}", _0)]
Block(block::Error), Block(block::Error),
/// Attempt to retrieve a header at a height greater than
/// the max allowed by u64 limits
#[fail(display = "Invalid Header Height: {}", _0)]
InvalidHeaderHeight(u64),
/// Anything else /// Anything else
#[fail(display = "Other Error: {}", _0)] #[fail(display = "Other Error: {}", _0)]
Other(String), Other(String),

View file

@ -110,6 +110,9 @@ impl PMMRHandle<BlockHeader> {
/// Get the header hash at the specified height based on the current header MMR state. /// Get the header hash at the specified height based on the current header MMR state.
pub fn get_header_hash_by_height(&self, height: u64) -> Result<Hash, Error> { pub fn get_header_hash_by_height(&self, height: u64) -> Result<Hash, Error> {
if height >= self.size {
return Err(ErrorKind::InvalidHeaderHeight(height).into());
}
let pos = pmmr::insertion_to_pmmr_index(height); let pos = pmmr::insertion_to_pmmr_index(height);
let header_pmmr = ReadonlyPMMR::at(&self.backend, self.size); let header_pmmr = ReadonlyPMMR::at(&self.backend, self.size);
if let Some(entry) = header_pmmr.get_data(pos) { if let Some(entry) = header_pmmr.get_data(pos) {

View file

@ -454,9 +454,15 @@ impl Server {
// We need to query again for the actual block hash, as // We need to query again for the actual block hash, as
// the difficulty iterator doesn't contain enough info to // the difficulty iterator doesn't contain enough info to
// create a hash // create a hash
let block_hash = match self.chain.get_header_by_height(height as u64) { // The diff iterator returns 59 block headers 'before' 0 to give callers
// enough detail to calculate initial block difficulties. Ignore these.
let block_hash = if height < 0 {
ZERO_HASH
} else {
match self.chain.get_header_by_height(height as u64) {
Ok(h) => h.hash(), Ok(h) => h.hash(),
Err(_) => ZERO_HASH, Err(_) => ZERO_HASH,
}
}; };
DiffBlock { DiffBlock {