{
 "number": 36330,
 "input_hash": "6dc0fa49c687b021",
 "model": "ledger",
 "prompt_hash": null,
 "created": "2026-10-10T01:23:41+00:00",
 "result": {
  "summary": "Disables unconfirmed wallet transaction resubmission when the node is configured with `-privatebroadcast`. The wallet checks this setting and skips re-adding unconfirmed transactions to the local mempool during startup, transaction imports, and scheduled periodic rebroadcasts. Initial broadcasts of newly created transactions remain unaffected.",
  "problem": "When the wider network drops an unconfirmed transaction from mempools, the local wallet periodically re-submits it to the node's mempool and announces or serves it to peers on request. Users running with `-privatebroadcast` expect privacy protections against origin inference, but serving a locally retained transaction that no other peer holds exposes the node as the sender or receiver over clearnet.",
  "card": "Suppresses unconfirmed wallet transaction resubmission to the mempool when running with -privatebroadcast. Currently, when the network evicts a transaction, a wallet periodically re-adds it to the local mempool and serves it to peers upon request, identifying the node as the transaction's originator or recipient over clearnet. Skipping resubmission on startup, import, and timer intervals prevents deanonymizing users who opted into private broadcast. Initial transaction broadcasts remain unaffected.",
  "evidence": [
   "Commit 6d5450244b: \"A transaction that the rest of the network has dropped is then held by this node alone, and served to any peer that asks for it, which marks it as the node's own. Not announcing the re-added transaction does not hide this: any relay peer can fetch anything in the mempool once the next inv round has passed.\"",
   "PR description points to long-standing origin privacy issues: \"e.g. an incoming dust payment triggering your node to rebroadcast 24-36th later over clearnet... see https://github.com/bitcoin/bitcoin/issues/3828 for running broader issue\""
  ],
  "scope_notes": "",
  "changed_since_previous": "No substantial changes to the approach or mechanism; the logic in `CWallet::ResubmitWalletTransactions` and configuration loading remains the same.",
  "thread": {
   "last_event_at": "2026-10-09T16:17:48Z",
   "events": 32,
   "head_sha": "3544df277deb658f150ed44f4a5f758fd8ef42af",
   "schema_floor": 2,
   "schema": 2
  },
  "waiting_on": [
   {
    "at": "2026-10-09",
    "id": "c:6084798078",
    "on": "author",
    "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-6084798078",
    "what": "author to reply to polespinasa's objection against disabling rebroadcast"
   },
   {
    "at": "2026-10-09",
    "id": "c:6081186947",
    "on": "reviewer",
    "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-6081186947",
    "what": "vasild to respond to author's reply on feature interactions and footguns"
   }
  ],
  "risk": {
   "level": "low",
   "touches": [
    "wallet",
    "tests"
   ],
   "why": "A bug could cause unconfirmed wallet transactions under -privatebroadcast to fail to reach the mempool after a restart until manually rebroadcast, but normal broadcast flows and non-privatebroadcast configurations are unaffected."
  },
  "discussion": {
   "author_status": "last statement processed 2026-10-09",
   "open_concerns": [
    "vasild: Tying wallet rebroadcast to -privatebroadcast contradicts documentation that -privatebroadcast does not affect the wallet and prevents having both -privatebroadcast and wallet rebroadcast",
    "vasild: Disabling wallet rebroadcast cripples the wallet due to an unrelated feature being enabled, whereas users sending via RPC should use -walletbroadcast=0",
    "polespinasa: Disabling rebroadcast is the wrong solution as it removes a useful feature, whereas the dust-resubmit privacy attack affects standard broadcast too and should be fixed generally or limited to mempool evictions"
   ],
   "resolved_concerns": [
    "achow101: Questioned whether resubmit should differ from CommitTransaction, which does not use private broadcast (answered by andrewtoth 2026-09-24)",
    "davidgumberg: Resubmitting transactions to the mempool still trivially reveals them to an active observer under -privatebroadcast (fixed by instagibbs 2026-09-25)",
    "andrewtoth: Asked whether the change is intended for backport, noting that full wallet private broadcast would be preferable if not backporting (answered by instagibbs 2026-09-25)",
    "andrewtoth: Use -persistmempool=0 instead of -mempoolexpiry=1 in wallet_resendwallettransactions.py to make the test more concise with identical coverage (fixed by instagibbs 2026-09-28)"
   ]
  },
  "reviewability": {
   "state": "Paused",
   "label": "Waiting on author",
   "reason": "Open objection from polespinasa with no author reply for 23 days; review would repeat what has been asked."
  },
  "agreement": {
   "state": "Blocked",
   "summary": "Blocked: objection that needs a change, nobody has replied (polespinasa)",
   "reason": "vasild Concept NACKed the PR in c:6074151790 arguing it cripples wallet rebroadcast, which the author answered in c:6081186947. polespinasa also objected / tended to Concept NACK in c:6084798078, which remains open.",
   "evidence": [
    "vasild (objection, approach, must be answered, contested): Tying wallet rebroadcast to -privatebroadcast contradicts documentation that -privatebroadcast does not affect the wallet and prevents having both -privatebroadcast and wallet rebroadcast",
    "vasild (objection, approach, must be changed, answered): Disabling wallet rebroadcast cripples the wallet due to an unrelated feature being enabled, whereas users sending via RPC should use -walletbroadcast=0",
    "polespinasa (objection, approach, must be changed, open): Disabling rebroadcast is the wrong solution as it removes a useful feature, whereas the dust-resubmit privacy attack affects standard broadcast too and should be fixed generally or limited to mempool evictions",
    "andrewtoth: support \u2014 protecting against transactions sent by other means that also belong to the wallet (e.g., watch-only, dust) being unexpectedly rebroadcast under -privatebroadcast",
    "w0xlt: ACK",
    "andrewtoth: ACK",
    "davidgumberg: ACK \u2014 reviewed commit 6d54502 and supported dropping wallet rebroadcast completely",
    "darosior: Concept ACK",
    "davidgumberg: ACK \u2014 simple and good enough fix that can be backported into 32.x and 31.x",
    "andrewtoth: ACK \u2014 Code Review ACK 3544df277deb658f150ed44f4a5f758fd8ef42af",
    "w0xlt: ACK \u2014 reACK 3544df277deb658f150ed44f4a5f758fd8ef42af"
   ],
   "objections": [
    {
     "reviewer": "achow101",
     "association": "MEMBER",
     "type": "suggestion",
     "kind": "approach",
     "harm": "",
     "request": "Questioned whether resubmit should differ from CommitTransaction, which does not use private broadcast",
     "question": "",
     "text": "Questioned whether resubmit should differ from CommitTransaction, which does not use private broadcast",
     "clears_with": "answer",
     "blocking": false,
     "status": "answered",
     "status_note": "andrewtoth explained that it protects against rebroadcast of transactions originating outside the wallet (sendrawtransaction, watch-only, dust)",
     "cleared": true,
     "author_replied": false,
     "others_replied": true,
     "fix_pushed": false,
     "replies": [
      "c:5823087651"
     ],
     "evidence": "2026-09-24: '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 behav'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5822665076",
     "id": "c:5822665076",
     "at": "2026-09-24",
     "status_at": "2026-09-24",
     "status_by": "andrewtoth",
     "resolution_evidence": "2026-09-24: andrewtoth: 'This is true, but the case this change is protecting against is transactions sent by other means that also belong to the'",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "davidgumberg",
     "association": "MEMBER",
     "type": "objection",
     "kind": "safety",
     "harm": "Resubmitting transactions to the mempool still trivially reveals them to an active observer under -privatebroadcast",
     "request": "",
     "question": "",
     "text": "Resubmitting transactions to the mempool still trivially reveals them to an active observer under -privatebroadcast",
     "clears_with": "answer",
     "blocking": false,
     "status": "fixed",
     "status_note": "author agreed and pushed an update to never resubmit when pb is set",
     "cleared": true,
     "author_replied": true,
     "others_replied": false,
     "fix_pushed": true,
     "replies": [
      "rc:4105713757",
      "rc:4106693516"
     ],
     "evidence": "2026-09-24: 'IMO should return here without ever being resubmitted to the mempool since learning a peer's mempool is trivial for an active observer.'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36330#discussion_r4099089685",
     "id": "rc:4099089685",
     "at": "2026-09-24",
     "status_at": "2026-09-25",
     "status_by": "instagibbs",
     "resolution_evidence": "2026-09-25: instagibbs: 'pushed an update so the wallet never resubmits when pb is set. Avoids restarts and loading wallets triggering it'",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "andrewtoth",
     "association": "MEMBER",
     "type": "question",
     "kind": "approach",
     "harm": "",
     "request": "",
     "question": "Asked whether the change is intended for backport, noting that full wallet private broadcast would be preferable if not backporting",
     "text": "Asked whether the change is intended for backport, noting that full wallet private broadcast would be preferable if not backporting",
     "clears_with": "answer",
     "blocking": false,
     "status": "answered",
     "status_note": "author replied that backporting makes sense since full wallet integration is not close to done",
     "cleared": true,
     "author_replied": true,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [
      "c:5836147841"
     ],
     "evidence": "2026-09-25: 'Is this intended for backport?'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5834307893",
     "id": "c:5834307893",
     "at": "2026-09-25",
     "status_at": "2026-09-25",
     "status_by": "instagibbs",
     "resolution_evidence": "2026-09-25: instagibbs: 'Given that wallet integration isn't close to done, I think we should remove footguns until we get there. This is easily '",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "andrewtoth",
     "association": "MEMBER",
     "type": "suggestion",
     "kind": "approach",
     "harm": "",
     "request": "Use -persistmempool=0 instead of -mempoolexpiry=1 in wallet_resendwallettransactions.py to make the test more concise with identical coverage",
     "question": "",
     "text": "Use -persistmempool=0 instead of -mempoolexpiry=1 in wallet_resendwallettransactions.py to make the test more concise with identical coverage",
     "clears_with": "answer",
     "blocking": false,
     "status": "fixed",
     "status_note": "author adopted the test suggestion in an update",
     "cleared": true,
     "author_replied": true,
     "others_replied": false,
     "fix_pushed": true,
     "replies": [
      "rc:4123678855"
     ],
     "evidence": "2026-09-27: 'I think we can use `-persistmempool=0` here instead of `-mempoolexpiry=1` to make this more concise with identical coverage'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36330#discussion_r4115855286",
     "id": "rc:4115855286",
     "at": "2026-09-27",
     "status_at": "2026-09-28",
     "status_by": "instagibbs",
     "resolution_evidence": "2026-09-28: instagibbs: 'largely took, thanks'",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "vasild",
     "association": "MEMBER",
     "type": "objection",
     "kind": "approach",
     "harm": "Tying wallet rebroadcast to -privatebroadcast contradicts documentation that -privatebroadcast does not affect the wallet and prevents having both -privatebroadcast and wallet rebroadcast",
     "request": "",
     "question": "",
     "text": "Tying wallet rebroadcast to -privatebroadcast contradicts documentation that -privatebroadcast does not affect the wallet and prevents having both -privatebroadcast and wallet rebroadcast",
     "clears_with": "answer",
     "blocking": false,
     "status": "contested",
     "status_note": "vasild pushed back against parameter interactions between -privatebroadcast and wallet settings",
     "cleared": false,
     "author_replied": true,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [
      "c:5890683539"
     ],
     "evidence": "2026-09-29: 'It adds a relationship between wallet behavior and `-privatebroadcast`. It is documented that `-privatebroadcast` does not affect the wallet.'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5887071448",
     "id": "c:5887071448",
     "at": "2026-09-29",
     "status_at": "2026-09-30",
     "status_by": "vasild",
     "resolution_evidence": "2026-09-30: vasild: 'I just don't like those parameter interactions - in general, they could be hard to reason about.'",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "vasild",
     "association": "MEMBER",
     "type": "objection",
     "kind": "approach",
     "harm": "Disabling wallet rebroadcast cripples the wallet due to an unrelated feature being enabled, whereas users sending via RPC should use -walletbroadcast=0",
     "request": "",
     "question": "",
     "text": "Disabling wallet rebroadcast cripples the wallet due to an unrelated feature being enabled, whereas users sending via RPC should use -walletbroadcast=0",
     "clears_with": "change",
     "blocking": true,
     "status": "answered",
     "status_note": "author replied that feature interactions exist and disabling footguns is better than relying on docs",
     "cleared": false,
     "author_replied": true,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [
      "c:6081186947"
     ],
     "evidence": "2026-10-09: '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.'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-6074151790",
     "id": "c:6074151790",
     "at": "2026-10-09",
     "status_at": "2026-10-09",
     "status_by": "instagibbs",
     "resolution_evidence": "2026-10-09: instagibbs: 'Interactions 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.'",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "polespinasa",
     "association": "MEMBER",
     "type": "objection",
     "kind": "approach",
     "harm": "Disabling rebroadcast is the wrong solution as it removes a useful feature, whereas the dust-resubmit privacy attack affects standard broadcast too and should be fixed generally or limited to mempool evictions",
     "request": "",
     "question": "",
     "text": "Disabling rebroadcast is the wrong solution as it removes a useful feature, whereas the dust-resubmit privacy attack affects standard broadcast too and should be fixed generally or limited to mempool evictions",
     "clears_with": "change",
     "blocking": true,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-10-09: 'I don't feel disabling a useful feature such as rebroadcast is the right step here.'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-6084798078",
     "id": "c:6084798078",
     "at": "2026-10-09",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    }
   ],
   "support": [
    {
     "reviewer": "andrewtoth",
     "reason": "protecting against transactions sent by other means that also belong to the wallet (e.g., watch-only, dust) being unexpectedly rebroadcast under -privatebroadcast",
     "substantive": true,
     "verdict": "",
     "id": "c:5823087651",
     "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5823087651",
     "at": "2026-09-24",
     "association": "MEMBER",
     "evidence": "read",
     "areas": []
    },
    {
     "reviewer": "w0xlt",
     "reason": "",
     "substantive": false,
     "verdict": "ACK",
     "id": "r:5309745790",
     "url": "https://github.com/bitcoin/bitcoin/pull/36330#pullrequestreview-5309745790",
     "at": "2026-09-24",
     "association": "CONTRIBUTOR",
     "evidence": "none",
     "areas": []
    },
    {
     "reviewer": "andrewtoth",
     "reason": "",
     "substantive": false,
     "verdict": "ACK",
     "id": "r:5330841772",
     "url": "https://github.com/bitcoin/bitcoin/pull/36330#pullrequestreview-5330841772",
     "at": "2026-09-27",
     "association": "MEMBER",
     "evidence": "none",
     "areas": []
    },
    {
     "reviewer": "davidgumberg",
     "reason": "reviewed commit 6d54502 and supported dropping wallet rebroadcast completely",
     "substantive": true,
     "verdict": "ACK",
     "id": "c:5879981602",
     "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-5879981602",
     "at": "2026-09-28",
     "association": "MEMBER",
     "evidence": "read",
     "areas": []
    },
    {
     "reviewer": "darosior",
     "reason": "",
     "substantive": false,
     "verdict": "Concept ACK",
     "id": "r:5336431896",
     "url": "https://github.com/bitcoin/bitcoin/pull/36330#pullrequestreview-5336431896",
     "at": "2026-09-28",
     "association": "MEMBER",
     "evidence": "none",
     "areas": []
    },
    {
     "reviewer": "davidgumberg",
     "reason": "simple and good enough fix that can be backported into 32.x and 31.x",
     "substantive": true,
     "verdict": "ACK",
     "id": "c:6051853288",
     "url": "https://github.com/bitcoin/bitcoin/pull/36330#issuecomment-6051853288",
     "at": "2026-10-08",
     "association": "MEMBER",
     "evidence": "read",
     "areas": []
    },
    {
     "reviewer": "andrewtoth",
     "reason": "Code Review ACK 3544df277deb658f150ed44f4a5f758fd8ef42af",
     "substantive": false,
     "verdict": "ACK",
     "id": "r:5460797236",
     "url": "https://github.com/bitcoin/bitcoin/pull/36330#pullrequestreview-5460797236",
     "at": "2026-10-08",
     "association": "MEMBER",
     "evidence": "none",
     "areas": []
    },
    {
     "reviewer": "w0xlt",
     "reason": "reACK 3544df277deb658f150ed44f4a5f758fd8ef42af",
     "substantive": false,
     "verdict": "ACK",
     "id": "r:5463038618",
     "url": "https://github.com/bitcoin/bitcoin/pull/36330#pullrequestreview-5463038618",
     "at": "2026-10-08",
     "association": "CONTRIBUTOR",
     "evidence": "none",
     "areas": []
    }
   ],
   "participants": [
    {
     "login": "achow101",
     "stance": "question",
     "note": "questioned why resubmit should differ from wallet broadcast under -privatebroadcast; opened #36403 for broader discussion",
     "association": "MEMBER",
     "comments": 2,
     "first": "2026-09-24",
     "last": "2026-10-01"
    },
    {
     "login": "andrewtoth",
     "stance": "support",
     "note": "ACKed the PR and updates, supported addressing unexpected rebroadcast, and suggested simplifying the test",
     "association": "MEMBER",
     "comments": 7,
     "first": "2026-09-24",
     "last": "2026-10-08"
    },
    {
     "login": "davidgumberg",
     "stance": "objection",
     "note": "objected that resubmitting to mempool leaks transactions, then ACKed the updates and supported backporting",
     "association": "MEMBER",
     "comments": 5,
     "first": "2026-09-24",
     "last": "2026-10-08"
    },
    {
     "login": "fanquake",
     "stance": "neutral",
     "note": "pinged reviewers",
     "association": "MEMBER",
     "comments": 1,
     "first": "2026-09-24",
     "last": "2026-09-24"
    },
    {
     "login": "w0xlt",
     "stance": "support",
     "note": "ACKed and reACKed without rationale",
     "association": "CONTRIBUTOR",
     "comments": 2,
     "first": "2026-09-24",
     "last": "2026-10-08"
    },
    {
     "login": "darosior",
     "stance": "support",
     "note": "Concept ACK",
     "association": "MEMBER",
     "comments": 1,
     "first": "2026-09-28",
     "last": "2026-09-28"
    },
    {
     "login": "mzumsande",
     "stance": "neutral",
     "note": "commented that private broadcast is optional and restarting without it could still reveal transactions",
     "association": "MEMBER",
     "comments": 1,
     "first": "2026-09-28",
     "last": "2026-09-28"
    },
    {
     "login": "vasild",
     "stance": "objection",
     "note": "Concept NACKed; objected that the change cripples wallet rebroadcast over an unrelated feature",
     "association": "MEMBER",
     "comments": 3,
     "first": "2026-09-29",
     "last": "2026-10-09"
    },
    {
     "login": "polespinasa",
     "stance": "objection",
     "note": "tended to Concept NACK; objected to disabling useful rebroadcast functionality rather than fixing dust resubmission generally",
     "association": "MEMBER",
     "comments": 1,
     "first": "2026-10-09",
     "last": "2026-10-09"
    }
   ],
   "derivation": "objection that needs a change, nobody has replied (polespinasa)",
   "model_state": null,
   "corrections": [],
   "notes": "vasild Concept NACKed the PR in c:6074151790 arguing it cripples wallet rebroadcast, which the author answered in c:6081186947. polespinasa also objected / tended to Concept NACK in c:6084798078, which remains open."
  },
  "dependencies": {
   "depends_on": [],
   "enables": []
  },
  "categories": [
   {
    "name": "docs",
    "member": false,
    "evidence": "Touches only doc/release-notes-wallet-privbcast-resend.md as a routine release note accompanying a code fix.",
    "band": "Unranked",
    "reason_tag": "bug fix",
    "score": 0.0,
    "factors": {
     "bug_severity": 2,
     "leverage": 0,
     "performance": 0,
     "security_stability": 2,
     "user_value": 2
    },
    "rationale": "Release notes that accompany a functional code change belong to the area of the change, not documentation."
   },
   {
    "name": "p2p",
    "member": true,
    "evidence": "Matches the 'Private Broadcast' label hint and directly addresses transaction origin privacy on the P2P network.",
    "band": "P2",
    "reason_tag": "bug fix",
    "score": 0.68,
    "factors": {
     "bug_severity": 2,
     "leverage": 0,
     "performance": 0,
     "security_stability": 2,
     "user_value": 1
    },
    "rationale": "Resolves a privacy leak where wallet rebroadcasts identify the node as the origin over clearnet despite `-privatebroadcast`. As noted in the commit, holding and serving an evicted transaction that no other peer holds 'marks it as the node's own,' undermining the core privacy objective of private broadcast."
   },
   {
    "name": "wallet",
    "member": true,
    "evidence": "Changes wallet resubmission logic in src/wallet/wallet.cpp and src/wallet/wallet.h, and carries the 'Wallet' label.",
    "band": "P2",
    "reason_tag": "bug fix",
    "score": 0.6,
    "factors": {
     "bug_severity": 2,
     "leverage": 0,
     "performance": 0,
     "security_stability": 2,
     "user_value": 1
    },
    "rationale": "Prevents the wallet from undermining user privacy expectations by suppressing periodic resubmissions of unconfirmed transactions under `-privatebroadcast`. Leaving this unresolved allows unexpected wallet rebroadcasts (such as incoming dust payments) to trigger clearnet announcements."
   }
  ],
  "confidence": "high",
  "uncertainties": [],
  "needs": []
 },
 "cost_usd": 0.0,
 "source": {
  "record": "2026-10-10T01:23:41+00:00",
  "code": "2026-09-29T14:36:05+00:00",
  "judgments": 3
 }
}