E530 [POC] Full Libevent removal by fanquake · Pull Request #34411 · bitcoin/bitcoin · GitHub
[go: up one dir, main page]

Skip to content

Conversation

@fanquake
Copy link
Member
@fanquake fanquake commented Jan 26, 2026

This builds on all the work being done by pinheadmz and fjahr (#32061, #34342, #34158), to demo a libevent-less bitcoind.

One thing we could decide to change, or not, is the libevent logging catergory. Other than that, any remaining references to libevent, should be in documentation/code comments.

@DrahtBot
Copy link
Contributor
DrahtBot commented Jan 26, 2026

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage & Benchmarks

For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/34411.

Reviews

See the guideline for information on the review process.
A summary of reviews will appear here.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #34408 (ci: remove gnu-getopt usage by fanquake)
  • #34143 (build: Prevent system header fallback and include path pollution by hebasto)
  • #33974 (cmake: Check dependencies after build option interaction by hebasto)
  • #32297 (bitcoin-cli: Add -ipcconnect option by ryanofsky)
  • #31929 (http: Make server shutdown more robust by hodlinator)
  • #31723 (qa: Facilitate debugging bitcoind inside functional tests by hodlinator)
  • #31425 (RFC: Riscv bare metal CI job by sedited)
  • #31260 (scripted-diff: Type-safe settings retrieval by ryanofsky)
  • #30342 (kernel, logging: Pass Logger instances to kernel objects by ryanofsky)
  • #26022 (Add util::ResultPtr class by ryanofsky)
  • #25722 (refactor: Use util::Result class for wallet loading by ryanofsky)
  • #25665 (refactor: Add util::Result failure types and ability to merge result values by ryanofsky)
  • #21283 (Implement BIP 370 PSBTv2 by achow101)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

LLM Linter (✨ experimental)

Possible typos and grammar issues:

  • "an unique id" -> "a unique id" [Use "a" before consonant-sound words; "unique" begins with a consonant sound, so "a" is correct.]
  • "Unrecoverbale error" -> "Unrecoverable error" [Spelling error: "Unrecoverbale" should be "Unrecoverable".]

Possible places where named args for integral literals may be used (e.g. func(x, /*named_arg=*/0) in C++, and func(x, named_arg=0) in Python):

  • LookupHost(m_host, 256, true) in src/bitcoin-cli.cpp

Possible places where comparison-specific test macros should replace generic comparisons:

  • [src/test/httpserver_tests.cpp] BOOST_CHECK_THROW(req.LoadControlData(reader), std::runtime_error) -> Consider using BOOST_CHECK_EXCEPTION(req.LoadControlData(reader), std::runtime_error, HasReason("...")) to assert the exception message/content in addition to the type.
  • [src/test/httpserver_tests.cpp] BOOST_CHECK_THROW(req.LoadControlData(reader), std::runtime_error) -> Consider using BOOST_CHECK_EXCEPTION(req.LoadControlData(reader), std::runtime_error, HasReason("...")) to assert the exception message/content in addition to the type.
  • [src/test/httpserver_tests.cpp] BOOST_CHECK_THROW(req.LoadControlData(reader), std::runtime_error) -> Consider using BOOST_CHECK_EXCEPTION(req.LoadControlData(reader), std::runtime_error, HasReason("...")) to assert the exception message/content in addition to the type.
  • [src/test/httpserver_tests.cpp] BOOST_CHECK_THROW(req.LoadControlData(reader), std::runtime_error) -> Consider using BOOST_CHECK_EXCEPTION(req.LoadControlData(reader), std::runtime_error, HasReason("...")) to assert the exception message/content in addition to the type.
  • [src/test/httpserver_tests.cpp] BOOST_CHECK_THROW(req.LoadHeaders(reader), std::runtime_error) -> Consider using BOOST_CHECK_EXCEPTION(req.LoadHeaders(reader), std::runtime_error, HasReason("...")) to assert the exception message/content in addition to the type.
  • [src/test/httpserver_tests.cpp] BOOST_CHECK_THROW(req.LoadBody(reader), std::runtime_error) -> Consider using BOOST_CHECK_EXCEPTION(req.LoadBody(reader), std::runtime_error, HasReason("Cannot parse Content-Length value")) (or the exact expected message) to validate both type and message.
  • [src/test/httpserver_tests.cpp] BOOST_CHECK_THROW(req.LoadBody(reader), std::runtime_error) -> Consider using BOOST_CHECK_EXCEPTION(req.LoadBody(reader), std::runtime_error, HasReason("Cannot parse chunk length value")) (or the exact expected message).
  • [src/test/httpserver_tests.cpp] BOOST_CHECK_THROW(req.LoadBody(reader), std::runtime_error) -> Consider using BOOST_CHECK_EXCEPTION(req.LoadBody(reader), std::runtime_error, HasReason("Improperly terminated chunk")) (or the exact expected message).

No comparison macro suggestions were found for Python tests (no bare "assert a == b" additions needing replacement were detected).

2026-01-28 13:37:34

@pinheadmz
Copy link
Member

nit: Pull request description should be replaced by the lyrics of Taylor Swift's "We Are Never Ever Getting Back Together" before merging.

pinheadmz and others added 22 commits January 28, 2026 13:35
This commit is a no-op to isolate HTTP methods and objects that
depend on libevent. Following commits will add replacement objects
and methods in a new namespace for testing and review before
switching over the server.
HTTP Response message:
https://datatracker.ietf.org/doc/html/rfc1945#section-6

Status line (first line of response):
https://datatracker.ietf.org/doc/html/rfc1945#section-6.1

Status code definitions:
https://datatracker.ietf.org/doc/html/rfc1945#section-9

This commit also moves StringToBuffer to test/util/str
since it is now used in more than one test.
HTTP Request message:
https://datatracker.ietf.org/doc/html/rfc1945#section-5

Request Line aka Control Line aka first line:
https://datatracker.ietf.org/doc/html/rfc1945#section-5.1

See message_read_status() in libevent http.c for how
`MORE_DATA_EXPECTED` is handled there
…ocket

Introduce a new low-level socket managing class `HTTPServer`.

BindAndStartListening() was copied from CConnMan's BindListenPort()
in net.cpp and modernized.

Unit-test it with a new class `SocketTestingSetup` which mocks
`CreateSock()` and will enable mock client I/O in future commits.

Co-authored-by: Vasil Dimov <vd@FreeBSD.org>
AcceptConnection() is mostly copied from CConmann in net.cpp
and then modernized.

Co-authored-by: Vasil Dimov <vd@FreeBSD.org>
Socket handling methods are copied from CConnMan:

`CConnman::GenerateWaitSockets()`
`CConnman::SocketHandlerListening()`
`CConnman::ThreadSocketHandler()` and `CConnman::SocketHandler()` are combined into ThreadSocketHandler()`.

Co-authored-by: Vasil Dimov <vd@FreeBSD.org>
`SocketHandlerConnected()` adapted from CConnman

Testing this requires adding a new feature to the SocketTestingSetup,
inserting a "request" payload into the mock client that connects
to us.

Co-authored-by: Vasil Dimov <vd@FreeBSD.org>
Sockets-touching bits copied and adapted from `CConnman::SocketSendData()`

Testing this requires adding a new feature to the SocketTestingSetup,
returning the DynSock I/O pipes from the mock socket so the received
data can be checked.

Co-authored-by: Vasil Dimov <vd@FreeBSD.org>
See https://www.rfc-editor.org/rfc/rfc7230#section-6.3.2

> A server MAY process a sequence of pipelined requests in
  parallel if they all have safe methods (Section 4.2.1 of [RFC7231]),
  but it MUST send the corresponding responses in the same order that
  the requests were received.

We choose NOT to process requests in parallel. They are executed in
the order recevied as well as responded to in the order received.
This prevents race conditions where old state may get sent in response
to requests that are very quick to process but were requested later on
in the queue.
This is a refactor to prepare for matching the API of HTTPRequest
definitions in both namespaces http_bitcoin and http_libevent. In
particular, to provide a consistent return type for GetRequestMethod()
in both classes.
These methods are called by http_request_cb() and are present in the
original http_libevent::HTTPRequest.
The original function is passed to libevent as a callback when HTTP
requests are received and processed. It wrapped the libevent request
object in a http_libevent::HTTPRequest and then handed that off to
bitcoin for basic checks and finally dispatch to worker threads.

In this commit we split the function after the
http_libevent::HTTPRequest is created, and pass that object to a new
function that maintains the logic of checking and dispatching.

This will be the merge point for http_libevent and http_bitcoin,
where HTTPRequest objects from either namespace have the same
downstream lifecycle.
The original function was already naturally split into two chunks:
First, we parse and validate the users' RPC configuration for IPs and
ports. Next we bind libevent's http server to the appropriate
endpoints.

This commit splits these chunks into two separate functions, leaving
the argument parsing in the common space of the module and moving the
libevent-specific binding into the http_libevent namespace.

A future commit will implement http_bitcoin::HTTPBindAddresses to
bind the validate list of endpoints by the new HTTP server.
@fanquake fanquake force-pushed the full_libevent_removal branch from cd01007 to 71fc75c Compare January 28, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

0