An overview of recent non-standard Bitcoin transactions

Monday, January 29, 2024

This blog post provides an overview of non-standard transactions that mining pools included in the last 117000 Bitcoin blocks.

Usually, before a Bitcoin transaction is included in the blockchain, it is relayed between nodes on the Bitcoin P2P network and cached in their mempools. To mitigate some transaction relay Denial-of-Service attacks, the Bitcoin Core node limits what transactions can be relayed. Transactions deemed as “standard” are relayed, while “non-standard” transactions are not relayed. In Bitcoin Core, these rules are known as the policy rules. Mining pools can receive non-standard transactions out-of-band or loosen the relay rules to accept them over the P2P network. Non-standard transactions can be, and frequently are, mined.

This post provides an overview of recent non-standard transactions included by mining pools. Frequent non-standard transactions might show policy rules that need to be adapted or changed, while ensuring no Denial-of-Service attacks are made possible. Having an overview of which non-standard transactions are mined and who mines them can serve as basis for future policy design. Additionally, vulnerabilities in Bitcoin software came to light, which require mining non-standard transactions to be exploited. Some of these vulnerabilities have been exploited, while others have been responsibly disclosed. Some mining pools try to extract more value from blocks than just the block reward by including non-standard transaction. This is generally known as Miner Extractable Value (MEV). A large mining pool might be able to extract more value by investing heavily into their transaction selection software to out-compete smaller mining pools. This causes further mining pool centralization.

Methodology

To detect non-standard transactions, two nodes are used. A data-node and a test-node. The data-node has access to the full blocks that should be checked1. The test-node is synced to a height just below the test-start-height. It can be a pruned node. Now, beginning from the test-start-height, blocks are requested from the data-node. For each transaction in a block, excluding the coinbase transaction, we test if the transaction is accepted to the test-node’s mempool using the testmempoolaccept RPC call. If the transaction is rejected from the test-node’s mempool, then the transaction is non-standard. The rejection reason is recorded. If the transaction is accepted, it is submitted to the test-node with the sendrawtransaction RPC call. This makes sure child transactions aren’t rejected due to parents from the same block not being available. Once all transactions have been tested, the block is submitted to the test-node with the submitblock RPC call. This clears the mempool. The next block is tested until the chain tip is reached. This methodology is implemented in the quick and dirty tool github.com/0xB10C/find-non-standard-tx.

While this methodology reliably detects non-standard transactions, there are a few limitations. For example, there is only one reject reason returned for a transaction even if the transaction would be rejected for multiple reasons. Furthermore, descendants of rejected transactions can’t be added to the mempool as their inputs are missing. These have to be analyzed manually. The ordering in the block might not represent the order in which transactions entered the mempool. Usually, this isn’t a problem. However, for the CPFP carve-out rule to be applicable, the 25th descendant has to be added last. This results in one transaction being rejected with an “too-long-mempool-chain” when the CPFP carve-out rule was used (but also allows detecting and measuring the use of CPFP carve-out).

Non-standard transactions by rejection reason

Here, a start height of 710575 (2021-11-20) and an end height of 827622 (2024-01-27) was used, which results in about 117k blocks checked for non-standard transactions. The start height was chosen to be shorty after Taproot activation. A Bitcoin Core v26.0 node was used as test-node. The following overview does not cover all 20k non-standard transaction detected. Rather, it picks out a few interesting examples and tries to highlight the reasoning behind these non-standard transactions, where possible.

“bad-txns-nonstandard-inputs”

In January 2023, between block 771609 and block 773957, MaraPool included 16 non-standard transactions in their blocks. These were all rejected with the reason: bad-txns-nonstandard-inputs. In this case, the redeemScripts in the inputs have more sigops than allowed. This is related to Bitcoin Core PR #26348 by Sergio Demian Lerner, where he describes that the RSK sidechain migrated to a non-standard P2SH redeemscript with now more than 3000 BTC stuck on there. MaraPool helped RSK by mining the non-standard transactions. Sergio noted, that their tests on testnet passed. At the time, non-standard transactions were allowed by default on testnet. This was later changed in the Bitcoin Core PR #28354.

“tx-size”

