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:
commit
d8a5e1d780
4
.github/workflows/main.yml
vendored
4
.github/workflows/main.yml
vendored
@ -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
|
||||
|
||||
@ -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
314
Cargo.lock
generated
@ -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",
|
||||
]
|
||||
|
||||
@ -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 }
|
||||
|
||||
@ -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", ¶ms!(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",
|
||||
¶ms!(
|
||||
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", ¶ms!(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",
|
||||
¶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))) => {
|
||||
@ -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", ¶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())
|
||||
@ -818,7 +823,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
|
||||
@ -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",
|
||||
¶ms!(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",
|
||||
¶ms!(
|
||||
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",
|
||||
¶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,
|
||||
@ -872,7 +877,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")
|
||||
@ -887,7 +892,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
|
||||
@ -922,7 +927,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
|
||||
@ -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",
|
||||
¶ms!(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",
|
||||
¶ms!(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",
|
||||
¶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
|
||||
@ -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", ¶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 {
|
||||
@ -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", ¶ms!(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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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};
|
||||
|
||||
|
||||
@ -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),
|
||||
}],
|
||||
};
|
||||
|
||||
|
||||
@ -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>;
|
||||
|
||||
@ -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], &[]),
|
||||
|
||||
@ -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 (
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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()
|
||||
|
||||
49
src/spend.rs
49
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<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);
|
||||
|
||||
@ -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,
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user