My project, miningpool-observer, aims to detect when Bitcoin mining pools are not mining transactions they could have been mining. Over the past few weeks, it detected six missing transactions spending from OFAC-sanctioned addresses. This post examines whether these transactions were intentionally filtered because they spent from OFAC-sanctioned addresses or if there are other possible explanations for these transactions to be missing from blocks. I conclude that four out of six transactions were likely filtered.
In September and October 2023, the RSS feed of my miningpool-observer instance reported six blocks missing an OFAC-sanctioned transaction. One block was mined by the ViaBTC mining pool, another by the Foundry USA pool, and four by F2Pool. An OFAC-sanctioned transaction is a transaction spending from or paying to an address sanctioned by the US Department of the Treasury’s Office of Foreign Assets Control. I maintain a tool to extract a list of OFAC-sanctioned addresses from the Specially Designated Nationals (SDN) list published by the OFAC.
Several reasons could explain why a transaction might be absent from a block. Generally, transactions do not propagate equally through the network, and there is no global mempool to pick transactions from. Each node has its own set of valid transactions. A pool might also prioritize transactions for which it received an out-of-band payment. However, it might also deprioritize or filter transactions.
The goal here is to determine if the mining pool filtered any of these six OFAC-sanctioned transactions or if there are other possible explanations for their absence from the block1. Note that mining pools are free to choose which transactions to include and which to leave out. However, to analyze Bitcoin’s censorship-resistant properties, it’s crucial to understand which pools and how many of them are filtering transactions.
I conclude that the reports from miningpool-observer indicating sanctioned transactions missing from blocks by ViaBTC and Foundry are likely false-positives and not the result of filtering. The transactions missing from F2Pool’s blocks are, however, likely filtered. All missing transactions have been picked up by other miners 2.
Block 808660 by ViaBTC
..866c79c53, mined by ViaBTC on September 21, 2023,
did not include transaction
262025e7..4. This transaction
consolidates 100 inputs into one output. One of these inputs spends an output
1ECeZBxCVJ8Wm2JSN3Cyc6rge2gnvD3W5K. This address was added
to the OFAC’s SDN list on September 21st, 2021.
The transaction has a size of 14.7 kvB and pays a feerate of 25.18 sat/vByte. The output spent from the sanctioned address is 0.0002 BTC (20k sat) and was only created a day before. When ViaBTC mined block 808660, the transaction had been in my node’s mempool for about 75 minutes. It did not have any dependency on in-mempool transactions.
Examining the feerate distribution of block 808660 on miningpool.observer, reveals that ViaBTC occupied about 1 MWU worth of block space, of a total of 4 MWU, with prioritized transactions. These likely stem from the ViaBTC Bitcoin Transaction Accelerator. Prioritizing some transactions means that lower feerate transactions, such as the transaction spending from the sanctioned address here, don’t make it into the block. For this ViaBTC block, my miningpool-observer instance lists 24 large consolidation transactions at the end of the template that didn’t make it into this block.
This leads to the conclusion that ViaBTC did not filter this transaction. It got displaced by other, prioritized transactions. This is supported by the fact that, three days later, ViaBTC mined a transaction 5 spending an output from the same sanctioned address in block 809181.
Block 813231 by Foundry USA
..0a8528b66, mined by Foundry USA on October 21st,
2023, did not include the transaction
c9b57191..7. This transaction
consolidates 150 inputs into one output. One of the inputs spends an output
3PKiHs4GY4rFg8dpppNVPXGPqMX6K2cBML8. This address was
added to the OFAC’s SDN list on April 14th, 2023.
As most of the 150 inputs are 2-of-3 multisig P2SH scripts, the missing transaction is large at 43842 vByte. It pays a feerate of 5.09 sat/vByte and had no dependencies on in-mempool transactions. This feerate was enough to place it at position 161 out of 2215 transactions in the template constructed by my Bitcoin Core node. However, this transaction, along with 18 other transactions, had only been in my mempool for around 30 seconds when I learned about block 812331 by Foundry USA. This makes it likely that Foundry didn’t have a chance to include the transaction in their block because they didn’t know about it yet.
It might take a few seconds for the transaction to propagate. Additionally, most pools only push new block templates to miners every 30 seconds, which then take a while to switch to the new job. Furthermore, the miningpool-observer tool requests new block templates every few seconds and does best-effort matching based on the minimum difference in missing and extra transactions (see Methodology in the FAQ). This makes false-positives for young transactions, probably up to around 60 seconds, possible.
The mempool.space block explorer also keeps track of differences between block
templates and the final blocks broadcast by miners. They show that
included in their template but missing from the actual block. The transaction is
tagged “recently broadcasted” by them too.
This leads to the conclusion that Foundry USA did not filter this transaction. The transaction was broadcast too late to be included in the mining job that ended up finding block 813231. In addition, Foundry USA also mined the next block at height 813232 and included the sanctioned transaction there.
Blocks 810727, 811791, 811920, and 813357 by F2Pool
F2Pool mined the block 810727
..ccda1498 on October 5th, 2023, the blocks
..af4453d6 and 811920
..00badf62 on October 12th, and the block
..63ac1669 on October 22nd 9. Each block is missing one
sanctioned transaction10. Each of these transactions consolidates 150
2-of-3 multisig inputs into one output. For each transaction, one of the inputs
spends an output paid to
3PKiHs4GY4rFg8dpppNVPXGPqMX6K2cBML. This is the same
consolidation pattern and address as discussed in the previous section. None of
the missing transactions had a dependency on in-mempool transactions.
In block 810727, F2Pool did not include the transaction
which spends a sanctioned output. Due to the 150 2-of-3 multisig inputs, the
transaction is rather large at 44017 vBytes. It pays a fee of 446260 sat and
had been in my node’s mempool for nearly 4 hours when F2Pool mined block 810727.
c6a66836.., F2Pool chose to include the transaction
This transaction is also a consolidation transaction with 150 inputs and
one output, but does not spend from a sanctioned output. It pays the
same fee of 446260 sat but happens to be 3 vByte larger12
at 44020 vByte. This means the missing transaction
c6a66836.. has a
slightly higher feerate than
907e1f45... When strictly sorting by feerate,
the missing transaction should have been included. However, in practice, it’s
unlikely that 3 vByte of additional block space will make a difference in the
total fees in the block.
The sanctioned transaction
aa001ce6..10 is missing from F2Pools
block 811791. Similar to the previous consolidation transactions, this
transaction has a size of 42459 vBytes (169836 WU). With a fee of 446260 sat
it pays a feerate of 10.5 sat/vByte. When block 811791 arrived at the
miningpool-observer node, the transaction had been in its mempool for four
In this block, it’s notable that five transactions with OP_RETURN Stacks block commitments are missing. F2Pool has, however, inserted their own Stacks block commitment. This happens regularly and has been reported before. Additionally, F2Pool is including two large, zero-fee transactions in their block. One consolidates previous F2Pool coinbase outputs, and the other is a payout transaction to miners. This is common behavior for blocks mined by F2Pool.
While these extra transactions take up more than 400 kWU of block space, there
would still have been enough space to include transaction
aa001ce6... The block
includes 2.86 MWU of transactions below
aa001ce6..’s feerate of 10.5
sat/vByte. This transaction, with about 170 kWU, would have fit into the block.
On mempool.space, this transaction is marked as “removed”,
which negatively affects their block health metric.
In block 811920, F2Pool did not include transaction
which spends a sanctioned output. This transaction is a large consolidation
transaction as well. It has a size of 43630 vBytes (169836 WU) and, with a fee
of 44660 sat it pays a feerate of 10.23 sat/vByte. When block 811920
arrived at the miningpool-observer node, the transaction had been in the node’s
mempool for close to 2 minutes.
In block 811920, 1.44 MWU of transactions pay less than 10.23 sat/vByte.
The 170 kWU transaction
1cb3d6bc.. would have fit into the block. As
the transaction was in my node’s mempool for only close to two minutes, there
is a possibility that it didn’t yet propagate to F2Pool when they were
building their block template. The transaction is shown as “recently broadcast”
on mempool.space, too. Usually, mining pools
try to have good connectivity to the Bitcoin network. There is a high likelihood
that the transaction was in F2Pool’s mempool if it was in mempool.space’s and
In F2Pool’s block 813357, the transaction
which spends a sanctioned output, is missing. This consolidation transaction
has a size of 43053 vBytes (172209 WU). With a fee of 178504 sat it pays
a feerate of 4.15 sat/vByte. When block 813357 arrived at the
miningpool-observer node, the transaction had been in the node’s mempool for
more than 25 minutes.
There are 684 kWU of transactions paying below 4.15 sat/vByte in block 813357.
The 172 kWU transaction
e49cdb60.. would have fit into the block. As the
transaction was in my node’s mempool for more than 25 minutes, it’s unlikely that
the transaction didn’t propagate to one of F2Pools nodes yet. The transaction
was included in mempool-space’s template for block 813357
Conclusion on F2Pools blocks
The sanctioned transaction missing from block 810727 had a slightly higher feerate because it’s 3 vByte smaller than the included transaction. While, in this case, these 3 vBytes of extra block space wouldn’t have made a difference in total fees, the Bitcoin Core block templating algorithm would have chosen the transaction with the higher feerate. The large extra transactions included in block 811791 wouldn’t have had an effect on the sanctioned transaction missing from block 811791. It has likely been filtered from the block. The block audit on mempool.space agrees with this. There is a chance that F2Pool didn’t yet know about the missing sanctioned transaction from block 811920. However, 2 minutes should be enough for a large pool to receive a transaction. Especially since mempool.space and miningpool.observer knew about this transaction. It’s likely that this sanctioned transaction is missing because F2Pool filtered it. Similar to the missing transaction from block 811791, the missing transaction from block 813357 has likely been filtered by F2Pool.
These four missing sanctioned transactions lead to the conclusion that F2Pool
is currently filtering transactions. Since we’ve only seen transactions spending
from the single OFAC-sanctioned address
missing, we can’t tell if F2Pool is filtering this single address or all OFAC-
This post discusses six Bitcoin transactions spending from OFAC-sanctioned addresses that the miningpool-observer tool detected as missing from blocks. The two transactions missing from the ViaBTC and Foundry USA pool blocks are false-positives and not filtered. The four OFAC-sanctioned transactions missing from the F2Pool blocks are likely filtered. This raises the question of why F2Pool, a pool with origins in Asia, is the first pool to filter transactions based on US OFAC sanctions.
The Bitcoin network, however, continues to work as normal. A single pool filtering transactions does not affect the censorship resistance of the Bitcoin network as a whole. Further monitoring of the transaction selection of mining pools allows identifying when more pools start to filter transactions based on, for example, OFAC sanctions. It also allows miners pointing their hashrate to these pools to make an informed decision on switching to a different pool if they don’t agree with a pool’s (unannounced) filtering policies.
After publishing this blog post, F2Pool Co-Founder @satofishi tweeted that F2Pool was indeed filtering these transactions. He followed up with a statement that F2Pool would disable the filtering for now. Both tweets have since been deleted. The second tweet is archived on archive.ph. After deleting the tweet that the transaction filtering patch is disabled for now, it is unclear if F2Pool is still filtering transactions. 2
As all blocks with missing transactions didn’t come close to the sigop limit of 80.000, these aren’t discussed here. ↩︎
ViaBTC block 808660:
Transaction missing from block 808660:
cb9f2592..mined in block 809181 by ViaBTC is an Omnilayer transaction transferring 1528 USDT deposited to this address in September, 2020. The output to the sanctioned address
1ECeZBxCVJ8Wm2JSN3Cyc6rge2gnvD3W5Kfor this transaction was created similarly to the transaction
262025e7..missing from block 808660 in
I checked a few of these addresses and they all contained USDT balances on OmniLayer which were swept in these transactions. While this is a guess, it seems someone wanted to sweep the remaining USDT on a bunch of addresses, sent 20k sats to each of them, and messed up the sweep by consolidating the newly created outputs again in
262025e7... They then retried with
d11019a2..and successfully swept it with
If that’s the case, then OFAC is likely missing a bunch of addresses by the same entity on their list. ↩︎
Block 813231 mined by Foundry has the header hash:
Missing sanctioned transaction from block 813231 has the txid:
Based on OXT.me data, this address belongs to an OKEX wallet. The consolidation transaction↩︎
c9b57191..is OKEX consolidating deposits. The output being consolidated is, according to OXT.me, a Hydra darknet market payout. Additional information can be found here.
Missing, sanctioned transactions:
Slightly larger and thus lower feerate transaction F2Pool picked for block 810727:
Likely because it has fewer low-r nonces in the signatures which makes the signatures larger. ↩︎