Turns out #32092 was incomplete and the issue can still happen:
https://github.com/bitcoin/bitcoin/actions/runs/39809026827/job/119929911875#step:14:14454
The basic idea is that peer1 disconnects to clear its orphan state. This happens in DisconnectNodes->DeleteNode->FinalizeNode->TxDownloadManager::DisconnectedPeer.
In my prior fix, I assumed that DisconnectNodes in the net thread would be possible to sync on via a ping-pong. However, the msghand thread may hold a reference to the node, preventing deletion and only moving the node to m_nodes_disconnected. Afterward, the net thread may hand the pings to the msghand thread and go to sleep for a bit.
Thus, the test proceed and cause a split getdata, meaning that peer2.wait_for_parent_requests([int(parent_peekaboo_AB["txid"], 16), int(parent_missing["txid"], 16)]) fails.
Fix this by just waiting for TxDownloadManager::DisconnectedPeer to have happened via self.wait_until(lambda: len(node.getorphantxs(verbosity=2)[0]["from"]) == 1).
Edit: Possible diff to reproduce with ~10% failure rate:
diff --git a/src/net.cpp b/src/net.cpp
index 1201d3bcb4..e81623484b 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -2229,2 +2229,3 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
WakeMessageHandler();
+ UninterruptibleSleep(333ms *m_nodes_disconnected.size());
}
@@ -3261,2 +3262,3 @@ void CConnman::ThreadMessageHandler()
}
+ UninterruptibleSleep(33ms);
}
Cmd: ./bld-cmake/test/functional/test_runner.py $(for i in {1..20}; do echo -n "p2p_orphan_handling.py ";done) -j $( nproc )