-
Notifications
You must be signed in to change notification settings - Fork 38.9k
test: refactor: use script_util helpers for creating P2{PKH,SH,WPKH,WSH} scripts
#22363
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
test: refactor: use script_util helpers for creating P2{PKH,SH,WPKH,WSH} scripts
#22363
Conversation
7494fba to
6c0038d
Compare
|
Concept ACK - if we've got these helpers for this, we might as well be using them. |
|
Concept ACK |
glozow
left a comment
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.
Definite Concept ACK to reusing helper functions instead of creating scripts manually. I think we should add some unit tests to wallet_util.py, since it's not outside the realm of possibility for those util functions to have errors.
Good catch, but is the first commit (61b6a01 fix multisig P2SH-P2WSH script creation ) necessary? You overwrite it immediately in the next commit. Perhaps it'd be better to add a unit test that hits that case instead?
6c0038d to
15e3379
Compare
Agree that unit tests are a good idea here! This way we can also check that the sanity checks in the helpers (i.e. for key/keyhash/scripthash lengths) work.
The intention was to clearly separate "bugfixing" (in parantheses because the result is not used in any test right now) and refactoring. I thought if that is mixed in a single commit, it could be potentially confusing for reviewers if at this single instance the replacement of CScript doesn't match the P2SH pattern. Will maybe squash it with a mention of the bugfix in the commit message though when I touch again. Adding a unit test is any case a good idea :) |
|
Concept ACK! |
rajarshimaitra
left a comment
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.
tACK 15e3379.
Just one nit.
15e3379 to
905d672
Compare
|
tACK 905d672 |
|
tACK 905d672 Review club meeting notes and IRC log: https://bitcoincore.reviews/22363 This PR has many simple "substitution" changes that follow the same pattern, and I wasn't confident that my attention span was sufficient to review all of them. So I made the following sort of change (in a semi-automated way) to the substitution changes in this PR (reinstated the old code and asserted that the new code created the same result): - spk = keyhash_to_p2pkh_script(pubkeyhash)
+ spk = CScript([OP_DUP, OP_HASH160, pubkeyhash, OP_EQUALVERIFY, OP_CHECKSIG])
+ assert_equal(spk, keyhash_to_p2pkh_script(pubkeyhash))With these changes, I also searched for places where these changes may have been missed and did not find any, so I think this PR is complete. Good PR! |
0xB10C
left a comment
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 905d672
Tested and reviewed the changes. Searched for missed P2{PKH,SH,WPKH,WSH} constructions by grepping for opcodes and CScript([.
| assert script is None | ||
| pubkeyhash = hash160(pkh) | ||
| spk = CScript([OP_0, pubkeyhash]) | ||
| spk = key_to_p2wpkh_script(pkh) |
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.
Note: I first thought we are passing a public-key-hash to key_to_p2wpkh_script() as the variable is named pkh. Printing pkh shows that it is an uncompressed public key and the function docs say pkh: the public key for P2PKH or P2WPKH spending too. (nothing to do here)
maflcko
left a comment
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.
review ACK 905d672 🕹
Show signature and timestamp
Signature:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
review ACK 905d672b743edf31531d095ffe800449eaffec69 🕹
-----BEGIN PGP SIGNATURE-----
iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUiQggv/fdwX+4DZ5Wjf0CHh/fHQyowwl2E2u77v7+QvwH1LWZIwQOPWsUZQA1E9
HpKRvJy1srqCr0IR57u7ao5B3crw/LmWoBmhdCKZTdOHrJ/CgkohEjLARYm0s5Im
1Ah0eX/DSUKhB8/fNHQ8+H92IlvuKczJTHfRMcI40IMPny57M1qcDRhKS0rZ1D35
EkJbMHppTHW7VcL8AeX4B4rxiOzXh4Yi5v0zbL+JahQlDmYPr8zXcPzFy8lvoUGG
veyVCPiK5y2yPrj3uH5XDX15FLZan3ev7odiD2f222XZGq3N1X0ErdAOBWevykpU
T6c72IqjCp3pu9IBOe6+2oAx+Opb7DM9hwYC4SZnWkZCCGU1SbTfo9IB/BirisbS
j/DLHOo9Y3PY1RWb4kG0ZvBY2WwF9LDzKNNBRLLwlO5T9aZ5vLq73WpZX8A7Vss1
QAOwpsO1yj5Ctt8kPr5RvIq1tUGlfZbzZiBDklwH1vo/75QzhRaOPTIUimVuuBBm
tsekFY8H
=AEH+
-----END PGP SIGNATURE-----
Timestamp of file with hash 9c7d420ec15f245669577f72ecacc3562260e8ea7e288845b37518b892345567 -
| p2wpkh_script=CScript([OP_0, pkh]).hex(), | ||
| p2wpkh_addr=key_to_p2wpkh(pubkey), | ||
| p2sh_p2wpkh_script=CScript([OP_HASH160, hash160(CScript([OP_0, pkh])), OP_EQUAL]).hex(), | ||
| p2sh_p2wpkh_script=script_to_p2sh_script(CScript([OP_0, pkh])).hex(), |
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.
unrelated nit in 285a65c:
Could use script_to_p2sh_script(p2wpkh_script) to avoid duplication and to clarify that p2sh redeem script is equal to the scriptPubKey (OP_0 + witness program)?
| self.disconnect_nodes(0, 2) | ||
|
|
||
| # Create two outputs, a p2wsh and p2sh-p2wsh | ||
| witness_program = CScript([OP_TRUE]) |
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.
Unrelated comment in 905d672:
This is wrong. This is the preimage to the witness program. According to BIP 141:
... 1-byte push opcode (for 0 to 16) followed by a data push between 2 and 40 bytes gets a new special meaning. The value of the first push is called the "version byte". The following byte vector pushed is called the "witness program".
The proper name is witnessScript:
The last item in the witness (the "witnessScript") is popped off, hashed with SHA256 ...
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.
Being updated in #22429.
…s/witness_program/witness_script/) 8a2b58d test: fix segwit terminology (s/witness_program/witness_script/) (Sebastian Falbesoner) Pull request description: This PR fixes wrong uses of the term "witness program", which according to [BIP141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#Witness_program) is defined as follows: > A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of a 1-byte push opcode (for 0 to 16) followed by a data push between 2 and 40 bytes gets a new special meaning. The value of the first push is called the "version byte". **The following byte vector pushed is called the "witness program".** In most cases where "witness program" is used in tests (concerns comments, variable names and in one instance even a function name) what we really want to denote is the "witness script". Thanks to [MarcoFalke for pointing this out in a review comment](bitcoin/bitcoin#22363 (comment))! Some historical background: At the time when the P2P segwit tests were first introduced (commit 330b0f3, PR #8149), the term "witness program" was not used consistently in BIP141: https://bitcoin.stackexchange.com/questions/46451/what-is-the-precise-definition-of-witness-program This was fixed in PR bitcoin/bips#416 later. So in some way, this PR can be seen as a very late follow-up to the BIP141 fix that also reflects these changes in the tests. ACKs for top commit: josibake: tACK bitcoin/bitcoin@8a2b58d Tree-SHA512: f36bb9e53d1b54b86bfa87ec12f33e3ebca64b5f59d97e9662fe35ba12c25e1c9a4f93a5425d0eaa3879dce9e50368d345555b927bfab76945511f873396892b
…s_program/witness_script/) 8a2b58d test: fix segwit terminology (s/witness_program/witness_script/) (Sebastian Falbesoner) Pull request description: This PR fixes wrong uses of the term "witness program", which according to [BIP141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#Witness_program) is defined as follows: > A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of a 1-byte push opcode (for 0 to 16) followed by a data push between 2 and 40 bytes gets a new special meaning. The value of the first push is called the "version byte". **The following byte vector pushed is called the "witness program".** In most cases where "witness program" is used in tests (concerns comments, variable names and in one instance even a function name) what we really want to denote is the "witness script". Thanks to [MarcoFalke for pointing this out in a review comment](bitcoin#22363 (comment))! Some historical background: At the time when the P2P segwit tests were first introduced (commit 330b0f3, PR bitcoin#8149), the term "witness program" was not used consistently in BIP141: https://bitcoin.stackexchange.com/questions/46451/what-is-the-precise-definition-of-witness-program This was fixed in PR bitcoin/bips#416 later. So in some way, this PR can be seen as a very late follow-up to the BIP141 fix that also reflects these changes in the tests. ACKs for top commit: josibake: tACK bitcoin@8a2b58d Tree-SHA512: f36bb9e53d1b54b86bfa87ec12f33e3ebca64b5f59d97e9662fe35ba12c25e1c9a4f93a5425d0eaa3879dce9e50368d345555b927bfab76945511f873396892b
…ting P2PK scripts 429b493 test: introduce script_util helper for creating P2PK scripts (Sebastian Falbesoner) Pull request description: This PR is a follow-up to #22363, which took use of already existing `script_util` helpers to get rid of manual CScript for the P2{PKH,SH,WPKH,WSH} output types, in order to increase readability and maintainability of the test code. Here the same is done for P2PK scripts by introducing a helper `key_to_p2pk_script` and using it. Note that the helper only accepts ECDSA pubkeys (i.e. ones with a size of 33 or 65 bytes), hence it can't be used for scripts in the form of [x-only-pubkey, OP_CHECKSIG]. ACKs for top commit: brunoerg: Code review ACK 429b493 laanwj: Code review ACK 429b493 rajarshimaitra: Concept + tACK 429b493 Tree-SHA512: 984aea01eba5f38a328d69905d90a3a36f0a02419ca3e5baf3c8095895fb094e3780c7da16fad5851db3847bdb05ce8cda244ab09b79b8aa9602dfb3c5e0414c
…or creating P2PK scripts 429b493 test: introduce script_util helper for creating P2PK scripts (Sebastian Falbesoner) Pull request description: This PR is a follow-up to bitcoin#22363, which took use of already existing `script_util` helpers to get rid of manual CScript for the P2{PKH,SH,WPKH,WSH} output types, in order to increase readability and maintainability of the test code. Here the same is done for P2PK scripts by introducing a helper `key_to_p2pk_script` and using it. Note that the helper only accepts ECDSA pubkeys (i.e. ones with a size of 33 or 65 bytes), hence it can't be used for scripts in the form of [x-only-pubkey, OP_CHECKSIG]. ACKs for top commit: brunoerg: Code review ACK 429b493 laanwj: Code review ACK 429b493 rajarshimaitra: Concept + tACK bitcoin@429b493 Tree-SHA512: 984aea01eba5f38a328d69905d90a3a36f0a02419ca3e5baf3c8095895fb094e3780c7da16fad5851db3847bdb05ce8cda244ab09b79b8aa9602dfb3c5e0414c
…are multisig scripts 4718897 test: add script_util helper for creating bare multisig scripts (Sebastian Falbesoner) Pull request description: This PR is a follow-up to #22363 and #23118 and introduces a helper `keys_to_multisig_script` for creating bare multisig outputs in the form of ``` OP_K PubKey1 PubKey2 ... PubKeyN OP_N OP_CHECKMULTISIG ``` The function takes a list of pubkeys (both hex- and byte-strings are accepted due to the `script_util.check_key` helper being used internally) and optionally a threshold _k_. If no threshold is passed, a n-of-n multisig output is created, with _n_ being the number of passed pubkeys. ACKs for top commit: shaavan: utACK 4718897 rajarshimaitra: tACK 4718897 Tree-SHA512: b452d8a75b0d17316b66ac4ed4c6893fe59c7c417719931d4cd3955161f59afca43503cd09b83a35b5a252a122eb3f0fbb9da9f0e7c944cf8da572a02219ed9d
…ating bare multisig scripts 4718897 test: add script_util helper for creating bare multisig scripts (Sebastian Falbesoner) Pull request description: This PR is a follow-up to bitcoin#22363 and bitcoin#23118 and introduces a helper `keys_to_multisig_script` for creating bare multisig outputs in the form of ``` OP_K PubKey1 PubKey2 ... PubKeyN OP_N OP_CHECKMULTISIG ``` The function takes a list of pubkeys (both hex- and byte-strings are accepted due to the `script_util.check_key` helper being used internally) and optionally a threshold _k_. If no threshold is passed, a n-of-n multisig output is created, with _n_ being the number of passed pubkeys. ACKs for top commit: shaavan: utACK 4718897 rajarshimaitra: tACK bitcoin@4718897 Tree-SHA512: b452d8a75b0d17316b66ac4ed4c6893fe59c7c417719931d4cd3955161f59afca43503cd09b83a35b5a252a122eb3f0fbb9da9f0e7c944cf8da572a02219ed9d
PR #18788 (commit 08067ae) introduced functions to generate output scripts for various types. This PR replaces all manual CScript creations in the P2PKH, P2SH, P2WPKH, P2WSH formats with those helpers in order to increase readability and maintainability over the functional test codebase. The first commit fixes a bug in the wallet_util helper module w.r.t. to P2SH-P2WSH script creation (the result is not used in any test so far, hence it can still be seen as refactoring).
The following table shows a summary of the output script patterns tackled in this PR:
CScript([OP_DUP, OP_HASH160, hash160(key), OP_EQUALVERIFY, OP_CHECKSIG])key_to_p2pkh_script(key)CScript([OP_DUP, OP_HASH160, keyhash, OP_EQUALVERIFY, OP_CHECKSIG])keyhash_to_p2pkh_script(keyhash)CScript([OP_HASH160, hash160(script), OP_EQUAL])script_to_p2sh_script(script)CScript([OP_0, hash160(key)])key_to_p2wpkh_script(key)CScript([OP_0, sha256(script)])script_to_p2wsh_script(script)Note that the
key_to_...helpers can't be used if an invalid key size (not 33 or 65 bytes) is passed, which is the case in some rare instances where the scripts still have to be created manually.Possible follow-up ideas:
key_to_p2sh_p2wpkh_script()andscript_to_p2sh_p2wsh_script()helperskey_to_p2pk_script()helper for P2PK scripts