Merge #906: Bump MSRV, upgrade dependencies and clippification

0e99136404fcbbdee09eef4b116f17222cb2dee0 Clippification (Antoine Poinsot)
4949632fe6510151df9281b55a049169842ee5ef bitcoin: remove unused import (Antoine Poinsot)
ce026a62e6bf064cea249f391e4ab870f1cbcb61 Update rust-bitcoin and rust-miniscript (Antoine Poinsot)
2bce4c525d51b8ecbc923a43632ef8a724426453 Cargo: bump jsonrpc version to 0.17 (Antoine Poinsot)
65c9e389bb89197c2e9066b82789cec63b18d2d1 Cargo: bump rusqlite to 0.30 (Antoine Poinsot)
84e8a2ae8630789f5b8cc3796e0f1e4ff87614f2 Cargo.lock: update minor dependencies after MSRV bump (Antoine Poinsot)
92328fb8f6e34a383e876a79fad3fee4110c09a5 Bump MSRV for lianad to 1.63 (Antoine Poinsot)

Pull request description:

  New years' cleanup!

  Our MSRV was becoming too restrictive to keep being able to benefit from the latest releases of our dependencies. Strike a better balance between not requiring a recklessly new compiler and still being able to get upstream bug fixes.

  From this update most of our dependencies to their latest point releases. Then upgrade rusqlite, jsonrpc and rust-[bitcoin, miniscript] to their latest major version. Note their is a ton of updates. I've done a minimal due diligence to check what was updated, to what version, what changed, but i can't realistically audit all the code changes this is effectively pulling. I think we need to look into `cargo-crev`.

  Take the opportunity to apply some clippy cleanups, and bump the version we're using in CI.

  See commit messages for details.

ACKs for top commit:
  darosior:
    reACK 0e99136404fcbbdee09eef4b116f17222cb2dee0 -- re-applying jp1ac4's ACK after addressing review

Tree-SHA512: f7940a90065fdf2e9c2013a882955f8f8febe537f8268224a321ae2df2e380c5a34c8c99891b25aa3ee14efe9c5eaaa7ee3ffa6ea163a749cec044db351dd408
This commit is contained in:
Antoine Poinsot 2024-01-11 10:48:22 +01:00
commit d8a5e1d780
No known key found for this signature in database
GPG Key ID: E13FC145CD3F4304
16 changed files with 361 additions and 263 deletions

View File

@ -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
@ -22,7 +22,7 @@ jobs:
strategy:
matrix:
toolchain:
- 1.54
- 1.63
- nightly
os:
- ubuntu-latest

View File

@ -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)

314
Cargo.lock generated
View File

