Author: 0xB10C; Translated by: Song Xue, Golden Finance

My project, miningpool-observer, is designed to detect when Bitcoin mining pools are not making transactions that they could have made. Over the past few weeks, it has detected six missing transaction spends from OFAC-approved addresses. This post explores whether these transactions were intentionally filtered out because they were spent from OFAC-approved addresses, or if there are other possible explanations for why these transactions were missing from blocks. I concluded that four of the transactions were likely filtered out.

In September and October 2023, the RSS feed of my mining pool watcher instance reported six blocks missing OFAC-approved transactions. One of the blocks was mined by the ViaBTC pool, another by the Foundry USA pool, and four by the F2Pool pool. OFAC-approved transactions are transactions where expenditures or payments were made from addresses approved by the U.S. Department of the Treasury's Office of Foreign Assets Control. I maintain a tool that extracts a list of OFAC-approved addresses from the Specially Designated Nationals (SDN) list published by OFAC.

There are several reasons why transactions might be missing from a block. In general, transactions are not spread evenly across the network, and there is no global memory pool from which transactions can be selected. Each node has its own set of valid transactions. A mining pool may also prioritize transactions that received out-of-band payments. However, it may also deprioritize or filter transactions.

The goal here is to determine whether mining pools filter any of these six OFAC-approved transactions, or if there are other possible explanations for their not appearing in blocks. Note that mining pools are free to choose which transactions to include and which to exclude. However, to analyze Bitcoin’s censorship-resistant properties, it is critical to understand which mining pools and how many are filtering transactions.

My conclusion is that the reports from miningpool-observer indicating that sanctioned transactions are missing from ViaBTC and Foundry’s blocks are most likely false positives rather than the result of filtering. However, the transactions missing from F2Pool’s blocks are likely to have been filtered.

ViaBTC block 808660

Block 808660..866c79c52 was mined by ViaBTC on 21 Sep 2023 and does not contain transaction 262025e7.. This transaction merged 100 inputs into one output. The output of one of these inputs pays 1ECeZBxCVJ8Wm2JSN3Cyc6rge2gnvD3W5K. This address was added to OFAC's SDN list on 21 Sep 2021.

The transaction has a size of 14.7 kvB and pays a fee of 25.18 sat/vByte. The output spent by the sanctioned address is 0.0002 BTC (20k sat) and was created the day before. The transaction had been in my node's mempool for about 75 minutes when ViaBTC mined block 808660. It does not have any dependencies on transactions in the mempool.

Fee distribution in templates and blocks

Fee distribution for blocks and template for block 808660. Screenshot from Miningpool.observer.

Checking the fee distribution for block 808660 on Miningpool.observer shows that ViaBTC took up about 1 MWU of block space (out of 4 MWUs) and had prioritized transactions. These likely stem from the ViaBTC Bitcoin transaction accelerator. Prioritizing certain transactions means that transactions with lower fees (such as the transaction payout from the sanctioned address here) do not make it into the block. For this ViaBTC block, my mining pool observer instance lists 24 large merged transactions at the end of the template that did not make it into the block.

List of large merged transactions missing from block 808660

The conclusion drawn from this is that ViaBTC did not filter this transaction. It was superseded by other priority transactions. This is evidenced by the fact that three days later, ViaBTC mined a transaction that spent the output of the same sanctioned address in block 809181.

Foundry USA Block 813231

Block 813231..0a8528b6 was mined by Foundry USA on October 21, 2023 and does not contain transaction c9b57191.. This transaction merged 150 inputs into one output. The output of one of the inputs was paid to 3PKiHs4GY4rFg8dpppNVPXGPqMX6K2cBML. This address was added to OFAC's SDN list on April 14, 2023.

Since most of the 150 inputs are 2-of-3 multi-signature P2SH scripts, the missing transaction is large, at 43842 vBytes. It pays a fee of 5.09 sat/vByte and does not rely on in-mempool transactions. In the template built from my Bitcoin Core node, this fee rate is enough to rank it 161st out of 2215 transactions. However, when I learned about Foundry USA's block 812331, this transaction, along with 18 others, had only been in my mempool for about 30 seconds. This makes it likely that Foundry did not have a chance to include this transaction in their block because they did not know about it yet.

It can take several seconds for transactions to propagate. Additionally, most mining pools only push new block templates to miners every 30 seconds, and then it takes a while to switch to a new job. Additionally, the miningpool-observer tool requests new block templates every few seconds and does a best effort match based on the minimum difference of missing and extra transactions (see the methodology in the FAQ). This allows new transactions to appear falsely positive for up to 60 seconds or so.

The mempool.space block explorer also tracks the differences between the block template and the final block broadcast by the miners. They show that c9b57191.. is included in their template but missing in the actual block. This transaction is also marked by them as "recently broadcast".

The missing transactions in Foundry’s block 813231 are considered “recently broadcasted” by mempool.space.

