@@ -635,3 +635,318 @@ impl TokenPerpetualDistributionMomentPaths for RewardDistributionMoment {
635635 }
636636 }
637637}
638+
639+ #[ cfg( feature = "server" ) ]
640+ #[ cfg( test) ]
641+ mod tests {
642+ use super :: * ;
643+ use crate :: drive:: RootTree ;
644+
645+ fn tokens_root_byte ( ) -> u8 {
646+ RootTree :: Tokens as u8
647+ }
648+
649+ /// Helper: verify array path and vec path produce identical data.
650+ fn assert_array_vec_consistent ( arr : & [ & [ u8 ] ] , v : & [ Vec < u8 > ] ) {
651+ assert_eq ! ( arr. len( ) , v. len( ) , "path lengths differ" ) ;
652+ for ( a, b) in arr. iter ( ) . zip ( v. iter ( ) ) {
653+ assert_eq ! ( * a, b. as_slice( ) ) ;
654+ }
655+ }
656+
657+ #[ test]
658+ fn root_paths_have_correct_structure ( ) {
659+ // All root-level paths: 1 segment (tokens root) or 2 segments (tokens root + subtree key)
660+ let root = tokens_root_path ( ) ;
661+ assert_eq ! ( root. len( ) , 1 ) ;
662+ assert_eq ! ( root[ 0 ] , & [ tokens_root_byte( ) ] ) ;
663+
664+ // 2-segment root paths: balances, direct_purchase, identity_infos, contract_infos, statuses, distributions
665+ for ( arr, v, key) in [
666+ (
667+ token_balances_root_path ( ) . to_vec ( ) ,
668+ token_balances_root_path_vec ( ) ,
669+ TOKEN_BALANCES_KEY ,
670+ ) ,
671+ (
672+ token_direct_purchase_root_path ( ) . to_vec ( ) ,
673+ token_direct_purchase_root_path_vec ( ) ,
674+ TOKEN_DIRECT_SELL_PRICE_KEY ,
675+ ) ,
676+ (
677+ token_identity_infos_root_path ( ) . to_vec ( ) ,
678+ token_identity_infos_root_path_vec ( ) ,
679+ TOKEN_IDENTITY_INFO_KEY ,
680+ ) ,
681+ (
682+ token_contract_infos_root_path ( ) . to_vec ( ) ,
683+ token_contract_infos_root_path_vec ( ) ,
684+ TOKEN_CONTRACT_INFO_KEY ,
685+ ) ,
686+ (
687+ token_statuses_root_path ( ) . to_vec ( ) ,
688+ token_statuses_root_path_vec ( ) ,
689+ TOKEN_STATUS_INFO_KEY ,
690+ ) ,
691+ (
692+ token_distributions_root_path ( ) . to_vec ( ) ,
693+ token_distributions_root_path_vec ( ) ,
694+ TOKEN_DISTRIBUTIONS_KEY ,
695+ ) ,
696+ ] {
697+ assert_eq ! ( arr. len( ) , 2 ) ;
698+ assert_eq ! ( v. len( ) , 2 ) ;
699+ assert_eq ! ( arr[ 0 ] , & [ tokens_root_byte( ) ] ) ;
700+ assert_eq ! ( v[ 1 ] , vec![ key] ) ;
701+ }
702+ }
703+
704+ #[ test]
705+ fn distribution_subtree_paths_have_correct_structure ( ) {
706+ let t = tokens_root_byte ( ) ;
707+
708+ // 3-segment paths: timed, perpetual, pre-programmed distributions
709+ assert_array_vec_consistent (
710+ & token_timed_distributions_path ( ) ,
711+ & token_timed_distributions_path_vec ( ) ,
712+ ) ;
713+ assert_eq ! (
714+ token_timed_distributions_path( ) [ 2 ] ,
715+ & [ TOKEN_TIMED_DISTRIBUTIONS_KEY ]
716+ ) ;
717+
718+ assert_array_vec_consistent (
719+ & token_root_perpetual_distributions_path ( ) ,
720+ & token_root_perpetual_distributions_path_vec ( ) ,
721+ ) ;
722+ assert_eq ! (
723+ token_root_perpetual_distributions_path( ) [ 2 ] ,
724+ & [ TOKEN_PERPETUAL_DISTRIBUTIONS_KEY ]
725+ ) ;
726+
727+ assert_array_vec_consistent (
728+ & token_root_pre_programmed_distributions_path ( ) ,
729+ & token_root_pre_programmed_distributions_path_vec ( ) ,
730+ ) ;
731+ assert_eq ! (
732+ token_root_pre_programmed_distributions_path( ) [ 2 ] ,
733+ & [ TOKEN_PRE_PROGRAMMED_DISTRIBUTIONS_KEY ]
734+ ) ;
735+
736+ // 4-segment timed distribution paths
737+ for ( arr, v, key) in [
738+ (
739+ token_ms_timed_distributions_path ( ) . to_vec ( ) ,
740+ token_ms_timed_distributions_path_vec ( ) ,
741+ TOKEN_MS_TIMED_DISTRIBUTIONS_KEY ,
742+ ) ,
743+ (
744+ token_block_timed_distributions_path ( ) . to_vec ( ) ,
745+ token_block_timed_distributions_path_vec ( ) ,
746+ TOKEN_BLOCK_TIMED_DISTRIBUTIONS_KEY ,
747+ ) ,
748+ (
749+ token_epoch_timed_distributions_path ( ) . to_vec ( ) ,
750+ token_epoch_timed_distributions_path_vec ( ) ,
751+ TOKEN_EPOCH_TIMED_DISTRIBUTIONS_KEY ,
752+ ) ,
753+ ] {
754+ assert_eq ! ( arr. len( ) , 4 ) ;
755+ assert_eq ! ( v. len( ) , 4 ) ;
756+ assert_eq ! ( arr[ 0 ] , & [ t] ) ;
757+ assert_eq ! ( v[ 3 ] , vec![ key] ) ;
758+ }
759+ }
760+
761+ #[ test]
762+ fn token_id_paths_include_id_and_are_consistent ( ) {
763+ let token_id = [ 0xAAu8 ; 32 ] ;
764+
765+ // Balances, identity infos, contract infos — all 3-segment with token_id
766+ assert_array_vec_consistent (
767+ & token_balances_path ( & token_id) ,
768+ & token_balances_path_vec ( token_id) ,
769+ ) ;
770+ assert_eq ! ( token_balances_path( & token_id) [ 2 ] , & token_id) ;
771+
772+ assert_array_vec_consistent (
773+ & token_identity_infos_path ( & token_id) ,
774+ & token_identity_infos_path_vec ( token_id) ,
775+ ) ;
776+ assert_eq ! ( token_identity_infos_path( & token_id) [ 2 ] , & token_id) ;
777+
778+ assert_array_vec_consistent (
779+ & token_contract_infos_path ( & token_id) ,
780+ & token_contract_infos_path_vec ( token_id) ,
781+ ) ;
782+ assert_eq ! ( token_contract_infos_path( & token_id) [ 2 ] , & token_id) ;
783+
784+ // Perpetual + pre-programmed distribution with token_id — 4-segment
785+ let perp = token_perpetual_distributions_path ( & token_id) ;
786+ assert_eq ! ( perp. len( ) , 4 ) ;
787+ assert_eq ! ( perp[ 3 ] , & token_id) ;
788+
789+ let pre = token_pre_programmed_distributions_path ( & token_id) ;
790+ assert_eq ! ( pre. len( ) , 4 ) ;
791+ assert_eq ! ( pre[ 3 ] , & token_id) ;
792+
793+ // Different token_ids produce different paths
794+ let other_id = [ 0xBBu8 ; 32 ] ;
795+ assert_ne ! (
796+ token_balances_path_vec( token_id) [ 2 ] ,
797+ token_balances_path_vec( other_id) [ 2 ]
798+ ) ;
799+ }
800+
801+ #[ test]
802+ fn parameterized_distribution_paths ( ) {
803+ let token_id = [ 0xCCu8 ; 32 ] ;
804+ let identity_id = [ 0xDDu8 ; 32 ] ;
805+
806+ // Perpetual distribution claim paths
807+ let claim_time = token_perpetual_distributions_identity_last_claimed_time_path ( & token_id) ;
808+ assert_eq ! ( claim_time. len( ) , 5 ) ;
809+ assert_eq ! ( claim_time[ 3 ] , & token_id) ;
810+ assert_eq ! (
811+ claim_time[ 4 ] ,
812+ & [ TOKEN_PERPETUAL_DISTRIBUTIONS_FOR_IDENTITIES_LAST_CLAIM_KEY ]
813+ ) ;
814+
815+ let claim_by_id = token_perpetual_distributions_identity_last_claimed_by_identity_path (
816+ & token_id,
817+ & identity_id,
818+ ) ;
819+ assert_eq ! ( claim_by_id. len( ) , 6 ) ;
820+ assert_eq ! ( claim_by_id[ 5 ] , & identity_id) ;
821+
822+ // Pre-programmed distribution claim paths
823+ let pre_claim =
824+ token_pre_programmed_distributions_identity_last_claimed_time_path ( & token_id) ;
825+ assert_eq ! ( pre_claim. len( ) , 5 ) ;
826+ assert_eq ! ( pre_claim[ 2 ] , & [ TOKEN_PRE_PROGRAMMED_DISTRIBUTIONS_KEY ] ) ;
827+
828+ // Timed at specific time/block/epoch
829+ let ts: u64 = 42000 ;
830+ assert_eq ! (
831+ token_ms_timed_at_time_distributions_path_vec( ts) [ 4 ] ,
832+ ts. to_be_bytes( ) . to_vec( )
833+ ) ;
834+
835+ let height: u64 = 500 ;
836+ assert_eq ! (
837+ token_block_timed_at_block_distributions_path_vec( height) [ 4 ] ,
838+ height. to_be_bytes( ) . to_vec( )
839+ ) ;
840+
841+ let epoch: u16 = 10 ;
842+ assert_eq ! (
843+ token_epoch_timed_at_epoch_distributions_path_vec( epoch) [ 4 ] ,
844+ epoch. to_be_bytes( ) . to_vec( )
845+ ) ;
846+
847+ // Pre-programmed at time
848+ let pre_time = token_pre_programmed_at_time_distribution_path_vec ( token_id, 1234567890 ) ;
849+ assert_eq ! ( pre_time. len( ) , 5 ) ;
850+ assert_eq ! ( pre_time[ 3 ] , token_id. to_vec( ) ) ;
851+ }
852+
853+ #[ test]
854+ fn array_and_vec_consistency_for_all_root_and_subtree_paths ( ) {
855+ let token_id = [ 0xFFu8 ; 32 ] ;
856+
857+ // All pairs of array/vec path functions
858+ assert_array_vec_consistent ( & tokens_root_path ( ) , & tokens_root_path_vec ( ) ) ;
859+ assert_array_vec_consistent ( & token_balances_root_path ( ) , & token_balances_root_path_vec ( ) ) ;
860+ assert_array_vec_consistent (
861+ & token_direct_purchase_root_path ( ) ,
862+ & token_direct_purchase_root_path_vec ( ) ,
863+ ) ;
864+ assert_array_vec_consistent (
865+ & token_identity_infos_root_path ( ) ,
866+ & token_identity_infos_root_path_vec ( ) ,
867+ ) ;
868+ assert_array_vec_consistent (
869+ & token_contract_infos_root_path ( ) ,
870+ & token_contract_infos_root_path_vec ( ) ,
871+ ) ;
872+ assert_array_vec_consistent ( & token_statuses_root_path ( ) , & token_statuses_root_path_vec ( ) ) ;
873+ assert_array_vec_consistent (
874+ & token_distributions_root_path ( ) ,
875+ & token_distributions_root_path_vec ( ) ,
876+ ) ;
877+ assert_array_vec_consistent (
878+ & token_balances_path ( & token_id) ,
879+ & token_balances_path_vec ( token_id) ,
880+ ) ;
881+ assert_array_vec_consistent (
882+ & token_timed_distributions_path ( ) ,
883+ & token_timed_distributions_path_vec ( ) ,
884+ ) ;
885+ assert_array_vec_consistent (
886+ & token_root_perpetual_distributions_path ( ) ,
887+ & token_root_perpetual_distributions_path_vec ( ) ,
888+ ) ;
889+ assert_array_vec_consistent (
890+ & token_root_pre_programmed_distributions_path ( ) ,
891+ & token_root_pre_programmed_distributions_path_vec ( ) ,
892+ ) ;
893+ assert_array_vec_consistent (
894+ & token_ms_timed_distributions_path ( ) ,
895+ & token_ms_timed_distributions_path_vec ( ) ,
896+ ) ;
897+ assert_array_vec_consistent (
898+ & token_block_timed_distributions_path ( ) ,
899+ & token_block_timed_distributions_path_vec ( ) ,
900+ ) ;
901+ assert_array_vec_consistent (
902+ & token_epoch_timed_distributions_path ( ) ,
903+ & token_epoch_timed_distributions_path_vec ( ) ,
904+ ) ;
905+ }
906+
907+ #[ test]
908+ fn key_constants_have_expected_values ( ) {
909+ assert_eq ! ( TOKEN_STATUS_INFO_KEY , 64 ) ;
910+ assert_eq ! ( TOKEN_IDENTITY_INFO_KEY , 192 ) ;
911+ assert_eq ! ( TOKEN_CONTRACT_INFO_KEY , 160 ) ;
912+ assert_eq ! ( TOKEN_BALANCES_KEY , 128 ) ;
913+ assert_eq ! ( TOKEN_DIRECT_SELL_PRICE_KEY , 92 ) ;
914+ assert_eq ! ( TOKEN_DISTRIBUTIONS_KEY , 32 ) ;
915+ assert_eq ! ( TOKEN_TIMED_DISTRIBUTIONS_KEY , 128 ) ;
916+ assert_eq ! ( TOKEN_PERPETUAL_DISTRIBUTIONS_KEY , 64 ) ;
917+ assert_eq ! ( TOKEN_PRE_PROGRAMMED_DISTRIBUTIONS_KEY , 192 ) ;
918+ assert_eq ! ( TOKEN_MS_TIMED_DISTRIBUTIONS_KEY , 128 ) ;
919+ assert_eq ! ( TOKEN_BLOCK_TIMED_DISTRIBUTIONS_KEY , 64 ) ;
920+ assert_eq ! ( TOKEN_EPOCH_TIMED_DISTRIBUTIONS_KEY , 192 ) ;
921+ assert_eq ! ( TOKEN_PERPETUAL_DISTRIBUTIONS_INFO_KEY , 128 ) ;
922+ assert_eq ! (
923+ TOKEN_PERPETUAL_DISTRIBUTIONS_FOR_IDENTITIES_LAST_CLAIM_KEY ,
924+ 192
925+ ) ;
926+ assert_eq ! (
927+ TOKEN_PRE_PROGRAMMED_DISTRIBUTIONS_FOR_IDENTITIES_LAST_CLAIM_KEY ,
928+ 192
929+ ) ;
930+ }
931+
932+ #[ test]
933+ fn reward_distribution_moment_paths ( ) {
934+ let block = RewardDistributionMoment :: BlockBasedMoment ( 100 ) ;
935+ assert_eq ! (
936+ block. distribution_path( ) ,
937+ token_block_timed_at_block_distributions_path_vec( 100 )
938+ ) ;
939+
940+ let time = RewardDistributionMoment :: TimeBasedMoment ( 5000 ) ;
941+ assert_eq ! (
942+ time. distribution_path( ) ,
943+ token_ms_timed_at_time_distributions_path_vec( 5000 )
944+ ) ;
945+
946+ let epoch = RewardDistributionMoment :: EpochBasedMoment ( 7 ) ;
947+ assert_eq ! (
948+ epoch. distribution_path( ) ,
949+ token_epoch_timed_at_epoch_distributions_path_vec( 7 )
950+ ) ;
951+ }
952+ }
0 commit comments