@ -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,20 +19,27 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
version = "0.7.6"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
dependencies = [
"getrandom",
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "backtrace"
version = "0.3.67"
name = "allocator-api2"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca"
checksum = "544a7f66f3407c6ed1285525418393891e0f31c2078a2d46aefb44ecef09b1b3"
[[package]]
name = "backtrace"
version = "0.3.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12"
dependencies = [
"addr2line",
"cc",
@ -49,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"
@ -57,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"
@ -74,19 +87,29 @@ dependencies = [
[[package]]
name = "bitcoin"
version = "0.30.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b36f4c848f6bd9ff208128f08751135846cc23ae57d66ab10a22efff1c675f3c"
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"
@ -106,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",
]
@ -116,10 +149,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,20 +180,21 @@ 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",
]
[[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"
@ -170,9 +213,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",
@ -187,22 +230,29 @@ 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",
]
[[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"
@ -211,17 +261,17 @@ 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"
version = "0.16.0"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34efde8d2422fb79ed56db1d3aea8fa5b583351d15a26770cdee2f88813dd702"
checksum = "a26d9104d516092f092d97448787505881fdb6518293b2d6500bf9c180c839dd"
dependencies = [
"base64",
"base64 0.13.1",
"minreq",
"serde",
"serde_json",
@ -250,15 +300,26 @@ 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"
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",
@ -267,44 +328,42 @@ 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"
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",
]
[[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 +372,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,65 +426,64 @@ 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",
]
[[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",
"bitflags 2.4.1",
"fallible-iterator",
"fallible-streaming-iterator",
"hashlink",
"libsqlite3-sys",
"memchr",
"smallvec",
]
[[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"
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",
@ -428,27 +492,27 @@ 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",
]
[[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 +521,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 +532,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 +549,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 +593,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 +626,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 +650,62 @@ 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"
[[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",
]

View File

@ -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" }
@ -50,10 +50,10 @@ 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 }
jsonrpc = { version = "0.17", features = ["minreq_http"], default-features = false }
# Used for daemonization
libc = { version = "0.2", optional = true }

View File

@ -220,11 +220,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,
)*
]
])))
};
}
@ -319,7 +320,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));
@ -395,7 +396,7 @@ impl BitcoinD {
&self,
client: &Client,
method: &str,
params: &[Box<serde_json::value::RawValue>],
params: Option<&serde_json::value::RawValue>,
retry: bool,
) -> Result<Json, BitcoindError> {
let req = client.build_request(method, params);
@ -410,7 +411,7 @@ impl BitcoinD {
&self,
client: &Client,
method: &str,
params: &[Box<serde_json::value::RawValue>],
params: Option<&serde_json::value::RawValue>,
) -> Result<Json, BitcoindError> {
self.make_request_inner(client, method, params, true)
}
@ -420,7 +421,7 @@ impl BitcoinD {
fn make_noreply_request(
&self,
method: &str,
params: &[Box<serde_json::value::RawValue>],
params: Option<&serde_json::value::RawValue>,
) -> Result<(), BitcoindError> {
match self.make_request_inner(&self.sendonly_client, method, params, false) {
Ok(_) => Ok(()),
@ -438,12 +439,16 @@ impl BitcoinD {
fn make_fallible_node_request(
&self,
method: &str,
params: &[Box<serde_json::value::RawValue>],
params: Option<&serde_json::value::RawValue>,
) -> Result<Json, BitcoindError> {
self.make_request(&self.node_client, method, params)
}
fn make_node_request(&self, method: &str, params: &[Box<serde_json::value::RawValue>]) -> 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")
}
@ -451,7 +456,7 @@ impl BitcoinD {
fn make_wallet_request(
&self,
method: &str,
params: &[Box<serde_json::value::RawValue>],
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")
@ -460,20 +465,20 @@ impl BitcoinD {
fn make_faillible_wallet_request(
&self,
method: &str,
params: &[Box<serde_json::value::RawValue>],
params: Option<&serde_json::value::RawValue>,
) -> Result<Json, BitcoindError> {
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?")
@ -481,7 +486,7 @@ impl BitcoinD {
}
fn list_wallets(&self) -> Vec<String> {
self.make_node_request("listwallets", &[])
self.make_node_request("listwallets", None)
.as_array()
.expect("API break, 'listwallets' didn't return an array.")
.iter()
@ -524,7 +529,7 @@ impl BitcoinD {
}
fn unload_wallet(&self, wallet_path: String) -> Option<String> {
let res = self.make_node_request("unloadwallet", &params!(Json::String(wallet_path),));
let res = self.make_node_request("unloadwallet", params!(Json::String(wallet_path),));
self.warning_from_res(&res)
}
@ -534,7 +539,7 @@ impl BitcoinD {
let res = self
.make_fallible_node_request(
"createwallet",
&params!(
params!(
Json::String(wallet_path),
Json::Bool(true), // watchonly
Json::Bool(true), // blank
@ -569,7 +574,7 @@ impl BitcoinD {
})
.collect();
let res = self.make_wallet_request("importdescriptors", &params!(Json::Array(descriptors)));
let res = self.make_wallet_request("importdescriptors", params!(Json::Array(descriptors)));
let all_succeeded = res
.as_array()
.map(|results| {
@ -586,7 +591,7 @@ impl BitcoinD {
}
fn list_descriptors(&self) -> Vec<ListDescEntry> {
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")
@ -667,7 +672,7 @@ impl BitcoinD {
}
let res = self.make_fallible_node_request(
"loadwallet",
&params!(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))) => {
@ -760,7 +765,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 {
@ -807,7 +812,7 @@ impl BitcoinD {
pub fn get_block_hash(&self, height: i32) -> Option<bitcoin::BlockHash> {
Some(
self.make_fallible_node_request("getblockhash", &params!(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())
@ -818,7 +823,7 @@ impl BitcoinD {
pub fn list_since_block(&self, block_hash: &bitcoin::BlockHash) -> LSBlockRes {
self.make_wallet_request(
"listsinceblock",
&params!(
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
@ -833,7 +838,7 @@ impl BitcoinD {
// TODO: Maybe assert we got a -5 error, and not any other kind of error?
self.make_faillible_wallet_request(
"gettransaction",
&params!(Json::String(txid.to_string())),
params!(Json::String(txid.to_string())),
)
.ok()
.map(|res| res.into())
@ -844,7 +849,7 @@ impl BitcoinD {
// The result of gettxout is empty if the outpoint is spent.
self.make_node_request(
"gettxout",
&params!(
params!(
Json::String(op.txid.to_string()),
Json::Number(op.vout.into())
),
@ -864,7 +869,7 @@ impl BitcoinD {
// unconfirmed, just use the tip.
let req = self.make_wallet_request(
"gettransaction",
&params!(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,
@ -872,7 +877,7 @@ impl BitcoinD {
};
let block_hash = if let Ok(res) = self.make_fallible_node_request(
"getblockhash",
&params!(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")
@ -887,7 +892,7 @@ impl BitcoinD {
// TODO: merge this with the existing list_since_block method.
let lsb_res = self.make_wallet_request(
"listsinceblock",
&params!(
params!(
Json::String(block_hash),
Json::Number(1.into()), // Default for min_confirmations for the returned
Json::Bool(true), // Whether to include watchonly
@ -922,7 +927,7 @@ impl BitcoinD {
let gettx_res = self.make_wallet_request(
"gettransaction",
&params!(
params!(
Json::String(spending_txid.to_string()),
Json::Bool(true), // watchonly
Json::Bool(true) // verbose
@ -975,7 +980,7 @@ impl BitcoinD {
pub fn get_block_stats(&self, blockhash: bitcoin::BlockHash) -> Option<BlockStats> {
let res = match self.make_fallible_node_request(
"getblockheader",
&params!(Json::String(blockhash.to_string()),),
params!(Json::String(blockhash.to_string()),),
) {
Ok(res) => res,
Err(e) => {
@ -1023,7 +1028,7 @@ impl BitcoinD {
pub fn broadcast_tx(&self, tx: &bitcoin::Transaction) -> Result<(), BitcoindError> {
self.make_fallible_node_request(
"sendrawtransaction",
&params!(bitcoin::consensus::encode::serialize_hex(tx)),
params!(bitcoin::consensus::encode::serialize_hex(tx).into()),
)?;
Ok(())
}
@ -1118,10 +1123,9 @@ impl BitcoinD {
const NUM_RETRIES: usize = 10;
let mut i = 0;
loop {
if let Err(e) = self.make_noreply_request(
"importdescriptors",
&params!(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
@ -1142,7 +1146,7 @@ impl BitcoinD {
/// Get the progress of the ongoing rescan, if there is any.
pub fn rescan_progress(&self) -> Option<f64> {
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)
@ -1169,7 +1173,7 @@ impl BitcoinD {
/// Returns `None` if it is not in the mempool.
pub fn mempool_entry(&self, txid: &bitcoin::Txid) -> Option<MempoolEntry> {
match self
.make_fallible_node_request("getmempoolentry", &params!(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 {
@ -1191,7 +1195,7 @@ impl BitcoinD {
.iter()
.map(|op| serde_json::json!({"txid": op.txid.to_string(), "vout": op.vout}))
.collect();
self.make_node_request("gettxspendingprevout", &params!(prevouts))
self.make_node_request("gettxspendingprevout", params!(prevouts))
.as_array()
.expect("Always returns an array")
.iter()
@ -1207,7 +1211,7 @@ impl BitcoinD {
/// Stop bitcoind.
pub fn stop(&self) {
self.make_node_request("stop", &[]);
self.make_node_request("stop", None);
}
}

View File

@ -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};

View File

@ -24,12 +24,11 @@ use utils::{
use std::{
collections::{hash_map, HashMap, HashSet},
convert::TryInto,
fmt, sync,
};
use miniscript::{
bitcoin::{self, address, bip32, psbt::PartiallySignedTransaction as Psbt},
bitcoin::{self, address, bip32, psbt::Psbt},
psbt::PsbtExt,
};
use serde::{Deserialize, Serialize};
@ -609,7 +608,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 +729,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),
)
})
@ -960,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()
@ -1138,9 +1138,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 +1300,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 +1371,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 +1420,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<bitcoin::Address<address::NetworkUnchecked>, u64> =
[(invalid_addr, dummy_value)].iter().cloned().collect();
assert!(matches!(
@ -1436,9 +1442,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 +1561,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 +1654,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 +1776,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 +1851,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 +1861,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 +1876,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 +1891,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 +1910,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 +2078,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 +2088,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 +2103,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 +2118,7 @@ mod tests {
}],
output: vec![TxOut {
script_pubkey: ScriptBuf::new(),
value: 3000,
value: Amount::from_sat(3000),
}],
};

View File

@ -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<dyn DatabaseConnection>;

View File

@ -39,7 +39,7 @@ use miniscript::bitcoin::{
self, bip32,
consensus::encode,
hashes::{sha256, Hash},
psbt::PartiallySignedTransaction as Psbt,
psbt::Psbt,
secp256k1,
};
@ -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], &[]),

View File

@ -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 (

View File

@ -72,7 +72,7 @@ fn is_single_key_or_multisig(policy: &SemanticPolicy<descriptor::DescriptorPubli
}
struct DescKeyChecker {
keys_set: HashSet<(bip32::ExtendedPubKey, descriptor::DerivPaths)>,
keys_set: HashSet<(bip32::Xpub, descriptor::DerivPaths)>,
}
impl DescKeyChecker {
@ -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
@ -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

View File

@ -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::<usize>();
assert_eq!(
desc.spender_input_size(),

View File

@ -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<serde_json::Value, Error> {
let destinations = params

View File

@ -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<Self, SignerError> {
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<impl secp256k1::Signing>,
) -> 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<impl secp256k1::Signing>,
) -> 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()

View File

@ -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<CandidateCoin>, 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> = 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
@ -537,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()
@ -575,7 +584,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 +609,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);

View File

@ -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,
};