@@ -629,3 +629,337 @@ async def test_get_total_stake_for_hotkey(subtensor, mocker):
629
629
)
630
630
mocked_substrate_query_multiple .assert_called_once ()
631
631
assert result == {0 : async_subtensor .Balance (1 )}
632
+
633
+
634
+ @pytest .mark .parametrize (
635
+ "records, response" ,
636
+ [([(0 , True ), (1 , False ), (3 , False ), (3 , True )], [0 , 3 ]), ([], [])],
637
+ ids = ["with records" , "empty-records" ],
638
+ )
639
+ @pytest .mark .asyncio
640
+ async def test_get_netuids_for_hotkey (subtensor , mocker , records , response ):
641
+ """Tests get_netuids_for_hotkey method."""
642
+ # Preps
643
+ fake_result = mocker .AsyncMock (autospec = list )
644
+ fake_result .records = records
645
+ fake_result .__aiter__ .return_value = iter (records )
646
+
647
+ mocked_substrate_query_map = mocker .AsyncMock (
648
+ autospec = async_subtensor .AsyncSubstrateInterface .query_map ,
649
+ return_value = fake_result ,
650
+ )
651
+
652
+ subtensor .substrate .query_map = mocked_substrate_query_map
653
+ fake_hotkey_ss58 = "hotkey_58"
654
+ fake_block_hash = None
655
+
656
+ # Call
657
+ result = await subtensor .get_netuids_for_hotkey (
658
+ hotkey_ss58 = fake_hotkey_ss58 , block_hash = fake_block_hash , reuse_block = True
659
+ )
660
+
661
+ # Assertions
662
+ mocked_substrate_query_map .assert_called_once_with (
663
+ module = "SubtensorModule" ,
664
+ storage_function = "IsNetworkMember" ,
665
+ params = [fake_hotkey_ss58 ],
666
+ block_hash = fake_block_hash ,
667
+ reuse_block_hash = True ,
668
+ )
669
+ assert result == response
670
+
671
+
672
+ @pytest .mark .asyncio
673
+ async def test_subnet_exists (subtensor , mocker ):
674
+ """Tests subnet_exists method ."""
675
+ # Preps
676
+ fake_netuid = 1
677
+ fake_block_hash = "block_hash"
678
+ fake_reuse_block_hash = True
679
+
680
+ mocked_substrate_query = mocker .AsyncMock (
681
+ autospec = async_subtensor .AsyncSubstrateInterface .query
682
+ )
683
+ subtensor .substrate .query = mocked_substrate_query
684
+
685
+ # Call
686
+ result = await subtensor .subnet_exists (
687
+ netuid = fake_netuid ,
688
+ block_hash = fake_block_hash ,
689
+ reuse_block = fake_reuse_block_hash ,
690
+ )
691
+
692
+ # Asserts
693
+ mocked_substrate_query .assert_called_once_with (
694
+ module = "SubtensorModule" ,
695
+ storage_function = "NetworksAdded" ,
696
+ params = [fake_netuid ],
697
+ block_hash = fake_block_hash ,
698
+ reuse_block_hash = fake_reuse_block_hash ,
699
+ )
700
+ assert result == mocked_substrate_query .return_value
701
+
702
+
703
+ @pytest .mark .asyncio
704
+ async def test_get_hyperparameter_happy_path (subtensor , mocker ):
705
+ """Tests get_hyperparameter method with happy path."""
706
+ # Preps
707
+ fake_param_name = "param_name"
708
+ fake_netuid = 1
709
+ fake_block_hash = "block_hash"
710
+ fake_reuse_block_hash = True
711
+
712
+ # kind of fake subnet exists
713
+ mocked_subtensor_subnet_exists = mocker .AsyncMock (return_value = True )
714
+ subtensor .subnet_exists = mocked_subtensor_subnet_exists
715
+
716
+ mocked_substrate_query = mocker .AsyncMock (
717
+ autospec = async_subtensor .AsyncSubstrateInterface .query
718
+ )
719
+ subtensor .substrate .query = mocked_substrate_query
720
+
721
+ # Call
722
+ result = await subtensor .get_hyperparameter (
723
+ param_name = fake_param_name ,
724
+ netuid = fake_netuid ,
725
+ block_hash = fake_block_hash ,
726
+ reuse_block = fake_reuse_block_hash ,
727
+ )
728
+
729
+ # Assertions
730
+ mocked_subtensor_subnet_exists .assert_called_once ()
731
+ mocked_substrate_query .assert_called_once_with (
732
+ module = "SubtensorModule" ,
733
+ storage_function = fake_param_name ,
734
+ params = [fake_netuid ],
735
+ block_hash = fake_block_hash ,
736
+ reuse_block_hash = fake_reuse_block_hash ,
737
+ )
738
+ assert result == mocked_substrate_query .return_value
739
+
740
+
741
+ @pytest .mark .asyncio
742
+ async def test_get_hyperparameter_if_subnet_does_not_exist (subtensor , mocker ):
743
+ """Tests get_hyperparameter method if subnet does not exist."""
744
+ # Preps
745
+ # kind of fake subnet doesn't exist
746
+ mocked_subtensor_subnet_exists = mocker .AsyncMock (return_value = False )
747
+ subtensor .subnet_exists = mocked_subtensor_subnet_exists
748
+
749
+ mocked_substrate_query = mocker .AsyncMock (
750
+ autospec = async_subtensor .AsyncSubstrateInterface .query
751
+ )
752
+ subtensor .substrate .query = mocked_substrate_query
753
+
754
+ # Call
755
+ result = await subtensor .get_hyperparameter (mocker .Mock (), mocker .Mock ())
756
+
757
+ # Assertions
758
+ mocked_subtensor_subnet_exists .assert_called_once ()
759
+ mocked_substrate_query .assert_not_called ()
760
+ assert result is None
761
+
762
+
763
+ @pytest .mark .parametrize (
764
+ "all_netuids, filter_for_netuids, response" ,
765
+ [([1 , 2 ], [3 , 4 ], []), ([1 , 2 ], [1 , 3 ], [1 ]), ([1 , 2 ], None , [1 , 2 ])],
766
+ ids = [
767
+ "all arguments -> no comparison" ,
768
+ "all arguments -> is comparison" ,
769
+ "not filter_for_netuids" ,
770
+ ],
771
+ )
772
+ @pytest .mark .asyncio
773
+ async def test_filter_netuids_by_registered_hotkeys (
774
+ subtensor , mocker , all_netuids , filter_for_netuids , response
775
+ ):
776
+ """Tests filter_netuids_by_registered_hotkeys method."""
777
+ # Preps
778
+ fake_wallet_1 = mocker .Mock (autospec = async_subtensor .Wallet )
779
+ fake_wallet_1 .hotkey .ss58_address = "ss58_address_1"
780
+ fake_wallet_2 = mocker .Mock (autospec = async_subtensor .Wallet )
781
+ fake_wallet_2 .hotkey .ss58_address = "ss58_address_2"
782
+
783
+ fake_all_netuids = all_netuids
784
+ fake_filter_for_netuids = filter_for_netuids
785
+ fake_all_hotkeys = [fake_wallet_1 , fake_wallet_2 ]
786
+ fake_block_hash = "fake_block_hash"
787
+ fake_reuse_block = True
788
+
789
+ mocked_get_netuids_for_hotkey = mocker .AsyncMock (
790
+ # returned subnets list
791
+ return_value = [1 , 2 ]
792
+ )
793
+ subtensor .get_netuids_for_hotkey = mocked_get_netuids_for_hotkey
794
+
795
+ # Call
796
+
797
+ result = await subtensor .filter_netuids_by_registered_hotkeys (
798
+ all_netuids = fake_all_netuids ,
799
+ filter_for_netuids = fake_filter_for_netuids ,
800
+ all_hotkeys = fake_all_hotkeys ,
801
+ block_hash = fake_block_hash ,
802
+ reuse_block = fake_reuse_block ,
803
+ )
804
+
805
+ # Asserts
806
+ mocked_get_netuids_for_hotkey .call_count = len (fake_all_netuids )
807
+ assert mocked_get_netuids_for_hotkey .mock_calls == [
808
+ mocker .call (
809
+ w .hotkey .ss58_address ,
810
+ block_hash = fake_block_hash ,
811
+ reuse_block = fake_reuse_block ,
812
+ )
813
+ for w in fake_all_hotkeys
814
+ ]
815
+ assert result == response
816
+
817
+
818
+ @pytest .mark .asyncio
819
+ async def test_get_existential_deposit_happy_path (subtensor , mocker ):
820
+ """Tests get_existential_deposit method."""
821
+ # Preps
822
+ fake_block_hash = "block_hash"
823
+ fake_reuse_block_hash = True
824
+
825
+ mocked_substrate_get_constant = mocker .AsyncMock (return_value = 1 )
826
+ subtensor .substrate .get_constant = mocked_substrate_get_constant
827
+
828
+ spy_balance_from_rao = mocker .spy (async_subtensor .Balance , "from_rao" )
829
+
830
+ # Call
831
+ result = await subtensor .get_existential_deposit (
832
+ block_hash = fake_block_hash , reuse_block = fake_reuse_block_hash
833
+ )
834
+
835
+ # Asserts
836
+ mocked_substrate_get_constant .assert_awaited_once ()
837
+ mocked_substrate_get_constant .assert_called_once_with (
838
+ module_name = "Balances" ,
839
+ constant_name = "ExistentialDeposit" ,
840
+ block_hash = fake_block_hash ,
841
+ reuse_block_hash = fake_reuse_block_hash ,
842
+ )
843
+ spy_balance_from_rao .assert_called_once_with (
844
+ mocked_substrate_get_constant .return_value
845
+ )
846
+ assert result == async_subtensor .Balance (mocked_substrate_get_constant .return_value )
847
+
848
+
849
+ @pytest .mark .asyncio
850
+ async def test_get_existential_deposit_raise_exception (subtensor , mocker ):
851
+ """Tests get_existential_deposit method raise Exception."""
852
+ # Preps
853
+ fake_block_hash = "block_hash"
854
+ fake_reuse_block_hash = True
855
+
856
+ mocked_substrate_get_constant = mocker .AsyncMock (return_value = None )
857
+ subtensor .substrate .get_constant = mocked_substrate_get_constant
858
+
859
+ spy_balance_from_rao = mocker .spy (async_subtensor .Balance , "from_rao" )
860
+
861
+ # Call
862
+ with pytest .raises (Exception ):
863
+ await subtensor .get_existential_deposit (
864
+ block_hash = fake_block_hash , reuse_block = fake_reuse_block_hash
865
+ )
866
+
867
+ # Asserts
868
+ mocked_substrate_get_constant .assert_awaited_once ()
869
+ mocked_substrate_get_constant .assert_called_once_with (
870
+ module_name = "Balances" ,
871
+ constant_name = "ExistentialDeposit" ,
872
+ block_hash = fake_block_hash ,
873
+ reuse_block_hash = fake_reuse_block_hash ,
874
+ )
875
+ spy_balance_from_rao .assert_not_called ()
876
+
877
+
878
+ @pytest .mark .asyncio
879
+ async def test_neurons (subtensor , mocker ):
880
+ """Tests neurons method."""
881
+ # Preps
882
+ fake_netuid = 1
883
+ fake_block_hash = "block_hash"
884
+ fake_neurons = [mocker .Mock (), mocker .Mock ()]
885
+ fake_weights = [(1 , [(10 , 20 ), (30 , 40 )]), (2 , [(50 , 60 ), (70 , 80 )])]
886
+ fake_bonds = [(1 , [(10 , 20 ), (30 , 40 )]), (2 , [(50 , 60 ), (70 , 80 )])]
887
+
888
+ mocked_neurons_lite = mocker .AsyncMock (return_value = fake_neurons )
889
+ subtensor .neurons_lite = mocked_neurons_lite
890
+
891
+ mocked_weights = mocker .AsyncMock (return_value = fake_weights )
892
+ subtensor .weights = mocked_weights
893
+
894
+ mocked_bonds = mocker .AsyncMock (return_value = fake_bonds )
895
+ subtensor .bonds = mocked_bonds
896
+
897
+ mocked_neuron_info_method = mocker .Mock ()
898
+ async_subtensor .NeuronInfo .from_weights_bonds_and_neuron_lite = (
899
+ mocked_neuron_info_method
900
+ )
901
+
902
+ # Call
903
+ result = await subtensor .neurons (netuid = fake_netuid , block_hash = fake_block_hash )
904
+
905
+ # Asserts
906
+ mocked_neurons_lite .assert_awaited_once ()
907
+ mocked_neurons_lite .assert_called_once_with (
908
+ netuid = fake_netuid , block_hash = fake_block_hash
909
+ )
910
+ mocked_weights .assert_awaited_once ()
911
+ mocked_weights .assert_called_once_with (
912
+ netuid = fake_netuid , block_hash = fake_block_hash
913
+ )
914
+ mocked_bonds .assert_awaited_once ()
915
+ mocked_bonds .assert_called_once_with (netuid = fake_netuid , block_hash = fake_block_hash )
916
+ assert result == [
917
+ mocked_neuron_info_method .return_value for _ in range (len (fake_neurons ))
918
+ ]
919
+
920
+
921
+ @pytest .mark .parametrize (
922
+ "fake_hex_bytes_result, response" ,
923
+ [(None , []), ("0xaabbccdd" , b"\xaa \xbb \xcc \xdd " )],
924
+ ids = ["none" , "with data" ],
925
+ )
926
+ @pytest .mark .asyncio
927
+ async def test_neurons_lite (subtensor , mocker , fake_hex_bytes_result , response ):
928
+ """Tests neurons_lite method."""
929
+ # Preps
930
+ fake_netuid = 1
931
+ fake_block_hash = "block_hash"
932
+ fake_reuse_block_hash = True
933
+
934
+ mocked_query_runtime_api = mocker .AsyncMock (return_value = fake_hex_bytes_result )
935
+ subtensor .query_runtime_api = mocked_query_runtime_api
936
+
937
+ mocked_neuron_info_lite_list_from_vec_u8 = mocker .Mock ()
938
+ async_subtensor .NeuronInfoLite .list_from_vec_u8 = (
939
+ mocked_neuron_info_lite_list_from_vec_u8
940
+ )
941
+
942
+ # Call
943
+ result = await subtensor .neurons_lite (
944
+ netuid = fake_netuid ,
945
+ block_hash = fake_block_hash ,
946
+ reuse_block = fake_reuse_block_hash ,
947
+ )
948
+
949
+ # Assertions
950
+ mocked_query_runtime_api .assert_awaited_once ()
951
+ mocked_query_runtime_api .assert_called_once_with (
952
+ runtime_api = "NeuronInfoRuntimeApi" ,
953
+ method = "get_neurons_lite" ,
954
+ params = [fake_netuid ],
955
+ block_hash = fake_block_hash ,
956
+ reuse_block = fake_reuse_block_hash ,
957
+ )
958
+ if fake_hex_bytes_result :
959
+ mocked_neuron_info_lite_list_from_vec_u8 .assert_called_once_with (
960
+ bytes .fromhex (fake_hex_bytes_result [2 :])
961
+ )
962
+ assert result == mocked_neuron_info_lite_list_from_vec_u8 .return_value
963
+ else :
964
+ mocked_neuron_info_lite_list_from_vec_u8 .assert_not_called ()
965
+ assert result == []
0 commit comments