{
 "number": 36434,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/36434",
 "title": "http: support unix sockets",
 "author": "pinheadmz",
 "author_association": "MEMBER",
 "created_at": "2026-10-04T18:10:37Z",
 "updated_at": "2026-10-31T12:51:51Z",
 "description_hash": "2fd75e6f29e84262",
 "age_days": 28,
 "draft": false,
 "labels": [
  "RPC/REST/ZMQ"
 ],
 "milestone": null,
 "base": "master",
 "head_sha": "ccbace1c33f30f9fb842451851263a7d83449323",
 "head_ref": "http-unix-sockets",
 "head_repo": "pinheadmz/bitcoin",
 "head_history": [
  {
   "t": "2026-10-08T14:56:24Z",
   "sha": "022a6aa69ed423fa66f5747b1f0d6413a01e1645"
  },
  {
   "t": "2026-10-08T15:13:32Z",
   "sha": "81b8369ac862a7e888606c2220df94d347a7ca59"
  },
  {
   "t": "2026-10-08T16:39:11Z",
   "sha": "c27a1fec1aa78cb721c31be5511bb1a542f09782"
  },
  {
   "t": "2026-10-08T19:06:20Z",
   "sha": "db638e0f44f0aaffe798a4ec7d4757246de9fb56"
  },
  {
   "t": "2026-10-28T19:55:55Z",
   "sha": "e34ffb6de9e3fcd635f1e88c29c616a3ef21a2c1"
  },
  {
   "t": "2026-10-28T23:33:16Z",
   "sha": "ccbace1c33f30f9fb842451851263a7d83449323"
  }
 ],
 "additions": 1547,
 "deletions": 265,
 "changed_files": 20,
 "commit_count": 10,
 "size_bucket": "XL",
 "mergeable_state": "clean",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "concept_ack": [
     {
      "login": "b-l-u-e",
      "url": "https://github.com/bitcoin/bitcoin/pull/36434#issuecomment-5993254913"
     }
    ],
    "approach_ack": [
     {
      "login": "winterrdog",
      "url": "https://github.com/bitcoin/bitcoin/pull/36434#pullrequestreview-5478881949"
     }
    ]
   },
   "conflicts": []
  }
 },
 "acks_parsed": {
  "b-l-u-e": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-10-05T11:10:32Z",
   "stale": false
  },
  "winterrdog": {
   "kind": "approach_ack",
   "hash": null,
   "t": "2026-10-16T13:22:36Z",
   "stale": false
  }
 },
 "acks_tally": {
  "ack": 0,
  "stale_ack": 0,
  "concept_ack": 1,
  "approach_ack": 1,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 0,
  "changes_requested": 0,
  "distinct_reviewers": [
   "b-l-u-e",
   "hodlinator",
   "winterrdog"
  ]
 },
 "signals": {
  "needs_rebase": false,
  "ci_failed": false,
  "mergeable_state": "clean",
  "last_author_activity": "2026-10-29T13:26:48Z",
  "last_reviewer_activity": "2026-10-29T12:29:20Z",
  "last_reviewer": "hodlinator",
  "author_silent_days": 3,
  "waiting_on_author_days": 0,
  "days_since_update": 1
 },
 "refs": {
  "mentioned": [
   34729,
   36159,
   36303,
   36509
  ],
  "depends_on": [],
  "fixes": [],
  "linked_issues": [],
  "references": [
   {
    "number": 34729,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2026-10-05",
    "title": "Reduce log noise"
   },
   {
    "number": 36159,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2026-10-19",
    "title": "http: Improve HTTPRemoteClient::MaybeDisconnect()"
   },
   {
    "number": 36303,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2026-10-05",
    "title": "http: Log bytes received from client, use to replace receive-throttle regression test"
   },
   {
    "number": 36509,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2026-10-21",
    "title": "refactor: remove more dead code"
   }
  ],
  "conflicts": []
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [
  "doc/JSON-RPC-interface.md",
  "doc/release-notes-36434.md",
  "src/bitcoin-cli.cpp",
  "src/httpserver.cpp",
  "src/netbase.cpp",
  "src/netbase.h"
 ],
 "body": "Closes https://github.com/bitcoin/bitcoin/issues/5029\n\nAccept unix socket paths as options for `-rpcbind=` (server) and `-rpcconnect=` (bitcoin-cli). Options follow the same pattern as `ipcbind`:\n\n- `=unix` is a magic keyword that means `<datadir>/http.sock`\n- `=unix:relative/path` means `<datadir>/relative/path`\n- `=unix:/absolute/path` means `/absolute/path`\n\nWe delete any existing `http.sock` before calling `bind()` and do not clean up at shutdown.\n\nBecause access is handled by the filesystem, `-rpcallowip` is ignored for unix sockets and not required at all if we are *only* binding to unix sockets.\n\nAuthentication by username/password/cookie is still required.\n\nA new option `--httpunix` is added to the test framework and added to test_runner for `rpc_bind.py` and `interface_http.py` for CI, but (like `--usecli`) most other tests should also pass with that option. When set, bitcoind is started with `-rpcbind=unix...`which overrides `tcp://localhost` entirely. `AuthProxy` has been extended to connect directly to the unix socket.\n\nTry it out!\n```\nbitcoind -regtest -rpcbind=unix\nbitcoin-cli -regtest -rpcconnect=unix getbestblockhash\n```\n\nRefactored code:\n\nBack in https://github.com/bitcoin/bitcoin/pull/27375 we added unix socket support but it was isolated to the `Proxy` class. That created a bit of tech debt which we pay off in this PR. Two new classes are implemented:\n- `UnixSocketAddr` reflects the `CService` API for generic unix sockets, without bitcoin-p2p-specific attributes\n- `SocketAddr` holds a variant of `UnixSocketAddr` and `Cservice` so classes like `Proxy` and `HTTPServer` can operate on an abstract level, with either socket type.\n- `CNetAddr` and `CService` are left untouched -- they are somewhat dirty combinations of generic socket classes and bitcoin p2p code, adding unix sockets to those classes wouldn't make sense for bitcoin p2p operations and that's why this design was chosen.\n\nFollow-up suggestions:\n- Deduplicate some of the unix socket path resolution code between IPC and HTTP\n- On macos the default unix socket buffer size is only ~8k. In the functional tests we have to bump the python client socket buffer up to ~256k or the \"throttle\" tests will stall on macos. We could apply this socket option on the server side as well, only on macos... requires some bike shedding.\n- This option replaces TCP but it does not replace HTTP, there may be a more efficient transport protocol.\n\nProduction code and test framework changes designed and authored by my own cranial meatball. Unit tests added by Opus. C++ cleaned up by Fable, security tightened by Kimi-k3 \ud83e\udde0 \ud83e\udd16 \ud83e\udd16 \ud83e\udd16",
 "commits": [
  {
   "sha": "530b7a5a3a72ffcb028a2eb42ca2f719fd7be99a",
   "date": "2026-10-28T19:50:50Z",
   "message": "netbase: introduce UnixSocketAddr class\n\nInclude unit tests to ensure the API matches CService"
  },
  {
   "sha": "07f4da524846be12daf592f6514f0f702bcd55e8",
   "date": "2026-10-28T19:50:50Z",
   "message": "netbase: introduce SocketAddr class"
  },
  {
   "sha": "ccfeff219581343d8082fa50abbaf7506a2a56d3",
   "date": "2026-10-28T23:04:06Z",
   "message": "test: cover existing Proxy API"
  },
  {
   "sha": "61c24c437d7a44334cead05e130f100fb41cdb9d",
   "date": "2026-10-28T23:14:00Z",
   "message": "netbase: refactor Proxy to use SocketAddr"
  },
  {
   "sha": "f0f54a97c19a6cb3934985b4b392fc7902f25a58",
   "date": "2026-10-28T23:14:03Z",
   "message": "http: use SocketAddr instead of CService"
  },
  {
   "sha": "517363b2bc461daff524a26bf492d7a0be064e4f",
   "date": "2026-10-28T23:14:03Z",
   "message": "http: support listening on UNIX domain sockets"
  },
  {
   "sha": "6ad23a85de32a3f80b67a7500ce92fb8b50f7660",
   "date": "2026-10-28T23:14:03Z",
   "message": "http: allow empty -rpcallowip if all bind addresses are unix sockets\n\nCo-authored-by: winterrdog <winterrdog@protonmail.ch>"
  },
  {
   "sha": "3d04d7cb4b75c21c97b1054e4fbcc9046459284a",
   "date": "2026-10-28T23:14:03Z",
   "message": "Enable unix sockets in test_framework: cover interface_http & rpc_bind\n\nMost functional tests will pass with --httpunix, which uses unix\nsockets instead of TCP for all RPC commands in the test. For now,\nonly require interface_http, rpc_bind --httpunix in CI to cover\nthe specific changes from this branch."
  },
  {
   "sha": "90b6f55b9407375cbafb9fe4501e6fb9dfa9dbff",
   "date": "2026-10-28T23:14:03Z",
   "message": "bitcoin-cli: support connecting on UNIX domain sockets"
  },
  {
   "sha": "ccbace1c33f30f9fb842451851263a7d83449323",
   "date": "2026-10-28T23:14:03Z",
   "message": "doc: add unix socket options to help and docs"
  }
 ],
 "timeline": [
  {
   "t": "2026-10-04T20:57:34Z",
   "kind": "review",
   "who": "winterrdog",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "6876eb2b5113a42a8cd2f5ca668edda9c26196ff",
   "text": "**concept** ACK\n\n---\n\nusers of other projects that rely on Core have always wanted sth similar to this and implemented workarounds in the meantime:\n\n- https://github.com/spesmilo/electrum/issues/4955\n- https://github.com/btcsuite/btcd/issues/2149\n\nthere was also an attempt to add this back in 2017:\n\n- https://github.com/bitcoin/bitcoin/pull/9919\n\nunfortunately, that attempt ran into a limitation in libevent's HTTP client. supporting Unix Domain sockets in `bitcoin-cli` required a libevent patch to pass an already-open Unix socket connection to the HTTP client. this was eventually addressed in https://github.com/libevent/libevent/pull/1722, but by then Core had decided to  moved away from libevent. anyway, with libevent dropped, this is no longer an issue",
   "id": "r:5408186323",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#pullrequestreview-5408186323",
   "hash": "48919cfcab5430de",
   "edited": "2026-10-04T21:01:06Z"
  },
  {
   "t": "2026-10-04T21:09:01Z",
   "kind": "comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "text": "Don't forget https://github.com/libevent/libevent/issues/1615 ! Its been a long time coming... now that that [pesky little refactor](https://github.com/bitcoin/bitcoin/pull/35182) is out of the way we can finally get to it ;-)",
   "id": "c:5984404559",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#issuecomment-5984404559",
   "hash": "d6b2dc25608ab776",
   "edited": "2026-10-04T21:09:28Z"
  },
  {
   "t": "2026-10-05T11:10:32Z",
   "kind": "comment",
   "who": "b-l-u-e",
   "assoc": "CONTRIBUTOR",
   "text": "concept ACK...i found an issue by running two nodes and noticed that second node can take over a live rpc unix socket path,  if two nodes use different datadirs but the same -rpcbind=unix:<path> the second node starts with no error..since it removes the first node socket file and creates its own then after that bitcoin cli talks to the second node.. the first node keeps running but becomes unreachable so with TCP the second bind fails with address already in use\n\ni reproduced this on regtest\n```\nB=build/bin\nSOCK=/tmp/btc-hijack.sock\nmkdir -p /tmp/nodeA /tmp/nodeB\nARGS=\"-regtest -daemon -listen=0 -rpcbind=unix:$SOCK -rpcuser=u -rpcpassword=p\"\nCLI=\"$B/bitcoin-cli -regtest -rpcconnect=unix:$SOCK -rpcuser=u -rpcpassword=p -rpcwait\"\n```\n\n1: **for node A**\n```\n$B/bitcoind -datadir=/tmp/nodeA $ARGS\n$CLI getrpcinfo | grep logpath && stat -c 'inode=%i' $SOCK\n\noutput:\nBitcoin Core starting\n\"logpath\": \"/tmp/nodeA/regtest/debug.log\"\ninode=2229678\n```\n\n2: **for node B**\n```\n$B/bitcoind -datadir=/tmp/nodeB $ARGS; sleep 2\n$CLI getrpcinfo | grep logpath && stat -c 'inode=%i' $SOCK\n\noutput:\nBitcoin Core starting                                  (as you can see node B starts without error)\n\"logpath\": \"/tmp/nodeB/regtest/debug.log\"              (cli now reaches B)\ninode=2229647   (and this replaces node A socket file)\n```\n\n3: ss -xlp | grep btc-hijack\n```\noutput:\nu_str LISTEN ... /tmp/btc-hijack.sock ... pid=1684462  (this is for B)\nu_str LISTEN ... /tmp/btc-hijack.sock ... pid=1684363  (here A still listening but unreachable)\n```\n\n4: $CLI stop; sleep 2\n```\noutput:\nBitcoin Core stopping                                  (`stop` reached B)\n```\n\n5: pgrep -a bitcoind\n```\noutput:\n1684363 build/bin/bitcoind -datadir=/tmp/nodeA ...     (A still running)\n```\n\n6: $CLI -rpcwait=0 getblockcount\n```\noutput:\nerror: Error while attempting to communicate with server unix:/tmp/btc-hijack.sock (Could not connect to the server)\n\nMake sure the bitcoind server is running and that you are connecting to the correct unix socket path.\nUse \"bitcoin-cli -help\" for more info.\n```",
   "id": "c:5993254913",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#issuecomment-5993254913",
   "hash": "30275bc4a996f420",
   "edited": "2026-10-05T11:28:40Z"
  },
  {
   "t": "2026-10-05T17:44:22Z",
   "kind": "comment",
   "who": "b-l-u-e",
   "assoc": "CONTRIBUTOR",
   "text": "i noticed a change in bitcoin-cli the host header contains the resolved IP instead of the hostname given in `-rpcconnect=localhost` the build from master sends `Host: localhost` but on this PR sends `Host: 127.0.0.1`\n\ni reproduced the result by running this py file on terminal 1\n```py\nimport socket\n\nsrv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\nsrv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\nsrv.bind((\"127.0.0.1\", 18555))\nsrv.listen()\nprint(\"listening on 127.0.0.1:18555\")\nwhile True:\n    conn, _ = srv.accept()\n    request = conn.recv(4096).decode(errors=\"replace\")\n    for line in request.split(\"\\r\\n\"):\n        if line.lower().startswith(\"host:\"):\n            print(line)\n    conn.close()\n ```\n\n on terminal 2 i ran this command\n ```\n build-master/bin/bitcoin-cli -rpcconnect=localhost -rpcport=18555 -rpcuser=u -rpcpassword=p -rpcclienttimeout=3 getblockcount\nbuild-pr36434/bin/bitcoin-cli       -rpcconnect=localhost -rpcport=18555 -rpcuser=u -rpcpassword=p -rpcclienttimeout=3 getblockcount\n```\n\n and the output was\n\n ```\n python3 /tmp/show_host.py\nlistening on 127.0.0.1:18555\nHost: localhost\nHost: 127.0.0.1\n```",
   "id": "c:5999886903",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#issuecomment-5999886903",
   "hash": "12729d2822b607b9",
   "edited": null
  },
  {
   "t": "2026-10-08T14:56:24Z",
   "kind": "force_push",
   "who": "pinheadmz",
   "commit": "022a6aa69ed423fa66f5747b1f0d6413a01e1645",
   "id": "push:022a6aa69ed423fa66f5747b1f0d6413a01e1645"
  },
  {
   "t": "2026-10-08T14:59:37Z",
   "kind": "comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "text": "push to  022a6aa69ed423fa66f5747b1f0d6413a01e1645:\n\n- rebase on master, fix conflicts with #36303 and #34729\n- fix `\"Host:` header in bitcoin-cli (@b-l-u-e)\n\nMajor change is copying the parameter format from `ipcbind`, so default is to create `http.sock` in the appropriate network data directory. This should also adderss @b-l-u-e concern about multiple processes messing with each others sockets. Or at least, makes it harder for a user to footgun. Will update the PR description as well.",
   "id": "c:6062694537",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#issuecomment-6062694537",
   "hash": "6f81c5fc4067229a",
   "edited": "2026-10-08T15:09:14Z"
  },
  {
   "t": "2026-10-08T15:13:32Z",
   "kind": "force_push",
   "who": "pinheadmz",
   "commit": "81b8369ac862a7e888606c2220df94d347a7ca59",
   "id": "push:81b8369ac862a7e888606c2220df94d347a7ca59"
  },
  {
   "t": "2026-10-08T15:13:33Z",
   "kind": "comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "text": "push to 81b8369ac862a7e888606c2220df94d347a7ca59\n\n- rebase on master, fix conflicts with https://github.com/bitcoin/bitcoin/pull/36340",
   "id": "c:6062975719",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#issuecomment-6062975719",
   "hash": "47f3e5694046468c",
   "edited": null
  },
  {
   "t": "2026-10-08T16:39:11Z",
   "kind": "force_push",
   "who": "pinheadmz",
   "commit": "c27a1fec1aa78cb721c31be5511bb1a542f09782",
   "id": "push:c27a1fec1aa78cb721c31be5511bb1a542f09782"
  },
  {
   "t": "2026-10-08T16:39:32Z",
   "kind": "comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "text": "push to c27a1fec1aa78cb721c31be5511bb1a542f09782\n\n- fix humiliating lint error \ud83d\ude2d",
   "id": "c:6064587986",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#issuecomment-6064587986",
   "hash": "f94607568ca04490",
   "edited": null
  },
  {
   "t": "2026-10-08T19:06:20Z",
   "kind": "force_push",
   "who": "pinheadmz",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "id": "push:db638e0f44f0aaffe798a4ec7d4757246de9fb56"
  },
  {
   "t": "2026-10-08T19:08:10Z",
   "kind": "comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "text": "push to db638e0f44f0aaffe798a4ec7d4757246de9fb56\n\nFix a test in interface_http made flaky by unix sockets and failed last CI run:\n\nUnix sockets report server closure much faster than TCP which lost a race against the logic where we assert the connection is closed in python by trying to send more data",
   "id": "c:6067107689",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#issuecomment-6067107689",
   "hash": "1f469d3bf0cb653c",
   "edited": null
  },
  {
   "t": "2026-10-10T12:09:29Z",
   "kind": "review_comment",
   "who": "winterrdog",
   "assoc": "CONTRIBUTOR",
   "path": "doc/release-notes-36434.md",
   "commit": "ccbace1c33f30f9fb842451851263a7d83449323",
   "in_reply_to": null,
   "text": "**nit:** sometimes, i see that you use \"unix socket\", while on other occasions it is \"unix _domain_ socket\". is that intentional, or should we choose uniformity, pick one option, and then just run with it all throughout ?\n\n\"unix socket\" seems more common in the docs and in the code comments in this PR's diff, so probably the best candidate to go with.",
   "id": "rc:4237560109",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4237560109",
   "hash": "1be9b949bfbbbe39",
   "edited": "2026-10-16T13:22:36Z"
  },
  {
   "t": "2026-10-10T22:27:55Z",
   "kind": "review_comment",
   "who": "winterrdog",
   "assoc": "CONTRIBUTOR",
   "path": "doc/release-notes-36434.md",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nTIL: windows has _basic_ support for unix domain sockets (UDS).\n\nsince Windows 10 version `1803` or later, windows has shipped UDS support but _limited_ to `SOCK_STREAM` sockets only: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/",
   "id": "rc:4239427247",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4239427247",
   "hash": "12c436ca3821fa93",
   "edited": "2026-10-16T13:22:36Z"
  },
  {
   "t": "2026-10-10T23:30:05Z",
   "kind": "review_comment",
   "who": "winterrdog",
   "assoc": "CONTRIBUTOR",
   "path": "src/netbase.h",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": null,
   "text": "**nit**: could you have _possibly_ meant this instead ?\n\n```suggestion\n     *  Unix sockets don't have a port but we'd like to match the CService API. */\n```",
   "id": "rc:4239583616",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4239583616",
   "hash": "aff28521260f78a2",
   "edited": "2026-10-16T13:22:37Z"
  },
  {
   "t": "2026-10-11T01:04:53Z",
   "kind": "review_comment",
   "who": "winterrdog",
   "assoc": "CONTRIBUTOR",
   "path": "src/netbase.cpp",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": null,
   "text": "`char` is signed on some platforms (e.g. x86), so bytes above `0x7f` are interpreted as negative values (they wrap around) and also match `c < 0x20`. this means a utf-8 path like `/tmp/jos\u00e9.sock` could end up being replaced with `\"unix\"` in the logs\n\ntaking `unsigned char` (*even* `uint8_t` *works OK*) in the lambda fixes this (i also switched to `std::ranges` in case you find that more appealing)\n\n```suggestion\n        if (std::ranges::any_of(path, [](unsigned char c) { return c < 0x20 || c == 0x7F; })) {\n```",
   "id": "rc:4239802579",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4239802579",
   "hash": "1b6aad0bb1d5e98a",
   "edited": "2026-10-16T13:22:37Z"
  },
  {
   "t": "2026-10-14T21:32:17Z",
   "kind": "review_comment",
   "who": "winterrdog",
   "assoc": "CONTRIBUTOR",
   "path": "src/httpserver.cpp",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": null,
   "text": "why don't we just put this behind an `#ifdef HAVE_SOCKADDR_UN` guard so we skip this code entirely on platforms that do not support unix sockets ?\n\nsure! we can never get here with a `UnixSocketAddr` on those platforms anyway, since those addresses get rejected much earlier. currently this would be a no-op at runtime, but we could avoid compiling code that can never be used on those platforms. seems like we can just sidestep it altogether :)",
   "id": "rc:4276497992",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4276497992",
   "hash": "039a43a8e372a6c0",
   "edited": "2026-10-16T13:22:37Z"
  },
  {
   "t": "2026-10-15T18:30:26Z",
   "kind": "review_comment",
   "who": "winterrdog",
   "assoc": "CONTRIBUTOR",
   "path": "src/httpserver.cpp",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": null,
   "text": "`strRPCBind` can show up in the logs if the _optional port is included_ in the bind address (e.g. `127.0.0.1:8332`), leading to logs like this one: `Could not bind RPC on address 127.0.0.1:8332 port 8332: Address lookup failed.`\n\n```suggestion\n                LogWarning(\"Could not bind RPC on address %s port %i: Address lookup failed.\", host, port);\n```",
   "id": "rc:4286800301",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4286800301",
   "hash": "3c5483d930cd00b9",
   "edited": "2026-10-16T13:22:37Z"
  },
  {
   "t": "2026-10-15T18:47:57Z",
   "kind": "review_comment",
   "who": "winterrdog",
   "assoc": "CONTRIBUTOR",
   "path": "src/httpserver.cpp",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": null,
   "text": "_optional_ style nit: we could make this a `const` initialised from a ternary expression:\n\n```suggestion\n    const int protocol{to.IsUnix() ? 0 : IPPROTO_TCP};\n```",
   "id": "rc:4286968868",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4286968868",
   "hash": "6a2ab7207b14f830",
   "edited": "2026-10-16T13:22:37Z"
  },
  {
   "t": "2026-10-15T18:53:21Z",
   "kind": "review_comment",
   "who": "winterrdog",
   "assoc": "CONTRIBUTOR",
   "path": "src/bitcoin-cli.cpp",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": null,
   "text": "**nit**: i think we could `std::move` both the host string & collection of socket addresses into the return `pair` object (trivial copy avoidance)\n\n```suggestion\n    return {std::move(host), std::move(ret)};\n```",
   "id": "rc:4287028863",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4287028863",
   "hash": "e3d63cc1727a9433",
   "edited": "2026-10-16T13:22:37Z"
  },
  {
   "t": "2026-10-15T19:06:34Z",
   "kind": "review_comment",
   "who": "winterrdog",
   "assoc": "CONTRIBUTOR",
   "path": "src/httpserver.cpp",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": null,
   "text": "when i went through `GetBindAddresses()` and `UnixSocketAddr::PreparePath()`, i noticed that duplicate unix endpoints can go unnoticed. if two `-rpcbind` values resolve to the same path (e.g. `-rpcbind=unix` and `-rpcbind=unix:http.sock`, or the same value in `bitcoin.conf` and perhaps on the command line), `PreparePath()` (later called in `HTTPServer::BindAndStartListening`) removes the first socket file before the second `bind()`. therefore, both binds succeed without sending a warning\n\nis this intentional, or just not something we need to worry about? in the case of TCP, the second bind just fails with `EADDRINUSE` and gets logged. would we expect the same here, or is silently rebinding just fine ?",
   "id": "rc:4287174385",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4287174385",
   "hash": "3642b0f3d6d05a15",
   "edited": "2026-10-16T13:22:37Z"
  },
  {
   "t": "2026-10-16T09:02:03Z",
   "kind": "review_comment",
   "who": "winterrdog",
   "assoc": "CONTRIBUTOR",
   "path": "src/httpserver.cpp",
   "commit": "ccbace1c33f30f9fb842451851263a7d83449323",
   "in_reply_to": null,
   "text": "while reviewing `GetBindAddresses()`, i ended up rewriting it to lower the cognitive load a bit and help me get my head around the flow. thought i could share it and see what you think:\n\ndiff\n\n```diff\ndiff --git a/src/httpserver.cpp b/src/httpserver.cpp\nindex 4b17dc5d89..4d97422f4f 100644\n--- a/src/httpserver.cpp\n+++ b/src/httpserver.cpp\n@@ -212,51 +212,57 @@ static void RejectRequest(std::unique_ptr<HTTPRequest> hreq)\n\n static std::vector<SocketAddr> GetBindAddresses()\n {\n-    uint16_t http_port{static_cast<uint16_t>(gArgs.GetIntArg(\"-rpcport\", BaseParams().RPCPort()))};\n-    std::vector<SocketAddr> endpoints;\n+    const uint16_t http_port{static_cast<uint16_t>(gArgs.GetIntArg(\"-rpcport\", BaseParams().RPCPort()))};\n+    const auto binds{gArgs.GetArgs(\"-rpcbind\")};\n+    const bool has_allowip{!gArgs.GetArgs(\"-rpcallowip\").empty()};\n+    const auto localhost_endpoints{[http_port]() -> std::vector<SocketAddr> {\n+        return {SocketAddr{Lookup(\"::1\", http_port, false).value()},\n+                SocketAddr{Lookup(\"127.0.0.1\", http_port, false).value()}};\n+    }};\n+\n+    // default to loopback when no rpc binds are provided\n+    if (binds.empty()) {\n+        if (has_allowip) {\n+            LogWarning(\"Option -rpcallowip was specified without -rpcbind; this doesn't usually make sense\");\n+        }\n+        return localhost_endpoints();\n+    }\n\n-    // Cleared as soon as any -rpcbind value is an IP address, whether or not it\n-    // resolves, so that a lookup failure can never make a TCP bind request\n-    // look like a unix-socket-only configuration.\n-    bool only_unix_sockets{true};\n-    // Set to true if no addresses were specified, or\n-    // if we need to override a user misconfiguration.\n-    bool force_localhost{false};\n+    std::vector<SocketAddr> endpoints;\n+    // Set before parsing or looking up, so that a failure can never make\n+    // a TCP bind request look like a unix-socket-only configuration.\n+    bool has_ip{false};\n\n     // Determine what addresses to bind to.\n-    if (!gArgs.GetArgs(\"-rpcbind\").empty()) {\n+    for (const std::string& bind : binds) {\n         // Specific bind addresses.\n-        for (const std::string& strRPCBind : gArgs.GetArgs(\"-rpcbind\")) {\n-            if (IsUnixSocketValue(strRPCBind, /*allow_default=*/true)) {\n-                // UNIX socket is a filesystem path, resolved like -ipcbind\n-                const auto unix_addr{ResolveUnixSocketAddr(strRPCBind, gArgs.GetDataDirNet(), DEFAULT_HTTP_UNIX_SOCKET_NAME)};\n-                if (!unix_addr) {\n-                    LogError(\"Invalid unix socket path specified in -rpcbind: '%s' (%s)\", strRPCBind, unix_addr.error());\n-                    return {}; // empty, refuse to start with a misconfigured bind\n-                }\n-                endpoints.emplace_back(*unix_addr);\n-                continue;\n-            }\n-            // IPv4 or IPv6 address\n-            only_unix_sockets = false;\n-            uint16_t port{http_port};\n-            std::string host;\n-            if (!SplitHostPort(strRPCBind, port, host)) {\n-                LogError(\"%s\\n\", InvalidPortErrMsg(\"-rpcbind\", strRPCBind).original);\n+        if (IsUnixSocketValue(bind, /*allow_default=*/true)) {\n+            // UNIX socket is a filesystem path, resolved like -ipcbind\n+            const auto unix_addr{ResolveUnixSocketAddr(bind, gArgs.GetDataDirNet(), DEFAULT_HTTP_UNIX_SOCKET_NAME)};\n+            if (!unix_addr) {\n+                LogError(\"Invalid unix socket path specified in -rpcbind: '%s' (%s)\", bind, unix_addr.error());\n                 return {}; // empty, refuse to start with a misconfigured bind\n             }\n-            const std::optional<CService> addr{Lookup(strRPCBind, port, false)};\n-            if (!addr) {\n-                LogWarning(\"Could not bind RPC on address %s port %i: Address lookup failed.\", strRPCBind, port);\n-                continue;\n-            }\n-            if (addr->IsBindAny()) {\n-                LogWarning(\"The RPC server is not safe to expose to untrusted networks such as the public internet\");\n-            }\n-            endpoints.emplace_back(addr.value());\n+            endpoints.emplace_back(*unix_addr);\n+            continue;\n         }\n-    } else {\n-        force_localhost = true;\n+        // IPv4 or IPv6 address\n+        has_ip = true;\n+        uint16_t port{http_port};\n+        std::string host;\n+        if (!SplitHostPort(bind, port, host)) {\n+            LogError(\"%s\\n\", InvalidPortErrMsg(\"-rpcbind\", bind).original);\n+            return {}; // empty, refuse to start with a misconfigured bind\n+        }\n+        const std::optional<CService> addr{Lookup(bind, port, false)};\n+        if (!addr) {\n+            LogWarning(\"Could not bind RPC on address %s port %i: Address lookup failed.\", host, port);\n+            continue;\n+        }\n+        if (addr->IsBindAny()) {\n+            LogWarning(\"The RPC server is not safe to expose to untrusted networks such as the public internet\");\n+        }\n+        endpoints.emplace_back(addr.value());\n     }\n\n     // Access to unix sockets is controlled by filesystem permissions, so if we\n@@ -264,19 +270,9 @@ static std::vector<SocketAddr> GetBindAddresses()\n     // Otherwise, to prevent misconfiguration and accidental exposure of the HTTP\n     // interface, require -rpcallowip whenever an IP address is bound.\n     // If the user is misconfigured we restrict HTTP to localhost and log warnings.\n-    if (!only_unix_sockets && gArgs.GetArgs(\"-rpcallowip\").empty()) {\n+    if (has_ip && !has_allowip) {\n         LogWarning(\"Option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\");\n-        force_localhost = true;\n-    }\n-\n-    // Default to loopback, or replace user misconfiguration.\n-    if (force_localhost) {\n-        endpoints.clear();\n-        endpoints.emplace_back(Lookup(\"::1\", http_port, false).value());\n-        endpoints.emplace_back(Lookup(\"127.0.0.1\", http_port, false).value());\n-        if (!gArgs.GetArgs(\"-rpcallowip\").empty()) {\n-            LogWarning(\"Option -rpcallowip was specified without -rpcbind; this doesn't usually make sense\");\n-        }\n+        return localhost_endpoints();\n     }\n     return endpoints;\n }\n```\n\n---\nthis is _purely_ a suggestion, so feel free to take or leave it :)",
   "id": "rc:4292770911",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4292770911",
   "hash": "20f3638c0a84497a",
   "edited": "2026-10-16T13:22:37Z"
  },
  {
   "t": "2026-10-16T13:22:36Z",
   "kind": "review",
   "who": "winterrdog",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "text": "approach ACK\n\n---\ni am convinced by the implementation here. particularly, i like the choice of `std::variant` over polymorphism  for the `SocketAddr` class\n\nafter staring at the implementation for a while now, i think the changes are mostly in very good shape, with the introduction of `SocketAddr` being the cornerstone change that everything else seems to spring from. most of my reviews have therefore been nitpicks, since i am convinced by the overall design choices. the security is tight too \ud83d\udd12\n\ni have mostly been looking at the implementation C++ code and have not yet had an extensive look at the tests or their infrastructure code, beyond a quick perusal\n\n_one last question_: i saw `UnixSocketAddr::SetSockAddr()` handles empty and abstract namespace addresses, but we do not support binding or connecting to abstract sockets. do you think it is worth supporting them in the future for linux-specific setups ?\n\n---\n\nlooks like the PR description is out of sync with the code\n\n[quoted text omitted]\nit says `=unix:relative/path` resolves to `<datadir>/relative/path/http.sock` and `=unix:/absolute/path` to `/absolute/path/http.sock`, but `ResolveUnixSocketAddr()` uses the given path _as the socket file itself_. so `unix:rpc.sock` turns into `<datadir>/rpc.sock`, and `unix:/tmp/rpc.sock` stays `/tmp/rpc.sock`. only the bare `unix` (or `unix:`) keyword uses the default `http.sock` name\n\nthe docs, release notes and `-help` text already match the code, so i think the PR description just needs updating to reflect this, so other reviewers do not get tripped up by the mismatch\n\n---\n\ni also think this PR would be a good candidate for v33. there has been interest in this for a long time, and i think it is worth tracking as an upcoming feature for the release",
   "id": "r:5478881949",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#pullrequestreview-5478881949",
   "hash": "b86c9728fe7ee06b",
   "edited": "2026-10-16T13:31:22Z"
  },
  {
   "t": "2026-10-28T18:38:24Z",
   "kind": "review_comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "path": "doc/release-notes-36434.md",
   "commit": "ccbace1c33f30f9fb842451851263a7d83449323",
   "in_reply_to": 4237560109,
   "text": "fair point. since \"unix domain sockets\" is *more* correct, I'll change any user-facing docs to use that term. code comments and internal phrasing i think is ok to leave alone.",
   "id": "rc:4404616055",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4404616055",
   "hash": "06537fef23994edc",
   "edited": "2026-10-28T19:55:26Z"
  },
  {
   "t": "2026-10-28T18:39:08Z",
   "kind": "review_comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "path": "doc/release-notes-36434.md",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": 4239427247,
   "text": "yeah \ud83e\udd37 we can add windows support for this feature in a follow up",
   "id": "rc:4404623354",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4404623354",
   "hash": "be7984e00b726ded",
   "edited": "2026-10-28T19:55:26Z"
  },
  {
   "t": "2026-10-28T18:46:37Z",
   "kind": "review_comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "path": "src/bitcoin-cli.cpp",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": 4287028863,
   "text": "sure, using `move` here for correctness",
   "id": "rc:4404705139",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4404705139",
   "hash": "b74f5d72347b3833",
   "edited": "2026-10-28T19:55:27Z"
  },
  {
   "t": "2026-10-28T19:25:38Z",
   "kind": "review_comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "path": "src/httpserver.cpp",
   "commit": "ccbace1c33f30f9fb842451851263a7d83449323",
   "in_reply_to": 4292770911,
   "text": "I think it's a good idea to clean this up now, thanks. Taking the suggestion and tweaking a bit more on top (comments and reducing unreachable code). Adding you as coauthor to that commit.",
   "id": "rc:4405115790",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4405115790",
   "hash": "8cf3f472c556fd46",
   "edited": "2026-10-28T19:55:27Z"
  },
  {
   "t": "2026-10-28T19:30:18Z",
   "kind": "review_comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "path": "src/httpserver.cpp",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": 4287174385,
   "text": "Heh that's kind of a funny edge case. We don't complain if a user sets `-rpcport=50000` twice for example. I think it's ok to leave it. I'm more worried about a user setting `ipcbind` and `rpcbind` to the same value, but that's a pretty silly mistake",
   "id": "rc:4405162282",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4405162282",
   "hash": "eff17f42353ffb59",
   "edited": "2026-10-28T19:55:27Z"
  },
  {
   "t": "2026-10-28T19:31:53Z",
   "kind": "review_comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "path": "src/httpserver.cpp",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": 4286800301,
   "text": "fixed this along with the `GetBindAddresses()` refactor.",
   "id": "rc:4405179611",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4405179611",
   "hash": "dcb0e998d15bfca3",
   "edited": "2026-10-28T19:55:27Z"
  },
  {
   "t": "2026-10-28T19:32:48Z",
   "kind": "review_comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "path": "src/httpserver.cpp",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": 4286968868,
   "text": "sure ternaries are fun! thanks.",
   "id": "rc:4405189476",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4405189476",
   "hash": "d5f82676ef0a24cf",
   "edited": "2026-10-28T19:55:27Z"
  },
  {
   "t": "2026-10-28T19:38:37Z",
   "kind": "review_comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "path": "src/httpserver.cpp",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": 4276497992,
   "text": "yep fair enough, putting behind a compile guard",
   "id": "rc:4405247453",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4405247453",
   "hash": "633b91928c9d4487",
   "edited": "2026-10-28T19:55:27Z"
  },
  {
   "t": "2026-10-28T19:44:07Z",
   "kind": "review_comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": 4239802579,
   "text": "good suggestion thanks, using `std::ranges` and `unsigned char` here",
   "id": "rc:4405304914",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4405304914",
   "hash": "8d75968b76a7e82a",
   "edited": "2026-10-28T19:55:27Z"
  },
  {
   "t": "2026-10-28T19:53:40Z",
   "kind": "review_comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "path": "src/netbase.h",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "in_reply_to": 4239583616,
   "text": "cleaned up this comment.",
   "id": "rc:4405396420",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4405396420",
   "hash": "d4f01be3084f5d83",
   "edited": "2026-10-28T19:55:26Z"
  },
  {
   "t": "2026-10-28T19:55:26Z",
   "kind": "review",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "db638e0f44f0aaffe798a4ec7d4757246de9fb56",
   "text": "push to  e34ffb6de9e3fcd635f1e88c29c616a3ef21a2c1\n\n- Rebase on master, fix conflicts from #36509 and #36159\n\n- Incorporate lots of great feedback from @winterrdog mostly code clarity and a good catch about signed char's in socket path names",
   "id": "r:5687834770",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#pullrequestreview-5687834770",
   "hash": "d3b44b66b8bdbfc4",
   "edited": null
  },
  {
   "t": "2026-10-28T19:55:55Z",
   "kind": "force_push",
   "who": "pinheadmz",
   "commit": "e34ffb6de9e3fcd635f1e88c29c616a3ef21a2c1",
   "id": "push:e34ffb6de9e3fcd635f1e88c29c616a3ef21a2c1"
  },
  {
   "t": "2026-10-28T23:33:16Z",
   "kind": "force_push",
   "who": "pinheadmz",
   "commit": "ccbace1c33f30f9fb842451851263a7d83449323",
   "id": "push:ccbace1c33f30f9fb842451851263a7d83449323"
  },
  {
   "t": "2026-10-28T23:33:49Z",
   "kind": "comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "text": "push to ccbace1c33\n\nFIx a test-after-remove rebase mistake that broke ancestor commit CI test",
   "id": "c:6483503326",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#issuecomment-6483503326",
   "hash": "ad8442832e21f5d2",
   "edited": null
  },
  {
   "t": "2026-10-29T12:16:49Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "doc/JSON-RPC-interface.md",
   "commit": "ccbace1c33f30f9fb842451851263a7d83449323",
   "in_reply_to": null,
   "text": "PR desc typo: isloated",
   "id": "rc:4412188649",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#discussion_r4412188649",
   "hash": "408e43d80a40ca8d",
   "edited": "2026-10-29T12:29:20Z"
  },
  {
   "t": "2026-10-29T12:29:20Z",
   "kind": "review",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "ccbace1c33f30f9fb842451851263a7d83449323",
   "text": "What is the benefit of allowing HTTP over unix sockets compared to using IPC over unix sockets?\n`executeRpc()` is already exposed through IPC.\nI guess the REST interface is only exposed through HTTP, not IPC.",
   "id": "r:5697528630",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#pullrequestreview-5697528630",
   "hash": "890cb24579dc756a",
   "edited": null
  },
  {
   "t": "2026-10-29T13:26:48Z",
   "kind": "comment",
   "who": "pinheadmz",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nYou get the security advantage and possibly an efficiency advantage with a very low bar for entry. IPC requires capnproto, unix sockets only require platform support. IPC is only exposed in multiprocess mode.\n\nSee also https://github.com/bitcoin/bitcoin/pull/32297#issuecomment-2813819778",
   "id": "c:6497954399",
   "url": "https://github.com/bitcoin/bitcoin/pull/36434#issuecomment-6497954399",
   "hash": "3c6599fb6474edd1",
   "edited": null
  }
 ],
 "labels_log": [
  {
   "t": "2026-10-04T18:10:42Z",
   "action": "labeled",
   "label": "RPC/REST/ZMQ",
   "who": "DrahtBot"
  },
  {
   "t": "2026-10-06T00:16:08Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-10-08T16:08:46Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-10-08T16:34:23Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-10-08T20:14:40Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-10-10T01:46:40Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-10-28T21:01:44Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-10-28T21:09:08Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-10-29T00:34:42Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  }
 ],
 "state_log": [],
 "text_chars": 21790,
 "text_tokens_estimate": 5447,
 "changed_paths": [
  "doc/JSON-RPC-interface.md",
  "doc/release-notes-36434.md",
  "src/bitcoin-cli.cpp",
  "src/httpserver.cpp",
  "src/httpserver.h",
  "src/init.cpp",
  "src/netbase.cpp",
  "src/netbase.h",
  "src/qt/clientmodel.cpp",
  "src/test/fuzz/http_request.cpp",
  "src/test/httpserver_tests.cpp",
  "src/test/netbase_tests.cpp",
  "test/functional/interface_bitcoin_cli.py",
  "test/functional/interface_http.py",
  "test/functional/rpc_bind.py",
  "test/functional/test_framework/authproxy.py",
  "test/functional/test_framework/netutil.py",
  "test/functional/test_framework/test_framework.py",
  "test/functional/test_framework/test_node.py",
  "test/functional/test_runner.py"
 ],
 "files": [
  {
   "path": "doc/JSON-RPC-interface.md",
   "add": 12,
   "del": 0
  },
  {
   "path": "doc/release-notes-36434.md",
   "add": 31,
   "del": 0
  },
  {
   "path": "src/bitcoin-cli.cpp",
   "add": 133,
   "del": 55
  },
  {
   "path": "src/httpserver.cpp",
   "add": 108,
   "del": 51
  },
  {
   "path": "src/httpserver.h",
   "add": 9,
   "del": 10
  },
  {
   "path": "src/init.cpp",
   "add": 67,
   "del": 43
  },
  {
   "path": "src/netbase.cpp",
   "add": 203,
   "del": 25
  },
  {
   "path": "src/netbase.h",
   "add": 190,
   "del": 16
  },
  {
   "path": "src/qt/clientmodel.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/fuzz/http_request.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/httpserver_tests.cpp",
   "add": 7,
   "del": 7
  },
  {
   "path": "src/test/netbase_tests.cpp",
   "add": 498,
   "del": 0
  },
  {
   "path": "test/functional/interface_bitcoin_cli.py",
   "add": 45,
   "del": 27
  },
  {
   "path": "test/functional/interface_http.py",
   "add": 64,
   "del": 17
  },
  {
   "path": "test/functional/rpc_bind.py",
   "add": 124,
   "del": 7
  },
  {
   "path": "test/functional/test_framework/authproxy.py",
   "add": 7,
   "del": 3
  },
  {
   "path": "test/functional/test_framework/netutil.py",
   "add": 15,
   "del": 0
  },
  {
   "path": "test/functional/test_framework/test_framework.py",
   "add": 7,
   "del": 0
  },
  {
   "path": "test/functional/test_framework/test_node.py",
   "add": 22,
   "del": 2
  },
  {
   "path": "test/functional/test_runner.py",
   "add": 3,
   "del": 0
  }
 ],
 "test_lines": 857,
 "git": {
  "head": "ccbace1c33f30f9fb842451851263a7d83449323",
  "head_matches_backup": true,
  "base": "0f27bed5b2924420d65caeca439e6b036d3c6cb2",
  "patch_id": "0089f48e8e7f8234",
  "commits": [
   {
    "sha": "530b7a5a3a",
    "subject": "netbase: introduce UnixSocketAddr class",
    "files": 3,
    "add": 460,
    "del": 1
   },
   {
    "sha": "07f4da5248",
    "subject": "netbase: introduce SocketAddr class",
    "files": 3,
    "add": 322,
    "del": 1
   },
   {
    "sha": "ccfeff2195",
    "subject": "test: cover existing Proxy API",
    "files": 1,
    "add": 112,
    "del": 18
   },
   {
    "sha": "61c24c437d",
    "subject": "netbase: refactor Proxy to use SocketAddr",
    "files": 5,
    "add": 26,
    "del": 66
   },
   {
    "sha": "f0f54a97c1",
    "subject": "http: use SocketAddr instead of CService",
    "files": 4,
    "add": 23,
    "del": 24
   },
   {
    "sha": "517363b2bc",
    "subject": "http: support listening on UNIX domain sockets",
    "files": 5,
    "add": 121,
    "del": 50
   },
   {
    "sha": "6ad23a85de",
    "subject": "http: allow empty -rpcallowip if all bind addresses are unix sockets",
    "files": 1,
    "add": 55,
    "del": 42
   },
   {
    "sha": "3d04d7cb4b",
    "subject": "Enable unix sockets in test_framework: cover interface_http & rpc_bind",
    "files": 7,
    "add": 239,
    "del": 29
   },
   {
    "sha": "90b6f55b94",
    "subject": "bitcoin-cli: support connecting on UNIX domain sockets",
    "files": 4,
    "add": 167,
    "del": 81
   },
   {
    "sha": "ccbace1c33",
    "subject": "doc: add unix socket options to help and docs",
    "files": 4,
    "add": 90,
    "del": 21
   }
  ],
  "patch_truncated": true
 },
 "patch_id": "0089f48e8e7f8234",
 "input_hash": "b198d82d2ad0872b",
 "extracted_at": "2026-11-02T01:09:49+00:00"
}