Skip to content
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

Migrate to bitcoin::FeeRate #1216

Merged
merged 5 commits into from Mar 22, 2024

Conversation

ValuedMammal
Copy link
Contributor

@ValuedMammal ValuedMammal commented Nov 15, 2023

Description

This follows a similar approach to #1141 namely to remove FeeRate from bdk::types and instead defer to the upstream implementation for all fee rates. The idea is that making the switch allows BDK to benefit from a higher level abstraction, leaving the implementation details largely hidden.

As noted in #774, we should avoid extraneous conversions that can result in deviations in estimated transaction size and calculated fee amounts, etc. This would happen for example whenever calling a method like FeeRate::to_sat_per_vb_ceil. The only exception I would make is if we must return a fee rate error to the user, we might prefer to display it in the more familiar sats/vb, but this would only be useful if the rate can be expressed as a float.

Notes to the reviewers

bitcoin::FeeRate is an integer whose native unit is sats per kilo-weight unit. In order to facilitate the change, a helper method feerate_unchecked is added and used only in wallet tests and psbt tests as necessary to convert existing fee rates to the new type. It's "unchecked" in the sense that we're not checking for integer overflow, because it's assumed we're passing a valid fee rate in a unit test.

Potential follow-ups can include:

  • Constructing a proper FeeRate from a u64 in all unit tests, and thus obviating the need for the helper feerate_unchecked going forward.
  • Remove trait Vbytes.
  • Consider adding an extra check that the argument to TxBuilder::drain_to is within "standard" size limits.
  • Consider refactoring coin_selection::select_sorted_utxos to be efficient and readable.

closes #1136

Changelog notice

  • Removed FeeRate type. All fee rates are now rust-bitcoin FeeRate.
  • Removed trait Vbytes.

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

@ValuedMammal
Copy link
Contributor Author

After looking at some related work, I'm not totally opposed to displaying only whole numbers of fee rates. The difference between 99 and 100 sat/vb seems less significant than the difference between 1 and 2 sat/vb.

Some other conveniences I think would be handy:

  • Saturating addition/subtraction of FeeRates
  • A sanity check that a given rate when applied to a minimum valid tx size doesn't produce an amount greater than MAX_MONEY

@ValuedMammal ValuedMammal marked this pull request as ready for review November 19, 2023 19:23
@ValuedMammal ValuedMammal changed the title WIP: Migrate to bitcoin::FeeRate (2) Migrate to bitcoin::FeeRate Nov 19, 2023
@ValuedMammal ValuedMammal force-pushed the refactor/FeeRate branch 2 times, most recently from f781978 to afeb4da Compare November 26, 2023 17:43
@notmandatory
Copy link
Member

* A sanity check that a given rate when applied to a minimum valid tx size doesn't produce an amount greater than `MAX_MONEY`

The fee and fee rate sanity check should be done in a new PR, I created #1231 for this issue.

@ValuedMammal ValuedMammal force-pushed the refactor/FeeRate branch 2 times, most recently from 1d43f8c to 553bdf9 Compare December 6, 2023 03:37
@ValuedMammal
Copy link
Contributor Author

Rebased to 553bdf9

@nondiremanuel nondiremanuel modified the milestones: 1.0.0-alpha.4, 1.0.0 Jan 6, 2024
@notmandatory notmandatory added the api A breaking API change label Jan 16, 2024
@evanlinjin
Copy link
Member

I think I have a controversial opinion about these changes. Because we plan to redo the entire tx building logic (after 1.0), and the current tx builder works okay as it is... Would this be worth the effort?

@notmandatory
Copy link
Member

This one needs a rebase after alpha.5 release.

@ValuedMammal
Copy link
Contributor Author

I think I have a controversial opinion about these changes. Because we plan to redo the entire tx building logic (after 1.0), and the current tx builder works okay as it is... Would this be worth the effort?

I think it's fair to have a deeper discussion about this. I don't have strong feelings either way. I think I lean toward making the change because 1) ease of maintainability by aligning with rust bitcoin, 2) the units of a feerate can always be converted to any unit you like.

Granted I'm not as familiar with some of the long-standing design efforts of BDK, so I'm happy to get other opinions or hold off until everyone's in agreement.