The conclusion drawn from this is that Foundry USA did not filter this transaction. The transaction was broadcast too late to be included in the mining operation that eventually found block 813231. In addition, Foundry USA mined the next block at height 813232 and included the approved transaction there.

F2Pool blocks 810727, 811791, 811920, 813357

F2Pool mined block 810727..ccda1498 on October 5, 2023, blocks 811791..af4453d6 and 811920..00badf62 on October 12, and block 813357..63ac1669 on October 22. Each block is missing an endorsement transaction. Each of these transactions consolidates 150 2-of-3 multi-signature inputs into a single output. For each transaction, one of the inputs pays to the output 3PKiHs4GY4rFg8dpppNVPXGPqMX6K2cBML. This is the same consolidation pattern and address discussed in the previous section. None of the missing transactions depend on transactions in the mempool.

Block 810727

In block 810727, F2Pool did not include transaction c6a66836.., which spent the endorsed output. With 150 2-of-3 multisignature inputs, the transaction is fairly large at 44017 vBytes. When F2Pool mined block 810727, it paid a fee of 446260 sats and sat in my node's mempool for nearly 4 hours. F2Pool chose to include transaction 907e1f45.. instead of c6a66836.. This transaction is also a merged transaction with 150 inputs and one output, but does not spend from an endorsed output. It pays the same fee of 446260 sats, but happens to be 3 vBytes larger than 44020 vBytes. This means that the missing transaction c6a66836.. has a slightly higher fee rate than 907e1f45.. When strictly sorted by fee rate, the missing transaction should have been included. However, in reality, the 3 vBytes of extra block space is unlikely to have an impact on the total fees in a block.

Comparison of the missing endorsed transactions and the included extra transactions in F2Pool block 810727. The extra transactions added 3 vBytes.

Block 811791

The approved transaction aa001ce6... is missing from F2Pools block 811791. Similar to the previous merged transaction, this transaction has a size of 42459 vBytes (169836 WU). With a fee of 446260 sats, the fee paid is 10.5 sats/vByte. When block 811791 reached the pool watcher node, the transaction had been in its memory pool for four minutes.

In this block, it is notable that 5 transactions with OP_RETURN Stacks block commitments are missing. However, F2Pool has inserted its own Stacks block commitment. This happens frequently and has been reported before. In addition, F2Pool includes two large zero-fee transactions in its block. One is a transaction that consolidates the previous F2Pool coinbase output, and the other is a payment to the miner. This is common behavior for blocks mined by F2Pool.

While these additional transactions took up over 400 kWU of block space, there was still enough space to include transaction aa001ce6.. The block included the transaction for 2.86 MWU, which is less than the 10.5 sat/vByte fee for aa001ce6.. The transaction was around 170 kWU and fit in the block. On mempool.space, the transaction was marked as "deleted", which negatively impacted its block health metric.

The fee distribution per transaction bundle in block 811791 includes the fee and weight markers for missing transactions.

Block 811920

In block 811920, F2Pool does not include transaction 1cb3d6bc.., which spends the endorsed output. This transaction is also a large merged transaction. It is 43630 vBytes (169836 WU) in size and has a fee of 44660 sats, paying a fee of 10.23 sat/vByte. When block 811920 arrived at the pool watcher node, the transaction had been in the node's memory pool for nearly 2 minutes.

In block 811920, the 1.44 MWU transaction paid less than 10.23 sat/vByte in fees. The 170 kWU transaction 1cb3d6bc.. would fit in that block. Since the transaction has only been in my node's mempool for nearly two minutes, it may not have propagated to F2Pool when they built the block template. The transaction also shows as "recently broadcasted" on mempool.space. Generally, mining pools try to have a good connection to the Bitcoin network. If the transaction is in the mempool of mempool.space and miningpool.observer, then it is likely that the transaction is in F2Pool's mempool.

The fee distribution per transaction bundle in block 811920 includes the fee and weight markers for missing transactions.

Block 813357

In block 813357 of F2Pool, the transaction e49cdb60..9 that spends the endorsed output is missing. The size of this merged transaction is 43053 vBytes (172209 WU). If the fee is 178504 sats, the fee paid is 4.15 sats/vByte. When block 813357 arrived at the pool watcher node, the transaction had been in the node's memory pool for more than 25 minutes.

In block 813357, there are 684 kWU transactions paying less than 4.15 sat/vByte. 172 kWU transaction e49cdb60.. would fit in that block. Since that transaction has been in my node mempool for more than 25 minutes, it is unlikely that the transaction has not yet propagated to one of the F2Pools nodes. This transaction is also included in the template of mempool-space block 813357.

Fee distribution by transaction bundle in block 813357, including fee and weight markings for lost transactions.

F2Pools Blockchain Conclusion

