Skip to content

Commit

Permalink
Merge pull request #22 from datachainlab/audit-202411-eelc-2
Browse files Browse the repository at this point in the history
EELC2: improve validation of `Fraction`

Signed-off-by: Jun Kimura <[email protected]>
  • Loading branch information
bluele authored Dec 23, 2024
2 parents 4645ecd + c6a6216 commit a9a27ae
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 17 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.82.0
- uses: Swatinem/rust-cache@v2
- run: cargo test
- run: cargo build
Expand Down
3 changes: 2 additions & 1 deletion crates/light-client-cli/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ impl<
verifier: Default::default(),
genesis_time,
genesis_validators_root,
trust_level: trust_level.unwrap_or(Fraction::new(2, 3)),
// safe to unwrap: `2/3` is valid fraction
trust_level: trust_level.unwrap_or(Fraction::new(2, 3).unwrap()),
}
}

Expand Down
18 changes: 9 additions & 9 deletions crates/light-client-verifier/src/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,9 @@ pub fn verify_sync_committee_attestation<
participants,
ctx.min_sync_committee_participants(),
));
} else if participants as u64 * ctx.signature_threshold().denominator
} else if participants as u64 * ctx.signature_threshold().denominator()
< consensus_update.sync_aggregate().sync_committee_bits.len() as u64
* ctx.signature_threshold().numerator
* ctx.signature_threshold().numerator()
{
return Err(Error::InsufficientParticipants(
participants as u64,
Expand Down Expand Up @@ -881,7 +881,7 @@ mod tests {
genesis_validators_root,
// NOTE: this is workaround. we must get the correct timestamp from beacon state.
minimal::get_config().min_genesis_time,
Fraction::new(2, 3),
Fraction::new(2, 3).unwrap(),
1729846322.into(),
);
assert!(verifier.validate_boostrap(&ctx, &bootstrap, None).is_ok());
Expand Down Expand Up @@ -928,7 +928,7 @@ mod tests {
genesis_validators_root,
// NOTE: this is workaround. we must get the correct timestamp from beacon state.
minimal::get_config().min_genesis_time,
Fraction::new(2, 3),
Fraction::new(2, 3).unwrap(),
1729846322.into(),
);
assert!(verifier.validate_boostrap(&ctx, &bootstrap, None).is_ok());
Expand Down Expand Up @@ -1039,7 +1039,7 @@ mod tests {
config::minimal::get_config(),
Default::default(),
Default::default(),
Fraction::new(2, 3),
Fraction::new(2, 3).unwrap(),
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
Expand Down Expand Up @@ -1458,7 +1458,7 @@ mod tests {
config::minimal::get_config(),
Default::default(),
Default::default(),
Fraction::new(2, 3),
Fraction::new(2, 3).unwrap(),
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
Expand Down Expand Up @@ -1779,7 +1779,7 @@ mod tests {
.as_ref(),
),
1731420304.into(),
Fraction::new(2, 3),
Fraction::new(2, 3).unwrap(),
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
Expand All @@ -1806,7 +1806,7 @@ mod tests {
.as_ref(),
),
1731420304.into(),
Fraction::new(2, 3),
Fraction::new(2, 3).unwrap(),
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
Expand Down Expand Up @@ -1971,7 +1971,7 @@ mod tests {
.as_ref(),
),
1731420304.into(),
Fraction::new(2, 3),
Fraction::new(2, 3).unwrap(),
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
Expand Down
30 changes: 24 additions & 6 deletions crates/light-client-verifier/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::errors::Error;
use ethereum_consensus::{
beacon::{Epoch, Root, Slot},
compute::{compute_epoch_at_slot, compute_slot_at_timestamp},
Expand All @@ -6,19 +7,36 @@ use ethereum_consensus::{
fork::{ForkParameters, ForkSpec},
types::U64,
};

/// Fraction is a struct representing a fraction for a threshold.
#[derive(Clone, Default, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct Fraction {
pub numerator: u64,
pub denominator: u64,
numerator: u64,
denominator: u64,
}

impl Fraction {
pub fn new(numerator: u64, denominator: u64) -> Self {
Self {
numerator,
denominator,
pub fn new(numerator: u64, denominator: u64) -> Result<Self, Error> {
if denominator == 0 || numerator > denominator {
Err(Error::InvalidFraction(Self {
numerator,
denominator,
}))
} else {
Ok(Self {
numerator,
denominator,
})
}
}

pub fn numerator(&self) -> u64 {
self.numerator
}

pub fn denominator(&self) -> u64 {
self.denominator
}
}

pub trait ConsensusVerificationContext {
Expand Down
4 changes: 3 additions & 1 deletion crates/light-client-verifier/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::internal_prelude::*;
use crate::{context::Fraction, internal_prelude::*};
use displaydoc::Display;
use ethereum_consensus::{
beacon::{BeaconBlockHeader, Epoch, Root, Slot},
Expand Down Expand Up @@ -91,6 +91,8 @@ pub enum Error {
InvalidExecutionBlockNumberMerkleBranch(MerkleError),
/// inconsistent next sync committee: `store:{0:?}` != `update:{1:?}`
InconsistentNextSyncCommittee(PublicKey, PublicKey),
/// invalid fraction: `fraction={0:?}`
InvalidFraction(Fraction),
/// other error: `{description}`
Other { description: String },
}
Expand Down

0 comments on commit a9a27ae

Please sign in to comment.