8000 Reduce usage of `FromHex` by tcharding · Pull Request #1565 · rust-bitcoin/rust-bitcoin · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Reduce usage of FromHex #1565

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

Merged
merged 8 commits into from
Feb 1, 2023
Merged

Conversation

tcharding
Copy link
Member
@tcharding tcharding commented Jan 20, 2023

This work started out, as the branch name suggests, as an effort to use the hex_lit crate. But once I got to this stage it seems that the hex! macro we have provides different, useful, functionality than the hex_lit::hex! macro (it allows usage with non-consts). So I'm unsure if we want to remove it now.

  • Patches 1 - 6 are preparatory clean ups
  • Patch 7 reduces usage of FromHex, please see git log for full description
  • Patch 8 removes hex_from_slice and fixes a bug in how we display Sighash

@tcharding tcharding force-pushed the 01-20-use-hex-lit branch 2 times, most recently from 6d806d5 to 49b7053 Compare January 20, 2023 05:45
@Kixunil
Copy link
Collaborator
Kixunil commented Jan 20, 2023

But once I got to this stage it seems that the hex! macro we have provides different, useful, functionality than the hex_lit::hex!

Indeed, I knew about this. I think it could be simply a function, there's nothing a function can't do that such macro can. I planned to do it.

implements FromStr for hash tyes directly using Vec::from_hex

Why? That seems like a significant regression to me. It's slowed down by allocation and also requires an allocator which previously wasn't required.

Copy link
Collaborator
@Kixunil Kixunil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from allocation in hex parsing this looks pretty good. There are few more unneeded turbofishes than what I marked but don't want to spam with such nits too much.

