Compact block reconstruction degradation between September - October 2026

On April, I was working on adding some stats based on logs about compact block reconstruction in peer-observer (see 420 and 465), since then, I’ve been looking to the added panels to validate them and I’ve seen some degradation around one of them: Compact block reconstruction without transaction requests per day.

In a simple way, ideally, when a block is mined and someone relay it to us, we’d have all transactions on our mempool. The sender send us a set of short ids of each transaction in that block instead of the full raw version of it, saving some bytes. If we don’t have one of the transactions, we ask the sender for them to be able to reconstruct the full block – a roundtrip that ideally wouldn’t happen. See BIP-152 for more details.

Example of a reconstruction log:

2026-04-06T15:02:09.404125Z [cmpctblock] Successfully reconstructed block 000000...6b6ad5
  with 1 txn prefilled,
  2714 txn from mempool (incl at least 2 from extra pool)
  and 4 txn (886 bytes) requested

I broke some lines to help reading, but it’s just a single line. This log tells us that: 1 transaction came prefilled, coinbase always comes prefilled as probably we wouldn’t have; 2714 were in our mempool and 2 of them were in extrapool, this extra acts like a “pre-discard”, instead of simply erasing it from the mempool, we keep it for some time; and the focus of this post, 4 transactions requested, this causes the roundtrip, making us send a getblocktxn to the sender.

The degradation

The below image shows how much reconstructions requested zero transactions from the sender, based on the previous log. Higher is better.

It shows a clear degradation in this metric from 2026-07-18 to 2026-10-18, from around 35~60% to at most 10% inside the period. This can be also seen in b10c’s nodes as the below image shows, see delving#1052 tables for a longer period.

What does it mean for the network? More roundtrips happening in reconstructions, so more getblocktxn being sent from nodes when (ideally) it shouldn’t happen – among other problems of network.

For a very long time, as a newbie in bitcoin, I had no idea of what could be causing this. But I recently read some posts/comments that opened a great hypothesis for this.

/p2aburn.*/

After reading #193, I took some time investigating those strange agents: /Sat0shi:31.0.0/ and /Satoshi:31.0.0/ with protocol version 70015. I also found another agent behaving similarly /p2aburn.*/, that was also mentioned later in the same post. Later, I found /txbroadcast.*/ which also behaves similarly to those peers.

The moment those nodes first appear seems to correlate with the degradation start and they make sense to impact on this. As mentioned by the author, and also seen on my node, they were sending many unsolicited transactions to our nodes.

At #193 comment, I built a first timeline with each event, but here it is a more updated version:

Notes:

  • The bar panels are based on logs and they go from now until 2026-07-08.
  • The query used for the peer-observer data (line panels) is sum by (useragent) (increase(peerobserver_p2p_version_useragent{useragent=~"/txbroadcast.*|/p2aburn.*|/Sat0shi:31.0.0/"}[1d])). Also, it doesn’t mean that they held X connections on that day.
  • There’s no way to filter Satoshi:31.0.0 70015 in peer-observer data, but they appear on the panel based on logs.

Timeline:

  1. 2026-07-03: /p2aburn-probe:0.1/ first appearance;
  2. 2026-07-04: /txbroadcast:0.1/ first appearance;
  3. 2026-07-07: a single /p2aburn:0.1/ connection;
  4. 2026-07-14: /p2aburn:1.0/ first appearance;
  5. 2026-07-18: compact block reconstruction degradation starts (below 10% from 2026-07-23);
  6. 2026-07-25: /txbroadcast:0.1/ last appearance;
  7. 2026-07-28: /Sat0shi:31.0.0/ first appearance;
  8. 2026-09-21: /Satoshi:31.0.0/ (protocol 70015) first appearance;
  9. 2026-09-22: /Sat0shi:31.0.0/ last appearance;
  10. 2026-10-18: /Satoshi:31.0.0/ (protocol 70015) last appearance;
  11. 2026-10-18: compact block reconstruction degradation stops;
  12. 2026-10-19: after some peaks, /p2aburn:1.0/ falls to about 30~50 connections per day and a very low volume of messages.

