Refactoring script generating functions into a single place#387
Refactoring script generating functions into a single place#387apoelstra merged 3 commits intorust-bitcoin:masterfrom
Conversation
95f3325 to
92aedb0
Compare
Codecov Report
@@ Coverage Diff @@
## master #387 +/- ##
==========================================
- Coverage 85.55% 84.97% -0.58%
==========================================
Files 40 40
Lines 8660 7315 -1345
==========================================
- Hits 7409 6216 -1193
+ Misses 1251 1099 -152
Continue to review full report at Codecov.
|
stevenroose
left a comment
There was a problem hiding this comment.
2 major concerns:
-
Try to avoid allocations for generating hashes. The
HashTrait::hashmethod is useful if the slice to be hashed already exists. Like for aScript. If the data to be hashed still needs to be created (i.e. serialized), then you can avoid allocating data by writing directly into the hash engine. Efficiency is more important than readability in for these cases. -
Exactly what code was duplicated? I see that here you move the p2* creation from
address.rstoscript.rs, but where did this code exist a second time?
I'm a bit double as to where this code belongs. The notion of p2* scripts has to exist in address.rs, but doesn't necessarily have to exist in script.rs. So that suggests it should stay in address.rs. The only exception is p2pk for which there isn't an address.
Argh, perhaps I can agree with templating code being in Builder; it kinda makes sense. First of all please remove all unnecessary allocations.
5e205ac to
3266c6f
Compare
|
@stevenroose I have reverted to hash engine procedure everywhere; so pls reconsider this version for the merge |
stevenroose
left a comment
There was a problem hiding this comment.
Now you changed some of the simpler hash functions into an engine without there being a reason for that..
Also, perhaps since the Builder::gen_* methods already construct a new builder so they can't be used on an existing builder, they should just also return a Script directly. That way they are just some kind of factory pattern. I think it's extremely uncommon to gen a template script and then add stuff to it. And it would make our code a lot more readable without all the into_scripts.
3266c6f to
c110dbc
Compare
|
Sorry for doing this such late; @stevenroose everything is fixed according to your comments + rebased onto master |
df952d4 to
305a252
Compare
|
You seem to have a Rust v1.22 compilation error. I'm thinking if it actually makes sense to have the |
|
I'm not sure if these methods belong into the |
07c4976 to
4221aa6
Compare
|
@sgeisler, @stevenroose I have moved all methods to It seems to me that @apoelstra comment from other PR #388 (comment) was actually addressing this PR (and not that one). I tend to agree that this generators are natural part of miniscript; however this code was anyway inside This PR also increases test coverage of the original rust bitcoin code |
4221aa6 to
e33cdcc
Compare
src/blockdata/script.rs
Outdated
| } | ||
|
|
||
| /// Generates OP_RETURN-type of scriptPubkey for a given data | ||
| pub fn with_op_return(data: &Vec<u8>) -> Self { |
There was a problem hiding this comment.
Please take a &[u8] rather than an &Vec<u8>.
There was a problem hiding this comment.
fixed with the new commit, as well as the rest of your points
src/blockdata/script.rs
Outdated
| pub fn with_op_return(data: &Vec<u8>) -> Self { | ||
| Builder::new() | ||
| .push_opcode(opcodes::all::OP_RETURN) | ||
| .push_slice(&data) |
src/blockdata/script.rs
Outdated
| pub fn new() -> Script { Script(vec![].into_boxed_slice()) } | ||
|
|
||
| /// Generates P2PK-type of scriptPubkey | ||
| pub fn with_pk(pubkey: &PublicKey) -> Script { |
There was a problem hiding this comment.
This should be named p2pk or something similar to indicate that you are making a pay-to-pubkey scriptpubkey. The with_ naming is confusing here.
There was a problem hiding this comment.
Right. I've taken with_ prefix after Rust naming guidelines https://rust-lang.github.io/api-guidelines/naming.html suggesting to name constructors as new or with_ prefix. But I agree that this is confusing and guidelines are not a law.
Renamed all methods to corresponding descriptor names with new_ prefix to signify that we are not converting existing script object into a scriptPubkey but constructing a new one from arguments.
src/blockdata/script.rs
Outdated
| } | ||
|
|
||
| /// Generates P2PKH-type of scriptPubkey | ||
| pub fn with_pkh(pubkey_hash: &PubkeyHash) -> Script { |
There was a problem hiding this comment.
Ditto here, the name should indicate that this is a pay-to-pubkeyhash scriptpubkey
src/blockdata/script.rs
Outdated
| } | ||
|
|
||
| /// Generates P2WSH-type of scriptPubkey with a given hash of the redeem script | ||
| pub fn with_witness_program(ver: ::bech32::u5, program: &Vec<u8>) -> Script { |
|
concept ACK. I like having these methods in |
I know that we do plan to utilize miniscript as much as possible, but as an intermediate step I propose to sort out some code duplication issues. Right now, we had script generation logic in
address::Payload, which was a duplication of the same code inScriptclass. With this PR I have:Builder, which seemed to be a more appropriate locationP2PKgeneration logic* sorted out unnecessary usage ofHashEnginewherehashfunction of the new hash types can be used instead