Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

node: fix overflow during faults validation #2087

Merged
merged 2 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions node-data/src/ledger/faults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ pub enum InvalidFault {
Expired,
#[error("Fault is from future")]
Future,
#[error("Fault is from genesis block")]
Genesis,
#[error("Previous hash mismatch")]
PrevHashMismatch,
#[error("Iteration mismatch")]
Expand Down Expand Up @@ -153,8 +155,12 @@ impl Fault {
return Err(InvalidFault::Duplicated);
}

if h1.round == 0 {
return Err(InvalidFault::Genesis);
}

// Check that fault is not expired. A fault expires after an epoch
if h1.round < current_height - EPOCH {
if h1.round < current_height.saturating_sub(EPOCH) {
return Err(InvalidFault::Expired);
}

Expand Down Expand Up @@ -298,10 +304,10 @@ impl Serializable for Fault {
FaultData::read(r)?,
FaultData::read(r)?,
),
p => {
println!("{p}");
Err(io::Error::new(io::ErrorKind::InvalidData, "Invalid faul"))?
}
p => Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("Invalid fault: {p}"),
))?,
};
Ok(fault)
}
Expand Down
6 changes: 4 additions & 2 deletions node/src/chain/header_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,15 +302,17 @@ pub async fn verify_faults<DB: database::DB>(
let prev_header = db
.fetch_block_header(&fault_header.prev_block_hash)?
.ok_or(anyhow::anyhow!("Slashing a non accepted header"))?;
// No overflow here, since the header has been already validated
// not to be 0
if prev_header.height != fault_header.round - 1 {
anyhow::bail!("Invalid height for fault");
}

// FIX_ME: Instead of fetching all store faults, check the fault
// id directly This needs the fault id to be
// changed into "HEIGHT|TYPE|PROV_KEY"
let stored_faults =
db.fetch_faults_by_block(fault_header.round - EPOCH)?;
let start_height = fault_header.round.saturating_sub(EPOCH);
let stored_faults = db.fetch_faults_by_block(start_height)?;
if stored_faults.iter().any(|other| f.same(other)) {
anyhow::bail!("Double fault detected");
}
Expand Down
Loading