mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 17:26:04 +00:00
Add more compute_deltas tests
This commit is contained in:
@@ -9,7 +9,6 @@ pub const PRUNE_THRESHOLD: usize = 200;
|
|||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
NodeUnknown(Hash256),
|
|
||||||
FinalizedNodeUnknown(Hash256),
|
FinalizedNodeUnknown(Hash256),
|
||||||
JustifiedNodeUnknown(Hash256),
|
JustifiedNodeUnknown(Hash256),
|
||||||
InvalidFinalizedRootChange,
|
InvalidFinalizedRootChange,
|
||||||
@@ -189,9 +188,6 @@ fn compute_deltas(
|
|||||||
let new_balance = new_balances.get(val_index).copied().unwrap_or_else(|| 0);
|
let new_balance = new_balances.get(val_index).copied().unwrap_or_else(|| 0);
|
||||||
|
|
||||||
if vote.current_root != vote.next_root || old_balance != new_balance {
|
if vote.current_root != vote.next_root || old_balance != new_balance {
|
||||||
// If the current vote is for the zero-hash there's no need to subtract the balance
|
|
||||||
// from it. Additionally, the zero-hash will most likley not exist in `indices`.
|
|
||||||
if vote.current_root != Hash256::zero() {
|
|
||||||
// We ignore the vote if it is not known in `indices`. We assume that it is outside
|
// We ignore the vote if it is not known in `indices`. We assume that it is outside
|
||||||
// of our tree (i.e., pre-finalization) and therefore not interesting.
|
// of our tree (i.e., pre-finalization) and therefore not interesting.
|
||||||
if let Some(current_delta_index) = indices.get(&vote.current_root).copied() {
|
if let Some(current_delta_index) = indices.get(&vote.current_root).copied() {
|
||||||
@@ -204,11 +200,7 @@ fn compute_deltas(
|
|||||||
// Array access safe due to check on previous line.
|
// Array access safe due to check on previous line.
|
||||||
deltas[current_delta_index] = delta;
|
deltas[current_delta_index] = delta;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If the next vote is for the zero-hash there's no need to add the balance
|
|
||||||
// to it. Additionally, the zero-hash will most likley not exist in `indices`.
|
|
||||||
if vote.next_root != Hash256::zero() {
|
|
||||||
// We ignore the vote if it is not known in `indices`. We assume that it is outside
|
// We ignore the vote if it is not known in `indices`. We assume that it is outside
|
||||||
// of our tree (i.e., pre-finalization) and therefore not interesting.
|
// of our tree (i.e., pre-finalization) and therefore not interesting.
|
||||||
if let Some(next_delta_index) = indices.get(&vote.next_root).copied() {
|
if let Some(next_delta_index) = indices.get(&vote.next_root).copied() {
|
||||||
@@ -221,7 +213,6 @@ fn compute_deltas(
|
|||||||
// Array access safe due to check on previous line.
|
// Array access safe due to check on previous line.
|
||||||
deltas[next_delta_index] = delta;
|
deltas[next_delta_index] = delta;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
vote.current_root = vote.next_root;
|
vote.current_root = vote.next_root;
|
||||||
}
|
}
|
||||||
@@ -545,10 +536,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, val: T) {
|
|
||||||
self.0.push(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(&mut self, i: usize) -> &T {
|
pub fn get(&mut self, i: usize) -> &T {
|
||||||
self.ensure(i);
|
self.ensure(i);
|
||||||
&self.0[i]
|
&self.0[i]
|
||||||
@@ -584,7 +571,7 @@ mod test {
|
|||||||
|
|
||||||
for i in 0..validator_count {
|
for i in 0..validator_count {
|
||||||
indices.insert(hash_from_index(i), i);
|
indices.insert(hash_from_index(i), i);
|
||||||
votes.push(VoteTracker {
|
votes.0.push(VoteTracker {
|
||||||
current_root: Hash256::zero(),
|
current_root: Hash256::zero(),
|
||||||
next_root: Hash256::zero(),
|
next_root: Hash256::zero(),
|
||||||
next_epoch: Epoch::new(0),
|
next_epoch: Epoch::new(0),
|
||||||
@@ -606,6 +593,13 @@ mod test {
|
|||||||
vec![0; validator_count],
|
vec![0; validator_count],
|
||||||
"deltas should all be zero"
|
"deltas should all be zero"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
for vote in votes.0 {
|
||||||
|
assert_eq!(
|
||||||
|
vote.current_root, vote.next_root,
|
||||||
|
"the vote shoulds should have been updated"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -621,7 +615,7 @@ mod test {
|
|||||||
|
|
||||||
for i in 0..validator_count {
|
for i in 0..validator_count {
|
||||||
indices.insert(hash_from_index(i), i);
|
indices.insert(hash_from_index(i), i);
|
||||||
votes.push(VoteTracker {
|
votes.0.push(VoteTracker {
|
||||||
current_root: Hash256::zero(),
|
current_root: Hash256::zero(),
|
||||||
next_root: hash_from_index(0),
|
next_root: hash_from_index(0),
|
||||||
next_epoch: Epoch::new(0),
|
next_epoch: Epoch::new(0),
|
||||||
@@ -650,6 +644,13 @@ mod test {
|
|||||||
assert_eq!(delta, 0, "all other deltas should be zero");
|
assert_eq!(delta, 0, "all other deltas should be zero");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for vote in votes.0 {
|
||||||
|
assert_eq!(
|
||||||
|
vote.current_root, vote.next_root,
|
||||||
|
"the vote shoulds should have been updated"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -665,7 +666,7 @@ mod test {
|
|||||||
|
|
||||||
for i in 0..validator_count {
|
for i in 0..validator_count {
|
||||||
indices.insert(hash_from_index(i), i);
|
indices.insert(hash_from_index(i), i);
|
||||||
votes.push(VoteTracker {
|
votes.0.push(VoteTracker {
|
||||||
current_root: Hash256::zero(),
|
current_root: Hash256::zero(),
|
||||||
next_root: hash_from_index(i),
|
next_root: hash_from_index(i),
|
||||||
next_epoch: Epoch::new(0),
|
next_epoch: Epoch::new(0),
|
||||||
@@ -689,5 +690,269 @@ mod test {
|
|||||||
"each root should have the same delta"
|
"each root should have the same delta"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for vote in votes.0 {
|
||||||
|
assert_eq!(
|
||||||
|
vote.current_root, vote.next_root,
|
||||||
|
"the vote shoulds should have been updated"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn compute_deltas_moving_votes() {
|
||||||
|
const BALANCE: u64 = 42;
|
||||||
|
|
||||||
|
let validator_count: usize = 16;
|
||||||
|
|
||||||
|
let mut indices = HashMap::new();
|
||||||
|
let mut votes = ElasticList::default();
|
||||||
|
let mut old_balances = vec![];
|
||||||
|
let mut new_balances = vec![];
|
||||||
|
|
||||||
|
for i in 0..validator_count {
|
||||||
|
indices.insert(hash_from_index(i), i);
|
||||||
|
votes.0.push(VoteTracker {
|
||||||
|
current_root: hash_from_index(0),
|
||||||
|
next_root: hash_from_index(1),
|
||||||
|
next_epoch: Epoch::new(0),
|
||||||
|
});
|
||||||
|
old_balances.push(BALANCE);
|
||||||
|
new_balances.push(BALANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
let deltas = compute_deltas(&indices, &mut votes, &old_balances, &new_balances)
|
||||||
|
.expect("should compute deltas");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
deltas.len(),
|
||||||
|
validator_count,
|
||||||
|
"deltas should have expected length"
|
||||||
|
);
|
||||||
|
|
||||||
|
let total_delta = BALANCE as i64 * validator_count as i64;
|
||||||
|
|
||||||
|
for (i, delta) in deltas.into_iter().enumerate() {
|
||||||
|
if i == 0 {
|
||||||
|
assert_eq!(
|
||||||
|
delta,
|
||||||
|
0 - total_delta,
|
||||||
|
"zero'th root should have a negative delta"
|
||||||
|
);
|
||||||
|
} else if i == 1 {
|
||||||
|
assert_eq!(delta, total_delta, "first root should have positive delta");
|
||||||
|
} else {
|
||||||
|
assert_eq!(delta, 0, "all other deltas should be zero");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for vote in votes.0 {
|
||||||
|
assert_eq!(
|
||||||
|
vote.current_root, vote.next_root,
|
||||||
|
"the vote shoulds should have been updated"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn compute_deltas_move_out_of_tree() {
|
||||||
|
const BALANCE: u64 = 42;
|
||||||
|
|
||||||
|
let mut indices = HashMap::new();
|
||||||
|
let mut votes = ElasticList::default();
|
||||||
|
|
||||||
|
// There is only one block.
|
||||||
|
indices.insert(hash_from_index(1), 0);
|
||||||
|
|
||||||
|
// There are two validators.
|
||||||
|
let old_balances = vec![BALANCE; 2];
|
||||||
|
let new_balances = vec![BALANCE; 2];
|
||||||
|
|
||||||
|
// One validator moves their vote from the block to the zero hash.
|
||||||
|
votes.0.push(VoteTracker {
|
||||||
|
current_root: hash_from_index(1),
|
||||||
|
next_root: Hash256::zero(),
|
||||||
|
next_epoch: Epoch::new(0),
|
||||||
|
});
|
||||||
|
|
||||||
|
// One validator moves their vote from the block to something outside the tree.
|
||||||
|
votes.0.push(VoteTracker {
|
||||||
|
current_root: hash_from_index(1),
|
||||||
|
next_root: Hash256::from_low_u64_be(1337),
|
||||||
|
next_epoch: Epoch::new(0),
|
||||||
|
});
|
||||||
|
|
||||||
|
let deltas = compute_deltas(&indices, &mut votes, &old_balances, &new_balances)
|
||||||
|
.expect("should compute deltas");
|
||||||
|
|
||||||
|
assert_eq!(deltas.len(), 1, "deltas should have expected length");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
deltas[0],
|
||||||
|
0 - BALANCE as i64 * 2,
|
||||||
|
"the block should have lost both balances"
|
||||||
|
);
|
||||||
|
|
||||||
|
for vote in votes.0 {
|
||||||
|
assert_eq!(
|
||||||
|
vote.current_root, vote.next_root,
|
||||||
|
"the vote shoulds should have been updated"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn compute_deltas_changing_balances() {
|
||||||
|
const OLD_BALANCE: u64 = 42;
|
||||||
|
const NEW_BALANCE: u64 = OLD_BALANCE * 2;
|
||||||
|
|
||||||
|
let validator_count: usize = 16;
|
||||||
|
|
||||||
|
let mut indices = HashMap::new();
|
||||||
|
let mut votes = ElasticList::default();
|
||||||
|
let mut old_balances = vec![];
|
||||||
|
let mut new_balances = vec![];
|
||||||
|
|
||||||
|
for i in 0..validator_count {
|
||||||
|
indices.insert(hash_from_index(i), i);
|
||||||
|
votes.0.push(VoteTracker {
|
||||||
|
current_root: hash_from_index(0),
|
||||||
|
next_root: hash_from_index(1),
|
||||||
|
next_epoch: Epoch::new(0),
|
||||||
|
});
|
||||||
|
old_balances.push(OLD_BALANCE);
|
||||||
|
new_balances.push(NEW_BALANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
let deltas = compute_deltas(&indices, &mut votes, &old_balances, &new_balances)
|
||||||
|
.expect("should compute deltas");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
deltas.len(),
|
||||||
|
validator_count,
|
||||||
|
"deltas should have expected length"
|
||||||
|
);
|
||||||
|
|
||||||
|
for (i, delta) in deltas.into_iter().enumerate() {
|
||||||
|
if i == 0 {
|
||||||
|
assert_eq!(
|
||||||
|
delta,
|
||||||
|
0 - OLD_BALANCE as i64 * validator_count as i64,
|
||||||
|
"zero'th root should have a negative delta"
|
||||||
|
);
|
||||||
|
} else if i == 1 {
|
||||||
|
assert_eq!(
|
||||||
|
delta,
|
||||||
|
NEW_BALANCE as i64 * validator_count as i64,
|
||||||
|
"first root should have positive delta"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
assert_eq!(delta, 0, "all other deltas should be zero");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for vote in votes.0 {
|
||||||
|
assert_eq!(
|
||||||
|
vote.current_root, vote.next_root,
|
||||||
|
"the vote shoulds should have been updated"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn compute_deltas_validator_appears() {
|
||||||
|
const BALANCE: u64 = 42;
|
||||||
|
|
||||||
|
let mut indices = HashMap::new();
|
||||||
|
let mut votes = ElasticList::default();
|
||||||
|
|
||||||
|
// There are two blocks.
|
||||||
|
indices.insert(hash_from_index(1), 0);
|
||||||
|
indices.insert(hash_from_index(2), 1);
|
||||||
|
|
||||||
|
// There is only one validator in the old balances.
|
||||||
|
let old_balances = vec![BALANCE; 1];
|
||||||
|
// There are two validators in the new balances.
|
||||||
|
let new_balances = vec![BALANCE; 2];
|
||||||
|
|
||||||
|
// Both validator move votes from block 1 to block 2.
|
||||||
|
for _ in 0..2 {
|
||||||
|
votes.0.push(VoteTracker {
|
||||||
|
current_root: hash_from_index(1),
|
||||||
|
next_root: hash_from_index(2),
|
||||||
|
next_epoch: Epoch::new(0),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let deltas = compute_deltas(&indices, &mut votes, &old_balances, &new_balances)
|
||||||
|
.expect("should compute deltas");
|
||||||
|
|
||||||
|
assert_eq!(deltas.len(), 2, "deltas should have expected length");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
deltas[0],
|
||||||
|
0 - BALANCE as i64,
|
||||||
|
"block 1 should have only lost one balance"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
deltas[1],
|
||||||
|
2 * BALANCE as i64,
|
||||||
|
"block 2 should have gained two balances"
|
||||||
|
);
|
||||||
|
|
||||||
|
for vote in votes.0 {
|
||||||
|
assert_eq!(
|
||||||
|
vote.current_root, vote.next_root,
|
||||||
|
"the vote shoulds should have been updated"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn compute_deltas_validator_disappears() {
|
||||||
|
const BALANCE: u64 = 42;
|
||||||
|
|
||||||
|
let mut indices = HashMap::new();
|
||||||
|
let mut votes = ElasticList::default();
|
||||||
|
|
||||||
|
// There are two blocks.
|
||||||
|
indices.insert(hash_from_index(1), 0);
|
||||||
|
indices.insert(hash_from_index(2), 1);
|
||||||
|
|
||||||
|
// There are two validators in the old balances.
|
||||||
|
let old_balances = vec![BALANCE; 2];
|
||||||
|
// There is only one validator in the new balances.
|
||||||
|
let new_balances = vec![BALANCE; 1];
|
||||||
|
|
||||||
|
// Both validator move votes from block 1 to block 2.
|
||||||
|
for _ in 0..2 {
|
||||||
|
votes.0.push(VoteTracker {
|
||||||
|
current_root: hash_from_index(1),
|
||||||
|
next_root: hash_from_index(2),
|
||||||
|
next_epoch: Epoch::new(0),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let deltas = compute_deltas(&indices, &mut votes, &old_balances, &new_balances)
|
||||||
|
.expect("should compute deltas");
|
||||||
|
|
||||||
|
assert_eq!(deltas.len(), 2, "deltas should have expected length");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
deltas[0],
|
||||||
|
0 - BALANCE as i64 * 2,
|
||||||
|
"block 1 should have lost both balances"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
deltas[1], BALANCE as i64,
|
||||||
|
"block 2 should have only gained one balance"
|
||||||
|
);
|
||||||
|
|
||||||
|
for vote in votes.0 {
|
||||||
|
assert_eq!(
|
||||||
|
vote.current_root, vote.next_root,
|
||||||
|
"the vote shoulds should have been updated"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user