@@ -239,7 +238,7 @@ fn generate_bip86_key_spend_tx(
lock_time: absolute::LockTime::ZERO,
input: vec![TxIn {
previous_output: OutPoint {
txid: Txid::from_hex(input_utxo.txid)?,
txid: input_utxo.txid.parse::<Txid>()?,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Turbofish is not needed here.

@@ -1143,11 +1143,11 @@ mod tests {

#[test]
fn test_p2sh_address_58() {
let addr = Address::new(Bitcoin, Payload::ScriptHash(hex_into!("162c5ea71c0b23f5b9022ef047c4a86470a5b070")));
let addr = Address::new(Bitcoin, Payload::ScriptHash("162c5ea71c0b23f5b9022ef047c4a86470a5b070".parse::<ScriptHash>().unwrap()));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more unneeded turbofishes.

impl core::str::FromStr for ScriptBuf {
type Err = hex::Error;
#[inline]
fn from_str(s: &str) -> Result<Self, hex::Error> {
hex::FromHex::from_hex(s)
ScriptBuf::from_hex(s)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, we had FromStr despite it not being inverse of Display. That's not great, I think we should remove it. (We could also parse human-friendly script but do we want to?)

@tcharding tcharding force-pushed the 01-20-use-hex-lit branch 3 times, most recently from 9f340d3 to 1298554 Compare January 21, 2023 03:00
@tcharding
Copy link
Member Author

Changes to the last 2 patches are significant. Patch 60b0d953 Manually format a bunch of vecs got a few fixes that I'd missed, one day rustfmt on day ...

@tcharding tcharding changed the title Reduce the number of test hex macros Reduce usage of FromHex Jan 21, 2023
@tcharding
Copy link
Member Author

Changing the PR title to better express what it does.

@tcharding tcharding force-pushed the 01-20-use-hex-lit branch 8000 2 times, most recently from 163117e to c28c211 Compare January 21, 2023 04:48
@tcharding tcharding mentioned this pull request Jan 22, 2023
@tcharding tcharding added the P-high High priority label Jan 22, 2023
@apoelstra
Copy link
Member

We probably want to rebase after #1576 because it will conflict with the first commit (which moves the hashbrown dep).

@tcharding
Copy link
Member Author

Rebased on master, no changes required.

@apoelstra
Copy link
Member

Heh, needs rebase again

@tcharding
Copy link
Member Author
tcharding commented Jan 25, 2023

I removed the leading 2 patches (from #1563) after noticing that this PR does not actually use those changes. Force push is rebase and dropping those two, no other changes.

apoelstra
apoelstra previously approved these changes Jan 26, 2023
Copy link
Member
@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 9257fdea96eebfe0747699f8c53f89923809cd94

Copy link
Collaborator
@Kixunil Kixunil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from error handling, it looks good.

/// Crate error type.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Error {
/// Tried to create a fixed-length hash from a slice with the wrong size (expected, got).
InvalidLength(usize, usize),
/// A hexadecimal parsing error.
Hex(hex::Error),
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not great, hex::Error already contains InvalidLength variant. I see this is because you wanted to use it in FromStr::Error. IMO we should have struct ParseError(hex::Error); for that.

This error type is provided only because we have redundant from_slice() methods for thing that can be achieved with from_inner(x.try_into()). I think we should consider removing both the type and the helper function.

Copy link
Member Author
@tcharding tcharding Jan 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not great, hex::Error already contains InvalidLength variant. I see this is because you wanted to use it in FromStr::Error. IMO we should have struct ParseError(hex::Error); for that.

I just changed the FromStr impls to use hex::Error instead of hashes::Error - any reason not to do that? Now I'm confused, the FromStr impls do use hex::Error currently on master already.

This error type is provided only because we have redundant from_slice() methods for thing that can be achieved with from_inner(x.try_into()). I think we should consider removing both the type and the helper function.

I played around with this, had to return core::alloc::TryFromSliceError - all was well until the derives on pstb::Error bit me. I'm going to leave this for now.

Copy link
Collaborator
@Kixunil Kixunil Jan 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused, the FromStr impls do use hex::Error currently on master already.

Yes, I meant we should encapsulate it to not leak internal type.

But thinking about it, long term we will have hex crate with Error being just invalid char and odd length - no invalid length. And since the crate will be public we could then have:

enum ParseError {
    Hex(hex::Error),
    InvalidLength(InvalidLengthError),
}

#[non_exhaustive]
struct InvalidLengthError {
    required: usize,
    provided: usize
}

until the derives on pstb::Error bit me

Oh, yeah, {Partial}Eq is annoying, but shouldn't PSBT code already supply the correct length, so just unwrapping is OK? Didn't read the code but when I did some deserialization stuff like this then unwrapping made more sense because the length was statically known.

use self::Error::*;

match self {
InvalidLength(ref ell, ref ell2) => write!(f, "bad slice length {} (expected {})", ell2, ell),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/bad/invalid/

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@tcharding
Copy link
Member Author

I rebased and removed the new error variant, returning hex::Error from the FromStr.

apoelstra
apoelstra previously approved these changes Jan 31, 2023
Copy link
Member
@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK bf976edfdb18ab043f35e4f142dba7d6972bebfd

Currently we have two things that are the same but use different
identifiers, use `$reverse` instead of `$reversed`.
Currently we have incorrect feature gating on unit tests and imports
leading to unused import warnings.
We have old Rust 1.29 error handling code still in `hashes`. Implement
`std::error::Error` for the `hex::Error` and `error::Error` types in
line with "modern" Rust 1.41.1 error handling.
It is easier to maintain code if macros use the fully qualified path to
types and functions instead of relying on code that uses the macro to
import said type or function.
There is no need to qualify `Script` and `ScriptBuf` with the `script::`
prefix, remove it.
In preparation for modifying some unit test data structures, manually
format the code so it is uniform.

Move elements added to a vec with `vec!` onto a new line so they all
line up and one can better see what fields go where.

Refactor only, no logic changes.
Remove `FromHex` from hash and script types

- Remove the `FromHex` implementation from hash types and `ScriptBuf`
- Remove the `FromStr` implementation from `ScriptBuf` because it does not
  roundtrip with `Display`.
- Implement a method `from_hex` on `ScriptBuf`.
- Implement `FromStr` on hash types using a fixed size array.

This leaves `FromHex` implementations only on `Vec` and fixed size arrays.
`Sighash` should be displayed forwards according to BIP143. Currently we
are displaying it backwards (as we do for double SHA256). This is
working because parse using `Vec::from_hex`.

We have the means to parse hex strings directly for hashes, we no longer
need `hex_from_slice`.

BIP143 test vectors display double SHA256 forwards but we display
backwards, this is acceptable because there is no fixed display in the
ecosystem for double SHA256 hashes. In order to overcome this we parse
test vector hex strings with into `Vec` when needed.
@tcharding
Copy link
Member Author

Rebase only, no other changes.

Copy link
Member
@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 32ca6cc

Copy link
Collaborator
@Kixunil Kixunil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 32ca6cc

@tcharding
Copy link
Member Author

ooo, two acks, can this one go in first please?

@apoelstra apoelstra merged commit f523011 into rust-bitcoin:master Feb 1, 2023
@tcharding tcharding deleted the 01-20-use-hex-lit branch February 4, 2023 02:33
apoelstra added a commit to apoelstra/rust-bitcoin that referenced this pull request Feb 29, 2024
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.
apoelstra added a commit that referenced this pull request Mar 20, 2024
… 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P-high High priority
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0