{
 "number": 36372,
 "input_hash": "c2fd9a60f1a9b683",
 "model": "ledger",
 "prompt_hash": null,
 "created": "2026-10-14T01:24:45+00:00",
 "result": {
  "summary": "Replaces outbound full-relay peers that do not relay transactions with peers that do, operating only outside of initial block download and when not in -blocksonly mode. To prevent connection drops below outbound targets, the node initiates an extra full-relay outbound connection before evicting a non-relaying peer. Peers that do not relay transactions are excluded from chain-sync eviction protection, though the sole connection to any specific network is preserved.",
  "problem": "Outbound full-relay slots can be occupied by peers that decline transaction relay (such as nodes running in -blocksonly mode). This degrades transaction broadcast and propagation topology without the node operator's knowledge, and nodes with feefilter mismatches or blocksonly peers can be left with too few transaction-relaying outbound connections.",
  "card": "Replaces outbound full-relay peers that do not relay transactions with peers that do, ensuring nodes maintain expected transaction relay capacity and diversity. To avoid dropping below outbound connection targets, an extra outbound connection is established before evicting the non-relaying peer, and non-relaying peers are denied disconnect protection unless they are the sole connection on a reachable network. The replacement mechanism is disabled during initial block download and when running with -blocksonly, addressing issues #16418 and #28371 by resolving design feedback on #28538.",
  "evidence": [
   "Resurrects and reworks #28538 to address previous review feedback, motivated by longstanding open issues #16418 ('Ensure we have sufficient transaction-relay peers') and #28371 ('Seek more/different peers when ours all have too high feefilter')."
  ],
  "scope_notes": "Includes a cleanup commit renaming CConnman::ForEachNode to ForEachFullyConnectedNode and removing redundant disconnected-peer checks at call sites.",
  "changed_since_previous": "Initial patch evaluation; the diff directly implements the strategy previously described without approach changes.",
  "thread": {
   "last_event_at": "2026-10-13T12:14:09Z",
   "events": 6,
   "head_sha": "07e58de16805e66fc2bccc842c1c2edc4ee1f897",
   "schema_floor": 2,
   "schema": 2
  },
  "waiting_on": [
   {
    "at": "2026-10-02",
    "id": "c:5951741726",
    "on": "author",
    "url": "https://github.com/bitcoin/bitcoin/pull/36372#issuecomment-5951741726",
    "what": "response to fametrano's test objection, instagibbs' questions, and Bicaru20's review comments"
   }
  ],
  "risk": {
   "level": "medium",
   "touches": [
    "p2p"
   ],
   "why": "Bugs in peer eviction and connection rotation could cause connection instability, network churn, or unintended peer disconnects."
  },
  "discussion": {
   "author_status": "last statement processed 2026-10-13",
   "open_concerns": [
    "instagibbs: whether replacement peers should be validated to ensure they actually do useful work before evicting existing peers",
    "instagibbs: whether there is evidence on the network that non-tx-relaying peers are a real problem",
    "fametrano: the functional test checks for non-eviction cannot fail because a node never evicts the only peer on a network",
    "Bicaru20: whether active peers that do not relay transactions should be prioritized over peers that relay transactions but have been silent for some time",
    "Bicaru20: add a test case to denialofservice_tests checking that a replacement is requested even when the candidate peer cannot be evicted yet because it is younger than MINIMUM_CONNECT_TIME"
   ],
   "resolved_concerns": []
  },
  "reviewability": {
   "state": "Paused",
   "label": "Waiting on author",
   "reason": "Open objections from Bicaru20, fametrano, instagibbs with no author reply for 19 days; review would repeat what has been asked."
  },
  "agreement": {
   "state": "Blocked",
   "summary": "Blocked: objection that needs a change, nobody has replied (fametrano)",
   "reason": "Added Bicaru20 with Concept ACK, a suggestion for unit test coverage in denialofservice_tests, and a question regarding eviction priority between inactive tx-relaying peers and active non-tx-relaying peers. Bicaru20's inline comment on logging format was treated as a nit.",
   "evidence": [
    "instagibbs (question, approach, must be answered, open): whether replacement peers should be validated to ensure they actually do useful work before evicting existing peers",
    "instagibbs (question, usefulness, must be answered, open): whether there is evidence on the network that non-tx-relaying peers are a real problem",
    "fametrano (objection, correctness, must be changed, open): the functional test checks for non-eviction cannot fail because a node never evicts the only peer on a network",
    "Bicaru20 (question, approach, must be answered, open): whether active peers that do not relay transactions should be prioritized over peers that relay transactions but have been silent for some time",
    "Bicaru20 (suggestion, maintenance, must be answered, open): add a test case to denialofservice_tests checking that a replacement is requested even when the candidate peer cannot be evicted yet because it is younger than MINIMUM_CONNECT_TIME",
    "mzumsande: Concept ACK \u2014 thanks for picking this up!",
    "Bicaru20: Concept ACK \u2014 summarized PR behavior and left suggestion to make tests more robust"
   ],
   "objections": [
    {
     "reviewer": "instagibbs",
     "association": "MEMBER",
     "type": "question",
     "kind": "approach",
     "harm": "",
     "request": "",
     "question": "whether replacement peers should be validated to ensure they actually do useful work before evicting existing peers",
     "text": "whether replacement peers should be validated to ensure they actually do useful work before evicting existing peers",
     "clears_with": "answer",
     "blocking": false,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-09-30: 'Would we want to do more validation of those claims before evicting someone?'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36372#issuecomment-5918463449",
     "id": "c:5918463449",
     "at": "2026-09-30",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "instagibbs",
     "association": "MEMBER",
     "type": "question",
     "kind": "usefulness",
     "harm": "",
     "request": "",
     "question": "whether there is evidence on the network that non-tx-relaying peers are a real problem",
     "text": "whether there is evidence on the network that non-tx-relaying peers are a real problem",
     "clears_with": "answer",
     "blocking": false,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-09-30: 'do we have evidence this is a real problem? ... Can we crawl the network to see evidence of this?'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36372#issuecomment-5918463449",
     "id": "c:5918463449#2",
     "at": "2026-09-30",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "fametrano",
     "association": "CONTRIBUTOR",
     "type": "objection",
     "kind": "correctness",
     "harm": "the functional test checks for non-eviction cannot fail because a node never evicts the only peer on a network",
     "request": "",
     "question": "",
     "text": "the functional test checks for non-eviction cannot fail because a node never evicts the only peer on a network",
     "clears_with": "change",
     "blocking": true,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-10-02: 'The \"not evicted\" checks in the first and third cases of the new `p2p_blocksonly.py` test can't fail.'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36372#issuecomment-5951741726",
     "id": "c:5951741726",
     "at": "2026-10-02",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "Bicaru20",
     "association": "CONTRIBUTOR",
     "type": "question",
     "kind": "approach",
     "harm": "",
     "request": "",
     "question": "whether active peers that do not relay transactions should be prioritized over peers that relay transactions but have been silent for some time",
     "text": "whether active peers that do not relay transactions should be prioritized over peers that relay transactions but have been silent for some time",
     "clears_with": "answer",
     "blocking": false,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-10-13: 'Shouldn't we chose the peer that is active over the one that has been silent for some time even if the active peer is not relaying transactions?'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36372#pullrequestreview-5502202695",
     "id": "r:5502202695",
     "at": "2026-10-13",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    },
    {
     "reviewer": "Bicaru20",
     "association": "CONTRIBUTOR",
     "type": "suggestion",
     "kind": "maintenance",
     "harm": "",
     "request": "add a test case to denialofservice_tests checking that a replacement is requested even when the candidate peer cannot be evicted yet because it is younger than MINIMUM_CONNECT_TIME",
     "question": "",
     "text": "add a test case to denialofservice_tests checking that a replacement is requested even when the candidate peer cannot be evicted yet because it is younger than MINIMUM_CONNECT_TIME",
     "clears_with": "answer",
     "blocking": false,
     "status": "open",
     "status_note": "",
     "cleared": false,
     "author_replied": false,
     "others_replied": false,
     "fix_pushed": false,
     "replies": [],
     "evidence": "2026-10-13: 'I think it would be good to add a new test case here to check that a replecemnt is requested even when the candidate with `m_relays_txs=false` cannot be evicted yet because it is younger than MINIMUM_CONNECT_TIME'",
     "url": "https://github.com/bitcoin/bitcoin/pull/36372#discussion_r4257881028",
     "id": "rc:4257881028",
     "at": "2026-10-13",
     "status_at": null,
     "status_by": null,
     "resolution_evidence": "",
     "pin": null,
     "from_schema": 2
    }
   ],
   "support": [
    {
     "reviewer": "mzumsande",
     "reason": "thanks for picking this up!",
     "substantive": false,
     "verdict": "Concept ACK",
     "id": "r:5344753685",
     "url": "https://github.com/bitcoin/bitcoin/pull/36372#pullrequestreview-5344753685",
     "at": "2026-09-28",
     "association": "MEMBER",
     "evidence": "none",
     "areas": []
    },
    {
     "reviewer": "Bicaru20",
     "reason": "summarized PR behavior and left suggestion to make tests more robust",
     "substantive": false,
     "verdict": "Concept ACK",
     "id": "r:5502202695",
     "url": "https://github.com/bitcoin/bitcoin/pull/36372#pullrequestreview-5502202695",
     "at": "2026-10-13",
     "association": "CONTRIBUTOR",
     "evidence": "read",
     "areas": []
    }
   ],
   "participants": [
    {
     "login": "mzumsande",
     "stance": "support",
     "note": "Concept ACK for picking up the PR",
     "association": "MEMBER",
     "comments": 1,
     "first": "2026-09-28",
     "last": "2026-09-28"
    },
    {
     "login": "instagibbs",
     "stance": "question",
     "note": "asked whether replacement peer claims should be validated before evicting existing peers, and whether network data shows this is a real problem",
     "association": "MEMBER",
     "comments": 1,
     "first": "2026-09-30",
     "last": "2026-09-30"
    },
    {
     "login": "fametrano",
     "stance": "objection",
     "note": "pointed out that non-eviction test cases in p2p_blocksonly.py cannot fail and provided a diff fixing them",
     "association": "CONTRIBUTOR",
     "comments": 1,
     "first": "2026-10-02",
     "last": "2026-10-02"
    },
    {
     "login": "Bicaru20",
     "stance": "support",
     "note": "Concept ACK; suggested an additional test case and questioned eviction ordering for silent peers",
     "association": "CONTRIBUTOR",
     "comments": 3,
     "first": "2026-10-13",
     "last": "2026-10-13"
    }
   ],
   "derivation": "objection that needs a change, nobody has replied (fametrano)",
   "model_state": null,
   "corrections": [],
   "notes": "Added Bicaru20 with Concept ACK, a suggestion for unit test coverage in denialofservice_tests, and a question regarding eviction priority between inactive tx-relaying peers and active non-tx-relaying peers. Bicaru20's inline comment on logging format was treated as a nit."
  },
  "dependencies": {
   "depends_on": [],
   "enables": []
  },
  "categories": [
   {
    "name": "p2p",
    "member": true,
    "evidence": "Carries the P2P label and modifies peer eviction logic and connection management in src/net.cpp and src/net_processing.cpp.",
    "band": "P2",
    "reason_tag": "new feature",
    "score": 0.65,
    "factors": {
     "bug_severity": 1,
     "leverage": 1,
     "performance": 0,
     "security_stability": 1,
     "user_value": 2
    },
    "rationale": "Improves transaction relay topology by ensuring outbound full-relay slots are not occupied by peers that decline transaction relay. Addresses longstanding network health issues (#16418, #28371) where nodes could be left with too few transaction-relaying outbound connections."
   },
   {
    "name": "tests",
    "member": false,
    "evidence": "Test modifications are domain-specific tests for p2p outbound eviction rather than improvements to test infrastructure.",
    "band": "Unranked",
    "reason_tag": "test coverage",
    "score": 0.0,
    "factors": {
     "bug_severity": 1,
     "leverage": 1,
     "performance": 0,
     "security_stability": 1,
     "user_value": 2
    },
    "rationale": "The functional test and test framework updates directly verify p2p eviction behavior and do not constitute changes to generic test machinery."
   }
  ],
  "confidence": "high",
  "uncertainties": [],
  "needs": []
 },
 "cost_usd": 0.0,
 "source": {
  "record": "2026-10-14T01:24:45+00:00",
  "code": "2026-09-29T14:36:19+00:00",
  "judgments": 2
 }
}