9aa235c24d BREAKING: Change Psbt serde implementations (Daniel Roberts)
d7e9a84339 Fix Psbt preimage keys in serde test (Daniel Roberts)
62026c1e2d Don't use PSBT_GLOBAL_XPUB as an unknown key in Psbt serde test (Daniel Roberts)
Pull request description:
Implements the conclusion of #3454 by serializing Psbts using the BIP-174 binary encoding, optionally using base64 where appropriate.
The core of the problem is the old derived serde implementation by its nature can't be backwards compatible when serialized in binary formats like bincode. Fields will be added to the Psbt (my motivating case in #4440 ) and this will always break formats like bincode.
ACKs for top commit:
apoelstra:
ACK 9aa235c24d65d23de2afc21fcbd019892bf4ad2a; successfully ran local tests
tcharding:
ACK 9aa235c24d
Tree-SHA512: 4dc9dbf1a71f06769d74fada7e3d5557a3df3ee78769c66c2d8480c434baa0abd2efba555137563af58da2cc1d545813eb43b6c696b363a5777a9836bc1b7382
a1ce2d1ac8 Use _u32 in FeeRate constructor instead of _unchecked (Tobin C. Harding)
Pull request description:
When constructing an `Amount` it was observed recently that a `u32` is often big enough. For the same reason we can use a `u32` to construct a fee rate instead of overflowing.
Use `_u32`in the constructor and remove the panic.
ACKs for top commit:
apoelstra:
ACK a1ce2d1ac8d646b63532ed9ac459ffea39ec8c20; successfully ran local tests
Tree-SHA512: 339974c954ad613b0be684f7b2fa1402f59fe401969f3785a702ffbb14ac913ecf4c8228240d068ba4b482e38263590154167a071d823ccc9b4d0691036ca484
Replace derived Psbt serde implementation with one that conforms to
BIP-174. In human readable serde contexts, serialize to the base64
encoded format, and in binary serde contexts, serialize to the raw
binary format.
The previous derived serde implementation cannot be used in a backward or
forward compatible way in binary formats like bincode, which means that
every field added to the Psbt struct would break serde de/serialization
into binary formats. Instead, this one-time breaking change will fix the
issue going forward.
Downstream users with persisted data in the old serde format should continue
using 0.32.x to create migrations to the new format.
The preimage values in the serde Psbt don't actually correspond to the
hash keys they should in the serde test. This doesn't cause an error
currently because the derived serde implementation doesn't enforce their
validity during deserialization, but it will when the serde
implementation is modified to use the BIP-174 format.
The previous test used global key id 1 which is not unknown, it's PSBT_GLOBAL_XPUB.
That's an inconsistent state for a Psbt to be in, and will cause a
deserialization error when the Psbt serde implementation is modified to
use the BIP-174 format.
When constructing an `Amount` it was observed recently that a `u32` is
often big enough. For the same reason we can use a `u32` to construct a
fee rate instead of overflowing.
Use `_u32`in the constructor and remove the panic.
ade7ea5fcf psbt: replace the fee rate magic numbers with named constants in tests (frankomosh)
Pull request description:
Replace a hardcoded fee rate numbers in PSBT high-fee checks test with named constants.
Close#4378
ACKs for top commit:
tcharding:
ACK ade7ea5fcf
apoelstra:
ACK ade7ea5fcfc1d00a7cb3c35b4022a4543a7efe1d; successfully ran local tests
Tree-SHA512: fa02217940ae32f00164c762c82ecb6bd28da58e5ad44165124a7ad44367d7d0f752e7ab189b991edb2460c449bbd0a83df16a47b082f6755bd9e9d38e398cd8
29b12bec6b Remove Display/FromStr for FeeRate (Tobin C. Harding)
Pull request description:
Parsing and displaying strings is a PITA. `FeeRate` is likely not that heavily used at the moment and users can always just call `to_sat_per_kwu()` to format it.
So we can get the `units-1.0-alpha.0` release out the door just remove the `Display` and `FromStr` impls for now. They can be added back in later when we have time to get #4339 in.
ACKs for top commit:
apoelstra:
ACK 29b12bec6b34148d6df9a4e6207132a667c53b4c; successfully ran local tests
Tree-SHA512: ffb49ab5d4f98be603eb1ca2f2e9d28ff7eaae66607eb9d2d5fef1f98ba2ac284a0007a86c3cae88f06e5b44f1e3e3ecb2014323b82ad4007e8ec59d6d04759b
a1d4bc31e5 test(p2p): add tests for `AddrV2` <> `SocketAddr` conversions (Luis Schwab)
64387f566e feat(p2p): add `AddrV2` <> `SocketAddr` conversions (Luis Schwab)
Pull request description:
Closes#4436.
Note: I made the `AddrV2::Cjdns` to `SocketAddr` conversion throw the `CjdnsNotRecommended` error. Do we want this behavior or just assume the user knows what he is doing? cc Kixunil
### Changelog
- Implement `From<SocketAddr> for AddrV2`.
- Implement `TryFrom<AddrV2> for SocketAddr`.
- Implement `AddrV2ConversionError` enum and it's `fmt::Display`.
- Tests for these conversions.
ACKs for top commit:
apoelstra:
ACK a1d4bc31e5c7cfe0227db64aec8671efcc0c6677; successfully ran local tests
tcharding:
ACK a1d4bc31e5
Tree-SHA512: c11f3053428d2c8ca971bbc6bc4ad4619260fe95cba055586f4889d7397733f7d286dcafa111234a6be4a739fd56cdd7e64dbf71b106a71d2483794ca7018105
d74eede260 fix(taproot): raname `from_key_and_tweak` to `from_key_and_merkle_root` (Luis Schwab)
Pull request description:
Closes#4236.
### Changelog
- Rename `TapTweakHash::from_key_and_tweak` to `TapTweakHash::from_key_and_merkle_root`. The naming was just wrong, since a TapTweak takes in a public key and a Merkle root to produce a tweak.
ACKs for top commit:
apoelstra:
ACK d74eede26064a40d70c7aeb3335b9a4a28eb6bd9; successfully ran local tests
tcharding:
ACK d74eede260
Tree-SHA512: 03fdb73758f965290c083165b23a0345325e475f159aa76ff141a9aa3251960041366ddf195b74cada7b289d4493190cf9b17130736002d48b6fac68941012fb
Parsing and displaying strings is a PITA. `FeeRate` is likely not that
heavily used at the moment and users can always just call
`to_sat_per_kwu()` to format it.
So we can get the `units-1.0-alpha.0` release out the door just remove
the `Display` and `FromStr` impls for now. They can be added back in
later when we have time to get #4339 in.
2c0f388108 Fix up script to/from hex (Tobin C. Harding)
Pull request description:
We (I) have recently done to PRs patching the way we handle converting scripts to and from hex.
In doing these I made a mess of the deprecation because after both PRs were in I had managed to change the return type and the behaviour of the deprecated function.
On top of that the docs were either outright wrong or not that clear.
Props to Kix for doing post merge review and finding my mistakes.
Close#4498
ACKs for top commit:
apoelstra:
ACK 2c0f3881085ba540d517de121d4ba005f9e73a8c; successfully ran local tests
Tree-SHA512: 8bd8590c07efdbfcf113bfcb4b96dc01992c4f215a11e4a1b1f907c8ae9fa47d83c29298bd9b2afc2628b12eb51afd023a48f241a456a0e02a37854b41f6654b
We (I) have recently done to PRs patching the way we handle converting
scripts to and from hex.
In doing these I made a mess of the deprecation because after both PRs
were in I had managed to change the return type and the behaviour of the
deprecated function.
On top of that the docs were either outright wrong or not that clear.
Props to Kix for doing post merge review and finding my mistakes.
d003d48592 Add `Builder::with_capacity()` (Daniel Roberts)
e492f94289 Update `ScriptBuf::with_capacity` docs (Daniel Roberts)
Pull request description:
Enable the creation of `bitcoin::script::Builder` with a preallocated capacity.
This is pretty minor, but it provides a small speedup if used correctly. I've observed a 0.4% speedup and a 0.7% speedup in two code bases that create lots of outputs (on the order of tens to hundreds of thousands). It provided a much larger speedup (5% or so) in the latter code base before some other optimizations dwarfed it.
I have a branch that also uses it for `ScriptBufExt::new_*()` but while it provides a small performance improvement for all script types except one, `ScriptBufExt::new_p2tr()` actually causes a small performance regression. Since the only use case I have for creating lots and lots of scripts is in taproot with CHECKTEMPLATEVERIFY, I'm holding back that change if/until I figure out what's going on exactly (and hopefully resolve it).
ACKs for top commit:
tcharding:
ACK d003d48592
apoelstra:
ACK d003d4859251abb01929ccab6009a02e0c96b0cd; successfully ran local tests
Tree-SHA512: 51137574ca3d9dc5c319df124f470abd0f82413c093a5636af0439eb0fc2ad01dcf83df366a02279fc7d28feed24aa8c7db33b3c474d8bde7a9b6636343f8e9a
3fbd6fb6b3 test: Add constructor test (yancy)
Pull request description:
The constructor currently has no test coverage.
ACKs for top commit:
apoelstra:
ACK 3fbd6fb6b3c6dc1f1d5c14b3f3486140a781d0f0; successfully ran local tests
tcharding:
ACK 3fbd6fb6b3
Tree-SHA512: 9819bd058b84a7b633279d12da48c9af7af765fd8dca5d297787872badc431769c026e57b03bf6d907c89a7b7a5c116cda1be98cb6261dd2a6c331276e627cc3
873880b192 test: push int minimality (ChrisCho-H)
Pull request description:
Integrate the minimality test of `push_int` into that of `push_slice`. This increases test coverage.
ACKs for top commit:
apoelstra:
utACK 873880b192
tcharding:
ACK 873880b192
Tree-SHA512: 8bbd0b7ec4c69faaadb9ab4bae7429bbebd66d1d718b80f19b323a1059a983ea1b41f743a920b6fdacce213e66708ed1028227246021457601bce968b8bf3f22
b038520c4d Change the return type of effective_value (yancy)
Pull request description:
Prefer the more informative return type NumOpResult over Option. Also a returns section was added which describes the different possible returns.
The api of NumOpResult could probably be extended to cleanup the match statement. Also consider api addition for unchecked calculations natively.
ACKs for top commit:
tcharding:
ACK b038520c4d
apoelstra:
ACK b038520c4dc8c2f92cb40a9fd272608ae2e9b799; successfully ran local tests
Tree-SHA512: 2e66a3ca83514f0ad011660178f8e5ea9d9b1de03dc030e7c57f558e08a42261724251364bb7a746b6970b4288a45539a33d3b36b114c855b6246a56fee3c61c
3b8164139f primitives: Add docs section for script hex API (Tobin C. Harding)
6b90e42e78 Finalize the script hex APIs (Tobin C. Harding)
Pull request description:
In #4316 we made some 'improvements' to what script functions and trait implementations do and do not include the length prefix. Iterate again on it as described here: https://github.com/rust-bitcoin/rust-bitcoin/pull/4316#issuecomment-2847710436
- Patch 1 does the changes
- Patch 2 adds some more docs, requires a grammarian to check my Aussie lingua
ACKs for top commit:
apoelstra:
ACK 3b8164139f6ecebc97b66a299b4a87c2288d8a76; successfully ran local tests
Tree-SHA512: 481db88ae1b6f5751e81e4cd126f545cfc34bef6dcfcf857f1c7464aeb41f5de95fc4582c015abde04372fe025efa13cdf2906e75517f62cff3ddec05c4d9711
Recently we made an attempt at making the hex APIs for scripts easier to
use, better documented, and shown via an example.
After that work we decided it would be better if `LowerHex`/`UpperHex`
did not have the prefix. We also wanted to further clarify the inherent
function names to make the all explicit.
See GitHub issue #4316 for the thread of discussion.
Note that this PR does not require changes to the serde regression test
which were non changed in the original work either.
Name the type exactly what it is. This used to be `Time`, then we tried
`MtpInterval`.
Note that this makes some of the original function names overly verbose
e.g., `NumberOf512seconds::from_512_second_intervals()` but given the
curlyness of locktimes too verbose is better than too terse. Also this
type, along with `NumberOfBlocks` is not going to be in very wide use so
the ergonomic hit is worth the additional clarity.
Name this type exactly what it is. Note for the error we just use
'height' even though this is a bit stale but the general concept is ok
in the error type because the name is long already.
47c77afaac units: delete MtpAndHeight type (Andrew Poelstra)
d82b8c0bcb primitives: stop using MtpAndHeight (Andrew Poelstra)
72d5fbad73 units: stop using MtpAndHeight in locktime::relative is_satisfied_by methods (Andrew Poelstra)
d933c754f5 units: change type of MtpHeight::to_mtp to BlockMtp (Andrew Poelstra)
dcbdb7ca8a units: add checked arithmetic to Block{Height,Mtp}{Interval,} (Andrew Poelstra)
4300271f0c units: add constructor for absolute::Mtp from timestamps (Andrew Poelstra)
4e4601b3d5 units: rename BlockInterval to BlockHeightInterval (Andrew Poelstra)
cb882c5ce1 units: add global `BlockMtpInterval` type (Andrew Poelstra)
4e3af5162f units: add global `BlockMtp` type (Andrew Poelstra)
a3228d4636 units: pull u32 conversions for BlockHeight/BlockInterval into macro (Andrew Poelstra)
Pull request description:
This is a more involved PR than I'd expected but hopefully the individual commits make sense and are well-motivated. Essentially, my goal was to replace `MtpAndHeight` as used by relative locktimes with a pair of `Mtp` and `Height`.
However, relative locktimes, when given a MTP/Height for the UTXO creation and the chain tip, are roughly modeled as "take a diff of MTPs to get a `relative::MtpInterval`, a diff of heights to get a `relative::HeightInterval`, and compare to the locktimes". *However*, we have no standalone MTP type to "take a diff of", and also there are failure modes when creating the diffs (e.g. if the diff would exceed the range of `MtpInterval` or `HeightInterval`).
So I backed up and decided to use the existing `BlockHeight`/`BlockInterval` as the type to "take a diff of". I needed to introduce a `BlockMtp`/`BlockMtpInterval` to work with MTPs. These types have full-u32 range, unlike the similarly-named types in `units::locktimes::absolute`. I then needed to add some conversion methods. Along the way, I cleaned up the APIs and documentation, added checked arithmetic, etc., as needed.
See the individual commit messages for more detail.
I believe the resulting API is much more consistent and discoverable, even though it has more surface than the old API.
I considered splitting this into 2 PRs but I think the first half of the changes aren't well-motivated with out the second half. Let me know.
ACKs for top commit:
tcharding:
ACK 47c77afaac
Tree-SHA512: ebe19a5b1684db8c2d913274347c994026aaa0dcdd79349c237920a82fe55560777278efdbbc7f1b1424c9391d9bbd891ae844db885deea75288000437a8a287
13cbead947 Use NumOpResult instead of Option (yancy)
002a0382aa Mark function constant (yancy)
Pull request description:
Prefer the more descriptive NumOpResult return type over Option where return types are fallible.
Closes https://github.com/rust-bitcoin/rust-bitcoin/issues/4419
ACKs for top commit:
apoelstra:
ACK 13cbead94766987f59482b1fbc1d0ebd0799737c; successfully ran local tests
tcharding:
ACK 13cbead947
Kixunil:
ACK 13cbead947
Tree-SHA512: 1a870962dcafe901a07abd93bd8075e41696341c1a4b3efef615493c73d5e5728bbc2326f8c2c95b9034ab001d0b3c668c9d64793ab03486d3a19f31df907c96
c11772a768 Accept flexible input types for Taproot-related functions (Erick Cestari)
2a518d62e6 Wrap secp256k1::XOnlyPublicKey to improve error handling (Erick Cestari)
Pull request description:
This PR addresses issue #4361 by creating a wrapper type for XOnlyPublicKey instead of directly re-exporting it from the secp256k1 library.
### Key Changes
1. Created a new `XOnlyPublicKey` struct that wraps `secp256k1::XOnlyPublicKey`
2. Implemented custom error types:
- `ParseXOnlyPublicKeyError` for handling parsing errors
- `TweakXOnlyPublicKeyError` for tweaking an `XOnlyPublicKey`
3. Updated all imports and usage throughout the codebase
4. Implemented necessary traits and methods for compatibility
Closes#4361
ACKs for top commit:
apoelstra:
ACK c11772a768eefd89dcc0e3b1a369d535c191f94a; successfully ran local tests
tcharding:
ACK c11772a768
Tree-SHA512: c8da3486e7ffcab6c24cc08f9b2f964dd9158449ef2bd720e54d56176bc7027052314ea23cac3f673d217fa785238ea8a9b5323ba57f02199f20e56df5893965
7ecef176f9 Fix documentation error for `TweakedPublicKey::serialize` (Daniel Roberts)
Pull request description:
Fixes an ancient copy/paste error in documentation ( `secp256k1::schnorrsig::PublicKey::serialize()` docs copied from ECDSA docs, which was copied into rust-bitcoin)
Is there a threshold beneath which a PR is too trivial?
ACKs for top commit:
apoelstra:
ACK 7ecef176f9523cd8fece7e8e71040507f46fb9c2; successfully ran local tests; thanks!
tcharding:
ACK 7ecef176f9
Tree-SHA512: 9b7469d34eadfcabc93264c114f292c415d2dbb09b41ec05de4ac399677d5c80f1d09ecd0c382680996450824f1fd60503d3e3d3ec8bdd8135cebdf7ef82fe0d
5ba763f1a2 Update Github CI to rustc nightly-2025-05-02 (Jamil Lambert, PhD)
09132b80e1 Fix rustdoc compile_fail example (Jamil Lambert, PhD)
282434d4bd Use variable directly in format! string (Jamil Lambert, PhD)
2fbbc825c9 Allow uninlined format args (Jamil Lambert, PhD)
Pull request description:
There is a new lint error on nightly-2025-04-25 "variables can be used directly in the `format!` string".
The existing syntax `format!("{}", x)` is more commonly used than `format!("{x}")` therefore allow it in existing code.
Also the rustdoc example in #4259 now causes the new nightly to fail CI because of the unused variable.
Patches in the PR:
- Exclude the lint to allow the existing syntax in `format!` strings in all crate `lib.rs`, `build.rs.` and test files.
- Use the variables in the `format!` string for all cases in `bitcoin/examples/` since there are no other allowed lints in examples.
- Correct the function names in the rustdoc example and prefix the unused variable with an underscore.
- Update rustc to nightly-2025-05-02 (2025-04-25 had a bug which is fixed in 2025-05-02).
ACKs for top commit:
apoelstra:
ACK 5ba763f1a2ebea2cb80ee50a80228e6bda11936f; successfully ran local tests
Kixunil:
ACK 5ba763f1a2
Tree-SHA512: 20b97d2bedc631715c2b541285559a6ab84bbdb8f2f11d7282bdfecadba0cc8781a1973f0c01c25432aaceaad09e3ddbf59afe54c0bba54768e93ed9d5e50d5a
51fe619fe0 Set deprecation to released date of to_inner (Tobin C. Harding)
Pull request description:
In #4373 we added a couple new conversion methods and deprecated the `to_inner` ones. During that the deprecation date was set to `0.33.0`.
We have backported the changes and will deprecate in `0.32.6` so set the version number now so we don't forget later.
ACKs for top commit:
apoelstra:
ACK 51fe619fe0c9e154a7979a3a71c56707bfa73e9c; successfully ran local tests
shinghim:
ACK 51fe619fe0
Tree-SHA512: 9f8badee92684204966107013b272ff51b88bee632bd6779ec6ecf2c78221c2228428a3c180200db5ae3205d042e58a6919dc9e621e153171e200e9b81c628d6
For our relative locktime API, we are going to want to take differences
of arbitrary MTPs in order to check whether they meet some relative
timelock threshold.
However, the `locktime::absolute::Mtp` type can only represent MTPs that
exceed 500 million. In practice this is a non-issue; by consensus MTPs
must be monotonic and every real chain (even test chains) have initial
real MTPs well above 500 million, which as a UNIX timestamp corresponds
to November 5, 1985.
But in theory this is a big problem: if we were to treat relative MTPs
as "differences of absolute-timelock MTPs" then we will be unable to
construct relative timelocks on chains with weird timestamps (and on
legitimate chains, we'd have .unwrap()s everywhere that would be hard to
justify). But we need to treat them as a "difference of MTPs" in *some*
sense, because otherwise they'd be very hard to construct.
Refactor Taproot functions to accept any type implementing `Into<XOnlyPublicKey>`,
instead of requiring `XOnlyPublicKey` directly. This improves ergonomics when working
with compatible types, avoiding unnecessary `.into()` conversions at call sites.