{
 "number": 30951,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/30951",
 "title": "net: option to disallow v1 connection on ipv4 and ipv6 peers",
 "author": "stratospher",
 "author_association": "MEMBER",
 "created_at": "2024-09-23T12:23:48Z",
 "updated_at": "2026-09-10T19:46:02Z",
 "age_days": 724,
 "draft": false,
 "labels": [
  "P2P",
  "Needs rebase"
 ],
 "milestone": "33.0",
 "base": "master",
 "head_sha": "7c6b70d728676ea2509a0aba6c67184eac958fa4",
 "head_ref": "v2-only-option",
 "head_repo": "stratospher/bitcoin",
 "head_history": [
  {
   "t": "2024-09-24T07:10:36Z",
   "sha": "0cfc9fcf05f8c32149dcba6ffe20c9a7ecac76f2"
  },
  {
   "t": "2024-09-25T07:58:56Z",
   "sha": "7c9e5a1345435ec0cc1b69e43e429881f7b78731"
  },
  {
   "t": "2024-09-25T08:00:00Z",
   "sha": "ab5f8759ab4161a6c303f879d1bf7360dbb2f905"
  },
  {
   "t": "2024-10-28T05:45:43Z",
   "sha": "b434583fbbdaf514d6b76052cfd9c81e340487f4"
  },
  {
   "t": "2025-01-24T05:32:30Z",
   "sha": "4d4f80940ca4bf8a24f71bd810184e7159c164d6"
  },
  {
   "t": "2025-01-27T04:59:18Z",
   "sha": "5e3fa6758ba940384747575df14a75be15bfa629"
  },
  {
   "t": "2025-03-28T05:40:57Z",
   "sha": "27e90008835a4c980447d97e80910742e041dfaf"
  },
  {
   "t": "2025-11-19T15:33:10Z",
   "sha": "14ee29dedc36611f9d33a207b7c5b25a7c9b89ea"
  },
  {
   "t": "2025-12-12T15:19:54Z",
   "sha": "6b2796a7f7615ee7523b256f23d309deabada4fe"
  },
  {
   "t": "2026-04-08T18:12:41Z",
   "sha": "f7027bde8ef4215aa7c54ead4962f5079a276d1c"
  },
  {
   "t": "2026-04-09T02:16:07Z",
   "sha": "1e61206583d87ff0bc0fd7e245cefce4203b423f"
  },
  {
   "t": "2026-04-29T08:49:28Z",
   "sha": "263c16b537e1073a45e829bb98506db3ef662698"
  },
  {
   "t": "2026-05-27T09:55:13Z",
   "sha": "b559f2fdb1adf6bddc467751d6da1fc8e02b78ee"
  },
  {
   "t": "2026-07-02T18:45:44Z",
   "sha": "d72df0fc8369efc391e3f777e1b9fb20a223beb3"
  },
  {
   "t": "2026-08-13T10:14:17Z",
   "sha": "7c6b70d728676ea2509a0aba6c67184eac958fa4"
  }
 ],
 "additions": 104,
 "deletions": 4,
 "changed_files": 9,
 "commit_count": 6,
 "size_bucket": "M",
 "mergeable_state": "dirty",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "concept_nack": [
     {
      "login": "1440000bytes",
      "url": "https://github.com/bitcoin/bitcoin/pull/30951#pullrequestreview-2419071104"
     }
    ],
    "concept_ack": [
     {
      "login": "mzumsande",
      "url": "https://github.com/bitcoin/bitcoin/pull/30951#issuecomment-2379597880"
     },
     {
      "login": "dergoegge",
      "url": "https://github.com/bitcoin/bitcoin/pull/30951#issuecomment-2388558223"
     },
     {
      "login": "fjahr",
      "url": "https://github.com/bitcoin/bitcoin/pull/30951#pullrequestreview-3378943773"
     },
     {
      "login": "sipa",
      "url": "https://github.com/bitcoin/bitcoin/pull/30951#issuecomment-3482378717"
     },
     {
      "login": "kristapsk",
      "url": "https://github.com/bitcoin/bitcoin/pull/30951#issuecomment-3485606391"
     },
     {
      "login": "laanwj",
      "url": "https://github.com/bitcoin/bitcoin/pull/30951#issuecomment-3486217821"
     },
     {
      "login": "sedited",
      "url": "https://github.com/bitcoin/bitcoin/pull/30951#issuecomment-4039758978"
     },
     {
      "login": "pinigapic-lang",
      "url": "https://github.com/bitcoin/bitcoin/pull/30951#issuecomment-4040232917"
     },
     {
      "login": "davidgumberg",
      "url": "https://github.com/bitcoin/bitcoin/pull/30951#issuecomment-4425750896"
     },
     {
      "login": "danielabrozzoni",
      "url": "https://github.com/bitcoin/bitcoin/pull/30951#pullrequestreview-4580909986"
     },
     {
      "login": "ViniciusCestarii",
      "url": "https://github.com/bitcoin/bitcoin/pull/30951#pullrequestreview-5171561924"
     }
    ],
    "approach_ack": [
     {
      "login": "ajtowns",
      "url": "https://github.com/bitcoin/bitcoin/pull/30951#pullrequestreview-3369242392"
     }
    ]
   },
   "conflicts": [
    {
     "number": 35852,
     "title": "scripted-diff: Use inline const(expr) over static constexpr in headers",
     "author": "maflcko"
    },
    {
     "number": 34486,
     "title": "net: Reduce local network activity when networkactive=0",
     "author": "willcl-ark"
    }
   ]
  }
 },
 "acks_parsed": {
  "mzumsande": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2024-09-27T15:54:16Z",
   "stale": false
  },
  "dergoegge": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2024-10-02T12:45:17Z",
   "stale": false
  },
  "1440000bytes": {
   "kind": "nack",
   "hash": null,
   "t": "2024-11-06T18:02:38Z",
   "stale": false
  },
  "fjahr": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2025-10-29T21:37:50Z",
   "stale": false
  },
  "sipa": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2025-11-03T20:10:22Z",
   "stale": false
  },
  "kristapsk": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2025-11-04T11:53:34Z",
   "stale": false
  },
  "sedited": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-03-11T14:48:49Z",
   "stale": false
  },
  "pinigapic-lang": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-03-11T15:54:41Z",
   "stale": false
  },
  "danielabrozzoni": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-06-29T13:57:43Z",
   "stale": false
  },
  "ViniciusCestarii": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-09-10T19:45:58Z",
   "stale": false
  }
 },
 "acks_tally": {
  "ack": 0,
  "stale_ack": 0,
  "concept_ack": 9,
  "approach_ack": 0,
  "nack": 1,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 0,
  "changes_requested": 3,
  "distinct_reviewers": [
   "1440000bytes",
   "ViniciusCestarii",
   "ajtowns",
   "andrewtoth",
   "brunoerg",
   "danielabrozzoni",
   "davidgumberg",
   "dergoegge",
   "fanquake",
   "fjahr",
   "gmaxwell",
   "jonatack",
   "kristapsk",
   "laanwj",
   "luke-jr",
   "mzumsande",
   "naiyoma",
   "pinigapic-lang",
   "sedited",
   "sipa",
   "vasild",
   "w0xlt"
  ]
 },
 "signals": {
  "needs_rebase": true,
  "ci_failed": false,
  "mergeable_state": "dirty",
  "last_author_activity": "2026-08-13T10:20:33Z",
  "last_reviewer_activity": "2026-09-10T19:45:58Z",
  "last_reviewer": "ViniciusCestarii",
  "author_silent_days": 35,
  "waiting_on_author_days": 6,
  "days_since_update": 6
 },
 "refs": {
  "mentioned": [
   29415,
   29618,
   35766
  ],
  "depends_on": [],
  "fixes": [
   29618
  ],
  "linked_issues": [
   {
    "number": 29618,
    "type": "issue",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "V2 Only Option"
   }
  ],
  "references": [
   {
    "number": 29618,
    "type": "issue",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "V2 Only Option"
   },
   {
    "number": 29415,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2026-01-12",
    "title": "Broadcast own transactions only via short-lived Tor or I2P connections"
   },
   {
    "number": 35766,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2026-07-22",
    "title": "p2p: Assume v2transport for addresses from seeds"
   }
  ],
  "conflicts": [
   35852,
   34486
  ]
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [
  "src/init.cpp",
  "src/net.cpp",
  "src/net.h",
  "src/netbase.cpp",
  "src/netbase.h",
  "test/functional/p2p_v2_encrypted.py"
 ],
 "body": "resolves #29618.\n\nThis PR adds a config flag option `-v2onlyclearnet` which disallows outbound v1 connections on ipv4 and ipv6 networks since they're unencrypted. outbound v1 connections are still possible from tor/i2p/cjdns peers since they're encrypted networks.\n\n- v1 outbound connections to peers are not attempted\n- v1 reconnections are not attempted (if peer is falsely advertised as v2 peer and we attempt a v2 connection but it fails, we do not attempt a v1 reconnection when `-v2onlyclearnet` is switched on)\n\nCurrently 70% of reachable nodes in network supporting v2 (according to https://21.ninja/reachable-nodes/node-service-share/ and https://bitnodes.io/nodes). Also found 81% of addresses supporting v2 in the addrman of nodes I checked - personal node and the nodes in [peer.observer](https://peer.observer/addrman/alice). (You can use [this branch ](https://github.com/stratospher/bitcoin/commits/addrinfo_service_display/)to check the % of v2 addresses in a node's addrman.)\n\nEDIT: see [summary](https://github.com/bitcoin/bitcoin/pull/30951#issuecomment-4346061700) on pros and cons for whether to allow v2 inbounds or not for `-v2onlyclearnet`.",
 "commits": [
  {
   "sha": "cc6c15a85a17debd42f9698010ba66ada4ecf20b",
   "date": "2026-08-13T07:17:03Z",
   "message": "net: add helper to identify clearnet networks\n\nonly-clearnet condition is used in a few other places as well."
  },
  {
   "sha": "8b5e2ee692a210d93e87631f2a7f255d20b9095d",
   "date": "2026-08-13T07:17:03Z",
   "message": "net: add option in CConman to allow only v2 clearnet connections\n\na boolean option `m_v2only_clearnet` is introduced in CConman\nwhich will (in a later commit) store if the user wishes to\nestablish only outbound v2 connections to IPv4/IPv6 peers\nsince they are unencrypted.\n\nthis option is accessible outside CConman using\n`RequiresV2ForOutbound()` function with the IP address we're trying\nto connect to passed as an argument."
  },
  {
   "sha": "5974d948ff72fceebf04cfa2e011220b9352ca0b",
   "date": "2026-08-13T07:17:03Z",
   "message": "init: add -v2onlyclearnet config option\n\nif this option is set by the user, v1 connections on unencrypted\nnetworks like IPV4/IPV6 will be disallowed. Only users with real\nneed are recommended to turn this on because it could risk network\npartitioning in the unlikely scenario that everyone turns it on."
  },
  {
   "sha": "517ae255f92acc58ee78d88637d017c7800b9b86",
   "date": "2026-08-13T07:17:03Z",
   "message": "net: disable v1 connections, reconnections on clearnet\n\nif `-v2onlyclearnet` is turned on,\n- v1 addresses from addrman are dropped if selected and manual\nconnections aren't attempted for outbound connections if it's\nfrom IPV4/IPV6 networks.\n- v1 downgrade mechanism is not attempted if v2 connection wasn't\nsuccessful"
  },
  {
   "sha": "777683143f6619be05fc5df2f4c92f8310f22ce9",
   "date": "2026-08-13T07:17:03Z",
   "message": "test: Check that v1 connections to clearnet peers don't work\n\nwhen `-v2onlyclearnet` is turned on:\n- v1 connections to clearnet peers don't work\n- v2 connections to clearnet peers work\n- v1 connections to tor/i2p/cjdns peer works\n\na proxy is used because otherwise NET_UNROUTABLE is the default\nnetwork in the tests."
  },
  {
   "sha": "7c6b70d728676ea2509a0aba6c67184eac958fa4",
   "date": "2026-08-13T07:17:03Z",
   "message": "doc: add release notes for v2onlyclearnet option"
  }
 ],
 "timeline": [
  {
   "t": "2024-09-24T07:10:36Z",
   "kind": "force_push",
   "who": "stratospher",
   "commit": "0cfc9fcf05f8c32149dcba6ffe20c9a7ecac76f2"
  },
  {
   "t": "2024-09-25T07:58:56Z",
   "kind": "force_push",
   "who": "stratospher",
   "commit": "7c9e5a1345435ec0cc1b69e43e429881f7b78731"
  },
  {
   "t": "2024-09-25T08:00:00Z",
   "kind": "force_push",
   "who": "stratospher",
   "commit": "ab5f8759ab4161a6c303f879d1bf7360dbb2f905"
  },
  {
   "t": "2024-09-26T16:40:02Z",
   "kind": "comment",
   "who": "vasild",
   "assoc": "MEMBER",
   "text": "In https://github.com/bitcoin/bitcoin/issues/29618 and here, I don't see the motivation to forbid v1 connections. In other words, what is the purpose of this?\n\nIn addition to the concerns expressed in https://github.com/bitcoin/bitcoin/issues/29618, there is one more - if V2-only is widespread, it may be hard to eclipse V2-only node, but then it becomes easy to eclipse a V1 node which has a problem of finding peers to connect to, so an attacker starts a lot of nodes that do accept V1 connections.\n\nI see possible downsides and 0 benefit of a v2only option."
  },
  {
   "t": "2024-09-27T15:54:16Z",
   "kind": "comment",
   "who": "mzumsande",
   "assoc": "MEMBER",
   "text": "Concept ACK\n\n[quoted text omitted]\nWell, to gain the benefits of BIP324. For example if you are concerned about someone inspecting the traffic to your node it really doesn't matter how many BIP324 peers you have if you have just one unencrypted connection. You could also run tor-only in this case, but that has its own disadvantages and `-onlynet=onion` shares the exact same downside that if everyone did it, the network would split. If some, but not all nodes who are running only on privacy networks would be willing to also have clearnet peers with this option, that would be a good thing in my opinion.\n\n[quoted text omitted]\nthat would be a problem, but `-onlynet`, `-blocksonly` etc. have that exact same problem. I see this as an option you would only choose if you actually need it because you are concerned about unencrypted traffic."
  },
  {
   "t": "2024-09-27T21:35:08Z",
   "kind": "comment",
   "who": "jonatack",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nOur docs address this to an extent [here](https://github.com/bitcoin/bitcoin/blob/master/doc/i2p.md#additional-configuration-options-related-to-i2p) and [here](https://github.com/bitcoin/bitcoin/blob/master/doc/cjdns.md#additional-configuration-options-related-to-cjdns). As those docs point out, `-onlynet` only affects outbound connections (not inbound and manual ones), and we suggest that it be used with multiple networks.  My blog goes further into it [here](https://jonatack.github.io/articles/using-alternative-p2p-networks-with-bitcoin-core#why-use-multiple-bitcoin-p2p-networks) and [here](https://jonatack.github.io/articles/using-alternative-p2p-networks-with-bitcoin-core#considerations-with-running-tor-only).\n\n[quoted text omitted]\nAgree. My node, for instance, runs over tor/i2p/cjdns and makes manual connections to trusted clearnet peers.\n\n[quoted text omitted]\nAgree. With this change, clearnet node operators may need to accept v2, whether they wish to or not. We generally try to avoid forcing users to do things. I suppose my concept ack on this would depend on that tradeoff."
  },
  {
   "t": "2024-09-28T04:28:46Z",
   "kind": "comment",
   "who": "vasild",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nTrue. Lets dive a bit deeper - what are the reasons to be concerned about somebody inspecting the traffic to my node?"
  },
  {
   "t": "2024-09-28T13:21:39Z",
   "kind": "review_comment",
   "who": "jonatack",
   "assoc": "MEMBER",
   "path": "src/init.cpp",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nThis is unfortunately only one brigading campaign by one or more prominent bitcoiners on social media away from being potentially adopted by many nodes.\n\nWith -onlynet, the network partition risk is in practice opt-in, i.e. chosen by a minority subset for themselves.  Whereas here, the network partitioning and the lack of peers risks could be imposed on a future minority of users that are running earlier versions of Bitcoin Core. This seems at odds with maintaining backward compatibility for that minority."
  },
  {
   "t": "2024-09-28T13:22:55Z",
   "kind": "review_comment",
   "who": "jonatack",
   "assoc": "MEMBER",
   "path": "src/net.h",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": null,
   "text": "\"may be\" or \"can be\"\n\n```suggestion\n     * connections on Tor/I2P/CJDNS can be v1 or v2 connections.\n```"
  },
  {
   "t": "2024-09-28T19:54:09Z",
   "kind": "comment",
   "who": "mzumsande",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nSome thoughts off the top my head:\n- You don't want others (e.g. network admins, internet providers, etc.) to know that you are running a bitcoin node at all. Maybe it's not allowed in your network / country etc., maybe for other reasons such as personal security.\n- Transaction privacy\n\nIn both of these cases, if you accept inbounds they could just connect to you as an alternative (but they would need to have a suspicion, whereas detection of bitcoin-related network data could be automated). So another alternative would be to only disallow v1 connections for outbound peers. In that case, if you don't want any v1 connections at all you'd have to run with `-nolisten`."
  },
  {
   "t": "2024-09-29T16:51:55Z",
   "kind": "comment",
   "who": "vasild",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nThis is what is worrying me - V2-only will not hide the fact that I am running a bitcoin node, but may give the false impression that it does. This is dangerous. My node will connect to publicly known bitcoin nodes and the mere fact that I have a TCP connection to an `addr:port`, where it is known that a bitcoin node is running, is already revealing enough. No need to inspect the traffic itself.\n\nAnother possible misunderstanding is that V2-only makes the traffic impossible to spy. I can imagine a blatant MITM, which is detectable because the session keys would differ, should somebody bother to check them. Once I detect this, whom am I going to complain to? My oppressive gov/ISP/whatever, same one that is doing the spying? Or the ISP can outright redirect my connections to `addr:port` to their spy node at `spyaddr:port` (I think I am talking to `addr`, but `addr` does not even have a connection from me). The point is that the traffic is spyable. Then, what is it so much that I want to keep away from spies? The data being transferred is all public, except if we are talking about me broadcasting my own transactions, there you go:\n\n[quoted text omitted]\nV2-only may give the false impression that it breaks the link between transaction origin and IP address / geolocation. Even with unspyable p2p encryption, I may have a connection to a spy bitcoin node which then sees my traffic. Like you said \"it really doesn't matter how many BIP324 peers you have if you have just one unencrypted connection\" I think this is the same as \"it does not matter even if all your connections are encrypted, if you have just one (encrypted) connection to a spy node\"."
  },
  {
   "t": "2024-09-29T18:20:22Z",
   "kind": "comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "text": "@vasild V2 only doesn't protect against active attacks like the ones you've mentioned which require resources from the other party to run a node to spy the traffic.\n\nV2 only protects against a cheaper attack vectors possible because of passive inspection of network traffic flowing through different medium. They don't need the other party to run a node to spy.\n\n[quoted text omitted]\nYes, for the same reason as wanting to encrypt network traffic in the first place and this just offers a stronger guarantee when running a node with v2 support that unencrypted clearnet bitcoin traffic is not being collected and sold by other parties. Deep packet inspection, keyword filtering are cheaper for ISPs/firewalls to pull off and v2 only would protect against this."
  },
  {
   "t": "2024-10-02T11:53:28Z",
   "kind": "comment",
   "who": "vasild",
   "assoc": "MEMBER",
   "text": "A V2-only option will:\n\n* not hide the fact that one runs bitcoin node (that is true regardless of encryption) and\n* not stop even moderately motivated actor from spying for transaction origin (either by opening a P2P connection to the target or bricking V2 encryption or outright redirecting connections to their node)\n\nbut it will give the false impression that it does those two things. Further, it will make it more difficult for old nodes to find peers to connect to.\n\nConcept NACK because of that."
  },
  {
   "t": "2024-10-02T12:45:17Z",
   "kind": "comment",
   "who": "dergoegge",
   "assoc": "MEMBER",
   "text": "Concept ACK\n\nThis option seems useful for users that want to:\n\n* prevent passive spying on their connections\n* increase the cost of tampering with the data exchanged on their connections\n* increase the cost of detecting that they run a bitcoin node\n\n[quoted text omitted]\nHave you checked how diverse these ~60% of v2 supporting nodes are? An extreme example: if they are all on running on AWS then I don't think we should add the option at this time."
  },
  {
   "t": "2024-10-02T14:19:22Z",
   "kind": "comment",
   "who": "vasild",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nHow? Given that the spy does not need to inspect the traffic at all:\n\n[quoted text omitted]"
  },
  {
   "t": "2024-10-02T14:27:42Z",
   "kind": "comment",
   "who": "sipa",
   "assoc": "MEMBER",
   "text": "@vasild That assumes the attacker has sufficient monitoring infrastructure in place to maintain an accurate list of Bitcoin P2P ip:ports. That's obviously not impossible, but it is a significantly larger effort than stateless packet inspection looking for the string \"\\xf9\\xbe\\xb4\\xd9version\\x00\\x00\\x00\\x00\\x00\".\n\nAnd yes, very little in BIP324 protects against an attacker deliberately targetting specific individuals - its goal is increasing costs for large-scale monitoring. From that perspective I agree there is a risk for a false sense of security when introducing options like these, but I think it's a stretch to say that that makes it pointless. I can very well imagine this makes it possible to run a node at all for some users.\n\nHowever, as I pointed out in the linked issue, I am somewhat concerned about a potential future where it becomes harder for other/older software to connect to the network if large swaths move to be v2-only. Because of that, I wonder if it isn't better to make this only apply to outbound connections, and advise people who want more private operation to not listen for inbound connections."
  },
  {
   "t": "2024-10-02T14:59:19Z",
   "kind": "comment",
   "who": "jonatack",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nYes. I may be potentially concept/approach ack here if this proposal adopts the suggestion above / in https://github.com/bitcoin/bitcoin/issues/29618#issuecomment-1994415042 or https://github.com/bitcoin/bitcoin/issues/29618#issuecomment-2384291593. (Along with perhaps additional user documentation for node runners, maybe in the relevant config option helps and/or in `/doc`.)"
  },
  {
   "t": "2024-10-03T21:15:53Z",
   "kind": "comment",
   "who": "1440000bytes",
   "assoc": "CONTRIBUTOR",
   "text": "I think it's too early to add this option but it will remain unused by most and off by default. I don't see anything wrong with some users testing it.\n\nThis doesn't hide the fact that a user is running a bitcoin node (most IPv4 nodes use default port). It just ensures all peers are using v2 for P2P."
  },
  {
   "t": "2024-10-10T20:22:13Z",
   "kind": "comment",
   "who": "brunoerg",
   "assoc": "MEMBER",
   "text": "A mutation testing report for this PR is available at: https://brunoerg.xyz/mutation-core-front"
  },
  {
   "t": "2024-10-24T10:15:46Z",
   "kind": "comment",
   "who": "laanwj",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nRight. Would it maybe make sense to have an option to restrict transaction broadcast and relay to v2-only, for IPv4 and IPv6 connections? Instead of not connect at all? Eg consider v1 connections blocks-only (except those over Tor/I2P). This alleviates the risk of network partition of consensus. While still providing a bit of added privacy for where it matters."
  },
  {
   "t": "2024-10-28T05:45:43Z",
   "kind": "force_push",
   "who": "stratospher",
   "commit": "b434583fbbdaf514d6b76052cfd9c81e340487f4"
  },
  {
   "t": "2024-10-28T05:50:00Z",
   "kind": "comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "text": "I've rebased and changed the approach in the PR to have v2 only outbound connections. So there's null partition risk because of the option now.\n\n[quoted text omitted]\nI don't think just sending transactions over encrypted connections gives that much extra privacy.\n\nPassive attackers can still:\n1. _cheaply_ tell you're running a bitcoin node looking at the network magic bytes.\n2. there's transaction lengths which can be used to distinguish 1 transaction from another.\n\nHaving all network traffic as encrypted would give better privacy when dealing with 1."
  },
  {
   "t": "2024-10-30T11:26:01Z",
   "kind": "comment",
   "who": "laanwj",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\ni'm not advicating to send *just transactions*, v2 connections would have blocks+transactions, all of it. Not sending transactions over v1 makes sure that transactions aren't sent over the network in plaintext.\n\nIn the long term, if the idea is to phase out P2P v1, i think demotiing it to a blocksonly-protocol makes sense. It holds the network together against eclipse attacks and accidental partitioning, but doesn't reveal anything privacy sensitive.\n\nSure, passive attackers can still see packet sizes in the v2 connections, but that doesn't actually change if you refuse to accept and/or make v1 connections at all?\n\n[quoted text omitted]\ni still don't believe there is any hiding like that. There's so many tells for passive attackers: using the DNS seeds, connecting to certain nodes, using port 8333 (in and/or out), using P2P address gossip. Sure, if you manage to avoid all of those, it's less apparent, but that's so much work and easy to screw up with a small mistake."
  },
  {
   "t": "2024-11-06T14:30:24Z",
   "kind": "comment",
   "who": "vasild",
   "assoc": "MEMBER",
   "text": "Before I could see the purpose of the full v2only option: 1. to hide the fact that a bitcoin node is running and 2. hide its own transactions. However I think it would achieve neither of those, but I could see how it looked like it would. Now it is changed:\n\n[quoted text omitted]\nDoes it still have the same motivation: 1. and 2.? I think the idea in https://github.com/bitcoin/bitcoin/issues/29618 is that v1 connections are somehow harmful and we must not have any of them. Now with this PR we would allow v1 inbound connections? @iotamega, do you think this would resolve #29618? Once the node has e.g. 30 connections and some of them are v1 and some v2, I think it is irrelevant which are inbound and which are outbound.\n\nConsider outbound v1 connections to clearnet but via the Tor proxy (via the Tor network and Tor exit nodes), if `-proxy=` is given. Assuming there is some reason to avoid v1 outbound (which I don't see), should those be avoided as well?"
  },
  {
   "t": "2024-11-06T18:02:38Z",
   "kind": "review",
   "who": "1440000bytes",
   "assoc": "CONTRIBUTOR",
   "state": "CHANGES_REQUESTED",
   "commit": "b434583fbbdaf514d6b76052cfd9c81e340487f4",
   "text": "NACK\n\nThis pull request and related efforts are bad for bitcoin in lot of ways not just partition risk.\n\nWe need to fix other things before trying to achieve this. Disappointed that some devs keep repeating it will hide that you are running a node."
  },
  {
   "t": "2025-01-16T21:23:41Z",
   "kind": "review_comment",
   "who": "luke-jr",
   "assoc": "CONTRIBUTOR",
   "path": "src/init.cpp",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": null,
   "text": "Rather avoid the temporary global and just check this when setting `connOptions`"
  },
  {
   "t": "2025-01-16T21:23:52Z",
   "kind": "review_comment",
   "who": "luke-jr",
   "assoc": "CONTRIBUTOR",
   "path": "src/init.cpp",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": null,
   "text": "nit: indentation"
  },
  {
   "t": "2025-01-16T21:41:00Z",
   "kind": "review_comment",
   "who": "luke-jr",
   "assoc": "CONTRIBUTOR",
   "path": "src/net.h",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": null,
   "text": "The method doesn't change anything, it just returns a value..."
  },
  {
   "t": "2025-01-16T22:22:58Z",
   "kind": "review",
   "who": "luke-jr",
   "assoc": "CONTRIBUTOR",
   "state": "CHANGES_REQUESTED",
   "commit": "b434583fbbdaf514d6b76052cfd9c81e340487f4",
   "text": "No opinion on concept. Just code review."
  },
  {
   "t": "2025-01-24T05:32:30Z",
   "kind": "force_push",
   "who": "stratospher",
   "commit": "4d4f80940ca4bf8a24f71bd810184e7159c164d6"
  },
  {
   "t": "2025-01-24T05:33:22Z",
   "kind": "review_comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "path": "src/init.cpp",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": 1919211882,
   "text": "good point! done."
  },
  {
   "t": "2025-01-24T05:34:50Z",
   "kind": "review_comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "path": "src/net.h",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": 1919254645,
   "text": "makes sense. changed the comment to \"Returns true if outbound v1 connections need to be disabled on IPV4/IPV6 network.\""
  },
  {
   "t": "2025-01-25T21:03:45Z",
   "kind": "review_comment",
   "who": "luke-jr",
   "assoc": "CONTRIBUTOR",
   "path": "src/init.cpp",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": null,
   "text": "```suggestion\n    connOptions.disable_v1conn_clearnet = args.GetBoolArg(\"-v2onlyclearnet\", false);\n```\n\nThe InitError above means this should be safe"
  },
  {
   "t": "2025-01-25T21:03:53Z",
   "kind": "review",
   "who": "luke-jr",
   "assoc": "CONTRIBUTOR",
   "state": "CHANGES_REQUESTED",
   "commit": "4d4f80940ca4bf8a24f71bd810184e7159c164d6",
   "text": ""
  },
  {
   "t": "2025-01-27T04:59:18Z",
   "kind": "force_push",
   "who": "stratospher",
   "commit": "5e3fa6758ba940384747575df14a75be15bfa629"
  },
  {
   "t": "2025-03-28T05:40:57Z",
   "kind": "force_push",
   "who": "stratospher",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf"
  },
  {
   "t": "2025-10-23T10:22:17Z",
   "kind": "review_comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": null,
   "text": "nit: Should check `DisableV10nClearnet()` first -- `ShouldReconnectV1` takes locks in order to return true."
  },
  {
   "t": "2025-10-23T10:26:21Z",
   "kind": "review_comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "path": "src/init.cpp",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": null,
   "text": "Shouldn't there be a constant with the default setting?\n\nWhen do you \"really need\" this option? Might be better to give a more specific recommendation here?\n\nIf you usually want to set `-listen=0` with it, should we add an arg-interaction rather than just help text?\n\n```c++\nif (args.GetBoolArg(\"-v2onlyclearnet\", false)) {\n    if (args.SoftSetBoolArg(\"-listen\", false)) {\n        LogInfo(\"parameter interaction: -v2onlyclearnet set -> setting -listen=0\\n\");\n    }\n}\n```"
  },
  {
   "t": "2025-10-23T10:27:38Z",
   "kind": "review_comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": null,
   "text": "Is there any reason to not have DisableV10nClearnet do the GetNetClass internally?"
  },
  {
   "t": "2025-10-23T14:11:45Z",
   "kind": "review_comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": null,
   "text": "Maybe add an `IsClearnet(Network net) { return net == NET_IPV4 || net == IPV6; }` helper? There's a few other only-clearnet conditions in the code."
  },
  {
   "t": "2025-10-23T14:28:34Z",
   "kind": "review",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "text": "Concept review:\n\nI think this has two potential benefits:\n\n * avoids cleartext relay of transactions, particularly your own. #29415 is better at solving that problem, but a small step is also a good thing. this is only useful if you also disable inboud clearnet connections however.\n * avoids easy detection that you're running a bitcoin node by stateless packet connection. if you're a listening node, then you still advertise your ip over the bitcoin network, so it's not hard to find you, in that case. traffic analysis or similar also likely gives this away, but that is significantly more work.\n\nBoth these suggest to me that this option is only really meaningful for non-listening nodes. Perhaps either automatically setting nolisten, or adding a \"only listen on non-clearnet networks\" option and automatically setting that would be good.\n\nOnly allowing v2 clearnet inbounds might make sense, but it seems concerning for eclipsing old nodes that don't support v2. Downgrading clearnet v1 inbounds to blocksonly mode might be an acceptable compromise there. Probably old nodes would still want some way to broadcast their transactions to the network, however, which might be hard to support in that model.\n\nParticularly if this option is only used by nodes that aren't listening on clearnet anyway, I think this is a reasonable option to have.\n\nApproach ACK 45bd8914658a675d00aa9c83373d6903a8a9ece8"
  },
  {
   "t": "2025-10-24T21:36:26Z",
   "kind": "review_comment",
   "who": "fjahr",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": 2454655782,
   "text": "Could the naming be kept consistent between the function names and the init arg? One is \"disable v1\" and the other is \"only v2\" and I don't see a good reason for that."
  },
  {
   "t": "2025-10-24T21:37:58Z",
   "kind": "review_comment",
   "who": "fjahr",
   "assoc": "MEMBER",
   "path": "src/net.h",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": null,
   "text": "nit: m_ prefix?"
  },
  {
   "t": "2025-10-27T15:09:23Z",
   "kind": "review",
   "who": "mzumsande",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "text": "A year later, adoption is now almost at ~70% according to https://21.ninja/reachable-nodes/node-service-share/ - could update the OP with that info."
  },
  {
   "t": "2025-10-29T21:37:50Z",
   "kind": "review",
   "who": "fjahr",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "text": "Concept ACK\n\nI agree with @ajtowns that coupling this with nolisten makes sense and also means that this should not be too dangerous. Rather than turning that on by default and potentially risking the user don't fully understand the implications of this, the option could also error if nolisten isn't set."
  },
  {
   "t": "2025-11-03T20:10:22Z",
   "kind": "comment",
   "who": "sipa",
   "assoc": "MEMBER",
   "text": "Concept ACK. I think deployment of v2-capable nodes is sufficient that it's reasonable to offer an outbound-v2-only option."
  },
  {
   "t": "2025-11-04T11:53:34Z",
   "kind": "comment",
   "who": "kristapsk",
   "assoc": "CONTRIBUTOR",
   "text": "Concept ACK"
  },
  {
   "t": "2025-11-04T14:13:37Z",
   "kind": "comment",
   "who": "laanwj",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nConcept ACK. i was critical of this in the past, but i'm more convinced that it makes some sense now, and believe it outweighs the implementation/maintenance cost of such a feature."
  },
  {
   "t": "2025-11-04T14:54:10Z",
   "kind": "review_comment",
   "who": "laanwj",
   "assoc": "MEMBER",
   "path": "src/net.h",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": null,
   "text": "do we want a `DEFAULT_DISABLE_V1CONN_CLEARNET`?\n(would be symmetric to the other options)"
  },
  {
   "t": "2025-11-04T15:02:44Z",
   "kind": "review_comment",
   "who": "laanwj",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": null,
   "text": "Would prefer to generalize this function name to `DisableV1OnNetwork`. That it happens to be about clearnet is an implementation, not an interface detail (as the network is passed in).\n\nEdit: could add `Outbound`, though. This is not obvious."
  },
  {
   "t": "2025-11-06T15:07:25Z",
   "kind": "comment",
   "who": "vasild",
   "assoc": "MEMBER",
   "text": "I re-assessed this carefully.\n\nIt seems ok to me to have v2only with the following properties:\n\n* Can only be enabled if not listening, like suggested above. Otherwise we have to either:\n   * accept v1 incoming which defeats the purpose of this because then we will have cleartext connections or\n   * deny v1 incoming (only allow v2 incoming) which is a problem if this is widely adopted because then old nodes that do not support v2 will have a hard time finding peers to connect to and will be subject to eclipse from an attacker who runs many v1-accepting nodes.\n\n[quoted text omitted]\nThe node is still making outbound connections to addresses on the internet to port `8333`!\n\n* So it would be good to make it very obvious to the user that this option will not hide the fact that they are running a Bitcoin node.\n\n* Also, it would be good to make it very obvious that this option only marginally if at all improves own transactions' privacy. Why? It improves it in the following case: if a node has only cleartext v1 connections, then their ISP can monitor all traffic that goes in and out of the node. So the ISP can know when the node sends their own transactions because it never received those transactions from others before sending them. Thus the node must be the originator. However, if there is at least one encrypted connection, then the ISP cannot know whether the transaction originated from the node or whether the node is just relaying a transaction it received over the encrypted connection. So this option helps to avoid the case of having only cleartext v1 connections with a passive spy that is only inspecting traffic. Then the option might be `-avoid-having-all-connections-as-v1` If the spy ISP is willing to redirect outgoing connections to their spyish nodes, then v2only does not help."
  },
  {
   "t": "2025-11-06T18:51:58Z",
   "kind": "review",
   "who": "mzumsande",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "text": "[quoted text omitted]\n\nI still don't find the reason for tying it to `-listen=0` instead of also disallowing v1 inbounds compelling. Yes, if everyone disabled v1 incoming peers that could lead to v1 nodes being eclipsed. But with the suggested approach, if too many nodes just disabled incoming connections entirely to be able to use the option, that wouldn't be any better, because now _every_ node would have trouble finding peers / risk being eclipsed.\n\nIf the downsides are documented well in the helptext, I don't see a difference to many other existing optional settings that would be bad if everyone used them. (`-listen`, `-blocksonly`, `-onlynet` etc.). But just comparing the two options in a vacuum, allowing only v2 inbounds seems better than allowing no inbounds at all."
  },
  {
   "t": "2025-11-11T17:27:41Z",
   "kind": "comment",
   "who": "vasild",
   "assoc": "MEMBER",
   "text": "From the [issue](https://github.com/bitcoin/bitcoin/issues/29618#issuecomment-2388394165) that prompted this:\n[quoted text omitted]\n\nI still think that this is misguided and can get people into \"very real issues\" if such an option gives the impression that it:\n\n1. Hides the fact that you run a bitcoin node. It does not at all because you will still connect to others at port `8333`, and that is the easiest way to detect bitcoin traffic, no need for spy nodes or inspecting the traffic contents.\n\n2. Hides you as originator of your own transactions from your ISP. A little bit it does, but not much as commented in details above. I [think](https://github.com/bitcoin/bitcoin/pull/30951#issuecomment-3497705768) that all-v2-connections is the same as at-least-one-v2-connection for concealing the transaction origin.\n\nAnyway, if it is made clear that a v2only option does not achieve 1. or 2., then I guess it is fine. V2 adoption has increased and there are enough knowledgeable people commenting here, so with this post I would like to withdraw my \"Concept NACK\" and leave it in your capable hands.\n\nConcept 0"
  },
  {
   "t": "2025-11-19T15:33:10Z",
   "kind": "force_push",
   "who": "stratospher",
   "commit": "14ee29dedc36611f9d33a207b7c5b25a7c9b89ea"
  },
  {
   "t": "2025-11-19T15:36:07Z",
   "kind": "review_comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": 2454643475,
   "text": "oh good point. done."
  },
  {
   "t": "2025-11-19T15:36:35Z",
   "kind": "review_comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "path": "src/init.cpp",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": 2454652805,
   "text": "done. I've made it an error instead so that the user doesn't accidentally switch off listening mode."
  },
  {
   "t": "2025-11-19T15:38:05Z",
   "kind": "review_comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": 2454655782,
   "text": "[quoted text omitted]\n\ndone. the initial version in the PR with both outbound+ inbound v2 only required another function to detect inbound onion and we had to pass network. but we can remove it for outbound v2 only."
  },
  {
   "t": "2025-11-19T15:39:15Z",
   "kind": "review_comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "27e90008835a4c980447d97e80910742e041dfaf",
   "in_reply_to": 2490867244,
   "text": "makes sense. changed it to `RequiresV2ForOutbound`. hopefully it's better."
  },
  {
   "t": "2025-11-20T03:27:28Z",
   "kind": "comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "text": "Thank you all for the very helpful feedback on this! and sorry for getting late with the update.\n\nI've pushed an [update](https://github.com/bitcoin/bitcoin/compare/27e90008835a4c980447d97e80910742e041dfaf..14ee29dedc36611f9d33a207b7c5b25a7c9b89ea) addressing all the review comments except @mzumsande's conceptual concern about whether\n`v2onlyclearnet` should accept v2 inbounds as well so that the network doesn't face a shortage of listening capacity in the worst case scenario where a huge fraction of network turns it on.\n\nQuick summary of the [update](https://github.com/bitcoin/bitcoin/compare/27e90008835a4c980447d97e80910742e041dfaf..14ee29dedc36611f9d33a207b7c5b25a7c9b89ea):\n- More description in help text to highlight that `-v2onlyclearnet` doesn't hide the fact that you're running a bitcoin node. (thanks @vasild!)\n- `-v2onlyclearnet`, `-listen` arg interaction which errors if we use `-v2onlyclearnet` on a listening node (thanks @ajtowns!)\n-  naming consistency in functions/variables to use \"v2 only\" language instead of mixing it with potentially confusing \"disable v1\" language also. Ex: s/`DisableV10nClearnet`/`RequiresV2ForOutbound` (thanks @fjahr!)\n- introduced `DEFAULT_DISABLE_V1CONN_CLEARNET=false` (thanks @laanwj!)\n\nregarding https://github.com/bitcoin/bitcoin/pull/30951#pullrequestreview-3429992454:\n[quoted text omitted]\n\nI assumed people who didn't want network traffic to be spyed on are already people who didn't accept (possibly spy) connections from others (people running private nodes) and didn't think of the impact on the listening slots in the network. This doesn't necessarily need to be the case though. `-v2onlyclearnet` being used with `listen=0` would also need `-listenonion=0`, so we'd also be turning off tor/i2p inbounds.\n\nHowever this feels like lots of users setting listen=0 problem, and we're showing someone a reason for setting listen=0 + making that future slightly more probable. Will need to think more about this and curious about other people's thoughts on https://github.com/bitcoin/bitcoin/pull/30951#pullrequestreview-3429992454 as well."
  },
  {
   "t": "2025-12-12T15:19:54Z",
   "kind": "force_push",
   "who": "stratospher",
   "commit": "6b2796a7f7615ee7523b256f23d309deabada4fe"
  },
  {
   "t": "2026-03-11T14:48:49Z",
   "kind": "comment",
   "who": "sedited",
   "assoc": "MEMBER",
   "text": "Concept ACK\n\nAfaict the project has communicated clearly that v2 encryption aims to protect against passive adversaries. It seems desirable to make good on that. Adding this to the 32 milestone."
  },
  {
   "t": "2026-03-11T15:54:41Z",
   "kind": "comment",
   "who": "pinigapic-lang",
   "assoc": "NONE",
   "text": "Concept ACK"
  },
  {
   "t": "2026-04-08T18:12:41Z",
   "kind": "force_push",
   "who": "stratospher",
   "commit": "f7027bde8ef4215aa7c54ead4962f5079a276d1c"
  },
  {
   "t": "2026-04-09T02:16:07Z",
   "kind": "force_push",
   "who": "stratospher",
   "commit": "1e61206583d87ff0bc0fd7e245cefce4203b423f"
  },
  {
   "t": "2026-04-19T19:21:36Z",
   "kind": "review_comment",
   "who": "fjahr",
   "assoc": "MEMBER",
   "path": "src/netbase.cpp",
   "commit": "1e61206583d87ff0bc0fd7e245cefce4203b423f",
   "in_reply_to": null,
   "text": "nit: `IsClearnet()` is more our usual style."
  },
  {
   "t": "2026-04-19T19:23:07Z",
   "kind": "review_comment",
   "who": "fjahr",
   "assoc": "MEMBER",
   "path": "src/net.h",
   "commit": "1e61206583d87ff0bc0fd7e245cefce4203b423f",
   "in_reply_to": null,
   "text": "Seems like this could be private?"
  },
  {
   "t": "2026-04-19T19:38:55Z",
   "kind": "review_comment",
   "who": "fjahr",
   "assoc": "MEMBER",
   "path": "src/init.cpp",
   "commit": "1e61206583d87ff0bc0fd7e245cefce4203b423f",
   "in_reply_to": null,
   "text": "This error message is a bit confusing, first \"Cannot set -v2onlyclearnet=1 with listen=0\" seems to be wrong, it should say \"listen=1\" there (or s/with/without/). And then maybe switch the order of the current second and third sentence, I think that would read a bit better. For my taste the second sentence is a bit much because I don't think it's going to change anyone's mind but I would be fine to keep it. But we could also ask people to read the help text of the option carefully where we are more detailed."
  },
  {
   "t": "2026-04-19T19:46:22Z",
   "kind": "review_comment",
   "who": "fjahr",
   "assoc": "MEMBER",
   "path": "src/init.cpp",
   "commit": "263c16b537e1073a45e829bb98506db3ef662698",
   "in_reply_to": null,
   "text": "Not a strong opinion but as it is worded now, probably everyone who runs a bitcoin node will say, yes, these network observers are a problem for my privacy. It might be better to say something like: \"if you are at risk of your traffic getting blocked or service shut down\". That would be a bit more strongly steer people away from this if they don't know what they are doing/don't really need it. But it's just an idea, feel free to ignore."
  },
  {
   "t": "2026-04-19T19:54:01Z",
   "kind": "review_comment",
   "who": "fjahr",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "7c6b70d728676ea2509a0aba6c67184eac958fa4",
   "in_reply_to": null,
   "text": "Seems like this filtering could already be done in the `resolved` loop above so that the addr doesn't even end up here?"
  },
  {
   "t": "2026-04-19T19:54:48Z",
   "kind": "review_comment",
   "who": "fjahr",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "7c6b70d728676ea2509a0aba6c67184eac958fa4",
   "in_reply_to": 3107414488,
   "text": "nit: In the commit message here: `s/mechainm/mechanism/`"
  },
  {
   "t": "2026-04-19T20:02:27Z",
   "kind": "review_comment",
   "who": "fjahr",
   "assoc": "MEMBER",
   "path": "test/functional/p2p_v2_encrypted.py",
   "commit": "7c6b70d728676ea2509a0aba6c67184eac958fa4",
   "in_reply_to": null,
   "text": "nit: In commit message `s/conneections/connections/`"
  },
  {
   "t": "2026-04-19T20:36:09Z",
   "kind": "review",
   "who": "fjahr",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "1e61206583d87ff0bc0fd7e245cefce4203b423f",
   "text": "[quoted text omitted]\n\nRe-reading the code and @mzumsande's argument, I think I am now slightly leaning towards not tying it to `listen=0` but rather only disallowing v1 connections. But I would still be fine with the current approach as well, especially if we can find a bit better wording."
  },
  {
   "t": "2026-04-20T08:53:03Z",
   "kind": "review_comment",
   "who": "vasild",
   "assoc": "MEMBER",
   "path": "src/init.cpp",
   "commit": "263c16b537e1073a45e829bb98506db3ef662698",
   "in_reply_to": 3107403404,
   "text": "[quoted text omitted]\n\nIf you are at such a risk, then `-v2onlyclearnet=1` will not help. Mentioning \"passive\" is good because `-v2onlyclearnet=1` protects only against \"passive\" observers and not against \"active\" ones who can MITM themselves and spy on the encrypted traffic. Then the user has no way to ensure that a possible adversary will stay \"passive\" and will not switch to \"active\" at any moment."
  },
  {
   "t": "2026-04-29T08:49:28Z",
   "kind": "force_push",
   "who": "stratospher",
   "commit": "263c16b537e1073a45e829bb98506db3ef662698"
  },
  {
   "t": "2026-04-29T08:51:10Z",
   "kind": "review_comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "path": "src/init.cpp",
   "commit": "1e61206583d87ff0bc0fd7e245cefce4203b423f",
   "in_reply_to": 3107394295,
   "text": "oh whoops, thank you for the great catch!\n\nmaybe also makes sense to keep the error message short + keep the context only in the help text - it also prevents duplication. I've changed the error message to : `\"Cannot set -v2onlyclearnet=1 with listen=1. See -help for details on -v2onlyclearnet.\"` open to better wordings/suggestions as well or if people feel we should give slightly more context."
  },
  {
   "t": "2026-04-29T08:52:16Z",
   "kind": "review_comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "7c6b70d728676ea2509a0aba6c67184eac958fa4",
   "in_reply_to": 3107414488,
   "text": "I like the idea but the resolved for loop only resolves a hostname to the possible IP addresses (ex: `thisnode.com` to `ipaddress1`, and maybe a backup `ipaddress2`). if we do move the check up, we'd also need to add it in 3 spots whenever we do `connect_to.push_back`. so haven't changed it."
  },
  {
   "t": "2026-04-29T17:35:36Z",
   "kind": "comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "text": "thank you for the great catch @fjahr! I've addressed your comments in [this push](https://github.com/bitcoin/bitcoin/compare/1e61206583d87ff0bc0fd7e245cefce4203b423f..263c16b537e1073a45e829bb98506db3ef662698). I've made the InitError message shorter but kept the help text as it is.\n\nalso summarising my understanding of the 2 implementation options possible for `v2onlyclearnet` in case it's helpful to reviewers:\n\npurpose is assurance that passive observers can't see your encrypted traffic content (it doesn't hides the fact that you're running a Bitcoin node nor protect you from active adversaries)\n\n|                          | Option A: outbound v2 only + no inbound connections (current PR) | Option B: outbound + inbound v2 only connection |\n|--------------------------|------------------------------------------------------------------|------------------------------------------------|\n| **Flag interaction**     | there's a flag interaction `-v2onlyclearnet=1` requires `-listen=0`   | no flag interaction                            |\n| **Outbound IPv4/IPv6**   | v2 only                                                 | v2 only                               |\n| **Outbound Tor/I2P/CJDNS** | v1 and v2 (those networks encrypt anyway)            | v1 and v2 (those networks encrypt anyway) |\n| **Inbound IPv4/IPv6**    | none accepted since `-listen=0`                                     | v2 only accepted                               |\n| **Inbound Tor/I2P/CJDNS** | no Tor/CJDNS inbound but I2P inbounds possible when overriding default with `-i2pacceptincoming` since it doesn't use a listening socket     | v1 and v2 accepted (those networks encrypt anyway) |\n| **Advantage**            | no v1-only eclipse risk                                          | preserves listening capacity on the network    |\n|                          |  Requiring -v2onlyclearnet=1 with -listen=0 would be a more private way of running a clearnet node since we also enforce no (maybe spy) node being able to connect to us |  (in option B, it is upto the user to configure whether they want inbounds or not)                                             |\n|                          | avoids easy detection that you're running a bitcoin node by stateless packet connection. (traffic analysis which is more effort will give you away)  | (in option B, listening nodes still advertise their IP on the network and is easier to discover compared to traffic analysis. traffic analysis which is more effort will give you away here as well.)|\n| **Disadvantage (hypothetical scenario when most of network switch on the option)** | total listening capacity on the network shrinks | risk of eclipsing legacy v1-only nodes. if many nodes accept only v2 inbound, an attacker can cheaply spin up many v1-accepting nodes and dominate the v1 node's peer set. |\n\nwhich implementation option is better?\n1. hypothetical worst case scenario - option B wins here but don't think we should base our decision entirely on this. Let's say some day far in the future if there are <50 v1 nodes and a large fraction of the network turn on `v2onlyclearnet`\n- the network not having enough listening capacity since `-v2onlyclearnet` also forces `-listen=0` (option A) is more dangerous than a v1 node not being able to connect to a v2 node and being eclipsed (option B).\n- chance of the hypothetical worst case scenario where most of the network turns on this flag is also unlikely. so don't think we should base our decision entirely on this. we already have a long list of opt-in flags that would be bad if huge fraction of network enabled them.\n2. user configurability - option A (or) B can win here\n\t- (option A) if user expects more to come along with the option - since passive adversaries can't read the message contents now - they might also expect passive adversary to not able to statelessly connect to them and detect their node.\n\t- (option B) if user likes to configure things themselves.\n3. option A wins here - there will be 1 extra condition in version message processing logic in net_processing for option B. we let them connect and while processing version message discover it's V1 and then disconnect. don't think it's important but just noting it here.\n4. option B wins here - more elegant in the sense that this option will naturally phase out and we can remove it in the far future when everyone is in v2 :)\n5. option A wins here - we don't want passive adversary statelessly connecting and detecting node.\n\nI personally am ok with both. Maybe slight inclination to B since it gives the user configuration knob to do what they want. And we could document it in the help text to mention using listen=0 as well. Not sure what others prefer though.\n\nWould love thoughts on what people prefer before changing approach/pushing an update :)"
  },
  {
   "t": "2026-05-10T21:02:35Z",
   "kind": "comment",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nCan you elaborate on how v2 without inbounds makes traffic analysis more difficult than v2 with inbounds? I'm not a traffic analysis expert, and to me it would make sense that any analysis happening on 10 v2 connections vs 125 v2 connections would come to the same conclusion about whether or not you were running a bitcoin node? I'm fairly sure I'm missing something though... :)\n\nBut otherwise I would lean towards requiring `listen=0`, since it would make node runners who were interested in providing inbound connections hesitate to turn this option on. Without requiring that, it seems too easy for everyone to just turn it on without considering existing v1 nodes."
  },
  {
   "t": "2026-05-11T15:05:21Z",
   "kind": "review_comment",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "path": "src/netbase.h",
   "commit": "7c6b70d728676ea2509a0aba6c67184eac958fa4",
   "in_reply_to": null,
   "text": "nit: A Doxygen comment can be added.\n\n```suggestion\n/** Returns true if the network is IPv4 or IPv6 (as opposed to a privacy network like Tor/I2P/CJDNS). */\nbool IsClearnet(enum Network net);\n```"
  },
  {
   "t": "2026-05-11T15:06:25Z",
   "kind": "review_comment",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "path": "src/net.h",
   "commit": "263c16b537e1073a45e829bb98506db3ef662698",
   "in_reply_to": null,
   "text": "nit:\n\n```suggestion\nstatic constexpr bool DEFAULT_V2_ONLY_CLEARNET{false};\n```"
  },
  {
   "t": "2026-05-11T15:07:52Z",
   "kind": "review_comment",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "path": "src/net.h",
   "commit": "263c16b537e1073a45e829bb98506db3ef662698",
   "in_reply_to": null,
   "text": "If code ever reads `m_v2only_clearnet` before `Init()` is called, it's UB.\n\n```suggestion\n    bool m_v2only_clearnet{false};\n```"
  },
  {
   "t": "2026-05-11T15:10:27Z",
   "kind": "review_comment",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "path": "src/init.cpp",
   "commit": "263c16b537e1073a45e829bb98506db3ef662698",
   "in_reply_to": null,
   "text": "```suggestion\n    argsman.AddArg(\"-v2onlyclearnet\", strprintf(\"Ensure all outbound IPv4/IPv6 peers use encrypted network traffic (default: %u). Using this option requires -listen=0 and takes valuable listening capacity away from the network. Enable this option only if passive network observers like ISPs, firewalls, etc. pose a threat and unencrypted network traffic must be avoided. Note: Encryption protects message contents but does not obscure that you are running a Bitcoin node. Peers can still connect to you, observers can still identify Bitcoin activity from your outbound connection attempts to the default port (8333) or by analysing traffic patterns.\", DEFAULT_V2_ONLY_CLEARNET), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);\n```"
  },
  {
   "t": "2026-05-11T15:34:33Z",
   "kind": "review_comment",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "path": "src/net.cpp",
   "commit": "263c16b537e1073a45e829bb98506db3ef662698",
   "in_reply_to": null,
   "text": "If a user enables this option and wonders why connections to certain peers aren't happening, there's nothing in the debug log to explain it.\n\n```suggestion\n        if (RequiresV2ForOutbound(target_addr) && !use_v2transport) {\n            LogDebug(BCLog::NET, \"skipping v1 connection to %s (-v2onlyclearnet)\\n\", target_addr.ToStringAddrPort());\n```"
  },
  {
   "t": "2026-05-11T21:06:24Z",
   "kind": "review_comment",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "path": "src/net.cpp",
   "commit": "263c16b537e1073a45e829bb98506db3ef662698",
   "in_reply_to": null,
   "text": "When `pszDest` is unresolved because DNS is delegated to a name proxy, it might be better to treat it as possibly IPv4/IPv6 and block v1 under `-v2onlyclearnet`.\n\n```suggestion\n        const bool possibly_clearnet_name{pszDest && !target_addr.IsValid()};\n        if ((RequiresV2ForOutbound(target_addr) ||\n             (m_v2only_clearnet && possibly_clearnet_name)) &&\n            !use_v2transport) {\n```\n\nP.S.: Same logic can be applied to `DisconnectNodes()`.\n\n```diff\n                 // and we don't want to hold up the socket handler thread for that long.\n-                if (network_active && !RequiresV2ForOutbound(pnode->addr) && pnode->m_transport->ShouldReconnectV1()) {\n+                const bool possibly_clearnet_name{\n+                    m_v2only_clearnet && !pnode->addr.IsValid() && !pnode->m_dest.empty()};\n+                if (network_active && !RequiresV2ForOutbound(pnode->addr) &&\n+                    !possibly_clearnet_name && pnode->m_transport->ShouldReconnectV1()) {\n                     reconnections_to_add.push_back({\n                         .addr_connect = pnode->addr,\n```"
  },
  {
   "t": "2026-05-11T22:43:14Z",
   "kind": "comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nI think there are two issues if you don't want to be discovered that you are running a node and have `listen=1` set:\n\n1. There are messages being passed around (on v1 connections for as long as there are v1 connections) with your address written on it that say \"This address is a bitcoin node!\".\n2. Any hostile network can probe that you are running a node by attempting to v2 handshake you, and honestly this is not a large escalation in threat model, this is a widely deployed technique by many passive observers. (https://dl.acm.org/doi/epdf/10.1145/2815675.2815690)\n\nThat being said, I still lean toward option B, of not tying `-v2only` to `listen=0`, even though in many cases one wants both, there are also cases that may want one without the other (you don't care about being detected as a node but you want to make it harder for a passive observer to learn anything interesting from your bitcoin traffic). Maybe in the future it would be good to have a single flag that enables sane defaults for privacy or some privacy document describing the shortcomings and tradeoffs of the available options.\n\nI am Concept +0 leaning towards Concept ACK on this, I agree that given all of the other privacy issues that exist in both Bitcoin P2P and Bitcoin Core's implementation there won't be a step change in privacy from doing this; but I am very skeptical of this species of argument since the same arguments are used circularly to persist the other practices that degrade privacy persist, e.g. port 8333 (why change the port if we are detectable anyways via v1 connections?) Yes there are other problems, and they ought to be addressed, but raising the cost seems a good direction.\n\nThe only concern I feel hasn't been clearly addressed is the depletion of inbound v1 slots on the network; but maybe this isn't an issue needing discussing yet since so few will run with this option enabled."
  },
  {
   "t": "2026-05-27T09:55:13Z",
   "kind": "force_push",
   "who": "stratospher",
   "commit": "b559f2fdb1adf6bddc467751d6da1fc8e02b78ee"
  },
  {
   "t": "2026-05-27T12:40:53Z",
   "kind": "comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "text": "pushed an [update](https://github.com/bitcoin/bitcoin/compare/263c16b537e1073a45e829bb98506db3ef662698..b559f2fdb1adf6bddc467751d6da1fc8e02b78ee ) addressing @w0xlt's comments. thanks @w0xlt  for the great catches! And thanks @andrewtoth and @davidgumberg  for sharing your opinions!\n\nThe PR still implements [option A](https://github.com/bitcoin/bitcoin/pull/30951#issuecomment-4346061700) (node with `-v2onlyclearnet=1` option does outbound only connection)\n\n[quoted text omitted]\n@andrewtoth you're right that they're all the same from a traffic analyser PoV. I should reword/remove that sentence. what I meant was - if we couple `-v2onlyclearnet=1` with `-listen=0`, we can get both:\n1. protection against passive observer who can see plaintext traffic.\n2. some protection against active adversary/probers who can connect to you and see and analyse your traffic\n\nIt was an assumption that users who care about (1) might often care about (2). Requiring `-v2onlyclearnet=1` with `-listen=0` would be a more private way of running a clearnet node.\n\nThough I personally prefer letting operators choose what they want to run: (1) becomes the responsibility of `-v2onlyclearnet`, (2) becomes the responsibility of `-listen`.\n\n[quoted text omitted]\n@davidgumberg I do think it is important as well since this is the main blocker concern for doing option B. Also not sure how to reason about it since it's hypothetical. It is very unlikely that all v2 listening nodes turn on `-v2onlyclearnet`. And yes in case majority of the v2 nodes turn on this option - v1 nodes won't find nodes to connect to and are at a risk. But how realistic is it that everyone turns on this option. It worked for `onlynet` and `listen` in the past though that doesn't necessarily guarantee it will work for us now.\n\n[quoted text omitted]\nRight. Good point about the hesitation. I could imagine operators turning this on to prevent the v1 node data crawlers/probers that exist today and leach on the inbound slots. Once those crawlers/probers add v2 handshake support (which they should easily be able to nowadays), that motivation disappears as well.\n\nMaybe a warning might make the node operator reconsider if they really need it?\n\n```\n  if (args.GetBoolArg(\"-v2onlyclearnet\", DEFAULT_V2_ONLY_CLEARNET) &&\n      args.GetBoolArg(\"-listen\", DEFAULT_LISTEN)) {\n      InitWarning(_(\"-v2onlyclearnet=1 is set with listening enabled: v1 inbound \"\n                    \"connections on IPv4/IPv6 will be rejected. If many nodes adopt \"\n                    \"this configuration, older v1-only nodes may struggle to find \"\n                    \"inbound peers. Do you really need it?\"));\n  }\n```"
  },
  {
   "t": "2026-05-27T12:42:33Z",
   "kind": "review_comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "263c16b537e1073a45e829bb98506db3ef662698",
   "in_reply_to": 3222147684,
   "text": "oh nice edge case! I've taken both your suggestions and placed it inside `RequiresV2ForOutbound`"
  },
  {
   "t": "2026-05-31T17:11:18Z",
   "kind": "comment",
   "who": "naiyoma",
   "assoc": "MEMBER",
   "text": "this is  a good improvement. While it doesn\u2019t fully solve the traffic analysis issue, making it harder is still a positive in my view.\nI also like that we\u2019re explicitly communicating that it\u2019s still possible for an observer to tell when someone is running a node .\nI\u2019m leaning toward option A here, mainly because it feels like the safest option.\nBut I  a bit hesitant about the tradeoff. I think it\u2019s better to think about this under the assumption that most nodes will adopt this option. In that case, an eclipse attack on v1 seems like a much worse outcome than the impact of listening traffic shrinking."
  },
  {
   "t": "2026-05-31T17:26:51Z",
   "kind": "review_comment",
   "who": "naiyoma",
   "assoc": "MEMBER",
   "path": "src/net.h",
   "commit": "b559f2fdb1adf6bddc467751d6da1fc8e02b78ee",
   "in_reply_to": null,
   "text": "micro nit: in 760354a0397859430bed2f861289de6f591aafab\n``` diff\n-    bool m_v2only_clearnet{false};\n+    bool m_v2only_clearnet{DEFAULT_V2_ONLY_CLEARNET};\n```"
  },
  {
   "t": "2026-06-26T16:07:15Z",
   "kind": "review_comment",
   "who": "danielabrozzoni",
   "assoc": "MEMBER",
   "path": "src/netbase.h",
   "commit": "7c6b70d728676ea2509a0aba6c67184eac958fa4",
   "in_reply_to": null,
   "text": "nit: In 0f32139ea080074f4d73b0e63747bae0fa8c74b3 (comment in a random place):\nI think you should also use `IsClearnet` in:\n- https://github.com/bitcoin/bitcoin/blob/ea9afb61a1c52979d0e64e4dae9b3a611f7b9a5e/src/net.cpp#L3149\n- https://github.com/bitcoin/bitcoin/blob/ea9afb61a1c52979d0e64e4dae9b3a611f7b9a5e/src/init.cpp#L865"
  },
  {
   "t": "2026-06-29T13:08:16Z",
   "kind": "review_comment",
   "who": "danielabrozzoni",
   "assoc": "MEMBER",
   "path": "test/functional/p2p_v2_encrypted.py",
   "commit": "b559f2fdb1adf6bddc467751d6da1fc8e02b78ee",
   "in_reply_to": null,
   "text": "nit (here and below): can you pass `v2transport=` explicitly?\nI found it a bit hard to see where the test was selecting v1 vs v2 transport :)\n\n```diff\ndiff --git a/test/functional/p2p_v2_encrypted.py b/test/functional/p2p_v2_encrypted.py\nindex e2acaf71a0..03e12e306a 100755\n--- a/test/functional/p2p_v2_encrypted.py\n+++ b/test/functional/p2p_v2_encrypted.py\n@@ -142,11 +142,15 @@ class P2PEncrypted(BitcoinTestFramework):\n         self.restart_node(0, extra_args=args)\n         self.log.info(\"Test -v2onlyclearnet=1 behaviour\")\n         self.log.info(\"Check that outbound v2 connection to an ipv4 peer is successful\")\n-        node0.addnode(\"15.61.23.23:1234\", \"onetry\", True)\n+        node0.addnode(\"15.61.23.23:1234\", \"onetry\", v2transport=True)\n         assert_equal(node0.getpeerinfo()[-1][\"addr\"], \"15.61.23.23:1234\")\n         self.log.info(\"Check that outbound v1 connection to an ipv4 peer is unsuccessful\")\n         with node0.assert_debug_log(expected_msgs=[\"skipping v1 connection to 8.8.8.8:1234\"]):\n-            node0.addnode(\"8.8.8.8:1234\", \"onetry\", False)\n+            node0.addnode(\"8.8.8.8:1234\", \"onetry\", v2transport=False)\n```"
  },
  {
   "t": "2026-06-29T13:57:43Z",
   "kind": "review",
   "who": "danielabrozzoni",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "b559f2fdb1adf6bddc467751d6da1fc8e02b78ee",
   "text": "Concept ACK!\n\nRegarding whether to allow incoming connections, I\u2019m slightly leaning towards disallowing them.\n(Thanks for the summary table @stratospher, it's very useful!)\n\nIn the hypothetical worst-case scenario, option A would be worse because the network might not have enough inbound capacity. However I agree with @andrewtoth:\n\n[quoted text omitted]\nFor this reason, I think disallowing incoming connections is better, as it lowers the chance of the worst-case scenario.\n\n---\n\nI have a question: throughout this thread, we talk about how with `-v2onlyclearnet` a passive observer can't identify a Bitcoin node by looking for network magic bytes in the traffic - although there's other relatively easy ways to spot one, such as looking for connections from/to port 8333.\n\nIf we implemented option B, would this still hold? I imagine the implementation would be: if a node connects to us using v1, we close the connection. I think that would mean that a passive observer could still observe the network magic. Does this make sense?\n\n---\n\nI also have some implementation questions.\n\nFirst of all, I'm wondering if we should disallow incoming, or disallow incoming *on clearnet* - since these are the connections that are unencrypted. (I'm not sure this can be easily done with the current startup flags)\n\nI think we currently disallow incoming Tor connections because `-listen=0` sets `-listenonion=0`, but incoming I2P connections are still allowed if explicitly requested. This works:\n\n```diff\ndiff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py\nindex bdb5c5293e..8e1478e868 100755\n--- a/test/functional/feature_config_args.py\n+++ b/test/functional/feature_config_args.py\n@@ -442,6 +442,15 @@ class ConfArgsTest(BitcoinTestFramework):\n         self.nodes[0].assert_start_raises_init_error(\n             extra_args=['-v2onlyclearnet=1', '-v2transport=1', '-listen=1'],\n             expected_msg='Error: Cannot set -v2onlyclearnet=1 with listen=1. See -help for details on -v2onlyclearnet.')\n+        args = [\n+            \"-v2onlyclearnet=1\",\n+            \"-v2transport=1\",\n+            \"-listen=0\",\n+            \"-i2psam=127.0.0.1:3333\",\n+            \"-nobind\",\n+            \"-i2pacceptincoming=1\",\n+        ]\n+        self.restart_node(0, extra_args=args)\n\n```\n\nAlso, we currently allow v1 connections to not publicly routable addresses, so you can addnode to a local network address, and connect to it through v1. Is this okay? I guess it doesn't pose a privacy concern in most cases, but maybe it makes sense to fix for consistency? This currently works:\n\n```diff\ndiff --git a/test/functional/p2p_v2_encrypted.py b/test/functional/p2p_v2_encrypted.py\nindex e2acaf71a0..880ec70972 100755\n--- a/test/functional/p2p_v2_encrypted.py\n+++ b/test/functional/p2p_v2_encrypted.py\n@@ -147,6 +147,8 @@ class P2PEncrypted(BitcoinTestFramework):\n         self.log.info(\"Check that outbound v1 connection to an ipv4 peer is unsuccessful\")\n         with node0.assert_debug_log(expected_msgs=[\"skipping v1 connection to 8.8.8.8:1234\"]):\n             node0.addnode(\"8.8.8.8:1234\", \"onetry\", False)\n+        with node0.assert_debug_log(expected_msgs=[], unexpected_msgs=[\"skipping v1 connection to 192.168.0.1:1234\"]):\n+            node0.addnode(\"192.168.0.1:1234\", \"onetry\", v2transport=False)\n         assert all(peer[\"addr\"] != \"8.8.8.8:1234\" for peer in node0.getpeerinfo())\n         self.log.info(\"Check that outbound v1 connection to an onion peer is successful\")\n         addr = \"pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion:8333\"\n```\n\n(You can see in logs that it doesn't really connect to 192.168.0.1, but it attemps the connection despite being v1)"
  },
  {
   "t": "2026-07-02T18:45:44Z",
   "kind": "force_push",
   "who": "stratospher",
   "commit": "d72df0fc8369efc391e3f777e1b9fb20a223beb3"
  },
  {
   "t": "2026-07-02T18:46:50Z",
   "kind": "review_comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "path": "src/net.h",
   "commit": "b559f2fdb1adf6bddc467751d6da1fc8e02b78ee",
   "in_reply_to": 3330633985,
   "text": "done. thanks!"
  },
  {
   "t": "2026-07-02T18:57:11Z",
   "kind": "comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "text": "thank you for the thorough review @danielabrozzoni! I've addressed your review comments in [this push](https://github.com/bitcoin/bitcoin/compare/b559f2fdb1adf6bddc467751d6da1fc8e02b78ee..d72df0fc8369efc391e3f777e1b9fb20a223beb3) and added a [commit](https://github.com/bitcoin/bitcoin/pull/30951/changes/d72df0fc8369efc391e3f777e1b9fb20a223beb3) for release notes.\n\n[quoted text omitted]\nyes if we allow inbound - they'd see the network magic and a few more bytes of the first message before we drop the connection. rest of the v2 network traffic (if not dropped) would be encrypted.\n\n[quoted text omitted]\nooh good find! I've corrected the [summary table](https://github.com/bitcoin/bitcoin/pull/30951#issuecomment-4346061700).\n\nideally we'd drop only the unencrypted (clearnet) inbounds and keep the Tor/I2P/CJDNS ones, since those are already encrypted. I think it will be awkward to implement though - I2P unlike the others doesn't use a listening socket which is why we can override it.\n\nthere is a soft-set in the init.cpp where `-listen=0` -> `-listenonion=0` and `-i2pacceptincoming=0`. I feel it's ok if the node operator really wants to override it to allow i2p inbound since the option's guarantees still hold and there's no privacy leak. Maybe we should just document this behaviour somewhere? I tried putting it in the release notes but felt it read too confusing for end users.\n\n[quoted text omitted]\ngood point. I think it's fine to leave as is - I've added a comment in `RequiresV2ForOutbound` rather than forcing v2 for LAN."
  },
  {
   "t": "2026-07-21T14:20:08Z",
   "kind": "comment",
   "who": "gmaxwell",
   "assoc": "CONTRIBUTOR",
   "text": "An incremental option to address partitioning concerns is to only allow inbound v1 connections that are fRelay=false.  While this doesn't achieve all the benefits of v2only, including lowering the visibility of plaintext traffic (including potential plaintext malware that trips up network scanning software), many concerns favoring v2 are related specifically to transaction relay.  As an added bonus the dnsseed indexing run today doesn't use v2, but it does connect with fRelay=false.\n\nI cannot express how strongly I disagree with forcing listen=0.  It is is an outright anti-feature to unnecessarily tie a security/privacy setting to providing resources to others-- it's analogous to saying that anyone running a limited node (prune>0) must be listen=0 or anyone not offering blockfilters must be listen=0.\n\nThere is no serious risk of abandoning older node through an off-by-default configuration setting. And failing to provide network capacity means that there are less sockets available for v2 connections which means other people's connections will use up v1 accommodating sockets that would otherwise be available-- so that move would have precisely opposite the intended effect purely by lowering the total number of sockets available in the network.  (To whatever extent a manually configured option will have any effect at all).\n\nIt isn't like users get paid or something for accepting listening connections as some incentive to accept connections from older peers, -- and to whatever extent users are hurt by not listening  (e.g. by getting a reduced txn relay anonymity set) then that is an argument to not have the restriction.   Moreover, in terms of transaction privacy privacy against a global passive observer is greatly improved to the extent that a users broadcast crosses more of the network through peers without attacker observed connections (so encryption is a pre-req), but v2only nodes can hardly contribute in this way if they don't accept connections.  I might go so far as to say that a v2 only listen=0 peer is pretty pointless, might as well just run a non-listening node that connects out exclusively through tor and forget about the v1/v2 distinction.\n\nThe question of leaving v1 out in the cold would be very material if considering making this a default option, but that isn't under discussion.  That said, Satoshi had no problem changing the p2p protocol in a way that was only backwards compatible for two years.  I don't see any great reason to run into disabling v1 by default today, but there may be one in the future (such as the further spread of network based anti-malware that can by triggered by traffic in the p2p connection). If there were it would be important that the existing v2 only nodes weren't listen=0.\n\nA separate issue that I don't see discussed or addressed in the commits:  Addresses learned via dnsseed right now as well as the static addr databases don't have the v2 flag.  And so a node that has v2 as a requirement for its peer selection won't find any peers at all from a cold start and will just sit connected to nothing. I think to address that, the seeds database should just be filtered to v2 peers (as there are plenty and already outdated peers get excluded) and treated as v2 in addrman,  and similar dnsseeds should provide a name to filter on that service bit as was done for NODE_WITNESS."
  },
  {
   "t": "2026-07-21T15:31:39Z",
   "kind": "comment",
   "who": "mzumsande",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nFWIW, I also still prefer not doing that, https://github.com/bitcoin/bitcoin/pull/30951#pullrequestreview-3429992454\n\n[quoted text omitted]\nGood point, but maybe it's not strictly necessary to change the dns seeds, we could also just switch the default to v2 for all results from dns seeds and fixed seeds - if it happens to be wrong, a regular node would just downgrade to v1. And given that most nodes support v2 by now, it's very unlikely that a v2-only node would only receive v1 peers from dns seeds."
  },
  {
   "t": "2026-07-21T15:45:05Z",
   "kind": "comment",
   "who": "gmaxwell",
   "assoc": "CONTRIBUTOR",
   "text": "Oh good point on the seeds. I agree, that's tidy enough."
  },
  {
   "t": "2026-07-21T17:01:58Z",
   "kind": "comment",
   "who": "mzumsande",
   "assoc": "MEMBER",
   "text": "proposed in #35766, I think it makes sense to change regardless of this PR."
  },
  {
   "t": "2026-07-24T08:46:21Z",
   "kind": "comment",
   "who": "sedited",
   "assoc": "MEMBER",
   "text": "@stratospher can you rebase to get the changes from #35766 in here?"
  },
  {
   "t": "2026-08-13T10:14:17Z",
   "kind": "force_push",
   "who": "stratospher",
   "commit": "7c6b70d728676ea2509a0aba6c67184eac958fa4"
  },
  {
   "t": "2026-08-13T10:20:33Z",
   "kind": "comment",
   "who": "stratospher",
   "assoc": "MEMBER",
   "text": "(just a rebase. will address the comments here soon!)"
  },
  {
   "t": "2026-08-18T13:24:48Z",
   "kind": "comment",
   "who": "fanquake",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\n@stratospher note that this needs rebase again, and feature freeze is in 2 days (this is tagged for v32.0)."
  },
  {
   "t": "2026-08-18T15:25:19Z",
   "kind": "comment",
   "who": "mzumsande",
   "assoc": "MEMBER",
   "text": "looks to me that there is no agreement among reviewers about coupling it to `listen=0`, so unless that changes very quickly, maybe we have to postpone for v33?"
  },
  {
   "t": "2026-08-18T15:47:05Z",
   "kind": "comment",
   "who": "sedited",
   "assoc": "MEMBER",
   "text": "Yes, postponing this."
  },
  {
   "t": "2026-09-10T19:45:58Z",
   "kind": "review",
   "who": "ViniciusCestarii",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "7c6b70d728676ea2509a0aba6c67184eac958fa4",
   "text": "Concept ACK, though I'd prefer option B.\n\nOn the option A hesitation point: I doubt anyone who has decided they want this reconsiders when bitcoind refuses to start. They'll set `listen=0` and carry on. The operator it actually pushes away is the one who wanted to keep serving inbound.\n\nI also don't think requiring `listen=0` actually helps v1 nodes. The number of v1-accepting peers shrinks the same either way, since under both options the node stops accepting v1 inbound on IPv4/IPv6. All A adds is dropping the v2 inbound capacity too, and as gmaxwell pointed out, that just pushes v2 connections onto the v1 and v2 accepting nodes that v1-only nodes are relying on.\n\nThe only real difference I could think of is that under B this node still advertises itself, so a v1-only node may spend an outbound attempt on it and get dropped. That cost seems small to me: the failed attempt is recorded and gets deprioritized for later selection, and with an off-by-default option the number of such peers stays low. Under A the same node contributes no inbound capacity at all, which seems worse.\n\nAs mzumsande noted, it would also be an odd coupling to add. `prune`, `blocksonly`, `maxconnections` and `onlynet` all reduce what you contribute and none of them is refused or discouraged for it. Option A would reject a combination of flags that works, simply because we think the operator should configure it differently to keep contributing to the network.\n\nIf someone doesn't want inbounds they can set `listen=0` themselves."
  }
 ],
 "labels_log": [
  {
   "t": "2024-09-23T12:23:53Z",
   "action": "labeled",
   "label": "P2P",
   "who": "DrahtBot"
  },
  {
   "t": "2024-09-23T12:32:06Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2024-09-24T08:22:15Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2024-09-29T07:32:55Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2024-09-29T10:51:47Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2024-10-09T02:17:43Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2024-10-28T06:09:14Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2025-03-24T22:39:34Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2025-03-28T07:27:55Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2025-07-03T06:22:49Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2025-07-03T08:49:49Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2025-12-12T10:59:04Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2025-12-12T15:39:30Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-03-26T19:57:40Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-04-08T19:02:00Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-04-08T19:08:08Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-04-09T03:01:45Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-14T17:55:20Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  }
 ],
 "state_log": [
  {
   "t": "2026-03-11T14:49:05Z",
   "kind": "milestoned",
   "who": "sedited"
  },
  {
   "t": "2026-08-18T15:47:35Z",
   "kind": "demilestoned",
   "who": "sedited"
  },
  {
   "t": "2026-08-18T15:47:36Z",
   "kind": "milestoned",
   "who": "sedited"
  }
 ],
 "text_chars": 54775,
 "text_tokens_estimate": 13693,
 "changed_paths": [
  "doc/release-notes-30951.md",
  "src/common/netif.cpp",
  "src/init.cpp",
  "src/net.cpp",
  "src/net.h",
  "src/netbase.cpp",
  "src/netbase.h",
  "test/functional/feature_config_args.py",
  "test/functional/p2p_v2_encrypted.py"
 ],
 "files": [
  {
   "path": "doc/release-notes-30951.md",
   "add": 11,
   "del": 0
  },
  {
   "path": "src/common/netif.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/init.cpp",
   "add": 11,
   "del": 1
  },
  {
   "path": "src/net.cpp",
   "add": 13,
   "del": 2
  },
  {
   "path": "src/net.h",
   "add": 29,
   "del": 0
  },
  {
   "path": "src/netbase.cpp",
   "add": 2,
   "del": 0
  },
  {
   "path": "src/netbase.h",
   "add": 2,
   "del": 0
  },
  {
   "path": "test/functional/feature_config_args.py",
   "add": 10,
   "del": 0
  },
  {
   "path": "test/functional/p2p_v2_encrypted.py",
   "add": 25,
   "del": 0
  }
 ],
 "test_lines": 35,
 "git": {
  "head": "7c6b70d728676ea2509a0aba6c67184eac958fa4",
  "head_matches_backup": true,
  "base": "b2c45888fde06429e86913fab5e7b7a075f091c3",
  "commits": [
   {
    "sha": "cc6c15a85a",
    "subject": "net: add helper to identify clearnet networks",
    "files": 5,
    "add": 7,
    "del": 3
   },
   {
    "sha": "8b5e2ee692",
    "subject": "net: add option in CConman to allow only v2 clearnet connections",
    "files": 2,
    "add": 36,
    "del": 0
   },
   {
    "sha": "5974d948ff",
    "subject": "init: add -v2onlyclearnet config option",
    "files": 1,
    "add": 10,
    "del": 0
   },
   {
    "sha": "517ae255f9",
    "subject": "net: disable v1 connections, reconnections on clearnet",
    "files": 1,
    "add": 5,
    "del": 1
   },
   {
    "sha": "777683143f",
    "subject": "test: Check that v1 connections to clearnet peers don't work",
    "files": 2,
    "add": 35,
    "del": 0
   },
   {
    "sha": "7c6b70d728",
    "subject": "doc: add release notes for v2onlyclearnet option",
    "files": 1,
    "add": 11,
    "del": 0
   }
  ],
  "patch_truncated": false
 },
 "input_hash": "11892b81689f6f4c",
 "extracted_at": "2026-09-17T16:15:31+00:00"
}