|
| 1 | +--- |
| 2 | +title: "Release 0.30.0 is out!" |
| 3 | +date: 2023-02-21T20:00:00-07:00 |
| 4 | +draft: false |
| 5 | +--- |
| 6 | + |
| 7 | +`rust-bitcoin` version 0.30.0 is out now. |
| 8 | + |
| 9 | +<!--more--> |
| 10 | + |
| 11 | +This is a rather large release so we decided to write an update guide for you guys. If this guide is |
| 12 | +not useful or lacking in some way please do let us know so we can do better. |
| 13 | + |
| 14 | +First a little excuse for why this is going to be so painful. We try to deprecate things when we |
| 15 | +make API breaking changes, using |
| 16 | + |
| 17 | + #[deprecated(since = "x.y.z", note = "use foobar instead")] |
| 18 | + |
| 19 | +This allows us to give you a hint on how to upgrade by way of the compiler. The problem we hit was |
| 20 | +that its not always possible to deprecate things (e.g. changing arguments to a function) so under |
| 21 | +the cover of "this is a pre-1.0 release" and with the aim of pushing kind of fast so we can get to |
| 22 | +the 1.0 release, we got a bit sloppy with deprecation this release - sorry about that. We are very |
| 23 | +much trying to get to a place where we can commit to our APIs and stabilize the codebase, that is |
| 24 | +the primary goal of development at the moment. If you have API changing suggestions or requests |
| 25 | +please get them into us now so your needs can be met. |
| 26 | + |
| 27 | +Without further ado, here is the upgrade guide. Enjoy! |
| 28 | + |
| 29 | +## Suggested steps |
| 30 | + |
| 31 | +We suggest that you take these steps when upgrading: |
| 32 | + |
| 33 | +0. Make sure to update other dependency versions in `Cargo.toml` if you use them explicitly: `bitcoin_hashes` to 0.12.0, `secp256k1` to 0.27.0 |
| 34 | +1. Remove all occurrences of `util::` referring to our crate |
| 35 | +2. Replace `Script` with [`ScriptBuf`](https://docs.rs/bitcoin/0.30.0/bitcoin/script/struct.ScriptBuf.html) (`s/\([^A-Za-z0-9]\)Script\([^A-Za-z0-9]\)/\1ScriptBuf\2/g` should work in most cases) |
| 36 | +3. Replace instances of `.parse::<Address>()` with `.parse::<Address<_>>()` |
| 37 | +4. Call `require_network(network)` on parsed addresses (you'll get no method found for `Address<NetworkUnchecked>` errors) |
| 38 | +5. Replace `locktime` with [`locktime::absolute`](https://docs.rs/bitcoin/0.30.0/bitcoin/locktime/absolute/index.html) |
| 39 | +6. Replace `PackedLockTime` with just [`LockTime`](https://docs.rs/bitcoin/0.30.0/bitcoin/locktime/absolute/struct.LockTime.html) |
| 40 | +7. Import key types from the `key` submodule rather than `schnorr` or `ecdsa` |
| 41 | +8. Replace `SchnorrSighashType` with [`TapSighashType`](https://docs.rs/bitcoin/0.30.0/bitcoin/sighash/struct.TapSighashType.html) |
| 42 | +9. Replace `TapBranchHash` with [`TapNodeHash`](https://docs.rs/bitcoin/0.30.0/bitcoin/taproot/struct.TapNodeHash.html) |
| 43 | +10. Change `hash_newtype!(FooHash, sha256::Hash, 32, doc="A hash of foo.");` to: |
| 44 | + |
| 45 | +```rust |
| 46 | +hash_newtype! { |
| 47 | + /// A hash of foo. |
| 48 | + pub struct FooHash(sha256::Hash); |
| 49 | +} |
| 50 | +``` |
| 51 | + |
| 52 | +11. Fix outstanding compiler errors, if any |
| 53 | +12. Optimize the code: replace occurrences of `&ScriptBuf` with `Script`, remove allocations... |
| 54 | +13. Remove useless conversions `LockTime` -> `LockTime` (clippy has a lint for it) |
| 55 | + |
| 56 | +These steps should get you most of the way - see "Renames" section below also. |
| 57 | + |
| 58 | +## Re-exports |
| 59 | + |
| 60 | +We are trying to separate the API from the directory structure, as part of this we are attempting to |
| 61 | +only re-export from the crate root types that exist in the standard Bitcoin vernacular i.e., for |
| 62 | +pubkey you can `use bitcoin::PublicKey` but to get an x-only pubkey you need to go to the `key` |
| 63 | +module `use bitcoin::key::XOnlyPublicKey`. |
| 64 | + |
| 65 | +Please note this is still work-in-progress, suggestions welcome. |
| 66 | + |
| 67 | +## Code moves |
| 68 | + |
| 69 | +We moved _a lot_ of stuff around. This was a precursor to crate smashing which we have now started. |
| 70 | +Hopefully things are in intuitive places, it might be useful to take a quick look at the new |
| 71 | +module structure to get a feel for things, specifically: |
| 72 | + |
| 73 | +- We have a workspace now! The main crate now lives in `bitcoin/`. The `bitcoin_hashes` repository |
| 74 | + has been merged into the `rust-bitcoin` repository and now lives under `hashes/`. |
| 75 | + |
| 76 | +- The `util` module is all but gone, try just removing `util::` at first, most modules are |
| 77 | + re-exported at the crate root. |
| 78 | + |
| 79 | +- Cryptography related stuff can now primarily be found in 4 modules (`ecdsa`, `taproot`, `sighash`, |
| 80 | + `key`). We have started to break ECDSA stuff up into legacy and segwit v0 where it is cleaner but |
| 81 | + this is still work-in-progress. |
| 82 | + |
| 83 | +- Some hash wrapper types are now to be found in the module that they are used in e.g., |
| 84 | + `TapLeafHash` is in the `taproot` module. Others are still in `hash_types` but the re-exports now |
| 85 | + conform to the aim stated above so you might need to add `hash_types::` to your paths for the more |
| 86 | + esoteric hash types. |
| 87 | + |
| 88 | +## Script changes |
| 89 | + |
| 90 | +To optimize efficiency of working with borrowed scripts we renamed `Script` to `ScriptBuf` and added |
| 91 | +an unsized `Script`. It works just like `PathBuf` and `Path` (and other such types) from `std`. The |
| 92 | +API tries to resemble those types as much as reasonable (deref coercions etc.), so it should be |
| 93 | +intuitive. Methods in the library that previously took `&Script` (which is now `ScriptBuf`) take the |
| 94 | +unsized `&Script` now. |
| 95 | + |
| 96 | +Additionally, we changed the type accepted by the `push_slice` method to be another unsized newtype: |
| 97 | +`PushBytes` and it's owned counterpart `PushBytesBuf`. These types maintain the invariant of storing |
| 98 | +at most 2^32-1 bytes - the maximum one can push into script. Previously the method would panic if |
| 99 | +you attempted to do it (and it wasn't documented, sorry about that). Now you can either handle it |
| 100 | +explicitly using `TryFrom` or just pass a known-length array (implemented for arrays up to 73 |
| 101 | +bytes). |
| 102 | + |
| 103 | +Types that are commonly pushed into script (serialized signatures, public keys...) implement |
| 104 | +`AsRef<PushBytes>` so you can pass those directly as well. You can also implement `AsRef` for your |
| 105 | +types so they can be pushed directly. |
| 106 | + |
| 107 | +## Taproot changes |
| 108 | + |
| 109 | +Since the introduction of Taproot support the API got "stress tested" and various issues were |
| 110 | +uncovered and fixed. One of them is that the name "Branch Hash" refers to the algorithm being used |
| 111 | +to compute the value but the resulting value is actually a node in the tree. Thus we renamed |
| 112 | +`TapBranchHash` to `TapNodeHash` to reflect this. Additionally we originally used raw |
| 113 | +`sha256::Hashes` for node hashes which was error-prone and annoying because of manual conversions. |
| 114 | +We changed them to use `TapNodeHash` instead. |
| 115 | + |
| 116 | +When writing smart contracts that have their taproot trees statically known it was annoying to use |
| 117 | +`TaprootMerkleBranch::try_from` for arrays that are statically known to be shorter than 128. We've |
| 118 | +added `From` conversion for these. |
| 119 | + |
| 120 | +`NodeInfo` got some improvements too. For trees that are statically guaranteed to not have hidden |
| 121 | +nodes we have `TapTree` type and both got methods for getting an iterator over their respective |
| 122 | +items. This also improved our code internally, fixing some bugs and decreasing the risk of other |
| 123 | +bugs. We have some additional ideas to improve it further. |
| 124 | + |
| 125 | +Some types that do not have a well-defined serialization in the Bitcoin ecosystem or are purely Rust |
| 126 | +constructs (e.g. builders) got serde support removed. Serializing these would be error-prone and |
| 127 | +difficult to support stably. You can instead (de)serialize other types and convert them. |
| 128 | + |
| 129 | +Overall, these changes should make working with Taproot less error-prone and more ergonomic. Taproot |
| 130 | +is still young technology so it's possible there will be more changes in the future as new users try |
| 131 | +out the API. Please let us know if you have questions or suggestions. |
| 132 | + |
| 133 | +## Sighash |
| 134 | + |
| 135 | +We moved around and renamed a bunch of types to do with sighashes. In the `sighash` module, along |
| 136 | +with the `SighashCache` we now have the hopefully clearly named: |
| 137 | + |
| 138 | +- `LegacySighash` |
| 139 | +- `SegwitV0Sighash` |
| 140 | +- `TapSighash` |
| 141 | +- `EcdsaSighashType` |
| 142 | +- `TapSighashType` |
| 143 | + |
| 144 | +Signatures are now in their respective modules (`ecdsa` for legacy and segwit v0): |
| 145 | + |
| 146 | +- `taproot::Signature` |
| 147 | +- `ecdsa::Signature` |
| 148 | + |
| 149 | +## Lock types |
| 150 | + |
| 151 | +There are now two lock times, one for absolute locks (CLTV) and one for relative locks (CSV). We |
| 152 | +export the `absolute` and `relative` modules at the crate root so you can either import them from |
| 153 | +there or `use bitcoin::locktime::{absolute, relative};` if that's clearer. We expect locks to be |
| 154 | +used as `absolute::LockTime`. |
| 155 | + |
| 156 | +## Address changes |
| 157 | + |
| 158 | +Bitcoin addresses for different networks are different, up until this release, when parsing an |
| 159 | +address from a string, a check that the address format matched up to the expected network (e.g. "bc1" |
| 160 | +prefix for Bitcoin mainnet segwit addresses) was available but easy to forget. We've attempted to |
| 161 | +improve the API to make such omissions harder. |
| 162 | + |
| 163 | +Now `Address<V>` includes a generic that is used as a marker for whether the address has been |
| 164 | +checked as valid for a particular network, we have `Address<NetworkChecked>` and |
| 165 | +`Address<NetworkUnchecked>`, defaulting to `NetworkChecked`. Because of the default some uses will |
| 166 | +just keep working but you should be aware that `Address` now means `Address<NetworkChecked>`. The |
| 167 | +string parsing functions return types as expected. See the docs on `Address` for more information. |
| 168 | + |
| 169 | +## Newtypes |
| 170 | + |
| 171 | +This is a non-exhaustive list of newtypes added this release: |
| 172 | + |
| 173 | +- `relative::LockTime` |
| 174 | +- `relative::Height` |
| 175 | +- `relative::Time` |
| 176 | +- `ecdsa::SerializedSignature` |
| 177 | +- `ScriptBuf` |
| 178 | +- `PushBytes` / `PushBytesBuf` |
| 179 | +- `Target` |
| 180 | +- `CompactTarget` |
| 181 | +- `Work` |
| 182 | + |
| 183 | +### Renames |
| 184 | + |
| 185 | +This is a non-exhaustive list of types renamed in this release: |
| 186 | + |
| 187 | +- `Script` -> `ScriptBuf` |
| 188 | +- `locktime::LockTime` -> `locktime::absolute::LockTime` |
| 189 | +- `locktime::Time` -> `locktime::absolute::Time` |
| 190 | +- `locktime::Height` -> `locktime::absolute::Height` |
| 191 | +- `TapBranchHash` / `TapLeafHash` -> `TapNodeHash` |
| 192 | +- `TapSighashHash` -> `TapSighash` |
| 193 | +- `SchnorrSighashtype` -> `TapSighashType` |
| 194 | +- `schnorr` -> `taproot` (module rename) |
| 195 | +- Various error types were renamed, we try to use `foo::Error` if there is a single error type in |
| 196 | + the `foo` module. |
| 197 | + |
| 198 | +### Removed types |
| 199 | + |
| 200 | +- `PackedLockTime` |
| 201 | + |
| 202 | +This type was intended as an optimization of the absolute locktime using a `u32`, this turned out to |
| 203 | +be not such a great idea. Please note `absolute::LockTime` does not implement `Ord`. |
| 204 | + |
| 205 | +- `Uint256` |
| 206 | + |
| 207 | +We changed the `Uint256` type to `U256` and made it private since it is not a general purpose |
| 208 | +integer type. Rather we wrapped it to create the `Work` and `Target` types. |
| 209 | + |
| 210 | +## Final thoughts |
| 211 | + |
| 212 | +I've tried to give you some context on why so many changes. Hopefully the context makes the upgrade |
| 213 | +path easier and helps to clarify the direction we are pushing in at the moment. As always, |
| 214 | +contributions are most welcome, issues, PRs, and even just ideas. We are here to provide the best |
| 215 | +crate we can for devs wishing to interact with the Bitcoin network in Rust, feedback from your |
| 216 | +usecase helps us a lot, help us out so we can help you. |
| 217 | + |
| 218 | +Thanks, |
| 219 | +Tobin (and the rust-bitcoin devs). |
0 commit comments