-
Notifications
You must be signed in to change notification settings - Fork 37.7k
POLICY: Relax MIN_STANDARD_TX_NONWITNESS_SIZE to 65 non-witness bytes #26265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
42cff87
to
d034748
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK
- originally introduced in 7485488 as part of #11423
- documented as CVE-2017-12842
- actual explanation added to code in #16885
- proposed as a consensus change in https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-March/016714.html / #15482
Maybe add a test that 65 bytes is passing now? |
@MarcoFalke Pushed a test of min size working via testmempoolaccept, and also updated another constants |
bcbd1d9
to
7633656
Compare
DUMMY_MIN_OP_RETURN_SCRIPT = CScript([OP_RETURN] * MIN_PADDING) | ||
|
||
# This can be spent, one shorter due to <push_MIN_PADDING> opcode | ||
DUMMY_MIN_SPEND_SCRIPT = CScript([b'a' * (MIN_PADDING - 1)]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't [RETURN FALSE FALSE FALSE FALSE]
be a better min op_return script, since that way it passes standardness rules?
For a spendable (but necessarily non-standard) output, [NOP NOP NOP NOP TRUE]
might be more explicit? But I don't think that case ever makes sense -- if it's a "dust" amount, that you don't care about, it's better to send it to fees and use a 0-value OP_RETURN output; if it's not a dust amount and you do care about it, you'll want to secure the funds and use something that requires an output to redeem. Saving a few bytes in the bip68 functional test doesn't seem worth the effort?
assert len(*_MIN_*_SCRIPT) == MIN_PADDING
might be clearer than explaining all the off-by-one things?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't [RETURN FALSE FALSE FALSE FALSE] be a better min op_return script, since that way it passes standardness rules?
done
For a spendable
Leaving for another PR
assert len(MIN_SCRIPT) == MIN_PADDING might be clearer than explaining all the off-by-one things?
Done
DUMMY_P2WPKH_SCRIPT = CScript([b'a' * 21]) | ||
DUMMY_2_P2WPKH_SCRIPT = CScript([b'b' * 21]) | ||
|
||
# least 5 bytes. DUMMY_P2WPKH_SCRIPT should be used when requiring |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You replaced DUMMY_P2WPKH_SCRIPT
with DUMMY_MIN_SPEND_SCRIPT
but didn't update this comment
But I think that doesn't make sense? The former was standard, the latter requires you to use -acceptnonstdtxn=1
, which seems likely to hide bugs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both are nonstandard (Edit: I guess no longer, now that the new dummy switched to OP_RETURN).
My goal was to get rid of this dummy completely by using standard scripts and/or MiniWallet, but I never got around to do it for the last remaining use here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, it's "p2wpkh" only in the sense that it's the same size... Weird.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These dummy constants are now being removed in #26277 along with acceptnonstdtxn=1
usage.
test/functional/data/invalid_txs.py
Outdated
@@ -122,7 +123,8 @@ class SizeTooSmall(BadTxTemplate): | |||
def get_tx(self): | |||
tx = CTransaction() | |||
tx.vin.append(self.valid_txin) | |||
tx.vout.append(CTxOut(0, CScript([OP_TRUE]))) | |||
tx.vout.append(CTxOut(0, CScript([OP_RETURN] * (MIN_PADDING - 1)))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be better to create an output that passes standardness checks here so that it's only failing for one reason?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry what's non-standard about this output? It's an OP_RETURN(so it can be dust), all pushes, under 80 bytes...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OP_RETURN is probably not a push?
decodescript 6a6a6a6a6a6a
{
"asm": "OP_RETURN OP_RETURN OP_RETURN OP_RETURN OP_RETURN OP_RETURN",
"desc": "raw(6a6a6a6a6a6a)#6j3qx6z8",
"type": "nonstandard"
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uhm, OP_RETURN isn't a push, gibbs... facepalm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could add OP_RESERVED to do a bit of trolling
Concept ACK. I think this needs a ML post. |
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ReviewsSee 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. ConflictsReviewers, this pull request conflicts with the following ones:
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. |
@darosior if I don't get any serious pushback through next week I can put forward a post |
01d3ae5
to
7f6dee6
Compare
Pushed updates and a fix so the passing case is actually running, and test will fail if it doesn't run. |
7f6dee6
to
861a276
Compare
f2922cc
to
8b32fc4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left a test nit
8b32fc4
to
72f1da4
Compare
234152a
to
e5adc1a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK e5adc1a
Checked that the invalid_txs test triggers if the tx is accepted (by changing the tx to be 65 bytes). Also noticed that the mempool_accept tx is greater than 65 vbytes (two flag bytes, a byte for the witness stack size, a byte for the witness length, and a byte for the OP_TRUE in the witness is 5 bytes total, divided by 4 gives 1.25 extra vbytes, for a total of 65.25 vbytes), so this is also testing that additional witness bytes doesn't actually help.
Anything not 64 bytes could be allowed
I believe the minimum possible transaction is 60 bytes: 4B version, 4B locktime, 2B for in and count of 1 each (0 is illegal), 32B+4B for utxo txid and vout, 1B for scriptSig length of 0, 4B for nSequence, 8B for output amount, 1B for output scriptPubKey length of 0, and thus the minimum possible tx that only generates provably unspendable outputs is 61 bytes. Presuming there's a 64B signature in the witness (66B total to include the count of witness elements and the size of the signature), padding to from 61B to 65B is an increase of ~4% in raw data, and ~5.2% in weight/vbytes, and if you're trying to pay fees to get some meaningful transaction mined, then adding that other transaction to the denominator makes the increase even smaller. That seems pretty negligible to me, and "60-63 is okay but 64 isn't" seems like a horrible special case.
(The smallest transaction you can easily create with bitcoind seems to be 63B since createrawtransaction and createpsbt require non-empty data for the OP_RETURN, which adds a byte for the push data opcode, and a byte for the data being pushed)
Emailing the dev list now that this has a couple ACKs and no showstopping discussion |
Slightly prefer #26398 Unless there is a compelling safety reason, and the code/tests don't become more complex, I'll leave the use-case designing to future developers who have more context/requirements than we do. The only additional danger with #26398 is that someone writes support for transactions up to 64 non-witness bytes and doesn't test at the 64 byte marker, causing their tx to not propagate. Any other dangers I'm missing? |
I've created a 60 byte transaction on testnet, since one didn't yet seem to exist https://mempool.space/testnet/tx/b0b076e6647711d8b80439a6ab6ed37764ec48153527629ff3033cc4d8c49751 |
Concept ACK.. Preferring #26398 over this.. |
closing in favor of #26398 |
e5adc1a
to
b2c900e
Compare
review ACK b2c900e 🗝 Show signatureSignature:
|
Resurrecting this PR as #26398 appears to be too controversial. I still prefer the other solution, but this PR is superior to the status quo in legibility and usability, so I'll take it. |
The policy could first relax to >64, then further to !=64 in the future, so the door on #26398 would not be completely closed. It seems that people are open to that possibility. |
Yes leaving it in draft as I'm willing to take it up again if/when there is consensus. Thank you for your patience with my flapping PRs! |
ACK b2c900e |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the original fix was set to be a "reasonable" transaction to reduce allocations and the true motivation later revealed, it makes sense to relax this check to something more principled. There are more exotic transaction patterns that could take advantage of a relaxed requirement, such as 1 input, 1 output OP_RETURN to burn a utxo to fees for CPFP purposes when change isn't practical. Two changes could be accomplished: 1) Anything not 64 bytes could be allowed 2) Anything above 64 bytes could be allowed In the Great Consensus Cleanup, suggestion (2) was the route taken. It would not allow an "empty" OP_RETURN but would reduce the required padding from 22 bytes to 5. The functional test is also modified to test the actual case we care about: 64 bytes
b2c900e
to
b2aa9e8
Compare
Done all as @glozow has suggested, and touched up commit messages a bit more |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reACK b2aa9e8
Changes were
- commit message note about Great Consensus Cleanup doing <=64
- assertion that size with witness is greater than 64
- comment typo fix
- release note
CI failure looks unrelated
reACK b2aa9e8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re-ACK b2aa9e8
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK b2aa9e8 with some suggestions
@@ -25,8 +25,8 @@ static constexpr unsigned int DEFAULT_BLOCK_MAX_WEIGHT{MAX_BLOCK_WEIGHT - 4000}; | |||
static constexpr unsigned int DEFAULT_BLOCK_MIN_TX_FEE{1000}; | |||
/** The maximum weight for transactions we're willing to relay/mine */ | |||
static constexpr unsigned int MAX_STANDARD_TX_WEIGHT{400000}; | |||
/** The minimum non-witness size for transactions we're willing to relay/mine (1 segwit input + 1 P2WPKH output = 82 bytes) */ | |||
static constexpr unsigned int MIN_STANDARD_TX_NONWITNESS_SIZE{82}; | |||
/** The minimum non-witness size for transactions we're willing to relay/mine: one larger than 64 */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be clearer to keep the unit.
/** The minimum non-witness size for transactions we're willing to relay/mine: one larger than 64 */ | |
/** The minimum non-witness size for transactions we're willing to relay/mine: one larger than 64 bytes */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will add if I ever touch the PR
tx.vout.append(CTxOut(0, CScript([OP_TRUE]))) | ||
tx.vout.append(CTxOut(0, CScript([OP_RETURN] + ([OP_0] * (MIN_PADDING - 2))))) | ||
assert len(tx.serialize_without_witness()) == 64 | ||
assert MIN_STANDARD_TX_NONWITNESS_SIZE - 1 == 64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check looks redundant with the one added in https://github.com/bitcoin/bitcoin/pull/26265/files#diff-a99d72c0ed66c256169e92327e04ab223e71f5ef598e14aac0ff44dc2a1194daR356, unless it's for documentation purposes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
documentation, thanks for double checking
P2P and network changes | ||
--------- | ||
|
||
- Transactions of non-witness size 65 and above are now allowed by mempool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest adding the unit and perhaps also stating what the previous value was to clarify the change.
- Transactions of non-witness size 65 and above are now allowed by mempool | |
- Transactions of non-witness size 65 bytes and above are now allowed by mempool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will add if I ever touch the PR
…_SIZE to 65 non-witness bytes b2aa9e8 Add release note for MIN_STANDARD_TX_NONWITNESS_SIZE relaxation (Greg Sanders) 8c5b364 Relax MIN_STANDARD_TX_NONWITNESS_SIZE to 65 non-witness bytes (Greg Sanders) Pull request description: Since the original fix was set to be a "reasonable" transaction to reduce allocations and the true motivation later revealed, it makes sense to relax this check to something more principled. There are more exotic transaction patterns that could take advantage of a relaxed requirement, such as 1 input, 1 output OP_RETURN to burn a utxo to fees for CPFP purposes when change isn't practical. Two changes could be accomplished: 1) Anything not 64 bytes could be allowed 2) Anything above 64 bytes could be allowed In the Great Consensus Cleanup, suggestion (2) was proposed as a consensus change, and is the simpler of the two suggestions. It would not allow an "empty" OP_RETURN but would reduce the required padding from 22 bytes to 5. The functional test is also modified to test the actual case we care about: 64 bytes Related mailing list discussions here: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-October/020995.html And a couple years earlier: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-May/017883.html ACKs for top commit: achow101: reACK b2aa9e8 glozow: reACK b2aa9e8 pablomartin4btc: re-ACK bitcoin/bitcoin@b2aa9e8 jonatack: ACK b2aa9e8 with some suggestions Tree-SHA512: c1ec1af9ddcf31b2272209a4f1ee0c5607399f8172e5a1dfd4604cf98bfb933810dd9369a5917ad122add003327c9fcf6ee26995de3aca41d5c42dba527991ad
Is this merged and should be closed? Edit: yes. |
Looks like it. @achow101 ? |
… 65 non-witness bytes b2aa9e8 Add release note for MIN_STANDARD_TX_NONWITNESS_SIZE relaxation (Greg Sanders) 8c5b364 Relax MIN_STANDARD_TX_NONWITNESS_SIZE to 65 non-witness bytes (Greg Sanders) Pull request description: Since the original fix was set to be a "reasonable" transaction to reduce allocations and the true motivation later revealed, it makes sense to relax this check to something more principled. There are more exotic transaction patterns that could take advantage of a relaxed requirement, such as 1 input, 1 output OP_RETURN to burn a utxo to fees for CPFP purposes when change isn't practical. Two changes could be accomplished: 1) Anything not 64 bytes could be allowed 2) Anything above 64 bytes could be allowed In the Great Consensus Cleanup, suggestion (2) was proposed as a consensus change, and is the simpler of the two suggestions. It would not allow an "empty" OP_RETURN but would reduce the required padding from 22 bytes to 5. The functional test is also modified to test the actual case we care about: 64 bytes Related mailing list discussions here: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-October/020995.html And a couple years earlier: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-May/017883.html ACKs for top commit: achow101: reACK b2aa9e8 glozow: reACK b2aa9e8 pablomartin4btc: re-ACK bitcoin@b2aa9e8 jonatack: ACK b2aa9e8 with some suggestions Tree-SHA512: c1ec1af9ddcf31b2272209a4f1ee0c5607399f8172e5a1dfd4604cf98bfb933810dd9369a5917ad122add003327c9fcf6ee26995de3aca41d5c42dba527991ad
… 65 non-witness bytes b2aa9e8 Add release note for MIN_STANDARD_TX_NONWITNESS_SIZE relaxation (Greg Sanders) 8c5b364 Relax MIN_STANDARD_TX_NONWITNESS_SIZE to 65 non-witness bytes (Greg Sanders) Pull request description: Since the original fix was set to be a "reasonable" transaction to reduce allocations and the true motivation later revealed, it makes sense to relax this check to something more principled. There are more exotic transaction patterns that could take advantage of a relaxed requirement, such as 1 input, 1 output OP_RETURN to burn a utxo to fees for CPFP purposes when change isn't practical. Two changes could be accomplished: 1) Anything not 64 bytes could be allowed 2) Anything above 64 bytes could be allowed In the Great Consensus Cleanup, suggestion (2) was proposed as a consensus change, and is the simpler of the two suggestions. It would not allow an "empty" OP_RETURN but would reduce the required padding from 22 bytes to 5. The functional test is also modified to test the actual case we care about: 64 bytes Related mailing list discussions here: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-October/020995.html And a couple years earlier: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-May/017883.html ACKs for top commit: achow101: reACK b2aa9e8 glozow: reACK b2aa9e8 pablomartin4btc: re-ACK bitcoin@b2aa9e8 jonatack: ACK b2aa9e8 with some suggestions Tree-SHA512: c1ec1af9ddcf31b2272209a4f1ee0c5607399f8172e5a1dfd4604cf98bfb933810dd9369a5917ad122add003327c9fcf6ee26995de3aca41d5c42dba527991ad
Since the original fix was set to be a "reasonable" transaction to reduce allocations and the true motivation later revealed, it makes sense to relax this check to something more principled.
There are more exotic transaction patterns that could take advantage of a relaxed requirement, such as 1 input, 1 output OP_RETURN to burn a utxo to fees for CPFP purposes when change isn't practical.
Two changes could be accomplished:
Anything not 64 bytes could be allowed
Anything above 64 bytes could be allowed
In the Great Consensus Cleanup, suggestion (2)
was proposed as a consensus change, and is the simpler of the two suggestions. It would not allow an "empty" OP_RETURN but would reduce the required padding from 22 bytes to 5.
The functional test is also modified to test the actual case
we care about: 64 bytes
Related mailing list discussions here:
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-October/020995.html
And a couple years earlier:
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-May/017883.html