The missing approved transaction in block 810727 has a slightly higher fee rate because it is 3 vBytes smaller than the included transaction. While the 3 vBytes of extra block space would have no impact on the total fees in this case, the Bitcoin Core block template algorithm would have chosen the transaction with the higher fee. The large number of additional transactions included in block 811791 would not have had an impact on the missing approved transaction in block 811791. It may have been filtered out of the block. The block audit on mempool.space agrees with this. It is possible that F2Pool was not yet aware of the missing approved transaction in block 811920. However, 2 minutes should be enough for a large mining pool to receive the transaction. Especially since mempool.space and Miningpool.observer are aware of the transaction. It is likely that the approved transaction was lost due to F2Pool filtering. Similar to the missing transaction in block 811791, the missing transaction in block 813357 is likely to have been filtered out by F2Pool.

These four missing sanctioned transactions lead to the conclusion that F2Pool is currently filtering transactions. Since we only see missing transaction spends from a single OFAC-sanctioned address, 3PKiHs4GY4rFg8dpppNVPXGPqMX6K2cBML, we cannot tell if F2Pool is filtering that single address or all OFAC-sanctioned addresses.

in conclusion

The post discusses six Bitcoin transaction spends from OFAC-approved addresses that the Pool Watcher tool detected as missing from blocks. The two transactions missing from the ViaBTC and Foundry USA pool blocks were false positives and were not filtered. The four OFAC-approved transactions missing from F2Pool blocks were likely filtered. This raises the question of why F2Pool, a pool originating in Asia, was the first to filter transactions based on US OFAC sanctions.

However, the Bitcoin network continues to operate normally. A single pool filtering transactions does not affect the censorship resistance of the entire Bitcoin network. Further monitoring of mining pools’ transaction selections could identify when more mining pools begin filtering transactions based on factors such as OFAC sanctions. It would also allow miners to point their hashpower to these mining pools, and if they disagree with a pool’s (unannounced) filtering policy, they could make an informed decision to switch to a different pool.

  1. Since all blocks with missing transactions are not close to the sigop limit of 80,000, they are not discussed here.

  2. ViaBTC block 808660: 000000000000000000017c18a76632d9e39e8c388ee1e4028ec75e50866c79c5

  3. Missing transaction in block 808660: 262025e73812fc68b6514ea366abf463147176c7867e5853f117aded58c30e0e

  4. Transaction cb9f2592.. mined by ViaBTC in block 809181 is an Omnilayer transaction that deposited 1528 USDT to the address in September 2020. The output of this transaction to the sanctioned address 1ECeZBxCVJ8Wm2JSN3Cyc6rge2gnvD3W5K is similar to the output of transaction 262025e7.. missing in block 80866.

    I checked some of these addresses and they all contained USDT balances on OmniLayer that were emptied in these transactions. While this is a guess, it seems someone wanted to clear out the remaining USDT on a bunch of addresses, sent 20k sats to each, and screwed up the sweep by merging the newly created outputs again in 262025e7…then they retried d11019a2..and successfully swept it with cb9f2592…

    If this is the case, then OFAC could be missing a bunch of addresses for the same entity on its list.

  5. Block 813231 mined by Foundry has header hash: 00000000000000000001740d5fbb8bbc0b93d4bf46ca2011f642e92a0a8528b6

  6. The txid of the approved transaction missing from block 813231 is: c9b5719131bfeac6378749243731c5e70f1ce56deabb7006a2b6539710866420

  7. According to OXT.me data, this address belongs to an OKEX wallet. The merged transaction c9b57191.. is an OKEX merged deposit. According to OXT.me, the merged output is a payout to the Hydra darknet market. More information can be found here.

  8. Block Hash

  • 810727: 

    0000000000000000000350ae5ee08a4415146612af59a20021efeaf2ccda1498

  • 811791: 

    00000000000000000001631243b00b6c1019c0d833b6738e0c591dacaf4453d6

  • 811920: 

    00000000000000000002efd0fc8801b149f505b125308a35c584ed2600badf62

  • 813357: 

    00000000000000000000519c33dcdf5ca386524b2cbacb561f767e9663ac1669

9. Missing, approved transactions:

  • 810727: 

    c6a668364f19df0f2977f8ad7d0a3a73c5e32b55b6a7c650cafa37a5ab4b19f2

  • 811791: 

    aa001ce6e262b8b9042645ecdec9c84e9e2ad06f56dff6dd5ae42005fdea8da9

  • 811920: 

    1cb3d6bcc650c2891b68e7b205d601bcf5158e30e1926d0fd0c8385cb456b37b

  • 813357: 

    e49cdb6075c49b8fc37b3e922038e2a3205d75a9a1fb4b69f3568707594c2d3e

10. F2Pool chose a slightly larger transaction size for block 810727, so the fee rate is lower:

  • 907e1f45334652dd344cf846639f3f9a2ee11b5489e2ffc2660ea543881b1bce

Probably because there are fewer low-r random numbers in the signature, which makes the signature larger.