Skip to content

units: Deprecate from_witness_data_size and from_non_witness_data_size#4915

Merged
apoelstra merged 3 commits intorust-bitcoin:masterfrom
shinghim:remove-weight
Oct 10, 2025
Merged

units: Deprecate from_witness_data_size and from_non_witness_data_size#4915
apoelstra merged 3 commits intorust-bitcoin:masterfrom
shinghim:remove-weight

Conversation

@shinghim
Copy link
Copy Markdown
Contributor

Weight::from_non_witness_data_size has an overflow bug. These methods duplicate the functionality of Weight::from_vb and Weight::from_wu, respectively. Furthermore, they are less discoverable than the methods they duplicate, so they will be removed in this PR.

Related discussion in #4847

@github-actions github-actions bot added C-bitcoin PRs modifying the bitcoin crate C-units PRs modifying the units crate test labels Aug 24, 2025
@shinghim shinghim force-pushed the remove-weight branch 2 times, most recently from 0ffdf46 to 23e2d73 Compare August 24, 2025 20:43
@shinghim shinghim marked this pull request as ready for review August 24, 2025 21:22
@shinghim shinghim changed the title Remove from_witness_data_size and from_non_witness_data_size units: Remove from_witness_data_size and from_non_witness_data_size Aug 24, 2025
}

/// Constructs a new [`Weight`] from witness size.
pub const fn from_witness_data_size(witness_size: u64) -> Self { Weight::from_wu(witness_size) }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is exposed in 0.32.7 so it would be worth a deprecation warning? Same with the other function.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah mate, we should deprecate then backport the deprecation to 0.32.x

If you deprecate here I'll do the backport.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

my bad, thought the next release was gonna be the 1.0 one so this wouldn't be in there (but we'd still need to backport). Ill update this later this afternoon when I have a sec

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The plan is to have a final RC release with all the deprecated stuff in there and then drop the 1.0 without it.

@tcharding tcharding added port-0.32.x Needs porting to 0.32.x branch Needs Backport labels Sep 2, 2025
@shinghim shinghim changed the title units: Remove from_witness_data_size and from_non_witness_data_size units: Deprecate from_witness_data_size and from_non_witness_data_size Sep 4, 2025
@github-actions github-actions bot removed the test label Sep 4, 2025
/// # Panics
///
/// If the conversion from virtual bytes overflows.
#[deprecated(since = "TBD", note = "use `from_vb` or `from_vb_unchecked` instead")]
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not sure if it's enough to just add the doc update here, but since it's already exposed, i didn't want to break it

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yep looks good to me. I'd just delete the unit test though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

since the constructors are still there, shouldn't we leave the tests and remove them all together when we clean out the deprecated code?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

As you wish, no stress.

apoelstra
apoelstra previously approved these changes Sep 7, 2025
Copy link
Copy Markdown
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 740a60e; successfully ran local tests

@shinghim
Copy link
Copy Markdown
Contributor Author

While looking into #5054, found that these constructors were causing the daily fuzz cron job to fail, so removing them from the fuzz target

@tcharding
Copy link
Copy Markdown
Member

In cacf1b3

The commit log says 'deprecate ...' but then two public functions have their return types changed. This is a breaking change and needs to be done in a separate patch please. I"d actually prefer to see it in a different PR. In this PR we could just throw and allow-deprecated attribute on the call sites in bitcoin.

@shinghim
Copy link
Copy Markdown
Contributor Author

shinghim commented Oct 1, 2025

@tcharding the two functions that had their return types changed aren't public:

fn legacy_weight(&self) -> Option<Weight> // previously not wrapped in `Option`

and

fn segwit_weight(&self) -> Option<Weight> // previously not wrapped in `Option`

I just added the deprecated tag to the public ones, and for from_non_witness_data_size, updated the doc to state that it panics (due to the overflow found from fuzzing)

apoelstra
apoelstra previously approved these changes Oct 1, 2025
Copy link
Copy Markdown
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 ebbfdcc; successfully ran local tests

@tcharding
Copy link
Copy Markdown
Member

