-
Notifications
You must be signed in to change notification settings - Fork 37.7k
tests: Fix calculation of external input weights #24454
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
2c09ad6
to
765b138
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.
If I'm parsing correctly, the tangible change here is replacing
41 + len_scriptsig + 2
with
40 + (len_scriptsig += len(ser_compact_size(len_scriptsig)))
In both tests "final_scriptwitness" in psbt_in
is currently false and so len_scriptwitness
is 0
"final_scriptSig" in psbt_in -> True
len(psbt_in["final_scriptSig"]["hex"]) -> 264
len_scriptsig -> 133
"final_scriptwitness" in psbt_in -> False
len_scriptwitness -> 0
input_weight -> (40 + 133) * 4 -> 692
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. 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. |
6f6529a
to
108935a
Compare
Running
The usual values I'm seeing on this branch are (see #24454 (review) above for more detail)
|
108935a
to
db4f737
Compare
Hmm. I guess that error is now the same problem in the other direction. I've added a |
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 haven't been able to make the latest push fail with wallet_send.py
on loop. That said, I wasn't able to reproduce the original issue locally either.
Light ACK db4f737
What is the status here? It looks like there is a comment, which may need to be replied to before merge? |
I've replied to the comment and will not be changing this unless there are more comments. |
db4f737
to
97bfa82
Compare
The external input test with specifying input weight would make a pessimistic estimate of the input weight. However this would result in a test failure as it is sometimes too pessimistic when an ECDSA signature ends up being smaller than usual. To correct this, we can calculate the input weight more accurately.
97bfa82
to
9a8cf70
Compare
I've added a commit that changes the descriptor to also have a segwit component so that we can the weight of |
Some background reviewers may find useful: https://bitcoin.stackexchange.com/a/77192/4948. Valid signatures were up to 73 bytes (since BIP 66). But our wallet only produces standard signatures, which are up to 72 bytes because they require a low S value (https://bitcoin.org/en/release/v0.11.1#test-for-lows-signatures-before-relaying). With R grinding in #13666 our signatures are always 71 bytes or less. It's the "or less" part that's the problem. DER requires using the shortest possible notation for a number, which means 1 in 256 times the R value will be 1 byte shorter. Ditto for the S value. See high school math for the odds of either a short R or S value. (Thank goodness BIP 340 Schnorr signatures get rid of DER encoding). So occasionally we produce signatures of 70 or even 69 bytes. At the same time, we can't expect co-signers to go beyond what's required by consensus (ditto for external signers). So they might give us a signature of up 73 bytes. (or 72 if we do insist on standardness) All that said, I'm still confused how this applies to our tests. Are we actually calculating the weight more "accurately" or are we assuming in the test that the external signature uses Bitcoin Core's convention? In the latter case, shouldn't the buffer be negative? |
Thanks @Sjors. You reminded me that I added a similar comment to
|
I suppose the more accurately part refers to the use of But the part that actually fixes the problem is really reducing the size of the buffer from 2 to 1. This has the desired effect for the test as |
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 9a8cf70
This looks considerably improved since my review above at #24454 (review).
The values in the tests have changed since then as well and in my runs are always the same/stable.
"final_scriptSig" in psbt_in -> True
len(psbt_in["final_scriptSig"]["hex"]) -> 70
len_scriptsig -> 35, then 37
"final_scriptwitness" in psbt_in -> True
len_scriptwitness -> 136
input_weight -> ((40 + 37) * 4) + 136 -> 444
Ran each of the two test files 100 times on a build of current master.
I'm still seeing these test failures in the CI.
9a8cf70
to
9f5ab67
Compare
re-ACK 9f5ab67 |
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.
code review ACK 9f5ab67
The external input test with specifying input weight would make a pessimistic estimate of the input weight. However this would result in a test failure as it is sometimes too pessimistic when an ECDSA signature ends up being smaller than usual. To correct this, we can calculate the input weight more accurately. Github-Pull: bitcoin#24454 Rebased-From: 8a04a38
Github-Pull: bitcoin#24454 Rebased-From: 9f5ab67
Backported in #25316. |
4ebf6e3 p2p: always set nTime for self-advertisements (Martin Zumsande) 039ef21 tests: Use descriptor that requires both legacy and segwit (Andrew Chow) 5fd25eb tests: Calculate input weight more accurately (Andrew Chow) bd6d3ac windeploy: Renewed windows code signing certificate (Andrew Chow) 32fa522 test: ensure createmultisig and addmultisigaddress are not returning any warning for expected cases (brunoerg) 7658055 rpc: fix inappropriate warning for address type p2sh-segwit in createmultisig and addmultisigaddress (brunoerg) Pull request description: Backports: - #24454 - #25201 - #25220 - #25314 ACKs for top commit: LarryRuane: re-utACK 4ebf6e3 achow101: ACK 4ebf6e3 Tree-SHA512: add3999d0330b3442f3894fce38ad9b5adc75da7d681c949e1d052bac5520c2c6fb06eba98bfbeb4aa9a560170451d24bf00d08dddd4a3d080030ecb8ad61882
The external input tests with specifying input weight would sometimes result in a test failure because it would add 2 to the calculated byte size in order to account for some of the variation in signature and script sizes. However 1 in 128 signatures are actually 1 byte smaller than we expect, so the difference between the actual signature size and our calculated size becomes 3 bytes which is outside of the tolerance of
assert_fee_amount
and would thus cause the test failure.To resolve this, the 2 byte buffer is reduced to 1 byte, so in the above scenario, the difference is 2 bytes which is within the tolerance of
assert_fee_amount
. Additionally, instead of putting a fixed size that we assume is the correct size for the length of the compact size length prefix of data, we actually get the length of the compact size uint.Lastly, the size calculation for a scriptWitness was simply incorrect and used fields that did not exist. This is fixed, and the test slightly modified so that it also produces a scriptWitness.
Fixes #24151