Skip to content

Conversation

@jamillambert
Copy link
Contributor

As brought up in issue rust-bitcoin/rust-bitcoin#3102 support for Rust arrays is now much better so slice-accepting methods that require a fixed length can be replaced with a method that accepts an array.

from_slice() methods have been deprecated and calls to it from within the crate have been changed to use the equivalent array method.

Copy link
Member

@tcharding tcharding left a comment

Choose a reason for hiding this comment

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

Only did shallow review, but everything apart from try_from thing looks good to me, my reviews don't carry much weight in this repo though.

@tcharding
Copy link
Member

tcharding commented Sep 10, 2024

There are currently not formatting issues on master so there should be no need for a separate formatting patch in this PR bro.

@jamillambert
Copy link
Contributor Author

Third patch removed and incorporated in first two

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.

Hard no deprecating PublicKey::from_slice (but only that one). Other suggestions are not that critical but I'd obviously prefer to fix them.

@jamillambert
Copy link
Contributor Author

Removed deprecation of PublicKey::from_slice and addressed other suggestions. Thanks.

@apoelstra
Copy link
Member

code review ack 46e06da except that the expect message is still wrong. Honestly I think you should just unwrap here. It is very obvious that let x: [u8; N] = slice[..N].try_into() will succeed and why.

Functions have been added to PrivateKey, PublicKey and XOnlyPublicKey to
allow the creation of a key directly from a byte array.
The PrivateKey and XOnlyPublicKey from_slice functions have been
deprecated and calls to them from within the crate have been changed to
use the equivalent array function.
@jamillambert
Copy link
Contributor Author

Thanks for the review. I have replaced expect with unwrap.

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 537b85b successfully ran local tests

Copy link
Member

@tcharding tcharding left a comment

Choose a reason for hiding this comment

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

ACK 537b85b

My suggestions are just because we all enjoy coding round here and it amused me to find a way to re-write your changes using combinators.