I believe these are public because they are defined as part of the TxInExt trait.

@shinghim
Copy link
Copy Markdown
Contributor Author

shinghim commented Oct 1, 2025

ah you're totally right. Is it ok if i use:

#![allow(deprecated_in_future)] // For `from_non_witness_data_size` and `from_witness_data_size`

at the top of transaction.rs? There's something weird going on with the internal_macros::define_extension_trait! marco that isn't adding the attributes correctly. For example,

internal_macros::define_extension_trait! {
    /// Extension functionality for the [`OutPoint`] type.
    pub trait OutPointExt impl for OutPoint {
        /// Constructs a new [`OutPoint`].
        #[inline]
        #[deprecated(since = "TBD", note = "use struct initialization syntax instead")]
        #[allow(clippy::new-ret-no-self)]
        fn new(txid: Txid, vout: u32) -> Self { OutPoint { txid, vout } }

        /// Checks if an `OutPoint` is "null".
        #[inline]
        #[deprecated(since = "TBD", note = "use `outpoint == OutPoint::COINBASE_PREVOUT` instead")]
        fn is_null(&self) -> bool { *self == OutPoint::COINBASE_PREVOUT }
    }
}

gets expanded to (note the missing deprecated and allow attributes):

#[cfg_attr(docsrs, doc(notable_trait))]
#[doc = " Extension functionality for the [`OutPoint`] type."]
pub trait OutPointExt: sealed::Sealed {
    #[doc = " Constructs a new [`OutPoint`]."]
    fn new(txid: Txid, vout: u32) -> Self;
    
    #[doc = " Checks if an `OutPoint` is \"null\"."]
    fn is_null(&self) -> bool;
}

impl OutPointExt for OutPoint {
    #[doc = " Constructs a new [`OutPoint`]."]
    fn new(txid: Txid, vout: u32) -> Self { 
        OutPoint { txid, vout } 
    }
    
    #[doc = " Checks if an `OutPoint` is \"null\"."]
    fn is_null(&self) -> bool { 
        *self == OutPoint::COINBASE_PREVOUT 
    }
}

I put the macro into an LLM, which got me to a point to where it was adding the missing attributes to the functions, but then it broke a bunch of stuff because

error: `#[deprecated]` attribute cannot be used on trait methods in impl blocks

I'm starting to understand why you guys hate macros now, and I'm quickly approaching that point too lol

@tcharding
Copy link
Copy Markdown
Member

ah I'm sorry mate, yeah deprecating doesn't work in macros. Let me think again tomorrow with fresh eyes.

@apoelstra
Copy link
Copy Markdown
Member

I believe these are public because they are defined as part of the TxInExt trait.

Oof, now you catch something important and obvious that I totally missed.

@tcharding
Copy link
Copy Markdown
Member

Its good to have a crew huh. Seems the only constant is that us humans make mistakes constantly.

@tcharding
Copy link
Copy Markdown
Member

tcharding commented Oct 2, 2025

My suggestion would be to use from_vb_unchecked, that way we maintain the current behaviour and API. Then either raise an issue about the overflow bug and/or raise a PR that changes the API.

Sorry to burden you with such thoroughness.

@apoelstra may want to override me and just update this PR title/description himself to something sane.

@apoelstra
Copy link
Copy Markdown
Member

My suggestion would be to backport the deprecation to 0.32.x and then just delete it in 0.33.x. This is a bit mean to users and is a faster deprecation than we'd prefer but these are fairly obscure methods and our extension-trait thing is causing us problems with doing a full deprecation cycle.

@tcharding
Copy link
Copy Markdown
Member

Let's go!

@tcharding
Copy link
Copy Markdown
Member

Did you mean delete them or just change the return value like originally attempted here?

tcharding added a commit to tcharding/rust-bitcoin that referenced this pull request Oct 3, 2025
Deprecation in trait methods is painful and these two weight
constructors are now defined in `TxInExt`.

