@@ -616,3 +616,109 @@ async def test_resync_removes_stale_neuron(observer):
616616
617617 observer .database .remove_neurons .assert_called_once_with ([stored ])
618618 observer .database .update_neurons .assert_called_once_with ([new ])
619+
620+
621+ @pytest .mark .asyncio
622+ async def test_non_ipv4_address_not_considered_change (observer ):
623+ fake_proto = MagicMock ()
624+ fake_proto .uid = 10
625+ fake_proto .axon_info .ip = "::1" # Not an IPv4
626+ fake_proto .hotkey = "ipv6_hotkey"
627+
628+ # Original neuron had the same IP and no country
629+ stored = scmm .Neuron (uid = 10 , ip = "::1" , hotkey = "ipv6_hotkey" , country = None )
630+ observer .metagraph = AsyncMock ()
631+ observer .metagraph .neurons = [fake_proto ]
632+ observer .database .get_neurons = AsyncMock (return_value = {"ipv6_hotkey" : stored })
633+ observer .database .update_neurons = AsyncMock ()
634+ observer .database .remove_neurons = AsyncMock ()
635+
636+ with patch (
637+ "subvortex.core.model.neuron.neuron.Neuron.from_proto" , return_value = stored
638+ ), patch ("subvortex.core.country.country.get_country" , return_value = None ):
639+ axons , has_missing_country = await observer ._resync ()
640+
641+ observer .database .update_neurons .assert_not_called ()
642+ observer .database .remove_neurons .assert_not_called ()
643+ assert axons ["ipv6_hotkey" ] == "::1"
644+ assert has_missing_country is False
645+
646+
647+ @pytest .mark .asyncio
648+ async def test_non_ipv4_address_but_other_change_triggers_update (observer ):
649+ fake_proto = MagicMock ()
650+ fake_proto .uid = 11
651+ fake_proto .axon_info .ip = "abcd" # Not a valid IPv4
652+ fake_proto .hotkey = "weird_ip_hotkey"
653+
654+ stored = scmm .Neuron (uid = 11 , ip = "abcd" , hotkey = "weird_ip_hotkey" , country = None )
655+ updated = scmm .Neuron (
656+ uid = 11 , ip = "abcd" , hotkey = "weird_ip_hotkey" , country = None , incentive = 0.1
657+ )
658+
659+ observer .metagraph = AsyncMock ()
660+ observer .metagraph .neurons = [fake_proto ]
661+ observer .database .get_neurons = AsyncMock (return_value = {"weird_ip_hotkey" : stored })
662+ observer .database .update_neurons = AsyncMock ()
663+ observer .database .remove_neurons = AsyncMock ()
664+
665+ with patch (
666+ "subvortex.core.model.neuron.neuron.Neuron.from_proto" , return_value = updated
667+ ), patch ("subvortex.core.country.country.get_country" , return_value = None ):
668+ axons , has_missing_country = await observer ._resync ()
669+
670+ observer .database .update_neurons .assert_called_once_with ([updated ])
671+ observer .database .remove_neurons .assert_not_called ()
672+ assert axons ["weird_ip_hotkey" ] == "abcd"
673+ assert has_missing_country is True
674+
675+
676+ @pytest .mark .asyncio
677+ async def test_change_from_non_ipv4_to_ipv4 (observer ):
678+ fake_proto = MagicMock ()
679+ fake_proto .uid = 12
680+ fake_proto .axon_info .ip = "8.8.8.8" # valid IPv4
681+ fake_proto .hotkey = "ipv4_later"
682+
683+ old = scmm .Neuron (uid = 12 , ip = "not-an-ip" , hotkey = "ipv4_later" , country = None )
684+ new = scmm .Neuron (uid = 12 , ip = "8.8.8.8" , hotkey = "ipv4_later" , country = "US" )
685+
686+ observer .metagraph = AsyncMock ()
687+ observer .metagraph .neurons = [fake_proto ]
688+ observer .database .get_neurons = AsyncMock (return_value = {"ipv4_later" : old })
689+ observer .database .update_neurons = AsyncMock ()
690+ observer .database .remove_neurons = AsyncMock ()
691+
692+ with patch (
693+ "subvortex.core.model.neuron.neuron.Neuron.from_proto" , return_value = new
694+ ), patch ("subvortex.core.country.country.get_country" , return_value = "US" ):
695+ axons , has_missing_country = await observer ._resync ()
696+
697+ observer .database .remove_neurons .assert_not_called ()
698+ observer .database .update_neurons .assert_called_once_with ([new ])
699+ assert axons ["ipv4_later" ] == "8.8.8.8"
700+ assert has_missing_country is False
701+
702+
703+ @pytest .mark .asyncio
704+ async def test_zero_ip_and_non_ipv4_not_considered_missing_country (observer ):
705+ fake_proto = MagicMock ()
706+ fake_proto .uid = 13
707+ fake_proto .axon_info .ip = "0.0.0.0" # should be skipped
708+ fake_proto .hotkey = "zero_ip"
709+
710+ stored = scmm .Neuron (uid = 13 , ip = "0.0.0.0" , hotkey = "zero_ip" , country = None )
711+
712+ observer .metagraph = AsyncMock ()
713+ observer .metagraph .neurons = [fake_proto ]
714+ observer .database .get_neurons = AsyncMock (return_value = {"zero_ip" : stored })
715+ observer .database .update_neurons = AsyncMock ()
716+
717+ with patch (
718+ "subvortex.core.model.neuron.neuron.Neuron.from_proto" , return_value = stored
719+ ):
720+ axons , has_missing_country = await observer ._resync ()
721+
722+ observer .database .remove_neurons .assert_not_called ()
723+ observer .database .update_neurons .assert_not_called ()
724+ assert has_missing_country is False
0 commit comments