Copy link
Contributor

@storopoli storopoli left a comment

Choose a reason for hiding this comment

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

Some changes proposed.
Mostly important is to use from_vb instead of from_vb_unchecked in code and examples.

Tests are fine to use the unchecked version.

crates/bdk/src/wallet/coin_selection.rs Outdated Show resolved Hide resolved
crates/bdk/src/wallet/coin_selection.rs Outdated Show resolved Hide resolved
crates/bdk/src/wallet/coin_selection.rs Show resolved Hide resolved
crates/bdk/src/wallet/mod.rs Outdated Show resolved Hide resolved
crates/bdk/src/wallet/mod.rs Outdated Show resolved Hide resolved
crates/bdk/src/wallet/tx_builder.rs Outdated Show resolved Hide resolved
crates/bdk/tests/psbt.rs Outdated Show resolved Hide resolved
crates/bdk/tests/wallet.rs Outdated Show resolved Hide resolved
crates/bdk/tests/wallet.rs Outdated Show resolved Hide resolved
crates/bdk/tests/wallet.rs Show resolved Hide resolved
@ValuedMammal
Copy link
Contributor Author

Thank you @storopoli , many good points brought up. I'm working through some of the comments now

Copy link
Contributor

@storopoli storopoli left a comment

Choose a reason for hiding this comment

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

Just a minor thing.

crates/bdk/src/types.rs Outdated Show resolved Hide resolved
@ValuedMammal
Copy link
Contributor Author

Recent changes:

  • Using checked vsize-to-weight conversions in documentation and during coin selection.
  • Added docstring to the test helper feerate_unchecked to explain its purpose, and moved it to bdk/tests/common.rs

Copy link
Member

@evanlinjin evanlinjin left a comment

Choose a reason for hiding this comment

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

Thanks for working on this, fee/weight calculations should be more accurate than before since the old FeeRate::fee_wu was rounding up virtual bytes to whole units, whereas the Mul<FeeRate> for Weight impl (which we are using now) is rounding up kilo-wus.

However, I think we should try our best to avoid these changes in the future. This took a long time to review for me as I had to revisit old code to understand the ramifications of these changes. If there is no bug, we should just leave it as is so we can focus our efforts on the new TxBuilder.

As a final nit, let's get rid of Vbytes and I will happily ACK this!

crates/bdk/src/wallet/coin_selection.rs Show resolved Hide resolved
crates/bdk/src/wallet/coin_selection.rs Show resolved Hide resolved
crates/bdk/src/types.rs Show resolved Hide resolved
@ValuedMammal
Copy link
Contributor Author

@ValuedMammal ValuedMammal mentioned this pull request Mar 19, 2024
4 tasks
@ValuedMammal ValuedMammal force-pushed the refactor/FeeRate branch 2 times, most recently from 4ec57c4 to 9ffced2 Compare March 21, 2024 23:17
@ValuedMammal
Copy link
Contributor Author

Posting clippy checks here instead.
error: file opened with create, but truncate behavior not defined
--> crates/file_store/src/store.rs:64:14
|
64 | .create(true)
| ^^^^^^^^^^^^- help: add: .truncate(true)
|
= help: if you intend to overwrite an existing file entirely, call .truncate(true)

@evanlinjin ?

@evanlinjin
Copy link
Member

@ValuedMammal rebase on master should fix it now!

Adopt `bitcoin::FeeRate` throughout
This makes the helper `feerate_unchecked` now redundant but
still usable.
Also modify a unit test `test_bump_fee_low_fee_rate` to
additionally assert the expected error message
The only place this is being used is a unit test that is
easily refactored. For size conversions prefer methods
on e.g. `Weight`.
Copy link
Member

@evanlinjin evanlinjin left a comment

Choose a reason for hiding this comment

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

ACK 475a772

@evanlinjin evanlinjin merged commit 6e8a4a8 into bitcoindevkit:master Mar 22, 2024
12 checks passed
@ValuedMammal ValuedMammal deleted the refactor/FeeRate branch March 25, 2024 12:55
@notmandatory notmandatory mentioned this pull request Mar 26, 2024
25 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api A breaking API change module-wallet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Replace bdk FeeRate with rust-bitcoin FeeRate
5 participants