As a protection against excessive resource usage, Bitcoin Core does not relay and rejects transactions larger than 100 kvB (400 kWU; MAX_STANDARD_TX_WEIGHT). These are rejected with the reason “tx-size”.

The Luxor pool mined the 985 kvB (3.94 MWU), zero-fee transaction 0301e0480b374b32851a9462db29dc19fe830a7f7d7a88b81612b9d42099c0ae 0301e0480b in block 774628 (2023-02-01). This transaction inscribes an 1803 × 1803 pixel JPEG showing a taproot wizard with a size of 3.9 MB and fills nearly the entire block.

Block 776884, mined by Terra Pool, includes the 850 kvB transaction b5a7e05f28d00e4a791759ad7b6bd6799d856693293ceeaad9b0bb93c8851f7f b5a7e05f28 , paying nearly 0.5 BTC in fees. The transaction inscribes a 1-minute MP4 music video showing a frog holding a drink. In block 777945, the ‎975 kvB transaction 79b91e594c03c8f06d70c44a288a88a413c540abca007829ca119686a7f979da 79b91e594c pays a fee of nearly 0.75 BTC to inscribe a 4000×5999 pixel WEBP image. The 992 kvB transaction 4af9047d8b4b6ffffaa5c74ee36d0506a6741ba6fc6b39fe20e4e08df799cf99 4af9047d8b , mined in block 786501, pays nearly 0.5 BTC in fees to inscribe a 2040×2653 pixel JPEG image of a Bitcoin Magazine cover with the face of Julian Assange.

F2Pool frequently includes larger-than-standard transaction in their blocks. These are mainly zero-fee mining pool payout transactions with one input and more than 3000 outputs. Examples are b460f758881bd1dd03da99ce6fb465637cbdcf6c6bb4664a4fedaf18d033e57f b460f75888 , 56c5b34eaca34967bc22dad74887339d94c620a6e33f3294e8ad2fbd24baa45e 56c5b34eac , and 8239fbb0da35b5f6bbbcff2a0c2b00d7b2f21efb47387bce6816b42e7fc3e61f 8239fbb0da .

There are two F2Pool transactions that are not pool payouts and stand out. The zero-fee transaction 7884712aae8685406c3b8f264fca151d76fc20ed3071d21275a6b6fc8dc2a82a 7884712aae has 800 inputs and 800 outputs, with a size just above 152 kvB. All inputs and outputs are 546 sat. This transaction moves F2Pool’s “uncommon sats”2 to a different address. Transaction 73be398c4bdc43709db7398106609eea2a7841aaf3a4fa2000dc18184faa2a7e 73be398c4b has a size of 125 kvB and pays the complete input amount of 0.03682719 BTC ($750 USD at the time) as fees. The only output is an OP_RETURN output with the message “you'll run cln. and you'll be happy.”. This transaction exploited a consensus bug in btcd causing, for example, LND, to stop processing new blocks. This transaction was constructed by brqgoo.

“non-mandatory-script-verify-flag”

The transaction 00c1af8f7d9e2bfe854d1718db078eb6740920f702bc00d4a9f205d3a084c40e 00c1af8f7d is non-standard with the reason “non-mandatory-script-verify-flag (OP_SUCCESSx reserved for soft-fork upgrades)”. This transaction has a size of 104 vB and pays a fee of 5000 sat. It was also constructed by brqgoo and, similar to the previous transaction, also includes an OP_SUCCESS. It was, however, mined before the transaction that exploited the consensus bug in LND and might have been a test transaction. The only output is an OP_RETURN with a 32 byte value, which could be a hash commitment to the later exploited vulnerability.

possible hash commitment: 5d86c2f206e5d9eb8c797035039ffac92ed94f794f9dab764be0ba40491dec47

“scriptpubkey” & “multi-op-return”

