@@ -26,7 +26,7 @@ use rlp::{Decodable, Encodable, Rlp, RlpStream};
2626
2727use super :: CUSTOM_ACTION_HANDLER_ID ;
2828
29- fn get_account_key ( address : & Address ) -> H256 {
29+ pub fn get_account_key ( address : & Address ) -> H256 {
3030 ActionDataKeyBuilder :: new ( CUSTOM_ACTION_HANDLER_ID , 2 ) . append ( & "Account" ) . append ( address) . into_key ( )
3131}
3232
@@ -35,7 +35,7 @@ lazy_static! {
3535 ActionDataKeyBuilder :: new( CUSTOM_ACTION_HANDLER_ID , 1 ) . append( & "StakeholderAddresses" ) . into_key( ) ;
3636}
3737
38- fn get_delegation_key ( address : & Address ) -> H256 {
38+ pub fn get_delegation_key ( address : & Address ) -> H256 {
3939 ActionDataKeyBuilder :: new ( CUSTOM_ACTION_HANDLER_ID , 2 ) . append ( & "Delegation" ) . append ( address) . into_key ( )
4040}
4141
@@ -64,8 +64,12 @@ impl<'a> StakeAccount<'a> {
6464
6565 pub fn save_to_state ( & self , state : & mut TopLevelState ) -> StateResult < ( ) > {
6666 let account_key = get_account_key ( self . address ) ;
67- let rlp = rlp:: encode ( & self . balance ) ;
68- state. update_action_data ( & account_key, rlp. into_vec ( ) ) ?;
67+ if self . balance != 0 {
68+ let rlp = rlp:: encode ( & self . balance ) ;
69+ state. update_action_data ( & account_key, rlp. into_vec ( ) ) ?;
70+ } else {
71+ state. remove_action_data ( & account_key) ;
72+ }
6973 Ok ( ( ) )
7074 }
7175
@@ -97,7 +101,12 @@ impl Stakeholders {
97101 }
98102
99103 pub fn save_to_state ( & self , state : & mut TopLevelState ) -> StateResult < ( ) > {
100- state. update_action_data ( & * STAKEHOLDER_ADDRESSES_KEY , encode_set ( & self . 0 ) ) ?;
104+ let key = * STAKEHOLDER_ADDRESSES_KEY ;
105+ if !self . 0 . is_empty ( ) {
106+ state. update_action_data ( & key, encode_set ( & self . 0 ) ) ?;
107+ } else {
108+ state. remove_action_data ( & key) ;
109+ }
101110 Ok ( ( ) )
102111 }
103112
@@ -106,10 +115,15 @@ impl Stakeholders {
106115 self . 0 . contains ( address)
107116 }
108117
109- pub fn update ( & mut self , account : & StakeAccount ) {
118+ pub fn update_by_increased_balance ( & mut self , account : & StakeAccount ) {
110119 if account. balance > 0 {
111120 self . 0 . insert ( * account. address ) ;
112- } else {
121+ }
122+ }
123+
124+ pub fn update_by_decreased_balance ( & mut self , account : & StakeAccount , delegation : & Delegation ) {
125+ assert ! ( account. address == delegation. delegator) ;
126+ if account. balance == 0 && delegation. sum ( ) == 0 {
113127 self . 0 . remove ( account. address ) ;
114128 }
115129 }
@@ -138,8 +152,12 @@ impl<'a> Delegation<'a> {
138152
139153 pub fn save_to_state ( & self , state : & mut TopLevelState ) -> StateResult < ( ) > {
140154 let key = get_delegation_key ( self . delegator ) ;
141- let encoded = encode_map ( & self . delegatees ) ;
142- state. update_action_data ( & key, encoded) ?;
155+ if !self . delegatees . is_empty ( ) {
156+ let encoded = encode_map ( & self . delegatees ) ;
157+ state. update_action_data ( & key, encoded) ?;
158+ } else {
159+ state. remove_action_data ( & key) ;
160+ }
143161 Ok ( ( ) )
144162 }
145163
@@ -296,6 +314,24 @@ mod tests {
296314 assert_eq ! ( account. balance, 10 ) ;
297315 }
298316
317+ #[ test]
318+ fn balance_subtract_all_should_remove_entry_from_db ( ) {
319+ let mut state = helpers:: get_temp_state ( ) ;
320+ let address = Address :: random ( ) ;
321+
322+ let mut account = StakeAccount :: load_from_state ( & state, & address) . unwrap ( ) ;
323+ account. add_balance ( 100 ) . unwrap ( ) ;
324+ account. save_to_state ( & mut state) . unwrap ( ) ;
325+
326+ let mut account = StakeAccount :: load_from_state ( & state, & address) . unwrap ( ) ;
327+ let result = account. subtract_balance ( 100 ) ;
328+ assert ! ( result. is_ok( ) ) ;
329+ account. save_to_state ( & mut state) . unwrap ( ) ;
330+
331+ let data = state. action_data ( & get_account_key ( & address) ) . unwrap ( ) ;
332+ assert_eq ! ( data, None ) ;
333+ }
334+
299335 #[ test]
300336 fn stakeholders_track ( ) {
301337 let mut rng = rng ( ) ;
@@ -311,7 +347,7 @@ mod tests {
311347
312348 let mut stakeholders = Stakeholders :: load_from_state ( & state) . unwrap ( ) ;
313349 for account in & accounts {
314- stakeholders. update ( account) ;
350+ stakeholders. update_by_increased_balance ( account) ;
315351 }
316352 stakeholders. save_to_state ( & mut state) . unwrap ( ) ;
317353
@@ -334,18 +370,17 @@ mod tests {
334370
335371 let mut stakeholders = Stakeholders :: load_from_state ( & state) . unwrap ( ) ;
336372 for account in & accounts {
337- stakeholders. update ( account) ;
373+ stakeholders. update_by_increased_balance ( account) ;
338374 }
339375 stakeholders. save_to_state ( & mut state) . unwrap ( ) ;
340376
377+ let mut stakeholders = Stakeholders :: load_from_state ( & state) . unwrap ( ) ;
341378 for account in & mut accounts {
342379 if rand:: random ( ) {
343380 account. balance = 0 ;
344381 }
345- }
346- let mut stakeholders = Stakeholders :: load_from_state ( & state) . unwrap ( ) ;
347- for account in & accounts {
348- stakeholders. update ( account) ;
382+ let delegation = Delegation :: load_from_state ( & state, account. address ) . unwrap ( ) ;
383+ stakeholders. update_by_decreased_balance ( account, & delegation) ;
349384 }
350385 stakeholders. save_to_state ( & mut state) . unwrap ( ) ;
351386
@@ -357,6 +392,40 @@ mod tests {
357392 }
358393 }
359394
395+ #[ test]
396+ fn stakeholders_doesnt_untrack_if_delegation_exists ( ) {
397+ let mut state = helpers:: get_temp_state ( ) ;
398+ let addresses: Vec < _ > = ( 1 ..100 ) . map ( |_| Address :: random ( ) ) . collect ( ) ;
399+ let mut accounts: Vec < _ > = addresses
400+ . iter ( )
401+ . map ( |address| StakeAccount {
402+ address,
403+ balance : 100 ,
404+ } )
405+ . collect ( ) ;
406+
407+ let mut stakeholders = Stakeholders :: load_from_state ( & state) . unwrap ( ) ;
408+ for account in & accounts {
409+ stakeholders. update_by_increased_balance ( account) ;
410+ }
411+ stakeholders. save_to_state ( & mut state) . unwrap ( ) ;
412+
413+ let mut stakeholders = Stakeholders :: load_from_state ( & state) . unwrap ( ) ;
414+ for account in & mut accounts {
415+ // like self-delegate
416+ let mut delegation = Delegation :: load_from_state ( & state, account. address ) . unwrap ( ) ;
417+ delegation. add_quantity ( * account. address , account. balance ) . unwrap ( ) ;
418+ account. balance = 0 ;
419+ stakeholders. update_by_decreased_balance ( account, & delegation) ;
420+ }
421+ stakeholders. save_to_state ( & mut state) . unwrap ( ) ;
422+
423+ let stakeholders = Stakeholders :: load_from_state ( & state) . unwrap ( ) ;
424+ for account in & accounts {
425+ assert ! ( stakeholders. contains( account. address) ) ;
426+ }
427+ }
428+
360429 #[ test]
361430 fn initial_delegation_is_empty ( ) {
362431 let state = helpers:: get_temp_state ( ) ;
0 commit comments