From e7f44a67e3d011cba802056afdaae6ce57a65d9c Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Fri, 4 Jul 2025 16:44:05 +0000 Subject: [PATCH 01/11] use lockfile rather than ad-hoc `cargo update` calls to pin dependencies Aside from not being future-proof at all, it's actually extremely hard to pin dependencies for this version of the library to get ones that work with 9.x. We have an ancient version of `bitcoind` in our deps, which in turn unconditionally depends on several crates which all have bad behavior (at least, the versions that we depend on). For example, both `zip` many versions and `bitcoind` itself have maximum `flate2` versions which are incompatible with each other. The latest version of `zip` 0.5.x removes the max version, but has an incorrectly stated minimum version of `thiserror`, which manifests in compilation errors because some trait impls aren't created by the `thiserror` macro. (And of course, you can't just use the latest `thiserror` because that does not compile with 1.41.1 for many reasons.) This is just one example. There are probably 10 such cases. Anyway now we have a lockfile and we can just forget about all this crap forever. As a secondary change: change all the `deny`s in lib.rs, except the one about unsafe code which seems likely to be future-proof, to `warn`s. The library doesn't compile on nightly otherwise, since e.g. the definition of `dead_code` has expanded. On my system I can now compile the library with both 1.41.1 and nightly 2025-06-23, with the same lockfile. --- Cargo-recent.lock | 1036 +++++++++++++++++++++++++++++++++++++++++++++ contrib/test.sh | 18 +- src/lib.rs | 14 +- 3 files changed, 1044 insertions(+), 24 deletions(-) create mode 100644 Cargo-recent.lock diff --git a/Cargo-recent.lock b/Cargo-recent.lock new file mode 100644 index 000000000..982b49459 --- /dev/null +++ b/Cargo-recent.lock @@ -0,0 +1,1036 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217" + +[[package]] +name = "ahash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efa60d2eadd8b12a996add391db32bd1153eac697ba4869660c0016353611426" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64-compat" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a8d4d2746f89841e49230dd26917df1876050f95abafafbe34f47cb534b88d7" +dependencies = [ + "byteorder", +] + +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "bitcoin" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" +dependencies = [ + "bech32", + "bitcoin_hashes", + "core2", + "hashbrown 0.8.2", + "secp256k1", + "serde", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" +dependencies = [ + "core2", + "serde", +] + +[[package]] +name = "bitcoincore-rpc" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0261b2bb7617e0c91b452a837bbd1291fd34ad6990cb8e3ffc28239cc045b5ca" +dependencies = [ + "bitcoincore-rpc-json", + "jsonrpc", + "log", + "serde", + "serde_json", +] + +[[package]] +name = "bitcoincore-rpc-json" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c231bea28e314879c5aef240f6052e8a72a369e3c9f9b20d9bfbb33ad18029b2" +dependencies = [ + "bitcoin", + "serde", + "serde_json", +] + +[[package]] +name = "bitcoind" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d0196050d8387a47ee50ff2bb0dff08e12b9199b79c717a5b9ccde0148dd691" +dependencies = [ + "bitcoin_hashes", + "bitcoincore-rpc", + "filetime 0.2.15", + "flate2", + "log", + "tar", + "tempfile", + "ureq", + "which", + "zip", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bzip2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "cc" +version = "1.0.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1770ced377336a88a67c473594ccc14eca6f4559217c34f64aac8f83d641b40" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chunked_transfer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" + +[[package]] +name = "const_fn" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f8a2ca5ac02d09563609681103aada9e1777d54fc57a5acd7a41404f9c93b6e" + +[[package]] +name = "cookie" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951" +dependencies = [ + "percent-encoding", + "time 0.2.27", + "version_check", +] + +[[package]] +name = "core2" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239fa3ae9b63c2dc74bd3fa852d4792b8b305ae64eeede946265b6af62f1fff3" +dependencies = [ + "memchr", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "discard" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" + +[[package]] +name = "either" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" + +[[package]] +name = "filetime" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714653f3e34871534de23771ac7b26e999651a0a228f47beb324dfdf1dd4b10f" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "redox_syscall 0.1.57", +] + +[[package]] +name = "filetime" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.2.16", + "winapi", +] + +[[package]] +name = "flate2" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +dependencies = [ + "cfg-if 1.0.0", + "crc32fast", + "libc", + "miniz_oxide", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "hashbrown" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25" +dependencies = [ + "ahash 0.3.8", + "autocfg", +] + +[[package]] +name = "hashbrown" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "362385356d610bd1e5a408ddf8d022041774b683f345a1d2cfcb4f60f8ae2db5" +dependencies = [ + "ahash 0.7.0", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "js-sys" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonrpc" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f8423b78fc94d12ef1a4a9d13c348c9a78766dda0cc18817adf0faf77e670c8" +dependencies = [ + "base64-compat", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" + +[[package]] +name = "log" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" +dependencies = [ + "cfg-if 0.1.10", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "memchr" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" + +[[package]] +name = "miniscript" +version = "9.2.0" +dependencies = [ + "bitcoin", + "bitcoind", + "hashbrown 0.11.0", + "rand", + "secp256k1", + "serde", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "ppv-lite86" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "qstring" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "quote" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5907a1b7c277254a8b15170f6e7c97cfa60ee7872a3217663bb81151e48184bb" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "rustls" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81" +dependencies = [ + "base64", + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "secp256k1" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" +dependencies = [ + "bitcoin_hashes", + "rand", + "secp256k1-sys", + "serde", +] + +[[package]] +name = "secp256k1-sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" +dependencies = [ + "cc", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.156" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "314b5b092c0ade17c00142951e50ced110ec27cea304b1037c6969246c2469a4" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.156" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7e29c4601e36bcec74a223228dce795f4cd3616341a4af93520ca1a837c087d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78a7a12c167809363ec3bd7329fc0a3369056996de43c4b37ef3cd54a6ce4867" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" +dependencies = [ + "sha1_smol", +] + +[[package]] +name = "sha1_smol" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "standback" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" +dependencies = [ + "version_check", +] + +[[package]] +name = "stdweb" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" +dependencies = [ + "discard", + "rustc_version", + "stdweb-derive", + "stdweb-internal-macros", + "stdweb-internal-runtime", + "wasm-bindgen", +] + +[[package]] +name = "stdweb-derive" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_derive", + "syn", +] + +[[package]] +name = "stdweb-internal-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" +dependencies = [ + "base-x", + "proc-macro2", + "quote", + "serde", + "serde_derive", + "serde_json", + "sha1", + "syn", +] + +[[package]] +name = "stdweb-internal-runtime" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tar" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1eb3bf6ec92843ca93f4fcfb5fc6dfe30534815b147885db4b5759b8e2ff7d52" +dependencies = [ + "filetime 0.1.15", + "libc", + "xattr", +] + +[[package]] +name = "tempfile" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "rand", + "redox_syscall 0.2.16", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "thiserror" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "205684fd018ca14432b12cce6ea3d46763311a571c3d294e71ba3f01adcf1aad" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e4d2e50ca050ed44fb58309bdce3efa79948f84f9993ad1978de5eebdce5a7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "time" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" +dependencies = [ + "const_fn", + "libc", + "standback", + "stdweb", + "time-macros", + "version_check", + "winapi", +] + +[[package]] +name = "time-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" +dependencies = [ + "proc-macro-hack", + "time-macros-impl", +] + +[[package]] +name = "time-macros-impl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "standback", + "syn", +] + +[[package]] +name = "tinyvec" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f331a553cacb14e99d183e5573c86044dd177b5a5277b21e562fd1bd5e1076e1" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "unicode-bidi" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2560b941fdb9ea38301b9b708504d612fcdf9c91a8c31d82219bd74cb07d304d" +dependencies = [ + "matches", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "ureq" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b770aa61edaa144d3af86a8b0ccbb1bf8ca9dd0c1ac2a17081f35943aae6eb82" +dependencies = [ + "base64", + "chunked_transfer", + "cookie", + "lazy_static", + "qstring", + "rustls", + "url", + "webpki", + "webpki-roots", +] + +[[package]] +name = "url" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ddaf52e65c6b81c56b7e957c0b1970f7937f21c5c6774c4e56fcb4e20b48c6" +dependencies = [ + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f" +dependencies = [ + "cfg-if 0.1.10", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639" + +[[package]] +name = "web-sys" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d6f51648d8c56c366144378a33290049eafdd784071077f6fe37dae64c1c4cb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f20dea7535251981a9670857150d571846545088359b28e4951d350bdaf179f" +dependencies = [ + "webpki", +] + +[[package]] +name = "which" +version = "4.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" +dependencies = [ + "either", + "lazy_static", + "libc", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "xattr" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f04de8a1346489a2f9e9bd8526b73d135ec554227b17568456e86aa35b6f3fc" +dependencies = [ + "libc", +] + +[[package]] +name = "zip" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" +dependencies = [ + "byteorder", + "bzip2", + "crc32fast", + "flate2", + "thiserror", + "time 0.1.45", +] diff --git a/contrib/test.sh b/contrib/test.sh index a1f213b49..90bb175e2 100755 --- a/contrib/test.sh +++ b/contrib/test.sh @@ -10,23 +10,7 @@ cargo update -p serde_derive --precise 1.0.142 cargo --version rustc --version -# Work out if we are using a nightly toolchain. -MSRV=false -if cargo --version | grep "1\.41\.0"; then - MSRV=true -fi - -if cargo --version | grep "1\.47\.0"; then - cargo update -p once_cell --precise 1.13.1 -fi - -# form_urlencoded 1.1.0 breaks MSRV. -if [ "$MSRV" = true ]; then - cargo update -p url --precise 2.2.2 - cargo update -p form_urlencoded --precise 1.0.1 - cargo update -p once_cell --precise 1.13.1 - cargo update -p syn --precise 1.0.107 -fi +cp Cargo-recent.lock Cargo.lock # Format if told to if [ "$DO_FMT" = true ] diff --git a/src/lib.rs b/src/lib.rs index 96bf0ae04..34445439b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -82,13 +82,13 @@ #![cfg_attr(all(test, feature = "unstable"), feature(test))] // Coding conventions #![deny(unsafe_code)] -#![deny(non_upper_case_globals)] -#![deny(non_camel_case_types)] -#![deny(non_snake_case)] -#![deny(unused_mut)] -#![deny(dead_code)] -#![deny(unused_imports)] -#![deny(missing_docs)] +#![warn(non_upper_case_globals)] +#![warn(non_camel_case_types)] +#![warn(non_snake_case)] +#![warn(unused_mut)] +#![warn(dead_code)] +#![warn(unused_imports)] +#![warn(missing_docs)] #[cfg(target_pointer_width = "16")] compile_error!( From ac1d9bbc28acd2fd2c9f365835b7e531fe825b0d Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Fri, 4 Jul 2025 16:44:05 +0000 Subject: [PATCH 02/11] ci: pin nightly compiler version --- .github/workflows/rust.yml | 20 +++++++++++++++++--- nightly-version | 1 + 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 nightly-version diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index eb3b0fd3d..900b7e08e 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -3,6 +3,17 @@ on: [push, pull_request] name: Continuous integration jobs: + Prepare: + runs-on: ubuntu-24.04 + outputs: + nightly_version: ${{ steps.read_toolchain.outputs.nightly_version }} + steps: + - name: "Checkout repo" + uses: actions/checkout@v4 + - name: "Read nightly version" + id: read_toolchain + run: echo "nightly_version=$(cat nightly-version)" >> $GITHUB_OUTPUT + Fuzz: name: Fuzz runs-on: ubuntu-latest @@ -29,6 +40,7 @@ jobs: Nightly: name: Nightly - Bench + Docs + Fmt + needs: Prepare runs-on: ubuntu-latest steps: - name: Checkout Crate @@ -37,7 +49,7 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly + toolchain: ${{ needs.Prepare.outputs.nightly_version }} override: true - name: Running benchmarks env: @@ -55,13 +67,14 @@ jobs: Tests: name: Tests + needs: Prepare runs-on: ubuntu-latest strategy: matrix: include: - rust: stable - rust: beta - - rust: nightly + - rust: ${{ needs.Prepare.outputs.nightly_version }} - rust: 1.41.1 - rust: 1.47 DO_NO_STD: true @@ -81,6 +94,7 @@ jobs: run: ./contrib/test.sh Embedded: + needs: Prepare runs-on: ubuntu-latest steps: - name: Checkout @@ -91,7 +105,7 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly + toolchain: ${{ needs.Prepare.outputs.nightly_version }} override: true components: rust-src target: thumbv7m-none-eabi diff --git a/nightly-version b/nightly-version new file mode 100644 index 000000000..b54e2edfc --- /dev/null +++ b/nightly-version @@ -0,0 +1 @@ +nightly-2025-06-20 From a17479a7aded4f2b21b622bb130dd14848a8843b Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Fri, 4 Jul 2025 17:28:48 +0000 Subject: [PATCH 03/11] test: delete bitcoind tests Sigh, after all the work I did to get a lockfile for the previous commit, it turns out that all the bitcoind tests were disabled anyway, with the explanation "breaking change in bitcoind". This commit deletes them entirely. We have no plans to fix them. If we ever want to regression test miniscript 9.x, we should do it externally by adding a fuzztest in master which pulls it in and tries to parse stuff. Then it will be actively exercised and maintained and not require ancient broken dependencies. This commit is all red EXCEPT a change to a test in src/miniscript/mod.rs. What's happening here is that we had one test (asserting on the string representation of errors from rust-bitcoin) which fails when the std feature is off. As it turns out, `bitcoind` unconditionally turns on that feature. So by having `bitcoind` as a dev-dependency it was impossible for us to ever test the nostd feature properly. Sigh. --- Cargo-recent.lock | 782 +-------------------------------- Cargo.toml | 1 - examples/psbt_sign_finalize.rs | 9 +- src/miniscript/mod.rs | 4 +- tests/setup/mod.rs | 20 - tests/setup/test_util.rs | 76 ---- tests/test_cpp.rs | 253 ----------- tests/test_desc.rs | 432 ------------------ 8 files changed, 10 insertions(+), 1567 deletions(-) delete mode 100644 tests/test_cpp.rs delete mode 100644 tests/test_desc.rs diff --git a/Cargo-recent.lock b/Cargo-recent.lock index 982b49459..8bf0f9f98 100644 --- a/Cargo-recent.lock +++ b/Cargo-recent.lock @@ -1,11 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "ahash" version = "0.3.8" @@ -29,27 +23,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" -[[package]] -name = "base-x" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" - -[[package]] -name = "base64" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" - -[[package]] -name = "base64-compat" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a8d4d2746f89841e49230dd26917df1876050f95abafafbe34f47cb534b88d7" -dependencies = [ - "byteorder", -] - [[package]] name = "bech32" version = "0.9.1" @@ -80,128 +53,18 @@ dependencies = [ "serde", ] -[[package]] -name = "bitcoincore-rpc" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0261b2bb7617e0c91b452a837bbd1291fd34ad6990cb8e3ffc28239cc045b5ca" -dependencies = [ - "bitcoincore-rpc-json", - "jsonrpc", - "log", - "serde", - "serde_json", -] - -[[package]] -name = "bitcoincore-rpc-json" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c231bea28e314879c5aef240f6052e8a72a369e3c9f9b20d9bfbb33ad18029b2" -dependencies = [ - "bitcoin", - "serde", - "serde_json", -] - -[[package]] -name = "bitcoind" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0196050d8387a47ee50ff2bb0dff08e12b9199b79c717a5b9ccde0148dd691" -dependencies = [ - "bitcoin_hashes", - "bitcoincore-rpc", - "filetime 0.2.15", - "flate2", - "log", - "tar", - "tempfile", - "ureq", - "which", - "zip", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bumpalo" -version = "3.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bzip2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0" -dependencies = [ - "bzip2-sys", - "libc", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.11+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - [[package]] name = "cc" version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1770ced377336a88a67c473594ccc14eca6f4559217c34f64aac8f83d641b40" -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chunked_transfer" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" - -[[package]] -name = "const_fn" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f8a2ca5ac02d09563609681103aada9e1777d54fc57a5acd7a41404f9c93b6e" - -[[package]] -name = "cookie" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951" -dependencies = [ - "percent-encoding", - "time 0.2.27", - "version_check", -] - [[package]] name = "core2" version = "0.3.3" @@ -211,71 +74,15 @@ dependencies = [ "memchr", ] -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - -[[package]] -name = "either" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" - -[[package]] -name = "filetime" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714653f3e34871534de23771ac7b26e999651a0a228f47beb324dfdf1dd4b10f" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "redox_syscall 0.1.57", -] - -[[package]] -name = "filetime" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "redox_syscall 0.2.16", - "winapi", -] - -[[package]] -name = "flate2" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" -dependencies = [ - "cfg-if 1.0.0", - "crc32fast", - "libc", - "miniz_oxide", -] - [[package]] name = "getrandom" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -297,71 +104,12 @@ dependencies = [ "ahash 0.7.0", ] -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "js-sys" -version = "0.3.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonrpc" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f8423b78fc94d12ef1a4a9d13c348c9a78766dda0cc18817adf0faf77e670c8" -dependencies = [ - "base64-compat", - "serde", - "serde_derive", - "serde_json", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "libc" version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" -[[package]] -name = "log" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" -dependencies = [ - "cfg-if 0.1.10", -] - -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - [[package]] name = "memchr" version = "2.4.0" @@ -373,53 +121,24 @@ name = "miniscript" version = "9.2.0" dependencies = [ "bitcoin", - "bitcoind", "hashbrown 0.11.0", "rand", "secp256k1", "serde", ] -[[package]] -name = "miniz_oxide" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" -dependencies = [ - "adler", - "autocfg", -] - [[package]] name = "once_cell" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - [[package]] name = "ppv-lite86" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - [[package]] name = "proc-macro2" version = "1.0.63" @@ -429,15 +148,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "qstring" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" -dependencies = [ - "percent-encoding", -] - [[package]] name = "quote" version = "1.0.30" @@ -477,83 +187,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags", -] - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", -] - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - -[[package]] -name = "rustls" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81" -dependencies = [ - "base64", - "log", - "ring", - "sct", - "webpki", -] - -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "secp256k1" version = "0.24.3" @@ -575,21 +208,6 @@ dependencies = [ "cc", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "serde" version = "1.0.156" @@ -610,96 +228,6 @@ dependencies = [ "syn", ] -[[package]] -name = "serde_json" -version = "1.0.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78a7a12c167809363ec3bd7329fc0a3369056996de43c4b37ef3cd54a6ce4867" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" -dependencies = [ - "sha1_smol", -] - -[[package]] -name = "sha1_smol" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "standback" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" -dependencies = [ - "version_check", -] - -[[package]] -name = "stdweb" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -dependencies = [ - "discard", - "rustc_version", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "serde_derive", - "syn", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" -dependencies = [ - "base-x", - "proc-macro2", - "quote", - "serde", - "serde_derive", - "serde_json", - "sha1", - "syn", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" - [[package]] name = "syn" version = "1.0.109" @@ -711,326 +239,20 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tar" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eb3bf6ec92843ca93f4fcfb5fc6dfe30534815b147885db4b5759b8e2ff7d52" -dependencies = [ - "filetime 0.1.15", - "libc", - "xattr", -] - -[[package]] -name = "tempfile" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "rand", - "redox_syscall 0.2.16", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "thiserror" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "205684fd018ca14432b12cce6ea3d46763311a571c3d294e71ba3f01adcf1aad" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e4d2e50ca050ed44fb58309bdce3efa79948f84f9993ad1978de5eebdce5a7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "time" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" -dependencies = [ - "const_fn", - "libc", - "standback", - "stdweb", - "time-macros", - "version_check", - "winapi", -] - -[[package]] -name = "time-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" -dependencies = [ - "proc-macro-hack", - "time-macros-impl", -] - -[[package]] -name = "time-macros-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" -dependencies = [ - "proc-macro-hack", - "proc-macro2", - "quote", - "standback", - "syn", -] - -[[package]] -name = "tinyvec" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f331a553cacb14e99d183e5573c86044dd177b5a5277b21e562fd1bd5e1076e1" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "unicode-bidi" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2560b941fdb9ea38301b9b708504d612fcdf9c91a8c31d82219bd74cb07d304d" -dependencies = [ - "matches", -] - [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" -[[package]] -name = "unicode-normalization" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "ureq" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b770aa61edaa144d3af86a8b0ccbb1bf8ca9dd0c1ac2a17081f35943aae6eb82" -dependencies = [ - "base64", - "chunked_transfer", - "cookie", - "lazy_static", - "qstring", - "rustls", - "url", - "webpki", - "webpki-roots", -] - -[[package]] -name = "url" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ddaf52e65c6b81c56b7e957c0b1970f7937f21c5c6774c4e56fcb4e20b48c6" -dependencies = [ - "idna", - "matches", - "percent-encoding", -] - [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f" -dependencies = [ - "cfg-if 0.1.10", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639" - -[[package]] -name = "web-sys" -version = "0.3.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d6f51648d8c56c366144378a33290049eafdd784071077f6fe37dae64c1c4cb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki-roots" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f20dea7535251981a9670857150d571846545088359b28e4951d350bdaf179f" -dependencies = [ - "webpki", -] - -[[package]] -name = "which" -version = "4.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" -dependencies = [ - "either", - "lazy_static", - "libc", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "xattr" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f04de8a1346489a2f9e9bd8526b73d135ec554227b17568456e86aa35b6f3fc" -dependencies = [ - "libc", -] - -[[package]] -name = "zip" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" -dependencies = [ - "byteorder", - "bzip2", - "crc32fast", - "flate2", - "thiserror", - "time 0.1.45", -] diff --git a/Cargo.toml b/Cargo.toml index 74bdc567a..3144010e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,6 @@ hashbrown = { version = "0.11", optional = true } actual-serde = { package = "serde", version = "1.0", optional = true } [dev-dependencies] -bitcoind = { version = "0.27.0", features=["23_0"] } actual-rand = { package = "rand", version = "0.8.4"} secp256k1 = {version = "0.24.0", features = ["rand-std"]} diff --git a/examples/psbt_sign_finalize.rs b/examples/psbt_sign_finalize.rs index 9876c92d6..735d310a0 100644 --- a/examples/psbt_sign_finalize.rs +++ b/examples/psbt_sign_finalize.rs @@ -4,8 +4,7 @@ use std::str::FromStr; use bitcoin::consensus::serialize; use bitcoin::util::sighash::SighashCache; use bitcoin::{PackedLockTime, PrivateKey}; -use bitcoind::bitcoincore_rpc::jsonrpc::base64; -use bitcoind::bitcoincore_rpc::RawTx; +use bitcoin::hashes::hex::ToHex as _; use miniscript::bitcoin::consensus::encode::deserialize; use miniscript::bitcoin::hashes::hex::FromHex; use miniscript::bitcoin::util::psbt; @@ -158,14 +157,18 @@ fn main() { println!("{:#?}", psbt); + /* + // In bitcoin 0.29.x there is no base64 encoding of PSBTs, so this line + // would require an entire extra dependency. let serialized = serialize(&psbt); println!("{}", base64::encode(&serialized)); + */ psbt.finalize_mut(&secp256k1).unwrap(); println!("{:#?}", psbt); let tx = psbt.extract_tx(); - println!("{}", tx.raw_hex()); + println!("{}", serialize(&tx).to_hex()); } // Find the Outpoint by spk diff --git a/src/miniscript/mod.rs b/src/miniscript/mod.rs index 8fb3d4988..c7a8c0fe8 100644 --- a/src/miniscript/mod.rs +++ b/src/miniscript/mod.rs @@ -996,8 +996,8 @@ mod tests { "pk(2788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99)" )); assert_eq!( - ms.unwrap_err().to_string(), - "unexpected «key hex decoding error»", + &ms.unwrap_err().to_string()[..35], + "unexpected «key hex decoding error", ); Tapscript::from_str_insane(&format!( "pk(2788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99)" diff --git a/tests/setup/mod.rs b/tests/setup/mod.rs index 6a7f27e37..e7d9e1f23 100644 --- a/tests/setup/mod.rs +++ b/tests/setup/mod.rs @@ -1,24 +1,4 @@ extern crate miniscript; -use bitcoind::bitcoincore_rpc::RpcApi; -use bitcoind::BitcoinD; -use miniscript::bitcoin; - pub mod test_util; -// Launch an instance of bitcoind with -pub fn setup() -> BitcoinD { - let exe_path = bitcoind::exe_path().unwrap(); - let bitcoind = bitcoind::BitcoinD::new(exe_path).unwrap(); - let cl = &bitcoind.client; - // generate to an address by the wallet. And wait for funds to mature - let addr = cl.get_new_address(None, None).unwrap(); - let blks = cl.generate_to_address(101, &addr).unwrap(); - assert_eq!(blks.len(), 101); - - assert_eq!( - cl.get_balance(Some(1) /*min conf*/, None).unwrap(), - bitcoin::Amount::from_sat(100_000_000 * 50) - ); - bitcoind -} diff --git a/tests/setup/test_util.rs b/tests/setup/test_util.rs index fc8e079e2..f091efdf8 100644 --- a/tests/setup/test_util.rs +++ b/tests/setup/test_util.rs @@ -22,7 +22,6 @@ use std::str::FromStr; use actual_rand as rand; use bitcoin::hashes::hex::ToHex; use bitcoin::hashes::{hash160, ripemd160, sha256, Hash}; -use bitcoin::secp256k1; use miniscript::descriptor::{SinglePub, SinglePubKey}; use miniscript::{ hash256, Descriptor, DescriptorPublicKey, Error, Miniscript, ScriptContext, TranslatePk, @@ -54,81 +53,6 @@ pub struct TestData { pub secretdata: SecretData, } -// Setup (sk, pk) pairs -fn setup_keys( - n: usize, -) -> ( - Vec, - Vec, - Vec, - Vec, -) { - let secp_sign = secp256k1::Secp256k1::signing_only(); - let mut sk = [0; 32]; - let mut sks = vec![]; - let mut pks = vec![]; - for i in 1..n + 1 { - sk[0] = i as u8; - sk[1] = (i >> 8) as u8; - sk[2] = (i >> 16) as u8; - - let sk = secp256k1::SecretKey::from_slice(&sk[..]).expect("secret key"); - let pk = miniscript::bitcoin::PublicKey { - inner: secp256k1::PublicKey::from_secret_key(&secp_sign, &sk), - compressed: true, - }; - pks.push(pk); - sks.push(sk); - } - - let mut x_only_keypairs = vec![]; - let mut x_only_pks = vec![]; - - for i in 0..n { - let keypair = bitcoin::KeyPair::from_secret_key(&secp_sign, &sks[i]); - let (xpk, _parity) = bitcoin::XOnlyPublicKey::from_keypair(&keypair); - x_only_keypairs.push(keypair); - x_only_pks.push(xpk); - } - (sks, pks, x_only_keypairs, x_only_pks) -} - -impl TestData { - // generate a fixed data for n keys - pub(crate) fn new_fixed_data(n: usize) -> Self { - let (sks, pks, x_only_keypairs, x_only_pks) = setup_keys(n); - let sha256_pre = [0x12 as u8; 32]; - let sha256 = sha256::Hash::hash(&sha256_pre); - let hash256_pre = [0x34 as u8; 32]; - let hash256 = hash256::Hash::hash(&hash256_pre); - let hash160_pre = [0x56 as u8; 32]; - let hash160 = hash160::Hash::hash(&hash160_pre); - let ripemd160_pre = [0x78 as u8; 32]; - let ripemd160 = ripemd160::Hash::hash(&ripemd160_pre); - - let pubdata = PubData { - pks, - sha256, - hash256, - ripemd160, - hash160, - x_only_pks, - }; - let secretdata = SecretData { - sks, - sha256_pre, - hash256_pre, - ripemd160_pre, - hash160_pre, - x_only_keypairs, - }; - Self { - pubdata, - secretdata, - } - } -} - /// Obtain an insecure random public key with unknown secret key for testing pub fn random_pk(mut seed: u8) -> bitcoin::PublicKey { loop { diff --git a/tests/test_cpp.rs b/tests/test_cpp.rs deleted file mode 100644 index 4e5196724..000000000 --- a/tests/test_cpp.rs +++ /dev/null @@ -1,253 +0,0 @@ -//! # rust-miniscript integration test -//! -//! Read Miniscripts from file and translate into miniscripts -//! which we know how to satisfy -//! - -use std::collections::BTreeMap; -use std::fs::File; -use std::io::{self, BufRead}; -use std::path::Path; - -use bitcoin::hashes::{sha256d, Hash}; -use bitcoin::secp256k1::{self, Secp256k1}; -use bitcoin::util::psbt; -use bitcoin::util::psbt::PartiallySignedTransaction as Psbt; -use bitcoin::{self, Amount, LockTime, OutPoint, Sequence, Transaction, TxIn, TxOut, Txid}; -use bitcoind::bitcoincore_rpc::{json, Client, RpcApi}; -use miniscript::psbt::PsbtExt; -use miniscript::Descriptor; - -mod setup; -use setup::test_util::{self, PubData, TestData}; - -// parse ~30 miniscripts from file -pub(crate) fn parse_miniscripts( - secp: &Secp256k1, - pubdata: &PubData, -) -> Vec> { - // File must exist in current path before this produces output - let mut desc_vec = vec![]; - // Consumes the iterator, returns an (Optional) String - for line in read_lines("tests/data/random_ms.txt") { - let ms = test_util::parse_insane_ms(&line.unwrap(), pubdata); - let wsh = Descriptor::new_wsh(ms).unwrap(); - desc_vec.push(wsh.derived_descriptor(secp, 0).unwrap()); - } - desc_vec -} - -// The output is wrapped in a Result to allow matching on errors -// Returns an Iterator to the Reader of the lines of the file. -fn read_lines

(filename: P) -> io::Lines> -where - P: AsRef, -{ - let file = File::open(filename).expect("File not found"); - io::BufReader::new(file).lines() -} - -/// Quickly create a BTC amount. -fn btc>(btc: F) -> Amount { - Amount::from_btc(btc.into()).unwrap() -} - -// Find the Outpoint by value. -// Ideally, we should find by scriptPubkey, but this -// works for temp test case -fn get_vout(cl: &Client, txid: Txid, value: u64) -> (OutPoint, TxOut) { - let tx = cl - .get_transaction(&txid, None) - .unwrap() - .transaction() - .unwrap(); - for (i, txout) in tx.output.into_iter().enumerate() { - if txout.value == value { - return (OutPoint::new(txid, i as u32), txout); - } - } - unreachable!("Only call get vout on functions which have the expected outpoint"); -} - -pub fn test_from_cpp_ms(cl: &Client, testdata: &TestData) { - let secp = secp256k1::Secp256k1::new(); - let desc_vec = parse_miniscripts(&secp, &testdata.pubdata); - let sks = &testdata.secretdata.sks; - let pks = &testdata.pubdata.pks; - // Generate some blocks - let blocks = cl - .generate_to_address(500, &cl.get_new_address(None, None).unwrap()) - .unwrap(); - assert_eq!(blocks.len(), 500); - - // Next send some btc to each address corresponding to the miniscript - let mut txids = vec![]; - for wsh in desc_vec.iter() { - let txid = cl - .send_to_address( - &wsh.address(bitcoin::Network::Regtest).unwrap(), - btc(1), - None, - None, - None, - None, - None, - None, - ) - .unwrap(); - txids.push(txid); - } - // Wait for the funds to mature. - let blocks = cl - .generate_to_address(50, &cl.get_new_address(None, None).unwrap()) - .unwrap(); - assert_eq!(blocks.len(), 50); - // Create a PSBT for each transaction. - // Spend one input and spend one output for simplicity. - let mut psbts = vec![]; - for (desc, txid) in desc_vec.iter().zip(txids) { - let mut psbt = Psbt { - unsigned_tx: Transaction { - version: 2, - lock_time: LockTime::from_time(1_603_866_330) - .expect("valid timestamp") - .into(), // 10/28/2020 @ 6:25am (UTC) - input: vec![], - output: vec![], - }, - unknown: BTreeMap::new(), - proprietary: BTreeMap::new(), - xpub: BTreeMap::new(), - version: 0, - inputs: vec![], - outputs: vec![], - }; - // figure out the outpoint from the txid - let (outpoint, witness_utxo) = get_vout(&cl, txid, btc(1.0).to_sat()); - let mut txin = TxIn::default(); - txin.previous_output = outpoint; - // set the sequence to a non-final number for the locktime transactions to be - // processed correctly. - // We waited 50 blocks, keep 49 for safety - txin.sequence = Sequence::from_height(49); - psbt.unsigned_tx.input.push(txin); - // Get a new script pubkey from the node so that - // the node wallet tracks the receiving transaction - // and we can check it by gettransaction RPC. - let addr = cl - .get_new_address(None, Some(json::AddressType::Bech32)) - .unwrap(); - psbt.unsigned_tx.output.push(TxOut { - value: 99_999_000, - script_pubkey: addr.script_pubkey(), - }); - let mut input = psbt::Input::default(); - input.witness_utxo = Some(witness_utxo); - input.witness_script = Some(desc.explicit_script().unwrap()); - psbt.inputs.push(input); - psbt.outputs.push(psbt::Output::default()); - psbts.push(psbt); - } - - let mut spend_txids = vec![]; - // Sign the transactions with all keys - // AKA the signer role of psbt - for i in 0..psbts.len() { - let ms = if let Descriptor::Wsh(wsh) = &desc_vec[i] { - match wsh.as_inner() { - miniscript::descriptor::WshInner::Ms(ms) => ms, - _ => unreachable!(), - } - } else { - unreachable!("Only Wsh descriptors are supported"); - }; - - let sks_reqd: Vec<_> = ms - .iter_pk() - .map(|pk| sks[pks.iter().position(|&x| x == pk).unwrap()]) - .collect(); - // Get the required sighash message - let amt = btc(1).to_sat(); - let mut sighash_cache = bitcoin::util::sighash::SighashCache::new(&psbts[i].unsigned_tx); - let sighash_ty = bitcoin::EcdsaSighashType::All; - let sighash = sighash_cache - .segwit_signature_hash(0, &ms.encode(), amt, sighash_ty) - .unwrap(); - - // requires both signing and verification because we check the tx - // after we psbt extract it - let msg = secp256k1::Message::from_slice(&sighash[..]).unwrap(); - - // Finally construct the signature and add to psbt - for sk in sks_reqd { - let sig = secp.sign_ecdsa(&msg, &sk); - let pk = pks[sks.iter().position(|&x| x == sk).unwrap()]; - psbts[i].inputs[0].partial_sigs.insert( - pk, - bitcoin::EcdsaSig { - sig, - hash_ty: sighash_ty, - }, - ); - } - // Add the hash preimages to the psbt - psbts[i].inputs[0].sha256_preimages.insert( - testdata.pubdata.sha256, - testdata.secretdata.sha256_pre.to_vec(), - ); - psbts[i].inputs[0].hash256_preimages.insert( - sha256d::Hash::from_inner(testdata.pubdata.hash256.into_inner()), - testdata.secretdata.hash256_pre.to_vec(), - ); - println!("{}", ms); - psbts[i].inputs[0].hash160_preimages.insert( - testdata.pubdata.hash160, - testdata.secretdata.hash160_pre.to_vec(), - ); - psbts[i].inputs[0].ripemd160_preimages.insert( - testdata.pubdata.ripemd160, - testdata.secretdata.ripemd160_pre.to_vec(), - ); - // Finalize the transaction using psbt - // Let miniscript do it's magic! - if let Err(e) = psbts[i].finalize_mall_mut(&secp) { - // All miniscripts should satisfy - panic!("Could not satisfy: error{} ms:{} at ind:{}", e[0], ms, i); - } else { - let tx = psbts[i].extract(&secp).unwrap(); - - // Send the transactions to bitcoin node for mining. - // Regtest mode has standardness checks - // Check whether the node accepts the transactions - let txid = cl - .send_raw_transaction(&tx) - .expect(&format!("{} send tx failed for ms {}", i, ms)); - spend_txids.push(txid); - } - } - // Finally mine the blocks and await confirmations - let _blocks = cl - .generate_to_address(10, &cl.get_new_address(None, None).unwrap()) - .unwrap(); - // Get the required transactions from the node mined in the blocks. - for txid in spend_txids { - // Check whether the transaction is mined in blocks - // Assert that the confirmations are > 0. - let num_conf = cl.get_transaction(&txid, None).unwrap().info.confirmations; - assert!(num_conf > 0); - } -} - -#[test] -#[ignore = "bitcoind crate breaking change"] -fn test_setup() { - setup::setup(); -} - -#[test] -#[ignore = "bitcoind crate breaking change"] -fn tests_from_cpp() { - let cl = &setup::setup().client; - let testdata = TestData::new_fixed_data(50); - test_from_cpp_ms(cl, &testdata); -} diff --git a/tests/test_desc.rs b/tests/test_desc.rs deleted file mode 100644 index 96281ae27..000000000 --- a/tests/test_desc.rs +++ /dev/null @@ -1,432 +0,0 @@ -//! # rust-miniscript integration test -//! -//! Read Miniscripts from file and translate into miniscripts -//! which we know how to satisfy -//! - -use std::collections::BTreeMap; -use std::{error, fmt}; - -use actual_rand as rand; -use bitcoin::blockdata::witness::Witness; -use bitcoin::hashes::{sha256d, Hash}; -use bitcoin::util::psbt::PartiallySignedTransaction as Psbt; -use bitcoin::util::sighash::SighashCache; -use bitcoin::util::taproot::{LeafVersion, TapLeafHash}; -use bitcoin::util::{psbt, sighash}; -use bitcoin::{ - self, secp256k1, Amount, LockTime, OutPoint, SchnorrSig, Script, Sequence, Transaction, TxIn, - TxOut, Txid, -}; -use bitcoind::bitcoincore_rpc::{json, Client, RpcApi}; -use miniscript::psbt::{PsbtExt, PsbtInputExt}; -use miniscript::{Descriptor, Miniscript, ScriptContext, ToPublicKey}; -mod setup; - -use rand::RngCore; -use setup::test_util::{self, TestData}; -/// Quickly create a BTC amount. -fn btc>(btc: F) -> Amount { - Amount::from_btc(btc.into()).unwrap() -} - -// Find the Outpoint by spk -fn get_vout(cl: &Client, txid: Txid, value: u64, spk: Script) -> (OutPoint, TxOut) { - let tx = cl - .get_transaction(&txid, None) - .unwrap() - .transaction() - .unwrap(); - for (i, txout) in tx.output.into_iter().enumerate() { - if txout.value == value && spk == txout.script_pubkey { - return (OutPoint::new(txid, i as u32), txout); - } - } - unreachable!("Only call get vout on functions which have the expected outpoint"); -} - -#[derive(Debug, PartialEq)] -pub enum DescError { - /// PSBT was not able to finalize - PsbtFinalizeError, - /// Problem with address computation - AddressComputationError, - /// Error while parsing the descriptor - DescParseError, -} - -impl fmt::Display for DescError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - DescError::PsbtFinalizeError => f.write_str("PSBT was not able to finalize"), - DescError::AddressComputationError => f.write_str("Problem with address computation"), - DescError::DescParseError => f.write_str("Not able to parse the descriptor"), - } - } -} - -impl error::Error for DescError {} - -pub fn test_desc_satisfy( - cl: &Client, - testdata: &TestData, - descriptor: &str, -) -> Result { - let secp = secp256k1::Secp256k1::new(); - let sks = &testdata.secretdata.sks; - let xonly_keypairs = &testdata.secretdata.x_only_keypairs; - let pks = &testdata.pubdata.pks; - let x_only_pks = &testdata.pubdata.x_only_pks; - // Generate some blocks - let blocks = cl - .generate_to_address(1, &cl.get_new_address(None, None).unwrap()) - .unwrap(); - assert_eq!(blocks.len(), 1); - - let definite_desc = test_util::parse_test_desc(&descriptor, &testdata.pubdata) - .map_err(|_| DescError::DescParseError)? - .at_derivation_index(0); - - let derived_desc = definite_desc.derived_descriptor(&secp).unwrap(); - let desc_address = derived_desc.address(bitcoin::Network::Regtest); - let desc_address = desc_address.map_err(|_x| DescError::AddressComputationError)?; - - // Next send some btc to each address corresponding to the miniscript - let txid = cl - .send_to_address(&desc_address, btc(1), None, None, None, None, None, None) - .unwrap(); - // Wait for the funds to mature. - let blocks = cl - .generate_to_address(2, &cl.get_new_address(None, None).unwrap()) - .unwrap(); - assert_eq!(blocks.len(), 2); - // Create a PSBT for each transaction. - // Spend one input and spend one output for simplicity. - let mut psbt = Psbt { - unsigned_tx: Transaction { - version: 2, - lock_time: LockTime::from_time(1_603_866_330) - .expect("valid timestamp") - .into(), // 10/28/2020 @ 6:25am (UTC) - input: vec![], - output: vec![], - }, - unknown: BTreeMap::new(), - proprietary: BTreeMap::new(), - xpub: BTreeMap::new(), - version: 0, - inputs: vec![], - outputs: vec![], - }; - // figure out the outpoint from the txid - let (outpoint, witness_utxo) = - get_vout(&cl, txid, btc(1.0).to_sat(), derived_desc.script_pubkey()); - let mut txin = TxIn::default(); - txin.previous_output = outpoint; - // set the sequence to a non-final number for the locktime transactions to be - // processed correctly. - // We waited 2 blocks, keep 1 for safety - txin.sequence = Sequence::from_height(1); - psbt.unsigned_tx.input.push(txin); - // Get a new script pubkey from the node so that - // the node wallet tracks the receiving transaction - // and we can check it by gettransaction RPC. - let addr = cl - .get_new_address(None, Some(json::AddressType::Bech32)) - .unwrap(); - // Had to decrease 'value', so that fees can be increased - // (Was getting insufficient fees error, for deep script trees) - psbt.unsigned_tx.output.push(TxOut { - value: 99_997_000, - script_pubkey: addr.script_pubkey(), - }); - let mut input = psbt::Input::default(); - input - .update_with_descriptor_unchecked(&definite_desc) - .unwrap(); - input.witness_utxo = Some(witness_utxo.clone()); - psbt.inputs.push(input); - psbt.outputs.push(psbt::Output::default()); - - // -------------------------------------------- - // Sign the transactions with all keys - // AKA the signer role of psbt - // Get all the pubkeys and the corresponding secret keys - - let mut sighash_cache = SighashCache::new(&psbt.unsigned_tx); - match derived_desc { - Descriptor::Tr(ref tr) => { - // Fixme: take a parameter - let hash_ty = sighash::SchnorrSighashType::Default; - - let internal_key_present = x_only_pks - .iter() - .position(|&x| x.to_public_key() == *tr.internal_key()); - let internal_keypair = internal_key_present.map(|idx| xonly_keypairs[idx].clone()); - let prevouts = [witness_utxo]; - let prevouts = sighash::Prevouts::All(&prevouts); - - if let Some(internal_keypair) = internal_keypair { - // ---------------------- Tr key spend -------------------- - let internal_keypair = internal_keypair - .add_xonly_tweak(&secp, &tr.spend_info().tap_tweak().to_scalar()) - .expect("Tweaking failed"); - let sighash_msg = sighash_cache - .taproot_key_spend_signature_hash(0, &prevouts, hash_ty) - .unwrap(); - let msg = secp256k1::Message::from_slice(&sighash_msg[..]).unwrap(); - let mut aux_rand = [0u8; 32]; - rand::thread_rng().fill_bytes(&mut aux_rand); - let schnorr_sig = - secp.sign_schnorr_with_aux_rand(&msg, &internal_keypair, &aux_rand); - psbt.inputs[0].tap_key_sig = Some(SchnorrSig { - sig: schnorr_sig, - hash_ty: hash_ty, - }); - } else { - // No internal key - } - // ------------------ script spend ------------- - let x_only_keypairs_reqd: Vec<(secp256k1::KeyPair, TapLeafHash)> = tr - .iter_scripts() - .flat_map(|(_depth, ms)| { - let leaf_hash = TapLeafHash::from_script(&ms.encode(), LeafVersion::TapScript); - ms.iter_pk().filter_map(move |pk| { - let i = x_only_pks.iter().position(|&x| x.to_public_key() == pk); - i.map(|idx| (xonly_keypairs[idx].clone(), leaf_hash)) - }) - }) - .collect(); - for (keypair, leaf_hash) in x_only_keypairs_reqd { - let sighash_msg = sighash_cache - .taproot_script_spend_signature_hash(0, &prevouts, leaf_hash, hash_ty) - .unwrap(); - let msg = secp256k1::Message::from_slice(&sighash_msg[..]).unwrap(); - let mut aux_rand = [0u8; 32]; - rand::thread_rng().fill_bytes(&mut aux_rand); - let sig = secp.sign_schnorr_with_aux_rand(&msg, &keypair, &aux_rand); - // FIXME: uncomment when == is supported for secp256k1::KeyPair. (next major release) - // let x_only_pk = pks[xonly_keypairs.iter().position(|&x| x == keypair).unwrap()]; - // Just recalc public key - let (x_only_pk, _parity) = secp256k1::XOnlyPublicKey::from_keypair(&keypair); - psbt.inputs[0].tap_script_sigs.insert( - (x_only_pk, leaf_hash), - bitcoin::SchnorrSig { - sig, - hash_ty: hash_ty, - }, - ); - } - } - _ => { - // Non-tr descriptors - // Ecdsa sigs - let sks_reqd = match derived_desc { - Descriptor::Bare(bare) => find_sks_ms(&bare.as_inner(), testdata), - Descriptor::Pkh(pk) => find_sk_single_key(*pk.as_inner(), testdata), - Descriptor::Wpkh(pk) => find_sk_single_key(*pk.as_inner(), testdata), - Descriptor::Sh(sh) => match sh.as_inner() { - miniscript::descriptor::ShInner::Wsh(wsh) => match wsh.as_inner() { - miniscript::descriptor::WshInner::SortedMulti(ref smv) => { - let ms = Miniscript::from_ast(smv.sorted_node()).unwrap(); - find_sks_ms(&ms, testdata) - } - miniscript::descriptor::WshInner::Ms(ref ms) => find_sks_ms(&ms, testdata), - }, - miniscript::descriptor::ShInner::Wpkh(pk) => { - find_sk_single_key(*pk.as_inner(), testdata) - } - miniscript::descriptor::ShInner::SortedMulti(smv) => { - let ms = Miniscript::from_ast(smv.sorted_node()).unwrap(); - find_sks_ms(&ms, testdata) - } - miniscript::descriptor::ShInner::Ms(ms) => find_sks_ms(&ms, testdata), - }, - Descriptor::Wsh(wsh) => match wsh.as_inner() { - miniscript::descriptor::WshInner::SortedMulti(ref smv) => { - let ms = Miniscript::from_ast(smv.sorted_node()).unwrap(); - find_sks_ms(&ms, testdata) - } - miniscript::descriptor::WshInner::Ms(ref ms) => find_sks_ms(&ms, testdata), - }, - Descriptor::Tr(_tr) => unreachable!("Tr checked earlier"), - }; - let msg = psbt - .sighash_msg(0, &mut sighash_cache, None) - .unwrap() - .to_secp_msg(); - - // Fixme: Take a parameter - let hash_ty = bitcoin::EcdsaSighashType::All; - - // Finally construct the signature and add to psbt - for sk in sks_reqd { - let sig = secp.sign_ecdsa(&msg, &sk); - let pk = pks[sks.iter().position(|&x| x == sk).unwrap()]; - assert!(secp.verify_ecdsa(&msg, &sig, &pk.inner).is_ok()); - psbt.inputs[0].partial_sigs.insert( - pk, - bitcoin::EcdsaSig { - sig, - hash_ty: hash_ty, - }, - ); - } - } - } - // Add the hash preimages to the psbt - psbt.inputs[0].sha256_preimages.insert( - testdata.pubdata.sha256, - testdata.secretdata.sha256_pre.to_vec(), - ); - psbt.inputs[0].hash256_preimages.insert( - sha256d::Hash::from_inner(testdata.pubdata.hash256.into_inner()), - testdata.secretdata.hash256_pre.to_vec(), - ); - psbt.inputs[0].hash160_preimages.insert( - testdata.pubdata.hash160, - testdata.secretdata.hash160_pre.to_vec(), - ); - psbt.inputs[0].ripemd160_preimages.insert( - testdata.pubdata.ripemd160, - testdata.secretdata.ripemd160_pre.to_vec(), - ); - println!("Testing descriptor: {}", definite_desc); - // Finalize the transaction using psbt - // Let miniscript do it's magic! - if let Err(_) = psbt.finalize_mut(&secp) { - return Err(DescError::PsbtFinalizeError); - } - let tx = psbt.extract(&secp).expect("Extraction error"); - - // Send the transactions to bitcoin node for mining. - // Regtest mode has standardness checks - // Check whether the node accepts the transactions - let txid = cl - .send_raw_transaction(&tx) - .expect(&format!("send tx failed for desc {}", definite_desc)); - - // Finally mine the blocks and await confirmations - let _blocks = cl - .generate_to_address(1, &cl.get_new_address(None, None).unwrap()) - .unwrap(); - // Get the required transactions from the node mined in the blocks. - // Check whether the transaction is mined in blocks - // Assert that the confirmations are > 0. - let num_conf = cl.get_transaction(&txid, None).unwrap().info.confirmations; - assert!(num_conf > 0); - return Ok(tx.input[0].witness.clone()); -} - -// Find all secret corresponding to the known public keys in ms -fn find_sks_ms( - ms: &Miniscript, - testdata: &TestData, -) -> Vec { - let sks = &testdata.secretdata.sks; - let pks = &testdata.pubdata.pks; - let sks = ms - .iter_pk() - .filter_map(|pk| { - let i = pks.iter().position(|&x| x.to_public_key() == pk); - i.map(|idx| (sks[idx])) - }) - .collect(); - sks -} - -fn find_sk_single_key(pk: bitcoin::PublicKey, testdata: &TestData) -> Vec { - let sks = &testdata.secretdata.sks; - let pks = &testdata.pubdata.pks; - let i = pks.iter().position(|&x| x.to_public_key() == pk); - i.map(|idx| vec![sks[idx]]).unwrap_or(Vec::new()) -} - -fn test_descs(cl: &Client, testdata: &TestData) { - // K : Compressed key available - // K!: Compressed key with corresponding secret key unknown - // X: X-only key available - // X!: X-only key with corresponding secret key unknown - - // Test 1: Simple spend with internal key - let wit = test_desc_satisfy(cl, testdata, "tr(X)").unwrap(); - assert!(wit.len() == 1); - - // Test 2: Same as above, but with leaves - let wit = test_desc_satisfy(cl, testdata, "tr(X,{pk(X1!),pk(X2!)})").unwrap(); - assert!(wit.len() == 1); - - // Test 3: Force to spend with script spend. Unknown internal key and only one known script path - // X! -> Internal key unknown - // Leaf 1 -> pk(X1) with X1 known - // Leaf 2-> and_v(v:pk(X2),pk(X3!)) with partial witness only to X2 known - let wit = test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1),and_v(v:pk(X2),pk(X3!))})").unwrap(); - assert!(wit.len() == 3); // control block, script and signature - - // Test 4: Force to spend with script spend. Unknown internal key and multiple script paths - // Should select the one with minimum weight - // X! -> Internal key unknown - // Leaf 1 -> pk(X1!) with X1 unknown - // Leaf 2-> and_v(v:pk(X2),pk(X3)) X2 and X3 known - let wit = test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1),and_v(v:pk(X2),pk(X3))})").unwrap(); - assert!(wit.len() == 3); // control block, script and one signatures - - // Test 5: When everything is available, we should select the key spend path - let wit = test_desc_satisfy(cl, testdata, "tr(X,{pk(X1),and_v(v:pk(X2),pk(X3!))})").unwrap(); - assert!(wit.len() == 1); // control block, script and signature - - // Test 6: Test the new multi_a opcodes - test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),multi_a(1,X2,X3!,X4!,X5!)})").unwrap(); - test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),multi_a(2,X2,X3,X4!,X5!)})").unwrap(); - test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),multi_a(3,X2,X3,X4,X5!)})").unwrap(); - test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),multi_a(4,X2,X3,X4,X5)})").unwrap(); - - // Test 7: Test script tree of depth 127 is valid, only X128 is known - test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),{pk(X2!),{pk(X3!),{pk(X4!),{pk(X5!),{pk(X6!),{pk(X7!),{pk(X8!),{pk(X9!),{pk(X10!),{pk(X11!),{pk(X12!),{pk(X13!),{pk(X14!),{pk(X15!),{pk(X16!),{pk(X17!),{pk(X18!),{pk(X19!),{pk(X20!),{pk(X21!),{pk(X22!),{pk(X23!),{pk(X24!),{pk(X25!),{pk(X26!),{pk(X27!),{pk(X28!),{pk(X29!),{pk(X30!),{pk(X31!),{pk(X32!),{pk(X33!),{pk(X34!),{pk(X35!),{pk(X36!),{pk(X37!),{pk(X38!),{pk(X39!),{pk(X40!),{pk(X41!),{pk(X42!),{pk(X43!),{pk(X44!),{pk(X45!),{pk(X46!),{pk(X47!),{pk(X48!),{pk(X49!),{pk(X50!),{pk(X51!),{pk(X52!),{pk(X53!),{pk(X54!),{pk(X55!),{pk(X56!),{pk(X57!),{pk(X58!),{pk(X59!),{pk(X60!),{pk(X61!),{pk(X62!),{pk(X63!),{pk(X64!),{pk(X65!),{pk(X66!),{pk(X67!),{pk(X68!),{pk(X69!),{pk(X70!),{pk(X71!),{pk(X72!),{pk(X73!),{pk(X74!),{pk(X75!),{pk(X76!),{pk(X77!),{pk(X78!),{pk(X79!),{pk(X80!),{pk(X81!),{pk(X82!),{pk(X83!),{pk(X84!),{pk(X85!),{pk(X86!),{pk(X87!),{pk(X88!),{pk(X89!),{pk(X90!),{pk(X91!),{pk(X92!),{pk(X93!),{pk(X94!),{pk(X95!),{pk(X96!),{pk(X97!),{pk(X98!),{pk(X99!),{pk(X100!),{pk(X101!),{pk(X102!),{pk(X103!),{pk(X104!),{pk(X105!),{pk(X106!),{pk(X107!),{pk(X108!),{pk(X109!),{pk(X110!),{pk(X111!),{pk(X112!),{pk(X113!),{pk(X114!),{pk(X115!),{pk(X116!),{pk(X117!),{pk(X118!),{pk(X119!),{pk(X120!),{pk(X121!),{pk(X122!),{pk(X123!),{pk(X124!),{pk(X125!),{pk(X126!),{pk(X127!),pk(X128)}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}})").unwrap(); - - // Test 8: Test script tree of depth 128 is valid, only X129 is known - test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),{pk(X2!),{pk(X3!),{pk(X4!),{pk(X5!),{pk(X6!),{pk(X7!),{pk(X8!),{pk(X9!),{pk(X10!),{pk(X11!),{pk(X12!),{pk(X13!),{pk(X14!),{pk(X15!),{pk(X16!),{pk(X17!),{pk(X18!),{pk(X19!),{pk(X20!),{pk(X21!),{pk(X22!),{pk(X23!),{pk(X24!),{pk(X25!),{pk(X26!),{pk(X27!),{pk(X28!),{pk(X29!),{pk(X30!),{pk(X31!),{pk(X32!),{pk(X33!),{pk(X34!),{pk(X35!),{pk(X36!),{pk(X37!),{pk(X38!),{pk(X39!),{pk(X40!),{pk(X41!),{pk(X42!),{pk(X43!),{pk(X44!),{pk(X45!),{pk(X46!),{pk(X47!),{pk(X48!),{pk(X49!),{pk(X50!),{pk(X51!),{pk(X52!),{pk(X53!),{pk(X54!),{pk(X55!),{pk(X56!),{pk(X57!),{pk(X58!),{pk(X59!),{pk(X60!),{pk(X61!),{pk(X62!),{pk(X63!),{pk(X64!),{pk(X65!),{pk(X66!),{pk(X67!),{pk(X68!),{pk(X69!),{pk(X70!),{pk(X71!),{pk(X72!),{pk(X73!),{pk(X74!),{pk(X75!),{pk(X76!),{pk(X77!),{pk(X78!),{pk(X79!),{pk(X80!),{pk(X81!),{pk(X82!),{pk(X83!),{pk(X84!),{pk(X85!),{pk(X86!),{pk(X87!),{pk(X88!),{pk(X89!),{pk(X90!),{pk(X91!),{pk(X92!),{pk(X93!),{pk(X94!),{pk(X95!),{pk(X96!),{pk(X97!),{pk(X98!),{pk(X99!),{pk(X100!),{pk(X101!),{pk(X102!),{pk(X103!),{pk(X104!),{pk(X105!),{pk(X106!),{pk(X107!),{pk(X108!),{pk(X109!),{pk(X110!),{pk(X111!),{pk(X112!),{pk(X113!),{pk(X114!),{pk(X115!),{pk(X116!),{pk(X117!),{pk(X118!),{pk(X119!),{pk(X120!),{pk(X121!),{pk(X122!),{pk(X123!),{pk(X124!),{pk(X125!),{pk(X126!),{pk(X127!),{pk(X128!),pk(X129)}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}})").unwrap(); - - // Test 9: Test script complete tree having 128 leaves with depth log(128), only X1 is known - test_desc_satisfy(cl, testdata, "tr(X!,{{{{{{{pk(X1),pk(X2!)},{pk(X3!),pk(X4!)}},{{pk(X5!),pk(X6!)},{pk(X7!),pk(X8!)}}},{{{pk(X9!),pk(X10!)},{pk(X11!),pk(X12!)}},{{pk(X13!),pk(X14!)},{pk(X15!),pk(X16!)}}}},{{{{pk(X17!),pk(X18!)},{pk(X19!),pk(X20!)}},{{pk(X21!),pk(X22!)},{pk(X23!),pk(X24!)}}},{{{pk(X25!),pk(X26!)},{pk(X27!),pk(X28!)}},{{pk(X29!),pk(X30!)},{pk(X31!),pk(X32!)}}}}},{{{{{pk(X33!),pk(X34!)},{pk(X35!),pk(X36!)}},{{pk(X37!),pk(X38!)},{pk(X39!),pk(X40!)}}},{{{pk(X41!),pk(X42!)},{pk(X43!),pk(X44!)}},{{pk(X45!),pk(X46!)},{pk(X47!),pk(X48!)}}}},{{{{pk(X49!),pk(X50!)},{pk(X51!),pk(X52!)}},{{pk(X53!),pk(X54!)},{pk(X55!),pk(X56!)}}},{{{pk(X57!),pk(X58!)},{pk(X59!),pk(X60!)}},{{pk(X61!),pk(X62!)},{pk(X63!),pk(X64!)}}}}}},{{{{{{pk(X65!),pk(X66!)},{pk(X67!),pk(X68!)}},{{pk(X69!),pk(X70!)},{pk(X71!),pk(X72!)}}},{{{pk(X73!),pk(X74!)},{pk(X75!),pk(X76!)}},{{pk(X77!),pk(X78!)},{pk(X79!),pk(X80!)}}}},{{{{pk(X81!),pk(X82!)},{pk(X83!),pk(X84!)}},{{pk(X85!),pk(X86!)},{pk(X87!),pk(X88!)}}},{{{pk(X89!),pk(X90!)},{pk(X91!),pk(X92!)}},{{pk(X93!),pk(X94!)},{pk(X95!),pk(X96!)}}}}},{{{{{pk(X97!),pk(X98!)},{pk(X99!),pk(X100!)}},{{pk(X101!),pk(X102!)},{pk(X103!),pk(X104!)}}},{{{pk(X105!),pk(X106!)},{pk(X107!),pk(X108!)}},{{pk(X109!),pk(X110!)},{pk(X111!),pk(X112!)}}}},{{{{pk(X113!),pk(X114!)},{pk(X115!),pk(X116!)}},{{pk(X117!),pk(X118!)},{pk(X119!),pk(X120!)}}},{{{pk(X121!),pk(X122!)},{pk(X123!),pk(X124!)}},{{pk(X125!),pk(X126!)},{pk(X127!),pk(X128!)}}}}}}})").unwrap(); - - // Test 10: Test taproot desc with ZERO known keys - let result = test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),pk(X2!)})"); - assert_eq!(result, Err(DescError::PsbtFinalizeError)); - - // Test 11: Test taproot with insufficient known keys - let result = test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),multi_a(3,X2!,X3,X4)})"); - assert_eq!(result, Err(DescError::PsbtFinalizeError)); - - // Test 12: size exceeds the limit - let result = test_desc_satisfy(cl, testdata, "wsh(thresh(1,pk(K1),a:pk(K2),a:pk(K3),a:pk(K4),a:pk(K5),a:pk(K6),a:pk(K7),a:pk(K8),a:pk(K9),a:pk(K10),a:pk(K11),a:pk(K12),a:pk(K13),a:pk(K14),a:pk(K15),a:pk(K16),a:pk(K17),a:pk(K18),a:pk(K19),a:pk(K20),a:pk(K21),a:pk(K22),a:pk(K23),a:pk(K24),a:pk(K25),a:pk(K26),a:pk(K27),a:pk(K28),a:pk(K29),a:pk(K30),a:pk(K31),a:pk(K32),a:pk(K33),a:pk(K34),a:pk(K35),a:pk(K36),a:pk(K37),a:pk(K38),a:pk(K39),a:pk(K40),a:pk(K41),a:pk(K42),a:pk(K43),a:pk(K44),a:pk(K45),a:pk(K46),a:pk(K47),a:pk(K48),a:pk(K49),a:pk(K50),a:pk(K51),a:pk(K52),a:pk(K53),a:pk(K54),a:pk(K55),a:pk(K56),a:pk(K57),a:pk(K58),a:pk(K59),a:pk(K60),a:pk(K61),a:pk(K62),a:pk(K63),a:pk(K64),a:pk(K65),a:pk(K66),a:pk(K67),a:pk(K68),a:pk(K69),a:pk(K70),a:pk(K71),a:pk(K72),a:pk(K73),a:pk(K74),a:pk(K75),a:pk(K76),a:pk(K77),a:pk(K78),a:pk(K79),a:pk(K80),a:pk(K81),a:pk(K82),a:pk(K83),a:pk(K84),a:pk(K85),a:pk(K86),a:pk(K87),a:pk(K88),a:pk(K89),a:pk(K90),a:pk(K91),a:pk(K92),a:pk(K93),a:pk(K94),a:pk(K95),a:pk(K96),a:pk(K97),a:pk(K98),a:pk(K99),a:pk(K100)))"); - assert_eq!(result, Err(DescError::DescParseError)); - - // Test 13: Test script tree of depth > 128 is invalid - let result = test_desc_satisfy(cl, testdata, "tr(X!,{pk(X1!),{pk(X2!),{pk(X3!),{pk(X4!),{pk(X5!),{pk(X6!),{pk(X7!),{pk(X8!),{pk(X9!),{pk(X10!),{pk(X11!),{pk(X12!),{pk(X13!),{pk(X14!),{pk(X15!),{pk(X16!),{pk(X17!),{pk(X18!),{pk(X19!),{pk(X20!),{pk(X21!),{pk(X22!),{pk(X23!),{pk(X24!),{pk(X25!),{pk(X26!),{pk(X27!),{pk(X28!),{pk(X29!),{pk(X30!),{pk(X31!),{pk(X32!),{pk(X33!),{pk(X34!),{pk(X35!),{pk(X36!),{pk(X37!),{pk(X38!),{pk(X39!),{pk(X40!),{pk(X41!),{pk(X42!),{pk(X43!),{pk(X44!),{pk(X45!),{pk(X46!),{pk(X47!),{pk(X48!),{pk(X49!),{pk(X50!),{pk(X51!),{pk(X52!),{pk(X53!),{pk(X54!),{pk(X55!),{pk(X56!),{pk(X57!),{pk(X58!),{pk(X59!),{pk(X60!),{pk(X61!),{pk(X62!),{pk(X63!),{pk(X64!),{pk(X65!),{pk(X66!),{pk(X67!),{pk(X68!),{pk(X69!),{pk(X70!),{pk(X71!),{pk(X72!),{pk(X73!),{pk(X74!),{pk(X75!),{pk(X76!),{pk(X77!),{pk(X78!),{pk(X79!),{pk(X80!),{pk(X81!),{pk(X82!),{pk(X83!),{pk(X84!),{pk(X85!),{pk(X86!),{pk(X87!),{pk(X88!),{pk(X89!),{pk(X90!),{pk(X91!),{pk(X92!),{pk(X93!),{pk(X94!),{pk(X95!),{pk(X96!),{pk(X97!),{pk(X98!),{pk(X99!),{pk(X100!),{pk(X101!),{pk(X102!),{pk(X103!),{pk(X104!),{pk(X105!),{pk(X106!),{pk(X107!),{pk(X108!),{pk(X109!),{pk(X110!),{pk(X111!),{pk(X112!),{pk(X113!),{pk(X114!),{pk(X115!),{pk(X116!),{pk(X117!),{pk(X118!),{pk(X119!),{pk(X120!),{pk(X121!),{pk(X122!),{pk(X123!),{pk(X124!),{pk(X125!),{pk(X126!),{pk(X127!),{pk(X128!),{pk(X129!),pk(X130)}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}})"); - assert_eq!(result, Err(DescError::DescParseError)); - - // Misc tests for other descriptors that we support - // Keys - test_desc_satisfy(cl, testdata, "wpkh(K)").unwrap(); - test_desc_satisfy(cl, testdata, "pkh(K)").unwrap(); - test_desc_satisfy(cl, testdata, "sh(wpkh(K))").unwrap(); - - // sorted multi - test_desc_satisfy(cl, testdata, "sh(sortedmulti(2,K1,K2,K3))").unwrap(); - test_desc_satisfy(cl, testdata, "wsh(sortedmulti(2,K1,K2,K3))").unwrap(); - test_desc_satisfy(cl, testdata, "sh(wsh(sortedmulti(2,K1,K2,K3)))").unwrap(); - - // Miniscripts - test_desc_satisfy(cl, testdata, "sh(and_v(v:pk(K1),pk(K2)))").unwrap(); - test_desc_satisfy(cl, testdata, "wsh(and_v(v:pk(K1),pk(K2)))").unwrap(); - test_desc_satisfy(cl, testdata, "sh(wsh(and_v(v:pk(K1),pk(K2))))").unwrap(); -} - -#[test] -#[ignore = "bitcoind crate made a breaking change"] -fn test_satisfy() { - let testdata = TestData::new_fixed_data(50); - let cl = &setup::setup().client; - test_descs(cl, &testdata); -} From 9f1af3b86029f35c490e2b3c18cbb0cde1e14ff1 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Fri, 4 Jul 2025 17:40:03 +0000 Subject: [PATCH 04/11] ci: update a bunch of versions --- .github/workflows/rust.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 900b7e08e..f0587d74a 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -20,10 +20,10 @@ jobs: strategy: matrix: rust: - - 1.58.0 + - 1.65.0 steps: - name: Checkout Crate - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Install hongfuzz dependancies run: sudo apt update && sudo apt install build-essential binutils-dev libunwind-dev libblocksruntime-dev liblzma-dev - name: Checkout Toolchain @@ -44,7 +44,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Crate - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Checkout Toolchain uses: actions-rs/toolchain@v1 with: @@ -80,7 +80,7 @@ jobs: DO_NO_STD: true steps: - name: Checkout Crate - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Checkout Toolchain uses: actions-rs/toolchain@v1 with: @@ -98,7 +98,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up QEMU run: sudo apt update && sudo apt install -y qemu-system-arm gcc-arm-none-eabi - name: Checkout Toolchain From 594fda48c0e5889c84335eb43f8654c233a9e289 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sat, 5 Jul 2025 01:50:21 +0000 Subject: [PATCH 05/11] modernize rustfmt::skip syntax and run cargo fmt --- examples/sign_multisig.rs | 2 +- examples/verify_tx.rs | 2 +- src/miniscript/decode.rs | 1 - src/miniscript/mod.rs | 23 ++++++++++--------- src/miniscript/ms_tests.rs | 10 ++++----- src/miniscript/types/extra_props.rs | 34 ++++++++++++++--------------- src/policy/compiler.rs | 12 +++------- src/policy/concrete.rs | 12 +++++++--- src/policy/semantic.rs | 9 ++++++-- 9 files changed, 56 insertions(+), 49 deletions(-) diff --git a/examples/sign_multisig.rs b/examples/sign_multisig.rs index 7471ff16f..f4a2c6801 100644 --- a/examples/sign_multisig.rs +++ b/examples/sign_multisig.rs @@ -105,8 +105,8 @@ fn spending_transaction() -> bitcoin::Transaction { } } +#[rustfmt::skip] fn list_of_three_arbitrary_public_keys() -> Vec { - #[cfg_attr(feature="cargo-fmt", rustfmt_skip)] vec![ bitcoin::PublicKey::from_slice(&[2; 33]).expect("key 1"), bitcoin::PublicKey::from_slice(&[ diff --git a/examples/verify_tx.rs b/examples/verify_tx.rs index 9b0e9731b..699f2408d 100644 --- a/examples/verify_tx.rs +++ b/examples/verify_tx.rs @@ -117,9 +117,9 @@ fn main() { } /// Returns an arbitrary transaction. +#[rustfmt::skip] fn hard_coded_transaction() -> bitcoin::Transaction { // tx `f27eba163c38ad3f34971198687a3f1882b7ec818599ffe469a8440d82261c98` - #[cfg_attr(feature="cargo-fmt", rustfmt_skip)] let tx_bytes = vec![ 0x01, 0x00, 0x00, 0x00, 0x02, 0xc5, 0x11, 0x1d, 0xb7, 0x93, 0x50, 0xc1, 0x70, 0x28, 0x41, 0x39, 0xe8, 0xe3, 0x4e, 0xb0, 0xed, 0xba, 0x64, 0x7b, diff --git a/src/miniscript/decode.rs b/src/miniscript/decode.rs index 472b35702..290e9f7dc 100644 --- a/src/miniscript/decode.rs +++ b/src/miniscript/decode.rs @@ -32,7 +32,6 @@ use crate::miniscript::ScriptContext; use crate::prelude::*; use crate::{bitcoin, hash256, Error, Miniscript, MiniscriptKey, ToPublicKey}; - /// Trait for parsing keys from byte slices pub trait ParseableKey: Sized + ToPublicKey + private::Sealed { /// Parse a key from slice diff --git a/src/miniscript/mod.rs b/src/miniscript/mod.rs index c7a8c0fe8..3dff15739 100644 --- a/src/miniscript/mod.rs +++ b/src/miniscript/mod.rs @@ -77,7 +77,6 @@ mod private { phantom: PhantomData, } impl Miniscript { - /// Add type information(Type and Extdata) to Miniscript based on /// `AstElem` fragment. Dependent on display and clone because of Error /// Display code of type_check. @@ -109,7 +108,12 @@ mod private { ty: types::Type, ext: types::extra_props::ExtData, ) -> Miniscript { - Miniscript { node, ty, ext, phantom: PhantomData } + Miniscript { + node, + ty, + ext, + phantom: PhantomData, + } } } } @@ -167,7 +171,6 @@ impl fmt::Display for Miniscript } impl Miniscript { - /// Extracts the `AstElem` representing the root of the miniscript pub fn into_inner(self) -> Terminal { self.node @@ -360,8 +363,8 @@ impl Miniscript { T: Translator, { let inner = self.node.real_translate_pk(t)?; - let ms = Miniscript::from_ast(inner) - .expect("Translator should not change the type of the AST"); + let ms = + Miniscript::from_ast(inner).expect("Translator should not change the type of the AST"); Ok(ms) } } @@ -503,12 +506,11 @@ mod tests { use sync::Arc; use super::{Miniscript, ScriptContext, Segwitv0, Tap}; - use crate::miniscript::types; - use crate::miniscript::Terminal; + use crate::miniscript::{types, Terminal}; use crate::policy::Liftable; - use crate::{prelude::*, Error}; + use crate::prelude::*; use crate::test_utils::{StrKeyTranslator, StrXOnlyKeyTranslator}; - use crate::{hex_script, DummyKey, ExtParams, Satisfier, ToPublicKey, TranslatePk}; + use crate::{hex_script, DummyKey, Error, ExtParams, Satisfier, ToPublicKey, TranslatePk}; type Segwitv0Script = Miniscript; type Tapscript = Miniscript; @@ -1143,7 +1145,8 @@ mod tests { #[test] fn test_script_parse_dos() { - let mut script = bitcoin::blockdata::script::Builder::new().push_opcode(bitcoin::blockdata::opcodes::OP_TRUE); + let mut script = bitcoin::blockdata::script::Builder::new() + .push_opcode(bitcoin::blockdata::opcodes::OP_TRUE); for _ in 0..10000 { script = script.push_opcode(bitcoin::blockdata::opcodes::all::OP_0NOTEQUAL); } diff --git a/src/miniscript/ms_tests.rs b/src/miniscript/ms_tests.rs index 2b44e2025..5d9f33cb6 100644 --- a/src/miniscript/ms_tests.rs +++ b/src/miniscript/ms_tests.rs @@ -79,7 +79,7 @@ mod tests { } #[test] - #[cfg_attr(feature="cargo-fmt", rustfmt_skip)] + #[rustfmt::skip] fn invalid_tests_from_alloy() { invalid_ms("or_b(or_i(0,sha256(926a54995ca48600920a19bf7bc502ca5f2f7d07e6f804c4f00ebf0325084dbc)),after(1))"); invalid_ms("or_b(s:pk_h(A),after(500000001))"); @@ -5657,7 +5657,7 @@ mod tests { invalid_ms("c:or_b(sha256(926a54995ca48600920a19bf7bc502ca5f2f7d07e6f804c4f00ebf0325084dbc),pk_k(A))"); } #[test] - #[cfg_attr(feature="cargo-fmt", rustfmt_skip)] + #[rustfmt::skip] fn mall_8f1e8_tests_from_alloy() { ms_test("or_d(or_d(sha256(926a54995ca48600920a19bf7bc502ca5f2f7d07e6f804c4f00ebf0325084dbc),sha256(926a54995ca48600920a19bf7bc502ca5f2f7d07e6f804c4f00ebf0325084dbc)),after(500000001))", "Bf"); ms_test("andor(sha256(926a54995ca48600920a19bf7bc502ca5f2f7d07e6f804c4f00ebf0325084dbc),or_d(multi(2,A,B,C),sha256(926a54995ca48600920a19bf7bc502ca5f2f7d07e6f804c4f00ebf0325084dbc)),after(1))", "B"); @@ -9154,7 +9154,7 @@ mod tests { } #[test] - #[cfg_attr(feature="cargo-fmt", rustfmt_skip)] + #[rustfmt::skip] fn main_tests_from_alloy() { ms_test("or_d(or_d(multi(2,A,B,C),or_d(multi(2,D,E,F),multi(2,G,I,J))),multi(2,K,L,M))", "Bdusem"); ms_test("andor(multi(2,A,B,C),or_d(multi(2,D,E,F),sha256(926a54995ca48600920a19bf7bc502ca5f2f7d07e6f804c4f00ebf0325084dbc)),c:pk_h(G))", "Bdusem"); @@ -15055,7 +15055,7 @@ mod tests { } #[test] - #[cfg_attr(feature="cargo-fmt", rustfmt_skip)] + #[rustfmt::skip] fn malleable_tests_from_alloy() { ms_test("and_v(v:after(500000001),or_d(j:multi(2,A,B,C),multi(2,D,E,F)))", "usB"); ms_test("or_b(j:multi(2,A,B,C),a:andor(multi(2,D,E,F),multi(2,G,I,J),multi(2,K,L,M)))", "dBesu"); @@ -22085,8 +22085,8 @@ mod tests { } #[test] + #[rustfmt::skip] fn conflict_tests_from_alloy() { - #[cfg_attr(feature="cargo-fmt", rustfmt_skip)] { ms_test("andor(multi(2,A,B,C),andor(multi(2,D,E,F),after(500000001),n:after(1)),0)","Bedsm"); ms_test("and_v(v:after(500000001),or_d(multi(2,A,B,C),and_b(multi(2,D,E,F),a:after(1))))","Busm"); diff --git a/src/miniscript/types/extra_props.rs b/src/miniscript/types/extra_props.rs index 1a55d68bc..375a3ef47 100644 --- a/src/miniscript/types/extra_props.rs +++ b/src/miniscript/types/extra_props.rs @@ -166,7 +166,7 @@ impl Property for ExtData { timelock_info: TimelockInfo::default(), exec_stack_elem_count_sat: Some(1), exec_stack_elem_count_dissat: None, - tree_height : 0, + tree_height: 0, } } @@ -182,7 +182,7 @@ impl Property for ExtData { timelock_info: TimelockInfo::default(), exec_stack_elem_count_sat: None, exec_stack_elem_count_dissat: Some(1), - tree_height : 0, + tree_height: 0, } } @@ -406,7 +406,7 @@ impl Property for ExtData { timelock_info: self.timelock_info, exec_stack_elem_count_sat: self.exec_stack_elem_count_sat, exec_stack_elem_count_dissat: self.exec_stack_elem_count_dissat, - tree_height : self.tree_height + 1, + tree_height: self.tree_height + 1, }) } @@ -422,7 +422,7 @@ impl Property for ExtData { timelock_info: self.timelock_info, exec_stack_elem_count_sat: self.exec_stack_elem_count_sat, exec_stack_elem_count_dissat: self.exec_stack_elem_count_dissat, - tree_height : self.tree_height + 1, + tree_height: self.tree_height + 1, }) } @@ -438,7 +438,7 @@ impl Property for ExtData { timelock_info: self.timelock_info, exec_stack_elem_count_sat: self.exec_stack_elem_count_sat, exec_stack_elem_count_dissat: self.exec_stack_elem_count_dissat, - tree_height : self.tree_height + 1, + tree_height: self.tree_height + 1, }) } @@ -457,7 +457,7 @@ impl Property for ExtData { // Even all V types push something onto the stack and then remove them exec_stack_elem_count_sat: self.exec_stack_elem_count_sat, exec_stack_elem_count_dissat: Some(1), - tree_height : self.tree_height + 1, + tree_height: self.tree_height + 1, }) } @@ -474,7 +474,7 @@ impl Property for ExtData { timelock_info: self.timelock_info, exec_stack_elem_count_sat: self.exec_stack_elem_count_sat, exec_stack_elem_count_dissat: None, - tree_height : self.tree_height + 1, + tree_height: self.tree_height + 1, }) } @@ -490,7 +490,7 @@ impl Property for ExtData { timelock_info: self.timelock_info, exec_stack_elem_count_sat: self.exec_stack_elem_count_sat, exec_stack_elem_count_dissat: Some(1), - tree_height : self.tree_height + 1, + tree_height: self.tree_height + 1, }) } @@ -507,7 +507,7 @@ impl Property for ExtData { // Technically max(1, self.exec_stack_elem_count_sat), same rationale as cast_dupif exec_stack_elem_count_sat: self.exec_stack_elem_count_sat, exec_stack_elem_count_dissat: self.exec_stack_elem_count_dissat, - tree_height : self.tree_height + 1, + tree_height: self.tree_height + 1, }) } @@ -548,7 +548,7 @@ impl Property for ExtData { l.exec_stack_elem_count_dissat, r.exec_stack_elem_count_dissat.map(|x| x + 1), ), - tree_height : cmp::max(l.tree_height, r.tree_height) + 1, + tree_height: cmp::max(l.tree_height, r.tree_height) + 1, }) } @@ -576,7 +576,7 @@ impl Property for ExtData { r.exec_stack_elem_count_sat, ), exec_stack_elem_count_dissat: None, - tree_height : cmp::max(l.tree_height, r.tree_height) + 1, + tree_height: cmp::max(l.tree_height, r.tree_height) + 1, }) } @@ -625,7 +625,7 @@ impl Property for ExtData { l.exec_stack_elem_count_dissat, r.exec_stack_elem_count_dissat.map(|x| x + 1), ), - tree_height : cmp::max(l.tree_height, r.tree_height) + 1, + tree_height: cmp::max(l.tree_height, r.tree_height) + 1, }) } @@ -663,7 +663,7 @@ impl Property for ExtData { l.exec_stack_elem_count_dissat, r.exec_stack_elem_count_dissat.map(|x| x + 1), ), - tree_height : cmp::max(l.tree_height, r.tree_height) + 1, + tree_height: cmp::max(l.tree_height, r.tree_height) + 1, }; Ok(res) } @@ -695,7 +695,7 @@ impl Property for ExtData { opt_max(r.exec_stack_elem_count_sat, l.exec_stack_elem_count_dissat), ), exec_stack_elem_count_dissat: None, - tree_height : cmp::max(l.tree_height, r.tree_height) + 1, + tree_height: cmp::max(l.tree_height, r.tree_height) + 1, }) } @@ -743,7 +743,7 @@ impl Property for ExtData { l.exec_stack_elem_count_dissat, r.exec_stack_elem_count_dissat, ), - tree_height : cmp::max(l.tree_height, r.tree_height) + 1, + tree_height: cmp::max(l.tree_height, r.tree_height) + 1, }) } @@ -789,7 +789,7 @@ impl Property for ExtData { a.exec_stack_elem_count_dissat, c.exec_stack_elem_count_dissat, ), - tree_height : cmp::max(a.tree_height, cmp::max(b.tree_height, c.tree_height)) + 1, + tree_height: cmp::max(a.tree_height, cmp::max(b.tree_height, c.tree_height)) + 1, }) } @@ -915,7 +915,7 @@ impl Property for ExtData { timelock_info: TimelockInfo::combine_threshold(k, timelocks), exec_stack_elem_count_sat, exec_stack_elem_count_dissat, - tree_height : max_child_height + 1, + tree_height: max_child_height + 1, }) } diff --git a/src/policy/compiler.rs b/src/policy/compiler.rs index 77febf917..22bb0f04a 100644 --- a/src/policy/compiler.rs +++ b/src/policy/compiler.rs @@ -506,9 +506,7 @@ impl AstElemExt { let ext = types::ExtData::type_check(&ast, |_| None)?; let comp_ext_data = CompilerExtData::type_check(&ast, lookup_ext)?; Ok(AstElemExt { - ms: Arc::new( - Miniscript::from_components_unchecked(ast, ty, ext) - ), + ms: Arc::new(Miniscript::from_components_unchecked(ast, ty, ext)), comp_ext_data, }) } @@ -531,9 +529,7 @@ impl AstElemExt { let ext = types::ExtData::type_check(&ast, |_| None)?; let comp_ext_data = CompilerExtData::type_check(&ast, lookup_ext)?; Ok(AstElemExt { - ms: Arc::new( - Miniscript::from_components_unchecked(ast, ty, ext) - ), + ms: Arc::new(Miniscript::from_components_unchecked(ast, ty, ext)), comp_ext_data, }) } @@ -1002,9 +998,7 @@ where let ast = Terminal::Thresh(k, sub_ast); let ast_ext = AstElemExt { - ms: Arc::new( - Miniscript::from_ast(ast).map_err(|_| CompilerError::LimitsExceeded)?, - ), + ms: Arc::new(Miniscript::from_ast(ast).map_err(|_| CompilerError::LimitsExceeded)?), comp_ext_data: CompilerExtData::threshold(k, n, |i| Ok(sub_ext_data[i])) .expect("threshold subs, which we just compiled, typeck"), }; diff --git a/src/policy/concrete.rs b/src/policy/concrete.rs index a91545beb..1f3e91c55 100644 --- a/src/policy/concrete.rs +++ b/src/policy/concrete.rs @@ -675,7 +675,9 @@ impl Policy { Policy::Threshold(_, ref subs) | Policy::And(ref subs) => { subs.iter().all(|sub| sub.real_for_each_key(&mut *pred)) } - Policy::Or(ref subs) => subs.iter().all(|(_, sub)| sub.real_for_each_key(&mut *pred)), + Policy::Or(ref subs) => subs + .iter() + .all(|(_, sub)| sub.real_for_each_key(&mut *pred)), } } @@ -1350,15 +1352,19 @@ mod compiler_tests { #[cfg(test)] mod tests { - use super::*; use std::str::FromStr; + use super::*; + #[test] fn for_each_key() { let liquid_pol = Policy::::from_str( "or(and(older(4096),thresh(2,pk(A),pk(B),pk(C))),thresh(11,pk(F1),pk(F2),pk(F3),pk(F4),pk(F5),pk(F6),pk(F7),pk(F8),pk(F9),pk(F10),pk(F11),pk(F12),pk(F13),pk(F14)))").unwrap(); let mut count = 0; - assert!(liquid_pol.for_each_key(|_| { count +=1; true })); + assert!(liquid_pol.for_each_key(|_| { + count += 1; + true + })); assert_eq!(count, 17); } } diff --git a/src/policy/semantic.rs b/src/policy/semantic.rs index 8239de456..ef7f858f7 100644 --- a/src/policy/semantic.rs +++ b/src/policy/semantic.rs @@ -91,7 +91,9 @@ impl Policy { | Policy::Hash160(..) | Policy::After(..) | Policy::Older(..) => true, - Policy::Threshold(_, ref subs) => subs.iter().all(|sub| sub.real_for_each_key(&mut *pred)), + Policy::Threshold(_, ref subs) => { + subs.iter().all(|sub| sub.real_for_each_key(&mut *pred)) + } } } @@ -1004,7 +1006,10 @@ mod tests { let liquid_pol = StringPolicy::from_str( "or(and(older(4096),thresh(2,pk(A),pk(B),pk(C))),thresh(11,pk(F1),pk(F2),pk(F3),pk(F4),pk(F5),pk(F6),pk(F7),pk(F8),pk(F9),pk(F10),pk(F11),pk(F12),pk(F13),pk(F14)))").unwrap(); let mut count = 0; - assert!(liquid_pol.for_each_key(|_| { count +=1; true })); + assert!(liquid_pol.for_each_key(|_| { + count += 1; + true + })); assert_eq!(count, 17); } } From ea545203e9b413fe2b87c707715b45609709d3c6 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sat, 5 Jul 2025 01:51:23 +0000 Subject: [PATCH 06/11] clippy: non-reference stuff As in other PRs, the meaningful changes here are: 'A'..'Z' becoming 'A'..='Z', and the partial_cmp replacements. --- clippy.toml | 8 +++++ examples/psbt_sign_finalize.rs | 20 ++++++------- examples/taproot.rs | 4 +-- examples/verify_tx.rs | 24 ++++++--------- src/descriptor/key.rs | 20 +++++-------- src/descriptor/mod.rs | 3 +- src/descriptor/sortedmulti.rs | 8 ++--- src/descriptor/tr.rs | 11 ++----- src/interpreter/inner.rs | 28 ++++++++---------- src/interpreter/mod.rs | 46 +++++++---------------------- src/lib.rs | 10 ------- src/miniscript/analyzable.rs | 8 ++--- src/miniscript/astelem.rs | 4 +-- src/miniscript/context.rs | 9 ++---- src/miniscript/decode.rs | 2 +- src/miniscript/iter.rs | 4 +-- src/miniscript/mod.rs | 6 ++-- src/miniscript/types/correctness.rs | 6 ++-- src/miniscript/types/extra_props.rs | 44 ++++++++++++--------------- src/policy/compiler.rs | 42 +++++++++++++------------- src/policy/concrete.rs | 6 ++-- src/policy/semantic.rs | 11 +++---- src/psbt/mod.rs | 25 ++++------------ src/test_utils.rs | 4 +-- 24 files changed, 136 insertions(+), 217 deletions(-) diff --git a/clippy.toml b/clippy.toml index 799264ef1..92cf0149a 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1 +1,9 @@ msrv = "1.41.1" +# PSBT API returns Self as an error type for an large-ish enum +large-error-threshold = 512 +# A couple tests have huge tuples instead of structs. This is fixed +# in a later major rev. For now we just turn down the lint. +type-complexity-threshold = 1000 +# Some internal compiler functions take a gazillion arguments. Again, +# this is fixed in a later major rev so just turn down the lint here. +too-many-arguments-threshold = 9 diff --git a/examples/psbt_sign_finalize.rs b/examples/psbt_sign_finalize.rs index 735d310a0..f7f3dfd63 100644 --- a/examples/psbt_sign_finalize.rs +++ b/examples/psbt_sign_finalize.rs @@ -2,9 +2,9 @@ use std::collections::BTreeMap; use std::str::FromStr; use bitcoin::consensus::serialize; +use bitcoin::hashes::hex::ToHex as _; use bitcoin::util::sighash::SighashCache; use bitcoin::{PackedLockTime, PrivateKey}; -use bitcoin::hashes::hex::ToHex as _; use miniscript::bitcoin::consensus::encode::deserialize; use miniscript::bitcoin::hashes::hex::FromHex; use miniscript::bitcoin::util::psbt; @@ -97,10 +97,12 @@ fn main() { let (outpoint, witness_utxo) = get_vout(&depo_tx, bridge_descriptor.script_pubkey()); - let mut txin = TxIn::default(); - txin.previous_output = outpoint; + let txin = TxIn { + previous_output: outpoint, - txin.sequence = Sequence::from_height(26); //Sequence::MAX; // + sequence: Sequence::from_height(26), + ..TxIn::default() + }; psbt.unsigned_tx.input.push(txin); psbt.unsigned_tx.output.push(TxOut { @@ -147,13 +149,9 @@ fn main() { let pk2 = backup2_private.public_key(&secp256k1); assert!(secp256k1.verify_ecdsa(&msg, &sig2, &pk2.inner).is_ok()); - psbt.inputs[0].partial_sigs.insert( - pk1, - bitcoin::EcdsaSig { - sig: sig1, - hash_ty: hash_ty, - }, - ); + psbt.inputs[0] + .partial_sigs + .insert(pk1, bitcoin::EcdsaSig { sig: sig1, hash_ty }); println!("{:#?}", psbt); diff --git a/examples/taproot.rs b/examples/taproot.rs index 576c0192f..5428d9b48 100644 --- a/examples/taproot.rs +++ b/examples/taproot.rs @@ -136,8 +136,8 @@ fn hardcoded_xonlypubkeys() -> Vec { ], ]; let mut keys: Vec = vec![]; - for idx in 0..4 { - keys.push(bitcoin::XOnlyPublicKey::from_slice(&serialized_keys[idx][..]).unwrap()); + for key in &serialized_keys { + keys.push(bitcoin::XOnlyPublicKey::from_slice(key).unwrap()); } keys } diff --git a/examples/verify_tx.rs b/examples/verify_tx.rs index 699f2408d..32965caa0 100644 --- a/examples/verify_tx.rs +++ b/examples/verify_tx.rs @@ -59,15 +59,12 @@ fn main() { for elem in interpreter.iter_assume_sigs() { // Don't bother checking signatures. - match elem.expect("no evaluation error") { - miniscript::interpreter::SatisfiedConstraint::PublicKey { key_sig } => { - let (key, sig) = key_sig - .as_ecdsa() - .expect("expected ecdsa sig, found schnorr sig"); - - println!("Signed with:\n key: {}\n sig: {}", key, sig); - } - _ => {} + if let Ok(miniscript::interpreter::SatisfiedConstraint::PublicKey { key_sig }) = elem { + let (key, sig) = key_sig + .as_ecdsa() + .expect("expected ecdsa sig, found schnorr sig"); + + println!("Signed with:\n key: {}\n sig: {}", key, sig); } } @@ -84,12 +81,9 @@ fn main() { let prevouts = sighash::Prevouts::All::(&[]); for elem in interpreter.iter(&secp, &tx, 0, &prevouts) { - match elem.expect("no evaluation error") { - miniscript::interpreter::SatisfiedConstraint::PublicKey { key_sig } => { - let (key, sig) = key_sig.as_ecdsa().unwrap(); - println!("Signed with:\n key: {}\n sig: {}", key, sig); - } - _ => {} + if let Ok(miniscript::interpreter::SatisfiedConstraint::PublicKey { key_sig }) = elem { + let (key, sig) = key_sig.as_ecdsa().unwrap(); + println!("Signed with:\n key: {}\n sig: {}", key, sig); } } diff --git a/src/descriptor/key.rs b/src/descriptor/key.rs index 6af0146e0..62cb21b51 100644 --- a/src/descriptor/key.rs +++ b/src/descriptor/key.rs @@ -665,9 +665,7 @@ impl DescriptorXKey { let (compare_fingerprint, compare_path) = match self.origin { Some((fingerprint, ref path)) => ( fingerprint, - path.into_iter() - .chain(self.derivation_path.into_iter()) - .collect(), + path.into_iter().chain(&self.derivation_path).collect(), ), None => ( self.xkey.xkey_fingerprint(secp), @@ -784,11 +782,9 @@ impl FromStr for DefiniteDescriptorKey { fn from_str(s: &str) -> Result { let inner = DescriptorPublicKey::from_str(s)?; - Ok( - DefiniteDescriptorKey::new(inner).ok_or(DescriptorKeyParseError( - "cannot parse key with a wilcard as a DerivedDescriptorKey", - ))?, - ) + DefiniteDescriptorKey::new(inner).ok_or(DescriptorKeyParseError( + "cannot parse key with a wilcard as a DerivedDescriptorKey", + )) } } @@ -948,17 +944,17 @@ mod test { let public_key = DescriptorPublicKey::from_str("[abcdef00/0'/1']tpubDBrgjcxBxnXyL575sHdkpKohWu5qHKoQ7TJXKNrYznh5fVEGBv89hA8ENW7A8MFVpFUSvgLqc4Nj1WZcpePX6rrxviVtPowvMuGF5rdT2Vi/2").unwrap(); assert_eq!(public_key.master_fingerprint().to_string(), "abcdef00"); assert_eq!(public_key.full_derivation_path().to_string(), "m/0'/1'/2"); - assert_eq!(public_key.has_wildcard(), false); + assert!(!public_key.has_wildcard()); let public_key = DescriptorPublicKey::from_str("[abcdef00/0'/1']tpubDBrgjcxBxnXyL575sHdkpKohWu5qHKoQ7TJXKNrYznh5fVEGBv89hA8ENW7A8MFVpFUSvgLqc4Nj1WZcpePX6rrxviVtPowvMuGF5rdT2Vi/*").unwrap(); assert_eq!(public_key.master_fingerprint().to_string(), "abcdef00"); assert_eq!(public_key.full_derivation_path().to_string(), "m/0'/1'"); - assert_eq!(public_key.has_wildcard(), true); + assert!(public_key.has_wildcard()); let public_key = DescriptorPublicKey::from_str("[abcdef00/0'/1']tpubDBrgjcxBxnXyL575sHdkpKohWu5qHKoQ7TJXKNrYznh5fVEGBv89hA8ENW7A8MFVpFUSvgLqc4Nj1WZcpePX6rrxviVtPowvMuGF5rdT2Vi/*h").unwrap(); assert_eq!(public_key.master_fingerprint().to_string(), "abcdef00"); assert_eq!(public_key.full_derivation_path().to_string(), "m/0'/1'"); - assert_eq!(public_key.has_wildcard(), true); + assert!(public_key.has_wildcard()); } #[test] @@ -970,7 +966,7 @@ mod test { assert_eq!(public_key.to_string(), "[2cbe2a6d/0'/1']tpubDBrgjcxBxnXyL575sHdkpKohWu5qHKoQ7TJXKNrYznh5fVEGBv89hA8ENW7A8MFVpFUSvgLqc4Nj1WZcpePX6rrxviVtPowvMuGF5rdT2Vi/2"); assert_eq!(public_key.master_fingerprint().to_string(), "2cbe2a6d"); assert_eq!(public_key.full_derivation_path().to_string(), "m/0'/1'/2"); - assert_eq!(public_key.has_wildcard(), false); + assert!(!public_key.has_wildcard()); let secret_key = DescriptorSecretKey::from_str("tprv8ZgxMBicQKsPcwcD4gSnMti126ZiETsuX7qwrtMypr6FBwAP65puFn4v6c3jrN9VwtMRMph6nyT63NrfUL4C3nBzPcduzVSuHD7zbX2JKVc/0'/1'/2'").unwrap(); let public_key = secret_key.to_public(&secp).unwrap(); diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index 31a30b2e3..d6516be1c 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -856,8 +856,7 @@ mod tests { use crate::{hex_script, Descriptor, DummyKey, Error, Miniscript, Satisfier}; type StdDescriptor = Descriptor; - const TEST_PK: &'static str = - "pk(020000000000000000000000000000000000000000000000000000000000000002)"; + const TEST_PK: &str = "pk(020000000000000000000000000000000000000000000000000000000000000002)"; impl cmp::PartialEq for DescriptorSecretKey { fn eq(&self, other: &Self) -> bool { diff --git a/src/descriptor/sortedmulti.rs b/src/descriptor/sortedmulti.rs index 7857188b0..352ffd0fe 100644 --- a/src/descriptor/sortedmulti.rs +++ b/src/descriptor/sortedmulti.rs @@ -112,11 +112,11 @@ impl SortedMultiVec { } impl ForEachKey for SortedMultiVec { - fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool + fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool where Pk: 'a, { - self.pks.iter().all(|key| pred(key)) + self.pks.iter().all(pred) } } @@ -258,11 +258,11 @@ mod tests { let mut pks = Vec::new(); for _ in 0..over { - pks.push(pk.clone()); + pks.push(pk); } let res: Result, Error> = SortedMultiVec::new(0, pks); - let error = res.err().expect("constructor should err"); + let error = res.expect_err("constructor should err"); match error { Error::BadDescriptor(_) => {} // ok diff --git a/src/descriptor/tr.rs b/src/descriptor/tr.rs index 3607461b9..91e71fbc5 100644 --- a/src/descriptor/tr.rs +++ b/src/descriptor/tr.rs @@ -81,11 +81,7 @@ impl Eq for Tr {} impl PartialOrd for Tr { fn partial_cmp(&self, other: &Self) -> Option { - match self.internal_key.partial_cmp(&other.internal_key) { - Some(cmp::Ordering::Equal) => {} - ord => return ord, - } - self.tree.partial_cmp(&other.tree) + Some(self.cmp(other)) } } @@ -352,9 +348,8 @@ where type Item = (u8, &'a Miniscript); fn next(&mut self) -> Option { - while !self.stack.is_empty() { - let (depth, last) = self.stack.pop().expect("Size checked above"); - match &*last { + while let Some((depth, last)) = self.stack.pop() { + match last { TapTree::Tree(l, r) => { self.stack.push((depth + 1, r)); self.stack.push((depth + 1, l)); diff --git a/src/interpreter/inner.rs b/src/interpreter/inner.rs index 59c8eb213..eed1398f7 100644 --- a/src/interpreter/inner.rs +++ b/src/interpreter/inner.rs @@ -344,22 +344,20 @@ pub(super) fn from_txdata<'txin>( None => Err(Error::UnexpectedStackEnd), } // ** bare script ** + } else if wit_stack.is_empty() { + // Bare script parsed in BareCtx + let miniscript = Miniscript::::parse_with_ext( + spk, + &ExtParams::allow_all(), + )?; + let miniscript = miniscript.to_no_checks_ms(); + Ok(( + Inner::Script(miniscript, ScriptType::Bare), + ssig_stack, + Some(spk.clone()), + )) } else { - if wit_stack.is_empty() { - // Bare script parsed in BareCtx - let miniscript = Miniscript::::parse_with_ext( - spk, - &ExtParams::allow_all(), - )?; - let miniscript = miniscript.to_no_checks_ms(); - Ok(( - Inner::Script(miniscript, ScriptType::Bare), - ssig_stack, - Some(spk.clone()), - )) - } else { - Err(Error::NonEmptyWitness) - } + Err(Error::NonEmptyWitness) } } diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 293fd3273..8720fc355 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -103,7 +103,7 @@ enum BitcoinKey { } impl BitcoinKey { - fn to_pubkeyhash(&self, sig_type: SigType) -> hash160::Hash { + fn to_pubkeyhash(self, sig_type: SigType) -> hash160::Hash { match self { BitcoinKey::Fullkey(pk) => pk.to_pubkeyhash(sig_type), BitcoinKey::XOnlyPublicKey(pk) => pk.to_pubkeyhash(sig_type), @@ -1123,7 +1123,7 @@ mod tests { let (pks, der_sigs, ecdsa_sigs, sighash, secp, xpks, schnorr_sigs, ser_schnorr_sigs) = setup_keys_sigs(10); let secp_ref = &secp; - let vfyfn_ = |pksig: &KeySigPair| match pksig { + let vfyfn = |pksig: &KeySigPair| match pksig { KeySigPair::Ecdsa(pk, ecdsa_sig) => secp_ref .verify_ecdsa(&sighash, &ecdsa_sig.sig, &pk.inner) .is_ok(), @@ -1139,7 +1139,7 @@ mod tests { ) -> Iter<'elem, 'txin> { Iter { verify_sig: verify_fn, - stack: stack, + stack, public_key: None, state: vec![NodeEvaluationState { node: &ms, @@ -1159,7 +1159,7 @@ mod tests { let after = no_checks_ms(&format!("after({})", 1000)); let older = no_checks_ms(&format!("older({})", 1000)); //Hashes - let preimage = [0xab as u8; 32]; + let preimage = [0xab_u8; 32]; let sha256_hash = sha256::Hash::hash(&preimage); let sha256 = no_checks_ms(&format!("sha256({})", sha256_hash)); let hash256_hash = hash256::Hash::hash(&preimage); @@ -1170,7 +1170,6 @@ mod tests { let ripemd160 = no_checks_ms(&format!("ripemd160({})", ripemd160_hash)); let stack = Stack::from(vec![stack::Element::Push(&der_sigs[0])]); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &pk); let pk_satisfied: Result, Error> = constraints.collect(); assert_eq!( @@ -1182,7 +1181,6 @@ mod tests { //Check Pk failure with wrong signature let stack = Stack::from(vec![stack::Element::Dissatisfied]); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &pk); let pk_err: Result, Error> = constraints.collect(); assert!(pk_err.is_err()); @@ -1193,7 +1191,6 @@ mod tests { stack::Element::Push(&der_sigs[1]), stack::Element::Push(&pk_bytes), ]); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &pkh); let pkh_satisfied: Result, Error> = constraints.collect(); assert_eq!( @@ -1206,7 +1203,6 @@ mod tests { //Check After let stack = Stack::from(vec![]); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &after); let after_satisfied: Result, Error> = constraints.collect(); assert_eq!( @@ -1218,7 +1214,6 @@ mod tests { //Check Older let stack = Stack::from(vec![]); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &older); let older_satisfied: Result, Error> = constraints.collect(); assert_eq!( @@ -1230,53 +1225,49 @@ mod tests { //Check Sha256 let stack = Stack::from(vec![stack::Element::Push(&preimage)]); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &sha256); let sah256_satisfied: Result, Error> = constraints.collect(); assert_eq!( sah256_satisfied.unwrap(), vec![SatisfiedConstraint::HashLock { hash: HashLockType::Sha256(sha256_hash), - preimage: preimage, + preimage, }] ); //Check Shad256 let stack = Stack::from(vec![stack::Element::Push(&preimage)]); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &hash256); let sha256d_satisfied: Result, Error> = constraints.collect(); assert_eq!( sha256d_satisfied.unwrap(), vec![SatisfiedConstraint::HashLock { hash: HashLockType::Hash256(hash256_hash), - preimage: preimage, + preimage, }] ); //Check hash160 let stack = Stack::from(vec![stack::Element::Push(&preimage)]); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &hash160); let hash160_satisfied: Result, Error> = constraints.collect(); assert_eq!( hash160_satisfied.unwrap(), vec![SatisfiedConstraint::HashLock { hash: HashLockType::Hash160(hash160_hash), - preimage: preimage, + preimage, }] ); //Check ripemd160 let stack = Stack::from(vec![stack::Element::Push(&preimage)]); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &ripemd160); let ripemd160_satisfied: Result, Error> = constraints.collect(); assert_eq!( ripemd160_satisfied.unwrap(), vec![SatisfiedConstraint::HashLock { hash: HashLockType::Ripemd160(ripemd160_hash), - preimage: preimage + preimage, }] ); @@ -1288,7 +1279,6 @@ mod tests { stack::Element::Push(&der_sigs[0]), ]); let elem = no_checks_ms(&format!("and_v(vc:pk_k({}),c:pk_h({}))", pks[0], pks[1])); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &elem); let and_v_satisfied: Result, Error> = constraints.collect(); @@ -1314,7 +1304,6 @@ mod tests { "and_b(c:pk_k({}),sjtv:sha256({}))", pks[0], sha256_hash )); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &elem); let and_b_satisfied: Result, Error> = constraints.collect(); @@ -1326,7 +1315,7 @@ mod tests { }, SatisfiedConstraint::HashLock { hash: HashLockType::Sha256(sha256_hash), - preimage: preimage, + preimage, } ] ); @@ -1340,7 +1329,6 @@ mod tests { "andor(c:pk_k({}),jtv:sha256({}),c:pk_h({}))", pks[0], sha256_hash, pks[1], )); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &elem); let and_or_satisfied: Result, Error> = constraints.collect(); @@ -1352,7 +1340,7 @@ mod tests { }, SatisfiedConstraint::HashLock { hash: HashLockType::Sha256(sha256_hash), - preimage: preimage, + preimage, } ] ); @@ -1364,7 +1352,6 @@ mod tests { stack::Element::Push(&pk_bytes), stack::Element::Dissatisfied, ]); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &elem); let and_or_satisfied: Result, Error> = constraints.collect(); @@ -1385,7 +1372,6 @@ mod tests { "or_b(c:pk_k({}),sjtv:sha256({}))", pks[0], sha256_hash )); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &elem); let or_b_satisfied: Result, Error> = constraints.collect(); @@ -1393,7 +1379,7 @@ mod tests { or_b_satisfied.unwrap(), vec![SatisfiedConstraint::HashLock { hash: HashLockType::Sha256(sha256_hash), - preimage: preimage, + preimage, }] ); @@ -1403,7 +1389,6 @@ mod tests { "or_d(c:pk_k({}),jtv:sha256({}))", pks[0], sha256_hash )); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &elem); let or_d_satisfied: Result, Error> = constraints.collect(); @@ -1423,7 +1408,6 @@ mod tests { "t:or_c(jtv:sha256({}),vc:pk_k({}))", sha256_hash, pks[0] )); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &elem); let or_c_satisfied: Result, Error> = constraints.collect(); @@ -1443,7 +1427,6 @@ mod tests { "or_i(jtv:sha256({}),c:pk_k({}))", sha256_hash, pks[0] )); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &elem); let or_i_satisfied: Result, Error> = constraints.collect(); @@ -1466,7 +1449,6 @@ mod tests { "thresh(3,c:pk_k({}),sc:pk_k({}),sc:pk_k({}),sc:pk_k({}),sc:pk_k({}))", pks[4], pks[3], pks[2], pks[1], pks[0], )); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &elem); let thresh_satisfied: Result, Error> = constraints.collect(); @@ -1496,7 +1478,6 @@ mod tests { "multi(3,{},{},{},{},{})", pks[4], pks[3], pks[2], pks[1], pks[0], )); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &elem); let multi_satisfied: Result, Error> = constraints.collect(); @@ -1526,7 +1507,6 @@ mod tests { "multi(3,{},{},{},{},{})", pks[4], pks[3], pks[2], pks[1], pks[0], )); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &elem); let multi_error: Result, Error> = constraints.collect(); @@ -1545,7 +1525,6 @@ mod tests { "multi_a(3,{},{},{},{},{})", xpks[0], xpks[1], xpks[2], xpks[3], xpks[4], )); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &elem); let multi_a_satisfied: Result, Error> = constraints.collect(); @@ -1577,7 +1556,6 @@ mod tests { "multi_a(3,{},{},{},{},{})", xpks[0], xpks[1], xpks[2], xpks[3], xpks[4], )); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack.clone(), &elem); let multi_a_error: Result, Error> = constraints.collect(); @@ -1588,7 +1566,6 @@ mod tests { "multi_a(2,{},{},{},{},{})", xpks[0], xpks[1], xpks[2], xpks[3], xpks[4], )); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack.clone(), &elem); let multi_a_error: Result, Error> = constraints.collect(); @@ -1599,7 +1576,6 @@ mod tests { "multi_a(3,{},{},{},{},{},{})", xpks[0], xpks[1], xpks[2], xpks[3], xpks[4], xpks[5] )); - let vfyfn = vfyfn_.clone(); // sigh rust 1.29... let constraints = from_stack(Box::new(vfyfn), stack, &elem); let multi_a_error: Result, Error> = constraints.collect(); diff --git a/src/lib.rs b/src/lib.rs index 34445439b..9ce19351e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -557,16 +557,6 @@ where T: Translator; } -/// Either a key or keyhash, but both contain Pk -// pub struct ForEach<'a, Pk: MiniscriptKey>(&'a Pk); - -// impl<'a, Pk: MiniscriptKey> ForEach<'a, Pk> { -// /// Convenience method to avoid distinguishing between keys and hashes when these are the same type -// pub fn as_key(&self) -> &'a Pk { -// self.0 -// } -// } - /// Trait describing the ability to iterate over every key pub trait ForEachKey { /// Run a predicate on every key in the descriptor, returning whether diff --git a/src/miniscript/analyzable.rs b/src/miniscript/analyzable.rs index a98d2acbf..e7ea2d73d 100644 --- a/src/miniscript/analyzable.rs +++ b/src/miniscript/analyzable.rs @@ -29,9 +29,7 @@ use crate::{Miniscript, MiniscriptKey, ScriptContext, Terminal}; /// /// This allows parsing miniscripts if /// 1. It is unsafe(does not require a digital signature to spend it) -/// 2. It contains a unspendable path because of either -/// a. Resource limitations -/// b. Timelock Mixing +/// 2. It contains a unspendable path because of either resource limitations or timelock mixing. /// 3. The script is malleable and thereby some of satisfaction weight /// guarantees are not satisfied. /// 4. It has repeated public keys @@ -137,9 +135,7 @@ impl ExtParams { /// Possible reasons Miniscript guarantees can fail /// We currently mark Miniscript as Non-Analyzable if /// 1. It is unsafe(does not require a digital signature to spend it) -/// 2. It contains a unspendable path because of either -/// a. Resource limitations -/// b. Timelock Mixing +/// 2. It contains a unspendable path because of either resource limitations or timelock mixing. /// 3. The script is malleable and thereby some of satisfaction weight /// guarantees are not satisfied. /// 4. It has repeated publickeys diff --git a/src/miniscript/astelem.rs b/src/miniscript/astelem.rs index e691ff931..c1557ad6a 100644 --- a/src/miniscript/astelem.rs +++ b/src/miniscript/astelem.rs @@ -113,9 +113,7 @@ impl Terminal { && c.real_for_each_key(pred) } Terminal::Thresh(_, ref subs) => subs.iter().all(|sub| sub.real_for_each_key(pred)), - Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => { - keys.iter().all(|key| pred(key)) - } + Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => keys.iter().all(pred), } } diff --git a/src/miniscript/context.rs b/src/miniscript/context.rs index 410d65031..d17cb9509 100644 --- a/src/miniscript/context.rs +++ b/src/miniscript/context.rs @@ -712,12 +712,9 @@ impl ScriptContext for BareCtx { return Err(ScriptContextError::MaxWitnessScriptSizeExceeded); } match ms.node { - Terminal::PkK(ref key) if key.is_x_only_key() => { - return Err(ScriptContextError::XOnlyKeysNotAllowed( - key.to_string(), - Self::name_str(), - )) - } + Terminal::PkK(ref key) if key.is_x_only_key() => Err( + ScriptContextError::XOnlyKeysNotAllowed(key.to_string(), Self::name_str()), + ), Terminal::Multi(_k, ref pks) => { if pks.len() > MAX_PUBKEYS_PER_MULTISIG { return Err(ScriptContextError::CheckMultiSigLimitExceeded); diff --git a/src/miniscript/decode.rs b/src/miniscript/decode.rs index 290e9f7dc..ee6e4e6ce 100644 --- a/src/miniscript/decode.rs +++ b/src/miniscript/decode.rs @@ -123,8 +123,8 @@ enum NonTerm { /// /// The average user should always use the [`crate::Descriptor`] APIs. Advanced users /// who want deal with Miniscript ASTs should use the [`crate::Miniscript`] APIs. -#[allow(broken_intra_doc_links)] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[allow(broken_intra_doc_links)] pub enum Terminal { /// `1` True, diff --git a/src/miniscript/iter.rs b/src/miniscript/iter.rs index 45f3ccbb3..bef0ea1af 100644 --- a/src/miniscript/iter.rs +++ b/src/miniscript/iter.rs @@ -272,10 +272,10 @@ pub mod test { .map(|pk| hash160::Hash::hash(&pk.to_bytes())) .collect(); - let preimage = vec![0xab as u8; 32]; + let preimage = vec![0xab_u8; 32]; let sha256_hash = sha256::Hash::hash(&preimage); let sha256d_hash_rev = sha256d::Hash::hash(&preimage); - let mut sha256d_hash_bytes = sha256d_hash_rev.clone().into_inner(); + let mut sha256d_hash_bytes = sha256d_hash_rev.into_inner(); sha256d_hash_bytes.reverse(); let sha256d_hash = sha256d::Hash::from_inner(sha256d_hash_bytes); let hash160_hash = hash160::Hash::hash(&preimage); diff --git a/src/miniscript/mod.rs b/src/miniscript/mod.rs index 3dff15739..2c4375ebc 100644 --- a/src/miniscript/mod.rs +++ b/src/miniscript/mod.rs @@ -125,7 +125,7 @@ pub use private::Miniscript; /// by the ast. impl PartialOrd for Miniscript { fn partial_cmp(&self, other: &Miniscript) -> Option { - Some(self.node.cmp(&other.node)) + Some(self.cmp(other)) } } @@ -474,7 +474,7 @@ impl_from_tree!( /// should not be called directly; rather go through the descriptor API. fn from_tree(top: &expression::Tree) -> Result, Error> { let inner: Terminal = expression::FromTree::from_tree(top)?; - Ok(Miniscript::from_ast(inner)?) + Miniscript::from_ast(inner) } ); @@ -627,7 +627,7 @@ mod tests { assert_eq!(ms.ty.mall.safe, need_sig); assert_eq!(ms.ext.ops.op_count().unwrap(), ops); } - (Err(_), false) => return, + (Err(_), false) => {} _ => unreachable!(), } } diff --git a/src/miniscript/types/correctness.rs b/src/miniscript/types/correctness.rs index 1beba0798..9c989c71e 100644 --- a/src/miniscript/types/correctness.rs +++ b/src/miniscript/types/correctness.rs @@ -496,10 +496,8 @@ impl Property for Correctness { if subtype.base != Base::B { return Err(ErrorKind::ThresholdBase(i, subtype.base)); } - } else { - if subtype.base != Base::W { - return Err(ErrorKind::ThresholdBase(i, subtype.base)); - } + } else if subtype.base != Base::W { + return Err(ErrorKind::ThresholdBase(i, subtype.base)); } if !subtype.unit { return Err(ErrorKind::ThresholdNonUnit(i)); diff --git a/src/miniscript/types/extra_props.rs b/src/miniscript/types/extra_props.rs index 375a3ef47..f78b9f050 100644 --- a/src/miniscript/types/extra_props.rs +++ b/src/miniscript/types/extra_props.rs @@ -852,11 +852,11 @@ impl Property for ExtData { .iter() .rev() .enumerate() - .fold(Some(0), |acc, (i, &(x, y))| { + .try_fold(0, |acc, (i, &(x, y))| { if i <= k { - opt_add(acc, x) + x.map(|x| acc + x) } else { - opt_add(acc, y) + y.map(|y| acc + y) } }); @@ -865,11 +865,11 @@ impl Property for ExtData { .iter() .rev() .enumerate() - .fold(Some(0), |acc, (i, &(x, y))| { + .try_fold(0, |acc, (i, &(x, y))| { if i <= k { - opt_max(acc, x) + x.map(|x| cmp::max(acc, x)) } else { - opt_max(acc, y) + y.map(|y| cmp::max(acc, y)) } }); @@ -879,26 +879,25 @@ impl Property for ExtData { max_sat_size_vec .iter() .enumerate() - .fold(Some((0, 0)), |acc, (i, &(x, y))| { + .try_fold((0, 0), |acc, (i, &(x, y))| { if i <= k { - opt_tuple_add(acc, x) + x.map(|x| (acc.0 + x.0, acc.1 + x.1)) } else { - opt_tuple_add(acc, y) + y.map(|y| (acc.0 + y.0, acc.1 + y.1)) } }); ops_count_sat_vec.sort_by(sat_minus_dissat); - let op_count_sat = - ops_count_sat_vec - .iter() - .enumerate() - .fold(Some(0), |acc, (i, &(x, y))| { - if i <= k { - opt_add(acc, x) - } else { - opt_add(acc, Some(y)) - } - }); + let op_count_sat = ops_count_sat_vec + .iter() + .enumerate() + .try_fold(0, |acc, (i, &(x, y))| { + if i <= k { + x.map(|x| acc + x) + } else { + Some(acc + y) + } + }); Ok(ExtData { pk_cost: pk_cost + n - 1, //all pk cost + (n-1)*ADD @@ -1112,11 +1111,6 @@ fn opt_add(a: Option, b: Option) -> Option { a.and_then(|x| b.map(|y| x + y)) } -/// Returns Some((x0+y0, x1+y1)) is both x and y are Some. Otherwise, returns `None`. -fn opt_tuple_add(a: Option<(usize, usize)>, b: Option<(usize, usize)>) -> Option<(usize, usize)> { - a.and_then(|x| b.map(|(w, s)| (w + x.0, s + x.1))) -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/policy/compiler.rs b/src/policy/compiler.rs index 22bb0f04a..472e9bde3 100644 --- a/src/policy/compiler.rs +++ b/src/policy/compiler.rs @@ -36,10 +36,15 @@ type PolicyCache = BTreeMap<(Concrete, OrdF64, Option), BTreeMap>>; ///Ordered f64 for comparison -#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)] +#[derive(Copy, Clone, PartialEq, Debug)] pub(crate) struct OrdF64(pub f64); impl Eq for OrdF64 {} +impl PartialOrd for OrdF64 { + fn partial_cmp(&self, other: &OrdF64) -> Option { + Some(self.cmp(other)) + } +} impl Ord for OrdF64 { fn cmp(&self, other: &OrdF64) -> cmp::Ordering { // will panic if given NaN @@ -674,13 +679,10 @@ fn insert_elem( // Check whether the new element is worse than any existing element. If there // is an element which is a subtype of the current element and has better // cost, don't consider this element. - let is_worse = map - .iter() - .map(|(existing_key, existing_elem)| { - let existing_elem_cost = existing_elem.cost_1d(sat_prob, dissat_prob); - existing_key.is_subtype(elem_key) && existing_elem_cost <= elem_cost - }) - .any(|x| x); + let is_worse = map.iter().any(|(existing_key, existing_elem)| { + let existing_elem_cost = existing_elem.cost_1d(sat_prob, dissat_prob); + existing_key.is_subtype(elem_key) && existing_elem_cost <= elem_cost + }); if !is_worse { // If the element is not worse any element in the map, remove elements // whose subtype is the current element and have worse cost. @@ -970,11 +972,11 @@ where let mut best_es = Vec::with_capacity(n); let mut best_ws = Vec::with_capacity(n); - let mut min_value = (0, f64::INFINITY as f64); + let mut min_value = (0, f64::INFINITY); for (i, ast) in subs.iter().enumerate() { let sp = sat_prob * k_over_n; //Expressions must be dissatisfiable - let dp = Some(dissat_prob.unwrap_or(0 as f64) + (1.0 - k_over_n) * sat_prob); + let dp = Some(dissat_prob.unwrap_or(0.0) + (1.0 - k_over_n) * sat_prob); let be = best(types::Base::B, policy_cache, ast, sp, dp)?; let bw = best(types::Base::W, policy_cache, ast, sp, dp)?; @@ -1240,7 +1242,7 @@ mod tests { // artificially create a policy that is problematic and try to compile let pol: SPolicy = Concrete::And(vec![ Concrete::Key("A".to_string()), - Concrete::And(vec![Concrete::after(9), Concrete::after(1000_000_000)]), + Concrete::And(vec![Concrete::after(9), Concrete::after(1_000_000_000)]), ]); assert!(pol.compile::().is_err()); @@ -1314,7 +1316,7 @@ mod tests { let (keys, sig) = pubkeys_and_a_sig(10); let key_pol: Vec = keys.iter().map(|k| Concrete::Key(*k)).collect(); - let policy: BPolicy = Concrete::Key(keys[0].clone()); + let policy: BPolicy = Concrete::Key(keys[0]); let ms: SegwitMiniScript = policy.compile().unwrap(); assert_eq!( ms.encode(), @@ -1400,11 +1402,11 @@ mod tests { let mut right_sat = HashMap::::new(); - for i in 0..5 { - left_sat.insert(keys[i], bitcoinsig); + for key in &keys[0..5] { + left_sat.insert(*key, bitcoinsig); } - for i in 5..8 { - right_sat.insert(keys[i].to_pubkeyhash(SigType::Ecdsa), (keys[i], bitcoinsig)); + for key in &keys[5..8] { + right_sat.insert(key.to_pubkeyhash(SigType::Ecdsa), (*key, bitcoinsig)); } assert!(ms.satisfy(no_sat).is_err()); @@ -1513,7 +1515,7 @@ mod tests { (1, Concrete::Threshold(keys_b.len(), keys_b)), ]) .compile(); - let script_size = thresh_res.clone().and_then(|m| Ok(m.script_size())); + let script_size = thresh_res.clone().map(|m| m.script_size()); assert_eq!( thresh_res, Err(CompilerError::LimitsExceeded), @@ -1529,7 +1531,7 @@ mod tests { Concrete::Threshold(keys.len(), keys).compile(); let n_elements = thresh_res .clone() - .and_then(|m| Ok(m.max_satisfaction_witness_elements())); + .map(|m| m.max_satisfaction_witness_elements()); assert_eq!( thresh_res, Err(CompilerError::LimitsExceeded), @@ -1546,7 +1548,7 @@ mod tests { keys.iter().map(|pubkey| Concrete::Key(*pubkey)).collect(); let thresh_res: Result = Concrete::Threshold(keys.len() - 1, keys).compile(); - let ops_count = thresh_res.clone().and_then(|m| Ok(m.ext.ops.op_count())); + let ops_count = thresh_res.clone().map(|m| m.ext.ops.op_count()); assert_eq!( thresh_res, Err(CompilerError::LimitsExceeded), @@ -1558,7 +1560,7 @@ mod tests { let keys: Vec> = keys.iter().map(|pubkey| Concrete::Key(*pubkey)).collect(); let thresh_res = Concrete::Threshold(keys.len() - 1, keys).compile::(); - let ops_count = thresh_res.clone().and_then(|m| Ok(m.ext.ops.op_count())); + let ops_count = thresh_res.clone().map(|m| m.ext.ops.op_count()); assert_eq!( thresh_res, Err(CompilerError::LimitsExceeded), diff --git a/src/policy/concrete.rs b/src/policy/concrete.rs index 1f3e91c55..bef0e5eb8 100644 --- a/src/policy/concrete.rs +++ b/src/policy/concrete.rs @@ -315,17 +315,15 @@ impl Policy { Policy::Or(ref subs) => { let total_odds: usize = subs.iter().map(|(ref k, _)| k).sum(); subs.iter() - .map(|(k, ref policy)| { + .flat_map(|(k, ref policy)| { policy.to_tapleaf_prob_vec(prob * *k as f64 / total_odds as f64) }) - .flatten() .collect::>() } Policy::Threshold(k, ref subs) if *k == 1 => { let total_odds = subs.len(); subs.iter() - .map(|policy| policy.to_tapleaf_prob_vec(prob / total_odds as f64)) - .flatten() + .flat_map(|policy| policy.to_tapleaf_prob_vec(prob / total_odds as f64)) .collect::>() } x => vec![(prob, x.clone())], diff --git a/src/policy/semantic.rs b/src/policy/semantic.rs index ef7f858f7..4f51c42c7 100644 --- a/src/policy/semantic.rs +++ b/src/policy/semantic.rs @@ -174,7 +174,6 @@ impl Policy { /// A |- B means every satisfaction of A is also a satisfaction of B. /// This implementation will run slow for larger policies but should be sufficient for /// most practical policies. - // This algorithm has a naive implementation. It is possible to optimize this // by memoizing and maintaining a hashmap. pub fn entails(self, other: Policy) -> Result { @@ -229,11 +228,10 @@ impl Policy { // a normalized policy pub(crate) fn satisfy_constraint(self, witness: &Policy, available: bool) -> Policy { debug_assert!(self.clone().normalized() == self); - match *witness { + if let Policy::Threshold(..) = *witness { // only for internal purposes, safe to use unreachable! - Policy::Threshold(..) => unreachable!(), - _ => {} - }; + unreachable!() + } let ret = match self { Policy::Threshold(k, subs) => { let mut ret_subs = vec![]; @@ -556,10 +554,9 @@ impl Policy { Policy::Older(t) => { if t.is_height_locked() && age.is_time_locked() || t.is_time_locked() && age.is_height_locked() + || t.to_consensus_u32() > age.to_consensus_u32() { Policy::Unsatisfiable - } else if t.to_consensus_u32() > age.to_consensus_u32() { - Policy::Unsatisfiable } else { Policy::Older(t) } diff --git a/src/psbt/mod.rs b/src/psbt/mod.rs index b6258c928..e220e11e4 100644 --- a/src/psbt/mod.rs +++ b/src/psbt/mod.rs @@ -1045,8 +1045,6 @@ trait PsbtFields { fn tap_key_origins( &mut self, ) -> &mut BTreeMap, bip32::KeySource)>; - fn proprietary(&mut self) -> &mut BTreeMap>; - fn unknown(&mut self) -> &mut BTreeMap>; // `tap_tree` only appears in psbt::Output, so it's returned as an option of a mutable ref fn tap_tree(&mut self) -> Option<&mut Option> { @@ -1080,12 +1078,6 @@ impl PsbtFields for psbt::Input { ) -> &mut BTreeMap, bip32::KeySource)> { &mut self.tap_key_origins } - fn proprietary(&mut self) -> &mut BTreeMap> { - &mut self.proprietary - } - fn unknown(&mut self) -> &mut BTreeMap> { - &mut self.unknown - } fn tap_scripts(&mut self) -> Option<&mut BTreeMap> { Some(&mut self.tap_scripts) @@ -1113,12 +1105,6 @@ impl PsbtFields for psbt::Output { ) -> &mut BTreeMap, bip32::KeySource)> { &mut self.tap_key_origins } - fn proprietary(&mut self) -> &mut BTreeMap> { - &mut self.proprietary - } - fn unknown(&mut self) -> &mut BTreeMap> { - &mut self.unknown - } fn tap_tree(&mut self) -> Option<&mut Option> { Some(&mut self.tap_tree) @@ -1548,8 +1534,7 @@ mod tests { assert!(psbt_input .tap_scripts .values() - .find(|value| *value == &(first_script.clone(), LeafVersion::TapScript)) - .is_some()); + .any(|value| *value == (first_script.clone(), LeafVersion::TapScript))); TapLeafHash::from_script(&first_script, LeafVersion::TapScript) }; @@ -1655,8 +1640,8 @@ mod tests { #[test] fn test_update_input_checks() { - let desc = format!("tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/0)"); - let desc = Descriptor::::from_str(&desc).unwrap(); + let desc = "tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/0)"; + let desc = Descriptor::::from_str(desc).unwrap(); let mut non_witness_utxo = bitcoin::Transaction { version: 1, @@ -1720,8 +1705,8 @@ mod tests { #[test] fn test_update_output_checks() { - let desc = format!("tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/0)"); - let desc = Descriptor::::from_str(&desc).unwrap(); + let desc = "tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/0)"; + let desc = Descriptor::::from_str(desc).unwrap(); let tx = bitcoin::Transaction { version: 1, diff --git a/src/test_utils.rs b/src/test_utils.rs index 6ea900d91..5cb0c77bd 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -134,7 +134,7 @@ impl StrKeyTranslator { .collect(); let mut pk_map = HashMap::new(); let mut pkh_map = HashMap::new(); - for (i, c) in (b'A'..b'Z').enumerate() { + for (i, c) in (b'A'..=b'Z').enumerate() { let key = String::from_utf8(vec![c]).unwrap(); pk_map.insert(key.clone(), pks[i]); pkh_map.insert(key, pks[i].to_pubkeyhash(SigType::Ecdsa)); @@ -165,7 +165,7 @@ impl StrXOnlyKeyTranslator { .collect(); let mut pk_map = HashMap::new(); let mut pkh_map = HashMap::new(); - for (i, c) in (b'A'..b'Z').enumerate() { + for (i, c) in (b'A'..=b'Z').enumerate() { let key = String::from_utf8(vec![c]).unwrap(); pk_map.insert(key.clone(), pks[i]); pkh_map.insert(key, pks[i].to_pubkeyhash(SigType::Schnorr)); From 2ab85ed58c50fe48098079c095d0aa0ad3340800 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sat, 5 Jul 2025 14:49:55 +0000 Subject: [PATCH 07/11] docs: fix broken links etc Remove the deprecated (well, renamed) "allow broken intradoc links" cfg flag, which exposes a ton of broken doc links. Mostly just uses of [] or <> that aren't in backticks. Fix them all. The one morally questionable change is to change two doclink references to Policy::enumerate_policy_tree to no longer be doclinks. The problem is that this function only exists when the `compiler` flag is on. In master in ebaa31bca7e80f02751e3435907b3aad99d74168 we just removed these references as well, but arguably we should have fixed them. Anyway in 9.x we're certainly not going to bend over backward to fix stuff like this. --- src/descriptor/key.rs | 2 +- src/descriptor/mod.rs | 4 ++-- src/lib.rs | 2 +- src/miniscript/decode.rs | 27 +++++++++++++-------------- src/policy/concrete.rs | 6 +++--- src/psbt/mod.rs | 2 +- 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/descriptor/key.rs b/src/descriptor/key.rs index 62cb21b51..a05c0fc8d 100644 --- a/src/descriptor/key.rs +++ b/src/descriptor/key.rs @@ -442,8 +442,8 @@ impl DescriptorPublicKey { } } + #[doc(hidden)] #[deprecated(note = "use at_derivation_index instead")] - /// Deprecated name of [`at_derivation_index`]. pub fn derive(self, index: u32) -> DefiniteDescriptorKey { self.at_derivation_index(index) } diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index d6516be1c..93cf2da57 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -542,8 +542,8 @@ impl Descriptor { .expect("BIP 32 key index substitution cannot fail") } + #[doc(hidden)] #[deprecated(note = "use at_derivation_index instead")] - /// Deprecated name for [`at_derivation_index`]. pub fn derive(&self, index: u32) -> Descriptor { self.at_derivation_index(index) } @@ -569,7 +569,7 @@ impl Descriptor { /// See [`at_derivation_index`] and `[derived_descriptor`] for more documentation. /// /// [`at_derivation_index`]: Self::at_derivation_index - /// [`derived_descriptor`]: crate::DerivedDescriptor::derived_descriptor + /// [`derived_descriptor`]: crate::Descriptor::derived_descriptor /// /// # Errors /// diff --git a/src/lib.rs b/src/lib.rs index 9ce19351e..8fe0baf3e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -167,7 +167,7 @@ pub trait MiniscriptKey: Clone + Eq + Ord + fmt::Debug + fmt::Display + hash::Ha /// The associated [`hash256::Hash`] for this [`MiniscriptKey`], /// used in the hash256 fragment. type Hash256: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash; - /// The associated [`ripedmd160::Hash`] for this [`MiniscriptKey`] type. + /// The associated [`ripemd160::Hash`] for this [`MiniscriptKey`] type. /// used in the ripemd160 fragment type Ripemd160: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash; diff --git a/src/miniscript/decode.rs b/src/miniscript/decode.rs index ee6e4e6ce..96f6f983f 100644 --- a/src/miniscript/decode.rs +++ b/src/miniscript/decode.rs @@ -124,7 +124,6 @@ enum NonTerm { /// The average user should always use the [`crate::Descriptor`] APIs. Advanced users /// who want deal with Miniscript ASTs should use the [`crate::Miniscript`] APIs. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[allow(broken_intra_doc_links)] pub enum Terminal { /// `1` True, @@ -164,38 +163,38 @@ pub enum Terminal { Check(Arc>), /// `DUP IF [V] ENDIF` DupIf(Arc>), - /// [T] VERIFY + /// `[T] VERIFY` Verify(Arc>), - /// SIZE 0NOTEQUAL IF [Fn] ENDIF + /// `SIZE 0NOTEQUAL IF [Fn] ENDIF` NonZero(Arc>), - /// [X] 0NOTEQUAL + /// `[X] 0NOTEQUAL` ZeroNotEqual(Arc>), // Conjunctions - /// [V] [T]/[V]/[F]/[Kt] + /// `[V] [T]/[V]/[F]/[Kt]` AndV(Arc>, Arc>), - /// [E] [W] BOOLAND + /// `[E] [W] BOOLAND` AndB(Arc>, Arc>), - /// [various] NOTIF [various] ELSE [various] ENDIF + /// `[various] NOTIF [various] ELSE [various] ENDIF` AndOr( Arc>, Arc>, Arc>, ), // Disjunctions - /// [E] [W] BOOLOR + /// `[E] [W] BOOLOR` OrB(Arc>, Arc>), - /// [E] IFDUP NOTIF [T]/[E] ENDIF + /// `[E] IFDUP NOTIF [T]/[E] ENDIF` OrD(Arc>, Arc>), - /// [E] NOTIF [V] ENDIF + /// `[E] NOTIF [V] ENDIF` OrC(Arc>, Arc>), - /// IF [various] ELSE [various] ENDIF + /// `IF [various] ELSE [various] ENDIF` OrI(Arc>, Arc>), // Thresholds - /// [E] ([W] ADD)* k EQUAL + /// `[E] ([W] ADD)* k EQUAL` Thresh(usize, Vec>>), - /// k ()* n CHECKMULTISIG + /// `k ()* n CHECKMULTISIG` Multi(usize, Vec), - /// CHECKSIG ( CHECKSIGADD)*(n-1) k NUMEQUAL + /// ` CHECKSIG ( CHECKSIGADD)*(n-1) k NUMEQUAL` MultiA(usize, Vec), } diff --git a/src/policy/concrete.rs b/src/policy/concrete.rs index bef0e5eb8..e2bd57034 100644 --- a/src/policy/concrete.rs +++ b/src/policy/concrete.rs @@ -228,7 +228,7 @@ pub enum DescriptorCtx { Wsh, /// Sh-wrapped [Wsh][`Descriptor::Wsh`] ShWsh, - /// [Tr][`Descriptor::Tr`] where the Option corresponds to the internal_key if no internal + /// [Tr][`Descriptor::Tr`] where the `Option` corresponds to the internal_key if no internal /// key can be inferred from the given policy Tr(Option), } @@ -427,7 +427,7 @@ impl Policy { } /// Compile the [`Policy`] into a [`Tr`][`Descriptor::Tr`] Descriptor, with policy-enumeration - /// by [`Policy::enumerate_policy_tree`]. + /// by `Policy::enumerate_policy_tree`. /// /// ### TapTree compilation /// @@ -439,7 +439,7 @@ impl Policy { /// /// ### Policy enumeration /// - /// Refer to [`Policy::enumerate_policy_tree`] for the current strategy implemented. + /// Refer to `Policy::enumerate_policy_tree` for the current strategy implemented. #[cfg(feature = "compiler")] pub fn compile_tr_private_experimental( &self, diff --git a/src/psbt/mod.rs b/src/psbt/mod.rs index e220e11e4..2a17a938e 100644 --- a/src/psbt/mod.rs +++ b/src/psbt/mod.rs @@ -594,7 +594,7 @@ pub trait PsbtExt { /// Get the sighash message(data to sign) at input index `idx` based on the sighash /// flag specified in the [`Psbt`] sighash field. If the input sighash flag psbt field is `None` - /// the [`SchnorrSighashType::Default`](bitcoin::util::sighash::SchnorrSighashType::Default) is chosen + /// the [`SchnorrSighashType::Default`] is chosen /// for for taproot spends, otherwise [`EcdsaSignatureHashType::All`](bitcoin::EcdsaSighashType::All) is chosen. /// If the utxo at `idx` is a taproot output, returns a [`PsbtSighashMsg::TapSighash`] variant. /// If the utxo at `idx` is a pre-taproot output, returns a [`PsbtSighashMsg::EcdsaSighash`] variant. From 57795f01b35ad03e4d9d6b4d3ea1c9829a73f9e2 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sat, 5 Jul 2025 01:58:26 +0000 Subject: [PATCH 08/11] clippy: all the lifetime-related stuff Split off because I imagine these ones will be easier to review. --- examples/psbt_sign_finalize.rs | 2 +- examples/xpub_descriptors.rs | 4 +-- src/descriptor/mod.rs | 24 ++++++------- src/descriptor/tr.rs | 6 ++-- src/interpreter/mod.rs | 2 +- src/miniscript/astelem.rs | 18 +++++----- src/miniscript/iter.rs | 52 ++++++++++++++--------------- src/miniscript/lex.rs | 2 +- src/miniscript/mod.rs | 34 +++++++++---------- src/miniscript/satisfy.rs | 26 +++++++-------- src/miniscript/types/extra_props.rs | 17 ++++------ src/policy/compiler.rs | 8 ++--- src/policy/concrete.rs | 14 ++++---- src/policy/mod.rs | 6 ++-- src/psbt/mod.rs | 1 + 15 files changed, 106 insertions(+), 110 deletions(-) diff --git a/examples/psbt_sign_finalize.rs b/examples/psbt_sign_finalize.rs index f7f3dfd63..426c98b03 100644 --- a/examples/psbt_sign_finalize.rs +++ b/examples/psbt_sign_finalize.rs @@ -19,7 +19,7 @@ fn main() { let secp256k1 = secp256k1::Secp256k1::new(); let s = "wsh(t:or_c(pk(027a3565454fe1b749bccaef22aff72843a9c3efefd7b16ac54537a0c23f0ec0de),v:thresh(1,pkh(032d672a1a91cc39d154d366cd231983661b0785c7f27bc338447565844f4a6813),a:pkh(03417129311ed34c242c012cd0a3e0b9bca0065f742d0dfb63c78083ea6a02d4d9),a:pkh(025a687659658baeabdfc415164528065be7bcaade19342241941e556557f01e28))))#7hut9ukn"; - let bridge_descriptor = Descriptor::from_str(&s).unwrap(); + let bridge_descriptor = Descriptor::from_str(s).unwrap(); //let bridge_descriptor = Descriptor::::from_str(&s).expect("parse descriptor string"); assert!(bridge_descriptor.sanity_check().is_ok()); println!( diff --git a/examples/xpub_descriptors.rs b/examples/xpub_descriptors.rs index 64f7d718b..b988f4683 100644 --- a/examples/xpub_descriptors.rs +++ b/examples/xpub_descriptors.rs @@ -42,7 +42,7 @@ fn p2wsh(secp: &Secp256k1) -> Address { let address = Descriptor::::from_str(&s) .unwrap() - .derived_descriptor(&secp) + .derived_descriptor(secp) .unwrap() .address(Network::Bitcoin) .unwrap(); @@ -63,7 +63,7 @@ fn p2sh_p2wsh(secp: &Secp256k1) -> Address { let address = Descriptor::::from_str(&s) .unwrap() - .derived_descriptor(&secp, 5) + .derived_descriptor(secp, 5) .unwrap() .address(Network::Bitcoin) .unwrap(); diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index 93cf2da57..44411020f 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -579,7 +579,7 @@ impl Descriptor { secp: &secp256k1::Secp256k1, index: u32, ) -> Result, ConversionError> { - self.at_derivation_index(index).derived_descriptor(&secp) + self.at_derivation_index(index).derived_descriptor(secp) } /// Parse a descriptor that may contain secret keys @@ -591,7 +591,7 @@ impl Descriptor { s: &str, ) -> Result<(Descriptor, KeyMap), Error> { fn parse_key( - s: &String, + s: &str, key_map: &mut KeyMap, secp: &secp256k1::Secp256k1, ) -> Result { @@ -762,7 +762,7 @@ impl Descriptor { &mut self, pk: &DefiniteDescriptorKey, ) -> Result { - pk.derive_public_key(&self.0) + pk.derive_public_key(self.0) } translate_hash_clone!(DefiniteDescriptorKey, bitcoin::PublicKey, ConversionError); @@ -861,10 +861,10 @@ mod tests { impl cmp::PartialEq for DescriptorSecretKey { fn eq(&self, other: &Self) -> bool { match (self, other) { - (&DescriptorSecretKey::Single(ref a), &DescriptorSecretKey::Single(ref b)) => { + (DescriptorSecretKey::Single(a), DescriptorSecretKey::Single(b)) => { a.origin == b.origin && a.key == b.key } - (&DescriptorSecretKey::XPrv(ref a), &DescriptorSecretKey::XPrv(ref b)) => { + (DescriptorSecretKey::XPrv(a), DescriptorSecretKey::XPrv(b)) => { a.origin == b.origin && a.xkey == b.xkey && a.derivation_path == b.derivation_path @@ -876,7 +876,7 @@ mod tests { } fn roundtrip_descriptor(s: &str) { - let desc = Descriptor::::from_str(&s).unwrap(); + let desc = Descriptor::::from_str(s).unwrap(); let output = desc.to_string(); let normalize_aliases = s.replace("c:pk_k(", "pk(").replace("c:pk_h(", "pkh("); assert_eq!( @@ -939,9 +939,9 @@ mod tests { #[test] pub fn script_pubkey() { - let bare = StdDescriptor::from_str(&format!( - "multi(1,020000000000000000000000000000000000000000000000000000000000000002)" - )) + let bare = StdDescriptor::from_str( + "multi(1,020000000000000000000000000000000000000000000000000000000000000002)", + ) .unwrap(); assert_eq!( bare.script_pubkey(), @@ -1663,8 +1663,8 @@ mod tests { "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))##tjq09x4t" ); - Descriptor::parse_descriptor(&secp, "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxfy").expect("Valid descriptor with checksum"); - Descriptor::parse_descriptor(&secp, "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5t").expect("Valid descriptor with checksum"); + Descriptor::parse_descriptor(secp, "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxfy").expect("Valid descriptor with checksum"); + Descriptor::parse_descriptor(secp, "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5t").expect("Valid descriptor with checksum"); } #[test] @@ -1694,7 +1694,7 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))"; let secp = &secp256k1::Secp256k1::signing_only(); let descriptor_str = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)#v20xlvm9"; let (descriptor, keymap) = - Descriptor::::parse_descriptor(&secp, descriptor_str).unwrap(); + Descriptor::::parse_descriptor(secp, descriptor_str).unwrap(); let expected = "wpkh([a12b02f4/44'/0'/0']xpub6BzhLAQUDcBUfHRQHZxDF2AbcJqp4Kaeq6bzJpXrjrWuK26ymTFwkEFbxPra2bJ7yeZKbDjfDeFwxe93JMqpo5SsPJH6dZdvV9kMzJkAZ69/0/*)#u37l7u8u"; assert_eq!(expected, descriptor.to_string()); diff --git a/src/descriptor/tr.rs b/src/descriptor/tr.rs index 91e71fbc5..4a8999280 100644 --- a/src/descriptor/tr.rs +++ b/src/descriptor/tr.rs @@ -116,7 +116,7 @@ impl TapTree { } /// Iterate over all miniscripts - pub fn iter(&self) -> TapTreeIter { + pub fn iter(&self) -> TapTreeIter<'_, Pk> { TapTreeIter { stack: vec![(0, self)], } @@ -185,7 +185,7 @@ impl Tr { /// Iterate over all scripts in merkle tree. If there is no script path, the iterator /// yields [`None`] - pub fn iter_scripts(&self) -> TapTreeIter { + pub fn iter_scripts(&self) -> TapTreeIter<'_, Pk> { match self.tree { Some(ref t) => t.iter(), None => TapTreeIter { stack: vec![] }, @@ -462,7 +462,7 @@ impl fmt::Display for Tr { } // Helper function to parse string into miniscript tree form -fn parse_tr_tree(s: &str) -> Result { +fn parse_tr_tree(s: &str) -> Result, Error> { for ch in s.bytes() { if !ch.is_ascii() { return Err(Error::Unprintable(ch)); diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 8720fc355..fb4908e5b 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -1142,7 +1142,7 @@ mod tests { stack, public_key: None, state: vec![NodeEvaluationState { - node: &ms, + node: ms, n_evaluated: 0, n_satisfied: 0, }], diff --git a/src/miniscript/astelem.rs b/src/miniscript/astelem.rs index c1557ad6a..c20660797 100644 --- a/src/miniscript/astelem.rs +++ b/src/miniscript/astelem.rs @@ -129,10 +129,10 @@ impl Terminal { Terminal::RawPkH(ref p) => Terminal::RawPkH(*p), Terminal::After(n) => Terminal::After(n), Terminal::Older(n) => Terminal::Older(n), - Terminal::Sha256(ref x) => Terminal::Sha256(t.sha256(&x)?), - Terminal::Hash256(ref x) => Terminal::Hash256(t.hash256(&x)?), - Terminal::Ripemd160(ref x) => Terminal::Ripemd160(t.ripemd160(&x)?), - Terminal::Hash160(ref x) => Terminal::Hash160(t.hash160(&x)?), + Terminal::Sha256(ref x) => Terminal::Sha256(t.sha256(x)?), + Terminal::Hash256(ref x) => Terminal::Hash256(t.hash256(x)?), + Terminal::Ripemd160(ref x) => Terminal::Ripemd160(t.ripemd160(x)?), + Terminal::Hash160(ref x) => Terminal::Hash160(t.hash160(x)?), Terminal::True => Terminal::True, Terminal::False => Terminal::False, Terminal::Alt(ref sub) => Terminal::Alt(Arc::new(sub.real_translate_pk(t)?)), @@ -622,7 +622,7 @@ impl Terminal { Terminal::RawPkH(ref hash) => builder .push_opcode(opcodes::all::OP_DUP) .push_opcode(opcodes::all::OP_HASH160) - .push_slice(&hash) + .push_slice(hash) .push_opcode(opcodes::all::OP_EQUALVERIFY), Terminal::After(t) => builder .push_int(t.to_u32().into()) @@ -635,28 +635,28 @@ impl Terminal { .push_int(32) .push_opcode(opcodes::all::OP_EQUALVERIFY) .push_opcode(opcodes::all::OP_SHA256) - .push_slice(&Pk::to_sha256(&h)) + .push_slice(&Pk::to_sha256(h)) .push_opcode(opcodes::all::OP_EQUAL), Terminal::Hash256(ref h) => builder .push_opcode(opcodes::all::OP_SIZE) .push_int(32) .push_opcode(opcodes::all::OP_EQUALVERIFY) .push_opcode(opcodes::all::OP_HASH256) - .push_slice(&Pk::to_hash256(&h)) + .push_slice(&Pk::to_hash256(h)) .push_opcode(opcodes::all::OP_EQUAL), Terminal::Ripemd160(ref h) => builder .push_opcode(opcodes::all::OP_SIZE) .push_int(32) .push_opcode(opcodes::all::OP_EQUALVERIFY) .push_opcode(opcodes::all::OP_RIPEMD160) - .push_slice(&Pk::to_ripemd160(&h)) + .push_slice(&Pk::to_ripemd160(h)) .push_opcode(opcodes::all::OP_EQUAL), Terminal::Hash160(ref h) => builder .push_opcode(opcodes::all::OP_SIZE) .push_int(32) .push_opcode(opcodes::all::OP_EQUALVERIFY) .push_opcode(opcodes::all::OP_HASH160) - .push_slice(&Pk::to_hash160(&h)) + .push_slice(&Pk::to_hash160(h)) .push_opcode(opcodes::all::OP_EQUAL), Terminal::True => builder.push_opcode(opcodes::OP_TRUE), Terminal::False => builder.push_opcode(opcodes::OP_FALSE), diff --git a/src/miniscript/iter.rs b/src/miniscript/iter.rs index bef0ea1af..5c706125f 100644 --- a/src/miniscript/iter.rs +++ b/src/miniscript/iter.rs @@ -29,14 +29,14 @@ impl Miniscript { /// Creates a new [Iter] iterator that will iterate over all [Miniscript] items within /// AST by traversing its branches. For the specific algorithm please see /// [Iter::next] function. - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter<'_, Pk, Ctx> { Iter::new(self) } /// Creates a new [PkIter] iterator that will iterate over all plain public keys (and not /// key hash values) present in [Miniscript] items within AST by traversing all its branches. /// For the specific algorithm please see [PkIter::next] function. - pub fn iter_pk(&self) -> PkIter { + pub fn iter_pk(&self) -> PkIter<'_, Pk, Ctx> { PkIter::new(self) } @@ -74,30 +74,30 @@ impl Miniscript { /// Returns child node with given index, if any pub fn get_nth_child(&self, n: usize) -> Option<&Miniscript> { match (n, &self.node) { - (0, &Terminal::Alt(ref node)) - | (0, &Terminal::Swap(ref node)) - | (0, &Terminal::Check(ref node)) - | (0, &Terminal::DupIf(ref node)) - | (0, &Terminal::Verify(ref node)) - | (0, &Terminal::NonZero(ref node)) - | (0, &Terminal::ZeroNotEqual(ref node)) - | (0, &Terminal::AndV(ref node, _)) - | (0, &Terminal::AndB(ref node, _)) - | (0, &Terminal::OrB(ref node, _)) - | (0, &Terminal::OrD(ref node, _)) - | (0, &Terminal::OrC(ref node, _)) - | (0, &Terminal::OrI(ref node, _)) - | (1, &Terminal::AndV(_, ref node)) - | (1, &Terminal::AndB(_, ref node)) - | (1, &Terminal::OrB(_, ref node)) - | (1, &Terminal::OrD(_, ref node)) - | (1, &Terminal::OrC(_, ref node)) - | (1, &Terminal::OrI(_, ref node)) - | (0, &Terminal::AndOr(ref node, _, _)) - | (1, &Terminal::AndOr(_, ref node, _)) - | (2, &Terminal::AndOr(_, _, ref node)) => Some(node), - - (n, &Terminal::Thresh(_, ref node_vec)) => node_vec.get(n).map(|x| &**x), + (0, Terminal::Alt(node)) + | (0, Terminal::Swap(node)) + | (0, Terminal::Check(node)) + | (0, Terminal::DupIf(node)) + | (0, Terminal::Verify(node)) + | (0, Terminal::NonZero(node)) + | (0, Terminal::ZeroNotEqual(node)) + | (0, Terminal::AndV(node, _)) + | (0, Terminal::AndB(node, _)) + | (0, Terminal::OrB(node, _)) + | (0, Terminal::OrD(node, _)) + | (0, Terminal::OrC(node, _)) + | (0, Terminal::OrI(node, _)) + | (1, Terminal::AndV(_, node)) + | (1, Terminal::AndB(_, node)) + | (1, Terminal::OrB(_, node)) + | (1, Terminal::OrD(_, node)) + | (1, Terminal::OrC(_, node)) + | (1, Terminal::OrI(_, node)) + | (0, Terminal::AndOr(node, _, _)) + | (1, Terminal::AndOr(_, node, _)) + | (2, Terminal::AndOr(_, _, node)) => Some(node), + + (n, Terminal::Thresh(_, node_vec)) => node_vec.get(n).map(|x| &**x), _ => None, } diff --git a/src/miniscript/lex.rs b/src/miniscript/lex.rs index a113824d3..bb2e8f188 100644 --- a/src/miniscript/lex.rs +++ b/src/miniscript/lex.rs @@ -89,7 +89,7 @@ impl<'s> TokenIter<'s> { } /// Look at the top at Iterator - pub fn peek(&self) -> Option<&'s Token> { + pub fn peek(&self) -> Option<&'s Token<'_>> { self.0.last() } diff --git a/src/miniscript/mod.rs b/src/miniscript/mod.rs index 2c4375ebc..471638714 100644 --- a/src/miniscript/mod.rs +++ b/src/miniscript/mod.rs @@ -994,28 +994,28 @@ mod tests { #[test] fn test_tapscript_rtt() { // Test x-only invalid under segwitc0 context - let ms = Segwitv0Script::from_str_insane(&format!( - "pk(2788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99)" - )); + let ms = Segwitv0Script::from_str_insane( + "pk(2788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99)", + ); assert_eq!( &ms.unwrap_err().to_string()[..35], "unexpected «key hex decoding error", ); - Tapscript::from_str_insane(&format!( - "pk(2788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99)" - )) + Tapscript::from_str_insane( + "pk(2788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99)", + ) .unwrap(); // Now test that bitcoin::PublicKey works with Taproot context - Miniscript::::from_str_insane(&format!( - "pk(022788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99)" - )) + Miniscript::::from_str_insane( + "pk(022788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99)", + ) .unwrap(); // uncompressed keys should not be allowed - Miniscript::::from_str_insane(&format!( + Miniscript::::from_str_insane( "pk(04eed24a081bf1b1e49e3300df4bebe04208ac7e516b6f3ea8eb6e094584267c13483f89dcf194132e12238cc5a34b6b286fc7990d68ed1db86b69ebd826c63b29)" - )) + ) .unwrap_err(); //---------------- test script <-> miniscript --------------- @@ -1041,14 +1041,14 @@ mod tests { .unwrap(); // multi not allowed in tapscript - Tapscript::from_str_insane(&format!( - "multi(1,2788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99)" - )) + Tapscript::from_str_insane( + "multi(1,2788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99)", + ) .unwrap_err(); // but allowed in segwit - Segwitv0Script::from_str_insane(&format!( - "multi(1,022788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99)" - )) + Segwitv0Script::from_str_insane( + "multi(1,022788ee41e76f4f3af603da5bc8fa22997bc0344bb0f95666ba6aaff0242baa99)", + ) .unwrap(); } diff --git a/src/miniscript/satisfy.rs b/src/miniscript/satisfy.rs index 03f2e1b1c..826c3fdb9 100644 --- a/src/miniscript/satisfy.rs +++ b/src/miniscript/satisfy.rs @@ -220,7 +220,7 @@ where } } -impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier> Satisfier for &'a S { +impl> Satisfier for &'_ S { fn lookup_ecdsa_sig(&self, p: &Pk) -> Option { (**self).lookup_ecdsa_sig(p) } @@ -286,7 +286,7 @@ impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier> Satisfier for &' } } -impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier> Satisfier for &'a mut S { +impl> Satisfier for &'_ mut S { fn lookup_ecdsa_sig(&self, p: &Pk) -> Option { (**self).lookup_ecdsa_sig(p) } @@ -548,17 +548,17 @@ impl PartialOrd for Witness { impl Ord for Witness { fn cmp(&self, other: &Self) -> cmp::Ordering { match (self, other) { - (&Witness::Stack(ref v1), &Witness::Stack(ref v2)) => { + (Witness::Stack(v1), Witness::Stack(v2)) => { let w1 = witness_size(v1); let w2 = witness_size(v2); w1.cmp(&w2) } - (&Witness::Stack(_), _) => cmp::Ordering::Less, - (_, &Witness::Stack(_)) => cmp::Ordering::Greater, - (&Witness::Impossible, &Witness::Unavailable) => cmp::Ordering::Less, - (&Witness::Unavailable, &Witness::Impossible) => cmp::Ordering::Greater, - (&Witness::Impossible, &Witness::Impossible) => cmp::Ordering::Equal, - (&Witness::Unavailable, &Witness::Unavailable) => cmp::Ordering::Equal, + (Witness::Stack(_), _) => cmp::Ordering::Less, + (_, Witness::Stack(_)) => cmp::Ordering::Greater, + (Witness::Impossible, Witness::Unavailable) => cmp::Ordering::Less, + (Witness::Unavailable, Witness::Impossible) => cmp::Ordering::Greater, + (Witness::Impossible, Witness::Impossible) => cmp::Ordering::Equal, + (Witness::Unavailable, Witness::Unavailable) => cmp::Ordering::Equal, } } } @@ -758,11 +758,11 @@ impl Satisfaction { let mut sat_indices = (0..subs.len()).collect::>(); sat_indices.sort_by_key(|&i| { let stack_weight = match (&sats[i].stack, &ret_stack[i].stack) { - (&Witness::Unavailable, _) | (&Witness::Impossible, _) => i64::MAX, + (Witness::Unavailable, _) | (Witness::Impossible, _) => i64::MAX, // This can only be the case when we have PkH without the corresponding // Pubkey. - (_, &Witness::Unavailable) | (_, &Witness::Impossible) => i64::MIN, - (&Witness::Stack(ref s), &Witness::Stack(ref d)) => { + (_, Witness::Unavailable) | (_, Witness::Impossible) => i64::MIN, + (Witness::Stack(s), Witness::Stack(d)) => { witness_size(s) as i64 - witness_size(d) as i64 } }; @@ -880,7 +880,7 @@ impl Satisfaction { (&Witness::Unavailable, _) | (&Witness::Impossible, _) => i64::MAX, // This is only possible when one of the branches has PkH (_, &Witness::Unavailable) | (_, &Witness::Impossible) => i64::MIN, - (&Witness::Stack(ref s), &Witness::Stack(ref d)) => { + (Witness::Stack(s), Witness::Stack(d)) => { witness_size(s) as i64 - witness_size(d) as i64 } } diff --git a/src/miniscript/types/extra_props.rs b/src/miniscript/types/extra_props.rs index f78b9f050..490a0b210 100644 --- a/src/miniscript/types/extra_props.rs +++ b/src/miniscript/types/extra_props.rs @@ -1063,10 +1063,7 @@ impl Property for ExtData { // costy satisfactions are satisfied, the most costy dissatisfactions are dissatisfied). // // Args are of form: (, ) -fn sat_minus_dissat<'r, 's>( - a: &'r (Option, usize), - b: &'s (Option, usize), -) -> cmp::Ordering { +fn sat_minus_dissat(a: &(Option, usize), b: &(Option, usize)) -> cmp::Ordering { a.0.map(|x| x as isize - a.1 as isize) .cmp(&b.0.map(|x| x as isize - b.1 as isize)) } @@ -1077,9 +1074,9 @@ fn sat_minus_dissat<'r, 's>( // costy satisfactions are satisfied, the most costy dissatisfactions are dissatisfied). // // Args are of form: (, ) -fn sat_minus_option_dissat<'r, 's>( - a: &'r (Option, Option), - b: &'s (Option, Option), +fn sat_minus_option_dissat( + a: &(Option, Option), + b: &(Option, Option), ) -> cmp::Ordering { a.0.map(|x| a.1.map(|y| x as isize - y as isize)) .cmp(&b.0.map(|x| b.1.map(|y| x as isize - y as isize))) @@ -1089,9 +1086,9 @@ fn sat_minus_option_dissat<'r, 's>( // // Args are of form: (, ) // max_[dis]sat_size of form: (, ) -fn sat_minus_dissat_witness<'r, 's>( - a: &'r (Option<(usize, usize)>, Option<(usize, usize)>), - b: &'s (Option<(usize, usize)>, Option<(usize, usize)>), +fn sat_minus_dissat_witness( + a: &(Option<(usize, usize)>, Option<(usize, usize)>), + b: &(Option<(usize, usize)>, Option<(usize, usize)>), ) -> cmp::Ordering { a.0.map(|x| a.1.map(|y| x.0 as isize - y.0 as isize)) .cmp(&b.0.map(|x| b.1.map(|y| x.0 as isize - y.0 as isize))) diff --git a/src/policy/compiler.rs b/src/policy/compiler.rs index 472e9bde3..8372cabad 100644 --- a/src/policy/compiler.rs +++ b/src/policy/compiler.rs @@ -688,7 +688,7 @@ fn insert_elem( // whose subtype is the current element and have worse cost. *map = mem::take(map) .into_iter() - .filter(|&(ref existing_key, ref existing_elem)| { + .filter(|(existing_key, existing_elem)| { let existing_elem_cost = existing_elem.cost_1d(sat_prob, dissat_prob); !(elem_key.is_subtype(*existing_key) && existing_elem_cost >= elem_cost) }) @@ -877,7 +877,7 @@ where let rw = subs[1].0 as f64 / total; //and-or - if let (&Concrete::And(ref x), _) = (&subs[0].1, &subs[1].1) { + if let (Concrete::And(x), _) = (&subs[0].1, &subs[1].1) { let mut a1 = best_compilations( policy_cache, &x[0], @@ -900,7 +900,7 @@ where compile_tern!(&mut a1, &mut b2, &mut c, [lw, rw]); compile_tern!(&mut b1, &mut a2, &mut c, [lw, rw]); }; - if let (_, &Concrete::And(ref x)) = (&subs[0].1, &subs[1].1) { + if let (_, Concrete::And(x)) = (&subs[0].1, &subs[1].1) { let mut a1 = best_compilations( policy_cache, &x[0], @@ -1173,7 +1173,7 @@ where { best_compilations(policy_cache, policy, sat_prob, dissat_prob)? .into_iter() - .filter(|&(ref key, ref val)| { + .filter(|(key, val)| { key.ty.corr.base == basic_type && key.ty.corr.unit && val.ms.ty.mall.dissat == types::Dissat::Unique diff --git a/src/policy/concrete.rs b/src/policy/concrete.rs index e2bd57034..71cbccf0f 100644 --- a/src/policy/concrete.rs +++ b/src/policy/concrete.rs @@ -367,7 +367,7 @@ impl Policy { } } match (internal_key, unspendable_key) { - (Some(ref key), _) => Ok((key.clone(), self.translate_unsatisfiable_pk(&key))), + (Some(ref key), _) => Ok((key.clone(), self.translate_unsatisfiable_pk(key))), (_, Some(key)) => Ok((key, self)), _ => Err(errstr("No viable internal key found.")), } @@ -757,7 +757,7 @@ impl Policy { )), Policy::Or(ref subs) => Ok(Policy::Or( subs.iter() - .map(|&(ref prob, ref sub)| Ok((*prob, sub._translate_pk(t)?))) + .map(|(prob, sub)| Ok((*prob, sub._translate_pk(t)?))) .collect::)>, E>>()?, )), } @@ -887,9 +887,7 @@ impl Policy { TimelockInfo::combine_threshold(subs.len(), iter) } Policy::Or(ref subs) => { - let iter = subs - .iter() - .map(|&(ref _p, ref sub)| sub.check_timelocks_helper()); + let iter = subs.iter().map(|(_p, sub)| sub.check_timelocks_helper()); TimelockInfo::combine_threshold(1, iter) } } @@ -918,7 +916,7 @@ impl Policy { Err(PolicyError::NonBinaryArgOr) } else { subs.iter() - .map(|&(ref _prob, ref sub)| sub.is_valid()) + .map(|(_prob, sub)| sub.is_valid()) .collect::, PolicyError>>()?; Ok(()) } @@ -995,7 +993,7 @@ impl Policy { Policy::Or(ref subs) => { let (all_safe, atleast_one_safe, all_non_mall) = subs .iter() - .map(|&(_, ref sub)| sub.is_safe_nonmalleable()) + .map(|(_, sub)| sub.is_safe_nonmalleable()) .fold((true, false, true), |acc, x| { (acc.0 && x.0, acc.1 || x.0, acc.2 && x.1) }); @@ -1264,7 +1262,7 @@ fn with_huffman_tree( /// any one of the conditions exclusively. #[cfg(feature = "compiler")] fn generate_combination( - policy_vec: &Vec>>, + policy_vec: &[Arc>], prob: f64, k: usize, ) -> Vec<(f64, Arc>)> { diff --git a/src/policy/mod.rs b/src/policy/mod.rs index c7cdcddf3..a18b848ab 100644 --- a/src/policy/mod.rs +++ b/src/policy/mod.rs @@ -215,7 +215,7 @@ impl Liftable for Concrete { } Concrete::Or(ref subs) => { let semantic_subs: Result<_, Error> = - subs.iter().map(|&(ref _p, ref sub)| sub.lift()).collect(); + subs.iter().map(|(_, sub)| sub.lift()).collect(); Semantic::Threshold(1, semantic_subs?) } Concrete::Threshold(k, ref subs) => { @@ -337,7 +337,7 @@ mod tests { #[test] fn heavy_nest() { let policy_string = "thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk(),thresh(1,pk(),pk(),pk()))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))"; - ConcretePol::from_str(&policy_string).unwrap_err(); + ConcretePol::from_str(policy_string).unwrap_err(); } #[test] @@ -454,7 +454,7 @@ mod tests { .iter() .zip(node_probabilities.iter()) .collect::>(); - sorted_policy_prob.sort_by(|a, b| (a.1).partial_cmp(&b.1).unwrap()); + sorted_policy_prob.sort_by(|a, b| (a.1).partial_cmp(b.1).unwrap()); let sorted_policies = sorted_policy_prob .into_iter() .map(|(x, _prob)| x) diff --git a/src/psbt/mod.rs b/src/psbt/mod.rs index 2a17a938e..426a4dc64 100644 --- a/src/psbt/mod.rs +++ b/src/psbt/mod.rs @@ -397,6 +397,7 @@ impl<'psbt, Pk: MiniscriptKey + ToPublicKey> Satisfier for PsbtInputSatisfie } } +#[allow(clippy::ptr_arg)] // this signature is forced by use in `and_then` fn try_vec_as_preimage32(vec: &Vec) -> Option { if vec.len() == 32 { let mut arr = [0u8; 32]; From 0679c7ac9270b69ef6a84e69443a82e0856b1c52 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sat, 5 Jul 2025 02:45:11 +0000 Subject: [PATCH 09/11] miniscript/iter: make test module non-pub We have a `pub mod tests` module which is commented as being public "in case dependent libraries want to use these functions". However, it's also gated by #[cfg(test)]. I am not aware of any way that dependent libraries could compile *this* one with cfg(test) on. So this module was, in effect, never public. Make it non-pub to make things clearer, and also to silence all the "missing docs" warnings that appear when running clippy with --all-targets. This is NOT an API-breaking change even though it removes a public module, because the module was never actually usable. --- src/miniscript/iter.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/miniscript/iter.rs b/src/miniscript/iter.rs index 5c706125f..0091ab30a 100644 --- a/src/miniscript/iter.rs +++ b/src/miniscript/iter.rs @@ -222,10 +222,8 @@ impl<'a, Pk: MiniscriptKey, Ctx: ScriptContext> Iterator for PkIter<'a, Pk, Ctx> } } -// Module is public since it export testcase generation which may be used in -// dependent libraries for their own tasts based on Miniscript AST #[cfg(test)] -pub mod test { +mod test { use bitcoin; use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d, Hash}; use bitcoin::secp256k1; @@ -233,14 +231,14 @@ pub mod test { use super::Miniscript; use crate::miniscript::context::Segwitv0; - pub type TestData = ( + type TestData = ( Miniscript, Vec, Vec, bool, // Indicates that the top-level contains public key or hashes ); - pub fn gen_secp_pubkeys(n: usize) -> Vec { + fn gen_secp_pubkeys(n: usize) -> Vec { let mut ret = Vec::with_capacity(n); let secp = secp256k1::Secp256k1::new(); let mut sk = [0; 32]; @@ -258,14 +256,14 @@ pub mod test { ret } - pub fn gen_bitcoin_pubkeys(n: usize, compressed: bool) -> Vec { + fn gen_bitcoin_pubkeys(n: usize, compressed: bool) -> Vec { gen_secp_pubkeys(n) .into_iter() .map(|inner| bitcoin::PublicKey { inner, compressed }) .collect() } - pub fn gen_testcases() -> Vec { + fn gen_testcases() -> Vec { let k = gen_bitcoin_pubkeys(10, true); let _h: Vec = k .iter() From 28877820c05d0d802376356eba24babfc03de87d Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sat, 5 Jul 2025 17:52:34 +0000 Subject: [PATCH 10/11] key: fix DefiniteDescriptorKey construction from key with hardened step Our current API allows constructing a DefiniteDescriptorKey with hardened steps, which means that you can't actually derive a public key. However, the point of this type is to provide a DescriptorPublicKey which implements the ToPublicKey trait. This is a backport, so it introduces the `has_hardened_steps` helper function but does *not* make it pub, in the interest of avoiding gratuitious API changes. --- src/descriptor/key.rs | 45 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/src/descriptor/key.rs b/src/descriptor/key.rs index a05c0fc8d..7137f8914 100644 --- a/src/descriptor/key.rs +++ b/src/descriptor/key.rs @@ -442,6 +442,22 @@ impl DescriptorPublicKey { } } + /// Whether or not the key has a wildcard + fn has_hardened_step(&self) -> bool { + let paths = match self { + DescriptorPublicKey::Single(..) => &[], + DescriptorPublicKey::XPub(xpub) => core::slice::from_ref(&xpub.derivation_path), + }; + for p in paths { + for step in p.into_iter() { + if step.is_hardened() { + return true; + } + } + } + false + } + #[doc(hidden)] #[deprecated(note = "use at_derivation_index instead")] pub fn derive(self, index: u32) -> DefiniteDescriptorKey { @@ -759,7 +775,7 @@ impl DefiniteDescriptorKey { /// /// Returns `None` if the key contains a wildcard fn new(key: DescriptorPublicKey) -> Option { - if key.has_wildcard() { + if key.has_wildcard() || key.has_hardened_step() { None } else { Some(Self(key)) @@ -783,8 +799,8 @@ impl FromStr for DefiniteDescriptorKey { fn from_str(s: &str) -> Result { let inner = DescriptorPublicKey::from_str(s)?; DefiniteDescriptorKey::new(inner).ok_or(DescriptorKeyParseError( - "cannot parse key with a wilcard as a DerivedDescriptorKey", - )) + "cannot parse multi-path keys, keys with a wildcard or keys with hardened derivation steps as a DerivedDescriptorKey", + )) } } @@ -844,7 +860,9 @@ mod test { use bitcoin::secp256k1; - use super::{DescriptorKeyParseError, DescriptorPublicKey, DescriptorSecretKey}; + use super::{ + DefiniteDescriptorKey, DescriptorKeyParseError, DescriptorPublicKey, DescriptorSecretKey, + }; use crate::prelude::*; #[test] @@ -1008,4 +1026,23 @@ mod test { b"\xb0\x59\x11\x6a" ); } + + #[test] + fn definite_keys() { + // basic xpub + let desc = "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8" + .parse::() + .unwrap(); + assert!(DefiniteDescriptorKey::new(desc).is_some()); + // xpub with wildcard + let desc = "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8/*" + .parse::() + .unwrap(); + assert!(DefiniteDescriptorKey::new(desc).is_none()); + // xpub with hardened path + let desc = "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8/1'/2" + .parse::() + .unwrap(); + assert!(DefiniteDescriptorKey::new(desc).is_none()); + } } From d34188cabfb384f66dbed53869a7c12046687814 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sat, 5 Jul 2025 21:17:36 +0000 Subject: [PATCH 11/11] bump version to 9.2.1 --- Cargo-recent.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo-recent.lock b/Cargo-recent.lock index 8bf0f9f98..9783376e2 100644 --- a/Cargo-recent.lock +++ b/Cargo-recent.lock @@ -118,7 +118,7 @@ checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" [[package]] name = "miniscript" -version = "9.2.0" +version = "9.2.1" dependencies = [ "bitcoin", "hashbrown 0.11.0", diff --git a/Cargo.toml b/Cargo.toml index 3144010e3..0a2b8de2c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "miniscript" -version = "9.2.0" +version = "9.2.1" authors = ["Andrew Poelstra , Sanket Kanjalkar "] license = "CC0-1.0" homepage = "https://github.com/rust-bitcoin/rust-miniscript/"