@@ -973,18 +973,29 @@ impl<T: Trait> Module<T> {
973973			) ; 
974974			T :: ChangeMembers :: set_prime ( prime) ; 
975975
976- 			// outgoing members lose their bond. 
977- 			let  mut  to_burn_bond = outgoing. to_vec ( ) ; 
976+ 			// outgoing members who are no longer a runner-up lose their bond. 
977+ 			let  mut  to_burn_bond = outgoing
978+ 				. iter ( ) 
979+ 				. filter ( |o| new_runners_up_ids_sorted. binary_search ( o) . is_err ( ) ) 
980+ 				. cloned ( ) 
981+ 				. collect :: < Vec < _ > > ( ) ; 
978982
979- 			// compute the outgoing of runners up as well and append them to the `to_burn_bond` 
983+ 			// compute the outgoing of runners up as well and append them to the `to_burn_bond`, if 
984+ 			// they are not members. 
980985			{ 
981986				let  ( _,  outgoing)  = T :: ChangeMembers :: compute_members_diff ( 
982987					& new_runners_up_ids_sorted, 
983988					& old_runners_up_ids_sorted, 
984989				) ; 
985990				// none of the ones computed to be outgoing must still be in the list. 
986991				debug_assert ! ( outgoing. iter( ) . all( |o| !new_runners_up_ids_sorted. contains( o) ) ) ; 
987- 				to_burn_bond. extend ( outgoing) ; 
992+ 				to_burn_bond. extend ( 
993+ 					outgoing
994+ 						. iter ( ) 
995+ 						. filter ( |o| new_members_ids_sorted. binary_search ( o) . is_err ( ) ) 
996+ 						. cloned ( ) 
997+ 						. collect :: < Vec < _ > > ( ) 
998+ 				) ; 
988999			} 
9891000
9901001			// Burn loser bond. members list is sorted. O(NLogM) (N candidates, M members) 
@@ -2876,4 +2887,86 @@ mod tests {
28762887			assert_eq ! ( balances( & 3 ) ,  ( 25 ,  5 ) ) ; 
28772888		} ) 
28782889	} 
2890+ 
2891+ 	#[ test]  
2892+ 	fn  member_to_runner_up_wont_slash ( )  { 
2893+ 		ExtBuilder :: default ( ) . desired_runners_up ( 2 ) . desired_members ( 1 ) . build_and_execute ( || { 
2894+ 			assert_ok ! ( submit_candidacy( Origin :: signed( 4 ) ) ) ; 
2895+ 			assert_ok ! ( submit_candidacy( Origin :: signed( 3 ) ) ) ; 
2896+ 			assert_ok ! ( submit_candidacy( Origin :: signed( 2 ) ) ) ; 
2897+ 
2898+ 
2899+ 			assert_ok ! ( vote( Origin :: signed( 4 ) ,  vec![ 4 ] ,  40 ) ) ; 
2900+ 			assert_ok ! ( vote( Origin :: signed( 3 ) ,  vec![ 3 ] ,  30 ) ) ; 
2901+ 			assert_ok ! ( vote( Origin :: signed( 2 ) ,  vec![ 2 ] ,  20 ) ) ; 
2902+ 
2903+ 			System :: set_block_number ( 5 ) ; 
2904+ 			Elections :: end_block ( System :: block_number ( ) ) ; 
2905+ 
2906+ 			assert_eq ! ( Elections :: members_ids( ) ,  vec![ 4 ] ) ; 
2907+ 			assert_eq ! ( Elections :: runners_up_ids( ) ,  vec![ 2 ,  3 ] ) ; 
2908+ 
2909+ 			assert_eq ! ( balances( & 4 ) ,  ( 35 ,  5 ) ) ; 
2910+ 			assert_eq ! ( balances( & 3 ) ,  ( 25 ,  5 ) ) ; 
2911+ 			assert_eq ! ( balances( & 2 ) ,  ( 15 ,  5 ) ) ; 
2912+ 
2913+ 			// this guy will shift everyone down. 
2914+ 			assert_ok ! ( submit_candidacy( Origin :: signed( 5 ) ) ) ; 
2915+ 			assert_ok ! ( vote( Origin :: signed( 5 ) ,  vec![ 5 ] ,  50 ) ) ; 
2916+ 
2917+ 			System :: set_block_number ( 10 ) ; 
2918+ 			Elections :: end_block ( System :: block_number ( ) ) ; 
2919+ 
2920+ 			assert_eq ! ( Elections :: members_ids( ) ,  vec![ 5 ] ) ; 
2921+ 			assert_eq ! ( Elections :: runners_up_ids( ) ,  vec![ 3 ,  4 ] ) ; 
2922+ 
2923+ 			// 4 went from member to runner-up -- don't slash. 
2924+ 			assert_eq ! ( balances( & 4 ) ,  ( 35 ,  5 ) ) ; 
2925+ 			// 3 stayed runner-up -- don't slash. 
2926+ 			assert_eq ! ( balances( & 3 ) ,  ( 25 ,  5 ) ) ; 
2927+ 			// 2 was removed -- slash. 
2928+ 			assert_eq ! ( balances( & 2 ) ,  ( 15 ,  2 ) ) ; 
2929+ 		} ) ; 
2930+ 	} 
2931+ 
2932+ 	#[ test]  
2933+ 	fn  runner_up_to_member_wont_slash ( )  { 
2934+ 		ExtBuilder :: default ( ) . desired_runners_up ( 2 ) . desired_members ( 1 ) . build_and_execute ( || { 
2935+ 			assert_ok ! ( submit_candidacy( Origin :: signed( 4 ) ) ) ; 
2936+ 			assert_ok ! ( submit_candidacy( Origin :: signed( 3 ) ) ) ; 
2937+ 			assert_ok ! ( submit_candidacy( Origin :: signed( 2 ) ) ) ; 
2938+ 
2939+ 
2940+ 			assert_ok ! ( vote( Origin :: signed( 4 ) ,  vec![ 4 ] ,  40 ) ) ; 
2941+ 			assert_ok ! ( vote( Origin :: signed( 3 ) ,  vec![ 3 ] ,  30 ) ) ; 
2942+ 			assert_ok ! ( vote( Origin :: signed( 2 ) ,  vec![ 2 ] ,  20 ) ) ; 
2943+ 
2944+ 			System :: set_block_number ( 5 ) ; 
2945+ 			Elections :: end_block ( System :: block_number ( ) ) ; 
2946+ 
2947+ 			assert_eq ! ( Elections :: members_ids( ) ,  vec![ 4 ] ) ; 
2948+ 			assert_eq ! ( Elections :: runners_up_ids( ) ,  vec![ 2 ,  3 ] ) ; 
2949+ 
2950+ 			assert_eq ! ( balances( & 4 ) ,  ( 35 ,  5 ) ) ; 
2951+ 			assert_eq ! ( balances( & 3 ) ,  ( 25 ,  5 ) ) ; 
2952+ 			assert_eq ! ( balances( & 2 ) ,  ( 15 ,  5 ) ) ; 
2953+ 
2954+ 			// swap some votes. 
2955+ 			assert_ok ! ( vote( Origin :: signed( 4 ) ,  vec![ 2 ] ,  40 ) ) ; 
2956+ 			assert_ok ! ( vote( Origin :: signed( 2 ) ,  vec![ 4 ] ,  20 ) ) ; 
2957+ 
2958+ 			System :: set_block_number ( 10 ) ; 
2959+ 			Elections :: end_block ( System :: block_number ( ) ) ; 
2960+ 
2961+ 			assert_eq ! ( Elections :: members_ids( ) ,  vec![ 2 ] ) ; 
2962+ 			assert_eq ! ( Elections :: runners_up_ids( ) ,  vec![ 4 ,  3 ] ) ; 
2963+ 
2964+ 			// 2 went from runner to member, don't slash 
2965+ 			assert_eq ! ( balances( & 2 ) ,  ( 15 ,  5 ) ) ; 
2966+ 			// 4 went from member to runner, don't slash 
2967+ 			assert_eq ! ( balances( & 4 ) ,  ( 35 ,  5 ) ) ; 
2968+ 			// 3 stayed the same 
2969+ 			assert_eq ! ( balances( & 3 ) ,  ( 25 ,  5 ) ) ; 
2970+ 		} ) ; 
2971+ 	} 
28792972} 
0 commit comments