@@ -142,11 +142,13 @@ impl AssignmentEntry {
142142 let seed_bytes: [ u8 ; 32 ] = Buf32 :: from ( seed) . into ( ) ;
143143 let mut rng = ChaChaRng :: from_seed ( seed_bytes) ;
144144
145- let empty_bitmap = OperatorBitmap :: new_empty ( ) ; // No previous assignees at creation
145+ // No previous assignees at creation
146+ let previous_assignees =
147+ OperatorBitmap :: new_with_size ( deposit_entry. notary_operators_bitmap ( ) . len ( ) , false ) ;
146148
147149 let eligible_operators = filter_eligible_operators (
148- deposit_entry. notary_operators ( ) ,
149- & empty_bitmap ,
150+ deposit_entry. notary_operators_bitmap ( ) ,
151+ & previous_assignees ,
150152 current_active_operators,
151153 ) ;
152154
@@ -162,10 +164,10 @@ impl AssignmentEntry {
162164 let current_assignee = eligible_indices[ random_index] ;
163165
164166 Ok ( Self {
165- deposit_entry,
167+ deposit_entry : deposit_entry . clone ( ) ,
166168 withdrawal_cmd,
167169 current_assignee,
168- previous_assignees : OperatorBitmap :: new_empty ( ) ,
170+ previous_assignees,
169171 exec_deadline,
170172 } )
171173 }
@@ -230,16 +232,19 @@ impl AssignmentEntry {
230232
231233 // Use the already cached bitmap from DepositEntry instead of converting from Vec
232234 let mut eligible_operators = filter_eligible_operators (
233- self . deposit_entry . notary_operators ( ) ,
235+ self . deposit_entry . notary_operators_bitmap ( ) ,
234236 & self . previous_assignees ,
235237 current_active_operators,
236238 ) ;
237239
238240 if eligible_operators. not_any ( ) {
239241 // If no eligible operators left, clear previous assignees
240- self . previous_assignees = OperatorBitmap :: new_empty ( ) ;
242+ self . previous_assignees = OperatorBitmap :: new_with_size (
243+ self . deposit_entry . notary_operators_bitmap ( ) . len ( ) ,
244+ false ,
245+ ) ;
241246 eligible_operators = filter_eligible_operators (
242- self . deposit_entry . notary_operators ( ) ,
247+ self . deposit_entry . notary_operators_bitmap ( ) ,
243248 & self . previous_assignees ,
244249 current_active_operators,
245250 ) ;
@@ -388,7 +393,7 @@ impl AssignmentTable {
388393 ///
389394 /// ```rust,ignore
390395 /// let current_height = BitcoinBlockHeight::from(1000);
391- /// let active_operators = OperatorBitmap::new_sequential_active(3 );
396+ /// let active_operators = OperatorBitmap::new_with_size(3, true );
392397 /// let seed = L1BlockId::from([0u8; 32]);
393398 ///
394399 /// table.reassign_expired_assignments(current_height, &active_operators, seed)?;
@@ -432,7 +437,7 @@ mod tests {
432437 let seed: L1BlockId = arb. generate ( ) ;
433438
434439 // Use the deposit's notary operators as active operators
435- let current_active_operators = deposit_entry. notary_operators ( ) . clone ( ) ;
440+ let current_active_operators = deposit_entry. notary_operators_bitmap ( ) . clone ( ) ;
436441
437442 let result = AssignmentEntry :: create_with_random_assignment (
438443 deposit_entry. clone ( ) ,
@@ -482,21 +487,24 @@ mod tests {
482487 #[ test]
483488 fn test_reassign_success ( ) {
484489 let mut arb = ArbitraryGenerator :: new ( ) ;
485- let deposit_entry: DepositEntry = arb. generate ( ) ;
490+
491+ // Keep generating deposit entries until we have at least 2 active operators
492+ let deposit_entry: DepositEntry = loop {
493+ let candidate: DepositEntry = arb. generate ( ) ;
494+ if candidate. notary_operators_bitmap ( ) . active_count ( ) >= 2 {
495+ break candidate;
496+ }
497+ } ;
498+
486499 let withdrawal_cmd: WithdrawalCommand = arb. generate ( ) ;
487500 let exec_deadline: BitcoinBlockHeight = 100 ;
488501 let seed1: L1BlockId = arb. generate ( ) ;
489502 let seed2: L1BlockId = arb. generate ( ) ;
490503
491504 // Use the deposit's notary operators as active operators
492- let current_active_operators = deposit_entry. notary_operators ( ) . clone ( ) ;
505+ let current_active_operators = deposit_entry. notary_operators_bitmap ( ) . clone ( ) ;
493506 let new_fee = BitcoinAmount :: from_sat ( 20_000 ) ;
494507
495- // Ensure we have at least 2 operators for reassignment
496- if current_active_operators. active_count ( ) < 2 {
497- return ; // Skip test if not enough operators
498- }
499-
500508 let mut assignment = AssignmentEntry :: create_with_random_assignment (
501509 deposit_entry,
502510 withdrawal_cmd,
@@ -513,18 +521,10 @@ mod tests {
513521 let result = assignment. reassign ( new_fee, seed2, & current_active_operators) ;
514522 assert ! ( result. is_ok( ) ) ;
515523
516- // Verify reassignment - the behavior depends on how many operators are available
517- if assignment. previous_assignees ( ) . len ( ) == 1 {
518- // Normal case: different operator selected and previous assignee tracked
519- assert_eq ! ( assignment. previous_assignees( ) [ 0 ] , original_assignee) ;
520- assert_ne ! ( assignment. current_assignee( ) , original_assignee) ;
521- } else {
522- // Edge case: previous assignees were cleared during reassignment
523- // This happens when no eligible operators are found initially, forcing
524- // the reassignment logic to clear previous assignees and retry
525- assert_eq ! ( assignment. previous_assignees( ) . len( ) , 0 ) ;
526- }
527- assert ! ( current_active_operators. is_active( assignment. current_assignee( ) ) ) ;
524+ // Verify reassignment
525+ assert_eq ! ( assignment. previous_assignees( ) . len( ) , 1 ) ;
526+ assert_eq ! ( assignment. previous_assignees( ) [ 0 ] , original_assignee) ;
527+ assert_ne ! ( assignment. current_assignee( ) , original_assignee) ;
528528 }
529529
530530 #[ test]
@@ -533,7 +533,7 @@ mod tests {
533533 let mut deposit_entry: DepositEntry = arb. generate ( ) ;
534534
535535 // Force single operator for this test
536- let operators = OperatorBitmap :: new_sequential_active ( 1 ) ;
536+ let operators = OperatorBitmap :: new_with_size ( 1 , true ) ;
537537 deposit_entry = DepositEntry :: new (
538538 deposit_entry. idx ( ) ,
539539 * deposit_entry. output ( ) ,
@@ -548,7 +548,7 @@ mod tests {
548548 let seed1: L1BlockId = arb. generate ( ) ;
549549 let seed2: L1BlockId = arb. generate ( ) ;
550550
551- let current_active_operators = OperatorBitmap :: new_sequential_active ( 1 ) ; // Single operator with index 0
551+ let current_active_operators = OperatorBitmap :: new_with_size ( 1 , true ) ; // Single operator with index 0
552552
553553 let mut assignment = AssignmentEntry :: create_with_random_assignment (
554554 deposit_entry,
@@ -579,7 +579,7 @@ mod tests {
579579 let withdrawal_cmd: WithdrawalCommand = arb. generate ( ) ;
580580 let exec_deadline: BitcoinBlockHeight = 100 ;
581581 let seed: L1BlockId = arb. generate ( ) ;
582- let current_active_operators = deposit_entry. notary_operators ( ) . clone ( ) ;
582+ let current_active_operators = deposit_entry. notary_operators_bitmap ( ) . clone ( ) ;
583583
584584 let assignment = AssignmentEntry :: create_with_random_assignment (
585585 deposit_entry. clone ( ) ,
@@ -623,7 +623,7 @@ mod tests {
623623 let deposit_entry1: DepositEntry = arb. generate ( ) ;
624624 let withdrawal_cmd1: WithdrawalCommand = arb. generate ( ) ;
625625 let expired_deadline: BitcoinBlockHeight = 100 ; // Less than current_height
626- let current_active_operators1 = deposit_entry1. notary_operators ( ) . clone ( ) ;
626+ let current_active_operators1 = deposit_entry1. notary_operators_bitmap ( ) . clone ( ) ;
627627
628628 let expired_assignment = AssignmentEntry :: create_with_random_assignment (
629629 deposit_entry1. clone ( ) ,
@@ -642,7 +642,7 @@ mod tests {
642642 let deposit_entry2: DepositEntry = arb. generate ( ) ;
643643 let withdrawal_cmd2: WithdrawalCommand = arb. generate ( ) ;
644644 let future_deadline: BitcoinBlockHeight = 200 ; // Greater than current_height
645- let current_active_operators2 = deposit_entry2. notary_operators ( ) . clone ( ) ;
645+ let current_active_operators2 = deposit_entry2. notary_operators_bitmap ( ) . clone ( ) ;
646646
647647 let future_assignment = AssignmentEntry :: create_with_random_assignment (
648648 deposit_entry2. clone ( ) ,
@@ -680,7 +680,7 @@ mod tests {
680680 let expired_assignment_after = table. get_assignment ( expired_deposit_idx) . unwrap ( ) ;
681681
682682 // The behavior depends on how many eligible operators are available
683- let deposit1_notary_count = deposit_entry1. notary_operators ( ) . active_count ( ) ;
683+ let deposit1_notary_count = deposit_entry1. notary_operators_bitmap ( ) . active_count ( ) ;
684684 if deposit1_notary_count > 1
685685 && expired_assignment_after. current_assignee ( ) != original_assignee
686686 {
0 commit comments