{
 "number": 36330,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/36330",
 "title": "wallet: don't resubmit transactions under -privatebroadcast",
 "author": "instagibbs",
 "author_association": "MEMBER",
 "created_at": "2026-09-24T17:59:59Z",
 "updated_at": "2026-10-10T17:47:42Z",
 "description_hash": "b5a8be39379644a4",
 "age_days": 38,
 "draft": false,
 "labels": [
  "Wallet",
  "Private Broadcast"
 ],
 "milestone": null,
 "base": "master",
 "head_sha": "3544df277deb658f150ed44f4a5f758fd8ef42af",
 "head_ref": "wallet-privbcast-no-reannounce",
 "head_repo": "instagibbs/bitcoin",
 "head_history": [
  {
   "t": "2026-09-25T16:47:19Z",
   "sha": "704238cf4f110e5c900d1240769dc673e88c46d3"
  },
  {
   "t": "2026-09-28T14:59:16Z",
   "sha": "8c4e257f475a7d2c5faf7f127ed3c63e3d839297"
  },
  {
   "t": "2026-09-28T15:00:45Z",
   "sha": "6d5450244b5539a454aee3f88152ef7c78e27055"
  },
  {
   "t": "2026-09-29T13:12:37Z",
   "sha": "3544df277deb658f150ed44f4a5f758fd8ef42af"
  }
 ],
 "additions": 31,
 "deletions": 0,
 "changed_files": 3,
 "commit_count": 1,
 "size_bucket": "S",
 "mergeable_state": "clean",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "ack": [
     {
      "login": "davidgumberg",
      "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-6051853288"
     },
     {
      "login": "andrewtoth",
      "url": "https://github.com/bitcoin/bitcoin/pull/36330#pullrequestreview-5460797236"
     },
     {
      "login": "w0xlt",
      "url": "https://github.com/bitcoin/bitcoin/pull/36330#pullrequestreview-5463038618"
     }
    ],
    "concept_nack": [
     {
      "login": "vasild",
      "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-6074151790"
     },
     {
      "login": "polespinasa",
      "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-6084798078"
     }
    ],
    "concept_ack": [
     {
      "login": "darosior",
      "url": "https://github.com/bitcoin/bitcoin/pull/36330#pullrequestreview-5336431896"
     }
    ]
   },
   "conflicts": []
  }
 },
 "acks_parsed": {
  "w0xlt": {
   "kind": "ack",
   "hash": "3544df277deb658f150ed44f4a5f758fd8ef42af",
   "t": "2026-10-08T21:25:35Z",
   "stale": false
  },
  "andrewtoth": {
   "kind": "ack",
   "hash": "3544df277deb658f150ed44f4a5f758fd8ef42af",
   "t": "2026-10-08T17:55:00Z",
   "stale": false
  },
  "darosior": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-09-28T09:19:38Z",
   "stale": false
  },
  "davidgumberg": {
   "kind": "ack",
   "hash": "3544df277deb658f150ed44f4a5f758fd8ef42af",
   "t": "2026-10-08T03:55:57Z",
   "stale": false
  }
 },
 "acks_tally": {
  "ack": 3,
  "stale_ack": 0,
  "concept_ack": 1,
  "approach_ack": 0,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 2,
  "changes_requested": 0,
  "distinct_reviewers": [
   "achow101",
   "andrewtoth",
   "darosior",
   "davidgumberg",
   "fanquake",
   "mzumsande",
   "polespinasa",
   "vasild",
   "w0xlt"
  ]
 },
 "signals": {
  "needs_rebase": false,
  "ci_failed": false,
  "mergeable_state": "clean",
  "last_author_activity": "2026-10-09T12:47:23Z",
  "last_reviewer_activity": "2026-10-09T16:17:48Z",
  "last_reviewer": "polespinasa",
  "author_silent_days": 23,
  "waiting_on_author_days": 23,
  "days_since_update": 22
 },
 "refs": {
  "mentioned": [
   36403,
   36482
  ],
  "depends_on": [],
  "fixes": [],
  "linked_issues": [],
  "references": [
   {
    "number": 36403,
    "type": "issue",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "Rethinking Transaction Rebroadcasting"
   },
   {
    "number": 36482,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "wallet: Only broadcast resubmitted transactions that were added to the mempool"
   }
  ],
  "conflicts": []
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [
  "src/wallet/wallet.cpp",
  "test/functional/wallet_resendwallettransactions.py"
 ],
 "body": "This doesn't fix the general case of rebroadcasting potentially surprising users by divulging the originator IP trivially, but for users opting into private broadcast, it seems a bridge too far for them to expect the current behavior.\n\ne.g. an incoming dust payment triggering your node to rebroadcast 24-36th later over clearnet\n\nThis can be removed if/when wallet drives through private broadcast.\n\nsee https://github.com/bitcoin/bitcoin/issues/3828 for running broader issue",
 "commits": [
  {
   "sha": "3544df277deb658f150ed44f4a5f758fd8ef42af",
   "date": "2026-09-29T13:11:28Z",
   "message": "wallet: don't resubmit transactions to the mempool under -privatebroadcast\n\nThe wallet re-adds its unconfirmed transactions to the mempool periodically\nand whenever a wallet is loaded or its transactions are imported. A\ntransaction that the rest of the network has dropped is then held by this\nnode alone, and served to any peer that asks for it, which marks it as the\nnode's own. Not announcing the re-added transaction does not hide this: any\nrelay peer can fetch anything in the mempool once the next inv round has\npassed.\n\nWith -privatebroadcast, skip the resubmission entirely. Transactions sent\nthrough the wallet are still submitted and announced as before, since those\nnever went through private broadcast in the first place."
  }
 ],
 "timeline": [
  {
   "t": "2026-09-24T20:17:38Z",
   "kind": "review",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "b7ea5786968f8cf9a0fe82628f9627fd27ec048b",
   "text": "ACK b7ea5786968f8cf9a0fe82628f9627fd27ec048b",
   "id": "r:5309745790",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#pullrequestreview-5309745790",
   "hash": "aed9d9bced7471e9",
   "edited": null
  },
  {
   "t": "2026-09-24T20:18:50Z",
   "kind": "comment",
   "who": "fanquake",
   "assoc": "MEMBER",
   "text": "cc @andrewtoth @vasild",
   "id": "c:5821589727",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5821589727",
   "hash": "d29ddf4fe6c475a9",
   "edited": null
  },
  {
   "t": "2026-09-24T21:38:02Z",
   "kind": "comment",
   "who": "achow101",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nIs it? The current behavior is that all transactions being sent via the wallet do not use private broadcast at all; `CommitTransaction` uses `MEMPOOL_AND_BROADCAST_TO_ALL`, and it follows that resubmit behaves in the same way.\n\nSee also: https://github.com/bitcoin/bitcoin/pull/34533#issuecomment-3969991481",
   "id": "c:5822665076",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5822665076",
   "hash": "d4dea197ed25c142",
   "edited": "2026-09-24T21:39:13Z"
  },
  {
   "t": "2026-09-24T22:12:21Z",
   "kind": "comment",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nThis is true, but the case this change is protecting against is transactions sent by other means that also belong to the wallet.\n\nSo if a user is running with `-privatebroadcast` and is sending transactions via `sendrawtransaction`, if they have a watch only wallet or their addresses are dusted with low fee transactions, then the wallet will still rebroadcast these transactions. This could be unexpected if the user thinks they are protected by `-privatebroadcast`.",
   "id": "c:5823087651",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5823087651",
   "hash": "0332396356b88018",
   "edited": null
  },
  {
   "t": "2026-09-24T22:26:21Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/wallet/wallet.cpp",
   "commit": "b7ea5786968f8cf9a0fe82628f9627fd27ec048b",
   "in_reply_to": null,
   "text": "```suggestion\n    if (context.args->GetBoolArg(\"-privatebroadcast\", DEFAULT_PRIVATE_BROADCAST)) {\n        return;\n    }\n```\n\nIMO should return here without ever being resubmitted to the mempool since learning a peer's mempool is trivial for an active observer.\n\n@andrewtoth @vasild",
   "id": "rc:4099089685",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#discussion_r4099089685",
   "hash": "e8376db7ca6bbe92",
   "edited": null
  },
  {
   "t": "2026-09-25T14:44:14Z",
   "kind": "comment",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "text": "Is this intended for backport?\n\nI ask because if we were not going to backport, then we could instead fix this by having the wallet use private broadcast. But for a backport fix this would be sufficient for existing users, with the tradeoff of reducing reliability of wallet transactions confirming a little bit.",
   "id": "c:5834307893",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5834307893",
   "hash": "3c586abb3ab46e0e",
   "edited": "2026-09-25T15:46:22Z"
  },
  {
   "t": "2026-09-25T14:51:16Z",
   "kind": "review_comment",
   "who": "instagibbs",
   "assoc": "MEMBER",
   "path": "src/wallet/wallet.cpp",
   "commit": "b7ea5786968f8cf9a0fe82628f9627fd27ec048b",
   "in_reply_to": 4099089685,
   "text": "right, if it comes back, then is evicted from the mempool, we don't want to resubmit to the mempool. I think this is correct.",
   "id": "rc:4105713757",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#discussion_r4105713757",
   "hash": "b3c9ec65dea8a6bb",
   "edited": "2026-09-25T14:51:17Z"
  },
  {
   "t": "2026-09-25T16:47:19Z",
   "kind": "force_push",
   "who": "instagibbs",
   "commit": "704238cf4f110e5c900d1240769dc673e88c46d3",
   "id": "push:704238cf4f110e5c900d1240769dc673e88c46d3"
  },
  {
   "t": "2026-09-25T16:48:12Z",
   "kind": "review_comment",
   "who": "instagibbs",
   "assoc": "MEMBER",
   "path": "src/wallet/wallet.cpp",
   "commit": "b7ea5786968f8cf9a0fe82628f9627fd27ec048b",
   "in_reply_to": 4099089685,
   "text": "pushed an update so the wallet never resubmits when pb is set. Avoids restarts and loading wallets triggering it",
   "id": "rc:4106693516",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#discussion_r4106693516",
   "hash": "6f7fa13d178f8201",
   "edited": "2026-09-25T16:48:13Z"
  },
  {
   "t": "2026-09-25T16:52:57Z",
   "kind": "comment",
   "who": "instagibbs",
   "assoc": "MEMBER",
   "text": "@andrewtoth Given that wallet integration isn't close to done, I think we should remove footguns until we get there. This is easily reversed. I think backporting makes sense for the same reason.",
   "id": "c:5836147841",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5836147841",
   "hash": "26ff24fd4c86b883",
   "edited": null
  },
  {
   "t": "2026-09-27T15:14:36Z",
   "kind": "review_comment",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_resendwallettransactions.py",
   "commit": "8c4e257f475a7d2c5faf7f127ed3c63e3d839297",
   "in_reply_to": null,
   "text": "I think we can use `-persistmempool=0` here instead of `-mempoolexpiry=1` to make this more concise with identical coverage:\n\n```diff\n\ndiff --git a/test/functional/wallet_resendwallettransactions.py b/test/functional/wallet_resendwallettransactions.py\nindex 69760ad0d0..36715cd007 100755\n--- a/test/functional/wallet_resendwallettransactions.py\n+++ b/test/functional/wallet_resendwallettransactions.py\n@@ -159,35 +159,21 @@ class ResendWalletTransactionsTest(BitcoinTestFramework):\n\n         self.log.info(\"With -privatebroadcast, the wallet never re-adds a transaction to the mempool\")\n         node1.replace_in_config([(\"connect=0\\n\", \"\")])  # -privatebroadcast refuses -connect\n-        privbcast_args = [\"-privatebroadcast\", \"-onion=127.0.0.1:9\", \"-mempoolexpiry=1\"]  # the proxy is never used here\n+        privbcast_args = [\"-privatebroadcast\", \"-onion=127.0.0.1:9\", \"-persistmempool=0\"]  # the proxy is never used here\n         self.restart_node(1, extra_args=privbcast_args + [f\"-mocktime={node1.mocktime}\"])\n-        # Resending needs a recent tip (the restart put node1 back in IBD) and a block seen since startup\n-        block = create_block(int(node1.getbestblockhash(), 16), height=node1.getblockcount() + 1, ntime=node1.mocktime)\n-        block.solve()\n-        node1.submitblock(block.serialize().hex())\n-        node1.syncwithvalidationinterfacequeue()\n-        # Expire the transaction so that a resubmit would visibly re-add it\n-        node1.bumpmocktime(2 * 60 * 60)\n-        node1.sendtoaddress(node1.getnewaddress(), 1)\n         assert recv_txid not in node1.getrawmempool()\n\n         self.log.info(\"The periodic resend does not re-add it\")\n-        peer = node1.add_p2p_connection(P2PTxInvStore())\n-        with node1.assert_debug_log(expected_msgs=[], unexpected_msgs=['resubmit']):\n-            node1.bumpmocktime(RESEND_TIMER_LIMIT)\n-            node1.mockscheduler(60)\n-            node1.syncwithvalidationinterfacequeue()  # runs on the scheduler thread, after the resend\n-        assert recv_txid not in node1.getrawmempool()\n-        node1.bumpmocktime(10 * 60)  # past the peer's announcement timer\n-        peer.sync_with_ping()\n-        assert int(recv_wtxid, 16) not in peer.get_invs()\n-\n-        self.log.info(\"Loading the wallet does not re-add it either\")\n-        self.restart_node(1, extra_args=privbcast_args + [f\"-mocktime={node1.mocktime}\"])\n+        # Resending needs a recent tip (the restart put node1 back in IBD) and a block seen since startup\n+        self.generate(node1, 1, sync_fun=self.no_op)\n+        node1.syncwithvalidationinterfacequeue()\n+        node1.bumpmocktime(RESEND_TIMER_LIMIT)\n+        node1.mockscheduler(60)\n+        node1.syncwithvalidationinterfacequeue()\n         assert recv_txid not in node1.getrawmempool()\n\n         self.log.info(\"Without -privatebroadcast, loading the wallet re-adds it\")\n-        self.restart_node(1, extra_args=[\"-mempoolexpiry=1\", f\"-mocktime={node1.mocktime}\"])\n+        self.restart_node(1, extra_args=[\"-persistmempool=0\", f\"-mocktime={node1.mocktime}\"])\n         assert recv_txid in node1.getrawmempool()\n\n```",
   "id": "rc:4115855286",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#discussion_r4115855286",
   "hash": "c6e0f66cbdd221fd",
   "edited": "2026-09-27T15:21:32Z"
  },
  {
   "t": "2026-09-27T15:21:32Z",
   "kind": "review",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "state": "APPROVED",
   "commit": "8c4e257f475a7d2c5faf7f127ed3c63e3d839297",
   "text": "ACK 704238cf4f110e5c900d1240769dc673e88c46d3",
   "id": "r:5330841772",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#pullrequestreview-5330841772",
   "hash": "44fb7a3ff75789af",
   "edited": "2026-09-28T14:59:15Z"
  },
  {
   "t": "2026-09-28T09:19:38Z",
   "kind": "review",
   "who": "darosior",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "704238cf4f110e5c900d1240769dc673e88c46d3",
   "text": "Concept ACK.",
   "id": "r:5336431896",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#pullrequestreview-5336431896",
   "hash": "39bcd188b11b7a83",
   "edited": null
  },
  {
   "t": "2026-09-28T14:59:16Z",
   "kind": "force_push",
   "who": "instagibbs",
   "commit": "8c4e257f475a7d2c5faf7f127ed3c63e3d839297",
   "id": "push:8c4e257f475a7d2c5faf7f127ed3c63e3d839297"
  },
  {
   "t": "2026-09-28T14:59:24Z",
   "kind": "review_comment",
   "who": "instagibbs",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_resendwallettransactions.py",
   "commit": "8c4e257f475a7d2c5faf7f127ed3c63e3d839297",
   "in_reply_to": 4115855286,
   "text": "largely took, thanks",
   "id": "rc:4123678855",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#discussion_r4123678855",
   "hash": "faa03c9d743b837d",
   "edited": "2026-09-28T14:59:25Z"
  },
  {
   "t": "2026-09-28T15:00:45Z",
   "kind": "force_push",
   "who": "instagibbs",
   "commit": "6d5450244b5539a454aee3f88152ef7c78e27055",
   "id": "push:6d5450244b5539a454aee3f88152ef7c78e27055"
  },
  {
   "t": "2026-09-28T22:16:55Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_resendwallettransactions.py",
   "commit": "6d5450244b5539a454aee3f88152ef7c78e27055",
   "in_reply_to": null,
   "text": "nit:\n\nThis second test that tx's are not readded at the resubmit timer is dependent on the test above, e.g. consider this diff:\n\n```diff\ndiff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp\nindex 93851a8736..8d15b02f37 100644\n--- a/src/wallet/wallet.cpp\n+++ b/src/wallet/wallet.cpp\n@@ -1917,7 +1917,7 @@ void CWallet::ResubmitWalletTransactions(node::TxBroadcast broadcast_method, boo\n     // Don't attempt to resubmit if the wallet is configured to not broadcast,\n     // even if forcing.\n     if (!fBroadcastTransactions) return;\n-    if (m_private_broadcast) return;\n+    // if (m_private_broadcast) return;\n\n     int submitted_tx_count = 0;\n\ndiff --git a/test/functional/wallet_resendwallettransactions.py b/test/functional/wallet_resendwallettransactions.py\nindex e4afad1d42..8f1da010e3 100755\n--- a/test/functional/wallet_resendwallettransactions.py\n+++ b/test/functional/wallet_resendwallettransactions.py\n@@ -161,7 +161,8 @@ class ResendWalletTransactionsTest(BitcoinTestFramework):\n         node1.replace_in_config([(\"connect=0\\n\", \"\")])  # -privatebroadcast refuses -connect\n         privbcast_args = [\"-privatebroadcast\", \"-onion=127.0.0.1:9\", \"-persistmempool=0\"]  # the proxy is never used here\n         self.restart_node(1, extra_args=privbcast_args + [f\"-mocktime={node1.mocktime}\"])\n-        assert recv_txid not in node1.getrawmempool()  # loading the wallet did not re-add it\n+        # [first test disabled]\n+        # assert recv_txid not in node1.getrawmempool()  # loading the wallet did not re-add it\n\n         self.log.info(\"The periodic resend does not re-add it\")\n         # Resending needs a recent tip (the restart put node1 back in IBD) and a block seen since startup\n```\n\nThen this second check passes (since the generate line included the tx in a block), maybe add a (redundant) check here, e.g.:\n\n```suggestion\n        assert recv_txid not in node1.getrawmempool()\n        self.generate(node1, 1, sync_fun=self.no_op)\n```\n\nmaybe spurious [why would somebody delete or move one of the tests], but IMO these long winded functional tests where each of the checks are not scoped and there's stateful stuff are hard enough to read and even though it's obvious to us reviewing this now, to my grug brain at least it would not be obvious that the properties this claims to test are only there if the test above also passes",
   "id": "rc:4127551255",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#discussion_r4127551255",
   "hash": "8eb8c18b9bec3bb2",
   "edited": "2026-09-28T22:16:56Z"
  },
  {
   "t": "2026-09-28T22:17:54Z",
   "kind": "review",
   "who": "mzumsande",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "6d5450244b5539a454aee3f88152ef7c78e27055",
   "text": "[quoted text omitted]\n\nI think that promoting private broadcast into an essential feature (and with it, connectivity to privacy networks) that is required for basic functionality such as rebroadcasting is a major change that needs to be very well discussed, to say the least.\n\nAs of now I view it as an optional feature.\n\nBut as such, I could see users starting with `-privatebroadcast` just to send out some transactions, and then restarting back to regular mode without private broadcast with a wallet that rebroadcasts them. This could reveal the origin of their transactions after the fact, so there is only so much this PR can achieve.",
   "id": "r:5345286414",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#pullrequestreview-5345286414",
   "hash": "47e5ef51426c13d4",
   "edited": "2026-09-28T22:24:59Z"
  },
  {
   "t": "2026-09-28T22:23:12Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_resendwallettransactions.py",
   "commit": "6d5450244b5539a454aee3f88152ef7c78e27055",
   "in_reply_to": null,
   "text": "nit: consider cleaning this up so the test is less stateful:\n\n```diff\ndiff --git a/test/functional/wallet_resendwallettransactions.py b/test/functional/wallet_resendwallettransactions.py\nindex e4afad1d42..3367468148 100755\n--- a/test/functional/wallet_resendwallettransactions.py\n+++ b/test/functional/wallet_resendwallettransactions.py\n@@ -158,7 +158,7 @@ class ResendWalletTransactionsTest(BitcoinTestFramework):\n             peer.wait_for_broadcast([recv_wtxid])\n\n         self.log.info(\"With -privatebroadcast, the wallet never re-adds a transaction to the mempool\")\n-        node1.replace_in_config([(\"connect=0\\n\", \"\")])  # -privatebroadcast refuses -connect\n+        node1.replace_in_config([(\"connect=0\\n\", \"#connect=0\\n\")])  # -privatebroadcast refuses -connect\n         privbcast_args = [\"-privatebroadcast\", \"-onion=127.0.0.1:9\", \"-persistmempool=0\"]  # the proxy is never used here\n         self.restart_node(1, extra_args=privbcast_args + [f\"-mocktime={node1.mocktime}\"])\n         assert recv_txid not in node1.getrawmempool()  # loading the wallet did not re-add it\n@@ -173,6 +173,7 @@ class ResendWalletTransactionsTest(BitcoinTestFramework):\n         assert recv_txid not in node1.getrawmempool()\n\n         self.log.info(\"Without -privatebroadcast, loading the wallet re-adds it\")\n+        node1.replace_in_config([(\"#connect=0\\n\", \"connect=0\\n\")]) # clean up the cfg changes made\n         self.restart_node(1, extra_args=[\"-persistmempool=0\", f\"-mocktime={node1.mocktime}\"])\n         assert recv_txid in node1.getrawmempool()\n\n```",
   "id": "rc:4127599050",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#discussion_r4127599050",
   "hash": "e055ecc24906504b",
   "edited": null
  },
  {
   "t": "2026-09-28T22:36:39Z",
   "kind": "comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "text": "crACK https://github.com/bitcoin/bitcoin/commit/6d5450244b5539a454aee3f88152ef7c78e27055\n\nIt is unfortunate that restarting subjects a user to potentially losing privacy if a TX is not confirmed. I would personally be in favor of dropping wallet rebroadcasting completely, it is a massive privacy footgun for non-privatebroadcast users as well, for little benefit. At least, for little benefit that couldn't be provided with other solutions that are less harmful.",
   "id": "c:5879981602",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5879981602",
   "hash": "dcc57852cac9a331",
   "edited": null
  },
  {
   "t": "2026-09-29T03:34:53Z",
   "kind": "comment",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nI was merely suggesting to have the wallet rebroadcast via private broadcast if `-privatebroadcast` was set, not fix the entire unexpected rebroadcasting issue by requiring `-privatebroadcast`. (Although I might have shared that idea in another channel, I am not advocating we do that here.)",
   "id": "c:5883120907",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5883120907",
   "hash": "923e7e0b6000200e",
   "edited": null
  },
  {
   "t": "2026-09-29T09:03:41Z",
   "kind": "comment",
   "who": "vasild",
   "assoc": "MEMBER",
   "text": "Improving privacy is good, but I think this has taken an odd approach:\n\n* It adds a relationship between wallet behavior and `-privatebroadcast`. It is documented that `-privatebroadcast` does not affect the wallet.\n\n* It makes it impossible to have `-privatebroadcast=1` and wallet rebroadcast. Wallet rebroadcast indeed looks bad wrt privacy, but it is so even without considering `-privatebroadcast`. There may be setups where the wallet rebroadcasts are not so bad (e.g. if the node is not directly connected to clearnet) and are desired. Wallet rebroadcasts shouldn't really be tied to the value of `-privatebroadcast`.\n\nI think it is better to make wallet rebroadcasts separately controllable, independently of `-privatebroadcast`. Opened https://github.com/bitcoin/bitcoin/pull/36380 to explore that.",
   "id": "c:5887071448",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5887071448",
   "hash": "73dd77a3e45f6962",
   "edited": null
  },
  {
   "t": "2026-09-29T12:52:07Z",
   "kind": "comment",
   "who": "instagibbs",
   "assoc": "MEMBER",
   "text": "@vasild I don't think adding more knobs is the right direction, we already have `-walletbroadcast` which arguably could the a soft default with private broadcast on. Users could over-ride that and retain old behavior. But of course, users may turn the feature on, then turn it back off, rebroadcasting anyways.\n\n[quoted text omitted]\nWe can change documentation if we change behavior. Only matters if the change is correct/good/etc.\n\n@davidgumberg yeah, I am quite skeptical of the wallet rebroadcast feature, it's built around corner cases and is a massive leak. Would be willing to discuss alternatives in an issue regardless of how this PR goes.",
   "id": "c:5890683539",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5890683539",
   "hash": "29f88a81c615da88",
   "edited": null
  },
  {
   "t": "2026-09-29T13:12:37Z",
   "kind": "force_push",
   "who": "instagibbs",
   "commit": "3544df277deb658f150ed44f4a5f758fd8ef42af",
   "id": "push:3544df277deb658f150ed44f4a5f758fd8ef42af"
  },
  {
   "t": "2026-09-29T13:14:03Z",
   "kind": "review_comment",
   "who": "instagibbs",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_resendwallettransactions.py",
   "commit": "6d5450244b5539a454aee3f88152ef7c78e27055",
   "in_reply_to": 4127551255,
   "text": "I had it mine an empty block, then did the assertion it's not in mempool. that help grug? (I agree these should all be subtests split off, easy cleanup task)",
   "id": "rc:4133865952",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#discussion_r4133865952",
   "hash": "ddf66d7043939e03",
   "edited": null
  },
  {
   "t": "2026-09-29T13:14:12Z",
   "kind": "review_comment",
   "who": "instagibbs",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_resendwallettransactions.py",
   "commit": "6d5450244b5539a454aee3f88152ef7c78e27055",
   "in_reply_to": 4127599050,
   "text": "taken",
   "id": "rc:4133867434",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#discussion_r4133867434",
   "hash": "99341d56cc288053",
   "edited": "2026-09-29T13:14:13Z"
  },
  {
   "t": "2026-09-29T14:41:10Z",
   "kind": "comment",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nOne such alternative has an issue open https://github.com/bitcoin/bitcoin/issues/30471.",
   "id": "c:5892534313",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5892534313",
   "hash": "633d189cb0595ab8",
   "edited": "2026-09-29T15:26:49Z"
  },
  {
   "t": "2026-09-30T08:17:00Z",
   "kind": "comment",
   "who": "vasild",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nRight, I am not convinced either. Maybe the existent option can be extended, see at the bottom of https://github.com/bitcoin/bitcoin/pull/36380#issuecomment-5906908312\n\n[quoted text omitted]\nI just don't like those parameter interactions - in general, they could be hard to reason about. So to have `-privatebroadcast=1` soft set `-walletbroadcast=0`? To stop also the initial wallet broadcast, given that `-privatebroadcast` is not used by the wallet... sounds odd to me.\n\n[quoted text omitted]\nRight. And it would be nice to have the wallet use the private broadcast for its transactions even if currently it is documented that it does not :)\n\n[quoted text omitted]\n:100:",
   "id": "c:5907108581",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5907108581",
   "hash": "2df7fb78103aabd5",
   "edited": null
  },
  {
   "t": "2026-10-01T19:49:26Z",
   "kind": "comment",
   "who": "achow101",
   "assoc": "MEMBER",
   "text": "I've opened #36403 where we can have more high level discussion about transaction rebroadcast in general.",
   "id": "c:5939296500",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5939296500",
   "hash": "92e45907e178e160",
   "edited": null
  },
  {
   "t": "2026-10-02T15:22:59Z",
   "kind": "comment",
   "who": "instagibbs",
   "assoc": "MEMBER",
   "text": "moving to draft due to lack of consensus",
   "id": "c:5955557449",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5955557449",
   "hash": "89bddd4f159801b7",
   "edited": null
  },
  {
   "t": "2026-10-08T03:55:57Z",
   "kind": "comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "text": "reACK 3544df277deb658f150ed44f4a5f758fd8ef42af\n\nI think this is a simple and good enough fix that can be backported into 32.x and 31.x\n\nAlso see discussion in https://github.com/bitcoin/bitcoin/issues/36403.",
   "id": "c:6051853288",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-6051853288",
   "hash": "23c113a73c16861f",
   "edited": "2026-10-08T03:56:57Z"
  },
  {
   "t": "2026-10-08T17:55:00Z",
   "kind": "review",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "state": "APPROVED",
   "commit": "3544df277deb658f150ed44f4a5f758fd8ef42af",
   "text": "Code Review ACK 3544df277deb658f150ed44f4a5f758fd8ef42af",
   "id": "r:5460797236",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#pullrequestreview-5460797236",
   "hash": "5bb6efd1ecea44fe",
   "edited": null
  },
  {
   "t": "2026-10-08T21:25:35Z",
   "kind": "review",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "3544df277deb658f150ed44f4a5f758fd8ef42af",
   "text": "reACK 3544df277deb658f150ed44f4a5f758fd8ef42af",
   "id": "r:5463038618",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#pullrequestreview-5463038618",
   "hash": "366c8cad9633da9a",
   "edited": null
  },
  {
   "t": "2026-10-09T04:16:48Z",
   "kind": "comment",
   "who": "vasild",
   "assoc": "MEMBER",
   "text": "* The wallet transactions are initially sent to all peers and periodically rebroadcast. This has not changed in 10 years and was not changed by the introduction of private broadcast. The wallet does not use private broadcast.\n\n* The wallet rebroadcast is and has always been bad for privacy, but it has its use cases. This PR would cripple the wallet due to an unrelated feature being enabled.\n\n* I see the idea here is to try to protect users that create transactions in the wallet, but do not broadcast them via the wallet and use `sendrawtransaction` RPC instead with private broadcast. For these users, that do not use the wallet initial send either, `-walletbroadcast=0` fits very well. I think this should be resolved via some communication channel to advise people of that.\n\nConcept NACK",
   "id": "c:6074151790",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-6074151790",
   "hash": "fad17b6e6b79f4eb",
   "edited": "2026-10-09T04:21:07Z"
  },
  {
   "t": "2026-10-09T12:47:23Z",
   "kind": "comment",
   "who": "instagibbs",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nInteractions between features exist and should not be ignored. It's a wallet issue, for sure, but for a wallet + pb user, it would be extremely surprising.\n\n[quoted text omitted]\nI don't think handing users footguns and hoping they read the docs is the right approach. Ideally we'd remove / replace rebroadcasts entirely, then this particular coupling can disappear safely. https://github.com/bitcoin/bitcoin/issues/36403#issuecomment-6051815930 for some discussion for those following at home.",
   "id": "c:6081186947",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-6081186947",
   "hash": "13fc26edc99f77b7",
   "edited": null
  },
  {
   "t": "2026-10-09T16:17:48Z",
   "kind": "comment",
   "who": "polespinasa",
   "assoc": "MEMBER",
   "text": "I tend to concept NACK this although I cannot come with a better proposal that 100% fixes this right now.\n\nI don't think disallowing re-broadcast is the right solution (I know this is proposed as a temporal fix). Although it is not perfect, I prefer something like #36482 which I consider a good half-patch that limits this issue to a really specific case were a transaction disappears from node's mempool and is when we should consider rebroadcast necessary (in its current implementation).\n\nI don't think the incoming dust privacy attack is an argument for pushing this PR forward. That attack affects both, private and standard broadcast, and as I understand private broadcast, it improves your privacy when you send a transaction, not when you receive one. It helps hiding you are the origin of a transaction, but that doesn't mean that it makes impossible to know that you are the origin of a transaction.\nIn other words, I think the dust-resubmit attack is worth fixing and we should fix it, but it is worth fixing for all cases, not only private broadcast. I don't feel disabling a useful feature such as rebroadcast is the right step here. We also shouldn't assume and say that private broadcast makes impossible to know the origin of a transaction, it does improve privacy and makes it more difficult and expensive to know.",
   "id": "c:6084798078",
   "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-6084798078",
   "hash": "56ff7b7d677d9a33",
   "edited": null
  }
 ],
 "labels_log": [
  {
   "t": "2026-09-24T18:00:02Z",
   "action": "labeled",
   "label": "Wallet",
   "who": "DrahtBot"
  },
  {
   "t": "2026-09-24T20:17:29Z",
   "action": "labeled",
   "label": "Private Broadcast",
   "who": "fanquake"
  },
  {
   "t": "2026-09-28T15:02:22Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-09-28T16:03:33Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-09-29T14:45:38Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-09-29T15:24:26Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  }
 ],
 "state_log": [
  {
   "t": "2026-09-25T17:20:11Z",
   "kind": "renamed",
   "who": "instagibbs",
   "from": "wallet: don't announce resubmitted transactions under -privatebroadcast",
   "to": "wallet: don't resubmit transactions under -privatebroadcast"
  },
  {
   "t": "2026-10-02T15:19:54Z",
   "kind": "convert_to_draft",
   "who": "instagibbs"
  },
  {
   "t": "2026-10-02T15:22:39Z",
   "kind": "renamed",
   "who": "instagibbs",
   "from": "wallet: don't resubmit transactions under -privatebroadcast",
   "to": "[NO MERGE] wallet: don't resubmit transactions under -privatebroadcast"
  },
  {
   "t": "2026-10-08T11:45:13Z",
   "kind": "ready_for_review",
   "who": "instagibbs"
  },
  {
   "t": "2026-10-08T17:53:45Z",
   "kind": "renamed",
   "who": "instagibbs",
   "from": "[NO MERGE] wallet: don't resubmit transactions under -privatebroadcast",
   "to": "wallet: don't resubmit transactions under -privatebroadcast"
  }
 ],
 "text_chars": 17240,
 "text_tokens_estimate": 4310,
 "changed_paths": [
  "src/wallet/wallet.cpp",
  "src/wallet/wallet.h",
  "test/functional/wallet_resendwallettransactions.py"
 ],
 "files": [
  {
   "path": "src/wallet/wallet.cpp",
   "add": 7,
   "del": 0
  },
  {
   "path": "src/wallet/wallet.h",
   "add": 3,
   "del": 0
  },
  {
   "path": "test/functional/wallet_resendwallettransactions.py",
   "add": 21,
   "del": 0
  }
 ],
 "test_lines": 21,
 "git": {
  "head": "3544df277deb658f150ed44f4a5f758fd8ef42af",
  "head_matches_backup": true,
  "base": "ad97933af248bf2e6a299ea643f4183353ffc237",
  "patch_id": "3a2970eb151ceb6b",
  "commits": [
   {
    "sha": "3544df277d",
    "subject": "wallet: don't resubmit transactions to the mempool under -privatebroadcast",
    "files": 3,
    "add": 31,
    "del": 0
   }
  ],
  "patch_truncated": false
 },
 "patch_id": "3a2970eb151ceb6b",
 "input_hash": "5b00b52475899e0d",
 "extracted_at": "2026-11-02T01:09:49+00:00"
}