Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions gittensor/validator/pat_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ async def priority_pat_broadcast(validator: 'Validator', synapse: PatBroadcastSy
async def handle_pat_check(validator: 'Validator', synapse: PatCheckSynapse) -> PatCheckSynapse:
"""Check if the validator has the miner's PAT stored and re-validate it."""
hotkey = _get_hotkey(synapse)

if hotkey not in validator.metagraph.hotkeys:
synapse.has_pat = False
synapse.pat_valid = False
synapse.rejection_reason = 'Hotkey not registered on subnet'
bt.logging.warning(f'PAT check rejected — hotkey {hotkey[:16]}... not registered')
return synapse

uid = validator.metagraph.hotkeys.index(hotkey)
entry = pat_storage.get_pat_by_uid(uid)

Expand Down
8 changes: 8 additions & 0 deletions tests/validator/test_pat_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,11 @@ def test_stored_but_invalid_pat(self, mock_validate, mock_test_query, mock_valid
assert result.has_pat is True
assert result.pat_valid is False
assert 'PAT expired' in (result.rejection_reason or '')

def test_unregistered_hotkey_returns_no_pat(self, mock_validator):
"""handle_pat_check must not raise ValueError for unregistered hotkeys."""
synapse = _make_check_synapse('unknown_hotkey')
result = _run(handle_pat_check(mock_validator, synapse))
assert result.has_pat is False
assert result.pat_valid is False
assert 'not registered' in (result.rejection_reason or '').lower()