In block 826775, F2Pool mined transaction c3dd9ae8b5e9811514ef15238e0de96db8cf2f17ea4bdc41942e8c591c961a25 c3dd9ae8b5 , which included a 100 byte OP_RETURN message. Similarly, in block 826796, F2Pool mined transaction ee8bbff798c5b07cfdf0a7379fb8ef2e05d91fcfac2daacb21de30c1f007bf79 ee8bbff798 with a 686 byte OP_RETURN message, in block 827419 17ec5d70668578d7e572eb9f821741759d1fe4ee4d6ca82ce35cb051d54bcf20 17ec5d7066 and 2c869583a8dc9109ac60760c9cfbfdf25e34416a0e4ad858f096a5a38e1eedda 2c869583a8 with 111 byte and 400 byte OP_RETURN messages. OP_RETURN is, by default, limited to 80 bytes of data. These transactions were rejected with the reason “scriptpubkey”. F2Pool also mined the transactions cb22f12d777e95e426fd31840171af453c600390276d29d307ef34dbaeda4387 cb22f12d77 and 6f660e9f1bbfcc8435593eb8ff70a501275ad6cdbaa536747bd9d55bdbeda65a 6f660e9f1b , which have five and two OP_RETURN outputs. As, by default, only one OP_RETURN output is allowed, these are non-standard with the reason “multi-op-return”.

While these transactions are non-standard when using Bitcoin Core, they are standard when using Peter Todd’s “Libre Relay” patch. In particular, these changes allow large OP_RETURN messages and multi-OP_RETURN transactions. F2Pool might be running the “Libre Relay” patches.

While writing this blog post, more non-standard “scriptpubkey” transactions were mined by F2Pool. For example, the 3.22 kvB transaction 8c9fe58186c199fa9f8d72c121a45270f70d3854e67238f3c7c319989a50921b 8c9fe58186 encodes a PNG image and 33a271fd7782754e3a73fd1b791be920898317f73b1c77cf6b94d9d718bce701 33a271fd77 a GIF. For more transactions, see this tweet thread.

“min relay fee not met”

By default, Bitcoin Core has a minimum relay fee of 1 sat/vByte. Transactions below this feerate are rejected and not relayed to other nodes. These are often sent to the mining pool out-of-band. Some mining pools might opt to mine their own zero-fee transactions. By creating zero-fee transactions and using, for example, the prioritisetransaction RPC to assign a virtual fee, they avoid their transaction from being relayed but still can get it accepted into their mempool. If they construct a transaction that pays a fee, they risk that it’s relayed to another pool and pays a competing mining pool. Additionally, depending on the mining pool’s payout and fee structure, including their own zero-fee transactions might shift the transaction fee costs to their miners. As the pool’s zero-fee transaction takes up block space, it reduces the transaction fees earned by their miners. The miners might not be aware of being exploited by the pool.

ECMD Pool mined b1360f73a7a990d5210ac43482ec4de83b76c3932522702dca6b9bb5f6468261 b1360f73a7 paying 7400 sat at 14 kvB resulting in a 0.52 sat/vB feerate. This transaction consolidates 96 inputs to the sending address and sends 43k USDT (Omnilayer) to Huobi3 in a nearly-dust output. The consolidated inputs don’t seem to stem from EMCD Pool themself. It’s unclear why the transaction did not pay more than the minimum relay fee of 1 sat/vByte. The output of the transaction was spent in the same block with a feerate of 89.1 sat/vB4. While this results in an effective feerate of over 2 sat/vB through CPFP, the first transaction would not have been relayed.

Transaction 9ffad0add040094e7d61dd021a2750eebd034042467b0ce0dbc3f4a4b3aac07d 9ffad0add0 , paying a feerate of 0.43 sat/vB with a fee of 7701 sat and a size of 17 kvB, was mined by SBICrypto. It consolidates 100 inputs into a single output. The addresses belong to the freebitco.in entity3. Why freebitco.in constructed a transaction paying below the minimum relay feerate is not known.

The transaction 4da9b2ab358a76c0dd9067b91f07078e25b77c82439fe58450ae206c3deb4464 4da9b2ab35 was mined by an unidentified pool5. It does not pay fees and script-path-spends a 2-of-2 multisig P2TR output. The parent transaction creates an OP_RETURN output with a valid but unused bech32 address bc1qypz2ynlgy3dmpqxxvap2s30wjfqcp24tk46p83. It’s unknown why the transaction does not pay fees.