In rust-bitcoin#4915 we deprecate `Weight::from_non_witness_data_size` and
`Weight::from_witness_data_size` in favour of `Weight::from_vb` and
`Weight::from_wu` respectively but doing so messes with the APIs of
these to `TxIn` methods because the return value changes from `Weight`
to `Option<Weight>`.

Deprecate the functions here so we can either break the API in 0.33 or
delete the functions entirely.
@tcharding
Copy link
Copy Markdown
Member

Done in #5082, the question above needs addressing please to ensure the deprecation message is sensible.

tcharding added a commit to tcharding/rust-bitcoin that referenced this pull request Oct 3, 2025
Deprecation in trait methods is painful and these two weight
constructors are now defined in `TxInExt`.

In rust-bitcoin#4915 we deprecate `Weight::from_non_witness_data_size` and
`Weight::from_witness_data_size` in favour of `Weight::from_vb` and
`Weight::from_wu` respectively but doing so messes with the APIs of
these to `TxIn` methods because the return value changes from `Weight`
to `Option<Weight>`.

Deprecate the functions here so we can either break the API in 0.33 or
delete the functions entirely.

Note this only does the stuff from 4915 in `bitcoin` not in `units`.
@apoelstra
Copy link
Copy Markdown
Member

Hmmm. So, we don't have good replacements for these methods (you can sorta use base_size and total_size but it's hard to do especially if you don't want arithmetic panics).

So I think "changing the signature" is the right way to go.

Now that I look at total_size and base_size I think these shoud also be changed to return an Option since it's possible to create transactions whose serialized size would overflow (at least, on 32-bit or lower machines).

I think the correct thing to do here, annoyingly, is to deprecate and rename, and change the signature of the renamed function. Then we can backport both the deprecation and the rename.

We may want to move to an issue to discuss the new names.

@tcharding
Copy link
Copy Markdown
Member

tcharding commented Oct 3, 2025

Is there anything wrong with the current names? Just to be clear we are talking about TxIn::segwit_weight and TxIn::legacy_weight.

If its all this hard why don't we just break the API, change the return value (exactly like what is done here) and call it a day. My main grievance, and why I originally brought it up, is that all this is hidden inside a PR titled 'units: Deprecate ...'.

@apoelstra
Copy link
Copy Markdown
Member

Hmmm, yeah, maybe we should just break it.

No, the existing names are fine. The only reason to rename would be to change the API in a non-breaking way.

My main grievance, and why I originally brought it up, is that all this is hidden inside a PR titled 'units: Deprecate ...

Yeah, ok, agreed. @shinghim can you remove this change (you'll have to stick an explicit .unwrap into these methods I guess, but the result will be the same as the old code) and then open a separate PR which changes the return type?

While we're at it lets do total_size and base_size the same way.

@shinghim shinghim force-pushed the remove-weight branch 2 times, most recently from cd2e679 to c7b3f78 Compare October 8, 2025 22:21
@shinghim
Copy link
Copy Markdown
Contributor Author

shinghim commented Oct 8, 2025

sorry was out traveling, but I'm following now. Updated to use non-deprecated functions and just .unwrap() with panic documentation and will follow to change the return type in a new change

Copy link
Copy Markdown
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 0cd384d

@shinghim
Copy link
Copy Markdown
Contributor Author

shinghim commented Oct 9, 2025

I just remembered that there used to be a bot that commented on the PR if it changed the public api. Did we get rid of it? I'm not at my computer so I can't check right now, but I don't want to forget and thought maybe one of you guys knew off the top of your head

@tcharding
Copy link
Copy Markdown
Member

There is a CI job that fails if a PR changes the API without updating the API text files (units only). We got rid of the bot.

Copy link
Copy Markdown
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 0cd384d; successfully ran local tests

@apoelstra apoelstra merged commit b868835 into rust-bitcoin:master Oct 10, 2025
25 checks passed
@shinghim shinghim deleted the remove-weight branch October 11, 2025 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-bitcoin PRs modifying the bitcoin crate C-units PRs modifying the units crate Needs Backport port-0.32.x Needs porting to 0.32.x branch test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants