Skip to content

Commit e59bfbb

Browse files
foriequal0mergify[bot]
authored andcommitted
Implement delegation subtract
1 parent 6b4fda0 commit e59bfbb

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

core/src/consensus/stake/action_data.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#[cfg(test)]
1818
use std::collections::btree_map;
19+
use std::collections::btree_map::Entry;
1920
use std::collections::{btree_set, BTreeMap, BTreeSet};
2021
use std::mem;
2122

@@ -174,6 +175,25 @@ impl<'a> Delegation<'a> {
174175
Ok(())
175176
}
176177

178+
pub fn subtract_quantity(&mut self, delegatee: Address, quantity: StakeQuantity) -> StateResult<()> {
179+
if quantity == 0 {
180+
return Ok(())
181+
}
182+
183+
if let Entry::Occupied(mut entry) = self.delegatees.entry(delegatee) {
184+
if *entry.get() > quantity {
185+
*entry.get_mut() -= quantity;
186+
return Ok(())
187+
} else if *entry.get() == quantity {
188+
entry.remove();
189+
return Ok(())
190+
}
191+
}
192+
193+
Err(RuntimeError::FailedToHandleCustomAction("Cannot subtract more than that is delegated to".to_string())
194+
.into())
195+
}
196+
177197
#[cfg(test)]
178198
pub fn get_quantity(&self, delegatee: &Address) -> StakeQuantity {
179199
self.delegatees.get(delegatee).cloned().unwrap_or(0)
@@ -581,6 +601,45 @@ mod tests {
581601
assert_eq!(&delegated, &[(&delegatee1, &100)]);
582602
}
583603

604+
#[test]
605+
fn delegation_can_subtract() {
606+
let mut state = helpers::get_temp_state();
607+
608+
// Prepare
609+
let delegator = Address::random();
610+
let delegatee = Address::random();
611+
612+
let mut delegation = Delegation::load_from_state(&state, &delegator).unwrap();
613+
delegation.add_quantity(delegatee, 100).unwrap();
614+
delegation.save_to_state(&mut state).unwrap();
615+
616+
// Do subtract
617+
let mut delegation = Delegation::load_from_state(&state, &delegator).unwrap();
618+
delegation.subtract_quantity(delegatee, 30).unwrap();
619+
delegation.save_to_state(&mut state).unwrap();
620+
621+
// Assert
622+
let delegation = Delegation::load_from_state(&state, &delegator).unwrap();
623+
assert_eq!(delegation.get_quantity(&delegatee), 70);
624+
}
625+
626+
#[test]
627+
fn delegation_cannot_subtract_mor_than_delegated() {
628+
let mut state = helpers::get_temp_state();
629+
630+
// Prepare
631+
let delegator = Address::random();
632+
let delegatee = Address::random();
633+
634+
let mut delegation = Delegation::load_from_state(&state, &delegator).unwrap();
635+
delegation.add_quantity(delegatee, 100).unwrap();
636+
delegation.save_to_state(&mut state).unwrap();
637+
638+
// Do subtract
639+
let mut delegation = Delegation::load_from_state(&state, &delegator).unwrap();
640+
assert!(delegation.subtract_quantity(delegatee, 130).is_err());
641+
}
642+
584643
#[test]
585644
fn delegation_empty_removed_from_state() {
586645
let mut state = helpers::get_temp_state();
@@ -598,6 +657,28 @@ mod tests {
598657
assert_eq!(result, None);
599658
}
600659

660+
#[test]
661+
fn delegation_became_empty_removed_from_state() {
662+
let mut state = helpers::get_temp_state();
663+
664+
// Prepare
665+
let delegator = Address::random();
666+
let delegatee = Address::random();
667+
668+
let mut delegation = Delegation::load_from_state(&state, &delegator).unwrap();
669+
delegation.add_quantity(delegatee, 100).unwrap();
670+
delegation.save_to_state(&mut state).unwrap();
671+
672+
// Do subtract
673+
let mut delegation = Delegation::load_from_state(&state, &delegator).unwrap();
674+
delegation.subtract_quantity(delegatee, 100).unwrap();
675+
delegation.save_to_state(&mut state).unwrap();
676+
677+
// Assert
678+
let result = state.action_data(&get_delegation_key(&delegator)).unwrap();
679+
assert_eq!(result, None);
680+
}
681+
601682
#[test]
602683
fn load_and_save_intermediate_rewards() {
603684
let mut state = helpers::get_temp_state();

0 commit comments

Comments
 (0)