@@ -323,6 +323,37 @@ impl<E: EthSpec> CustodyContext<E> {
323
323
. expect ( "all_custody_columns_ordered should be initialized" ) ;
324
324
& all_columns_ordered[ ..num_of_columns_to_sample]
325
325
}
326
+
327
+ /// Returns the ordered list of column indices that the node is assigned to custody
328
+ /// (and advertised to peers) at the given epoch. If epoch is `None`, this function
329
+ /// computes the custody columns at head.
330
+ ///
331
+ /// This method differs from [`self::sampling_columns_for_epoch`] which returns all sampling columns.
332
+ /// The columns returned by this method are either identical to or a subset of the sampling columns,
333
+ /// representing only those columns that this node is responsible for maintaining custody of.
334
+ ///
335
+ /// # Parameters
336
+ /// * `epoch_opt` - Optional epoch to determine custody columns for.
337
+ ///
338
+ /// # Returns
339
+ /// A slice of ordered custody column indices for this epoch based on the node's custody configuration
340
+ pub fn custody_columns_for_epoch (
341
+ & self ,
342
+ epoch_opt : Option < Epoch > ,
343
+ spec : & ChainSpec ,
344
+ ) -> & [ ColumnIndex ] {
345
+ let custody_group_count = if let Some ( epoch) = epoch_opt {
346
+ self . custody_group_count_at_epoch ( epoch, spec) as usize
347
+ } else {
348
+ self . custody_group_count_at_head ( spec) as usize
349
+ } ;
350
+
351
+ let all_columns_ordered = self
352
+ . all_custody_columns_ordered
353
+ . get ( )
354
+ . expect ( "all_custody_columns_ordered should be initialized" ) ;
355
+ & all_columns_ordered[ ..custody_group_count]
356
+ }
326
357
}
327
358
328
359
/// The custody count changed because of a change in the
@@ -670,4 +701,82 @@ mod tests {
670
701
assert_eq ! ( updated_custody_count_opt, expected_cgc_change) ;
671
702
}
672
703
}
704
+
705
+ #[ test]
706
+ fn custody_columns_for_epoch_no_validators_fullnode ( ) {
707
+ let custody_context = CustodyContext :: < E > :: new ( false ) ;
708
+ let spec = E :: default_spec ( ) ;
709
+ let all_custody_groups_ordered = ( 0 ..spec. number_of_custody_groups ) . collect :: < Vec < _ > > ( ) ;
710
+
711
+ custody_context
712
+ . init_ordered_data_columns_from_custody_groups ( all_custody_groups_ordered, & spec)
713
+ . expect ( "should initialise ordered data columns" ) ;
714
+
715
+ assert_eq ! (
716
+ custody_context. custody_columns_for_epoch( None , & spec) . len( ) ,
717
+ spec. custody_requirement as usize
718
+ ) ;
719
+ }
720
+
721
+ #[ test]
722
+ fn custody_columns_for_epoch_no_validators_supernode ( ) {
723
+ let custody_context = CustodyContext :: < E > :: new ( true ) ;
724
+ let spec = E :: default_spec ( ) ;
725
+ let all_custody_groups_ordered = ( 0 ..spec. number_of_custody_groups ) . collect :: < Vec < _ > > ( ) ;
726
+
727
+ custody_context
728
+ . init_ordered_data_columns_from_custody_groups ( all_custody_groups_ordered, & spec)
729
+ . expect ( "should initialise ordered data columns" ) ;
730
+
731
+ assert_eq ! (
732
+ custody_context. custody_columns_for_epoch( None , & spec) . len( ) ,
733
+ spec. number_of_custody_groups as usize
734
+ ) ;
735
+ }
736
+
737
+ #[ test]
738
+ fn custody_columns_for_epoch_with_validators_should_match_cgc ( ) {
739
+ let custody_context = CustodyContext :: < E > :: new ( false ) ;
740
+ let spec = E :: default_spec ( ) ;
741
+ let all_custody_groups_ordered = ( 0 ..spec. number_of_custody_groups ) . collect :: < Vec < _ > > ( ) ;
742
+ let val_custody_units = 10 ;
743
+
744
+ custody_context
745
+ . init_ordered_data_columns_from_custody_groups ( all_custody_groups_ordered, & spec)
746
+ . expect ( "should initialise ordered data columns" ) ;
747
+
748
+ let _ = custody_context. register_validators (
749
+ vec ! [ (
750
+ 0 ,
751
+ val_custody_units * spec. balance_per_additional_custody_group,
752
+ ) ] ,
753
+ Slot :: new ( 10 ) ,
754
+ & spec,
755
+ ) ;
756
+
757
+ assert_eq ! (
758
+ custody_context. custody_columns_for_epoch( None , & spec) . len( ) ,
759
+ val_custody_units as usize
760
+ ) ;
761
+ }
762
+
763
+ #[ test]
764
+ fn custody_columns_for_epoch_specific_epoch_uses_epoch_cgc ( ) {
765
+ let custody_context = CustodyContext :: < E > :: new ( false ) ;
766
+ let spec = E :: default_spec ( ) ;
767
+ let all_custody_groups_ordered = ( 0 ..spec. number_of_custody_groups ) . collect :: < Vec < _ > > ( ) ;
768
+ let test_epoch = Epoch :: new ( 5 ) ;
769
+
770
+ custody_context
771
+ . init_ordered_data_columns_from_custody_groups ( all_custody_groups_ordered, & spec)
772
+ . expect ( "should initialise ordered data columns" ) ;
773
+
774
+ let expected_cgc = custody_context. custody_group_count_at_epoch ( test_epoch, & spec) ;
775
+ assert_eq ! (
776
+ custody_context
777
+ . custody_columns_for_epoch( Some ( test_epoch) , & spec)
778
+ . len( ) ,
779
+ expected_cgc as usize
780
+ ) ;
781
+ }
673
782
}
0 commit comments