-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Add several policy limits and disable uncompressed keys for segwit scripts #8499
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
|
Concept ACK |
|
I think this is only a temporary solution to protect some of the most common script types. It's easy for P2WPKH. For P2WSH, it could only be done on a case-by-case basis. This approach won't work for more complicated scripts like MAST |
|
|
2150139 to
1c75a39
Compare
|
Updated to do more sanity checks:
|
abb2085 to
47335e4
Compare
src/policy/policy.cpp
Outdated
| std::vector<unsigned char> pubKey = tx.wit.vtxinwit[i].scriptWitness.stack[1]; | ||
| if (tx.wit.vtxinwit[i].scriptWitness.stack[0].size() > 73 || pubKey.size() > 65) | ||
| return true; | ||
| if (pubKey.size() > 33) { |
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.
Why only when the size is above 33 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.
The main objective of this PR is to detect extra witness data in some known forms of scripts, and DoS ban if found.
The normal size for compressed key is 33. If the size is 33, we are sure that no extra data is added. Whether the provided key matches the hash or not will be tested later in script evaluation. Testing here is just duplicated work.
If the size is bigger than 33, we don't know whether it is legit (uncompressed key) or not (malleated witness). To exclude the invalid case we must compare the hash early, and DoS ban if it does not match. If we don't compare the hash here, an attacker may increase the key size up to 65 bytes, get the transaction rejected due to insufficient fee, and not get banned
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.
Unless I'm missing something, I think this is over-eager optimization. It took me a few reads of even this explanation to understand the reasoning behind this line, and even then I'm not quite sure if I've fully understood it. Is the only harm in being more general that we are duplicating work later?
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.
At a minimum there should be a comment something like:
"We want to make sure malleated pubkeys don't trigger too-low-fee to avoid DoS ban"
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.
@instagibbs >Is the only harm in being more general that we are duplicating work later?
yes, because the only purpose of this PR is to early detect some kinds of witness mutation that would trigger too-low-fee ban. We don't care if the size is same as expected or too small. Otherwise we are just doing the validation twice.
But this one is probably over optimized.
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.
I believe this is over-optimized, yes. Let's just always check it.
|
I don't think this belongs in policy. It detects witness transaction inputs that are unambiguously invalid by consensus rules, so I think it belongs in script/interpreter.cpp, but for that it can't depend on CCoinsView. Would it be possible to just have a function per input, that just takes the prevout, scriptsig, and scriptwitness? |
|
@sipa: can I still use The This is more like an "assertion" for the following policy checking, rather than for consensus purpose |
9065f89 to
27294a2
Compare
|
need a 0.13.1 tag? |
27294a2 to
cf802ff
Compare
|
The function is updated. It returns 1 for witness-related error, and 2 for P2SH-related error. We shouldn't mark corruption possible for P2SH related error. It also always checks the HASH160 in P2WPKH |
src/policy/policy.cpp
Outdated
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.
Can you define an enum instead?
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.
Revised
0bc4296 to
79a2248
Compare
|
utACK 056dc99bdc538a7af04b21fe3b25586afbc03861 |
src/policy/policy.cpp
Outdated
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.
Please use the constant found here: https://github.com/bitcoin/bitcoin/blob/master/src/script/script.h#L31
|
nit aside utACK 056dc99 |
79a2248 to
08f5e22
Compare
|
Sync is failing to complete for some reason in p2p-segwit.py utACK fixes at 26bd36ba64cd090c862ca19d64e8e73ee79184d2 with only a couple nits |
|
Comments added and edited. By the way, it seems the p2p-segwit.py would fail randomly File "./qa/rpc-tests/p2p-segwit.py", line 2000, in run_test |
|
I'm removing the tests that causing random sync fail. A similar test is done already to show that policy-rejection won't blind a node to the tx, so I think it's just redundant to try it again. |
|
utACK 67d6ee1 |
…for segwit scripts 67d6ee1 remove redundant tests in p2p-segwit.py (Johnson Lau) 9260085 test segwit uncompressed key fixes (Johnson Lau) 248f3a7 Fix ismine and addwitnessaddress: no uncompressed keys in segwit (Pieter Wuille) b811124 [qa] Add tests for uncompressed pubkeys in segwit (Suhas Daftuar) 9f0397a Make test framework produce lowS signatures (Johnson Lau) 4c0c25a Require compressed keys in segwit as policy and disable signing with uncompressed keys for segwit scripts (Johnson Lau) 3ade2f6 Add standard limits for P2WSH with tests (Johnson Lau)
|
utACK 67d6ee1 |
Github-Pull: bitcoin#8499 Rebased-From: 3ade2f6
…uncompressed keys for segwit scripts Github-Pull: bitcoin#8499 Rebased-From: 4c0c25a
Github-Pull: bitcoin#8499 Rebased-From: 9f0397a
Github-Pull: bitcoin#8499 Rebased-From: b811124
Github-Pull: bitcoin#8499 Rebased-From: 248f3a7
Github-Pull: bitcoin#8499 Rebased-From: 9260085
Github-Pull: bitcoin#8499 Rebased-From: 67d6ee1
|
Backported in #8916 |
|
post-merge ACK laanwj@9777fe1 |
Previously this was an inline test where the specificity was probably judged overly specific. As a class method it makes sense to maintain consistency. And replace some magic values with their constant equivalents. Zcash: Excludes changes to the following functions we don't have: - ExtractPubKey (bitcoin/bitcoin#6415) - IsCompressedPubKey (bitcoin/bitcoin#8499)
Previously this was an inline test where the specificity was probably judged overly specific. As a class method it makes sense to maintain consistency. And replace some magic values with their constant equivalents. Excludes changes to the following functions we don't have: - ExtractPubKey (bitcoin#6415) - IsCompressedPubKey (bitcoin#8499)
…ompressed keys for segwit scripts 67d6ee1 remove redundant tests in p2p-segwit.py (Johnson Lau) 9260085 test segwit uncompressed key fixes (Johnson Lau) 248f3a7 Fix ismine and addwitnessaddress: no uncompressed keys in segwit (Pieter Wuille) b811124 [qa] Add tests for uncompressed pubkeys in segwit (Suhas Daftuar) 9f0397a Make test framework produce lowS signatures (Johnson Lau) 4c0c25a Require compressed keys in segwit as policy and disable signing with uncompressed keys for segwit scripts (Johnson Lau) 3ade2f6 Add standard limits for P2WSH with tests (Johnson Lau)
(See #8499 (comment) : updated on 8 Oct 2016)