At the same time that /p2aburn:1.0/ arrived and started sending a meaningful volume of messages, the metric started declining. And just recently, since many VPS providers rebooted their machines due to CVE-2026-99999 (including mine), see more at #189, this metric bumped to the usual 40~60%. This may have another reasons, but at the moment is my only clue on why they’ve stopped.

Note: from now on, I will call /txbroadcast:0.1/, /Sat0shi:31.0.0/ and /Satoshi:31.0.0/ (protocol 70015) set as the “fleet” – because their behavior are similar, unlike /p2aburn.*/.

Currently, we have zero connections to the fleet and just a few /p2aburn.*/ active, but sending a way lower volume of messages.

Also, see how much tx messages they were sending to my node (based on logs, until 2026-07-08):

Differences in behavior

For this specific section, most part of it was written by a llm checking my data/logs, it seems to make sense with all the data I’ve seen.

The “fleet” (builds the chains)

  • It pushes transactions without announcing them. We received 32.9M tx messages from it against only 1.8M inv. A normal peer announces with inv and sends the transaction only when asked. At its peak (Oct 5) it sent ~1.33M transactions a day.
  • It reconnects constantly. We saw ~31.7k handshakes over the period.
  • It builds P2A chains carrying Runes:
    • A root transaction, funded by a wallet input, creates an anchor (290 sats in the chain we followed; other roots use 280, 350 and so on).
    • Each link spends the previous anchor, pays 10 sats of fee and creates an anchor 10 sats smaller.
    • When the anchor reaches 240 sats (the dust limit), a refill transaction tops it up again.
    • A closing transaction pays 679 sats of fee and ends the chain.
    • Each link mints 1 unit of rune 1:0. Under the mint rule, the runes accumulate on the anchor until the closing transaction.

p2aburn (breaks the chains)

  • It says the bare minimum. We received only tx (2.96M), pong, version and verack from it. It never sends inv, ping, addr or headers, so it does not announce anything either: it just pushes transactions.
  • It reconnects a lot. We saw 28,770 handshakes, close to 3k a day at the peak (Oct 17).
  • It sweeps anchors. Each of its transactions spends an anchor in the middle of a fleet chain and turns the anchor’s whole value into fee. The verified example is sweeper 0b88a628...: 66 vB, 290 sats of fee, and it replaced links 1 to 4 in our mempool. Its average transaction size, ~66 to 80 bytes, fits this. Under the Runes mint rule, a sweep would also burn the runes accumulated on the anchor. That part is inferred: we never decoded a sweeper.
  • It was already sending transactions on Jul 22, a week before the fleet showed up. We don’t know what it was sweeping then.
  • It almost stopped after Oct 18. The following days saw ~150 transactions and ~40 connections a day, against 69k transactions on Oct 17. That fits: it ran out of chains to sweep.

The transaction chains

A transaction can spend an output of another transaction that is not confirmed yet. Doing this repeatedly gives a chain: tx1 is in the mempool, tx2 spends tx1’s output, tx3 spends tx2’s, and so on. A miner can include the whole chain in one block, as long as each link comes after its parent.

The “fleet” builds these chains on top of P2A (pay-to-anchor) outputs. A P2A output has a 4-byte script and no key: anyone can spend it without a signature, and the input is the smallest there is (41 vB). Each link in the fleet’s chains:

  • spends the P2A anchor created by the previous link;
  • creates a new anchor 10 sats smaller than the one it spends (from 290 down to 240, the dust limit), and a closing tx sweeps the last anchor with a wallet input, paying 679 sats;
  • carries a Runes OP_RETURN;
  • is 94 to 107 bytes and pays 10 sats of fee (~0.1 sat/vB).

