Skip to content

Commit

Permalink
Checking weights sum for overflow
Browse files Browse the repository at this point in the history
  • Loading branch information
ElFantasma committed Mar 27, 2024
1 parent 49efb35 commit 6a650e7
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
10 changes: 9 additions & 1 deletion node/libs/roles/src/validator/messages/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,25 @@ impl Default for Fork {
pub struct ValidatorCommittee {
vec: Vec<WeightedValidator>,
indexes: BTreeMap<validator::PublicKey, usize>,
total_weight: u64,
}

impl ValidatorCommittee {
/// Creates a new ValidatorCommittee from a list of validator public keys.
pub fn new(validators: impl IntoIterator<Item = WeightedValidator>) -> anyhow::Result<Self> {
let mut set = BTreeSet::new();
let mut weighted_validators = BTreeMap::new();
let mut total_weight: u64 = 0;
for validator in validators {
anyhow::ensure!(
set.insert(validator.key.clone()),
"Duplicate validator in ValidatorCommittee"
);
if let Some(result) = total_weight.checked_add(validator.weight) {
total_weight = result
} else {
anyhow::bail!("Sum of weights overflows in ValidatorCommittee")
}
weighted_validators.insert(validator.key.clone(), validator);
}
anyhow::ensure!(
Expand All @@ -106,6 +113,7 @@ impl ValidatorCommittee {
.enumerate()
.map(|(i, pk)| (pk, i))
.collect(),
total_weight,
})
}

Expand Down Expand Up @@ -168,7 +176,7 @@ impl ValidatorCommittee {

/// Sum of all validators' weight in the committee
pub fn total_weight(&self) -> u64 {
self.vec.iter().map(|v| v.weight).sum()
self.total_weight
}
}

Expand Down
23 changes: 23 additions & 0 deletions node/libs/roles/src/validator/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::*;
use crate::validator::testonly::Setup;
use anyhow::Error;
use assert_matches::assert_matches;
use rand::{seq::SliceRandom, Rng};
use std::vec;
Expand Down Expand Up @@ -313,3 +314,25 @@ fn test_validator_committee_weights() {
);
}
}

#[test]
fn test_validator_weights_sanity() {
let ctx = ctx::test_root(&ctx::RealClock);
let rng = &mut ctx.rng();

let setup = Setup::new(rng, 6);
// Validators weights
let weight = u64::MAX / 5;
let weights = [weight, weight, weight, weight, weight, weight];
let validators: Vec<WeightedValidator> = weights
.iter()
.enumerate()
.map(|(i, w)| WeightedValidator {
key: setup.keys[i].public(),
weight: *w,
})
.collect();

// Creation should overflow
assert_matches!(ValidatorCommittee::new(validators), Err(Error { .. }));
}

0 comments on commit 6a650e7

Please sign in to comment.