The mining pool Terra Pool mined the zero-fee transaction 1a6466600e05ccf5b63ded29d4a1a067ce33b79cd1252754ead733f21fae1775 1a6466600e in block 811775 creating a 10k sat output. The output was directly consumed by the next, also a zero-fee, transaction f9aa65bb55baa3e2ba95deac89afc99d28934cdb613e72abe20b1f25a0c848ee f9aa65bb55 in the same block. It inscribes a “Clean Bitcoin Certificate”. In a block mined by a “Clean Incentive” pool, the transaction d2a769546e9182d8b23765850e3ef605eec48fe641822bcce86594417072c96b d2a769546e creates an additional 10k sat output. This output, and the previously inscribed certificate, are then consumed by another zero-fee transaction, ed8819d17dbd6ab0d934b24d1e6dadd6bcd7b91866a9a235a081576421c68022 ed8819d17d , which inscribes an accompanying JSON object with more information about the certificate. This is later moved in yet another zero-fee transaction 7cc18418b814a1e9fe731e630e638201c36bf45e1f20aa084e0182a43cdc8174 7cc18418b8 , where a collection of inscriptions is inscribed.

The same pool also mined the zero-fee transaction 699e9a96320465223172d739e0fb8723c5951314e4aba31d9ed7d1703b5b07d0 699e9a9632 , which has one input and one output. It spends a 1-of-2 P2SH output created in the same block. The 1-of-2 multisig is composed of two public keys with well-known private keys. The private keys are 1 and 26. The transaction creating the multisig output has a feerate of 3.9 sat/vB and is the first transaction in the block after the coinbase. As the remaining transactions in the block pay a significantly higher feerate, this is an indication the transaction was manually prioritized by the pool. The pool might run a tool that checking for UTXOs spendable with well-known private keys, and tries to spend and mine them before someone else does 7.

MaraPool mined the zero-fee transaction 0026faeccb25b9837ccf9d8e7b88f676669967263bcd8d5de1b55fedb08a328d 0026faeccb , which script-path-spends a single P2TR output from a depth-2 merkle tree, revealing a 1-of-1 multisig. The parent transaction has an OP_RETURN output with the data cc1qjdexdhgqu95zfkvw20vfn3uh9r6s563y86qpsd. It’s unclear why MaraPool mined this zero-fee transaction.

F2Pool frequently mines zero-fee transactions. These are mainly consolidations of their coinbase outputs and pool payout transactions8. An example for a coinbase consolidation is transaction 11887bfc724d3486b7da3e70cf13cc992f16e25273b3a685a70a7890957310e5 11887bfc72 . It consolidates 21 inputs from 1KFHE7w8BhaENAswwryaoccDb6qcT6DbYY, the well-known F2Pool coinbase output address, into two outputs paying no fees.

However, it seems F2Pool is also using zero-fee transactions for payments to Huobi (44335aef14) and Binance (a5c062118a). While these are small, one-input two-output transaction and don’t take up much block space, they reduce the fees earned in the block and the payout distributed to F2Pool’s miners.

In block 730459, F2Pool mined the zero-fee, one-input one-output transaction 26a9e3872fadcee3144aae6629e887500d33813217b5447d2fb8e5ae6e5e0329 26a9e3872f , which moved 3900 BTC from 1J1F3U7gHrCjsEsRimDJ3oYBiV24wA8FuV to the same address. While this seems pointless at first, one explain could be that there existed an alternative, (pre-) signed transaction spending this UTXO. To invalidate this transaction, the UTXO was spent. The transactions 03e43f5e2877a48c253cd9e05be63805f2717c47bf1bc7c1b210e43309e6899c 03e43f5e28 and 68e129eb0a00cf8d9717e33ba213c9a9849989b9ccfe57b6ea0275c38d2f8cf0 68e129eb0a are similar occurrences.

F2Pool also transferred it’s “uncommon sats”2 to another address in the‎38 kvB transaction 9f62795a4766409d7e32e2ca6a9e3565284cdbaa31a25687249e40cd80671049 9f62795a47 . This transaction has 200 inputs and 200 outputs worth 546 sat each. F2Pool sells “uncommon sats”2, starting at 450 USD for a single 546 sat UTXO7.

“dust”