The chains are up to 25 links long. Since there is no key, the fleet can build and broadcast whole chains very fast. The flip side is that the same property lets anyone spend an anchor in the middle of a chain.

Those 25 txs clusters are very common to be in mempool, take a look at the below metric taken out of Cluster Mempool Observer histogram. Btw it’s a personal project to track a history of every movement of the mempool and its clusters (still experimental). Here you can look at many examples of them individually, and here you can see them in mempool space.

Also those “Rune mint chains” possibility is mentioned at delving#1052.

How a mid-chain replacement could degrade compact block reconstruction

I personally didn’t know much about P2A, tried to learn a bit about it. Feel free to correct me if I say anything wrong.

This is my main hypothesis right now, since a single transaction is all that’s need to trigger a getblocktxn in reconstruction, I think this can be great part of the reason why we see this degradation.

Anyone who gets a conflicting spend of one link into the mempool can cut a chain of unconfirmed transactions. For example:

  1. A chain of 10 transactions, tx1 to tx10, each spending an output of the previous one.
  2. Someone broadcasts tx5’, which spends the same input as tx5 and pays a higher fee.
  3. My node correctly accepts tx5’ under the RBF rules and evicts tx5 along with its descendants, tx6 to tx10. If tx5’ arrives first, the node rejects tx5 instead, and tx6 to tx10 never get in because their inputs are missing.
  4. A miner that has the original chain and never takes tx5’ mines all 10.
  5. When the block arrives, my node is missing tx5 to tx10. It cannot rebuild the block from the compact block alone and has to fetch them with getblocktxn. Bitcoin Core keeps recently replaced transactions in extrapool for this case, but at high enough volume they no longer fit.

My node did nothing wrong at any step. Its mempool holds a valid history that differs from the one the miner chose.

Cost

With plain RBF, the replacement must pay more in absolute fees than everything it evicts. It costs nothing only when it never confirms, which is what happens in the example: the block containing the original chain invalidates it. If a miner picks up tx5’ instead, the sender pays.

P2A anchors remove most of that cost. Because anyone can spend an anchor, the sweeper’s fee comes almost entirely from the anchor’s own value. In what I saw, a sweeper spends an anchor and turns its whole value into fee (290 sats for the root anchor), so the sender adds nothing of their own.

Real case

  1. without the sweeper tx

    • Confirmed chain at mempool space.
    • Log of a mid-chain replace transaction (sweep):
    02:52:51.520852 [mempool] replacing mempool tx 13b821bcdf10da153ab6f1e98b58bd45772cfd1e02a0e51369a2b0e319092d2a (fees=10, vsize=94). New tx 0b88a6…e6b (fees=290, vsize=66)
    