Comment on lines 1212 to +1217
pub fn from_slice(data: &[u8]) -> Result<XOnlyPublicKey, Error> {
if data.is_empty() || data.len() != constants::SCHNORR_PUBLIC_KEY_SIZE {
return Err(Error::InvalidPublicKey);
match <[u8; constants::SCHNORR_PUBLIC_KEY_SIZE]>::try_from(data) {
Ok(data) => Self::from_byte_array(&data),
Err(_) => Err(InvalidPublicKey),
}
}
Copy link
Member

Choose a reason for hiding this comment

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

This function could be written with combinators like this:

    pub fn from_slice(data: &[u8]) -> Result<XOnlyPublicKey, Error> {
        <[u8; constants::SCHNORR_PUBLIC_KEY_SIZE]>::try_from(data)
            .map_err(|_| InvalidPublicKey)
            .and_then(|data| Self::from_byte_array(&data))
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does look quite neat with a combinator

pub fn from_bytes(bytes: [u8; SHARED_SECRET_SIZE]) -> SharedSecret { SharedSecret(bytes) }

/// Creates a shared secret from `bytes` slice.
#[deprecated(since = "TBD", note = "Use `from_bytes` instead.")]
Copy link
Member

Choose a reason for hiding this comment

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

I would have expected with this addition to see a change to call from_bytes. If you like the combinator style you could use

    pub fn from_slice(bytes: &[u8]) -> Result<SharedSecret, Error> {
        <[u8; SHARED_SECRET_SIZE]>::try_from(bytes)
            .map_err(|_| Error::InvalidSharedSecret)
            .and_then(|a| Ok(Self::from_bytes(a)))
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I need to change anything again I'll add this too, thanks

@apoelstra
Copy link
Member

I also prefer the combinator version, though of course I won't hold up the PR over it.

But @Kixunil we need you to take a look at this one again since your status is "change requested".

@Kixunil
Copy link
Collaborator

Kixunil commented Sep 12, 2024

I find match cleaner in cases like this where we're transforming stuff in both branches but if we want combinators then I'd use ? instead of and_then.

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 537b85b

Ok(constants::UNCOMPRESSED_PUBLIC_KEY_SIZE) => PublicKey::from_slice(&res),
Ok(constants::PUBLIC_KEY_SIZE) => {
let bytes: [u8; constants::PUBLIC_KEY_SIZE] =
res[0..constants::PUBLIC_KEY_SIZE].try_into().unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Strictly speaking, it'd be better to create a reference here (simply annotating the type with & should work because the conversion is defined) to avoid useless copying but there's a good chance compiler will optimize it out anyway.

Copy link
Member

Choose a reason for hiding this comment

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

Are you saying you can convert a &[u8] to a &[u8; N] via try_into and the compiler will just cast the pointers rather than copying?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Exactly.

Copy link
Member

Choose a reason for hiding this comment

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

Wow, that's a huge win and I feel like a clippy lint should exist for it. (Though it'd be a bit tough in general to tell when the array is only used by reference.)

let mut res = [0u8; constants::SCHNORR_PUBLIC_KEY_SIZE];
match from_hex(s, &mut res) {
Ok(constants::SCHNORR_PUBLIC_KEY_SIZE) =>
XOnlyPublicKey::from_slice(&res[0..constants::SCHNORR_PUBLIC_KEY_SIZE]),
Copy link
Collaborator

Choose a reason for hiding this comment

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

LOL, the previous code...

@apoelstra apoelstra merged commit 3453adb into rust-bitcoin:master Sep 12, 2024
chain-forgexcr45 added a commit to chain-forgexcr45/rust-secp256k1 that referenced this pull request Sep 28, 2025
…n favor of arrays

537b85b793862096c6a335e0fd14315f64ef1995 Deprecate and replace `from_slice` (Jamil Lambert, PhD)
1661f57d84140b0800552c10d10454d2ad99632e Add `from_byte_array` functions (Jamil Lambert, PhD)

Pull request description:

  As brought up in issue rust-bitcoin/rust-bitcoin#3102 support for Rust arrays is now much better so slice-accepting methods that require a fixed length can be replaced with a method that accepts an array.

  `from_slice()` methods have been deprecated and calls to it from within the crate have been changed to use the equivalent array method.

ACKs for top commit:
  apoelstra:
    ACK 537b85b793862096c6a335e0fd14315f64ef1995 successfully ran local tests
  tcharding:
    ACK 537b85b793862096c6a335e0fd14315f64ef1995
  Kixunil:
    ACK 537b85b793862096c6a335e0fd14315f64ef1995

Tree-SHA512: 8f8f807af0032130b64a93ff86cae0df1ccee83de052603968be9e30751c27dfc763a6128472e6d0f3a5c2016e7da8e4d06eefc86d8310bdaacc6be0f8fe3822
william2332-limf added a commit to william2332-limf/rust-secp256k1 that referenced this pull request Oct 2, 2025
…n favor of arrays

537b85b793862096c6a335e0fd14315f64ef1995 Deprecate and replace `from_slice` (Jamil Lambert, PhD)
1661f57d84140b0800552c10d10454d2ad99632e Add `from_byte_array` functions (Jamil Lambert, PhD)

Pull request description:

  As brought up in issue rust-bitcoin/rust-bitcoin#3102 support for Rust arrays is now much better so slice-accepting methods that require a fixed length can be replaced with a method that accepts an array.

  `from_slice()` methods have been deprecated and calls to it from within the crate have been changed to use the equivalent array method.

ACKs for top commit:
  apoelstra:
    ACK 537b85b793862096c6a335e0fd14315f64ef1995 successfully ran local tests
  tcharding:
    ACK 537b85b793862096c6a335e0fd14315f64ef1995
  Kixunil:
    ACK 537b85b793862096c6a335e0fd14315f64ef1995

Tree-SHA512: 8f8f807af0032130b64a93ff86cae0df1ccee83de052603968be9e30751c27dfc763a6128472e6d0f3a5c2016e7da8e4d06eefc86d8310bdaacc6be0f8fe3822
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants