From 92328fb8f6e34a383e876a79fad3fee4110c09a5 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Wed, 3 Jan 2024 15:06:14 +0100 Subject: [PATCH 1/7] Bump MSRV for lianad to 1.63 1.63 is the latest version supported by Debian. It's also now almost a year and a half old (August 2023). We start getting way behind on our dependency updates, and sometimes even missing some security updates (nothing which affects us but still..). Asking to support a less than 2.5yo compiler shouldn't be that much to ask, but hey. 1.63 is now a better balance between support for upstream updates and support for a not recklessly new compiler. --- .github/workflows/main.yml | 2 +- CONTRIBUTING.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9005cff6..4689a540 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: toolchain: - - 1.54 + - 1.63 - nightly os: - ubuntu-latest diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 412a5809..51767ece 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -66,7 +66,7 @@ query). ## Minimum Supported Rust Version -`lianad` should always compile and pass tests using **Rust 1.54**. The rationale behind this is +`lianad` should always compile and pass tests using **Rust 1.63**. The rationale behind this is support something reasonable, and preferably supported by all of: - [Guix](https://guix.gnu.org/) - Popular distributions' packages (especially Debian which is the most conservative) From 84e8a2ae8630789f5b8cc3796e0f1e4ff87614f2 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Wed, 3 Jan 2024 15:27:33 +0100 Subject: [PATCH 2/7] Cargo.lock: update minor dependencies after MSRV bump Took care of keeping dirs pinned to avoid the dirs license shitshow. See https://github.com/dirs-dev/dirs-sys-rs/commit/e169da7af901eb621e5d244efe960f4da8ed150d#r111303146 for more. --- Cargo.lock | 198 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 111 insertions(+), 87 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 341f2d65..14592641 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" dependencies = [ "gimli", ] @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" dependencies = [ "addr2line", "cc", @@ -74,9 +74,9 @@ dependencies = [ [[package]] name = "bitcoin" -version = "0.30.0" +version = "0.30.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b36f4c848f6bd9ff208128f08751135846cc23ae57d66ab10a22efff1c675f3c" +checksum = "1945a5048598e4189e239d3f809b19bdad4845c4b2ba400d304d2dcf26d2c462" dependencies = [ "base64", "bech32", @@ -116,10 +116,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "cc" -version = "1.0.73" +name = "bitflags" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -138,11 +147,12 @@ dependencies = [ [[package]] name = "dirs-sys" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04414300db88f70d74c5ff54e50f9e1d1737d9a5b90f53fcf2e95ca2a9ab554b" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" dependencies = [ "libc", + "option-ext", "redox_users", "windows-sys", ] @@ -170,9 +180,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", @@ -211,9 +221,9 @@ checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jsonrpc" @@ -250,9 +260,20 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.147" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall", +] [[package]] name = "libsqlite3-sys" @@ -267,18 +288,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "miniscript" @@ -293,18 +311,18 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] [[package]] name = "minreq" -version = "2.8.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3de406eeb24aba36ed3829532fa01649129677186b44a49debec0ec574ca7da7" +checksum = "cb3371dfc7b772c540da1380123674a8e20583aca99907087d990ca58cf44203" dependencies = [ "log", "serde", @@ -313,39 +331,45 @@ dependencies = [ [[package]] name = "object" -version = "0.30.4" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.13.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "pkg-config" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" [[package]] name = "proc-macro2" -version = "1.0.64" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" +checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -361,30 +385,30 @@ dependencies = [ [[package]] name = "rdrand" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e233b642160555c1aa1ff7a78443c6139342f411b6fa6602af2ebbfee9e166bb" +checksum = "d92195228612ac8eed47adbc2ed0f04e513a4ccb98175b6f2bd04d963b533655" dependencies = [ "rand_core", ] [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" dependencies = [ "getrandom", - "redox_syscall", + "libredox", "thiserror", ] @@ -394,7 +418,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85127183a999f7db96d1a976a309eebbfb6ea3b0b400ddd8340190129de6eb7a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -405,15 +429,15 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "secp256k1" @@ -437,18 +461,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.147" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" dependencies = [ "proc-macro2", "quote", @@ -457,9 +481,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.99" +version = "1.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" +checksum = "6fbd975230bada99c8bb618e0c365c2eefa219158d5c6c29610fd09ff1833257" dependencies = [ "itoa", "ryu", @@ -468,15 +492,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "syn" -version = "1.0.102" +version = "2.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" +checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e" dependencies = [ "proc-macro2", "quote", @@ -485,18 +509,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", @@ -529,9 +553,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.2" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -562,18 +586,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "windows-sys" -version = "0.45.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -586,42 +610,42 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" From 65c9e389bb89197c2e9066b82789cec63b18d2d1 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Wed, 3 Jan 2024 16:48:51 +0100 Subject: [PATCH 3/7] Cargo: bump rusqlite to 0.30 This gives us bundled SQLite 3.44.0. Notably this patches CVE-2022-35737 but it shouldn't affect us. --- Cargo.lock | 57 ++++++++++++++++++++++++++++++++++++++++-------------- Cargo.toml | 2 +- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 14592641..2934881e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,15 +19,22 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.7" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ - "getrandom", + "cfg-if", "once_cell", "version_check", + "zerocopy", ] +[[package]] +name = "allocator-api2" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "544a7f66f3407c6ed1285525418393891e0f31c2078a2d46aefb44ecef09b1b3" + [[package]] name = "backtrace" version = "0.3.68" @@ -159,9 +166,9 @@ dependencies = [ [[package]] name = "fallible-iterator" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] name = "fallible-streaming-iterator" @@ -197,18 +204,19 @@ checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", + "allocator-api2", ] [[package]] name = "hashlink" -version = "0.7.0" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ "hashbrown", ] @@ -277,9 +285,9 @@ dependencies = [ [[package]] name = "libsqlite3-sys" -version = "0.24.2" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" dependencies = [ "cc", "pkg-config", @@ -414,16 +422,15 @@ dependencies = [ [[package]] name = "rusqlite" -version = "0.27.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85127183a999f7db96d1a976a309eebbfb6ea3b0b400ddd8340190129de6eb7a" +checksum = "a78046161564f5e7cd9008aff3b2990b3850dc8e0349119b98e8f251e099f24d" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.1", "fallible-iterator", "fallible-streaming-iterator", "hashlink", "libsqlite3-sys", - "memchr", "smallvec", ] @@ -649,3 +656,23 @@ name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 693b8b79..1b56beed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ backtrace = "0.3" # Pinned to this version because they keep breaking their MSRV in point releases... # FIXME: this is unfortunate, we don't receive the updates (sometimes critical) from SQLite. -rusqlite = { version = "0.27", features = ["bundled", "unlock_notify"] } +rusqlite = { version = "0.30", features = ["bundled", "unlock_notify"] } # To talk to bitcoind jsonrpc = { version = "0.16", features = ["minreq_http"], default-features = false } From 2bce4c525d51b8ecbc923a43632ef8a724426453 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Wed, 3 Jan 2024 17:15:05 +0100 Subject: [PATCH 4/7] Cargo: bump jsonrpc version to 0.17 It now finally accepts an option as argument. --- Cargo.lock | 4 +-- Cargo.toml | 2 +- src/bitcoin/d/mod.rs | 80 +++++++++++++++++++++++--------------------- 3 files changed, 45 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2934881e..02b8fc58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -235,9 +235,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jsonrpc" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34efde8d2422fb79ed56db1d3aea8fa5b583351d15a26770cdee2f88813dd702" +checksum = "a26d9104d516092f092d97448787505881fdb6518293b2d6500bf9c180c839dd" dependencies = [ "base64", "minreq", diff --git a/Cargo.toml b/Cargo.toml index 1b56beed..cd63dd83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,7 @@ backtrace = "0.3" rusqlite = { version = "0.30", features = ["bundled", "unlock_notify"] } # To talk to bitcoind -jsonrpc = { version = "0.16", features = ["minreq_http"], default-features = false } +jsonrpc = { version = "0.17", features = ["minreq_http"], default-features = false } # Used for daemonization libc = { version = "0.2", optional = true } diff --git a/src/bitcoin/d/mod.rs b/src/bitcoin/d/mod.rs index e356f3e8..41e7fe1e 100644 --- a/src/bitcoin/d/mod.rs +++ b/src/bitcoin/d/mod.rs @@ -213,11 +213,12 @@ pub struct BitcoinD { macro_rules! params { ($($param:expr),* $(,)?) => { - [ + // FIXME: is there a way to avoid the allocation of an unnecessary Box? + Some(&*arg(Json::Array(vec![ $( - arg($param), + $param, )* - ] + ]))) }; } @@ -312,7 +313,7 @@ impl BitcoinD { } fn check_client(&self, client: &Client) -> Result<(), BitcoindError> { - if let Err(e) = self.make_request(client, "echo", &[]) { + if let Err(e) = self.make_request(client, "echo", None) { if e.is_warming_up() { log::info!("bitcoind is warming up. Retrying connection sanity check in 1 second."); thread::sleep(Duration::from_secs(1)); @@ -388,7 +389,7 @@ impl BitcoinD { &self, client: &Client, method: &str, - params: &[Box], + params: Option<&serde_json::value::RawValue>, retry: bool, ) -> Result { let req = client.build_request(method, params); @@ -403,7 +404,7 @@ impl BitcoinD { &self, client: &Client, method: &str, - params: &[Box], + params: Option<&serde_json::value::RawValue>, ) -> Result { self.make_request_inner(client, method, params, true) } @@ -413,7 +414,7 @@ impl BitcoinD { fn make_noreply_request( &self, method: &str, - params: &[Box], + params: Option<&serde_json::value::RawValue>, ) -> Result<(), BitcoindError> { match self.make_request_inner(&self.sendonly_client, method, params, false) { Ok(_) => Ok(()), @@ -431,12 +432,16 @@ impl BitcoinD { fn make_fallible_node_request( &self, method: &str, - params: &[Box], + params: Option<&serde_json::value::RawValue>, ) -> Result { self.make_request(&self.node_client, method, params) } - fn make_node_request(&self, method: &str, params: &[Box]) -> Json { + fn make_node_request( + &self, + method: &str, + params: Option<&serde_json::value::RawValue>, + ) -> Json { self.make_request(&self.node_client, method, params) .expect("We must not fail to make a request for more than a minute") } @@ -444,7 +449,7 @@ impl BitcoinD { fn make_wallet_request( &self, method: &str, - params: &[Box], + params: Option<&serde_json::value::RawValue>, ) -> Json { self.make_request(&self.watchonly_client, method, params) .expect("We must not fail to make a request for more than a minute") @@ -453,20 +458,20 @@ impl BitcoinD { fn make_faillible_wallet_request( &self, method: &str, - params: &[Box], + params: Option<&serde_json::value::RawValue>, ) -> Result { self.make_request(&self.watchonly_client, method, params) } fn get_bitcoind_version(&self) -> u64 { - self.make_node_request("getnetworkinfo", &[]) + self.make_node_request("getnetworkinfo", None) .get("version") .and_then(Json::as_u64) .expect("Missing or invalid 'version' in 'getnetworkinfo' result?") } fn get_network_bip70(&self) -> String { - self.make_node_request("getblockchaininfo", &[]) + self.make_node_request("getblockchaininfo", None) .get("chain") .and_then(Json::as_str) .expect("Missing or invalid 'chain' in 'getblockchaininfo' result?") @@ -474,7 +479,7 @@ impl BitcoinD { } fn list_wallets(&self) -> Vec { - self.make_node_request("listwallets", &[]) + self.make_node_request("listwallets", None) .as_array() .expect("API break, 'listwallets' didn't return an array.") .iter() @@ -517,7 +522,7 @@ impl BitcoinD { } fn unload_wallet(&self, wallet_path: String) -> Option { - let res = self.make_node_request("unloadwallet", ¶ms!(Json::String(wallet_path),)); + let res = self.make_node_request("unloadwallet", params!(Json::String(wallet_path),)); self.warning_from_res(&res) } @@ -527,7 +532,7 @@ impl BitcoinD { let res = self .make_fallible_node_request( "createwallet", - ¶ms!( + params!( Json::String(wallet_path), Json::Bool(true), // watchonly Json::Bool(true), // blank @@ -562,7 +567,7 @@ impl BitcoinD { }) .collect(); - let res = self.make_wallet_request("importdescriptors", ¶ms!(Json::Array(descriptors))); + let res = self.make_wallet_request("importdescriptors", params!(Json::Array(descriptors))); let all_succeeded = res .as_array() .map(|results| { @@ -579,7 +584,7 @@ impl BitcoinD { } fn list_descriptors(&self) -> Vec { - self.make_wallet_request("listdescriptors", &[]) + self.make_wallet_request("listdescriptors", None) .get("descriptors") .and_then(Json::as_array) .expect("Missing or invalid 'descriptors' field in 'listdescriptors' response") @@ -660,7 +665,7 @@ impl BitcoinD { } let res = self.make_fallible_node_request( "loadwallet", - ¶ms!(Json::String(self.watchonly_wallet_path.clone()),), + params!(Json::String(self.watchonly_wallet_path.clone()),), ); match res { Err(BitcoindError::Server(jsonrpc::Error::Rpc(ref e))) => { @@ -753,7 +758,7 @@ impl BitcoinD { } fn block_chain_info(&self) -> Json { - self.make_node_request("getblockchaininfo", &[]) + self.make_node_request("getblockchaininfo", None) } pub fn sync_progress(&self) -> SyncProgress { @@ -800,7 +805,7 @@ impl BitcoinD { pub fn get_block_hash(&self, height: i32) -> Option { Some( - self.make_fallible_node_request("getblockhash", ¶ms!(Json::Number(height.into()),)) + self.make_fallible_node_request("getblockhash", params!(Json::Number(height.into()),)) .ok()? .as_str() .and_then(|s| bitcoin::BlockHash::from_str(s).ok()) @@ -811,7 +816,7 @@ impl BitcoinD { pub fn list_since_block(&self, block_hash: &bitcoin::BlockHash) -> LSBlockRes { self.make_wallet_request( "listsinceblock", - ¶ms!( + params!( Json::String(block_hash.to_string()), Json::Number(1.into()), // Default for min_confirmations for the returned Json::Bool(true), // Whether to include watchonly @@ -826,7 +831,7 @@ impl BitcoinD { // TODO: Maybe assert we got a -5 error, and not any other kind of error? self.make_faillible_wallet_request( "gettransaction", - ¶ms!(Json::String(txid.to_string())), + params!(Json::String(txid.to_string())), ) .ok() .map(|res| res.into()) @@ -837,7 +842,7 @@ impl BitcoinD { // The result of gettxout is empty if the outpoint is spent. self.make_node_request( "gettxout", - ¶ms!( + params!( Json::String(op.txid.to_string()), Json::Number(op.vout.into()) ), @@ -857,7 +862,7 @@ impl BitcoinD { // unconfirmed, just use the tip. let req = self.make_wallet_request( "gettransaction", - ¶ms!(Json::String(spent_outpoint.txid.to_string())), + params!(Json::String(spent_outpoint.txid.to_string())), ); let list_since_height = match req.get("blockheight").and_then(Json::as_i64) { Some(h) => h as i32, @@ -865,7 +870,7 @@ impl BitcoinD { }; let block_hash = if let Ok(res) = self.make_fallible_node_request( "getblockhash", - ¶ms!(Json::Number((list_since_height - 1).into())), + params!(Json::Number((list_since_height - 1).into())), ) { res.as_str() .expect("'getblockhash' result isn't a string") @@ -880,7 +885,7 @@ impl BitcoinD { // TODO: merge this with the existing list_since_block method. let lsb_res = self.make_wallet_request( "listsinceblock", - ¶ms!( + params!( Json::String(block_hash), Json::Number(1.into()), // Default for min_confirmations for the returned Json::Bool(true), // Whether to include watchonly @@ -915,7 +920,7 @@ impl BitcoinD { let gettx_res = self.make_wallet_request( "gettransaction", - ¶ms!( + params!( Json::String(spending_txid.to_string()), Json::Bool(true), // watchonly Json::Bool(true) // verbose @@ -968,7 +973,7 @@ impl BitcoinD { pub fn get_block_stats(&self, blockhash: bitcoin::BlockHash) -> Option { let res = match self.make_fallible_node_request( "getblockheader", - ¶ms!(Json::String(blockhash.to_string()),), + params!(Json::String(blockhash.to_string()),), ) { Ok(res) => res, Err(e) => { @@ -1016,7 +1021,7 @@ impl BitcoinD { pub fn broadcast_tx(&self, tx: &bitcoin::Transaction) -> Result<(), BitcoindError> { self.make_fallible_node_request( "sendrawtransaction", - ¶ms!(bitcoin::consensus::encode::serialize_hex(tx)), + params!(bitcoin::consensus::encode::serialize_hex(tx).into()), )?; Ok(()) } @@ -1084,10 +1089,9 @@ impl BitcoinD { const NUM_RETRIES: usize = 10; let mut i = 0; loop { - if let Err(e) = self.make_noreply_request( - "importdescriptors", - ¶ms!(Json::Array(desc_json.clone())), - ) { + if let Err(e) = self + .make_noreply_request("importdescriptors", params!(Json::Array(desc_json.clone()))) + { log::error!( "Error when calling 'importdescriptors' for rescanning: {}", e @@ -1108,7 +1112,7 @@ impl BitcoinD { /// Get the progress of the ongoing rescan, if there is any. pub fn rescan_progress(&self) -> Option { - self.make_wallet_request("getwalletinfo", &[]) + self.make_wallet_request("getwalletinfo", None) .get("scanning") // If no rescan is ongoing, it will fail cause it would be 'false' .and_then(Json::as_object) @@ -1135,7 +1139,7 @@ impl BitcoinD { /// Returns `None` if it is not in the mempool. pub fn mempool_entry(&self, txid: &bitcoin::Txid) -> Option { match self - .make_fallible_node_request("getmempoolentry", ¶ms!(Json::String(txid.to_string()))) + .make_fallible_node_request("getmempoolentry", params!(Json::String(txid.to_string()))) { Ok(json) => Some(MempoolEntry::from(json)), Err(BitcoindError::Server(jsonrpc::Error::Rpc(jsonrpc::error::RpcError { @@ -1157,7 +1161,7 @@ impl BitcoinD { .iter() .map(|op| serde_json::json!({"txid": op.txid.to_string(), "vout": op.vout})) .collect(); - self.make_node_request("gettxspendingprevout", ¶ms!(prevouts)) + self.make_node_request("gettxspendingprevout", params!(prevouts)) .as_array() .expect("Always returns an array") .iter() @@ -1173,7 +1177,7 @@ impl BitcoinD { /// Stop bitcoind. pub fn stop(&self) { - self.make_node_request("stop", &[]); + self.make_node_request("stop", None); } } From ce026a62e6bf064cea249f391e4ab870f1cbcb61 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Wed, 3 Jan 2024 18:31:48 +0100 Subject: [PATCH 5/7] Update rust-bitcoin and rust-miniscript The most notable change is rust-bitcoin's change in the serialization of transaction with no input. It now accounts for the segwit marker even for those. The base tx weight in coin selection had to be adapted to handle this. See https://gnusha.org/bitcoin-rust/2024-01-04.log for details. --- Cargo.lock | 63 +++++++++++++++++++++++-------- Cargo.toml | 2 +- src/commands/mod.rs | 71 +++++++++++++++++++---------------- src/database/mod.rs | 2 +- src/database/sqlite/mod.rs | 2 +- src/database/sqlite/schema.rs | 4 +- src/descriptors/analysis.rs | 10 +++-- src/descriptors/mod.rs | 4 +- src/jsonrpc/api.rs | 2 +- src/signer.rs | 33 ++++++++-------- src/spend.rs | 46 ++++++++++++++--------- src/testutils.rs | 4 +- 12 files changed, 144 insertions(+), 99 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 02b8fc58..7d057c72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,6 +56,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + [[package]] name = "bdk_coin_select" version = "0.1.1" @@ -64,9 +70,9 @@ checksum = "c0320167c3655e83f0415d52f39618902e449186ffc7dfb090f922f79675c316" [[package]] name = "bech32" -version = "0.9.1" +version = "0.10.0-beta" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +checksum = "98f7eed2b2781a6f0b5c903471d48e15f56fb4e1165df8a9a2337fd1a59d45ea" [[package]] name = "bip39" @@ -81,19 +87,29 @@ dependencies = [ [[package]] name = "bitcoin" -version = "0.30.2" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1945a5048598e4189e239d3f809b19bdad4845c4b2ba400d304d2dcf26d2c462" +checksum = "5973a027b341b462105675962214dfe3c938ad9afd395d84b28602608bdcec7b" dependencies = [ - "base64", + "base64 0.21.5", "bech32", - "bitcoin-private", - "bitcoin_hashes 0.12.0", + "bitcoin-internals", + "bitcoin_hashes 0.13.0", + "hex-conservative", "hex_lit", "secp256k1", "serde", ] +[[package]] +name = "bitcoin-internals" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" +dependencies = [ + "serde", +] + [[package]] name = "bitcoin-private" version = "0.1.0" @@ -113,6 +129,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501" dependencies = [ "bitcoin-private", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" +dependencies = [ + "bitcoin-internals", + "hex-conservative", "serde", ] @@ -221,6 +247,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "hex-conservative" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ed443af458ccb6d81c1e7e661545f94d3176752fb1df2f543b902a1e0f51e2" + [[package]] name = "hex_lit" version = "0.1.1" @@ -239,7 +271,7 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26d9104d516092f092d97448787505881fdb6518293b2d6500bf9c180c839dd" dependencies = [ - "base64", + "base64 0.13.1", "minreq", "serde", "serde_json", @@ -308,12 +340,13 @@ checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "miniscript" -version = "10.0.0" +version = "11.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eb102b66b2127a872dbcc73095b7b47aeb9d92f7b03c2b2298253ffc82c7594" +checksum = "86a23dd3ad145a980e231185d114399f25a0a307d2cd918010ddda6334323df9" dependencies = [ + "bech32", "bitcoin", - "bitcoin-private", + "bitcoin-internals", "serde", ] @@ -448,9 +481,9 @@ checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "secp256k1" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +checksum = "2acea373acb8c21ecb5a23741452acd2593ed44ee3d343e72baaa143bc89d0d5" dependencies = [ "bitcoin_hashes 0.12.0", "secp256k1-sys", @@ -459,9 +492,9 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.8.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +checksum = "4dd97a086ec737e30053fd5c46f097465d25bb81dd3608825f65298c4c98be83" dependencies = [ "cc", ] diff --git a/Cargo.toml b/Cargo.toml index cd63dd83..21c21949 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ nonblocking_shutdown = [] [dependencies] # For managing transactions (it re-exports the bitcoin crate) -miniscript = { version = "10.0", features = ["serde", "compiler", "base64"] } +miniscript = { version = "11.0", features = ["serde", "compiler", "base64"] } # Coin selection algorithms for spend transaction creation. bdk_coin_select = { version = "0.1.0" } diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 12343d37..83d8ec2c 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -29,7 +29,7 @@ use std::{ }; use miniscript::{ - bitcoin::{self, address, bip32, psbt::PartiallySignedTransaction as Psbt}, + bitcoin::{self, address, bip32, psbt::Psbt}, psbt::PsbtExt, }; use serde::{Deserialize, Serialize}; @@ -609,7 +609,8 @@ impl DaemonControl { // Then, broadcast it (or try to, we never know if we are not going to hit an // error at broadcast time). - let final_tx = spend_psbt.extract_tx(); + // These checks are already performed at Spend creation time. TODO: a belt-and-suspenders is still worth it though. + let final_tx = spend_psbt.extract_tx_unchecked_fee_rate(); self.bitcoin .broadcast_tx(&final_tx) .map_err(CommandError::TxBroadcast) @@ -729,7 +730,7 @@ impl DaemonControl { .expect("address already used in finalized transaction"); ( address.clone(), - bitcoin::Amount::from_sat(txo.value), + txo.value, db_conn.derivation_index_by_address(&address), ) }) @@ -1138,9 +1139,9 @@ mod tests { use bitcoin::{ bip32::{self, ChildNumber}, - blockdata::transaction::{TxIn, TxOut}, + blockdata::transaction::{TxIn, TxOut, Version as TxVersion}, locktime::absolute, - OutPoint, ScriptBuf, Sequence, Transaction, Txid, Witness, + Amount, OutPoint, ScriptBuf, Sequence, Transaction, Txid, Witness, }; use std::{collections::BTreeMap, str::FromStr}; @@ -1300,7 +1301,7 @@ mod tests { dummy_op.txid, ( bitcoin::Transaction { - version: 2, + version: TxVersion::TWO, lock_time: absolute::LockTime::Blocks(absolute::Height::ZERO), input: vec![], output: vec![], @@ -1371,18 +1372,24 @@ mod tests { assert_eq!(tx.output.len(), 2); assert_eq!( tx.output[0].script_pubkey, - dummy_addr.payload.script_pubkey() + dummy_addr.payload().script_pubkey() ); - assert_eq!(tx.output[0].value, dummy_value); + assert_eq!(tx.output[0].value.to_sat(), dummy_value); + + // NOTE: if you are wondering about the usefulness of these tests asserting arbitrary fixed + // values, that's a belt-and-suspenders check to make sure size and fee calculations do not + // change unexpectedly. For instance this specific test caught how a change in + // rust-bitcoin's serialization of transactions with no input silently affected our fee + // calculation. // Transaction is 1 in (P2WSH satisfaction), 2 outs. At 1sat/vb, it's 170 sats fees. // At 2sats/vb, it's twice that. - assert_eq!(tx.output[1].value, 89_830); + assert_eq!(tx.output[1].value.to_sat(), 89_830); let res = control .create_spend(&destinations, &[dummy_op], 2, None) .unwrap(); let tx = res.psbt.unsigned_tx; - assert_eq!(tx.output[1].value, 89_660); + assert_eq!(tx.output[1].value.to_sat(), 89_660); // A feerate of 555 won't trigger the sanity checks (they were previously not taking the // satisfaction size into account and overestimating the feerate). @@ -1414,7 +1421,7 @@ mod tests { // If we ask to create an output for an address from another network, it will fail. let invalid_addr = - bitcoin::Address::new(bitcoin::Network::Testnet, dummy_addr.payload.clone()); + bitcoin::Address::new(bitcoin::Network::Testnet, dummy_addr.payload().clone()); let invalid_destinations: HashMap, u64> = [(invalid_addr, dummy_value)].iter().cloned().collect(); assert!(matches!( @@ -1436,9 +1443,9 @@ mod tests { assert_eq!(tx.output.len(), 1); assert_eq!( tx.output[0].script_pubkey, - dummy_addr.payload.script_pubkey() + dummy_addr.payload().script_pubkey() ); - assert_eq!(tx.output[0].value, 95_000); + assert_eq!(tx.output[0].value.to_sat(), 95_000); // Now if we mark the coin as spent, we won't create another Spend transaction containing // it. @@ -1555,9 +1562,9 @@ mod tests { assert_eq!(tx_auto.output.len(), 2); assert_eq!( tx_auto.output[0].script_pubkey, - dummy_addr.payload.script_pubkey() + dummy_addr.payload().script_pubkey() ); - assert_eq!(tx_auto.output[0].value, 80_000); + assert_eq!(tx_auto.output[0].value, Amount::from_sat(80_000)); // Create a second transaction using manual coin selection. let res_manual = control @@ -1648,7 +1655,7 @@ mod tests { .unwrap(); let mut dummy_bitcoind = DummyBitcoind::new(); let dummy_tx = bitcoin::Transaction { - version: 2, + version: TxVersion::TWO, lock_time: absolute::LockTime::Blocks(absolute::Height::ZERO), input: vec![], output: vec![], @@ -1770,7 +1777,7 @@ mod tests { let mut dummy_bitcoind = DummyBitcoind::new(); // Transaction spends outpoint a. let dummy_tx_a = bitcoin::Transaction { - version: 2, + version: TxVersion::TWO, lock_time: absolute::LockTime::Blocks(absolute::Height::ZERO), input: vec![bitcoin::TxIn { previous_output: dummy_op_a, @@ -1845,7 +1852,7 @@ mod tests { ); let deposit1: Transaction = Transaction { - version: 1, + version: TxVersion::ONE, lock_time: absolute::LockTime::Blocks(absolute::Height::from_consensus(1).unwrap()), input: vec![TxIn { witness: Witness::new(), @@ -1855,12 +1862,12 @@ mod tests { }], output: vec![TxOut { script_pubkey: ScriptBuf::new(), - value: 100_000_000, + value: Amount::from_sat(100_000_000), }], }; let deposit2: Transaction = Transaction { - version: 1, + version: TxVersion::ONE, lock_time: absolute::LockTime::Blocks(absolute::Height::from_consensus(1).unwrap()), input: vec![TxIn { witness: Witness::new(), @@ -1870,12 +1877,12 @@ mod tests { }], output: vec![TxOut { script_pubkey: ScriptBuf::new(), - value: 2000, + value: Amount::from_sat(2000), }], }; let deposit3: Transaction = Transaction { - version: 1, + version: TxVersion::ONE, lock_time: absolute::LockTime::Blocks(absolute::Height::from_consensus(1).unwrap()), input: vec![TxIn { witness: Witness::new(), @@ -1885,12 +1892,12 @@ mod tests { }], output: vec![TxOut { script_pubkey: ScriptBuf::new(), - value: 3000, + value: Amount::from_sat(3000), }], }; let spend_tx: Transaction = Transaction { - version: 1, + version: TxVersion::ONE, lock_time: absolute::LockTime::Blocks(absolute::Height::from_consensus(1).unwrap()), input: vec![TxIn { witness: Witness::new(), @@ -1904,11 +1911,11 @@ mod tests { output: vec![ TxOut { script_pubkey: ScriptBuf::new(), - value: 4000, + value: Amount::from_sat(4000), }, TxOut { script_pubkey: ScriptBuf::new(), - value: 100_000_000 - 4000 - 1000, + value: Amount::from_sat(100_000_000 - 4000 - 1000), }, ], }; @@ -2072,7 +2079,7 @@ mod tests { ); let tx1: Transaction = Transaction { - version: 1, + version: TxVersion::ONE, lock_time: absolute::LockTime::Blocks(absolute::Height::from_consensus(1).unwrap()), input: vec![TxIn { witness: Witness::new(), @@ -2082,12 +2089,12 @@ mod tests { }], output: vec![TxOut { script_pubkey: ScriptBuf::new(), - value: 100_000_000, + value: Amount::from_sat(100_000_000), }], }; let tx2: Transaction = Transaction { - version: 1, + version: TxVersion::ONE, lock_time: absolute::LockTime::Blocks(absolute::Height::from_consensus(1).unwrap()), input: vec![TxIn { witness: Witness::new(), @@ -2097,12 +2104,12 @@ mod tests { }], output: vec![TxOut { script_pubkey: ScriptBuf::new(), - value: 2000, + value: Amount::from_sat(2000), }], }; let tx3: Transaction = Transaction { - version: 1, + version: TxVersion::ONE, lock_time: absolute::LockTime::Blocks(absolute::Height::from_consensus(1).unwrap()), input: vec![TxIn { witness: Witness::new(), @@ -2112,7 +2119,7 @@ mod tests { }], output: vec![TxOut { script_pubkey: ScriptBuf::new(), - value: 3000, + value: Amount::from_sat(3000), }], }; diff --git a/src/database/mod.rs b/src/database/mod.rs index 375d8ad0..9c2be7c6 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -20,7 +20,7 @@ use std::{ sync, }; -use miniscript::bitcoin::{self, bip32, psbt::PartiallySignedTransaction as Psbt, secp256k1}; +use miniscript::bitcoin::{self, bip32, psbt::Psbt, secp256k1}; pub trait DatabaseInterface: Send { fn connection(&self) -> Box; diff --git a/src/database/sqlite/mod.rs b/src/database/sqlite/mod.rs index b51b6a30..3654cc4b 100644 --- a/src/database/sqlite/mod.rs +++ b/src/database/sqlite/mod.rs @@ -39,7 +39,7 @@ use miniscript::bitcoin::{ self, bip32, consensus::encode, hashes::{sha256, Hash}, - psbt::PartiallySignedTransaction as Psbt, + psbt::Psbt, secp256k1, }; diff --git a/src/database/sqlite/schema.rs b/src/database/sqlite/schema.rs index 7ebb280b..6add975a 100644 --- a/src/database/sqlite/schema.rs +++ b/src/database/sqlite/schema.rs @@ -2,9 +2,7 @@ use crate::descriptors::LianaDescriptor; use std::{convert::TryFrom, str::FromStr}; -use miniscript::bitcoin::{ - self, address, bip32, consensus::encode, psbt::PartiallySignedTransaction as Psbt, -}; +use miniscript::bitcoin::{self, address, bip32, consensus::encode, psbt::Psbt}; pub const SCHEMA: &str = "\ CREATE TABLE version ( diff --git a/src/descriptors/analysis.rs b/src/descriptors/analysis.rs index b106a068..499a4d7e 100644 --- a/src/descriptors/analysis.rs +++ b/src/descriptors/analysis.rs @@ -72,7 +72,7 @@ fn is_single_key_or_multisig(policy: &SemanticPolicy, + keys_set: HashSet<(bip32::Xpub, descriptor::DerivPaths)>, } impl DescKeyChecker { @@ -347,7 +347,9 @@ impl PathInfo { PathInfo::Single(key) => ConcretePolicy::Key(key), PathInfo::Multi(thresh, keys) => ConcretePolicy::Threshold( thresh, - keys.into_iter().map(ConcretePolicy::Key).collect(), + keys.into_iter() + .map(|key| ConcretePolicy::Key(key).into()) + .collect(), ), } } @@ -531,9 +533,9 @@ impl LianaPolicy { .fold(primary_keys, |tl_policy, (timelock, path_info)| { let timelock = ConcretePolicy::Older(Sequence::from_height(timelock)); let keys = path_info.into_ms_policy(); - let recovery_branch = ConcretePolicy::And(vec![keys, timelock]); + let recovery_branch = ConcretePolicy::And(vec![keys.into(), timelock.into()]); // We assume the larger the timelock the less likely a branch would be used. - ConcretePolicy::Or(vec![(99, tl_policy), (1, recovery_branch)]) + ConcretePolicy::Or(vec![(99, tl_policy.into()), (1, recovery_branch.into())]) }); tl_policy diff --git a/src/descriptors/mod.rs b/src/descriptors/mod.rs index b822ac82..06f46b79 100644 --- a/src/descriptors/mod.rs +++ b/src/descriptors/mod.rs @@ -786,10 +786,10 @@ mod tests { // NOTE: The specific value is asserted because this was tested against a regtest // transaction. let stack = vec![vec![0; 65], vec![0; 0], vec![0; 33], vec![0; 72]]; - let witness_size = bitcoin::VarInt(stack.len() as u64).len() + let witness_size = bitcoin::VarInt(stack.len() as u64).size() + stack .iter() - .map(|item| bitcoin::VarInt(item.len() as u64).len() + item.len()) + .map(|item| bitcoin::VarInt(item.len() as u64).size() + item.len()) .sum::(); assert_eq!( desc.spender_input_size(), diff --git a/src/jsonrpc/api.rs b/src/jsonrpc/api.rs index 403563cf..f99ee9ef 100644 --- a/src/jsonrpc/api.rs +++ b/src/jsonrpc/api.rs @@ -10,7 +10,7 @@ use std::{ str::FromStr, }; -use miniscript::bitcoin::{self, psbt::PartiallySignedTransaction as Psbt}; +use miniscript::bitcoin::{self, psbt::Psbt}; fn create_spend(control: &DaemonControl, params: Params) -> Result { let destinations = params diff --git a/src/signer.rs b/src/signer.rs index 495a6bb5..e074e233 100644 --- a/src/signer.rs +++ b/src/signer.rs @@ -58,7 +58,7 @@ pub const MNEMONICS_FOLDER_NAME: &str = "mnemonics"; /// A signer that keeps the key on the laptop. Based on BIP39. pub struct HotSigner { mnemonic: bip39::Mnemonic, - master_xpriv: bip32::ExtendedPrivKey, + master_xpriv: bip32::Xpriv, } // TODO: instead of copying them here we could have a util module with those helpers. @@ -103,8 +103,8 @@ impl HotSigner { network: bitcoin::Network, mnemonic: bip39::Mnemonic, ) -> Result { - let master_xpriv = bip32::ExtendedPrivKey::new_master(network, &mnemonic.to_seed("")) - .map_err(SignerError::Bip32)?; + let master_xpriv = + bip32::Xpriv::new_master(network, &mnemonic.to_seed("")).map_err(SignerError::Bip32)?; Ok(Self { mnemonic, master_xpriv, @@ -212,7 +212,7 @@ impl HotSigner { &self, der_path: &bip32::DerivationPath, secp: &secp256k1::Secp256k1, - ) -> bip32::ExtendedPrivKey { + ) -> bip32::Xpriv { self.master_xpriv .derive_priv(secp, der_path) .expect("Never fails") @@ -223,9 +223,9 @@ impl HotSigner { &self, der_path: &bip32::DerivationPath, secp: &secp256k1::Secp256k1, - ) -> bip32::ExtendedPubKey { + ) -> bip32::Xpub { let xpriv = self.xpriv_at(der_path, secp); - bip32::ExtendedPubKey::from_priv(secp, &xpriv) + bip32::Xpub::from_priv(secp, &xpriv) } /// Sign all inputs of the given PSBT. @@ -254,9 +254,9 @@ impl HotSigner { .value; let sig_type = sighash::EcdsaSighashType::All; let sighash = sighash_cache - .segwit_signature_hash(i, witscript, value, sig_type) + .p2wsh_signature_hash(i, witscript, value, sig_type) .map_err(|_| SignerError::InsanePsbt)?; - let sighash = secp256k1::Message::from_slice(sighash.as_byte_array()) + let sighash = secp256k1::Message::from_digest_slice(sighash.as_byte_array()) .expect("Sighash is always 32 bytes."); // Then provide a signature for all the keys they asked for. @@ -297,7 +297,7 @@ mod tests { use super::*; use crate::{descriptors, testutils::*}; use miniscript::{ - bitcoin::{locktime::absolute, psbt::Input as PsbtIn}, + bitcoin::{locktime::absolute, psbt::Input as PsbtIn, Amount}, descriptor::{DerivPaths, DescriptorMultiXKey, DescriptorPublicKey, Wildcard}, }; use std::collections::{BTreeMap, HashSet}; @@ -429,7 +429,7 @@ mod tests { let spent_coin_desc = desc.receive_descriptor().derive(42.into(), &secp); let mut dummy_psbt = Psbt { unsigned_tx: bitcoin::Transaction { - version: 2, + version: bitcoin::transaction::Version::TWO, lock_time: absolute::LockTime::Blocks(absolute::Height::ZERO), input: vec![bitcoin::TxIn { sequence: bitcoin::Sequence::ENABLE_RBF_NO_LOCKTIME, @@ -440,12 +440,12 @@ mod tests { ..bitcoin::TxIn::default() }], output: vec![bitcoin::TxOut { - value: 18_420, + value: Amount::from_sat(18_420), script_pubkey: bitcoin::Address::from_str( "bc1qvklensptw5lk7d470ds60pcpsr0psdpgyvwepv", ) .unwrap() - .payload + .payload() .script_pubkey(), }], }, @@ -457,7 +457,7 @@ mod tests { witness_script: Some(spent_coin_desc.witness_script()), bip32_derivation: spent_coin_desc.bip32_derivations(), witness_utxo: Some(bitcoin::TxOut { - value: 19_000, + value: Amount::from_sat(19_000), script_pubkey: spent_coin_desc.script_pubkey(), }), ..PsbtIn::default() @@ -479,10 +479,7 @@ mod tests { // We can add another external output to the transaction, we can still sign without issue. // The output can be insane, we don't check it. It doesn't even need an accompanying PSBT // output. - dummy_psbt - .unsigned_tx - .output - .push(bitcoin::TxOut::default()); + dummy_psbt.unsigned_tx.output.push(bitcoin::TxOut::NULL); let psbt = dummy_psbt.clone(); assert!(psbt.inputs[0].partial_sigs.is_empty()); let psbt = prim_signer_a.sign_psbt(psbt, &secp).unwrap(); @@ -499,7 +496,7 @@ mod tests { witness_script: Some(other_spent_coin_desc.witness_script()), bip32_derivation: other_spent_coin_desc.bip32_derivations(), witness_utxo: Some(bitcoin::TxOut { - value: 19_000, + value: Amount::from_sat(19_000), script_pubkey: other_spent_coin_desc.script_pubkey(), }), ..PsbtIn::default() diff --git a/src/spend.rs b/src/spend.rs index 9a308521..091839f7 100644 --- a/src/spend.rs +++ b/src/spend.rs @@ -23,7 +23,7 @@ pub const DUST_OUTPUT_SATS: u64 = 5_000; pub const LONG_TERM_FEERATE_VB: f32 = 10.0; /// Assume that paying more than 1BTC in fee is a bug. -pub const MAX_FEE: u64 = bitcoin::blockdata::constants::COIN_VALUE; +pub const MAX_FEE: bitcoin::Amount = bitcoin::Amount::ONE_BTC; /// Assume that paying more than 1000sat/vb in feerate is a bug. pub const MAX_FEERATE: u64 = 1_000; @@ -53,7 +53,7 @@ impl fmt::Display for SpendCreationError { Self::InvalidOutputValue(amount) => write!(f, "Invalid output value '{}'.", amount), Self::InsaneFees(info) => write!( f, - "We assume transactions with a fee larger than {} sats or a feerate larger than {} sats/vb are a mistake. \ + "We assume transactions with a fee larger than {} or a feerate larger than {} sats/vb are a mistake. \ The created transaction {}.", MAX_FEE, MAX_FEERATE, @@ -81,10 +81,7 @@ impl std::error::Error for SpendCreationError {} // Sanity check the value of a transaction output. fn check_output_value(value: bitcoin::Amount) -> Result<(), SpendCreationError> { - // NOTE: the network parameter isn't used upstream - if value.to_sat() > bitcoin::blockdata::constants::MAX_MONEY - || value.to_sat() < DUST_OUTPUT_SATS - { + if value > bitcoin::Amount::MAX_MONEY || value.to_sat() < DUST_OUTPUT_SATS { Err(SpendCreationError::InvalidOutputValue(value)) } else { Ok(()) @@ -118,15 +115,16 @@ fn sanity_check_psbt( .witness_utxo .as_ref() .ok_or_else(|| SpendCreationError::SanityCheckFailure(psbt.clone()))? - .value; + .value + .to_sat(); } // Compute the output value and check the absolute fee isn't insane. - let value_out: u64 = tx.output.iter().map(|o| o.value).sum(); + let value_out: u64 = tx.output.iter().map(|o| o.value.to_sat()).sum(); let abs_fee = value_in .checked_sub(value_out) .ok_or(SpendCreationError::InsaneFees(InsaneFeeInfo::NegativeFee))?; - if abs_fee > MAX_FEE { + if abs_fee > MAX_FEE.to_sat() { return Err(SpendCreationError::InsaneFees(InsaneFeeInfo::TooHighFee( abs_fee, ))); @@ -147,7 +145,7 @@ fn sanity_check_psbt( // Check for dust outputs for txo in psbt.unsigned_tx.output.iter() { - if txo.value < txo.script_pubkey.dust_value().to_sat() { + if txo.value < txo.script_pubkey.dust_value() { return Err(SpendCreationError::SanityCheckFailure(psbt.clone())); } } @@ -257,16 +255,25 @@ fn select_coins_for_spend( max_sat_weight: u32, must_have_change: bool, ) -> Result<(Vec, bitcoin::Amount), InsufficientFunds> { - let out_value_nochange = base_tx.output.iter().map(|o| o.value).sum(); + let out_value_nochange = base_tx.output.iter().map(|o| o.value.to_sat()).sum(); // Create the coin selector from the given candidates. NOTE: the coin selector keeps track // of the original ordering of candidates so we can select any mandatory candidates using their // original indices. - let base_weight: u32 = base_tx + let mut base_weight: u32 = base_tx .weight() .to_wu() .try_into() .expect("Transaction weight must fit in u32"); + // Starting with version 0.31, rust-bitcoin now accounts for the segwit marker when serializing + // transactions with no input. But BDK's coin selector does add the segwit marker cost to the + // transaction size upon selecting the first segwit coin. To avoid accounting twice for it, + // drop it from the base weight (but only when it was added). + // NOTE: make sure to reconsider this when updating rust-bitcoin!! Behaviour may change again + // who knows. + if base_tx.input.is_empty() { + base_weight = base_weight.saturating_sub(2); + } let max_input_weight = TXIN_BASE_WEIGHT + max_sat_weight; let candidates: Vec = candidate_coins .iter() @@ -293,12 +300,15 @@ fn select_coins_for_spend( let long_term_feerate = FeeRate::from_sat_per_vb(LONG_TERM_FEERATE_VB); let drain_weights = DrainWeights { output_weight: { + // We don't reuse the above base_weight.since 2 WU may have been substracted from it. + // See comment above for details. + let nochange_weight = base_tx.weight().to_wu(); let mut tx_with_change = base_tx; tx_with_change.output.push(change_txo); tx_with_change .weight() .to_wu() - .checked_sub(base_weight.into()) + .checked_sub(nochange_weight) .expect("base_weight can't be larger") .try_into() .expect("tx size must always fit in u32") @@ -481,7 +491,7 @@ pub fn create_spend( // Create transaction with no inputs and no outputs. let mut tx = bitcoin::Transaction { - version: 2, + version: bitcoin::transaction::Version::TWO, lock_time: LockTime::Blocks(Height::ZERO), // TODO: randomized anti fee sniping input: Vec::with_capacity(candidate_coins.iter().filter(|c| c.must_select).count()), output: Vec::with_capacity(destinations.len()), @@ -493,7 +503,7 @@ pub fn create_spend( check_output_value(*amount)?; tx.output.push(bitcoin::TxOut { - value: amount.to_sat(), + value: *amount, script_pubkey: address.addr.script_pubkey(), }); // If it's an address of ours, signal it as change to signing devices by adding the @@ -520,7 +530,7 @@ pub fn create_spend( // We need to get the size of a potential change output to select coins / determine whether // we should include one, so get the change address and create a dummy txo for this purpose. let mut change_txo = bitcoin::TxOut { - value: std::u64::MAX, + value: bitcoin::Amount::MAX, script_pubkey: change_addr.addr.script_pubkey(), }; // Now select the coins necessary using the provided candidates and determine whether @@ -575,7 +585,7 @@ pub fn create_spend( }; // TODO: shuffle once we have Taproot - change_txo.value = change_amount.to_sat(); + change_txo.value = change_amount; tx.output.push(change_txo); psbt_outs.push(PsbtOut { bip32_derivation, @@ -600,7 +610,7 @@ pub fn create_spend( let coin_desc = derived_desc(secp, main_descriptor, cand); let witness_script = Some(coin_desc.witness_script()); let witness_utxo = Some(bitcoin::TxOut { - value: cand.amount.to_sat(), + value: cand.amount, script_pubkey: coin_desc.script_pubkey(), }); let non_witness_utxo = tx_getter.get_tx(&cand.outpoint.txid); diff --git a/src/testutils.rs b/src/testutils.rs index 3bd663b0..c175c156 100644 --- a/src/testutils.rs +++ b/src/testutils.rs @@ -13,9 +13,7 @@ use std::{ }; use miniscript::{ - bitcoin::{ - self, bip32, psbt::PartiallySignedTransaction as Psbt, secp256k1, Transaction, Txid, - }, + bitcoin::{self, bip32, psbt::Psbt, secp256k1, Transaction, Txid}, descriptor, }; From 4949632fe6510151df9281b55a049169842ee5ef Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Thu, 4 Jan 2024 14:34:40 +0100 Subject: [PATCH 6/7] bitcoin: remove unused import --- src/bitcoin/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bitcoin/mod.rs b/src/bitcoin/mod.rs index 4ac4680d..60388c1e 100644 --- a/src/bitcoin/mod.rs +++ b/src/bitcoin/mod.rs @@ -9,7 +9,7 @@ use crate::{ bitcoin::d::{BitcoindError, CachedTxGetter, LSBlockEntry}, descriptors, }; -pub use d::{MempoolEntry, MempoolEntryFees, SyncProgress}; +pub use d::{MempoolEntry, SyncProgress}; use std::{fmt, sync}; From 0e99136404fcbbdee09eef4b116f17222cb2dee0 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Thu, 4 Jan 2024 14:40:15 +0100 Subject: [PATCH 7/7] Clippification Bump clippy in CI to latest stable. --- .github/workflows/main.yml | 2 +- src/commands/mod.rs | 3 +-- src/database/sqlite/mod.rs | 30 +++++++++++++++--------------- src/descriptors/analysis.rs | 2 +- src/spend.rs | 3 +-- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4689a540..f8e9c971 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,7 +9,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.70.0 + toolchain: 1.75.0 components: rustfmt, clippy override: true - name: rustfmt diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 83d8ec2c..9eb22449 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -24,7 +24,6 @@ use utils::{ use std::{ collections::{hash_map, HashMap, HashSet}, - convert::TryInto, fmt, sync, }; @@ -961,7 +960,7 @@ impl DaemonControl { let current_height = self.bitcoin.chain_tip().height; let timelock = timelock.unwrap_or_else(|| self.config.main_descriptor.first_timelock_value()); - let height_delta: i32 = timelock.try_into().expect("Must fit, it's a u16"); + let height_delta: i32 = timelock.into(); let sweepable_coins: Vec<_> = db_conn .coins(&[CoinStatus::Confirmed], &[]) .into_values() diff --git a/src/database/sqlite/mod.rs b/src/database/sqlite/mod.rs index 3654cc4b..0433c42e 100644 --- a/src/database/sqlite/mod.rs +++ b/src/database/sqlite/mod.rs @@ -973,7 +973,7 @@ CREATE TABLE spend_transactions ( }; conn.new_unspent_coins(&[coin_a]); // We can query by status and/or outpoint. - assert!(vec![ + assert!([ conn.coins(&[], &[]), conn.coins(&[CoinStatus::Unconfirmed], &[]), conn.coins(&[CoinStatus::Unconfirmed], &[outpoint_a]), @@ -1022,7 +1022,7 @@ CREATE TABLE spend_transactions ( }; conn.new_unspent_coins(&[coin_b]); // Both coins are unconfirmed. - assert!(vec![ + assert!([ conn.coins(&[], &[]), conn.coins(&[CoinStatus::Unconfirmed], &[]), conn.coins(&[CoinStatus::Unconfirmed], &[outpoint_a, outpoint_b]), @@ -1034,7 +1034,7 @@ CREATE TABLE spend_transactions ( && c[0].outpoint == coin_a.outpoint && c[1].outpoint == coin_b.outpoint)); // We can filter for just the first coin. - assert!(vec![ + assert!([ conn.coins(&[CoinStatus::Unconfirmed], &[outpoint_a]), conn.coins(&[], &[outpoint_a]), conn.db_coins(&[outpoint_a]) @@ -1042,7 +1042,7 @@ CREATE TABLE spend_transactions ( .iter() .all(|res| res.len() == 1 && res[0].outpoint == coin_a.outpoint)); // Or we can filter for just the second coin. - assert!(vec![ + assert!([ conn.coins(&[CoinStatus::Unconfirmed], &[outpoint_b]), conn.coins(&[], &[outpoint_b]), conn.db_coins(&[outpoint_b]) @@ -1062,7 +1062,7 @@ CREATE TABLE spend_transactions ( .is_empty()); // Now if we confirm one, it'll be marked as such. conn.confirm_coins(&[(coin_a.outpoint, 174500, 174500)]); - assert!(vec![ + assert!([ conn.coins(&[CoinStatus::Confirmed], &[]), conn.coins(&[CoinStatus::Confirmed], &[outpoint_a]), conn.coins(&[], &[outpoint_a]), @@ -1071,7 +1071,7 @@ CREATE TABLE spend_transactions ( .iter() .all(|res| res.len() == 1 && res[0].outpoint == coin_a.outpoint)); // We can get both confirmed and unconfirmed. - assert!(vec![ + assert!([ conn.coins(&[], &[]), conn.coins(&[CoinStatus::Unconfirmed, CoinStatus::Confirmed], &[]), conn.coins( @@ -1091,7 +1091,7 @@ CREATE TABLE spend_transactions ( coin_a.outpoint, bitcoin::Txid::from_slice(&[0; 32][..]).unwrap(), )]); - assert!(vec![ + assert!([ conn.coins(&[CoinStatus::Spending], &[]), conn.coins(&[CoinStatus::Spending], &[outpoint_a]), conn.coins(&[], &[outpoint_a]), @@ -1101,7 +1101,7 @@ CREATE TABLE spend_transactions ( .iter() .all(|res| res.len() == 1 && res[0].outpoint == coin_a.outpoint)); // The second coin is still unconfirmed. - assert!(vec![ + assert!([ conn.coins(&[CoinStatus::Unconfirmed], &[]), conn.coins(&[CoinStatus::Unconfirmed], &[outpoint_b]), conn.coins(&[], &[outpoint_b]), @@ -1118,7 +1118,7 @@ CREATE TABLE spend_transactions ( 3_000_000, )]); // The coin no longer has spending status. - assert!(vec![ + assert!([ conn.coins(&[CoinStatus::Spending], &[]), conn.coins(&[CoinStatus::Spending], &[outpoint_a]), conn.list_spending_coins(), @@ -1127,7 +1127,7 @@ CREATE TABLE spend_transactions ( .all(|res| res.is_empty())); // Both coins are still in DB. - assert!(vec![ + assert!([ conn.coins(&[], &[]), conn.coins(&[CoinStatus::Unconfirmed, CoinStatus::Spent], &[]), conn.coins( @@ -1174,7 +1174,7 @@ CREATE TABLE spend_transactions ( conn.new_unspent_coins(&[coin_c, coin_d]); // We can get all three unconfirmed coins with different status/outpoint filters. - assert!(vec![ + assert!([ conn.coins(&[CoinStatus::Unconfirmed], &[]), conn.coins( &[CoinStatus::Unconfirmed], @@ -1190,7 +1190,7 @@ CREATE TABLE spend_transactions ( && coin[2].outpoint == coin_d.outpoint)); // We can also get two of the three unconfirmed coins by filtering for their outpoints. - assert!(vec![ + assert!([ conn.coins(&[CoinStatus::Unconfirmed], &[outpoint_b, outpoint_c]), conn.coins(&[], &[outpoint_b, outpoint_c]), conn.db_coins(&[outpoint_b, outpoint_c]), @@ -1206,7 +1206,7 @@ CREATE TABLE spend_transactions ( bitcoin::Txid::from_slice(&[1; 32][..]).unwrap(), )]); // The coin shows as spending. - assert!(vec![ + assert!([ conn.coins(&[CoinStatus::Spending], &[]), conn.coins(&[CoinStatus::Spending], &[outpoint_b]), conn.coins(&[], &[outpoint_b]), @@ -1220,7 +1220,7 @@ CREATE TABLE spend_transactions ( conn.confirm_coins(&[(coin_c.outpoint, 175500, 175500)]); // We now only have one unconfirmed coin. - assert!(vec![ + assert!([ conn.coins(&[CoinStatus::Unconfirmed], &[]), conn.coins( &[CoinStatus::Unconfirmed], @@ -1233,7 +1233,7 @@ CREATE TABLE spend_transactions ( .all(|c| c.len() == 1 && c[0].outpoint == coin_d.outpoint)); // There is now one coin for each status. - assert!(vec![ + assert!([ conn.coins(&[CoinStatus::Unconfirmed], &[]), conn.coins(&[CoinStatus::Unconfirmed], &[outpoint_d]), conn.coins(&[CoinStatus::Confirmed], &[]), diff --git a/src/descriptors/analysis.rs b/src/descriptors/analysis.rs index 499a4d7e..e840002d 100644 --- a/src/descriptors/analysis.rs +++ b/src/descriptors/analysis.rs @@ -109,7 +109,7 @@ impl DescKeyChecker { // without origin entirely. if let Some(ref origin) = xpub.origin { let der_paths = xpub.derivation_paths.paths(); - let first_der_path = der_paths.get(0).expect("Cannot be empty"); + let first_der_path = der_paths.first().expect("Cannot be empty"); // We also rule out xpubs with hardened derivation steps (non-normalized xpubs). let valid = xpub.wildcard == descriptor::Wildcard::Unhardened && der_paths.len() == 2 diff --git a/src/spend.rs b/src/spend.rs index 091839f7..c139271f 100644 --- a/src/spend.rs +++ b/src/spend.rs @@ -547,8 +547,7 @@ pub fn create_spend( })?; fr } - .try_into() - .expect("u16 must fit in f32"); + .into(); let max_sat_wu = main_descriptor .max_sat_weight() .try_into()