Problem
CountingSemaphoreGrant::operator=(CountingSemaphoreGrant&&) releases the
currently held semaphore grant before taking ownership from the source grant.
On self-move assignment, the source and destination are the same object, so this releases the held grant and leaves the object empty.
Fix
Guard move assignment against self-move, making it a no-op when source and destination alias.
Add a regression test that verifies a self-moved grant remains held.
Test
git diff --check
cmake --build build --target test_bitcoin -j 8
build/bin/test_bitcoin --run_test=sync_tests