Skip to content

Commit a6db2f4

Browse files
authored
Merge pull request #166 from osmosis-labs/fix/slashing-sequence
Fix/slashing sequence
2 parents 3164c23 + 707be75 commit a6db2f4

File tree

2 files changed

+25
-12
lines changed

2 files changed

+25
-12
lines changed

contracts/consumer/virtual-staking/src/contract.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ mod tests {
880880
.hit_epoch(deps.as_mut())
881881
.assert_bond(&[]) // No bond msgs after jailing
882882
.assert_unbond(&[]) // No unbond msgs after jailing
883-
.assert_rewards(&["val1", "val2"]); // But rewards are still being gathered
883+
.assert_rewards(&["val2"]); // Rewards are not gathered anymore because of the removal
884884

885885
// Check that the bonded amounts of val1 have been slashed for being offline (10%)
886886
// Val2 is unaffected.
@@ -946,7 +946,7 @@ mod tests {
946946
.hit_epoch(deps.as_mut())
947947
.assert_bond(&[("val1", (20u128, &denom))]) // Tombstoned validators can still bond
948948
.assert_unbond(&[]) // No unbond msgs after jailing
949-
.assert_rewards(&["val1"]); // Rewards are still being gathered
949+
.assert_rewards(&[]); // Rewards are not gathered anymore because of jailing implying removal
950950

951951
// Check that the non-slashed amounts of val1 have been bonded
952952
let bonded = contract.bonded.load(deps.as_ref().storage).unwrap();
@@ -978,7 +978,7 @@ mod tests {
978978
.hit_epoch(deps.as_mut())
979979
.assert_bond(&[]) // No bond msgs after jailing
980980
.assert_unbond(&[("val1", (9u128, &denom))]) // Only unbond non-slashed amount
981-
.assert_rewards(&["val1"]); // Rewards are still being gathered
981+
.assert_rewards(&[]); // Rewards are not gathered anymore because of the removal
982982

983983
// Check that the non-slashed amounts of val1 have been unbonded
984984
// FIXME: Remove / filter zero amounts
@@ -1424,8 +1424,17 @@ mod tests {
14241424
}
14251425

14261426
fn jail(&self, deps: DepsMut, val: &str) {
1427-
self.handle_valset_update(deps, &[], &[], &[], &[val.to_string()], &[], &[])
1428-
.unwrap();
1427+
// We sent a removal along with the jail, as this is what the blockchain does
1428+
self.handle_valset_update(
1429+
deps,
1430+
&[],
1431+
&[val.to_string()],
1432+
&[],
1433+
&[val.to_string()],
1434+
&[],
1435+
&[],
1436+
)
1437+
.unwrap();
14291438
}
14301439

14311440
fn unjail(&self, deps: DepsMut, val: &str) {

contracts/provider/external-staking/src/contract.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -488,13 +488,6 @@ impl ExternalStakingContract<'_> {
488488
// Maintenance
489489
valopers.insert(valoper.clone());
490490
}
491-
// Process removals. Non-existent validators will be ignored.
492-
for valoper in removals {
493-
self.val_set
494-
.remove_validator(deps.storage, valoper, height, time)?;
495-
// Maintenance
496-
valopers.insert(valoper.clone());
497-
}
498491
// Process jailings. Non-existent validators will be ignored.
499492
for valoper in jailed {
500493
// Check that the validator is active at height and slash it if that is the case
@@ -514,6 +507,17 @@ impl ExternalStakingContract<'_> {
514507
// Maintenance
515508
valopers.insert(valoper.clone());
516509
}
510+
// Process removals. Non-existent validators will be ignored.
511+
// Filter out jailed validators, as they are already removed from the active validator set
512+
let rms: HashSet<_> = removals.iter().collect();
513+
let j: HashSet<_> = jailed.iter().collect();
514+
let rms: Vec<_> = rms.difference(&j).collect();
515+
for valoper in rms {
516+
self.val_set
517+
.remove_validator(deps.storage, valoper, height, time)?;
518+
// Maintenance
519+
valopers.insert((*valoper).clone());
520+
}
517521
// Process unjailings. Does nothing at the moment, as we don't have a way to know if we the
518522
// validator must go to the active or the unbonded state.
519523

0 commit comments

Comments
 (0)