Closes #36216
Improves and fixes the test introduced by #36123 to cover regressions in the server's receive throttle. The original test relied on client-side signals to assert server-side behavior which can easily be disrupted by a platform's TCP stack. Macos for example may suddenly re-open a TCP window size based on heuristics out of our control (SB_AUTOSIZE), despite the application not reading any data from the socket. Macos also may delay transmission of data between 5-60 seconds as the TCP window shrinks (TCPTV_PERSMIN / TCPT_PERSIST / "silly window syndrome" avoidance). All these behaviors were observed by running the current CI test on my fork hundreds of times, capturing TCP packets and processing them locally against the CI debug log.
The improved approach is similar to how we test the send-side throttle in #36174 using debug log messages. This way we test the thing we know we can control (bitcoind).
To introduce the regression patched by #36123 and fail the new test:
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
--- a/src/httpserver.cpp
+++ b/src/httpserver.cpp
@@ -1040,13 +1040,7 @@ HTTPServer::IOReadiness HTTPServer::GenerateWaitSockets() const
// before the next is taken and they stay separate critical sections.
// Holding m_sock_mutex while acquiring m_send_mutex would invert that
// order and risk a lock-order-inversion deadlock.
- Sock::Event event{0};
- if (http_client->ReadyToSend()) {
- event = Sock::SendEvent;
- } else if (http_client->GetRequest() != nullptr || http_client->ReceiveBufferEmpty()) {
- // Mid-parse (need more bytes) or buffer empty.
- event = Sock::RecvEvent;
- }
+ Sock::Event event = (http_client->ReadyToSend() ? Sock::SendEvent : Sock::RecvEvent);
io_readiness.events_per_sock.emplace(sock, Sock::Events{event});
io_readiness.httpclients_per_sock.emplace(sock, http_client);
For usual bitcoind activity, httpo debug logs will only grow by one extra line per request. Huge requests like those generated by the test may produce a hundred or so lines of "Received data" messages. These are optional debug lines in a worst-case scenario, but reviewers can discuss rate-limiting that log activity if we're afraid it's too much.