-
Notifications
You must be signed in to change notification settings - Fork 243
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
Fix feature gating #520
Fix feature gating #520
Conversation
Currently we have a few problems with our feature gating, attempt to audit all feature gating and fix it by doing: 1. Do not enable features on optional dependencies (`rand` and `bitcoin-hashes`) in dev-dependencies, doing so hides broken feature gating in unit tests. 2. Do not use unnecessary feature combinations when one feature enables another e.g. `any(feature = "std", feature = "alloc")`. 3. Enable "std" from "rand-std" and "bitcoin-std" (and fix features gating as for point 2). 4. Clean up code around `rand::thread_rng`, this is part of this patch because `thread_rng` requires the "rand-std" feature. 5. Clean up CI test script to test each feature individually now that "rand-std" and "bitcoin-hashes-std" enable "std".
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 9c74855
Will wait on @Kixunil to sanity-check before merging. This is a big PR but it's almost entirely mechanical and all the "real" changes are in |
And I could easily have missed some places, I was relying on grep heavily to find lines of code that needed patching. |
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.
@@ -46,10 +46,8 @@ bitcoin_hashes = { version = "0.11", default-features = false, optional = true } | |||
rand = { version = "0.8", default-features = false, optional = true } | |||
|
|||
[dev-dependencies] | |||
rand = "0.8" | |||
rand_core = "0.6" |
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.
FTR, IIRC I had WIP changes that add rand_core
feature so this one would have to go too. But it's OK now.
/// # #[cfg(all(feature = "std", feature = "rand-std"))] { | ||
/// # use secp256k1::Secp256k1; | ||
/// # #[cfg(feature = "rand-std")] { | ||
/// # use secp256k1::{rand, Secp256k1}; |
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.
Not for this PR but this looks very confusing - it looks as if #[cfg]
was controlling use
, not the whole block. If we don't want to indent it I suggest we put {
on the next line - this is unusual in Rust but much more readable in this case.
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.
Agreed. The old formatting was chosen with "this line will be hidden" in mind.
I have a mild preference for indenting vs putting {
on the next line.
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.
Its already laborious to write example code in comments because of zero tooling support, we should be careful what we choose because we (I) will have to go back and change every example in the whole codebase.
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.
Ok, then let's do {
on the next line since that's easiest :P and say that this is a very low priority thing.
let mut ret = [0u8; 32]; | ||
rng.fill(&mut ret); | ||
ret | ||
} |
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 completely OK for this PR but I don't like non-generic 32_bytes
much. For the future I was thinking of some alternative designs: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=3123fb72993eabdeeb4a51eb2558be88
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 function is only available within the crate, where we routinely need 32 uniformly random bytes and never need any other quantity of differently-random bytes.
use crate::ffi::types::AlignedType; | ||
use crate::ffi::{self}; | ||
#[cfg(feature = "alloc")] | ||
use crate::{ffi, PublicKey, Secp256k1, SecretKey}; |
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.
IIUC these do not require alloc
but only tests requiring alloc
happen to use them, right?
It's not very readable but the only somewhat reasonable idea beyond adding a comment that comes to my mind is having test_std
, test_alloc
, test_rand
... etc modules and the modules have appropriate cfg. Maybe not having same cfgs multiple times is good enough benefit for 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.
I think this is a pretty common pattern in test modules to have feature-gated imports because there are feature-gated tests.
#[cfg_attr(docsrs, doc(cfg(feature = "rand-std")))] | ||
pub fn random() -> Self { Self::random_custom(rand::thread_rng()) } | ||
|
||
/// Generates a random scalar using supplied RNG | ||
#[cfg(any(test, feature = "rand"))] | ||
#[cfg(feature = "rand")] | ||
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))] | ||
pub fn random_custom<R: rand::Rng>(mut rng: R) -> Self { |
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, I should've implemented Distribution<Scalar> for Standard
. 🤦♂️
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.
ITYM for Uniform
, but honestly this seems like more complexity (and reading rand
docs) (and hoping they never change) than it's worth.
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 for both Standard
and Uniform
. If rand
is still too far away from stabilizing maybe we should just put it off until then.
Thanks for your review and (somewhat hesitant) ACK! We'll address things in followup PRs. |
Thanks fellas, feels like the feature gating saga is going to be an ongoing one :) |
Should we release a new version so that we unblock development in |
I'd like to get #518 in as well since I believe it is also semver-breaking. |
Oh, yes, we had "remove deprecated" commits. Would it make sense to backport this for point release? |
I think so. Normally changes to feature flags are breaking but I think this is purely additive (except for dev-dependencies). Similarly I think all the changes to feature-gating of functionality is purely additive (things are now available that didn't use to be). Because it touches so many LOC it'd be a real pain to backport, I think. In particular #499 will be really annoying to backport past :). I think it'd be less work to get #518 in and then cut a release -- it's almost ready. |
Oh, OK. Yes, this change is backwards-compatible. |
Ok, 518 is in. We can just do a major release and pull that into rust-bitcoin I think. |
cc @tcharding can you open a release PR so that I can ack and merge it? |
Sure thing! |
Currently we have a few problems with our feature gating, attempt to audit all feature gating and fix it by doing:
rand
andbitcoin-hashes
) in dev-dependencies, doing so hides broken feature gating in unit tests.any(feature = "std", feature = "alloc")
.rand::thread_rng
, this is part of this patch becausethread_rng
requires the "rand-std" feature.