0b88a6…e6b log history
2026-10-18T02:52:46.375697Z [net] got inv: wtx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b  new peer=558834
2026-10-18T02:52:47.654915Z [net] got inv: wtx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b  new peer=579887
2026-10-18T02:52:47.968011Z [net] got inv: wtx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b  new peer=559137
2026-10-18T02:52:49.006334Z [net] Requesting wtx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b peer=558834
2026-10-18T02:52:49.900944Z [net] got inv: wtx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b  new peer=198695
2026-10-18T02:52:50.026483Z [mempoolrej] 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b (wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b) from peer=558834 was not accepted: bad-txns-inputs-missingorspent
2026-10-18T02:52:50.026531Z [txpackages] added peer=558834 as a candidate for resolving orphan 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b
2026-10-18T02:52:50.026558Z [txpackages] stored orphan tx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b (wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b), weight: 264 (mapsz 3000 outsz 547)
2026-10-18T02:52:50.027014Z [txpackages] added peer=198695 as a candidate for resolving orphan 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b
2026-10-18T02:52:50.027049Z [txpackages] added peer=198695 as announcer of orphan tx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b (wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b)
2026-10-18T02:52:50.029756Z [txpackages] added peer=559137 as a candidate for resolving orphan 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b
2026-10-18T02:52:50.029854Z [txpackages] added peer=559137 as announcer of orphan tx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b (wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b)
2026-10-18T02:52:50.030228Z [txpackages] added peer=579887 as a candidate for resolving orphan 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b
2026-10-18T02:52:50.030299Z [txpackages] added peer=579887 as announcer of orphan tx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b (wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b)
2026-10-18T02:52:50.436991Z [net] got inv: wtx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b  have peer=68215
2026-10-18T02:52:51.350667Z [txpackages] added 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b (wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b) to peer 579887 workset
2026-10-18T02:52:51.520852Z [mempool] replacing mempool tx 13b821bcdf10da153ab6f1e98b58bd45772cfd1e02a0e51369a2b0e319092d2a (wtxid=13b821bcdf10da153ab6f1e98b58bd45772cfd1e02a0e51369a2b0e319092d2a, fees=10, vsize=94). New tx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b (wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b, fees=290, vsize=66)
2026-10-18T02:52:51.520937Z [mempool] replacing mempool tx 4f8c3171b8113f58908a49aabfa1e9fc0c132424744bb590ca5748092fa6b076 (wtxid=4f8c3171b8113f58908a49aabfa1e9fc0c132424744bb590ca5748092fa6b076, fees=10, vsize=94). New tx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b (wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b, fees=290, vsize=66)
2026-10-18T02:52:51.521007Z [mempool] replacing mempool tx 5474f4ed1416e5eb4e6c08f304e7ae9cc7d8810550c3cc50fe58d3f674214278 (wtxid=5474f4ed1416e5eb4e6c08f304e7ae9cc7d8810550c3cc50fe58d3f674214278, fees=10, vsize=94). New tx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b (wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b, fees=290, vsize=66)
2026-10-18T02:52:51.521052Z [mempool] replacing mempool tx ef435405d8d1d26004227a4ccb9bba0f986ed341e0e2b90953b874208a78cca3 (wtxid=ef435405d8d1d26004227a4ccb9bba0f986ed341e0e2b90953b874208a78cca3, fees=10, vsize=94). New tx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b (wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b, fees=290, vsize=66)
2026-10-18T02:52:51.521427Z [validation] Enqueuing TransactionAddedToMempool: txid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b
2026-10-18T02:52:51.521636Z [txpackages]    accepted orphan tx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b (wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b)
2026-10-18T02:52:51.521716Z [txpackages] removed orphan tx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b (wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b) (4 announcements)
2026-10-18T02:52:51.521746Z [mempool] AcceptToMemoryPool: peer=579887: accepted 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b (wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b) (poolsz 65628 txn, 203753 kB)
2026-10-18T02:52:51.522529Z [validation] TransactionAddedToMempool: txid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b
2026-10-18T02:52:53.404301Z [net] received getdata for: wtx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b peer=525174
  ... many messages like this one ...
2026-10-18T02:53:09.123461Z [net] received getdata for: wtx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b peer=203622
2026-10-18T02:53:32.038941Z [net] received getdata for: witness-tx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b peer=575294
2026-10-18T02:53:33.445418Z [net] received getdata for: witness-tx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b peer=189287
2026-10-18T02:53:38.900648Z [net] received getdata for: witness-tx 0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b peer=159574
2026-10-18T03:51:20.505211Z [validation] Enqueuing TransactionRemovedFromMempool: txid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b reason=conflict
2026-10-18T03:51:20.505399Z [validation] TransactionRemovedFromMempool: txid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b wtxid=0b88a6283cd045dadc500d1fc92a735da0c35357351c7d46111c18930e5e8e6b reason=conflict
  1. with the sweeper tx

    • Confirmed sweeper case.
    • In this case, my node already have the rest of the chain, so it rejected the sweeper, but later a miner mined the sweeper.
fada93...89b log history
# sweeper fada93f79fdfd38ffd9049ffe61195e858b5b110fdffefa16f1440a62078e89b and its parent 9d887fdb2cd62c6af31801f4f9dc2dece40b0c69255c8a46125275368bf8b788

2026-10-13T05:45:50.736096Z \[validation\] Enqueuing TransactionAddedToMempool: txid=9d887fdb2cd62c6af31801f4f9dc2dece40b0c69255c8a46125275368bf8b788 wtxid=265a8c7dad0c3e0fb0329777c279aab78b031b149333357ec3fade3ec42d7c4f
2026-10-13T05:45:50.736226Z \[mempool\] AcceptToMemoryPool: peer=492350: accepted 9d887fdb2cd62c6af31801f4f9dc2dece40b0c69255c8a46125275368bf8b788 (wtxid=265a8c7dad0c3e0fb0329777c279aab78b031b149333357ec3fade3ec42d7c4f) (poolsz 80331 txn, 219945 kB)
2026-10-13T05:45:50.736435Z \[validation\] TransactionAddedToMempool: txid=9d887fdb2cd62c6af31801f4f9dc2dece40b0c69255c8a46125275368bf8b788 wtxid=265a8c7dad0c3e0fb0329777c279aab78b031b149333357ec3fade3ec42d7c4f
2026-10-13T05:45:50.882843Z \[mempoolrej\] fada93f79fdfd38ffd9049ffe61195e858b5b110fdffefa16f1440a62078e89b (wtxid=fada93f79fdfd38ffd9049ffe61195e858b5b110fdffefa16f1440a62078e89b) from peer=491503 was not accepted: insufficient fee, rejecting replacement fada93f79fdfd38ffd9049ffe61195e858b5b110fdffefa16f1440a62078e89b, not enough additional fees to relay; 0.00 < 0.00000007
2026-10-13T05:45:50.882883Z \[txpackages\] tx fada93f79fdfd38ffd9049ffe61195e858b5b110fdffefa16f1440a62078e89b (wtxid=fada93f79fdfd38ffd9049ffe61195e858b5b110fdffefa16f1440a62078e89b) failed but reconsiderable, looking for child in orphanage
2026-10-13T05:45:50.979074Z \[net\] got inv: tx 9d887fdb2cd62c6af31801f4f9dc2dece40b0c69255c8a46125275368bf8b788 have peer=492350
2026-10-13T05:45:50.996410Z \[net\] got inv: tx 9d887fdb2cd62c6af31801f4f9dc2dece40b0c69255c8a46125275368bf8b788 have peer=492349
2026-10-13T05:45:51.016461Z \[net\] got inv: tx 9d887fdb2cd62c6af31801f4f9dc2dece40b0c69255c8a46125275368bf8b788 have peer=492352
2026-10-13T05:45:51.191786Z \[mempoolrej\] 9d887fdb2cd62c6af31801f4f9dc2dece40b0c69255c8a46125275368bf8b788 (wtxid=9d887fdb2cd62c6af31801f4f9dc2dece40b0c69255c8a46125275368bf8b788) from peer=454673 was not accepted: txn-same-nonwitness-data-in-mempool
2026-10-13T05:45:54.662342Z \[net\] got inv: wtx fada93f79fdfd38ffd9049ffe61195e858b5b110fdffefa16f1440a62078e89b have peer=453525
2026-10-13T05:45:55.571249Z \[net\] received getdata for: witness-tx 9d887fdb2cd62c6af31801f4f9dc2dece40b0c69255c8a46125275368bf8b788 peer=439623
 ... many messages like this one ...
2026-10-13T05:46:01.483448Z \[net\] received getdata for: witness-tx 9d887fdb2cd62c6af31801f4f9dc2dece40b0c69255c8a46125275368bf8b788 peer=446573

# block 971201 (0000000000000000000036fa723572e1e835152288cc97f72e0bafd5cdbb80cd) on our node