Bitcoin Core treats low value outputs as non-standard or “dust”, when the output value is lower than the cost of creating and spending it. Dust UTXOs aren’t economical to spend and pollutes the UTXO set. F2Pool is the mining pool that frequently mines transactions, creating “dust” outputs.

In the Stacks 2.0 mining protocol, stacks-miners try to get their commit transaction into the next block by paying a high fee. In their commit transaction, they include, as a proof-of-transfer, two outputs to two other stack miners. The higher the (bitcoin) amount of these outputs, compared to the other stack-miners competing for the same block, the higher the probability to mine the Stacks block and be rewarded. There is no minimal proof-of-transfer amount besides the Bitcoin dust limit. F2Pool is using their position as a mining pool to their advantage7. They filter all stacks block commits broadcast by other stacks-miners. This allows them to include only their own commit transaction in their block. In this zero-fee transaction, they pay dust outputs to two other stack-miners. This allows them to have a 100% probability of being rewarded while only having to spend a few sats.

F2Pool creates other dust outputs too. In the zero-fee transaction 638d8cf6da03eef9ccfdd6505782be98bb7c3b909dc650eef32a910dd0d74c2f 638d8cf6da , F2Pool splits their “uncommon sats”2 from some of their coinbase payout outputs into separate UTXOs. While these separate UTXOs all have a value of 546 sat, there is one UTXO created with a value of 330 sat, which makes it a dust output. On the output, according to the ordinal theory, a portrait of a frog in a suit is inscribed. This inscription was inscribed about 40k blocks before F2Pool split these out. The inscription somehow made its way to one of F2Pool’s addresses.

F2Pool also mined the one-input two-output transaction d82e322d9dc3ccd7b69450cc29c42b9da2576aa4184e4d4620f45bb9e269ff27 d82e322d9d , which creates a 250 sat dust output. It’s unclear why this transaction was included by F2Pool. The transaction 38086f6079c9eeb1e1a637600645e99982281f5f8ee23dd9680d879b9e7da204 38086f6079 creates two dust outputs and was sent to F2Pool out-of-band. The story behind this transaction can be found on Twitter.

F2Pool mined the one-input and one-output transaction 2814d0a3c9e6dd5b88911a6280fc3899391f5c47072eb11593af2838160fad2f 2814d0a3c9 , paying a fee of 10k sat. The output has a value of zero, which is below the dust limit. This zero-value output is spent in transaction c1e0db6368a43f5589352ed44aa1ff9af33410e4a9fd9be0f6ac42d9e4117151 c1e0db6368 , which inscribes a text inscription you will use soma and you will like it and creates another zero-output. An inscription on a zero-value output broke the ordinals index. These transactions were created by supertestnet, who later released his code in a tool called breaker-of-jpegs.

There are plenty of other cases where F2Pool included transactions that create outputs below the dust limit. This could indicate that they use a lower dust limit than what’s set by default.

“too-long-mempool-chain”

By default, Bitcoin Core limits the number of in-mempool descendants a transaction can have to less than 25. An exception is the CPFP carve out rule, which allows a single, small child of the top most ancestor transaction. When these limits are exceeded, transactions are rejected with the “too-long-mempool-chain” reason. These transactions are usually standard on their own but aren’t accepted into the mempool at the same time.

In block 788839, ViaBTC included multiple ancestry sets with more than 200 transactions in total. These would have been rejected from a default mempool. These sets include the transactions 6cd3e204ae299952e30acf4a7c5c337a6a0310b5a58e081199b2d17c7aec504e 6cd3e204ae and 174f1695d537fd21455b3a195a3dac6c430c0060b986ecc8bea5fa8c6d32ef09 174f1695d5 . Both ancestry sets are related to minting BRC-20 tokens.

In block 789149, AntPool mined an ancestor transaction A d4431ed437bce8de22c1c134c6cd9427f5eb08e7b401d7152be936fed58848d0 d4431ed437 with 28 descendants as part of an BRC-20 token mint. With default Bitcoin Core rules, only 24 children would have been allowed.

'A' is an ancestor transaction with 28 descendants. The arrow direction shows a 'is-parent-of' relationship between the transactions.
‘A’ is an ancestor transaction with 28 descendants. The arrow direction shows a ‘is-parent-of’ relationship between the transactions.

