{
 "number": 35558,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/35558",
 "title": "p2p: Prefill compact blocks",
 "author": "davidgumberg",
 "author_association": "MEMBER",
 "created_at": "2026-06-18T06:44:54Z",
 "updated_at": "2026-09-15T14:52:44Z",
 "age_days": 91,
 "draft": false,
 "labels": [
  "P2P"
 ],
 "milestone": null,
 "base": "master",
 "head_sha": "864895088b1e660297a46ac034ba1230f19b7f3f",
 "head_ref": "2025-11-13-0xB10C-prefill-rebase-binary-limit",
 "head_repo": "davidgumberg/bitcoin",
 "head_history": [
  {
   "t": "2026-07-03T00:37:06Z",
   "sha": "63757da199e9ee8d858909b4ffde98a98298abbd"
  },
  {
   "t": "2026-07-03T23:28:38Z",
   "sha": "9c3a0a566670ce18b625179151386456349ffc73"
  },
  {
   "t": "2026-07-14T21:52:25Z",
   "sha": "ab9fc736f0c1a15a7d675cffa73184ce9cbb2936"
  },
  {
   "t": "2026-07-14T23:34:38Z",
   "sha": "9f36a29393663bb2a70d0f0690ec30f2176f6ef6"
  },
  {
   "t": "2026-08-04T23:01:11Z",
   "sha": "864895088b1e660297a46ac034ba1230f19b7f3f"
  }
 ],
 "additions": 717,
 "deletions": 143,
 "changed_files": 16,
 "commit_count": 16,
 "size_bucket": "L",
 "mergeable_state": "clean",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "concept_ack": [
     {
      "login": "w0xlt",
      "url": "https://github.com/bitcoin/bitcoin/pull/35558#issuecomment-4739425253"
     },
     {
      "login": "ismaelsadeeq",
      "url": "https://github.com/bitcoin/bitcoin/pull/35558#issuecomment-4740957399"
     },
     {
      "login": "josibake",
      "url": "https://github.com/bitcoin/bitcoin/pull/35558#issuecomment-4741030804"
     },
     {
      "login": "edilmedeiros",
      "url": "https://github.com/bitcoin/bitcoin/pull/35558#issuecomment-4742097236"
     },
     {
      "login": "murchandamus",
      "url": "https://github.com/bitcoin/bitcoin/pull/35558#issuecomment-4743728397"
     },
     {
      "login": "0xB10C",
      "url": "https://github.com/bitcoin/bitcoin/pull/35558#pullrequestreview-4530717536"
     },
     {
      "login": "johnnyasantoss",
      "url": "https://github.com/bitcoin/bitcoin/pull/35558#pullrequestreview-4583332964"
     }
    ],
    "stale_ack": [
     {
      "login": "m4ycon",
      "url": "https://github.com/bitcoin/bitcoin/pull/35558#issuecomment-4995282022"
     },
     {
      "login": "s00ly",
      "url": "https://github.com/bitcoin/bitcoin/pull/35558#issuecomment-5040544280"
     }
    ]
   },
   "conflicts": [
    {
     "number": 35724,
     "title": "cmpctblock: Improve logging of `cmpctblock` message reconstruction statistics [part of prefill series]",
     "author": "davidgumberg"
    }
   ]
  }
 },
 "acks_parsed": {
  "w0xlt": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-06-18T07:55:01Z",
   "stale": false
  },
  "ismaelsadeeq": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-06-18T10:20:59Z",
   "stale": false
  },
  "josibake": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-06-18T10:28:44Z",
   "stale": false
  },
  "edilmedeiros": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-06-18T12:50:42Z",
   "stale": false
  },
  "murchandamus": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-06-18T15:49:58Z",
   "stale": false
  },
  "0xB10C": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-06-19T07:06:19Z",
   "stale": false
  }
 },
 "acks_tally": {
  "ack": 0,
  "stale_ack": 0,
  "concept_ack": 6,
  "approach_ack": 0,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 0,
  "changes_requested": 0,
  "distinct_reviewers": [
   "0xB10C",
   "andrewtoth",
   "edilmedeiros",
   "ismaelsadeeq",
   "johnnyasantoss",
   "josibake",
   "m4ycon",
   "murchandamus",
   "s00ly",
   "w0xlt"
  ]
 },
 "signals": {
  "needs_rebase": false,
  "ci_failed": false,
  "mergeable_state": "clean",
  "last_author_activity": "2026-08-04T23:02:45Z",
  "last_reviewer_activity": "2026-07-28T20:55:59Z",
  "last_reviewer": "m4ycon",
  "author_silent_days": 43,
  "waiting_on_author_days": 0,
  "days_since_update": 2
 },
 "refs": {
  "mentioned": [
   26755,
   35724,
   35727
  ],
  "depends_on": [],
  "fixes": [
   26755
  ],
  "linked_issues": [],
  "references": [
   {
    "number": 26755,
    "type": "pull",
    "state": "closed",
    "merged": false,
    "merged_at": null,
    "title": "p2p: cache compact block message to use for low bandwidth CMPCT_BLOCK"
   },
   {
    "number": 35724,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "cmpctblock: Improve logging of `cmpctblock` message reconstruction statistics [part of prefill series]"
   },
   {
    "number": 35727,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2026-07-21",
    "title": "blockencodings: fix extra transaction count"
   }
  ],
  "conflicts": [
   35724
  ]
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [
  "src/blockencodings.cpp",
  "src/blockencodings.h",
  "src/net.cpp",
  "src/net_processing.cpp"
 ],
 "body": "[quoted text omitted]\n\nThis is an implementation based on 0xB10C's [proposal][proposal] and [implementation][implementation] of prefilling CMPCTBLOCK messages with what we[^1] needed during CMPCTBLOCK reconstruction in the hopes of providing everything our peers will need to reconstruct without having to ask us for transactions.\n\nAlthough full support for receiving prefills is [implemented][cb-og-pr] in Bitcoin Core, the only prefills sent presently are coinbases. The goal of prefilling is to improve compact block reconstruction rates, which reduces the number of roundtrips needed to propagate blocks per-hop, which reduces the amount of time needed for blocks to propagate on the network, which mitigates selfish mining attacks by lowering the stale rate and the ratio $\u03b3$ of honest miners a selfish miner is able to recruit in a block race.[^2] The tradeoff of prefilling is that it uses a small amount of extra bandwidth and makes propagation slightly worse when the predictions are bad.\n\nMy primary contribution is limiting the prefill based on the connection's TCP window. Exceeding the boundary of the current TCP window will result in a ~[roundtrip][roundtrip] at the network layer,[^3] and any time a roundtrip is going to be incurred anyways, it would be [better][better] to let our peer tell us exactly what they are missing in a roundtrip instead of hazarding a guess, which risks sending redundant information.[^4]\n\n## Prefill do\n\nIn measurements I took from 2026-02-15 to 2026-03-16, a node receiving prefilled `CMPCTBLOCK`s limited to the TCP window size was able to reconstruct 89.7% of compact blocks received without a GETBLOCKTXN roundtrip, and a node receiving typical `CMPCTBLOCK`s with only coinbases prefilled was able to reconstruct 56.9% of blocks received without a GETBLOCKTXN roundtrip.[^5]\n\nThe mean prefill sent was 1,694.64 bytes and the median was 897 bytes. If all the bytes of every prefill were redundant [^6], the cost of prefilling 1,694.64 bytes would be 1.39 MiB per node in wasted bandwidth per day (counting both the sending and the receiving bandwidth for all 3 HB peers).\n\n## Prefill why\n\nThere are changes that are likely more effective at improving propagation times than prefilling, for example:\n- [Using a sketch instead of shortids][sketch-shortid] in CMPCTBLOCK messages\n- Using a UDP connection with FEC as [the FIBRE project does][the-fibre-project-does]\n- Sharing [block templates][block-templates]\n\nThe advantage of this approach is that it requires no protocol changes and is entirely backwards compatible with existing node software that has implemented the `CMPCTBLOCK` [protocol][protocol]. Concretely: An old version of Bitcoin Core that knows nothing about this PR can enjoy faster block reconstructions if it connects to a peer that prefills blocks. I think these benefits are worth the tradeoff of violating the layer cake and taking transport matters into our own hands.\n\n## Prefill what\n\n- The transactions which we were missing during reconstruction and received in a `GETBLOCKTXN->BLOCKTXN` round trip with our peer.\n- The transactions which were pulled from our extrapool during reconstruction.[^7]\n- Any transactions that were prefilled to us that we didn't already have in our mempool.\n\nThe reasons to like this heuristic are that it's simple, per-block rather than per-peer, makes sense on paper, and seems to be effective in practice.\n\n## Prefill when\n\nTo avoid having to generate unique CMPCTBLOCK messages for each of our peers, which might be costly[^8], we (lazily[^9]) build and cache 2 CMPCTBLOCK messages: one prefilled and one not prefilled.\n\nAt sending time we check the available bytes in our peer's TCP window, and if the total number of TCP windows occupied by the prefilled block is equal to the total number of windows occupied by the nonprefilled block, then we send the prefilled block.\n\n----\n\n## TCP Windows\n\nDiscussed in greater detail [elsewhere][elsewhere], I'll try to summarize here:\n\nIn [RFC 793][rfc-793], TCP was specified with receiver advertised window sizes because receivers allocate some buffer size to a given TCP connection, and this receiver advertised window represents the most **unacknowledged** data a receiver will process before dropping bytes on the ground or something awful like that. So the sender of a message over a TCP connection will only send up to the last acknowledged byte + the receiver's advertised window size in order to avoid filling up their peer's receive buffer.\n\nIt was later discovered that TCP was susceptible to [\"congestion collapse\"][congestion-collapse], which can probably describe any congestion feedback loop but in TCP is where packets being dropped due to congestion results in retransmissions that cause even more congestion. TCP implementers addressed this with \"congestion control\" algorithms which decide on the sending side to limit the number of bytes to send dynamically, based on how frequently packets are dropped on a TCP connection. For a more concrete account of various congestion control algorithms see [RFC 5681][rfc-5681]. A user's TCP implementation (typically in their OS kernel) will compute a window size dynamically for each TCP connection usually increasing as packets sent are ACKnowledged and decreasing when packets sent are dropped.\n\nComputed congestion control window sizes vary:\n- per-connection\n- over connection lifetime\n- with the congestion control algorithm used by the system TCP implementation\n- with user configuration of the TCP implementation.\n\nThere is not likely to be any way to guess or predict what the TCP window will be very effectively, and we must query the TCP implementation in order to learn what our connection window sizes are.\n\nThe usable window size is the smaller of the receiver advertised window and the sender computed congestion control window, but in practice the congestion control window is far smaller. In my observation node, the mean Bitcoin P2P congestion window observed was 17,360.52 bytes and the median was 14,480 bytes.\n\n[^1]: 'We' refers to the Royal Node.\n[^2]: (2013) Eyal and Sirer *Majority is not Enough* (pg. 8) https://arxiv.org/pdf/1311.0243 The claim that lowering block propagation times lowers \u03b3 probably needs serious analysis, but my hand-waving argument is that the faster public network-wide block propagation is, the more expensive any proportional propagation time advantage over the public network becomes, and \u03b3 is a function of propagation time advantage.\n[^3]: A network layer roundtrip will be faster than an application layer roundtrip, although probably not by much for most connections. Since at the application layer there will be some time your message spends waiting to be processed by your peer, at least for peers that use single-threaded message processing like Bitcoin Core does presently.\n[^4]: In practice exceeding the TCP window is ~not quite as bad as I've implied here and in the delving post: because the window is sliding, once the first 1.5 round-trips are completed there is a continuous stream as ACKnowledgements for the oldest segments arrive and the newest segments are fired out. The effect of this more precisely is that if a message exceeds a window boundary, the minimum travel time of the message becomes 1.5 round-trip-time (RTT) instead of 0.5 RTT and the throughput limit of the connection becomes $\\text{window size} / \\text{RTT}$. I am working on a more complete write-up that takes this more precise cost into consideration, but I think approximating it as a ~round trip is reasonable.\n[^5]: In reality, not all of the prefill is redundant otherwise prefilling would not be very useful. In my observation node that received prefilled compact blocks, the mean redundant prefill bytes was 865.62 bytes/block. 2 HB announcements will always be redundant so: 1.17 MiB per node in wasted bandwidth per day if one CMPCTBLOCK announcement only has 865.62 redundant bytes.\n[^6]: I will share a write-up describing my full experimental setup and data soon. It was mostly identical to the set up described here: https://delvingbitcoin.org/t/stats-on-compact-block-reconstructions/1052/34 I had one node running a prefilling branch, and another node set up to only receive CMPCTBLOCK messages from the prefilling node. My infrastructure as code observation set up: https://github.com/davidgumberg/prefill-research and the script I used to analyze the results: https://radicle.network/nodes/iris.radicle.network/rad:z37pH1UAxFvazXnfAMS5qbcUjQaP6/tree/leave/scripts/prefill.py\n[^7]: The reason to pluck from the extrapool is because it is very likely to differ between nodes.\n[^8]: But maybe there is some cost here that is worth trading off, it's not something I've explored.\n[^9]: This is based on andrewtoth's #26755.\n\n[proposal]: https://delvingbitcoin.org/t/stats-on-compact-block-reconstructions/1052/24\n[cb-og-pr]: https://github.com/bitcoin/bitcoin/pull/8068\n[sketch-shortid]: https://delvingbitcoin.org/t/stats-on-compact-block-reconstructions/1052/30\n[the-fibre-project-does]: https://github.com/bitcoinfibre/bitcoinfibre/blob/master/src/udprelay.cpp\n[roundtrip]: https://en.wikipedia.org/wiki/TCP_window_scale_option#TCP_windows\n[better]: https://delvingbitcoin.org/t/stats-on-compact-block-reconstructions/1052/34\n[rfc-793]: https://www.rfc-editor.org/rfc/rfc793.html#section-2.6\n[elsewhere]: https://delvingbitcoin.org/t/stats-on-compact-block-reconstructions/1052/34\n[congestion-collapse]: https://dl.acm.org/doi/epdf/10.1145/52325.52356\n[rfc-5681]: https://datatracker.ietf.org/doc/html/rfc5681\n[block-templates]: https://delvingbitcoin.org/t/sharing-block-templates/1906\n[implementation]: https://github.com/0xB10C/bitcoin/tree/2025-03-prefill-cmpctblocks\n[protocol]: https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki\n\n[quoted text omitted]",
 "commits": [
  {
   "sha": "a01d69f8ec967b86aaa1717393ecd312e9c08bfd",
   "date": "2026-08-04T20:00:44Z",
   "message": "cmpctblock: log: debuglevel=trace print TXID's of all missing tx'es.\n\nIt doesn't make that much sense to log here only when there's a few\ntransactions, since either a user is interested in what tx'es caused\nreconstruction to fail or they aren't, so log all txid's and this a\ntrace-level log message."
  },
  {
   "sha": "78715aab9475b25bb10c82d2e8c1c827560b76ed",
   "date": "2026-08-04T20:56:43Z",
   "message": "cmpctblock: log: Log extrapool separately from mempool\n\nPreviously, in the log message and in the `InitData()` logic, the\nmempool was treated as a superset that includes the extra pool, it makes\nmore sense to treat them as separate pools.\n\nThis commit also separates the reconstruction critical logic of the\nfound transaction count from the logging specific counting of tx\nsources."
  },
  {
   "sha": "43bc34af72bf09afb14b223fde81dac583956020",
   "date": "2026-08-04T21:00:48Z",
   "message": "cmpctblock: log: Print sizes of all tx types and prefill redundancies\n\nAt block reconstruction time, log the counts and sizes of prefilled\ntransactions, transactions pulled from the mempool, transactions from\nthe extrapool, and missing transactions that were acquired via\n`GETBLOCKTXN`.\n\nAlso log the count and size of prefilled transactions that were\nredundant and their source (mempool or extrapool)."
  },
  {
   "sha": "e02a06d8a9036265d1eea8444957577ebc683883",
   "date": "2026-08-04T22:53:42Z",
   "message": "build: Bump minimum Windows to >= Windows 1703\n\nThis is needed for the use of the `SIO_TCP_INFO` API.\n\nhttps://learn.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-tcp_info_v0#requirements"
  },
  {
   "sha": "75c5582597e2096d8c1be73b07f645ac107e0128",
   "date": "2026-08-04T22:53:42Z",
   "message": "sock: Add TCPInfo wrapper for getting socket info."
  },
  {
   "sha": "63cd12c2a477b4d7160561be74d4aeaed40443dd",
   "date": "2026-08-04T22:53:42Z",
   "message": "sock: TCPInfo::GetTCPWindowSize()"
  },
  {
   "sha": "6252c9a5be10beae929fc85d42ac391c96ba3a23",
   "date": "2026-08-04T22:53:42Z",
   "message": "sock: Add GetOSBytesQueued"
  },
  {
   "sha": "d840c9e8d362d016bb90acc394af782aa9cf4bb1",
   "date": "2026-08-04T22:53:42Z",
   "message": "net: Add Transport::GetMessageSize() for serialized msg sizes\n\nThis is unused here, but will be useful for estimating the serialized\nbytes in the application send queue."
  },
  {
   "sha": "fc55202cd4df0d88607cf2fb403036e2372e217a",
   "date": "2026-08-04T22:53:42Z",
   "message": "net: Add GetSendQueueSize()\n\nNot used yet, but will be useful for deciding whether or not prefilling\na CMPCTBLOCK will cause the current message queue to overflow a TCP\nwindow boundary."
  },
  {
   "sha": "67723d9be3bd13178c541241a5a4b425b3f28e9c",
   "date": "2026-08-04T22:53:42Z",
   "message": "net: Add CNode::WindowBytesTotalAndAvailable()"
  },
  {
   "sha": "e53cad585e70da8670af18cf43b3b1efca730fcb",
   "date": "2026-08-04T22:53:42Z",
   "message": "p2p: refactor: Stuff m_most_recent* into a struct"
  },
  {
   "sha": "f255b4ea46bc5291e2be810c6afc7531f5d4d4a4",
   "date": "2026-08-04T22:53:42Z",
   "message": "p2p: Cache cmpct_block_msg for low bandwidth relay.\n\nThis commit is drawn from the closed #26755.\n(https://github.com/bitcoin/bitcoin/pull/26755)\n\nThis also changes `std::launch::deferred` to `std::launch::async` since\nwe are likely going to use this result very soon if someone has\nrequested HB blocks from us, and if no one has, then performance here is\nnot that critical.\n\nCo-authored-by: Andrew Toth <andrewstoth@gmail.com"
  },
  {
   "sha": "ac7054b4ef7b744b8bba679b2b0064ad284f556d",
   "date": "2026-08-04T22:53:42Z",
   "message": "net: refactor: Move common logic into SendCompactBlock\n\nAlso one non-refactor change which is setting the `pIndexBestHeaderSent`\non the `SendMessages` CMPCTBLOCK announcement fallback."
  },
  {
   "sha": "a921698912237442eab1ce24d6de6872e85936cd",
   "date": "2026-08-04T22:53:42Z",
   "message": "net: Protect PeerHasHeader from nullptr"
  },
  {
   "sha": "b16bf611b9b2cb494fe982747d7a614ddaad8eb5",
   "date": "2026-08-04T23:01:02Z",
   "message": "p2p: keep track of cmpctblock prefill candidates\n\nKeep track of the block position of transactions that we didn't have in\nour mempool while reconstructing this compact block. We can use these to\npredictively prefill transactions in our compact block annoucements.\nThis includes transactions that:\n- were prefilled by the cmpctblock announcer and were not in our mempool\n- transactions we found in our extra_pool (but not mempool)\n- transactions we had to request from the announcer"
  },
  {
   "sha": "864895088b1e660297a46ac034ba1230f19b7f3f",
   "date": "2026-08-04T23:01:03Z",
   "message": "p2p: prefill our compact blocks with candidates\n\nUpon receving a compact block, we keep a set of prefill candidates\n(transactions we didn't have in our mempool) for this block. When\nconstructing a compact block, we try to use these candiates to prefill\nour compact block annocement of this block."
  }
 ],
 "timeline": [
  {
   "t": "2026-06-18T07:55:01Z",
   "kind": "comment",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "text": "Concept ACK"
  },
  {
   "t": "2026-06-18T10:20:59Z",
   "kind": "comment",
   "who": "ismaelsadeeq",
   "assoc": "MEMBER",
   "text": "Concept ACK.\n\nCurious to see also **Prefill Who** section.\n\n[quoted text omitted]\nThese transactions in the extrapool were sent to us by some peers, no? We can reduce a bit of redundancy by not sending them again to the peers that announced them to us."
  },
  {
   "t": "2026-06-18T10:28:44Z",
   "kind": "comment",
   "who": "josibake",
   "assoc": "MEMBER",
   "text": "Concept ACK\n\nBased on prior discussions we've had about this, very excited to see it come to life. I have not looked at the code yet, but after reading the PR description (very well done, btw), I strongly agree that the simplicity and backwards compatibility of the approach make this a very strong proposal."
  },
  {
   "t": "2026-06-18T12:50:42Z",
   "kind": "comment",
   "who": "edilmedeiros",
   "assoc": "CONTRIBUTOR",
   "text": "Concept ACK"
  },
  {
   "t": "2026-06-18T15:49:58Z",
   "kind": "comment",
   "who": "murchandamus",
   "assoc": "MEMBER",
   "text": "Concept ACK\n\nVery excited to see this PR."
  },
  {
   "t": "2026-06-19T06:58:22Z",
   "kind": "review_comment",
   "who": "0xB10C",
   "assoc": "MEMBER",
   "path": "src/net_processing.cpp",
   "commit": "f610cdd2a6d3aa6de8de8cc20af3664277bba07d",
   "in_reply_to": null,
   "text": "Running this PR and observing this in the logs should give us information about how often we can prefill."
  },
  {
   "t": "2026-06-19T07:02:02Z",
   "kind": "review_comment",
   "who": "0xB10C",
   "assoc": "MEMBER",
   "path": "src/blockencodings.cpp",
   "commit": "f610cdd2a6d3aa6de8de8cc20af3664277bba07d",
   "in_reply_to": null,
   "text": "I'm not too sure about logging this for all required transactions in a non-test setting (which might be a few thousands). Could this cause log rate-limiting? Maybe a good use for the `trace` log level?"
  },
  {
   "t": "2026-06-19T07:06:19Z",
   "kind": "review",
   "who": "0xB10C",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "f610cdd2a6d3aa6de8de8cc20af3664277bba07d",
   "text": "Concept ACK.\n\nAgain, thanks for picking this idea up and moving it closer to the finish line.\n\nAn idea mentioned in the delving post was to log information about wasted prefill bandwidth on the receiving side. How many transactions were received that we didn't use? How many extra bytes did we receive? This doesn't have to happen in this PR, but would probably good to have before this is reaches broader deployment on mainnet.\n\nOnce merged: I've been thinking about how I could test the effect on mainnet once this is deployed. One idea would be to run a node that's patched to specifically NOT use anything prefilled besides the coinbase and compare it's reconstruction performance to the other mainnet nodes. Additionally, keeping track of what share of blocks come with more than a coinbase prefilled and measuring their reconstruction performance would be interesting."
  },
  {
   "t": "2026-06-19T13:56:45Z",
   "kind": "comment",
   "who": "edilmedeiros",
   "assoc": "CONTRIBUTOR",
   "text": "[quoted text omitted]\n\nThis is probably a good idea even before merging this, maybe there is some fine tuning we can find.\n\ncc @m4ycon"
  },
  {
   "t": "2026-06-26T23:56:30Z",
   "kind": "review_comment",
   "who": "johnnyasantoss",
   "assoc": "NONE",
   "path": "src/net.cpp",
   "commit": "f610cdd2a6d3aa6de8de8cc20af3664277bba07d",
   "in_reply_to": null,
   "text": "nit: this assert is not needed here and elsewhere in this file (feel free to ignore)\nhttps://github.com/bitcoin/bitcoin/blob/e1290ce7f74b50f99932e7b83e414dec2732a8b9/doc/developer-notes.md?plain=1#L976-L979"
  },
  {
   "t": "2026-06-27T00:21:29Z",
   "kind": "review_comment",
   "who": "johnnyasantoss",
   "assoc": "NONE",
   "path": "src/net.cpp",
   "commit": "f610cdd2a6d3aa6de8de8cc20af3664277bba07d",
   "in_reply_to": null,
   "text": "```suggestion\n    auto send_state = WITH_LOCK(m_send_mutex, return m_send_state);\n```\nSince we are just reading the `send_state` why not prefer WITH_LOCK?"
  },
  {
   "t": "2026-06-27T01:53:58Z",
   "kind": "review",
   "who": "johnnyasantoss",
   "assoc": "NONE",
   "state": "COMMENTED",
   "commit": "f610cdd2a6d3aa6de8de8cc20af3664277bba07d",
   "text": "f610cdd2a6d3aa6de8de8cc20af3664277bba07d utACK\n\nwill test it locally and gather debug logs.\n\nContext: 1) I'm not cpp programmer. 2) we (@vinteumorg folks and I) did a deepdive on compact block relay BIP and other resources and then reviewed this PR together.\n\nPS: add context"
  },
  {
   "t": "2026-06-27T18:05:08Z",
   "kind": "review_comment",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "path": "src/net_processing.cpp",
   "commit": "f610cdd2a6d3aa6de8de8cc20af3664277bba07d",
   "in_reply_to": null,
   "text": "I think we can hoist `cb_fut` and `prefilled_cb_fut` out and copy the shared futures while `m_most_recent_block_mutex` is held, then release the lock for the rest of this method.\nThe only other thing we need is `m_most_recent_pow_block.hash` below, but we can get that via `pindex->GetBlockHash()` instead."
  },
  {
   "t": "2026-06-27T19:23:46Z",
   "kind": "review_comment",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "path": "src/net_processing.cpp",
   "commit": "63757da199e9ee8d858909b4ffde98a98298abbd",
   "in_reply_to": null,
   "text": "style nit: no hungarian notation. Also, please be consistent in declaration and implementation of parameters. Some places are putting the ref or pointer marker next to the variable name, but they should all be next to the type (`CNode& node` instead of `CNode &node`).\n\n```suggestion\nbool PeerManagerImpl::SendCompactBlock(CNode& node, const CBlockIndex* block_index)\n```"
  },
  {
   "t": "2026-06-30T18:25:15Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/blockencodings.cpp",
   "commit": "f610cdd2a6d3aa6de8de8cc20af3664277bba07d",
   "in_reply_to": 3440801043,
   "text": "[quoted text omitted]\n\n Ah! Great idea! Pushing an update that does this...\n\n[quoted text omitted]\n Yeah I kind of agree, to me it just didn't make sense to log only if there are 5 or fewer, it seems either all of them should be logged or none.\n\n[quoted text omitted]\nTrace and Debug level logs are not rate limited:\n\nhttps://github.com/bitcoin/bitcoin/blob/dc282ff31d1cc97507530a541d9cec8a8f6a6ef4/src/util/log.h#L132-L140"
  },
  {
   "t": "2026-07-03T00:37:06Z",
   "kind": "force_push",
   "who": "davidgumberg",
   "commit": "63757da199e9ee8d858909b4ffde98a98298abbd"
  },
  {
   "t": "2026-07-03T00:37:57Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "f610cdd2a6d3aa6de8de8cc20af3664277bba07d",
   "in_reply_to": 3484649149,
   "text": "I didn't know that! thanks, taken."
  },
  {
   "t": "2026-07-03T00:38:09Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "f610cdd2a6d3aa6de8de8cc20af3664277bba07d",
   "in_reply_to": 3484712027,
   "text": "Good catch, fixed, thank you."
  },
  {
   "t": "2026-07-03T00:38:14Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/net_processing.cpp",
   "commit": "f610cdd2a6d3aa6de8de8cc20af3664277bba07d",
   "in_reply_to": 3486512370,
   "text": "Nice! Much better to not hold a lock that prevents block updates while doing syscalls!!"
  },
  {
   "t": "2026-07-03T00:39:17Z",
   "kind": "comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "text": "Thanks to reviewers for feedback, I've pushed to address.\n\n----\n\n[quoted text omitted]\nEven if a peer has sent us a transaction that ends up in our extrapool, they may not have it in their mempool now since:\n\n1. It might have been RBF'ed. (good chance this is how it ends up in your extra pool)\n2. It might have been evicted.\n\nThe other problem with this that I see would be the cost in implementation complexity and in node resources of tracking per-peer, and potentially creating new CMPCTBLOCK's per-peer. The current branch is very conservative in only generating two candidate CMPCTBLOCK messages, one prefilled, and one not prefilled, as the working assumption is that it would be bad for performance to have to generate unique CMPCTBLOCK messages for each peer, and because of the way CMPCTBLOCK serialization works, adding a single prefilled transaction unfortunately means having to reserialize the whole thing, since the short-txid has to be removed, and the differential index for the next prefill would have to be changed.\n\nThe assumption that per-peer prefills would be too expensive might be wrong, but needs to be investigated. Empirically in my observations, I should point out that of the redundant prefill data received by the prefill-receiving node, 85% was stuff that was already in the prefill-receiving node's extra-pool.\n\n-----\n\n[quoted text omitted]\nThat's a great point, I had logic for this in my observation nodes, but I've incorporated the changes into this PR.\n\n----"
  },
  {
   "t": "2026-07-03T16:57:13Z",
   "kind": "review_comment",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "path": "src/net_processing.cpp",
   "commit": "864895088b1e660297a46ac034ba1230f19b7f3f",
   "in_reply_to": null,
   "text": "I don't think we should be switching the serialization from `std::launch::deferred` to `std::launch::async`. The latter spawns a new thread and serializes message eagerly, while the former just defers the serialization lazily until something calls `get()` on the future.\n\nSpawning threads is harder to reason about here as well. There can be lifetime issues introduced.\n\nEdit: Hmm I see from the commit message this is intentional. I suppose it doesn't introduce any lifetime issues since we're just copying shared_ptrs. But, I think the main benefit was that we serialize the message once for all our peers, instead of having to reserialize for each. With prefilling it might make sense to also do that eagerly in a background thread."
  },
  {
   "t": "2026-07-03T16:59:41Z",
   "kind": "review_comment",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "path": "src/net_processing.cpp",
   "commit": "864895088b1e660297a46ac034ba1230f19b7f3f",
   "in_reply_to": null,
   "text": "When will the block hash in `prefill_candidates` differ from `hash` above? Can these be merged?"
  },
  {
   "t": "2026-07-03T17:02:42Z",
   "kind": "review_comment",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "864895088b1e660297a46ac034ba1230f19b7f3f",
   "in_reply_to": null,
   "text": "We log `window_size` and `bytes_available` here, but we also log them on the call side. Can we remove one of the logs?"
  },
  {
   "t": "2026-07-03T17:17:53Z",
   "kind": "review_comment",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "path": "src/blockencodings.h",
   "commit": "864895088b1e660297a46ac034ba1230f19b7f3f",
   "in_reply_to": null,
   "text": "I don't think we should seed with the coinbase here. In that case, the check in net_processing for `prefill_candidates.size() > 0` is always true, so we will always go through the prefill path and do all the syscalls even for the current behavior of always prefilling only the coinbase. We should only bother with that logic if we have at least one *non-coinbase* prefill tx."
  },
  {
   "t": "2026-07-03T21:06:13Z",
   "kind": "review_comment",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "ab9fc736f0c1a15a7d675cffa73184ce9cbb2936",
   "in_reply_to": null,
   "text": "Here and in `GetMessageSize` above, we should take `m_send_mutex` lock and return the value if `send_state != SendState::v1`, and then return the fallback after releasing the lock. That way we don't take and release the lock multiple times."
  },
  {
   "t": "2026-07-03T21:22:27Z",
   "kind": "review_comment",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "path": "src/blockencodings.cpp",
   "commit": "9f36a29393663bb2a70d0f0690ec30f2176f6ef6",
   "in_reply_to": null,
   "text": "This is a use-after-free. We need to get the size before we reset it 3 lines above."
  },
  {
   "t": "2026-07-03T21:31:22Z",
   "kind": "review_comment",
   "who": "andrewtoth",
   "assoc": "MEMBER",
   "path": "src/blockencodings.cpp",
   "commit": "9c3a0a566670ce18b625179151386456349ffc73",
   "in_reply_to": null,
   "text": "Also need `prefilled_size += tx_size;`\nWe don't increment/decrement `extra_size` either. Seems like an oversight?"
  },
  {
   "t": "2026-07-03T22:33:04Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/blockencodings.cpp",
   "commit": "9f36a29393663bb2a70d0f0690ec30f2176f6ef6",
   "in_reply_to": 3521879984,
   "text": "Thanks for catching, sorry the quality of this logging commit was low when I pushed it."
  },
  {
   "t": "2026-07-03T22:39:05Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/blockencodings.cpp",
   "commit": "9c3a0a566670ce18b625179151386456349ffc73",
   "in_reply_to": 3521900074,
   "text": "Thanks for catching, sorry this went out broken."
  },
  {
   "t": "2026-07-03T22:43:12Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/blockencodings.cpp",
   "commit": "9f36a29393663bb2a70d0f0690ec30f2176f6ef6",
   "in_reply_to": 3521879984,
   "text": "Also this probably should've been caught by a sanitizer during testing, I'll investigate."
  },
  {
   "t": "2026-07-03T23:28:38Z",
   "kind": "force_push",
   "who": "davidgumberg",
   "commit": "9c3a0a566670ce18b625179151386456349ffc73"
  },
  {
   "t": "2026-07-03T23:28:46Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/net_processing.cpp",
   "commit": "63757da199e9ee8d858909b4ffde98a98298abbd",
   "in_reply_to": 3486625381,
   "text": "Fixed, thank you."
  },
  {
   "t": "2026-07-14T21:52:25Z",
   "kind": "force_push",
   "who": "davidgumberg",
   "commit": "ab9fc736f0c1a15a7d675cffa73184ce9cbb2936"
  },
  {
   "t": "2026-07-14T22:25:00Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/blockencodings.cpp",
   "commit": "9f36a29393663bb2a70d0f0690ec30f2176f6ef6",
   "in_reply_to": 3521879984,
   "text": "Hmm, looking back at this I can't think of a good way to test collisions in unit tests, but I think this would have been caught by fuzzing."
  },
  {
   "t": "2026-07-14T23:34:02Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/net_processing.cpp",
   "commit": "864895088b1e660297a46ac034ba1230f19b7f3f",
   "in_reply_to": 3521114497,
   "text": "Yeah, sorry if it's weird to combine both changes in one commit, I can split up if you think that makes sense. OK to mark this resolved or is there still a concern?"
  },
  {
   "t": "2026-07-14T23:34:38Z",
   "kind": "force_push",
   "who": "davidgumberg",
   "commit": "9f36a29393663bb2a70d0f0690ec30f2176f6ef6"
  },
  {
   "t": "2026-07-14T23:34:47Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "ab9fc736f0c1a15a7d675cffa73184ce9cbb2936",
   "in_reply_to": 3521842667,
   "text": "Taken thanks, this also made me realize `GetMessageHeaderSize` shouldn't be virtual, public, or take a lock, so fixed that as well."
  },
  {
   "t": "2026-07-14T23:34:58Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/blockencodings.h",
   "commit": "864895088b1e660297a46ac034ba1230f19b7f3f",
   "in_reply_to": 3521178456,
   "text": "Great catch, thank you, I took this by changing the check to be `prefill_candidates.size() > 1`"
  },
  {
   "t": "2026-07-14T23:35:10Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/net.cpp",
   "commit": "864895088b1e660297a46ac034ba1230f19b7f3f",
   "in_reply_to": 3521130932,
   "text": "Ok, I removed it on the caller side."
  },
  {
   "t": "2026-07-14T23:35:19Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/net_processing.cpp",
   "commit": "864895088b1e660297a46ac034ba1230f19b7f3f",
   "in_reply_to": 3521122201,
   "text": "I have to think about this a little more, but right now the issue is that we'll update the prefill candidates on reconstruction, but the block might still fail somewhere in `ProcessBlock()`:\n\nhttps://github.com/bitcoin/bitcoin/blob/9f36a29393663bb2a70d0f0690ec30f2176f6ef6/src/net_processing.cpp#L3659-L3667"
  },
  {
   "t": "2026-07-16T18:28:12Z",
   "kind": "comment",
   "who": "m4ycon",
   "assoc": "NONE",
   "text": "tACK 9c3a0a5\n\nFor the past week I\u2019ve been running this PR and collecting some data. I created a repository to show some statistics about how effective this change is, by trying to show some numbers that could answer my research questions (RQs).\n\nFor those who don't want to get too deep into this, I recommend just taking a look at RQ1.5 and RQ2.2 -- readme points where they are.\n\nRepository: https://github.com/m4ycon/prefill-compact-blocks-review\n\nI still plan to run for about a week or two, to see if anything changes (I suppose not). And to implement a good suggestion by @johnnyasantoss, to run a \"Node-C\" from a second machine to see if it makes some difference on RQs -- current setup is running two nodes on the same machine.\n\n[quoted text omitted]"
  },
  {
   "t": "2026-07-20T20:03:08Z",
   "kind": "review_comment",
   "who": "m4ycon",
   "assoc": "NONE",
   "path": "src/blockencodings.cpp",
   "commit": "864895088b1e660297a46ac034ba1230f19b7f3f",
   "in_reply_to": null,
   "text": "Maybe I'm missing something here. Just a minor issue affecting logs, but why inside this condition `!pool->exists(tx_wtxid)` which means \"not in mempool\", there's a mempool variable `redundant_prefilled_mp_...` handling? Wouldn't this else hold cases like \"not in mempool and not in extrapool\"?"
  },
  {
   "t": "2026-07-22T00:42:06Z",
   "kind": "comment",
   "who": "s00ly",
   "assoc": "NONE",
   "text": "tACK 9f36a29393663bb2a70d0f0690ec30f2176f6ef6\n\nBuilt and ran on Linux x86_64 (gcc 13.3, RelWithDebInfo, `-DBUILD_GUI=OFF -DENABLE_IPC=OFF`):\n\n- Full unit test suite: pass (incl. `blockencodings_tests`, 8 cases)\n- `p2p_compactblocks.py`, `p2p_compactblocks_blocksonly.py`, `p2p_compactblocks_hb.py` (v1 + v2 transport): all pass\n\nI also rebased this onto current master (70d9ec7f3d45), resolving the conflicts with #35727's `TxSource` refactor: https://github.com/s00ly/bitcoin/tree/35558-rebase-2026-07-22 (head `fc4355a0cf7e`). The same test battery passes on the rebased branch. Feel free to cherry-pick it or treat it as reference only.\n\nRebase notes (worth author/maintainer eyes):\n\n1. **\"cmpctblock: log: Log extrapool separately from mempool\"**: ported the disjoint counting onto master's `TxSource` enum. Collision decrements are now attributed by source: `EXTRA` decrements `extra_count`, otherwise `mempool_count`.\n2. **\"cmpctblock: log: Print sizes of all tx types and prefill redundancies\"**: applied the same attribution to the debug-log size counters \u2014 the original commit subtracted `extra_size` unconditionally on collision; the rebased version subtracts from the pool the slot actually came from. Log numbers only; flagging in case the unconditional version was deliberate.\n3. Updated one expectation in `ReceiveWithExtraTransactions` (`GetMempoolCount()` 1U -> 0U after the MEMPOOL-slot collision) to match this PR's intended disjoint semantics; folded into commit 2.\n4. **\"p2p: keep track of cmpctblock prefill candidates\"**: kept both `TxSource::EXTRA` and `prefill_candidates.insert` in the extrapool-hit path.\n\n(Also noting the LLM-linter typos are still present: `annoucements` x4, `recontruct` x1.)\n\nrange-diff vs 9f36a2939\n\n```\n 1:  7fac2d165 =  1:  a353ddab6 cmpctblock: log: debuglevel=trace print TXID's of all missing tx'es.\n 2:  35b79db9f <  -:  --------- cmpctblock: log: Log extrapool separately from mempool\n -:  --------- >  2:  f68c64478 cmpctblock: log: Log extrapool separately from mempool\n 3:  cef79baeb !  3:  00d9b871a cmpctblock: log: Print sizes of all tx types and prefill redundancies\n    @@ src/blockencodings.cpp: ReadStatus PartiallyDownloadedBlock::InitData(const CBlo\n          // Because well-formed cmpctblock messages will have a (relatively) uniform distribution\n     @@ src/blockencodings.cpp: ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c\n                      txn_available[idit->second] = txit->GetSharedTx();\n    -                 have_txn[idit->second]  = true;\n    +                 tx_source[idit->second] = TxSource::MEMPOOL;\n                      mempool_count++;\n    --            } else {\n     +                if (debug_log) {\n     +                    mempool_size += txn_available[idit->second]->ComputeTotalSize();\n     +                }\n    -+            } else if (txn_available[idit->second]) {\n    +             } else if (tx_source[idit->second] != TxSource::COLLIDED) {\n                      // If we find two mempool txn that match the short id, just request it.\n                      // This should be rare enough that the extra bandwidth doesn't matter,\n                      // but eating a round-trip due to FillBlock failure would be annoying\n    --                if (txn_available[idit->second]) {\n    --                    txn_available[idit->second].reset();\n    --                    mempool_count--;\n     +                if (debug_log) {\n     +                    mempool_size -= txn_available[idit->second]->ComputeTotalSize();\n    -                 }\n    -+                txn_available[idit->second].reset();\n    -+                mempool_count--;\n    -             }\n    -         }\n    -         // Though ideally we'd continue scanning for the two-txn-match-shortid case,\n    ++                }\n    +                 txn_available[idit->second].reset();\n    +                 mempool_count--;\n    +                 tx_source[idit->second] = TxSource::COLLIDED;\n     @@ src/blockencodings.cpp: ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c\n                      txn_available[idit->second] = extra_txn[i].second;\n    -                 have_txn[idit->second]  = true;\n    +                 tx_source[idit->second] = TxSource::EXTRA;\n                      extra_count++;\n     +                if (debug_log) {\n     +                    extra_size += txn_available[idit->second]->ComputeTotalSize();\n     +                }\n    -             } else {\n    +             } else if (tx_source[idit->second] != TxSource::COLLIDED &&\n    +                        txn_available[idit->second]->GetWitnessHash() != extra_txn[i].second->GetWitnessHash()) {\n                      // If we find two mempool/extra txn that match the short id, just\n    -                 // request it.\n     @@ src/blockencodings.cpp: ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c\n    +                 // but eating a round-trip due to FillBlock failure would be annoying\n    +                 // Note that we don't want duplication between extra_txn and mempool to\n                      // trigger this case, so we compare witness hashes first\n    -                 if (txn_available[idit->second] &&\n    -                         txn_available[idit->second]->GetWitnessHash() != extra_txn[i].second->GetWitnessHash()) {\n    -+                    if (debug_log) {\n    ++                if (debug_log) {\n    ++                    if (tx_source[idit->second] == TxSource::EXTRA) {\n     +                        extra_size -= txn_available[idit->second]->ComputeTotalSize();\n    ++                    } else {\n    ++                        mempool_size -= txn_available[idit->second]->ComputeTotalSize();\n     +                    }\n    -                     txn_available[idit->second].reset();\n    ++                }\n    +                 txn_available[idit->second].reset();\n    +                 if (tx_source[idit->second] == TxSource::EXTRA) {\n                          extra_count--;\n    -                 }\n     @@ src/blockencodings.cpp: ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<\n              const uint256 hash{block.GetHash()};\n              uint32_t tx_missing_size{0};\n 4:  7c92df3c1 =  4:  1b8951e19 build: Bump minimum Windows to >= Windows 1703\n 5:  f1c57190d =  5:  fddf657fb sock: Add TCPInfo wrapper for getting socket info.\n 6:  929785af6 =  6:  f449fc156 sock: TCPInfo::GetTCPWindowSize()\n 7:  91a625170 =  7:  fd4b0c6f6 sock: Add GetOSBytesQueued\n 8:  fa39ff202 =  8:  e3d5f0478 net: Add Transport::GetMessageSize() for serialized msg sizes\n 9:  4d6e73c88 =  9:  b4ffd1a20 net: Add GetSendQueueSize()\n10:  682d22272 = 10:  1af76c94f net: Add CNode::WindowBytesTotalAndAvailable()\n11:  d399ab14c = 11:  da768df72 p2p: refactor: Stuff m_most_recent* into a struct\n12:  d73d76c9a = 12:  a7adf1d06 p2p: Cache cmpct_block_msg for low bandwidth relay.\n13:  09579eeb1 = 13:  c450c319d net: refactor: Move common logic into SendCompactBlock\n14:  b6111762b = 14:  9c7b1bc82 net: Protect PeerHasHeader from nullptr\n15:  70c2b71d9 ! 15:  ad98503dc p2p: keep track of cmpctblock prefill candidates\n    @@ src/blockencodings.cpp: ReadStatus PartiallyDownloadedBlock::InitData(const CBlo\n          // Calculate map of txids -> positions and check mempool to see what we have (or don't)\n     @@ src/blockencodings.cpp: ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c\n              if (idit != shorttxids.end()) {\n    -             if (!have_txn[idit->second]) {\n    +             if (tx_source[idit->second] == TxSource::NONE) {\n                      txn_available[idit->second] = extra_txn[i].second;\n     +                prefill_candidates.insert(idit->second);\n    -                 have_txn[idit->second]  = true;\n    +                 tx_source[idit->second] = TxSource::EXTRA;\n                      extra_count++;\n                      if (debug_log) {\n     @@ src/blockencodings.cpp: bool PartiallyDownloadedBlock::IsTxAvailable(size_t index) const\n16:  9f36a2939 = 16:  fc4355a0c p2p: prefill our compact blocks with candidates\n```"
  },
  {
   "t": "2026-07-27T22:58:07Z",
   "kind": "review_comment",
   "who": "m4ycon",
   "assoc": "NONE",
   "path": "src/blockencodings.cpp",
   "commit": "864895088b1e660297a46ac034ba1230f19b7f3f",
   "in_reply_to": null,
   "text": "It seems that there's some problem with `prefilled_size` in this log. Using my recent logs (run against the most recent version of this PR, 9f36a29), the value is **always** zero. Which could not be true in any scenario as coinbase is always prefilled. I couldn't find any assignment to it, probably it's a simple fix."
  },
  {
   "t": "2026-07-27T23:44:55Z",
   "kind": "review",
   "who": "m4ycon",
   "assoc": "NONE",
   "state": "COMMENTED",
   "commit": "9f36a29393663bb2a70d0f0690ec30f2176f6ef6",
   "text": "I was about to update datasets on my [analysis repo](https://github.com/m4ycon/prefill-compact-blocks-review) (see [this](https://github.com/bitcoin/bitcoin/pull/35558#issuecomment-4995282022) for more context), but I realized that drawing conclusions from logs is unreliable if they are not 100% accurate -- some questions could still be answered, but not all. I'll take a break from those tests until they are fixed.\n\nI assume that the first version of the analysis is still accurate, although I'm not 100% sure because I couldn't check the code state of that commit.\n\nIf it helps, I have uploaded the last logs [here on this branch](https://github.com/m4ycon/prefill-compact-blocks-review/tree/feat/update-datasets-07-27/logs)."
  },
  {
   "t": "2026-07-28T09:20:18Z",
   "kind": "review_comment",
   "who": "0xB10C",
   "assoc": "MEMBER",
   "path": "src/blockencodings.cpp",
   "commit": "864895088b1e660297a46ac034ba1230f19b7f3f",
   "in_reply_to": 3661499292,
   "text": "See also https://github.com/bitcoin/bitcoin/pull/35724 for the logging changes which will be merged first."
  },
  {
   "t": "2026-07-28T20:55:59Z",
   "kind": "review_comment",
   "who": "m4ycon",
   "assoc": "NONE",
   "path": "src/blockencodings.cpp",
   "commit": "864895088b1e660297a46ac034ba1230f19b7f3f",
   "in_reply_to": 3661499292,
   "text": "Hmm totally forgot about this one. I'll let both my comments open, although I see they are fixed in #35724. Feel free to resolve those comments when this PR is rebased with them (author)."
  },
  {
   "t": "2026-08-04T23:01:11Z",
   "kind": "force_push",
   "who": "davidgumberg",
   "commit": "864895088b1e660297a46ac034ba1230f19b7f3f"
  },
  {
   "t": "2026-08-04T23:01:30Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/blockencodings.cpp",
   "commit": "864895088b1e660297a46ac034ba1230f19b7f3f",
   "in_reply_to": 3617193836,
   "text": "Good catch, this got messed up while rebasing, pushed a fix."
  },
  {
   "t": "2026-08-04T23:02:21Z",
   "kind": "comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "text": "Rebased on top of #35724, where I've pulled out the logging changes, review there would be appreciated."
  },
  {
   "t": "2026-08-04T23:02:45Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/blockencodings.cpp",
   "commit": "864895088b1e660297a46ac034ba1230f19b7f3f",
   "in_reply_to": 3661499292,
   "text": "Thanks, I've rebased this on #35724, so marking as resolved."
  }
 ],
 "labels_log": [
  {
   "t": "2026-06-18T06:45:23Z",
   "action": "labeled",
   "label": "P2P",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-04T00:33:20Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-06T22:57:26Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-14T23:13:47Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-14T23:41:36Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-21T21:18:48Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-05T01:05:11Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  }
 ],
 "state_log": [
  {
   "t": "2026-06-18T06:45:13Z",
   "kind": "renamed",
   "who": "davidgumberg",
   "from": "Prefill compact blocks",
   "to": "p2p: Prefill compact blocks"
  }
 ],
 "text_chars": 32182,
 "text_tokens_estimate": 8045,
 "changed_paths": [
  "CMakeLists.txt",
  "src/bench/blockencodings.cpp",
  "src/blockencodings.cpp",
  "src/blockencodings.h",
  "src/compat/compat.h",
  "src/net.cpp",
  "src/net.h",
  "src/net_processing.cpp",
  "src/test/blockencodings_tests.cpp",
  "src/test/fuzz/cmpctblock.cpp",
  "src/test/fuzz/p2p_headers_presync.cpp",
  "src/test/fuzz/partially_downloaded_block.cpp",
  "src/test/sock_tests.cpp",
  "src/test/util/net.cpp",
  "src/util/sock.cpp",
  "src/util/sock.h"
 ],
 "files": [
  {
   "path": "CMakeLists.txt",
   "add": 1,
   "del": 0
  },
  {
   "path": "src/bench/blockencodings.cpp",
   "add": 2,
   "del": 1
  },
  {
   "path": "src/blockencodings.cpp",
   "add": 120,
   "del": 35
  },
  {
   "path": "src/blockencodings.h",
   "add": 21,
   "del": 1
  },
  {
   "path": "src/compat/compat.h",
   "add": 27,
   "del": 1
  },
  {
   "path": "src/net.cpp",
   "add": 94,
   "del": 0
  },
  {
   "path": "src/net.h",
   "add": 29,
   "del": 0
  },
  {
   "path": "src/net_processing.cpp",
   "add": 165,
   "del": 50
  },
  {
   "path": "src/test/blockencodings_tests.cpp",
   "add": 11,
   "del": 8
  },
  {
   "path": "src/test/fuzz/cmpctblock.cpp",
   "add": 19,
   "del": 40
  },
  {
   "path": "src/test/fuzz/p2p_headers_presync.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/fuzz/partially_downloaded_block.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/sock_tests.cpp",
   "add": 49,
   "del": 4
  },
  {
   "path": "src/test/util/net.cpp",
   "add": 1,
   "del": 0
  },
  {
   "path": "src/util/sock.cpp",
   "add": 46,
   "del": 1
  },
  {
   "path": "src/util/sock.h",
   "add": 130,
   "del": 0
  }
 ],
 "test_lines": 139,
 "git": {
  "head": "864895088b1e660297a46ac034ba1230f19b7f3f",
  "head_matches_backup": true,
  "base": "17c5e33e9c5418fb0240f5d4210c87f54b88cdda",
  "commits": [
   {
    "sha": "a01d69f8ec",
    "subject": "cmpctblock: log: debuglevel=trace print TXID's of all missing tx'es.",
    "files": 2,
    "add": 8,
    "del": 3
   },
   {
    "sha": "78715aab94",
    "subject": "cmpctblock: log: Log extrapool separately from mempool",
    "files": 2,
    "add": 24,
    "del": 9
   },
   {
    "sha": "43bc34af72",
    "subject": "cmpctblock: log: Print sizes of all tx types and prefill redundancies",
    "files": 2,
    "add": 63,
    "del": 2
   },
   {
    "sha": "e02a06d8a9",
    "subject": "build: Bump minimum Windows to >= Windows 1703",
    "files": 1,
    "add": 1,
    "del": 0
   },
   {
    "sha": "75c5582597",
    "subject": "sock: Add TCPInfo wrapper for getting socket info.",
    "files": 3,
    "add": 110,
    "del": 4
   },
   {
    "sha": "63cd12c2a4",
    "subject": "sock: TCPInfo::GetTCPWindowSize()",
    "files": 3,
    "add": 83,
    "del": 1
   },
   {
    "sha": "6252c9a5be",
    "subject": "sock: Add GetOSBytesQueued",
    "files": 3,
    "add": 59,
    "del": 1
   },
   {
    "sha": "d840c9e8d3",
    "subject": "net: Add Transport::GetMessageSize() for serialized msg sizes",
    "files": 2,
    "add": 41,
    "del": 0
   },
   {
    "sha": "fc55202cd4",
    "subject": "net: Add GetSendQueueSize()",
    "files": 3,
    "add": 46,
    "del": 0
   },
   {
    "sha": "67723d9be3",
    "subject": "net: Add CNode::WindowBytesTotalAndAvailable()",
    "files": 2,
    "add": 37,
    "del": 0
   },
   {
    "sha": "e53cad585e",
    "subject": "p2p: refactor: Stuff m_most_recent* into a struct",
    "files": 1,
    "add": 20,
    "del": 18
   },
   {
    "sha": "f255b4ea46",
    "subject": "p2p: Cache cmpct_block_msg for low bandwidth relay.",
    "files": 1,
    "add": 17,
    "del": 13
   },
   {
    "sha": "ac7054b4ef",
    "subject": "net: refactor: Move common logic into SendCompactBlock",
    "files": 1,
    "add": 45,
    "del": 28
   },
   {
    "sha": "a921698912",
    "subject": "net: Protect PeerHasHeader from nullptr",
    "files": 1,
    "add": 11,
    "del": 1
   },
   {
    "sha": "b16bf611b9",
    "subject": "p2p: keep track of cmpctblock prefill candidates",
    "files": 3,
    "add": 55,
    "del": 22
   },
   {
    "sha": "864895088b",
    "subject": "p2p: prefill our compact blocks with candidates",
    "files": 8,
    "add": 124,
    "del": 68
   }
  ],
  "patch_truncated": true
 },
 "input_hash": "98bd55596ce53b7d",
 "extracted_at": "2026-09-17T16:15:31+00:00"
}