-
Notifications
You must be signed in to change notification settings - Fork 827
Make hash_newtype
evocative of the output
#1659
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
Make hash_newtype
evocative of the output
#1659
Conversation
We want to get rid of this argument since its value is implied by the inner hash type. First we stop using it.
Now that the `$len` argument is no longer used, remove it completely.
The API guidelines say macro input should be evocative of the output. `hash_newtype` didn't have this property. This change makes it look exactly like the resulting struct, `$len` parameter was removed since it's not needed, reversing is controlled using an attribute. The macro is also better documented and ready to be extended in the future. The tagged SHA256 newtype is not yet modified because it has a more complicated input parameters. Closes rust-bitcoin#1648
76850c0
to
06f1f02
Compare
Looks good to me! I'm ambivalent about whether we try to get this in before release. But ACK for now. |
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 06f1f02
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 is cool, complicated as f***, but very cool. I had a good long play with it including trying to write broken things to see if the compiler caught them. Cheers.
I"m good for this to merge into the release.
EDIT: The suggested comments are hard to see where they go because of which line I clicked +
on, sorry about that.
#[rustfmt::skip] | ||
sha256t_hash_newtype!(TapSighash, TapSighashTag, MIDSTATE_TAPSIGHASH, 64, | ||
doc="Taproot-tagged hash with tag \"TapSighash\". |
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 think we want to keep this skip, without it, IIRC, the args get put on separate lines (from memory only, I did not check).
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, crap, will fix in a followup PR to not trigger re-review.
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 also be pulled into the rustfmt PR (sorry @tcharding for putting it on you :P)
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.
No sweat!
pub struct FilterHash(sha256d::Hash); | ||
/// Filter header, as defined in BIP-157 | ||
pub struct FilterHeader(sha256d::Hash); | ||
} |
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 new usage is sick bro, nice effort!
#[allow(unused)] // the user of macro may not need this | ||
pub fn from_hash(inner: $hash) -> $newtype { |
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 does the linter warn for non-use of a public method? Is it when hash_newtype!
is used to create a private type?
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.
Yes, when pub
is ommitted and the methods are not used the compiler complains.
#[doc(hidden)] | ||
#[macro_export] | ||
macro_rules! hash_newtype_our_attrs { | ||
(hash_newtype($($attr:tt)*)) => { $($attr)* }; | ||
($($ignore:tt)*) => {}; | ||
} |
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 is unused but hidden, should be removed, right?
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, yes, I rewrote it so many times to get right I didn't notice it.
)+ | ||
}; | ||
} | ||
|
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 hash_newtype_struct
macro took me a while to work out. Perhaps throw a comment on it.
/// Declares the `$newtype` struct, the recursive macro calls are to strip the `#[hash_newtype(direction)]` attribute from the attributes list.
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.
Yeah, I guess I should document my design somewhere so that if people attempt "simpler" design they don't get into insane hair pulling like I did.
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.
Yeah my thought process while reading was "why the f*** did he do that ... oh for that reason, ouch that would have hurt to work out" :)
($hash:ty, #[hash_newtype(backward)] $($others:tt)*) => { { $crate::hash_newtype_forbid_direction!(backward, $($others)*); true } }; | ||
($hash:ty, #[$($ignore:tt)*] $($others:tt)*) => { $crate::hash_newtype_get_direction!($hash, $($others)*) }; | ||
} | ||
|
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.
Perhaps add a comment
/// Gets the boolean to use for DISPLAY_BACKWARD from all attributes i.e., turns `#[hash_newtype(backward)]` into `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.
On hash_newtype_get_direction
$crate::hash_newtype_forbid_direction!($direction, $(#[$others])*) | ||
}; | ||
} | ||
|
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.
Perhaps
/// Asserts at compile time that multiple `#[newtype(direction)]` attributes were not present on the new type.
@@ -110,28 +110,77 @@ macro_rules! engine_input_impl( | |||
|
|||
|
|||
/// Creates a new newtype around a [`Hash`] type. |
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.
perhaps
/// Creates a new `$newtype`, which is a wrapper around a [`Hash`] type (`$hash`).
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.
On hash_newtype_get_direction
, also a possible alternate name for this macro is hash_newtype_forbid_duplicate_direction_attributes
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 think after refactoring this should be sufficiently obvious?
/// You can use any valid visibility specifier in place of `pub` or you can leave it out if you | ||
/// don't want the type or its field to be private. |
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 can use any valid visibility specifier in place of `pub` or you can leave it out if you | |
/// don't want the type or its field to be private. | |
/// You can use any valid visibility specifier in place of `pub` or you can omit either, or both, if | |
/// you want the type or its field to be private. |
/// Whether the hash is reversed or not depends on the inner type. However you can override it like | ||
/// this: |
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.
/// Whether the hash is reversed or not depends on the inner type. However you can override it like | |
/// this: | |
/// Whether the hash is reversed or not when displaying depends on the inner type. However you can | |
/// override it like this: |
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.
Bizarre that these suggestions are below the other ones on this page since they make suggested changes to code earlier in the file?
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 GH changed recently to put the comments here in the order you wrote them.
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.
Cool, I can use "as above" without it getting put in the wrong place - lets see how this goes.
@tcharding looks like your nits are mostly about documentation -- ok if I merge this? |
Go for it! Thanks for checking. |
8ccfb41 Improve documentation of `hash_newtype!` (Martin Habovstiak) 58876e2 Remove unused macro (Martin Habovstiak) Pull request description: Removed unused macro and improved documentation to address review of #1659 - see commits. I also added a note about recursion. ACKs for top commit: apoelstra: ACK 8ccfb41 tcharding: ACK 8ccfb41 Tree-SHA512: 3b4b0c4ffc8a5166619110d9dcb51affd5cafbb2af84a55dd540a815e4702514d99c71dc1c54aca27fb91970e7e7189d1dffb4f7da7951b0f71336ef6f32d30b
Oops, looks like we reversed the direction of |
Damn! I need to go now so don't have time to investigate, hopefully later. |
No worries. We did this almost a year ago and this is the first complaint I've gotten about it (the Liquid team is working through several versions of rust-bitcoin now and reporting problems they bump into). So we can wait a few more days. But we should fix this for 0.32 (or at least, make a deliberate decision for each hashtype). Unfortunately this'll be a little annoying/tedious to deal with. We probably want to create encoding unit tests for all of the hash types in rust-bitcoin 0.28 and then check that the same test passes today. |
I think we should also backport the fix. |
This can be checked against the 0.29.x branch, and against the commit prior to rust-bitcoin#1659 (40c2467^) and you will see that it is consistent EXCEPT: * In rust-bitcoin 0.29.x we did not have multiple sighash types, only `Sighash`; we now have `LegacySighash`, `SegwitV0Sighash`, and `TapSighash`. * In rust-bitcoin#1565 we deliberately changed the display direction of the sighashes, to match BIP 143. Fixes rust-bitcoin#2495.
… in the library b816c0b hash_types: add unit tests for display of all hash types in the library (Andrew Poelstra) Pull request description: This can be checked against the 0.29.x branch, and against the commit prior to #1659 (40c2467^) and you will see that it is consistent EXCEPT: * In rust-bitcoin 0.29.x we did not have multiple sighash types, only `Sighash`; we now have `LegacySighash`, `SegwitV0Sighash`, and `TapSighash`. * In #1565 we deliberately changed the display direction of the sighashes, to match BIP 143. Fixes #2495. ACKs for top commit: tcharding: That's a win. ACK b816c0b Tree-SHA512: 5b44f40165699910ea9ba945657cd1f960cf00a0b4dfa44c513feb3b74cda33ed80d3551042c15b85d6e57c30a54242db202eefd9ec8c8b6e1498b5578e52800
The API guidelines say macro input should be evocative of the output.
hash_newtype
didn't have this property.This change makes it look exactly like the resulting struct,
$len
parameter was removed since it's not needed, reversing is controlled
using an attribute. The macro is also better documented and ready to be
extended in the future.
The tagged SHA256 newtype is not yet modified because it has a more
complicated input parameters.
Closes #1648