In block 802625, F2Pool mined an ancestor A 1a4fa7cadc072f1937da9857531950069776e2742c7b15b04f3ef9292a46d50b 1a4fa7cadc with two descendants. The children are rejected from a default mempool with the reason “too-long-mempool-chain”. Here, the ancestry set is clearly under the limit of 25 transactions. However, the ancestor A has a size of 52 kvB, child 1 a size of 60 kvB, and 2 a size of‎70 kvB. The default Bitcoin Core configuration only allows an ancestry set to have a maximum size of 101 kvB (DEFAULT_ANCESTOR_SIZE_LIMIT_KVB). Transaction A and child 1 together already exceed this limit. These transactions seem related to the KuCoin exchange3.

'A' is an ancestor transaction with two descendants. The arrow direction shows a 'is-parent-of' relationship between the transactions.
‘A’ is an ancestor transaction with two descendants. The arrow direction shows a ‘is-parent-of’ relationship between the transactions.

As mentioned in the methodology limitations, occurrences of CPFP carve out are incorrectly rejected with “too-long-mempool-chain”. The ordering in the block is different from the valid mempool submission order. An example is 0b9900440d01600e0589a855fb9d9393860b65a3e0f76a8fc8915385d43ae3e9 0b9900440d mined by Binance Pool. This ancestor transaction A has a child transaction 1. Transaction 1 has transaction 2 through 24 as children. This is the maximum number of allowed children. Transaction 25 is a direct child of the ancestor A and has a size smaller than 1000 vB, which makes it a valid CPFP carve out. Future work could closer analyze how the CPFP carve out rule is being used on the network.

'A' is an ancestor transaction with 25 descendants. Transaction '25' is an example of a CPFP carve out. Here, arrow direction shows a 'is-parent-of' relationship between the transactions.
‘A’ is an ancestor transaction with 25 descendants. Transaction ‘25’ is an example of a CPFP carve out. Here, arrow direction shows a ‘is-parent-of’ relationship between the transactions.

Conclusion

Non-standard transactions are frequently included by mining pools. While some pools occasionally help community members by, for example, mining UTXOs stuck on non-standard scripts, other pools use their position as pool to extract more value from blocks. The F2Pool mining pool is clearly the pool having the least strict standardness rules and, from time to time, they accept to mine transactions that exploit vulnerabilities in Bitcoin related software. The recent non-standard transactions don’t immediately show standardness rules that need to be changed.


  1. An alternative to a data node could be a block explorer API serving the full blocks. ↩︎

  2. https://docs.ordinals.com/overview.html ↩︎ ↩︎ ↩︎ ↩︎

  3. According to OXT.me. ↩︎ ↩︎ ↩︎

  4. And it tries to double spent the 43k USDT. https://omniexplorer.info/search/05abfed93a56683ac909e1e0142c0f90f1180e04ba42b18841abcc7c820809d0 ↩︎

  5. https://github.com/bitcoin-data/mining-pools/issues/102 ↩︎

  6. The private key 1 corresponds to the address 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH and the private key 2 to the address 1cMh228HTCiwS8ZsaakH8A8wze1JR5ZsP. The particular P2SH address used here is 38fEX6RbBBMmpu3nbbuULku1xyrrzqqqnE. This is a 1-of-2 and a 1-or-2 multisig! ↩︎

  7. This is MEV. ↩︎ ↩︎ ↩︎

  8. These are usually too large and listed under the tx-size section. ↩︎

All text and images in this work are licensed under a Creative Commons Attribution-ShareAlike 4.0 International License Creative Commons License

Next

Image for ViaBTC's mutated blocks without witness data

March 18, 2024

ViaBTC's mutated blocks without witness data

I noticed multiple ERROR: AcceptBlock: bad-witness-nonce-size errors in the debug log of my Bitcoin Core node. These indicate that a block my node received is invalid and not accepted. It turned out that these are ViaBTC’s blocks, broadcast by their mining pool software, where transaction witness data is missing. In this post, I’ve written down my notes on this observation.

Previous

Image for Six OFAC-sanctioned transactions missing

November 20, 2023

Six OFAC-sanctioned transactions missing

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.