Remove arbitrary limits on OP_Return (datacarrier) outputs #32359

pull petertodd wants to merge 7 commits into bitcoin:master from petertodd:2025-op-return changing 30 files +93 −197
  1. petertodd commented at 8:52 pm on April 27, 2025: contributor

    As per recent bitcoindev mailing list discussion.

    Also removes the code to enforce those limits, including the -datacarrier and -datacarriersize config options.

    These limits are easily bypassed by both direct submission to miner mempools (e.g. MARA Slipstream), and forks of Bitcoin Core that do not enforce them (e.g. Libre Relay). Secondly, protocols are bypassing them by simply publishing data in other ways, such as unspendable outputs and scriptsigs.

    The form of datacarrier outputs remains standardized: a single OP_Return followed by zero or more data pushes; non-data opcodes remain non-standard.

    CC: sipa darosior

  2. DrahtBot commented at 8:52 pm on April 27, 2025: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32359.

    Reviews

    See the guideline for information on the review process.

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #32406 (policy: uncap datacarrier by default by instagibbs)
    • #32368 (Catch harmful arbitrary data. (missing code for #32359) by Retropex)
    • #32133 (RFC: Accept non-std transactions in Testnet4 by default again by fjahr)
    • #29954 (RPC: Return permitbaremultisig and maxdatacarriersize in getmempoolinfo by kristapsk)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  3. DrahtBot added the label CI failed on Apr 27, 2025
  4. DrahtBot commented at 9:01 pm on April 27, 2025: contributor

    🚧 At least one of the CI tasks failed. Debug: previous releases, depends DEBUG https://github.com/bitcoin/bitcoin/runs/41237737205 LLM reason (✨ experimental): (empty)

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  5. petertodd force-pushed on Apr 27, 2025
  6. Remove arbitrary limits on OP_Return (datacarrier) outputs
    Also removes the code to enforce those limits, including the
    `-datacarrier` and `-datacarriersize` config options.
    
    These limits are easily bypassed by both direct submission to miner
    mempools (e.g. MARA Slipstream), and forks of Bitcoin Core that do not
    enforce them (e.g. Libre Relay). Secondly, protocols are bypassing them
    by simply publishing data in other ways, such as unspendable outputs and
    scriptsigs.
    
    The *form* of datacarrier outputs remains standardized: a single
    OP_Return followed by zero or more data pushes; non-data opcodes remain
    non-standard.
    cd7872ca54
  7. petertodd force-pushed on Apr 27, 2025
  8. luke-jr commented at 9:14 pm on April 27, 2025: member
    As per ML discussion, firm Concept NACK.
  9. darosior commented at 9:21 pm on April 27, 2025: member
    Concept ACK.
  10. BitcoinMechanic commented at 9:21 pm on April 27, 2025: none
    Concept NACK. Hard to take this seriously. Those config options not having direct impact over what miners may put in blocks does not equate to users no longer having a choice over what ends up in their mempools.
  11. Retropex commented at 9:36 pm on April 27, 2025: none

    Concept NACK. If miners want larger datacarrier transactions, they can use these settings to do so.

    There’s no reason to prevent miners and node runners from making this choice.

  12. 1ma commented at 9:41 pm on April 27, 2025: none

    Again? #28130

    Concept NACK, for the same reasons already discussed 2 years ago.

  13. petertodd commented at 9:43 pm on April 27, 2025: contributor

    @1ma Please read the relevant mailing list discussion first: https://groups.google.com/g/bitcoindev/c/d6ZO7gXGYbQ

    There are good reasons why this is being brought up again.

  14. 1ma commented at 9:51 pm on April 27, 2025: none

    Already did. I’m actually waiting for someone to add a new message so I can add mine with the data I gathered (just joined the mailing list).

    If you care to actually look at the blockchain turns out no one is trying to get large OP_RETURNs mined: https://github.com/1ma/blockstats

  15. petertodd commented at 10:04 pm on April 27, 2025: contributor

    @1ma As was discussed in the mailing list discussion, entities are using unspendable outputs in liu of OP_Return outputs. Precisely because of the size limit. This increases the UTXO set size unnecessarily, a harmful effect of having the arbitrary OP_Return output limitations. Your analysis does not take that kind of issue into account.

    Rather than do a stream of incremental increases, wasting dev bandwidth, this pull-req simply removes those arbitrary limits.

    Anyway, this kind of non-technical discussion seems off-topic for this pull-req. Best to do it on the mailing list. And furthermore, people have choice - Knots exists. If they wish to enforce these limits on their own nodes they’re welcome to run Knots. There’s no reason why Bitcoin Core should be forced to take on the maintenance burden of maintaining arbitrary limits that we believe are ineffective, and even harmful.

  16. Rob1Ham commented at 10:06 pm on April 27, 2025: none
    Concept ACK. Better to have provable unspendable outputs than dust outputs forever in the utxo set.
  17. BitcoinMechanic commented at 10:06 pm on April 27, 2025: none

    entities are using unspendable outputs in liu of OP_Return outputs. Precisely because of the size limit.

    Schrödinger’s spamfilters. They work/don’t work whenever is convenient for people trying to turn nodes into unpaid cloud storage.

  18. DrahtBot removed the label CI failed on Apr 27, 2025
  19. 1ma commented at 10:12 pm on April 27, 2025: none
    @petertodd @Rob1Ham Sounds like a new standardness rule is called for, not removing existing ones.
  20. DrahtBot requested review from darosior on Apr 27, 2025
  21. Retropex commented at 10:29 pm on April 27, 2025: none
    @petertodd, if you genuinely want to promote OP_RETURN for the network’s health, this PR should include a similar filter like #28408.
  22. petertodd commented at 10:41 pm on April 27, 2025: contributor
    @Retropex Data publishing via unspendable UTXOs is undetectable. We can’t block it without significant changes to the consensus protocol.
  23. jlopp commented at 10:59 pm on April 27, 2025: contributor

    Concept ACK.

    It’s time to come to terms with the fact that Bitcoin is desirable for some people to use as a data anchor and they will find a way to use it as such, thus we should be asking what the preferred means of data anchoring is and how to incentivize it over less preferable options.

  24. polespinasa commented at 11:02 pm on April 27, 2025: contributor

    I could cACK on removing those limits by default, but:

    Also removes the code to enforce those limits, including the -datacarrier and -datacarriersize config options.

    Concept nack to this. The code is already there, I don’t see the point of taking away users configuration options to their mempool policies.

  25. luke-jr commented at 11:04 pm on April 27, 2025: member

    Data publishing via unspendable UTXOs is undetectable. We can’t block it without significant changes to the consensus protocol.

    This is false. It would require invasive changes to the address format (and disabling old address formats), but there are no consensus changes required.

  26. petertodd commented at 11:19 pm on April 27, 2025: contributor

    This is false. It would require invasive changes to the address format (and disabling old address formats), but there are no consensus changes required.

    You are referring to standardness rules, which can be easily bypassed Consensus changes are required to have any hope of actually preventing the publication of data.

    Besides, deprecating old address formats to “fight spam” — an enormously costly ecosystem wide change — is clearly unlikely to happen. Not least of which because it would be ineffective. Similarly, the consensus changes that could in theory prevent most (but not all) data publication are also clearly unlikely to happen.

  27. petertodd commented at 11:20 pm on April 27, 2025: contributor

    @polespinasa

    I don’t see the point of taking away users configuration options to their mempool policies.

    We did exactly that with Full-RBF, because the policies of individual nodes are unable to prevent profitable transactions from being broadcast and mined. Full-RBF reached ~100% miner adoption before Bitcoin Core even released a version with it enabled by default.

  28. nsvrn commented at 11:25 pm on April 27, 2025: contributor

    Anyway, this kind of non-technical discussion seems off-topic for this pull-req. Best to do it on the mailing list. And furthermore, people have choice - Knots exists. If they wish to enforce these limits on their own nodes they’re welcome to run Knots. There’s no reason why Bitcoin Core should be forced to take on the maintenance burden of maintaining arbitrary limits that we believe are ineffective, and even harmful.

    Concept NACK

    There are certainly users who are using these config options(including Core users and on UI of packaged software like Umbrel etc.), removing useful optionality that already exists is completely bogus. What kind of maintenance burden this has been for the “we”(whoever that refers to) as claimed, sounds like a made up claim to achieve your end goal.

  29. jesterhodl commented at 11:29 pm on April 27, 2025: none

    Removing an easy way for bitcoin users to precisely express their preference as to how their node works is like trying to centrally plan an economic system. It will end up in suboptimal results, which nobody will be happy of except non-monetary applications and related beneficiaries.

    ML talk references Citrea. The PR seems to anticipate some company’s mere intent. Are we now shapeshifting Bitcoin to whatever people publish they might be doing? Bitcoin has a purpose and it’s not appeasement.

    As a node runner I Concept NACK on both grounds.

  30. libertyluminary commented at 0:02 am on April 28, 2025: none
    This literally advocates for a reduction in sovereignty of node runners to choose how to config their node. Why do so many people hate freedom?
  31. pinheadmz commented at 0:04 am on April 28, 2025: member

    This is apparently a controversial issue and so this thread will be watched closely for moderation. Please make sure all comments are technical in nature, and on topic: the topic is the title, description, and code changes of this pull request. References to people will result in 24 hour ban, to start.

    edit: criticism of people, not of ideas, will result in a ban. See https://github.com/bitcoin-core/meta/blob/main/MODERATION-GUIDELINES.md

  32. Christewart commented at 1:06 am on April 28, 2025: contributor
    concept ACK
  33. benthecarman commented at 2:37 am on April 28, 2025: contributor
    huge concept ack removing the incentive to bloat the utxo set is definitely needed
  34. chrisguida commented at 4:10 am on April 28, 2025: none

    Concept NACK

    The proper response to a spam attack is not to cave to the spammers. This will only embolden them. If our rationale for loosening the restrictions is “a bunch of degenerates want to gamble on the blockchain, so that means there’s lots of economic demand for such transactions”, then that will become a self-fulfilling prophecy… indeed it already has. Thus the spammers’ claim to using bitcoin as a dump-bucket for their altcoin Ponzis will only become stronger over time, while people just trying to use bitcoin to pay for stuff will get crowded out over time. Since fiat VC funding heavily favors the altcoin Ponzis over real-world use cases, it is inevitable that this slippery slope will eventually lead to bitcoin being impossible to use for payments.

    The best time to turn on spam filters was a couple of years ago, swiftly and decisively. Since we didn’t manage that, the second best time is now.

  35. wizkid057 commented at 5:22 am on April 28, 2025: none

    Concept NACK

    OP_RETURN was only ever made standard at all as a tolerated form of data carrying to prevent more harmful forms of data carrying (fake pubkeys/script hashes/bare multisig/etc). To serve that purpose, it only needs to be ~40 bytes. The ~80 byte allowance is beyond sufficient for its intended purpose.

    Arbitrary data in transactions was never an intended use case of the network, the resources of nodes, etc.

    We should be a) leaving this as-is for now, b) fixing standardness policies to slow down other forms of data carrying, and c) considering as part of an eventual fork to change to addresses that prevent data carrying all together (and make OP_RETURN non-standard again simultaneously)

    Bitcoin is money. It’s not a place for people to cheaply dump their garbage for the world to store for eternity.

    The fact that anyone ACK’d this is absolutely insane to me.

  36. Seccour commented at 6:08 am on April 28, 2025: none

    Also removes the code to enforce those limits, including the -datacarrier and -datacarriersize config options.

    Concept NACK

    • Just giving up on fighting spam because they found a new way of spamming is the opposite of what we should do. We should double down and find a way to fight the spam instead of embracing it.

    • Core should give bitcoiners more freedom on what rules they want to enforce, not the opposite. Removing config options is the opposite of what should be done.

  37. torkelrogstad commented at 6:42 am on April 28, 2025: contributor
    Concept ACK
  38. Sjors commented at 9:58 am on April 28, 2025: member

    Concept ACK

    Moderation suggestion: close to non-contributors.

    It’s a bit draconian, but it’s hard to review code in a pull request that’s being brigaded, which unfortunately often happens when OP_RETURN or full RBF is involved. At the same time this isn’t a technically difficult PR that needs thousands of eyes on it. Even if a non-contributor finds a bug and can’t report it here, there’s plenty of time to fix it in a followup.

    The conceptual discusion should be continued on the mailinglist, but even there it’s counter productive to say things without first reading earlier discussions.

    I would also suggest that people who really want to continue filtering OP_RETURN transactions, release a simple fork of Bitcoin Core. Such a patch is relatively straight-forward to maintain and thanks to deterministic guix builds, easy for anyone to audit. @polespinasa wrote:

    The code is already there

    Removing code reduces long term maintenance cost. Not all code is equal; for code that enforces standardness it’s critical there are no bugs in it, so it requires a lot more review / attention / maintenance than other areas.

    On the one hand it’s only a small part of standardness code, hasn’t changed in a long time and afaik doesn’t cause technical headache in other areas of the code. Reducing code complexity is certainly not the main reason for this PR, but it’s a nice extra.

    On the other hand, any time this code is touched there’s a risk of of drama, which is a huge resource drain (and therefore comes with opportunity cost).


    The form of datacarrier outputs remains standardized: a single OP_Return followed by zero or more data pushes; non-data opcodes remain non-standard.

    Probably worth keeping mempool_datacarrier.py around to at least test this aspect. Alternatively, you could replace the check you dropped from mempool_accept.py with one that looks for scriptpubkey.

    I’ll continue code review in a bit.

  39. michael1011 commented at 10:00 am on April 28, 2025: none
    Concept ACK
  40. laanwj added the label TX fees and policy on Apr 28, 2025
  41. 1ma commented at 10:30 am on April 28, 2025: none
    @Sjors are you not interested in the feedback of the end users of the software?
  42. Sjors commented at 10:41 am on April 28, 2025: member

    @Sjors are you not interested in the feedback of the end users of the software?

    Yes, but brigading is generally done by a very small group of users that don’t represent the whole ecosystem. And we already know the reasons some people insist on keeping limits on OP_RETURN. That’s why I suggested releasing a forked version of the software for those people (and I would recommend against running it, but it’s your decision).

    So the net result of these comments are distraction with no new useful information.

  43. jesterhodl commented at 10:49 am on April 28, 2025: none

    This is apparently a controversial issue and so this thread will be watched closely for moderation. Please make sure all comments are technical in nature, and on topic: the topic is the title, description, and code changes of this pull request. References to people will result in 24 hour ban, to start.

    edit: criticism of people, not of ideas, will result in a ban. See https://github.com/bitcoin-core/meta/blob/main/MODERATION-GUIDELINES.md

    When an issue is controversial it means it must be treated carefully as it is far from unanimous support. As it stands, it should not merged.

  44. in test/functional/mining_basic.py:286 in cd7872ca54 outdated
    283+        # Restart the node
    284         LARGE_TXS_COUNT = 10
    285         LARGE_VSIZE = int(((MAX_BLOCK_WEIGHT - DEFAULT_BLOCK_RESERVED_WEIGHT) / WITNESS_SCALE_FACTOR) / LARGE_TXS_COUNT)
    286         HIGH_FEERATE = Decimal("0.0003")
    287-        self.restart_node(0, extra_args=[f"-datacarriersize={LARGE_VSIZE}"])
    288+        self.restart_node(0)
    


    Sjors commented at 1:20 pm on April 28, 2025:

    I found myself confused why this restart is still needed. It’s because the previous test used -persistmempool=0 and we need to forget about the transaction it created.

     0diff --git a/test/functional/mining_basic.py b/test/functional/mining_basic.py
     1index cbb1cf789e..85c0f38291 100755
     2--- a/test/functional/mining_basic.py
     3+++ b/test/functional/mining_basic.py
     4@@ -186,6 +186,9 @@ class MiningTest(BitcoinTestFramework):
     5             assert tx_below_min_feerate['txid'] not in block_template_txids
     6             assert tx_below_min_feerate['txid'] not in block_txids
     7
     8+        # Restart node to clear mempool for the next test
     9+        self.restart_node(0)
    10+
    11     def test_timewarp(self):
    12         self.log.info("Test timewarp attack mitigation (BIP94)")
    13         node = self.nodes[0]
    14@@ -279,11 +282,9 @@ class MiningTest(BitcoinTestFramework):
    15     def test_block_max_weight(self):
    16         self.log.info("Testing default and custom -blockmaxweight startup options.")
    17
    18-        # Restart the node
    19         LARGE_TXS_COUNT = 10
    20         LARGE_VSIZE = int(((MAX_BLOCK_WEIGHT - DEFAULT_BLOCK_RESERVED_WEIGHT) / WITNESS_SCALE_FACTOR) / LARGE_TXS_COUNT)
    21         HIGH_FEERATE = Decimal("0.0003")
    22-        self.restart_node(0)
    23
    24         # Ensure the mempool is empty
    

    petertodd commented at 8:18 pm on April 28, 2025:
    I’ve applied that patch as-is.
  45. in test/functional/mempool_accept.py:335 in cd7872ca54 outdated
    330-        tx.vout[0].scriptPubKey = CScript([OP_RETURN, b'\xff'])
    331-        tx.vout = [tx.vout[0]] * 2
    332-        self.check_mempool_result(
    333-            result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'multi-op-return'}],
    334-            rawtxs=[tx.serialize().hex()],
    335-        )
    


    Sjors commented at 1:54 pm on April 28, 2025:
     0diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py
     1index f4b21cd204..609d826a6f 100755
     2--- a/test/functional/mempool_accept.py
     3+++ b/test/functional/mempool_accept.py
     4@@ -327,6 +327,26 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
     5             rawtxs=[tx.serialize().hex()],
     6         )
     7
     8+        # OP_RETURN followed by non-push
     9+        tx = tx_from_hex(raw_tx_reference)
    10+        tx.vout[0].scriptPubKey = CScript([OP_RETURN, OP_HASH160])
    11+        tx.vout = [tx.vout[0]] * 2
    12+        self.check_mempool_result(
    13+            result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'scriptpubkey'}],
    14+            rawtxs=[tx.serialize().hex()],
    15+        )
    16+
    17+        # Multiple OP_RETURN and more than 83 bytes are standard since v30
    18+        tx = tx_from_hex(raw_tx_reference)
    19+        tx.vout.append(CTxOut(0, CScript([OP_RETURN, b'\xff'])))
    20+        tx.vout.append(CTxOut(0, CScript([OP_RETURN, b'\xff' * 90])))
    21+
    22+        self.check_mempool_result(
    23+            result_expected=[{'txid': tx.rehash(), 'allowed': True, 'vsize': tx.get_vsize(), 'fees': {'base': Decimal('0.05')}}],
    24+            rawtxs=[tx.serialize().hex()],
    25+            maxfeerate=0
    26+        )
    27+
    28         self.log.info('A timelocked transaction')
    29         tx = tx_from_hex(raw_tx_reference)
    30         tx.vin[0].nSequence -= 1  # Should be non-max, so locktime is not ignored
    

    petertodd commented at 8:20 pm on April 28, 2025:
    So we actually test the OP_RETURN followed by non-push in src/test/transaction_tests.cpp. But it wouldn’t hurt to test it separately in terms of mempool-acceptance.

    petertodd commented at 8:24 pm on April 28, 2025:
    I included this patch and @darosior’s patch verbatim.
  46. in src/test/transaction_tests.cpp:869 in cd7872ca54 outdated
    865-
    866-    // MAX_OP_RETURN_RELAY+1-byte TxoutType::NULL_DATA (non-standard)
    867+    // TxoutType::NULL_DATA
    868     t.vout[0].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800"_hex;
    869-    BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY + 1, t.vout[0].scriptPubKey.size());
    870-    CheckIsNotStandard(t, "scriptpubkey");
    


    Sjors commented at 1:56 pm on April 28, 2025:
    0// Until v30 OP_RETURN was limited to 83 bytes (80 bytes of data, +1 for
    1// OP_RETURN, +2 for the pushdata opcodes). Add one more byte.
    

    petertodd commented at 8:15 pm on April 28, 2025:
    Added comment.
  47. Sjors commented at 2:00 pm on April 28, 2025: member

    cd7872ca543d31d20f419fd2203138b8301c2e68 looks good other than what I said above: we should make sure the push-only standardness rule is both tested and illustrated. See inline suggestions.

    This PR removes more (test) code than I expected, which is good.

  48. in test/functional/mempool_package_rbf.py:36 in cd7872ca54 outdated
    32@@ -33,7 +33,6 @@ def set_test_params(self):
    33         self.setup_clean_chain = True
    34         # Required for fill_mempool()
    35         self.extra_args = [[
    36-            "-datacarriersize=100000",
    


    darosior commented at 2:02 pm on April 28, 2025:

    petertodd commented at 8:26 pm on April 28, 2025:
    Fixed.
  49. wizkid057 commented at 2:35 pm on April 28, 2025: none

    Moderation suggestion: close to non-contributors.

    This is far more than a small technical change, so the broader community should not be shut out of the discussion or shuffled off to the mailing list. This is a fundamental change to the nature of what the Bitcoin network itself is in its entirety.

    • Merging this PR means Bitcoin is no longer a decentralized currency.
    • Merging this PR means Bitcoin is no longer money.
    • Merging this PR means Bitcoin is no longer a store of value.
    • Merging this PR means Bitcoin is no longer what users, node runners, etc signed up for and adopted.
    • Merging this PR means Bitcoin is no longer Bitcoin.

    That may sound like hyperbole, but it really isn’t. If this PR is merged, Bitcoin as we know it changes forever in the most fundamental way imaginable: The reference implementation explicitly turning the Bitcoin network into an arbitrary data storage system, instead of evolving it as a decentralized currency.

    It’s one thing to not act in the face of an attack. It takes discipline and dare I say courage to act in the face of a heavy attack on a system. So while I wholeheartedly disagree with the refusal to merge bug fixes like #28408, I can partly understand the developers’ inaction and fear.

    This PR on the other hand, is not only a direct attack on the nature of Bitcoin itself, its merge would undermine that same nature in the worst possible way. This type of change should be treated with no less scrutiny than a hard fork, because that’s essentially what this is: A fork away from being a decentralized currency towards being decentralized nothingness.

    I don’t think the gravity of such a change can be understated. This PR might as well be titled, “Quickest way to kill the Bitcoin project.”

    Anyway, since this is going to get merged anyway despite wide community objections, allow me to make a prediction:

    • This PR get’s merged.
    • Centralized mining pools continue to adopt Bitcoin Core changes like this.
    • After some relatively short period of time, there are an incredibly small number of > 83 byte OP_RETURNs mined.
    • Headline: See? It wasn’t so bad! No abuse of oversized OP_RETURNs.

    Why? Because the people cramming arbitrary data into the blockchain already have an effectively sanctioned method of doing so that will cost them 4x less in fees, and 4x the arbitrary data size. As someone attacking the network with spam, why would I pay 4x the cost to store my garbage with this PR via OP_RETURN when my current method is ALREADY “standard” through Bitcoin Core’s stated intention to do nothing about it, AND when done non-standard can give me 4x the data? No-brainer for them.

    So while this PR is an attack on Bitcoin itself and I hate everything about it (and so should you), it’s also completely pointless from a technical and incentives perspective unless combined with something like #28408 to make OP_RETURN the “proper” way to store data.

  50. pinheadmz commented at 2:56 pm on April 28, 2025: member
    @wizkid057 your comment borders on off-topic, but I’m not going to hide it because at this point in the PR thread it is new information. This will be last comment allowed with this information though – meaning all future comments talking about the end of decentralized money as we know it will be considered redundant brigadeing. Everyone else who agrees with you can 👍 your comment instead of rewriting it in their own words. I also encourage you to take longer arguments like this to the mailing list instead of github.
  51. darosior approved
  52. darosior commented at 3:00 pm on April 28, 2025: member

    ACK cd7872ca543d31d20f419fd2203138b8301c2e68

    You missed a mention of -datacarriersize which i think should be deleted. Although IsStandard is already checked for these outputs in the unit tests, i think it is worth having a functional test which exercises both cases as well as tests the bounds (here hitting the maximum standard transaction size). Here is a diff which adds those cases:

     0diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py
     1index f4b21cd2044..b9ef6e993da 100755
     2--- a/test/functional/mempool_accept.py
     3+++ b/test/functional/mempool_accept.py
     4@@ -9,6 +9,7 @@ from decimal import Decimal
     5 import math
     6 
     7 from test_framework.test_framework import BitcoinTestFramework
     8+from test_framework.blocktools import MAX_STANDARD_TX_WEIGHT
     9 from test_framework.messages import (
    10     MAX_BIP125_RBF_SEQUENCE,
    11     COIN,
    12@@ -327,6 +328,32 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
    13             rawtxs=[tx.serialize().hex()],
    14         )
    15 
    16+        self.log.info("A transaction with several OP_RETURN outputs.")
    17+        tx = tx_from_hex(raw_tx_reference)
    18+        op_return_count = 42
    19+        tx.vout[0].nValue = int(tx.vout[0].nValue / op_return_count)
    20+        tx.vout[0].scriptPubKey = CScript([OP_RETURN, b'\xff'])
    21+        tx.vout = [tx.vout[0]] * op_return_count
    22+        self.check_mempool_result(
    23+            result_expected=[{"txid": tx.rehash(), "allowed": True, "vsize": tx.get_vsize(), "fees": {"base": Decimal("0.05000026")}}],
    24+            rawtxs=[tx.serialize().hex()],
    25+        )
    26+
    27+        self.log.info("A transaction with an OP_RETUN output that bumps into the max standardness tx size.")
    28+        tx = tx_from_hex(raw_tx_reference)
    29+        tx.vout[0].scriptPubKey = CScript([OP_RETURN])
    30+        data_len = int(MAX_STANDARD_TX_WEIGHT / 4) - tx.get_vsize() - 5 - 4  # -5 for PUSHDATA4 and -4 for script size
    31+        tx.vout[0].scriptPubKey = CScript([OP_RETURN, b"\xff" * (data_len)])
    32+        self.check_mempool_result(
    33+            result_expected=[{"txid": tx.rehash(), "allowed": True, "vsize": tx.get_vsize(), "fees": {"base": Decimal("0.1") - Decimal("0.05")}}],
    34+            rawtxs=[tx.serialize().hex()],
    35+        )
    36+        tx.vout[0].scriptPubKey = CScript([OP_RETURN, b"\xff" * (data_len + 1)])
    37+        self.check_mempool_result(
    38+            result_expected=[{"txid": tx.rehash(), "allowed": False, "reject-reason": "tx-size"}],
    39+            rawtxs=[tx.serialize().hex()],
    40+        )
    41+
    42         self.log.info('A timelocked transaction')
    43         tx = tx_from_hex(raw_tx_reference)
    44         tx.vin[0].nSequence -= 1  # Should be non-max, so locktime is not ignored
    

    I am in favor of removing the option. Although i am sympathetic to the argument of letting more control to the user over what gets into their mempool, i do not see any valid reason why a user would want to set -datacarriersize. For obvious reasons, we should not keep options we do not expect to be set. This argument is also brought up in this thread by a vocal aggressive minority of non-contributors to and non-users of the software, who i do not think are representative of the Bitcoin Core users.

    Edited on request of a moderator to remove unnecessarily inflammatory comments.

  53. DrahtBot requested review from Sjors on Apr 28, 2025
  54. Fiach-Dubh commented at 3:27 pm on April 28, 2025: none

    NACK

    Removing long time, policy level, end user config option choice is extreme.

    Core shouldn’t be in the business of compelling speech at a policy level from it’s users unless it’s interested in losing users, which is already happening for related reasons.

    When you remove an end users choice to configure their policy you are doing harm to that user. Please don’t harm end users by nixing these config options altogether.

    Thank you for the work you all do.

  55. wizkid057 commented at 3:28 pm on April 28, 2025: none

    @wizkid057 your comment borders on off-topic, but I’m not going to hide it

    Thanks. As a general note I want to briefly point out that I’ve personally been a long time contributor to the Bitcoin ecosystem as a whole. Longer than many/most active devs here. While my contributions haven’t been directly to Bitcoin Core code to-date (although there is certainly code of mine passed through to it from me through others from long before I had any need for recognition for such things), there’s 10,000+ blocks of “proof of work” from my wider efforts out there, thousands of which are from my direct personal efforts.

    Just because someone hasn’t made huge code contributions to Bitcoin Core code doesn’t mean they’re not users or contributors to the underlying ecosystem. So, please don’t be quick to judge comments from folks without a “Contributor” or other tag.

    At this point in the PR thread it is new information.

    In the spirt of that, some additional information that needs consideration:

    It’s worth pointing out a huge difference between the currently “allowed” ‘inscriptions’ method of data storage and unlimited-sized OP_RETURN data storage. By nature of being an exploit, ‘inscriptions’ have to inject PUSH opcodes along with their arbitrary data. This means when examining the raw on-disk data (with external tools, data recovery, forensic examination, etc) that the data stored generally doesn’t get interpreted as the actual data the creator intended it to be (a JPEG, whatever).

    However, arbitrary sized OP_RETURN does not have this limitation. An entire file can be serialized directly after an OP_RETURN as-is. So later, when a Bitcoin user goes to do data recovery, or has their system seized by a government and they do a cursory analysis of its contents, both will have to contend with the now completely plaintext arbitrary data that any anonymous person has now effectively forced them to store and/or process on their system in order to participate in the Bitcoin network.

    Use your imagination to see how badly this can turn out for folks, and how badly this could indefinitely stifle adoption of Bitcoin full nodes of any implementation now and in the future, not just Bitcoin Core. “Oh that [insert objectionable/illegal/etc content present on my PC]? That’s not mine I swear.”

    So far, we’ve dodged this by pure happenstance of the mechanisms involved being technically hindered (inscriptions needing PUSHes, OP_RETURN being size limited by standardness), costly (bribe a miner), or otherwise prohibitive (mine your own block). We’ll lose the protections once this is merged. Please consider these wider implications before hastily merging such a sweeping change.

    I also encourage you to take longer arguments like this to the mailing list instead of github.

    I will do so, thanks.

  56. rstmsn commented at 4:37 pm on April 28, 2025: none
    Concept NACK.
  57. Sjors commented at 4:45 pm on April 28, 2025: member

    @rstmsn that’s not a sensible metric of “success”, which you haven’t defined either. If I were to define “success” as “percentage of attempted OP_RETURN transactions permanently excluded from the blockchain”, and if I then consider the lack of evidence for a single failed attempt, the success rate is 0%. The fact that one can find such wildly different metrics and definitions, implies they’re all useless.

    (updated to be more in line with your sense that more filtering means more success)

  58. wizkid057 commented at 5:09 pm on April 28, 2025: none

    @rstmsn that’s not a sensible metric of “success”, which you haven’t defined either. If I were to define “success” as “percentage of attempted OP_RETURN transactions permanently excluded from the blockchain”, and if I then consider the lack of evidence for a single failed attempt, the success rate is 0%. The fact that one can find such wildly different metrics and definitions, implies they’re all useless.

    (updated to be more in line with your sense that more filtering means more success)

    I think the bar to bypass IsStandard is very underestimated. The fact that we don’t see huge OP_RETURNs all the time proves its overall effectiveness in protecting the network as a first line of defense. And by extension, changes that loosen it should warrant significant, extended, and public scrutiny.

  59. instagibbs commented at 6:25 pm on April 28, 2025: member

    I’ve historically been -0 on these kinds of restrictions, and as soon as we run into non-trivial usage outside the bounds of standardness, there needs to be strong motivations to keep those restrictions otherwise they become a centralizing force. This is doubly so in a world where witness stuffing is a highly dynamic and well-paid method of publishing arbitrary data on the blockchain, so we’re not even accomplishing the ostensible goals of those who oppose removal.

    There are roughly 3 ways to handle this in an active sense for Bitcoin Core as a project:

    1. Expand filtering in a game of cat and mouse that of contributors only @luke-jr is interested in. We have rejected this as a group goal for at least 1.5 years now and I see no motion in the other direction.
    2. Turn the dial up a bit to allow known-non-spam use-cases, say 150vbytes per, and multiple outputs per transaction. This would accommodate the cited use-case by Citrea in one output, and add additional overhead allow unbounded data for when this dial is incorrect.
    3. Remove the dial and move on.

    Protocols have real Bitcoin-payment reasons to use larger sized OP_RETURNs, and falling to adapt means spamming the utxo set to get around it. The days of manually adjusting this dial is over.

    For alternative projects like Knots that want to chase the concept of (1), knock yourselves out. I promise I will not come and lobby to increase defaults with apocalyptic visions.

    concept ACK, code looks correct. Would be good to take in the additional test suggestions.

  60. portlandhodl commented at 6:40 pm on April 28, 2025: contributor

    Concept Ack,

    As a note the current MARA non-standard mempool policy is

    • Unlimited OP_RETURNS
    • No size limitations
    • No restrictions on burn amount.

    MARA currently has 3-5% of the network hashrate and charges 3x priority feerate for these transactions arbitraging standardness rules. The ability to profit from this activity would be reduced if these types of transactions became standard.

    Edit: Just today a user overpaid to get their nonstandard OP_RETURN mined https://mempool.space/tx/2154a77befea7b7c1700f37fafa2a3db238b62b891a66df953f08385f3cd178e

  61. instagibbs commented at 6:43 pm on April 28, 2025: member

    @portlandhodl

    No restrictions on burn amount.

    IIRC that’s just a sendrawtransaction/submitpackage argument, not a relay concern

  62. portlandhodl commented at 6:48 pm on April 28, 2025: contributor

    @portlandhodl

    No restrictions on burn amount.

    IIRC that’s just a sendrawtransaction/submitpackage argument, not a relay concern

    This is absolutely correct per Solver + IsStandard(), thanks will edit post.

    https://github.com/bitcoin/bitcoin/blob/3a29ba33dca6b9d53377d2e6a9f28453bb14ee6c/src/script/solver.cpp#L185C39-L185C72

  63. Add comment to test noting when OP_RETURN limit was removed b420376aef
  64. Move node restart in test to better place.
    Needed because the previous test used -persistmempool=0 and we need to
    forget about the transaction it created.
    
    Credit: Sjors Provoost
    47f9565c15
  65. petertodd commented at 8:28 pm on April 28, 2025: contributor
    @Sjors @darosior I think I made all the code corrections you both suggested. Let me know if I missed anything.
  66. 1ma commented at 8:43 pm on April 28, 2025: none

    Concept ACK.

    It’s time to come to terms with the fact that Bitcoin is desirable for some people to use as a data anchor and they will find a way to use it as such, thus we should be asking what the preferred means of data anchoring is and how to incentivize it over less preferable options. @jlopp I think it would be appropriate for you to disclose that you’re one of the VCs backing Citrea, a company that is currently abusing unspendable Taproot outputs to embed arbitrary data onchain and whose behavior motivated the ML discussion and this PR.

    Source on the Citrea website: https://www.blog.citrea.xyz/announcing-citrea-series-a-round/

  67. BitcoinMechanic commented at 9:03 pm on April 28, 2025: none

    The above comment (that has been marked “abuse”) alerting us to Lopp’s conflict of interest is entirely appropriate to point out. I am happy to disclose my affiliation with OCEAN for anyone that feels it is relevant to the input I have given here.

    The moderation on this thread - and the suggestion that only Core contributors may participate in this discussion - is completely unacceptable.

  68. andrewtoth commented at 10:42 pm on April 28, 2025: contributor

    An entire file can be serialized directly after an OP_RETURN as-is. So later, when a Bitcoin user goes to do data recovery, or has their system seized by a government and they do a cursory analysis of its contents, both will have to contend with the now completely plaintext arbitrary data that any anonymous person has now effectively forced them to store and/or process on their system in order to participate in the Bitcoin network.

    Luckily, blocks and mempool data are stored obfuscated on disk by XOR-ing with a random per-node key. See #28052, #28207.

  69. cmdruid commented at 11:40 pm on April 28, 2025: none

    The limitation to a single OP_RETURN output per tx is indeed dumb and should be removed, but I don’t see why you would remove filtering rules if people actively use them and build clients around them.

    There’s always going to be a difference in policy between mempool and onchain. Just because you can bribe a miner to side-step mempool consensus isn’t really an argument to remove filtering rules, you may as well remove the dust limit while you’re at it.

  70. Turtlecute33 commented at 11:45 pm on April 28, 2025: none

    NACK

    Removing the limits on OP_RETURN does not mean that people minting ordinals will stop using Taproot outputs, so it will not prevent the continued growth of the UTXO set.

    Any non-definitive restriction on mempool policy is essentially useless, as it can be easily circumvented via slipstream techniques and accelerator services. Meanwhile, removing arbitrary limits on data carrier outputs does not guarantee any meaningful improvement or change in the behavior of ordinal minters.

    Given the current situation, I believe the best course of action is to maintain the status quo. We are not currently seeing major issues with accelerator services (ViaBTC started many years ago, and slipstream transactions still account for an insignificant portion of Bitcoin traffic).

    Maintaining the status quo is the only viable option at this time because removing these rules would represent a definitive and irreversible decision about Bitcoin’s future, whereas adjusting mempool policies cannot truly resolve the underlying issues.

  71. danielabrozzoni commented at 0:02 am on April 29, 2025: contributor

    While there are valid arguments on both sides of this discussion, I am leaning towards a NACK

    It is true that mempool policy filters have not been completely successful at preventing transaction spam, and they will never be. However, they do provide a form of friction if enough people use them; for example, if all mempools refuse transactions with OP_RETURNs above the current limit, spammers have no choice but to use mempool accelerators and pay higher fees for their transactions.

    I also agree that it’s better to have people using OP_RETURNs rather than creating outputs that pollute the UTXO set forever.

    I am also concerned that in the future we might see a large scale bypassing of the Core standarness rules, but it’s unclear whether we’ve reached that point yet. We can always reconsider dropping the OP_RETURN limit once it becomes truly problematic - but, and this is a genuine question, are we there yet?

    Finally, as Seccour put it:

    Just giving up on fighting spam because they found a new way of spamming is the opposite of what we should do. We should double down and find a way to fight the spam instead of embracing it.

    I don’t see a reasonable way to double down and fight the spam, but I don’t think it makes sense to embrace it.

  72. petertodd commented at 1:14 am on April 29, 2025: contributor
    I want to remind people that you should actually read the mailing list discussion first, and understand what exactly lead to this pull-req: https://groups.google.com/g/bitcoindev/c/d6ZO7gXGYbQ
  73. wizkid057 commented at 3:01 am on April 29, 2025: none

    Luckily, blocks and mempool data are stored obfuscated on disk by XOR-ing with a random per-node key. See #28052, #28207.

    This, admittedly, partly mitigates one objection of mine (out of dozens, to be clear). I recall this was discussed many years ago in #bitcoin-dev, but I didn’t know it actually finally martialized. Thanks.

    However, unless I’m missing something, it seems regular upgrade paths don’t have a mechanism to make any use of this obfuscation. Only new nodes seem to benefit. (My personal Bitcoin Core nodes are ancient, and it seems only fresh nodes benefit. One I’ve had since I started with Bitcoin in 2011-ish, and have done my best to keep updating it over the years across several machines, just for fun. Yes, I run some Core nodes, Knots nodes, and some other forks.)

    With that said, there’s going to be thousands of users who have followed an upgrade path that did not bring them this very recent (and about to be very necessary) obfuscation protection, like myself, most of which will be completely unaware of what is about the be forced on to their storage devices without their knowledge if this PR, or a future one like it, is in fact merged.

    Considering the floodgates of absolutely horror this PR is going to bring upon Bitcoin node runners, there absolutely needs to be a way for existing users to protect themselves and retroactively apply this on-disk obfuscation to existing node data, and a firm suggestion to users upon upgrading that they should actually do this… perhaps even forcing it as part of an upgrade if not enabled or explicitly disabled.

    In fact, if this PR somehow isn’t controversial enough to avoid being merged (the excuse given for not merging similar opposing PRs in the past, so hopefully some consistency is applied to this one), merging without such protective functionality widely applied and available to protect existing users seems like the absolute minimum bar to pass to minimize some obvious potential damage to those end users.

    I could probably be convinced to make the effort to write a PR for such obfuscation improving changes if it means helping protect innocent Bitcoin users minimally from the harm that will come from merging this PR, and I’d campaign furiously that people adopt that obfuscation ASAP. This is a necessary stopgap until Bitcoin development as a whole comes to its senses and stops actively enabling/encouraging abuse of the network.

    I presume we don’t want to put unsuspecting users in harm’s way, and it seems like plenty of reason to put the brakes on hastily merging this PR.

  74. petertodd commented at 3:41 am on April 29, 2025: contributor

    @wizkid057 I need to remind people that Bitcoin Core is not the only implementation out there. It is already quite easy to get arbitrarily sized OP_Returns mined, and even Bitcoin Core’s standardness rules already allow long byte sequences to get mined and thus included in block*.dat files.

    Anyway, I just checked, and Google Chromium v135 at least appears to store cached data on your hard drive verbatim (plus a file header). If even they aren’t concerned about unobfuscated random cached data ending up on your hard drive from every website you happen visit, I don’t think this is a serious concern for Bitcoin Core. In the very rare case that it is, it’s perfectly reasonable to tell people they might want to delete their .bitcoin and resync from scratch to ensure the XOR obfuscation is applied.

  75. wizkid057 commented at 5:05 am on April 29, 2025: none

    @wizkid057 I need to remind people that Bitcoin Core is not the only implementation out there. It is already quite easy to get arbitrarily sized OP_Returns mined, and even Bitcoin Core’s standardness rules already allow long byte sequences to get mined and thus included in block*.dat files.

    By “long byte sequences”, I don’t know of any way to get more than few hundred bytes in a sequence without a miner’s involvement.

    I’m talking about entire real world files without breaks.

    It’s already been pretty well established that these alternate implementations are the exception, not the rule.

    If it’s so simple to get these transactions mined, why would you be bothering to try and remove these rules? 🙃

    Anyway, I just checked, and Google Chromium v135 at least appears to store cached data on your hard drive verbatim (plus a file header). If even they aren’t concerned about unobfuscated random cached data ending up on your hard drive from every website you happen visit, I don’t think this is a serious concern for Bitcoin Core.

    This isn’t even remotely comparable. Everyone knows there’s a huge difference between using a browser and ending up with something nefarious on your drive (likely from visiting a questionable site in the first place) that doesn’t get redistributed by your browser, no less, than completely opening yourself up to unattended storage of anything an anonymous attacker decides to put in the chain AND you now redistribute that to peers.

    Quite a ridiculous and unserious comparison.

    In the very rare case that it is, it’s perfectly reasonable to tell people they might want to delete their .bitcoin and resync from scratch to ensure the XOR obfuscation is applied.

    It’s not a “rare case”. The moment someone uses this newly opened attack vector, every Bitcoin user will need this minimal protection already enabled. We can’t be the one to judge if it’s OK for certain arbitrary data to be present on another user’s disk without their explicit consent, so there must be a mechanism in place well BEFORE that’s an issue for every user.

  76. shahsb commented at 7:01 am on April 29, 2025: none

    It’s great to see constructive discussions taking place here!

    I don’t see any valid reason to take away configuration settings from users.

    Just because certain config options don’t directly influence what miners include in blocks doesn’t mean users lose control over what appears in their mempools.

    Therefore, my take is: Concept NACK.

  77. in test/functional/mempool_accept.py:343 in 8fd09d622d outdated
    338+        )
    339+
    340+        # Multiple OP_RETURN and more than 83 bytes are standard since v30
    341+        tx = tx_from_hex(raw_tx_reference)
    342+        tx.vout.append(CTxOut(0, CScript([OP_RETURN, b'\xff'])))
    343+        tx.vout.append(CTxOut(0, CScript([OP_RETURN, b'\xff' * 90])))
    


    Sjors commented at 7:28 am on April 29, 2025:

    In 8fd09d622d161eb554f080a52735832119cb35e5 “Add more OP_RETURN mempool acceptance functional tests”

    This this is now a bit redundant with the tests from @darosior below, so might as well expand it to clarify something:

     0diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py
     1index a4dfda8443..2ac4905a57 100755
     2--- a/test/functional/mempool_accept.py
     3+++ b/test/functional/mempool_accept.py
     4@@ -338,9 +338,10 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
     5         )
     6
     7         # Multiple OP_RETURN and more than 83 bytes are standard since v30
     8+        # MAX_SCRIPT_SIZE (10kB) does not apply
     9         tx = tx_from_hex(raw_tx_reference)
    10         tx.vout.append(CTxOut(0, CScript([OP_RETURN, b'\xff'])))
    11-        tx.vout.append(CTxOut(0, CScript([OP_RETURN, b'\xff' * 90])))
    12+        tx.vout.append(CTxOut(0, CScript([OP_RETURN, b'\xff' * 10000])))
    
  78. Sjors approved
  79. Sjors commented at 7:37 am on April 29, 2025: member

    ACK 47e713ea5a96d3bb2ddd64c8a87607e5ccea8c72

    Thanks for adding the tests.

    Nits:

    • maybe rename the first commit title to: “Drop OP_RETURN standardness limits for datacarrier size and output count”
    • squash 47e713ea5a96d3bb2ddd64c8a87607e5ccea8c72 into it
    • see inline comment for test improvement

    Considering the floodgates of absolutely horror this PR is going to bring upon Bitcoin node runners

    Anything that can appear in your mempool via OP_RETURN can already appear as an inscription, at 1/4th the cost for the attacker. The solution to that problem, if you perceive it as such, is to run a fork of Bitcoin Core with different mempool policy, such as Knots.

    Even if this PR is not merged, it’s extremely unlikely any of the additional filtering in Knots will be added here (previous attempts failed). So this software can’t achieve what you need, while Knots can. It has the exact same consensus code (afaik) and is reproducibly built. Someone could even create and maintain an alternative client with fewer features than Knots and only its transaction filtering.

    In the very rare case that it is, it’s perfectly reasonable to tell people they might want to delete their .bitcoin and resync from scratch to ensure the XOR obfuscation is applied.

    Or we can add a way to retroactively XOR these files. Just open an issue if you need that.

    To clear the mempool, all you need is to delete mempool.dat. A new one is automatically created and will be XOR’d.

    Don’t delete your whole data directory, as that includes your wallet. Deleting the blocks, indexes and chainstate directories does the trick. By the way, that procedure also works if you have a pruned node and can’t open your wallet anymore because it’s too far behind.

  80. DrahtBot requested review from instagibbs on Apr 29, 2025
  81. DrahtBot requested review from darosior on Apr 29, 2025
  82. in test/functional/mempool_accept.py:363 in 47e713ea5a outdated
    359+        self.check_mempool_result(
    360+            result_expected=[{"txid": tx.rehash(), "allowed": True, "vsize": tx.get_vsize(), "fees": {"base": Decimal("0.05000026")}}],
    361+            rawtxs=[tx.serialize().hex()],
    362+        )
    363+
    364+        self.log.info("A transaction with an OP_RETUN output that bumps into the max standardness tx size.")
    


    DrahtBot commented at 7:45 am on April 29, 2025:

    LLM Linter (✨ experimental)

    OP_RETUN → OP_RETURN

  83. wizkid057 commented at 8:11 am on April 29, 2025: none

    Anything that can appear in your mempool via OP_RETURN can already appear as an inscription, at 1/4th the cost for the attacker.

    Incorrect. Because ‘inscriptions’ are an exploit, they have to break up that data into ~500 byte chunks partitioned by PUSH opcodes. This means the largest contiguous piece of raw data to contend with is ~500 bytes.

    With unlimited sized OP_RETURN, we now have to deal with ~100KB contiguous pieces of data… 200x more. Far more dangerous from an external analysis standpoint.

    Without on-disk obfuscation, users are vulnerable to a variety of attacks that end up with virtually no barrier to entry under this PR.

    The solution to that problem, if you perceive it as such, is to run a fork of Bitcoin Core with different mempool policy, such as Knots.

    As you’re well aware, running Bitcoin Knots doesn’t solve this problem (unless all miners use Knots, of course).

    I think you’re missing the point of this particular argument. I’ve tried to make it clear without directly noting the specific attacks, which I thought would be obvious to those with knowledge of the topic. Seems I may be incorrect in that assumption. Let me try one more time.

    Merging this PR lowers the bar for storing large contiguous chunks arbitrary data on the systems of thousands of node runners worldwide from “you must get a miner to mine this for you” down to “you have to broadcast it and pay a fee”.

    That’s a massive change with massive implications. We’re going from a landscape with tolerated data carrying of ~80 bytes alongside an unpatched exploit that can stuff ~500 bytes per chunk disguised as a script…. to keeping the exploit AND adding a method for storing data up to ~100KB in length contiguously… and I’m one of the only ones here with the foresight to know that this will have undermining consequences to the ecosystem as a whole? To the point where entire swaths of users will be unable and/or unwilling to run full nodes, forever, for a variety of reasons?

    And no one here is considering these issues at all? That’s wild to me, and incredibly disappointing.

    Like I said above, this kind of huge fundamental change needs to be treated with the same level of scrutiny as a fork. This can’t be fast tracked into the code just because. Everyone needs to stop, take 10 steps back, and consider the broader implications. Thus far all I see are people with some authority here trying to sweep those implications and global consequences to the Bitcoin project under the rug as quickly as possible… for reasons unknown.

    Or we can add a way to retroactively XOR these files. Just open an issue if you need that.

    This absolutely must be a thing before merging this PR is even remotely considered. If the developers here can’t see why that is, then there really is no hope left for this project. Bitcoin’s success as a currency is already on shaky ground with the clear failure to address obvious exploits. If we can and do go down the path of just completely changing what Bitcoin is on a whim, it’s kind of pointless to begin with.

    I’d like to believe the people involved here are acting in good faith, are competent, and are willing to look at this from all sides and come to a conclusion on what is best for Bitcoin as a whole. I’ve done this, and I can’t logically come to any positive conclusion. It’s surprising to me that others either are not doing this at all, or are somehow doing the mental gymnastics needed to avoid inconvenient truths of the matter.

  84. Turtlecute33 commented at 8:18 am on April 29, 2025: none
    Hey, I’d like to ask why my comment above (https://github.com/bitcoin/bitcoin/pull/32359#pullrequestreview-2801335235) was marked as a duplicate. I believe it includes some technical points that weren’t cited earlier, for example, that allowing more OP_RETURN usage doesn’t necessarily mean spammers will stop using witness-discounted Taproot outputs. (cc @pinheadmz)
  85. polespinasa commented at 8:26 am on April 29, 2025: contributor

    allowing more OP_RETURN usage doesn’t necessarily mean spammers will stop using witness-discounted Taproot outputs

    That’s in the mailing list, not that direct sentence but cost comparison with witness-discount and multiple op_returns use cases.

  86. Sjors commented at 9:22 am on April 29, 2025: member

    [Inscriptions] have to break up that data into ~500 byte chunks partitioned by PUSH opcodes. This means the largest contiguous piece of raw data to contend with is ~500 bytes.

    With unlimited sized OP_RETURN, we now have to deal with ~100KB contiguous pieces of data… 200x more. Far more dangerous from an external analysis standpoint.

    It would be a reasonable precaution to pre-emptively XOR existing mempools by the next release. Tracking in #32372. Update: we already do that.

    Merging this PR lowers the bar for storing large contiguous chunks arbitrary data on the systems of thousands of node runners worldwide from “you must get a miner to mine this for you” down to “you have to broadcast it and pay a fee”.

    This can be further subdivided into:

    1. Getting it into a user mempool: this PR indeed lowers that barrier
    2. Getting it into a block i. this is already trivial with LibreRelay and such, there hasn’t been a need to contact miners directly in recent years ii. even going directly to a miner requires little sophistication. There’s already almost no deterrence against this attack. I doubt many, or any, companies that offer this service run a full suite of virus and other content scanners to check for matches.

    If you want to go further down this rabbit hole, you would also need to consider p2p traffic. You can already send any node on the planet (even unreachable ones, if they randomly connect to you) any payload. No filter can fix that. The only thing this PR does, is cause nodes to subsequently also broadcast the payload. Perhaps with some ISP deep package inspection system that distinction matters. That would be another good reason to only broadcast transactions over v2 encrypted connections, see #32373.

    The solution to that problem, if you perceive it as such, is to run a fork of Bitcoin Core with different mempool policy, such as Knots.

    As you’re well aware, running Bitcoin Knots doesn’t solve this problem (unless all miners use Knots, of course).

    I was referring to the more general objection people have against having non-transaction data on their node (OP_RETURN, inscriptions, etc). That’s never going to be “fixed” in Bitcoin Core. But the more narrow concern of payloads that trigger e.g. virus scanners seems within scope.

    It’s just that Knots tried to address this by trying to filter all non-transaction data (which they want to do anyway), whereas here we’ll have to find another solution (such as encrypted storage and transport).

  87. jlopp commented at 10:20 am on April 29, 2025: contributor

    @wizkid057 I think you still need to provide further clarification

    We’re going from a landscape with tolerated data carrying of ~80 bytes alongside an unpatched exploit that can stuff ~500 bytes per chunk disguised as a script…. to keeping the exploit AND adding a method for storing data up to ~100KB in length contiguously… and I’m one of the only ones here with the foresight to know that this will have undermining consequences to the ecosystem as a whole?

    What is the exploit you are imagining and what harm does it cause? Earlier you seemed to vaguely allude to perhaps illegal content but you have yet to actually outline a specific attack and its consequences.

    I’ll note that (according to ChatGPT) Ethereum allows 128KB data blobs and Solana allows 10MB data blobs. I’m not saying Bitcoin should strive to be like them, I’m just wondering why the supposed exploit to which you refer has not seemed to have harmed them.

    To the point where entire swaths of users will be unable and/or unwilling to run full nodes, forever, for a variety of reasons?

    This claim certainly doesn’t make sense, as the PR makes absolutely no changes to the total data throughput allowed on the network.

  88. theDavidCoen commented at 11:17 am on April 29, 2025: none

    I agree with Pieter Wuille when he wrotes: “(…) these arguments do not apply to OP_RETURN limits, which don’t serve an objective harm reduction beyond a subjective “that isn’t what you should be using the chain for”.

    So yes, maybe OP_RETURN limits do not work to prevent spam and we can remove the default value that is totally arbitrary, but node policies are subjective by definition and, as a node operator, I should be allow to define my own size limit without recurring to a fork of Bitcoin Core which might come with additional bugs or a non audited-enough code.

    If we take this PR as is, then it’s a NACK.

  89. andrewtoth commented at 1:34 pm on April 29, 2025: contributor

    I think @wizkid057 raises a valid point. Merging this would significantly reduce the technical barriers to getting arbitrary large(ish) files stored plaintext on users’ disks. I don’t think appealing to what other software systems have gotten away with so far is relevant to this project.

    The mempool is trivial to obfuscate, simply by restarting the node. The chainstate has been obfuscated for a decade, so there are not likely many users at risk. Nor are any standardness rules for adding plaintext data to the chainstate being relaxed.

    However, block obfuscation is relatively new, and will only be enabled if the blockchain is downloaded from scratch. This takes at least several hours if you’re an expert and can connect to a local node to redownload, or several days if you’re using a raspi over the public network. I don’t think it’s fair to tell users to undertake a several days long resync.

    I think we should have an option (default on) to obfuscate the block data files on startup if they are not yet obfuscated.

  90. instagibbs commented at 2:01 pm on April 29, 2025: member

    I am also concerned that in the future we might see a large scale bypassing of the Core standarness rules, but it’s unclear whether we’ve reached that point yet

    I see no evidence that it’s not being regularly bypassed already: https://opreturnbot.com/

    If it was any standardness issue that had systemic risks being turned off I’d consider a bit harder, but it does not. Things are simply worse for decentralization with the restrictions in place. There are explicit plans to either use centralized miner infra, or dust the utxo set to get around it and no amount of posturing is going to change that.

    I know you didn’t posit this, but others did: To talk as if this filtering is providing security to users is also extreme nonsense unless your attacker model is the attacker’s inability to use a website. If there are software updates needed to give users security, let’s do those as well.

    I don’t see a reasonable way to double down and fight the spam, but I don’t think it makes sense to embrace it.

    Allowing people to do things on the p2p network vs centralized actors is not an “embracing” of it. It’s a harm reduction. Bitcoin Core as a project is not taking on transaction filtering as an engineering priority. Status quo for status quo sake is only an argument if you reasonably expect us to gain more information that will change the future direction of the project.

    It’s clear to me that it will not. It’s been multiple years now that Bitcoin Core as a project has rejected this as a priority. It’s not worth arguing about anymore.

    People are free to fork, free to use Knots; I’m also free to not engage with these meta conversations any longer.

    ====

    Back to technical discussion, I think leaving the option is in disingenuous: unless 90%+ of users change the default it will have zero effect on what is mined, and will simply result in wasted bandwidth and round-trips for the user changing settings.

  91. in test/functional/mempool_accept.py:334 in 8fd09d622d outdated
    327@@ -327,6 +328,52 @@ def run_test(self):
    328             rawtxs=[tx.serialize().hex()],
    329         )
    330 
    331+        # OP_RETURN followed by non-push
    332+        tx = tx_from_hex(raw_tx_reference)
    333+        tx.vout[0].scriptPubKey = CScript([OP_RETURN, OP_HASH160])
    334+        tx.vout = [tx.vout[0]] * 2
    


    instagibbs commented at 2:03 pm on April 29, 2025:
    what’s this doubling doing?

    Sjors commented at 2:57 pm on April 29, 2025:
    It creates two outputs to demonstrate that you can have more than one. Though this specific test probably shouldn’t demo that aspect.

  92. Sjors commented at 2:04 pm on April 29, 2025: member

    @andrewtoth wrote:

    The mempool is trivial to obfuscate, simply by restarting the node.

    Anyone upgrading their node to v30, or any other version, has to restart their node.

    block obfuscation is relatively new, and will only be enabled if the blockchain is downloaded from scratch

    There’s no new attack here, getting arbitrary data confirmed on chain has been trivial for years. See #32359 (comment) and @instagibbs’s comment above mine. @theDavidCoen

    node policies are subjective by definition and, as a node operator, I should be allow to define my own size limit without recurring to a fork of Bitcoin Core which might come with additional bugs or a non audited-enough code

    No they’re not. They’re the result of (mostly) careful engineering and consideration of trade-offs. If you wish to run a policy based on taste, then indeed you’ll have to accept the trade-off of code that’s less audited. Potentially even code that’s poorly designed because it was not driven by careful engineering considerations but rather by ideology. Of course Bitcoin has always threaded a careful balance between those two things.

    There are good reasons not to support multiple incompatible standardness rules. See #26438 for an explanation. In retrospect we should never have made this configurable in the first place, but that realisation is only a few years old. It also didn’t matter as much back when this was introduced, because we didn’t have compact blocks. @instagibbs wrote:

    will simply result in wasted bandwidth and round-trips for the user changing settings

    And for the user not changing their settings if they peer with such a user.

  93. in test/functional/mempool_accept.py:359 in 8fd09d622d outdated
    353+        op_return_count = 42
    354+        tx.vout[0].nValue = int(tx.vout[0].nValue / op_return_count)
    355+        tx.vout[0].scriptPubKey = CScript([OP_RETURN, b'\xff'])
    356+        tx.vout = [tx.vout[0]] * op_return_count
    357+        self.check_mempool_result(
    358+            result_expected=[{"txid": tx.rehash(), "allowed": True, "vsize": tx.get_vsize(), "fees": {"base": Decimal("0.05000026")}}],
    


    instagibbs commented at 2:04 pm on April 29, 2025:
    micro-nit: 0.05000026 is pretty magical, would be better to be computed if possible

    Sjors commented at 2:59 pm on April 29, 2025:
    Maybe better for a followup to refactor this test. The “bad” examples are nice, but the “good” examples can be simplified by adding a check_mempool_happy helper that doesn’t require all fields to match. The fee is irrelevant, but you have to specify it.
  94. in test/functional/mempool_accept.py:367 in 8fd09d622d outdated
    361+
    362+        self.log.info("A transaction with an OP_RETUN output that bumps into the max standardness tx size.")
    363+        tx = tx_from_hex(raw_tx_reference)
    364+        tx.vout[0].scriptPubKey = CScript([OP_RETURN])
    365+        data_len = int(MAX_STANDARD_TX_WEIGHT / 4) - tx.get_vsize() - 5 - 4  # -5 for PUSHDATA4 and -4 for script size
    366+        tx.vout[0].scriptPubKey = CScript([OP_RETURN, b"\xff" * (data_len)])
    


    instagibbs commented at 2:10 pm on April 29, 2025:

    sanity check

    0        tx.vout[0].scriptPubKey = CScript([OP_RETURN, b"\xff" * (data_len)])
    1        assert_equal(tx.get_vsize(), int(MAX_STANDARD_TX_WEIGHT / 4))
    
  95. in test/functional/mempool_accept.py:372 in 8fd09d622d outdated
    366+        tx.vout[0].scriptPubKey = CScript([OP_RETURN, b"\xff" * (data_len)])
    367+        self.check_mempool_result(
    368+            result_expected=[{"txid": tx.rehash(), "allowed": True, "vsize": tx.get_vsize(), "fees": {"base": Decimal("0.1") - Decimal("0.05")}}],
    369+            rawtxs=[tx.serialize().hex()],
    370+        )
    371+        tx.vout[0].scriptPubKey = CScript([OP_RETURN, b"\xff" * (data_len + 1)])
    


    instagibbs commented at 2:13 pm on April 29, 2025:

    nit sanity check

    0        tx.vout[0].scriptPubKey = CScript([OP_RETURN, b"\xff" * (data_len + 1)])
    1        assert_greater_than(tx.get_vsize(), int(MAX_STANDARD_TX_WEIGHT / 4))
    
  96. in src/init.cpp:643 in 47e713ea5a outdated
    634@@ -635,12 +635,6 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
    635     argsman.AddArg("-dustrelayfee=<amt>", strprintf("Fee rate (in %s/kvB) used to define dust, the value of an output such that it will cost more than its value in fees at this fee rate to spend it. (default: %s)", CURRENCY_UNIT, FormatMoney(DUST_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
    636     argsman.AddArg("-acceptstalefeeestimates", strprintf("Read fee estimates even if they are stale (%sdefault: %u) fee estimates are considered stale if they are %s hours old", "regtest only; ", DEFAULT_ACCEPT_STALE_FEE_ESTIMATES, Ticks<std::chrono::hours>(MAX_FILE_AGE)), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
    637     argsman.AddArg("-bytespersigop", strprintf("Equivalent bytes per sigop in transactions for relay and mining (default: %u)", DEFAULT_BYTES_PER_SIGOP), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
    638-    argsman.AddArg("-datacarrier", strprintf("Relay and mine data carrier transactions (default: %u)", DEFAULT_ACCEPT_DATACARRIER), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
    639-    argsman.AddArg("-datacarriersize",
    640-                   strprintf("Relay and mine transactions whose data-carrying raw scriptPubKey "
    641-                             "is of this size or less (default: %u)",
    642-                             MAX_OP_RETURN_RELAY),
    643-                   ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
    


    jamesob commented at 2:15 pm on April 29, 2025:
    Can’t remember how this has been handled in the past, but simply removing these options will cause existing invocations/configurations that use these options to error on start. Might be better to show a deprecation message and set new defaults, but might also be unnecessary if similar provisions haven’t been made in the past.

    Sjors commented at 3:00 pm on April 29, 2025:

    It’s probably OK for node operators who explicitly set this option to be “confronted” with the change, if they didn’t check the release note.

    The only case that should arguably be a smooth upgrade is someone who set this value > 100000, since nothing changes for them. But those people will be aware of this PR probably, looking at the author :-)

  97. instagibbs approved
  98. instagibbs commented at 2:20 pm on April 29, 2025: member

    ACK 47e713ea5a96d3bb2ddd64c8a87607e5ccea8c72

    Commits could be squashed

  99. jamesob commented at 2:22 pm on April 29, 2025: contributor

    Concept ACK

    Relaxing Core’s standardness rules makes it less likely that some users will eschew its P2P relay network in favor of “private” mempool submission systems that are more permissive but (debatably) less censorship resistant.

    While I think this outcome is probably inevitable, any change that brings Core’s policy closer to the consensus rules is likely to slow this eventuality, and so is probably worth doing.

  100. glozow added the label Needs release note on Apr 29, 2025
  101. eragmus commented at 3:01 pm on April 29, 2025: none

    Concept ACK

    Arbitrary data enjoyers will continue regardless if this is not done, but in more harmful ways. Adhering Bitcoin Core to reality, then, through this change, will benefit the Bitcoin network. It is a simple change, yet effectively resolves the downsides that otherwise will continue to exist and can even get worse (already explained by others).

    The pro-free-market, pro-fee-market, pro-freedom, harm-reduction reasoning behind this change should have been understood and acted upon many many many years ago, as fundamentally nothing has changed with Bitcoin, but it is better late than never to harmonize Bitcoin with reality via this common sense change.

    p.s. Thank you again Peter for Libre Relay to help more people understand.

  102. glozow commented at 3:08 pm on April 29, 2025: member

    Concept ACK, code looks correct to me. In the past, this limit may have discouraged (i.e. proactively) usage but that ship has sailed. It now has the additional negative effect of pushing usage away from the public network, which is a serious problem worth addressing. If someone has something that is, say, 100B and it’s more expensive to use an inscription than to use an OP_RETURN + pay a miner privately, they’d pay a miner. Being able to get rid of -datacarriersize on tests is a nice plus.

    You could consider leaving the options in and just increasing the default to max block size. I don’t feel strongly about doing this - the config option would just be a footgun long term - but we did do -mempoolfullrbf removal in separate stages. It might make this less controversial.

  103. bkkarki21 commented at 3:16 pm on April 29, 2025: none
    Concept NACK. My node is not a cloud storage for arbitrary data
  104. wizkid057 commented at 3:29 pm on April 29, 2025: none
    1. Getting it into a block

    i. this is already trivial with LibreRelay and such, there hasn’t been a need to contact miners directly in recent years ii. even going directly to a miner requires little sophistication. There’s already almost no deterrence against this attack. I doubt many, or any, companies that offer this service run a full suite of virus and other content scanners to check for matches.

    Everyone here overestimates the market penetration and actual usage of such things. As someone stated above, there have been over 7M OP_RETURN outputs recently, 30 of which used a miner-based service to exceed the 83 byte limit. Not 30,000. Not 3,000,000. 30.

    Sorry, but clearly no one really uses these things to bypass IsStandard for OP_RETURN, and this is also not an excuse to avoid the issue of what this PR can and will do to users.

    We can not put users in harm’s way by fast tracking a sweeping change like this. Get protections in place widely FIRST, then CONSIDER the major change like this one.

    If you want to go further down this rabbit hole, you would also need to consider p2p traffic. You can already send any node on the planet (even unreachable ones, if they randomly connect to you) any payload. No filter can fix that. The only thing this PR does, is cause nodes to subsequently also broadcast the payload. Perhaps with some ISP deep package inspection system that distinction matters. That would be another good reason to only broadcast transactions over v2 encrypted connections, see #32373.

    P2P must also be encrypted by default to protect users from this change. 100%.

    I was referring to the more general objection people have against having non-transaction data on their node (OP_RETURN, inscriptions, etc). That’s never going to be “fixed” in Bitcoin Core. But the more narrow concern of payloads that trigger e.g. virus scanners seems within scope.

    It’s just that Knots tried to address this by trying to filter all non-transaction data (which they want to do anyway), whereas here we’ll have to find another solution (such as encrypted storage and transport).

    That’s fine. It’s obvious this is being steamrolled through despite clear community objections.

    So since that’s the case, my goal is to protect as many users as possible as much as possible from the fallout.

    Right now that’s:

    • P2P encryption must be default and no more clear relay of txn or block data can happen
    • On-disk mempool and block data can only exist in an obfuscated form, regardless of their upgrade path.
    • Other node implementations probably should be contacted, if possible, to give them a heads up to do similar obfuscation if they haven’t already.

    We MUST mitigate harm to end users as much as possible. PLEASE PLEASE PLEASE do not underestimate the damage this can and will do to Bitcoin and its users, especially without MINIMAL protections solidly in place.

  105. in src/policy/policy.cpp:162 in 47e713ea5a outdated
    151@@ -159,12 +152,6 @@ bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_dat
    152         return false;
    153     }
    154 
    155-    // only one OP_RETURN txout is permitted
    


    jesterhodl commented at 3:32 pm on April 29, 2025:

    I thought in @darosior’s first email on this topic, he mentioned removing the size limits first, and subsequently removing the count limit. Being a bit contradictory:

    • Why was relaxing proposed in 2 stages?
    • Why was implementation done in 1 stage?
  106. instagibbs commented at 3:41 pm on April 29, 2025: member

    P2P encryption must be default and no more clear relay of txn or block data can happen

    It’s been default for a few releases now

    Mandating it for peers would split the network for any nodes that don’t support v2 transport. It’s not going to happen in the next 5-10 years, maybe ever.

    30 of which used a miner-based service to exceed the 83 byte limit. Not 30,000. Not 3,000,000. 30.

    This directly contradicts your security argument. If nodes need protection, they need protection, but this PR materially doesn’t change it. You’re relying on attackers simply not trying.

  107. moth-oss commented at 3:44 pm on April 29, 2025: none

    Concept NACK

    removing this limit won’t solve the UTXO bloat issue. There are efforts underway to solve that which is a more productive direction for those worried about the bloat.

    I’m not opposed to changes in the future, but right now there is no hurry to do this. In fact, doing so now can be counterproductive, both from a scalability lens, as well as community trust and perception of core.

  108. ctrlbreak- commented at 3:49 pm on April 29, 2025: none
    Concept NACK.
  109. hsjoberg commented at 4:11 pm on April 29, 2025: contributor
    Concept ACK for the reasons given in OP.
  110. PlayBounty commented at 4:17 pm on April 29, 2025: none
    We can all at least agree that this is controversial, so the urgency to merge is confusing. Please stop and give folks more opportunity to reach a rough consensus.
  111. Jeremy-coding commented at 4:25 pm on April 29, 2025: none

    ACK.

    So many people in this thread have not read Hijacking Bitcoin & it shows. People here are actually commenting on Github expecting their opinion or “the amount of controversy” to have any impact on what happens at all.

    Sorry guys, but that’s how you like to imagine Bitcoin works but not how it actually does. Read some Bitcoin history & figure it out.

  112. glozow commented at 4:26 pm on April 29, 2025: member
    Reminder that this is a pull request open for code review, not a per-username voting forum. Reviews are weighted by the merit of their arguments, not the number of times they are posted. Please rest assured that if your point has already been made here or on #28130, you don’t need to post it again. There is no reason to leave unsubstantiated or repeat acks/nacks other than to spam the people subscribed to this repo.
  113. donaldevine commented at 4:31 pm on April 29, 2025: none
    Concept NACK. There are no valid reasons to remove the code to enforce datacarrier limits unless the objective was to provide a potential attack vector.
  114. wizkid057 commented at 4:42 pm on April 29, 2025: none

    P2P encryption must be default and no more clear relay of txn or block data can happen

    It’s been default for a few releases now

    Mandating it for peers would split the network for any nodes that don’t support v2 transport. It’s not going to happen in the next 5-10 years, maybe ever.

    Sad reality is that we’ll directly cause people grief from this.

    30 of which used a miner-based service to exceed the 83 byte limit. Not 30,000. Not 3,000,000. 30.

    This directly contradicts your security argument. If nodes need protection, they need protection, but this PR materially doesn’t change it. You’re relying on attackers simply not trying.

    It does not contradict anything.

    As much as everyone likes to dunk on it, security through obscurity is a thing that has some amount of impact. Right now the methods of actual attack are rather obscure or exceedingly difficult. No one knows about librerelay. No one cares about mara slipstream. Just a handful of generic spammers. Neither of them do any good for Bitcoin as Bitcoin, and we’ve been incredibly fortunate that more harm hasn’t already been done through these and other methods to-date.

    Tearing down the only thing standing between users and obvious and likely harm should not be something we just all nod in agreement to without serious consideration of all possible damage it can and will do to the ecosystem and project as a whole.

    This change is as controversial as it could possible get.

  115. TheGuySwann commented at 4:53 pm on April 29, 2025: none

    NACK

    Not only is this issue deeply controversial and the standard has been since the beginning to not force or push changes that are controversial and this is a horrible look and will create pointless distrust in Core, but continuing to spend time on this issue and making changes for the sake of making changes when nobody asked for this is such a profound waste of time and resources.

    This is only showing people that core isn’t interested in what the users or the network actually care about, and pushing forward with this would be incredibly ill advised. This is not an arbitrary or small issue and you will start problems that are vastly larger than this in response.

  116. rot13maxi commented at 4:55 pm on April 29, 2025: none

    Here’s an opreturn from a year ago that contains a base64-encoded dickbutt: https://mempool.space/tx/8c9fe58186c199fa9f8d72c121a45270f70d3854e67238f3c7c319989a50921b

    Not mined by MARA btw.

    if someone wants to put something fun or malicious in an opreturn, its not hard.

    Also, if inscriptions ever became a popular mechanism for content that was illegal or politically unpopular and people/companies/LEO wanted to scan for it, its trivial to add (the hashes of) inscription-encoded versions of those files to scanners. Files being in 520-byte chunks vs in an opreturn doesnt really change anything in your hypothetical threat model.

  117. TheGuySwann commented at 5:07 pm on April 29, 2025: none

    That makes no difference and everyone knows this, making it easier is not a strategy. That’s like saying its easy for someone to jump over my fence, thus why should i be allowed to put up a fence? The point is Im deciding whether or not i want a fence and when you push a change that removes the option, you’re going to make people furious over nothing… and per you’re own argument it wouldn’t change anything. If it doesn’t change anything then its clearly not needed for any reason. The only reason to even suggest it would be to argue that it does, in fact, change something.

    Notice I didn’t mention whether it was trivial or not to add data, I explicitly brought up the controversy behind the idea and the obvious fact that this is done directly in opposition to what users and node operators are concerned with or care about. Bringing up the same point that’s been brought up 15,000 times isn’t addressing the issue or solving any problem.

  118. Psifour commented at 5:14 pm on April 29, 2025: none

    Concept ACK

    I support reducing/eliminating standardness rules where possible; however, the inclusion of a reduction in user (node runner) choice is unacceptable. Simplify this to just a change of the default value to match the blocksize or transaction size limits and I am 100% onboard.

    I may think that it is illogical to do so, but I support having the -datacarrier and -datacarriersize flags remain available for those who feel they need them. Doing so is relatively trivial and comes with minimal/no downsides for those operating in the default codepath (other than a few cycles wasted on a conditional check).

  119. owenstrevor commented at 5:19 pm on April 29, 2025: none

    Concept ACK.

    Since @pinheadmz is allowing @wizkid057 from Ocean Mining—an organization that has repeatedly demonstrated ideologically-driven positions disconnected from both facts and practical considerations—to keep his off-topic rant here, I trust the moderators will remain unbiased by similarly allowing myself and others the opportunity to respond to it.

    Moderation suggestion: close to non-contributors.

    This is far more than a small technical change, so the broader community should not be shut out of the discussion or shuffled off to the mailing list. This is a fundamental change to the nature of what the Bitcoin network itself is in its entirety.

    • Merging this PR means Bitcoin is no longer a decentralized currency.
    • Merging this PR means Bitcoin is no longer money.
    • Merging this PR means Bitcoin is no longer a store of value.
    • Merging this PR means Bitcoin is no longer what users, node runners, etc signed up for and adopted.
    • Merging this PR means Bitcoin is no longer Bitcoin.

    That may sound like hyperbole, but it really isn’t. If this PR is merged, Bitcoin as we know it changes forever in the most fundamental way imaginable: The reference implementation explicitly turning the Bitcoin network into an arbitrary data storage system, instead of evolving it as a decentralized currency.

    It’s one thing to not act in the face of an attack. It takes discipline and dare I say courage to act in the face of a heavy attack on a system. So while I wholeheartedly disagree with the refusal to merge bug fixes like #28408, I can partly understand the developers’ inaction and fear.

    This PR on the other hand, is not only a direct attack on the nature of Bitcoin itself, its merge would undermine that same nature in the worst possible way. This type of change should be treated with no less scrutiny than a hard fork, because that’s essentially what this is: A fork away from being a decentralized currency towards being decentralized nothingness.

    I don’t think the gravity of such a change can be understated. This PR might as well be titled, “Quickest way to kill the Bitcoin project.”

    Anyway, since this is going to get merged anyway despite wide community objections, allow me to make a prediction:

    • This PR get’s merged.
    • Centralized mining pools continue to adopt Bitcoin Core changes like this.
    • After some relatively short period of time, there are an incredibly small number of > 83 byte OP_RETURNs mined.
    • Headline: See? It wasn’t so bad! No abuse of oversized OP_RETURNs.

    Why? Because the people cramming arbitrary data into the blockchain already have an effectively sanctioned method of doing so that will cost them 4x less in fees, and 4x the arbitrary data size. As someone attacking the network with spam, why would I pay 4x the cost to store my garbage with this PR via OP_RETURN when my current method is ALREADY “standard” through Bitcoin Core’s stated intention to do nothing about it, AND when done non-standard can give me 4x the data? No-brainer for them.

    So while this PR is an attack on Bitcoin itself and I hate everything about it (and so should you), it’s also completely pointless from a technical and incentives perspective unless combined with something like #28408 to make OP_RETURN the “proper” way to store data.

    1. Misrepresentation of Bitcoin’s Nature The author claims merging this PR means Bitcoin stops being money, a decentralized currency, or a store of value. This is pure hyperbole (even though he says it’s not) without any substantive evidence. Bitcoin’s essence isn’t altered by accommodating arbitrary data. Bitcoin remains a decentralized, permissionless protocol—exactly what enables its resilience and innovation.

    2. Fear vs. Empirical Evidence The author’s prediction—that Bitcoin would devolve into “decentralized nothingness”—is grounded entirely in fear-based rhetoric rather than empirical analysis. Historically, disruptive technologies always grow beyond their initial use cases (PayPal came from eBay, WeChat Pay from WeChat, etc.). Let’s not forget, the original Bitcoin Client v0.1 release by Satoshi had an unfinished poker game and an eBay-style marketplace in the source code. Not to mention, Satoshi supported selling a JPEG for 500 BTC in 2010. Ordinals and expanded data use-cases via OP_RETURN enhance practical utility without compromising Bitcoin’s foundational decentralization.

    3. Ignoring Bitcoin’s Adoption Flywheel The author overlooks the critical importance of real-world use cases as key drivers of adoption. Expanded OP_RETURN capability aligns precisely with The Bitcoin Use Cases Theory: more use cases → more adoption → increased user base → stronger Bitcoin network effect. Rather than weakening Bitcoin, such changes are vital for driving mass adoption and economic relevance.

    4. False Dichotomy of “Spam” and Value The author frames storing data in Bitcoin as “spam,” conveniently ignoring that Ordinals and similar use cases are valued in billions of dollars. Labeling high-value economic activities as “spam” is misleading. Markets, not individual opinions, determine what has value. Clearly, the market finds Ordinals valuable, reinforcing Bitcoin’s role as a unit of account and medium of exchange.

    5. Ignoring Historical Precedent of Innovation The author incorrectly asserts that allowing other use cases to be possible will damage Bitcoin irreparably. Yet, historically, things like Ordinals have strengthened Bitcoin, driving greater decentralization (through self-custody) and adoption (new user inflows). Just like how PayPal leveraged eBay (which rose to prominence selling Beanie Babies), Bitcoin can leverage use cases like Ordinals to become robustly adopted peer-to-peer cash.

    6. Misguided Technical Arguments The author admits the PR change is technically benign—stating attackers already have cheaper methods. Ironically, this undermines their entire argument. If cheaper, more data-intensive methods already exist without harming Bitcoin, why would a more expensive alternative suddenly destroy Bitcoin’s foundational attributes? Their logic contradicts itself.

    7. No Evidence of Centralization The author’s claim about increased centralization is unsubstantiated. Historically, new Bitcoin use cases have incentivized self-custody and decentralization. Ordinals actively motivate moving BTC off centralized exchanges into self-custodied wallets. Thus, innovation fosters greater decentralization, not less.

  120. crownbtc commented at 5:25 pm on April 29, 2025: none

    NACK

    Echoing the reasons stated by @TheGuySwann

  121. matthew-ellis commented at 5:32 pm on April 29, 2025: none

    Bitcoin’s success rests on prioritizing decentralization and minimizing the resource burden on full nodes over time.

    Removing arbitrary limits on OP_RETURN data increases the risk of blockchain bloat for marginal benefit. Even if fees partially discourage abuse, Bitcoin’s adversarial environment teaches that any opening for data monetization will eventually be exploited.

    Every additional byte recorded imposes a cost not just today but permanently on future node operators, many of whom may not have high bandwidth, storage, or technical resources.

    Bitcoin must remain accessible to anyone running inexpensive hardware if it is to retain its censorship resistance and neutral verification properties.

    OP_RETURN was intentionally designed for small metadata, not bulk storage. Expanding it undermines Bitcoin’s role as a monetary settlement layer and risks repurposing it as a generic data host — a mission creep Bitcoin explicitly avoided.

    Long-term decentralization demands that protocol changes bias heavily toward conservatism, not flexibility, particularly where irreversible growth pressures are concerned.

    NACK on the grounds of decentralization risk and permanent costs to future node operators.

  122. billylindeman commented at 5:33 pm on April 29, 2025: none

    Concept NACK,

    Making it easier to embed files in bitcoin is fundamentally the opposite direction I would like to see the project go. Might be time to fork core if this gets merged in. Bitcoin is money, let’s keep it that way.

  123. jaonoctus commented at 6:05 pm on April 29, 2025: none

    Concept ACK

    This is just a mempool policy and other implementations, like Libre Relay, “bypass” it. So I don’t see a reason to filter transactions from the mempool if we’re still going to accept them in blocks. So if someone wants to broadcast a certain type of transaction that follows the consensus rules validated by nodes and they are paying for, they should be able to

  124. bitcoin deleted a comment on Apr 29, 2025
  125. murchandamus commented at 6:19 pm on April 29, 2025: contributor

    Concept ACK on removing the limit on OP_RETURN size and count.

    The limit on OP_RETURNs size is ineffectual, causes increased node traffic, and drives mining centralization. While I have no personal desire for more large OP_RETURNs on the blockchain, it is preferable to have data be written into OP_RETURNs than the UTXO set, and it is preferable to see the transactions I’m competing with in my mempool, than to incentivize build-out of mechanisms for direct submission to the largest mining pools.

  126. gavinmclelland commented at 6:34 pm on April 29, 2025: none

    This change brings Bitcoin closer to its original spirit as designed by Satoshi Nakamoto.

    Early Bitcoin allowed arbitrary data to be recorded on-chain without hardcoded limits. OP_RETURN and transaction outputs were intended to serve general-purpose timestamping, settlement, and proof anchoring, governed by economic incentives rather than protocol constraints.

    Removing arbitrary datacarrier size limits aligns with the principle that Bitcoin should be a flexible, permissionless settlement layer — where fees, not code, decide the economic viability of embedding metadata.

    It’s good to see Bitcoin regaining this aspect of its original design.”

    (Source: Satoshi, BitcoinTalk.org, August 2010 — “I’m not advocating this, but Bitcoin can be extended to record other types of data transactions, e.g. stock trades, bets, or any kind of contracts.”)

  127. cbspears commented at 7:04 pm on April 29, 2025: none
    Concept ACK. Relay policies should be updated to match consensus rules, especially when there is demonstrated demand for nonstandard transaction types that are not identified as DoS attack vectors.
  128. sonoranai commented at 7:10 pm on April 29, 2025: none
    NACK—lifting OP_RETURN limits trades off blockchain efficiency for marginal utility, risking bloat and undermining Bitcoin’s core monetary use-case. This should not proceed.
  129. sonoranai commented at 7:17 pm on April 29, 2025: none

    Removing arbitrary datacarrier size limits aligns with the principle that Bitcoin should be a flexible, permissionless settlement layer — where fees, not code, decide the economic viability of embedding metadata.

    That position overlooks a critical reality:

    Bitcoin’s economic viability isn’t solely determined by fees but also by node operability and decentralization.

    Removing OP_RETURN limits opens the door to systematic blockchain bloat, disproportionately burdening smaller operators and eroding decentralization over time.

    Bandwidth and storage costs aren’t theoretical—they directly influence the network’s accessibility and resilience.

    Bitcoin’s flexibility must remain balanced by thoughtful protocol constraints, not simply delegated to fee markets that often lag behind systemic risk.

    NOT A DUPE.

  130. LaurentMT commented at 7:53 pm on April 29, 2025: none

    Concept NACK.

    This proposal won’t allow to reach the stated goal (limiting the misuse of witness data) if the incentives model isn’t aligned too but doing it is likely to be very contentious.

    As is, data stored in an op_return output will consume more resources (block weight) than the same amount of data stored in the witness and as a consequence will do more harm than good by providing a “solution” that decreases the utility provided by the network (independently of how this utility is measured - i.e. in term of quantity of arbitrary data stored in the block or in term of number of bitcoin payments registered in the block- ) while still allowing to store data in the witness at a lower cost.

    A proper solution would also change the weight of data stored in op_return outputs in order to align it with the weight applied to witness data. It wouldn’t protect blocks from being used as data stores but it would properly protect the UTXO set.

    But no need to say that such a proposal would be very contentious…

  131. miketwenty1 commented at 8:11 pm on April 29, 2025: contributor

    Concept ACK.

    Right now AFAIK:

    • 1 standardness OP_RETURN per transaction, capped on size.
    • People who want to bypass this limit use specialized services and send transactions directly to miners.
    • “Clever” ideas have come about to embed data arbitrarily within rules of relay standardness, and these utxo’s cannot be pruned, unlike OP_RETURN data.
    • If the rules to cap OP_RETURN didn’t exist, perhaps the current trend of embedding into witness data and creating forever dust wouldn’t have emerged (though speculative).

    Lifting the OP_RETURN limits for standardness won’t completely prevent the more harmful forms of spam or UTXO set bloating. However, it provides clear, pruneable alternative for arbitrary data (better long term).

    Ben summarized this well here: #32359 (comment)

    I sympathize with the “NACKers”. I assume they are correct to suspect if OP_RETURNS are more liberal then people will openly create more transactions with large OP_RETURNS for the luls and new invented spam protocols. But there’s no practical reason to mandate that “spam” HAS to create unprunable utxo’s and create permanent graffiti on-chain.

    I’m not worried about people paying for blockspace and finding usecases they want to pay for in a cleaner way. For me it comes down to unprunable occult dust utxos vs making it easier to create huge pruneable OP_RETURNs.

  132. fjahr commented at 8:25 pm on April 29, 2025: contributor
    Concept ACK to remove the limits on OP_RETURN (both size and count). I don’t see a need to remove the config options at this point and would support keeping them in at this point, with a deprecation message. Though that is not a blocker for me.
  133. BTCMcBoatface commented at 9:02 pm on April 29, 2025: none
    ACK, but actually NACK. What if you leave the datacarrier and datacarriersize config options but remove the enforcement code: filter-enjoyers don’t get mad, code is cleaner, limits remain ineffective.
  134. BrazyDevelopment commented at 9:27 pm on April 29, 2025: none

    I have significant concerns about removing the datacarrier and datacarriersize limits without thoroughly addressing the potential for exacerbating existing attack vectors.

    Bitcoin’s mempool and network already face challenges from known attack vectors like flood and loot attacks, replacement cycling, and irreversible fee attacks, which exploit transaction propagation and fee mechanics to burden nodes or disrupt confirmation reliability.

    By removing OP_RETURN limits, we risk introducing new vectors for abuse, such as flooding the network with large, unspendable data outputs, without clear mitigations. These could amplify mempool bloat, increase node resource demands, and potentially incentivise malicious actors to exploit unspendable outputs in ways that compound existing issues, like driving up fees or delaying legitimate transactions.

    While provably unspendable outputs are preferable to dust outputs in some contexts, the absence of any guardrails could make it easier for bad actors to stress the network, especially in combination with existing vulnerabilities. I’d suggest a more cautious approach: perhaps retain a configurable upper bound on OP_RETURN size or introduce rate limiting mechanisms to deter abuse while still allowing flexibility. We should also prioritise simulations or testnet experiments to quantify the impact on mempool dynamics and node performance under adversarial conditions.

    I’d love to see this PR paired with robust protections against these risks, as adding potential attack vectors on top of Bitcoin’s existing challenges feels counterproductive without them.

  135. owenkemeys commented at 10:06 pm on April 29, 2025: none

    Concept ACK - but go further and clean this up once and for all. We may not want data, but many do, and are happy to work around frictions including creating tooling to automate that. Similarly, the fullrbf saga demonstrated that a minority of more permissive nodes is enough to undermine all filtering.

    I entirely sympathise with the desire of many to minimise arbitrary data - I even agree. Bitcoin is not for that. But the mechanics and economics of the situation dictate that as soon as anyone wants there to be data - there will be data. Given that, we have a duty to users to minimise the burden it causes, and this can be economically incentivised.

    op_return is the least burdensome way to store data. Less than as witnesses (inscriptions) or hiding in any of the multitude of other “real” fields which will never be blocked until everything is whitelisted. The only reason remaining to use inscriptions over a consensus-bound-only op_return for data storage would be either because you want over 1mb in one chunk, or because of the witness discount - which we should retain to encourage UTXO consumption.

    Counterintuitive as it may seem at casual glance, the least-harm path would be removing the various limits on op_return AND providing it a fee rate discount in line with the witness discount. Inscriptions need two transactions to store data, whilst op_return only needs one, so they would fall out of favor for most use cases, and thus free up block space.

  136. jackedproxy commented at 11:09 pm on April 29, 2025: none

    Concept NACK Core holds 90%+ of active nodes. It’s the go-to, and as such has a responsibility of keeping to sound defaults. Merging such a change with the amount of controversy it’s generating on this thread (and elsewhere) is, at best, irresponsible.

    A change such as this will have severe consequences on storage space, disincentivizing users from running nodes. Node-running accessibility starts with hardware pre-reqs.

    Bitcoin’s node count is only so high because it is accessible to run and storage space follows general consumer trends over time, be it in storage space and price - Setting an expectation of high-costs on storage space potentially not proportional to and on-par with today’s trend is not acceptable.

  137. jlopp commented at 11:52 pm on April 29, 2025: contributor

    A change such as this will have severe consequences on storage space, disincentivizing users from running nodes.

    Absolutely false, @jackedproxy. This policy change does not increase the total data throughput allowed on the network. If anything, one could argue that it does the opposite: OP_RETURN data is not discounted like witness data is, thus the size of blocks with data in OP_RETURNs is smaller than those with data in witnesses.

  138. jlopp commented at 0:01 am on April 30, 2025: contributor

    Bitcoin’s mempool and network already face challenges from known attack vectors like flood and loot attacks, replacement cycling, and irreversible fee attacks, which exploit transaction propagation and fee mechanics to burden nodes or disrupt confirmation reliability.

    By removing OP_RETURN limits, we risk introducing new vectors for abuse, such as flooding the network with large, unspendable data outputs, without clear mitigations. These could amplify mempool bloat, increase node resource demands, and potentially incentivise malicious actors to exploit unspendable outputs in ways that compound existing issues, like driving up fees or delaying legitimate transactions.

    This is so incredibly vague that it reads like an LLM output. @BrazyDevelopment nothing in your comment actually specifies a novel attack vector. Nodes already have resource management logic that mitigates the issues you outlined.

  139. blksqd commented at 0:12 am on April 30, 2025: none
    Seems to me that Peterodd has an agenda and this issue appears to reflect his wish to brute force this PR at all costs. That alone should make this change rejectable.
  140. 0ceanSlim commented at 0:55 am on April 30, 2025: none

    That makes no difference and everyone knows this, making it easier is not a strategy. That’s like saying its easy for someone to jump over my fence, thus why should i be allowed to put up a fence? The point is Im deciding whether or not i want a fence and when you push a change that removes the option, you’re going to make people furious over nothing… and per you’re own argument it wouldn’t change anything. If it doesn’t change anything then its clearly not needed for any reason. The only reason to even suggest it would be to argue that it does, in fact, change something.

    Notice I didn’t mention whether it was trivial or not to add data, I explicitly brought up the controversy behind the idea and the obvious fact that this is done directly in opposition to what users and node operators are concerned with or care about. Bringing up the same point that’s been brought up 15,000 times isn’t addressing the issue or solving any problem.

    It’s more like Core devs gave everyone a fence by default and the size of the fence was arbitrary. The better solution is to not force everyone to have a fence by default and let people build their own fences however high they want.

  141. sbddesign commented at 3:20 am on April 30, 2025: none

    Concept ACK

    As long as there is hashrate willing to include a non-standard OP_RETURN in a block, then no one single node’s policy is going to prevent that OP_RETURN from entering a block. And if users are going to try and store data on-chain, using an output that does add to the existing UTXO set seems preferable.

  142. SergioDemianLerner commented at 3:36 am on April 30, 2025: contributor

    Concept ACK.

    OP_RETURN not only allows arbitrary data to be included, it allows data that can be consumed by Bitcoin smart contracts with ESSPI (https://arxiv.org/abs/2503.02772). This facilitates the creation of Bitcoin L2s that need more expressive Bitcoin contracts to work.

  143. albertoig commented at 3:38 am on April 30, 2025: none
    Concept NACK. This is a direct method of attack.
  144. abdelrahman543873 commented at 4:09 am on April 30, 2025: none
    The proposed Bitcoin Core change could pose risks to Bitcoin’s usability and decentralization by allowing more non-financial data, potentially bloating the blockchain and making it harder for regular users to run nodes. This might centralize control, as only those with significant resources could manage full nodes
  145. nolim1t commented at 4:12 am on April 30, 2025: none

    Moderation suggestion: close to non-contributors.

    This is far more than a small technical change, so the broader community should not be shut out of the discussion or shuffled off to the mailing list. This is a fundamental change to the nature of what the Bitcoin network itself is in its entirety.

    * Merging this PR means Bitcoin is no longer a decentralized currency.
    
    * Merging this PR means Bitcoin is no longer money.
    
    * Merging this PR means Bitcoin is no longer a store of value.
    
    * Merging this PR means Bitcoin is no longer what users, node runners, etc signed up for and adopted.
    
    * Merging this PR means Bitcoin is no longer Bitcoin.
    

    That may sound like hyperbole, but it really isn’t. If this PR is merged, Bitcoin as we know it changes forever in the most fundamental way imaginable: The reference implementation explicitly turning the Bitcoin network into an arbitrary data storage system, instead of evolving it as a decentralized currency.

    It’s one thing to not act in the face of an attack. It takes discipline and dare I say courage to act in the face of a heavy attack on a system. So while I wholeheartedly disagree with the refusal to merge bug fixes like #28408, I can partly understand the developers’ inaction and fear.

    This PR on the other hand, is not only a direct attack on the nature of Bitcoin itself, its merge would undermine that same nature in the worst possible way. This type of change should be treated with no less scrutiny than a hard fork, because that’s essentially what this is: A fork away from being a decentralized currency towards being decentralized nothingness.

    I don’t think the gravity of such a change can be understated. This PR might as well be titled, “Quickest way to kill the Bitcoin project.”

    Anyway, since this is going to get merged anyway despite wide community objections, allow me to make a prediction:

    * This PR get's merged.
    
    * Centralized mining pools continue to adopt Bitcoin Core changes like this.
    
    * After some relatively short period of time, there are an incredibly small number of > 83 byte OP_RETURNs mined.
    
    * Headline: See? It wasn't so bad! No abuse of oversized OP_RETURNs.
    

    Why? Because the people cramming arbitrary data into the blockchain already have an effectively sanctioned method of doing so that will cost them 4x less in fees, and 4x the arbitrary data size. As someone attacking the network with spam, why would I pay 4x the cost to store my garbage with this PR via OP_RETURN when my current method is ALREADY “standard” through Bitcoin Core’s stated intention to do nothing about it, AND when done non-standard can give me 4x the data? No-brainer for them.

    So while this PR is an attack on Bitcoin itself and I hate everything about it (and so should you), it’s also completely pointless from a technical and incentives perspective unless combined with something like #28408 to make OP_RETURN the “proper” way to store data.

    But all this is optional to run right? I run a node which does not forward shitcoin data. If enough of us run this then whoever has wanted this is wasting their time?

  146. leCheeseRoyale commented at 4:28 am on April 30, 2025: none

    Additional Concerns – Concept NACK

    While many critical points have already been raised, I’d like to highlight several underdiscussed but significant risks introduced by this PR:

    1. Fee Market Distortion via “Cheap” OP_RETURNs

    Removing all limits on OP_RETURNs creates a perverse incentive: transactions can now carry large, non-economic payloads while avoiding long-term storage costs (since OP_RETURNs don’t enter the UTXO set).This allows chain data to be subsidized at rates far below what’s fair in a constrained blockspace market, encouraging chain bloat for effectively free.

    1. Off-Chain Miner Incentives + Spam Collusion Risk

    A key overlooked threat: miners can be externally compensated to mine low-fee, high-data transactions (e.g., from protocols like inscriptions or private data anchoring services).With this PR making such transactions “standard,” Core relinquishes its main tool to discourage such behavior, potentially enabling coordinated spam attacks that the mempool can no longer filter.

    1. Legal & Reputational Risk: Malicious Payloads

    Expanding unrestricted OP_RETURN use invites obfuscated data insertion, including hashes of illicit content, malware blobs, or CSAM fingerprints — none of which are visibly labeled or filtered.This could expose node operators (especially in regulated environments) to unintended legal liability and reputational harm.

    1. Forensics and Spam Detection Blind Spots

    OP_RETURN abuse weakens tools used to detect spam or adversarial behavior, since these outputs are inherently unlinked to future transactions and harder to analyze.This undermines both public monitoring and miner reputation systems.

    ⚠️ Conclusion

    This PR does more than remove “arbitrary limits.” It dismantles policy-level defenses and opens clear attack vectors without adding compensatory safeguards.

    We should not normalize high-bandwidth, low-fee chain usage under the banner of simplification or user freedom. The unintended consequences are substantial, and under a worst-case model, could degrade the Bitcoin network’s utility for economic transactions.

  147. captCovalent commented at 6:48 am on April 30, 2025: none

    Concept NACK

    • First, it’s a security mess.

    • Second, bigger transactions would bloat the blockchain, slowing things down and making it tougher for regular folks to run nodes, which could centralize Bitcoin.

    • Third, Bitcoin’s about money, not storing random data. Opening this up feels like a step away from its core purpose. Plus, there’s no clear agreement among devs or the community, and there are better ways to handle data needs without going all-in like this. I mean what does this PR achieve other than issues!?

    Bottom line: this PR’s too risky and doesn’t fit Bitcoin’s vibe. It shouldn’t be merged.

  148. nud3l commented at 7:58 am on April 30, 2025: none

    Concept ACK

    There should be a canonical way to include data to Bitcoin that is most efficient for the network. OP_RETURN is a much more efficient way than using taproot tricks.

  149. bitcoin deleted a comment on Apr 30, 2025
  150. mrberlinorg commented at 8:05 am on April 30, 2025: none

    Concept NACK

    This PR introduces a fundamental shift in Bitcoin’s networking model by encrypting peer-to-peer transport via BIP324. While the goals of improving privacy and censorship resistance may seem beneficial, the trade-offs involved are deeply concerning from both a philosophical and technical standpoint.

    Loss of network transparency Bitcoin’s peer-to-peer layer has always been observable, enabling traffic analysis, censorship detection, and independent verification of network behavior. Encrypting message payloads obscures this visibility, making it significantly harder to detect censorship, analyze propagation issues, or audit the health of the network.

    Security overreach undermines auditability While this change is framed as a security improvement, it primarily obfuscates traffic patterns rather than securing critical data. Tor and I2P already offer transport-level privacy where needed. Introducing encryption at the Bitcoin protocol layer disables legitimate observability without solving meaningful privacy issues on-chain.

    Increased complexity and maintenance burden Adding cryptographic handshakes, session management, and encryption layers significantly increases protocol complexity and the potential attack surface. This raises the barrier to entry for contributors and node operators, fostering a more centralized, expert-driven maintenance model over time.

    Lack of community-wide consensus This proposal effectively deprecates the plaintext P2P layer in the long run. A change of this magnitude requires explicit community-wide consensus, not just implementation-level agreement. Merging such a deep protocol change without broader buy-in risks alienating users and downstream ecosystems.

    This proposal, although technically impressive, erodes key properties that have defined Bitcoin’s resilience and trust minimization for over a decade. Any privacy gain should not come at the cost of disabling independent network auditability and transparency.

    Strong Concept NACK.

  151. monlovesmango commented at 8:09 am on April 30, 2025: contributor

    The proposed Bitcoin Core change could pose risks to Bitcoin’s usability and decentralization by allowing more non-financial data, potentially bloating the blockchain and making it harder for regular users to run nodes.

    Second, bigger transactions would bloat the blockchain, slowing things down and making it tougher for regular folks to run nodes, which could centralize Bitcoin.

    As #32359 (comment) states, this PR does not increase node resources nor make it harder for regular users to run nodes. In regards to mitigating bloat on the blockchain, that’s exactly what the motivation of this PR is about. Minimizing the number of unspendable taproot outputs that will forever have to be stored on every node.

    Of all the claims that it will be harder to run a node, I have yet to read one that actually states the technical reasons why running a node would be harder. It would be greatly appreciated if someone can clarify that for me. There shouldn’t be any additional storage/bandwidth costs with this change, and if this change does have an impact it would be to reduce UTXO bloat by preventing unspendable outputs.

    1. Fee Market Distortion via “Cheap” OP_RETURNs

    If this PR actually has the intended effect, it would actually be more expensive to use data in OP_RETURNs because it is not discounted like the witness data. If you are concerned about subsidizing data storage on the blockchain, then you should want less data storage in the witness (which is the aim of this PR).

    1. Off-Chain Miner Incentives + Spam Collusion Risk

    Miners are more likely to be externally compensated when the transactions users/companies want mined are non-standard by mempool policies. Imposing data size limits on OP_RETURN in Core’s mempool policy actually encourages this behavior, as coordinating privately with miners would be the best option to get txs mined.

    1. Legal & Reputational Risk: Malicious Payloads

    This has already been covered, see #32359 (comment).

    1. Forensics and Spam Detection Blind Spots

    It sounds to me you are suggesting that being able to do “public monitoring” on “spam” txs is a good thing, in which case I just fundamentally disagree as this sounds awfully similar to chain analysis. I couldn’t follow how this relates to miner reputation systems.

    I mean what does this PR achieve other than issues!?

    Stating its a security mess with no elaboration does not count as an issue. In what way is this a security mess, specifically? Your second issue is not an issue, as addressed above. Your third issue is not an issue, it is a disagreement on what you think bitcoin’s vibe should be.

    Given that OP_RETURN is more expensive than storing data in the witness I am not even sure this PR will make people switch to using the OP_RETURN. However, at least it directionally does encourage less harmful usage of the blockchain which is what most of the ACK rationales seem to focus on. Disappointingly, the NACK rationales seem to mostly center around a philosophy of “bitcoin shouldn’t give into spammers” which I find to be far less important (and frankly, a complete antithesis to the saying “bitcoin is for enemies”) than actually finding ways to mitigate the harm that spam does to the blockchain long term.

  152. francisco-alonso commented at 8:16 am on April 30, 2025: none

    Concept NACK !

    This affects node costs, increases pressure on fees, and slowly centralizes the network. These are not side effects, for me they are fundamental design tradeoffs. Bitcoin’s value comes from being simple, predictable, and hard to change (and should be like this forever). Core fundamentals like minimizing blockchain bloat and protecting decentralization should not be addressed without consensus.

    At the end of the day, this is not just about OP_RETURN. The real issue is whether it is acceptable for a small group of developers to push changes that touch Bitcoin’s core assumptions without clear aand community consensus

  153. in src/policy/policy.cpp:163 in 47e713ea5a outdated
    151@@ -159,12 +152,6 @@ bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_dat
    152         return false;
    153     }
    154 
    155-    // only one OP_RETURN txout is permitted
    156-    if (nDataOut > 1) {
    


    mrberlinorg commented at 8:26 am on April 30, 2025:

    Removing the check for nDataOut > 1 would allow multiple OP_RETURN outputs in a single transaction, which goes against the standard behavior of the Bitcoin protocol. This could introduce several issues:

    Non-standard transactions: Multiple OP_RETURN outputs in a transaction are considered non-standard. Allowing them could lead to network inconsistencies, as some nodes might not be able to properly process or relay these transactions.

    Network congestion: More OP_RETURN outputs would increase transaction size, reducing the number of transactions that can be included in each block, which could lead to increased network congestion.

    Compatibility problems: Non-standard transactions could cause compatibility issues with other nodes, wallets, and services that expect standard behavior.

    Maintaining this check ensures that Bitcoin transactions remain within the protocol’s standards, preventing these potential issues and maintaining network stability.

  154. Sjors commented at 8:38 am on April 30, 2025: member

    You could consider leaving the options in and just increasing the default to max block size. I don’t feel strongly about doing this - the config option would just be a footgun long term - but we did do -mempoolfullrbf removal in separate stages. It might make this less controversial.

    At this point I think the controversy is sunk cost, and staging the removal just means another round of all this.


    Things that should be discussed on the mailinglist*, but I’ll respond to them here anyway: @moth-oss wrote:

    removing this limit won’t solve the UTXO bloat issue. There are efforts underway to solve that which is a more productive direction for those worried about the bloat.

    I’m a fan of Utreexo, but it’s years if not decades away from being a soft fork (proposal). Meanwhile the UTXO set keeps growing, and although the set doesn’t need to kept all in RAM, you can’t prune it either.

    Also note that Utreexo as a soft fork, with the spend proofs committed in blocks, would significantly increase the block size. @LaurentMT:

    As is, data stored in an op_return output will consume more resources (block weight) than the same amount of data stored in the witness

    There is no difference in actual resource consumption, block weight is just an accounting trick. The only exception is a pruned node that syncs without downloading and verifying the witness data, which nobody has implemented for the past eight years since SegWit made it possible…

    * = discussing Bitcoin Core settings seems appropriate for a PR here, but (new!) objections to the change in standardness should be raised on the mailinglist

  155. Haaroon commented at 9:03 am on April 30, 2025: none

    I’m on the fence with this proposal as a user of core.

    It’s wholly unfair that those who have the power to use a private mempool or use custom node implementations can already do such things. Those around us are using bypasses, then this clearly levels the playing field.

    After reading the discussion…

    Concept ACK.

  156. cezar1 commented at 9:23 am on April 30, 2025: none
    as a node runner, concept NACK. the parameters and functionalities to be removed act ad minimum as tutorial for spam self defense.
  157. boring877 commented at 9:51 am on April 30, 2025: none

    Hello, I dont support this bip. Bitcoin is P2P and not financial institutions. The core use case for bitcoin is we can send bitcoin to each other W/O middle man. I dont need more then thats.

    Bitcoin being simple what make it good.

    Please Do NOT play with BITCOIN and LEAVE IT AS It is.

  158. boring877 commented at 9:54 am on April 30, 2025: none
    I have No IDEA how commenting on Bitcoin change make it off-topic. when Changing core thesis of Bitcoin. Bitcoin CORE ARE NOT BITCOIN FRIENDS. YOU are guys are the enemy.
  159. AiJunki commented at 9:57 am on April 30, 2025: none
    Fuck you petertodd. stay off bitcoin. you cunts.
  160. i5hi commented at 10:32 am on April 30, 2025: none
    humble concept NACK
  161. i5hi commented at 10:36 am on April 30, 2025: none
    opens up a worse attack vector. we should be exploring more creative ways to solve utxo bloat.
  162. snakezhu commented at 11:48 am on April 30, 2025: none
    Concept ACK.
  163. LaurentMT commented at 11:48 am on April 30, 2025: none

    @Sjors

    There is no difference in actual resource consumption, block weight is just an accounting trick.

    I have to disagree here. The weight of data stored in blocks has a direct impact on the throughput of the system, a property that is as critical for the operations of the system, if not more, than others properties like the size of the UTXO set.

    A given quantity of data stored in a op_return output has a far larger negative externality on the throughput than the same data stored in a witness. On the others hand, data stored in the witness have a small additional cost in terms of block space and a temporary negative impact on the UTXO set. All aspects considered, it would be rational for any honest actor to prioritize storing data in the witness because 1/ it’s cheaper and 2/ it’s less damaging for the operations of the system.

    From a pure engineering perspective, there’s absolutely no reason for data stored in op_return outputs being weighted differently from data stored in the witness (see archives of posts explaining the rationale behind the “discount” applied to witness data). The real (big) problem is that it would imply that financial bitcoin data cost more than blobs of non-financial data, which is basically the opposite of what we want for a system like Bitcoin…

  164. scgbckbone commented at 11:56 am on April 30, 2025: none

    Concept ACK

    Better to just increase default size and keep config ops. If some people’d like to pretend that it is not already happenig - so be it

  165. Ali2kCom commented at 12:14 pm on April 30, 2025: none
    Concept NACK. Removing OP_RETURN makes it more difficult to run full nodes and, as a result, gradually centralizes the network. This is not an issue where a small group of developers can implement changes that affect Bitcoin core assumptions.
  166. stevenroose commented at 12:15 pm on April 30, 2025: contributor
    Concept ACK. Implementation looks ok, can’t comment on functional test coverage.
  167. Kakar21 commented at 12:34 pm on April 30, 2025: none

    Concept NACK:

    Dropping the 83-byte datacarrier limit makes cheap data-dumping trivial. Even ~1 MB extra OP_RETURN per block means about 52 GB extra chain growth per year, which every node operator has to store. Higher disk and bandwidth costs reduce the number of volunteer nodes and hurt decentralisation. I don’t see a use-case that justifies that trade-off.

  168. ake-khada commented at 12:37 pm on April 30, 2025: none

    Concept NACK.

    Wasn’t folks running their own nodes the prerogative since like all the time? WTF is this other than direct attack on that premise?

  169. Sjors commented at 12:38 pm on April 30, 2025: member

    @LaurentMT

    A given quantity of data stored in a op_return output has a far larger negative externality on the throughput than the same data stored in a witness.

    This makes absolutely no sense, I think you’re confused about how either OP_RETURN or inscriptions work. A byte is a byte no matter where it’s stored in the block.

  170. Specter2100 commented at 12:42 pm on April 30, 2025: none
    Concept NACK. But if the proposal is changed to allow “choosing” a size between 0 and 10,000 bytes instead of “removing” the feature, then I would be Concept ACK. Rather than “removing” the individual choice that has existed until now, wouldn’t it be better to keep it as a “choice” like it is currently?
  171. smbpunt commented at 12:48 pm on April 30, 2025: none

    Concept NACK

    Removing the OP_RETURN size limit risks excessive blockchain growth, increasing storage and bandwidth costs for node operators. This could reduce the number of volunteer nodes, threatening Bitcoin’s decentralization—a core element that must be taken very seriously. I see no use-case justifying this trade-off.

    Additionally, marking some comments as duplicates and hiding them is concerning. Some comments added valuable perspective and weren’t copy/paste. Suppressing discussion on such a critical topic undermines the review process.

  172. bitcoin deleted a comment on Apr 30, 2025
  173. francisco-alonso commented at 1:39 pm on April 30, 2025: none

    This PR must not be merged. I seriously question whether the fact that we can even entertain proposals like this means Bitcoin is truly decentralized. BTC was designed as a p2p transaction system and it has nothing to do with embedding garbage into transactions.

    Core concepts must be untouchable; from that foundation, any proposal is welcome.

  174. LaurentMT commented at 1:39 pm on April 30, 2025: none

    @Sjors Sorry but it seems that we’re talking past each other. Are you telling me that 1 byte of data stored in the witness is weighted like 1 byte of data stored in an op_return output? If it’s not the case then I don’t see how we can disagree that 1 byte of data stored in an op_return output is more damaging to the throughput of the system than 1 byte of data stored in the witness. The fact that the user pays more fees to the miner doesn’t change that.

    EDIT: Ok. I think I get it. You"re talking about the specific case of the Citrea’s project that plans to stores its data directly in an UTXO and not in the witness, right? Well. I think that pushing this PR for this specific reason is a bad idea but I won’t discuss it here since it’s not a technical matter (except for the fact that Citrea’s design choice is terribly bad).

  175. 1440000bytes commented at 2:06 pm on April 30, 2025: none

    Approach NACK

    The options datacarrier and datacarriersize should not be removed. Instead only limits should be removed. Some people may want to use them for different reasons.

    Maintaining core with a patch is not easy. Running older versions is not safe either.

  176. adamdecaf commented at 2:12 pm on April 30, 2025: none

    Concept NACK

    The silencing of dissenting comments here is worrying because they’re not being addressed. There are many valid reasons already expressed in this PR that are valid enough to close this and reject the proposal, but the team has refused so far. Larger data has been tried in other chains, but isn’t what Bitcoin is for. We should be focusing on removing opportunities for spammers, not make their lives easier.

  177. Sjors commented at 2:20 pm on April 30, 2025: member

    Maintaining core with a patch is not easy.

    Knots already does this, plus all the other mempool filtering stuff people demand. The extra maintenance for them is negligible.

    Some people may want to use them for different reasons.

    Such as?

  178. BrazyDevelopment commented at 2:35 pm on April 30, 2025: none

    @jlopp This is so incredibly vague that it reads like an LLM output. @BrazyDevelopment nothing in your comment actually specifies a novel attack vector. Nodes already have resource management logic that mitigates the issues you outlined.

    Apologies for the “vagueness”, it was not an LLM output, allow me to clarify…

    I’m not worried about some brand-new attack vector popping up, my concern is that scrapping OP_RETURN limits could make existing ones, like flood-and-loot or mempool spam, way worse.

    Take flood-and-loot: an attacker could stuff transactions with huge OP_RETURN payloads (think multi-MB within consensus rules) to bloat mempools across nodes. This clogs things up, delays real transactions, and jacks up fees as users compete. Sure, nodes have tools like maxmempool or min relay fees, but those are tuned for normal traffic. Massive OP_RETURN data could push smaller nodes to their memory or bandwidth limits, making it harder for them to kick out junk transactions and keep things running smoothly.

    Then there’s replacement cycling with RBF. Attackers could chain big OP_RETURN transactions, swapping them out repeatedly to gum up the mempool with low-value junk. This messes with fee markets, as nodes struggle to sort out what’s worth confirming. It’s not new, but it’s easier and cheaper to pull off without size caps.

    I get that node resource management helps, but it’s not bulletproof, especially against someone with deep pockets. I’d feel better keeping a high but reasonable datacarriersize limit (say, 100 KB) or adding a dynamic cap tied to mempool stress.

    We should run some testnet attacks to see how bad it could get.

    What do you think current defenses already cover here?

  179. 0ceanSlim commented at 2:39 pm on April 30, 2025: none
    @BrazyDevelopment Who is the arbiter of “low value” here?
  180. jlopp commented at 2:40 pm on April 30, 2025: contributor

    This clogs things up, delays real transactions, and jacks up fees as users compete.

    This is literally how the market for block space operates. You haven’t described anything different.

    Massive OP_RETURN data could push smaller nodes to their memory or bandwidth limits, making it harder for them to kick out junk transactions and keep things running smoothly.

    What, specifically, would make mempool eviction “harder?” The lowest fee rate paying transactions get automatically evicted regardless of what data they contain.

    Then there’s replacement cycling with RBF. Attackers could chain big OP_RETURN transactions, swapping them out repeatedly to gum up the mempool with low-value junk.

    Once again, you describe how Bitcoin already works. This is why RBF replacement requires each new replacement package to pay a higher fee rate that what it’s replacing, thus imposing an economic cost for doing so.

  181. stevanlohja commented at 3:03 pm on April 30, 2025: none

    I like this proposal, however, a moderate increase in the limit is the most prudent path to harness the benefits while managing the downsides because the idea of removing the arbitrary limit is dependent on execution.

    Obvious benefits of removing the limit size is innovation and efficiency because we already have to workaround with multiple UTXO sets and I can see this limit increase making that more streamlined. So, great for the Bitcoin economy imo.

    More data heavy applications will also supply more potential revenue to miners which creates more economic incentive to drive utility on chain in general.

    However, the obvious downsizes is this doesn’t introduce any new vulnerabilities, but could simply amplify existing ones like block bloat, spam, and fee distortion.

    So, I feel a moderate increase is a great compromise between the polarized view points discussed here.

  182. bitcoin locked this on Apr 30, 2025
  183. bitcoin unlocked this on May 1, 2025
  184. DrahtBot requested review from fjahr on May 1, 2025
  185. DrahtBot requested review from jamesob on May 1, 2025
  186. DrahtBot requested review from glozow on May 1, 2025
  187. DrahtBot requested review from jaonoctus on May 1, 2025
  188. DrahtBot requested review from murchandamus on May 1, 2025
  189. bitcoin locked this on May 1, 2025
  190. bitcoin deleted a comment on May 1, 2025
  191. petertodd force-pushed on May 2, 2025
  192. Add more OP_RETURN mempool acceptance functional tests
    Credit: Sjors Provoost and Antoine Poinsot
    c833def396
  193. Remove old comment to datacarriersize argument e690d44707
  194. petertodd force-pushed on May 2, 2025
  195. Update test/functional/mempool_accept.py
    Co-authored-by: Gregory Sanders <gsanders87@gmail.com>
    dec36a7242
  196. Update test/functional/mempool_accept.py
    Co-authored-by: Gregory Sanders <gsanders87@gmail.com>
    92b05c17b1

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-05-05 12:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me