Skip to content

Commit ee023de

Browse files
drcpu-githubguidiaz
authored andcommitted
fix(stakes): fix mining age reset function and add test
1 parent 07be4c5 commit ee023de

File tree

2 files changed

+92
-40
lines changed

2 files changed

+92
-40
lines changed

data_structures/src/staking/mod.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub mod prelude {
2020
}
2121

2222
#[cfg(test)]
23+
/// Test module
2324
pub mod test {
2425
use super::prelude::*;
2526

@@ -33,32 +34,32 @@ pub mod test {
3334
stakes.add_stake("Alpha", 2, 0, MIN_STAKE_NANOWITS).unwrap();
3435

3536
// Nobody holds any power just yet
36-
let rank = stakes.rank(Capability::Mining, 0).collect::<Vec<_>>();
37+
let rank = stakes.by_rank(Capability::Mining, 0).collect::<Vec<_>>();
3738
assert_eq!(rank, vec![("Alpha".into(), 0)]);
3839

3940
// One epoch later, Alpha starts to hold power
40-
let rank = stakes.rank(Capability::Mining, 1).collect::<Vec<_>>();
41+
let rank = stakes.by_rank(Capability::Mining, 1).collect::<Vec<_>>();
4142
assert_eq!(rank, vec![("Alpha".into(), 2)]);
4243

4344
// Beta stakes 5 @ epoch 10
4445
stakes.add_stake("Beta", 5, 10, MIN_STAKE_NANOWITS).unwrap();
4546

4647
// Alpha is still leading, but Beta has scheduled its takeover
47-
let rank = stakes.rank(Capability::Mining, 10).collect::<Vec<_>>();
48+
let rank = stakes.by_rank(Capability::Mining, 10).collect::<Vec<_>>();
4849
assert_eq!(rank, vec![("Alpha".into(), 20), ("Beta".into(), 0)]);
4950

5051
// Beta eventually takes over after epoch 16
51-
let rank = stakes.rank(Capability::Mining, 16).collect::<Vec<_>>();
52+
let rank = stakes.by_rank(Capability::Mining, 16).collect::<Vec<_>>();
5253
assert_eq!(rank, vec![("Alpha".into(), 32), ("Beta".into(), 30)]);
53-
let rank = stakes.rank(Capability::Mining, 17).collect::<Vec<_>>();
54+
let rank = stakes.by_rank(Capability::Mining, 17).collect::<Vec<_>>();
5455
assert_eq!(rank, vec![("Beta".into(), 35), ("Alpha".into(), 34)]);
5556

5657
// Gamma should never take over, even in a million epochs, because it has only 1 coin
5758
stakes
5859
.add_stake("Gamma", 1, 30, MIN_STAKE_NANOWITS)
5960
.unwrap();
6061
let rank = stakes
61-
.rank(Capability::Mining, 1_000_000)
62+
.by_rank(Capability::Mining, 1_000_000)
6263
.collect::<Vec<_>>();
6364
assert_eq!(
6465
rank,
@@ -73,7 +74,7 @@ pub mod test {
7374
stakes
7475
.add_stake("Delta", 1_000, 50, MIN_STAKE_NANOWITS)
7576
.unwrap();
76-
let rank = stakes.rank(Capability::Mining, 50).collect::<Vec<_>>();
77+
let rank = stakes.by_rank(Capability::Mining, 50).collect::<Vec<_>>();
7778
assert_eq!(
7879
rank,
7980
vec![
@@ -83,7 +84,7 @@ pub mod test {
8384
("Delta".into(), 0)
8485
]
8586
);
86-
let rank = stakes.rank(Capability::Mining, 51).collect::<Vec<_>>();
87+
let rank = stakes.by_rank(Capability::Mining, 51).collect::<Vec<_>>();
8788
assert_eq!(
8889
rank,
8990
vec![
@@ -96,7 +97,7 @@ pub mod test {
9697

9798
// If Alpha removes all of its stake, it should immediately disappear
9899
stakes.remove_stake("Alpha", 2, MIN_STAKE_NANOWITS).unwrap();
99-
let rank = stakes.rank(Capability::Mining, 51).collect::<Vec<_>>();
100+
let rank = stakes.by_rank(Capability::Mining, 51).collect::<Vec<_>>();
100101
assert_eq!(
101102
rank,
102103
vec![

data_structures/src/staking/stakes.rs

Lines changed: 82 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,9 @@ where
322322
&self,
323323
capability: Capability,
324324
current_epoch: Epoch,
325-
) -> impl Iterator<Item = (StakeKey<Address>, Power)> + '_ {
325+
) -> impl Iterator<Item = (StakeKey<Address>, Power)> + Clone + '_ {
326326
self.by_key
327327
.iter()
328-
.filter(|(_, sync_entry)| {
329-
sync_entry.read_value().epochs.get(capability) <= current_epoch
330-
})
331328
.map(move |(key, entry)| {
332329
(key.clone(), entry.read_value().power(capability, current_epoch))
333330
})
@@ -428,10 +425,11 @@ where
428425
let validator = validator.into();
429426

430427
// order mining stake entries by rank, as for given current_epoch:
431-
let mut by_rank = self.by_rank(Capability::Mining, current_epoch);
428+
// let stakes_clone = self.clone();
429+
let by_rank = self.by_rank(Capability::Mining, current_epoch);
432430

433431
// locate first entry whose validator matches the one searched for:
434-
let winner_rank = by_rank.position(|(key, _)| key.validator == validator);
432+
let winner_rank = by_rank.clone().position(|(key, _)| key.validator == validator);
435433

436434
if let Some(winner_rank) = winner_rank {
437435
let stakers: Vec<StakeKey<Address>> = by_rank
@@ -444,9 +442,9 @@ where
444442
let stake_entry = self.by_key.get_mut(key);
445443
if let Some(stake_entry) = stake_entry {
446444
let penalty_epochs = Epoch::from((1 + winner_rank - index) as u32);
447-
log::info!(
448-
"Resetting and disabling mining power of {} (ranked as #{}) during +{} epochs",
449-
key, index + 1, penalty_epochs
445+
log::debug!(
446+
"Resetting mining power of {} (ranked as #{}) during +{} epochs to {}",
447+
key, index + 1, penalty_epochs, current_epoch + penalty_epochs
450448
);
451449
stake_entry
452450
.value
@@ -1477,51 +1475,104 @@ mod tests {
14771475
}
14781476

14791477
#[test]
1480-
fn test_stakes_cloneability() {
1478+
fn test_reset_mining_age() {
14811479
// First, lets create a setup with a few stakers
14821480
let mut stakes = StakesTester::default();
14831481
let alice = "Alice";
14841482
let bob = "Bob";
14851483
let charlie = "Charlie";
14861484
let david = "David";
14871485

1486+
let alice_alice = (alice, alice);
1487+
let bob_alice = (bob, alice);
1488+
let charlie_charlie = (charlie, charlie);
1489+
let david_charlie = (david, charlie);
1490+
14881491
// Add some stake and verify the power
14891492
stakes
1490-
.add_stake((alice, charlie), 10, 0, MIN_STAKE_NANOWITS)
1493+
.add_stake(alice_alice, 10, 0, MIN_STAKE_NANOWITS)
1494+
.unwrap();
1495+
stakes
1496+
.add_stake(bob_alice, 20, 0, MIN_STAKE_NANOWITS)
14911497
.unwrap();
14921498
stakes
1493-
.add_stake((bob, david), 20, 10, MIN_STAKE_NANOWITS)
1499+
.add_stake(charlie_charlie, 30, 10, MIN_STAKE_NANOWITS)
14941500
.unwrap();
1495-
assert_eq!(stakes.query_power(alice, Capability::Mining, 30), Ok(300));
1496-
assert_eq!(stakes.query_power(bob, Capability::Mining, 30), Ok(400));
1501+
stakes
1502+
.add_stake(david_charlie, 40, 10, MIN_STAKE_NANOWITS)
1503+
.unwrap();
1504+
assert_eq!(
1505+
stakes.by_rank(Capability::Mining, 30).collect::<Vec<_>>(),
1506+
[
1507+
(david_charlie.into(), 800),
1508+
(charlie_charlie.into(), 600),
1509+
(bob_alice.into(), 600),
1510+
(alice_alice.into(), 300),
1511+
]
1512+
);
1513+
1514+
stakes.reset_mining_age(david, 30).unwrap();
14971515

1498-
// Clone the stakes structure and verify the power
1499-
let cloned_stakes = stakes.clone();
15001516
assert_eq!(
1501-
cloned_stakes.query_power(alice, Capability::Mining, 30),
1502-
Ok(300)
1517+
stakes.by_rank(Capability::Mining, 31).collect::<Vec<_>>(),
1518+
[
1519+
(charlie_charlie.into(), 630),
1520+
(bob_alice.into(), 620),
1521+
(alice_alice.into(), 310),
1522+
(david_charlie.into(), 0),
1523+
]
15031524
);
1525+
15041526
assert_eq!(
1505-
cloned_stakes.query_power(bob, Capability::Mining, 30),
1506-
Ok(400)
1527+
stakes.by_rank(Capability::Mining, 50).collect::<Vec<_>>(),
1528+
[
1529+
(charlie_charlie.into(), 1_200),
1530+
(bob_alice.into(), 1_000),
1531+
(david_charlie.into(), 760),
1532+
(alice_alice.into(), 500),
1533+
]
15071534
);
15081535

1509-
// Reset age and verify power
1510-
stakes.reset_age(alice, Capability::Mining, 25, 1).unwrap();
1511-
stakes.reset_age(bob, Capability::Mining, 30, 1).unwrap();
1536+
stakes.reset_mining_age(david, 50).unwrap();
15121537

1513-
// Power of validators in stakes should have changed
1514-
assert_eq!(stakes.query_power(alice, Capability::Mining, 30), Ok(50));
1515-
assert_eq!(stakes.query_power(bob, Capability::Mining, 30), Ok(0));
1538+
assert_eq!(
1539+
stakes.by_rank(Capability::Mining, 51).collect::<Vec<_>>(),
1540+
[
1541+
(alice_alice.into(), 510),
1542+
(david_charlie.into(), 0),
1543+
(charlie_charlie.into(), 0),
1544+
(bob_alice.into(), 0),
1545+
]
1546+
);
15161547

1517-
// Power of validators in cloned_stakes should have changed
15181548
assert_eq!(
1519-
cloned_stakes.query_power(alice, Capability::Mining, 30),
1520-
Ok(300)
1549+
stakes.by_rank(Capability::Mining, 52).collect::<Vec<_>>(),
1550+
[
1551+
(alice_alice.into(), 520),
1552+
(david_charlie.into(), 40),
1553+
(charlie_charlie.into(), 0),
1554+
(bob_alice.into(), 0),
1555+
]
15211556
);
1557+
15221558
assert_eq!(
1523-
cloned_stakes.query_power(bob, Capability::Mining, 30),
1524-
Ok(400)
1559+
stakes.by_rank(Capability::Mining, 53).collect::<Vec<_>>(),
1560+
[
1561+
(alice_alice.into(), 530),
1562+
(david_charlie.into(), 80),
1563+
(bob_alice.into(), 20),
1564+
(charlie_charlie.into(), 0),
1565+
]
1566+
);
1567+
1568+
assert_eq!(
1569+
stakes.by_rank(Capability::Mining, 54).collect::<Vec<_>>(),
1570+
[
1571+
(alice_alice.into(), 540),
1572+
(david_charlie.into(), 120),
1573+
(bob_alice.into(), 40),
1574+
(charlie_charlie.into(), 30),
1575+
]
15251576
);
15261577
}
15271578
}

0 commit comments

Comments
 (0)