2026-10-13T06:19:55.156703Z Saw new header hash=0000000000000000000036fa723572e1e835152288cc97f72e0bafd5cdbb80cd height=971201 peer=320080
2026-10-13T06:19:55.717381Z \[cmpctblock\] Successfully reconstructed block 0000000000000000000036fa723572e1e835152288cc97f72e0bafd5cdbb80cd with 1 txn prefilled, 4395 txn from mempool (incl at least 3 from extra pool) and 1784 txn (203298 bytes) requested
2026-10-13T06:19:56.484269Z UpdateTip: new best=0000000000000000000036fa723572e1e835152288cc97f72e0bafd5cdbb80cd height=971201 version=0x20170000 log2_work=96.388563 tx=1458976279 date='2026-10-13T06:19:32Z' progress=1.000000 cache=526.0MiB(3921176txo)

Final thoughts

  • Why is p2aburn still active but not harming the metric? Maybe because the fleet is not sending transactions? So they don’t have anything to harm? I suppose fleet operators didn’t realize it yet (nodes off), as we don’t have connections to them? And when they do, will we have the same degradation?
  • I still need to cross data around what is the reason that each block is not fully on our mempool, requiring getblocktxn call, if data points out to “most blocks are missing a tx from some rune chain” instead of the other options mentioned at delving#1052, it will strengthen this hypothesis.
  • I still need to really understand P2A, it shouldn’t be that easy to cause this mess in the network, probably I’m missing something out.

Although this post focus on this hypothesis about P2A and sweepers, feel free to comment about other theories. The focus is on why do we see this reconstruction degradation on the network.

Thanks for putting this together. I don’t log cmpctblock, but I have a side measurement that moves at the same time: for each new block, the gap between the first job from a local stratum server fed by my own Core and the fastest of three public pools.

Same node, no restart, the same manual peers until Oct 21. Median gap:

Oct 7 – Oct 18 13:28 UTC (last fleet session here): 249 ms over 1,741 blocks

Oct 18 13:28 – Oct 22: 115 ms over 600 blocks I had to restart my node on Oct 22.

My node’s own block detection minus the fastest pool drops the same way (209 → 98 ms), so it’s not just template building. And since my node wasn’t restarted around Oct 18, the change here isn’t from a reboot.

My guess is your effect: my mempool was missing transactions from new blocks, so Core had to fetch them first. One extra round trip fits the size of the step. It’s one node and only a correlation, and my data starts mid-September.

Follow-up: I checked every block from Oct 7 to Oct 22 for fleet txs. Blocks without any sped up just the same. SecPool and Luxor never included a fleet tx or a sweep, yet on my node:

SecPool: 356 → 114 ms

Luxor: 330 → 98 ms

So here it doesn’t look like the chain txs inside the block were the main cause. Something else in the mempool, maybe? Small samples after Oct 18, and no cmpctblock logs, so I can’t say more. Sorry for the hasty guess earlier.

I had some peer-observer archives from Aug 12 and Aug 18–19, so I went looking for the fleet and decoded the txs it pushed to us. They look exactly like the P2A chains described above!

The fleet showed up as /Sat0shi:31.0.0/, always inbound. It sent around 3.4k tx and only ~130 inv, and it never requested anything back. Every tx carries a runestone. Almost all of them are 25-long chains:

  • a root tx with a ~474 sat P2A output
  • 24 links, each spending the previous anchor and paying 10–11 sats of fee (~0.1 sat/vB)
  • a tail tx paying ~13 sat/vB, which pulls the whole chain in with CPFP

On Aug 12 we also had mempool events, and I could see the sweeps happening. They’re 66 vB txs that pay exactly the anchor’s 474 sats as fee, and each one evicted up to 17 links. On the same day, a good chunk of the fleet’s txs were mined, others were replaced, and a few hundred were rejected for missing inputs.

p2aburn did connect to this node, but it never sent a tx. It only did handshakes, so the sweeps reached us through other peers.

I haven’t cross-checked any of this against our cmpctblock getblocktxn yet
Will post it once I have it.