diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2c31d92d..81330fd6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,8 +19,6 @@ jobs: - name: Check formatting uses: dprint/check@v2.1 - with: - dprint-version: 0.30.3 - name: Run clippy with default features run: cargo clippy --workspace --all-targets -- -D warnings diff --git a/Cargo.lock b/Cargo.lock index 47f5155a..de999d00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,7 +69,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -78,7 +78,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -174,7 +174,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -218,15 +218,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "base64" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -dependencies = [ - "byteorder", -] - [[package]] name = "base64" version = "0.12.3" @@ -250,9 +241,9 @@ dependencies = [ [[package]] name = "bdk" -version = "0.16.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3face7de38293a2f7e2a9f69a48b442f28e864da0fc7a6a977388e31bdc367d7" +checksum = "14836e8b1312be32e46f5da47e1189c2239fa75f9237a0a7c7aea9ee7071a2bc" dependencies = [ "async-trait", "bdk-macros", @@ -299,11 +290,10 @@ checksum = "50ae17cabbc8a38a1e3e4c1a6a664e9a09672dc14d0896fa8d865d3a5a446b07" [[package]] name = "bincode" -version = "1.3.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "byteorder", "serde", ] @@ -324,9 +314,9 @@ checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitcoin" -version = "0.27.1" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a41df6ad9642c5c15ae312dd3d074de38fd3eb7cc87ad4ce10f90292a83fe4d" +checksum = "05bba324e6baf655b882df672453dbbc527bc938cadd27750ae510aaccc3a66a" dependencies = [ "base64-compat", "bech32", @@ -338,19 +328,18 @@ dependencies = [ [[package]] name = "bitcoin-harness" version = "0.2.0" -source = "git+https://github.com/coblox/bitcoin-harness-rs#53bdc62a98b9a1e0debb06ab3a4239df1bfe4e04" +source = "git+https://github.com/coblox/bitcoin-harness-rs?rev=bff9a64b5cd75dec2ce807cbfade7b98c2e1e0d4#bff9a64b5cd75dec2ce807cbfade7b98c2e1e0d4" dependencies = [ - "async-trait", "base64 0.12.3", "bitcoin", "bitcoincore-rpc-json", "futures", "hex", - "jsonrpc_client 0.5.1", + "jsonrpc_client", "reqwest", "serde", "serde_json", - "testcontainers 0.11.0", + "testcontainers 0.14.0", "thiserror", "tokio", "tracing", @@ -368,9 +357,9 @@ dependencies = [ [[package]] name = "bitcoincore-rpc-json" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce91de73c61f5776cf938bfa88378c5b404a70e3369b761dacbe6024fea79dd" +checksum = "2e2ae16202721ba8c3409045681fac790a5ddc791f05731a2df22c0c6bffc0f1" dependencies = [ "bitcoin", "serde", @@ -429,6 +418,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "bollard-stubs" +version = "1.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2f2e73fffe9455141e170fb9c1feb0ac521ec7e7dcd47a7cab72a658490fb8" +dependencies = [ + "chrono", + "serde", + "serde_with", +] + [[package]] name = "bs58" version = "0.4.0" @@ -541,7 +541,9 @@ dependencies = [ "libc", "num-integer", "num-traits", - "winapi 0.3.9", + "serde", + "time 0.1.43", + "winapi", ] [[package]] @@ -634,7 +636,7 @@ dependencies = [ "regex", "terminal_size", "unicode-width", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -763,7 +765,7 @@ dependencies = [ "parking_lot 0.12.0", "signal-hook", "signal-hook-mio", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -772,7 +774,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -898,17 +900,6 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "derive_more" version = "0.99.16" @@ -950,6 +941,7 @@ checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ "block-buffer 0.10.2", "crypto-common", + "subtle", ] [[package]] @@ -970,7 +962,7 @@ checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", "redox_users", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -987,8 +979,8 @@ checksum = "5caaa75cbd2b960ff1e5392d2cfb1f44717fffe12fc1f32b7b5d1267f99732a6" [[package]] name = "ecdsa_fun" -version = "0.6.2-alpha.0" -source = "git+https://github.com/LLFourn/secp256kfun#84134daf34845434d7f38cdae7ffc31730a3b1e9" +version = "0.7.1" +source = "git+https://github.com/LLFourn/secp256kfun#7c3d592bae20cd4b4309ed6cf6551dc971fed43e" dependencies = [ "bincode", "rand_chacha 0.3.1", @@ -1031,18 +1023,20 @@ dependencies = [ [[package]] name = "electrum-client" -version = "0.8.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd12f125852d77980725243b2a8b3bea73cd4c7a22c33bc52b08b664c561dc7" +checksum = "af53c415260dcb220fa02182669727c730535bfed4edbfde42e1291342af95cd" dependencies = [ "bitcoin", + "byteorder", + "libc", "log", - "rustls 0.16.0", + "rustls 0.20.2", "serde", "serde_json", - "socks", - "webpki 0.21.4", - "webpki-roots 0.19.0", + "webpki 0.22.0", + "webpki-roots 0.22.2", + "winapi", ] [[package]] @@ -1110,7 +1104,7 @@ dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1167,7 +1161,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1458,16 +1452,6 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" -[[package]] -name = "hmac" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" -dependencies = [ - "crypto-mac 0.8.0", - "digest 0.9.0", -] - [[package]] name = "hmac" version = "0.10.1" @@ -1488,6 +1472,15 @@ dependencies = [ "digest 0.9.0", ] +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.3", +] + [[package]] name = "hostname" version = "0.3.1" @@ -1496,7 +1489,7 @@ checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" dependencies = [ "libc", "match_cfg", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1593,7 +1586,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbc0fa01ffc752e9dbc72818cdb072cd028b86be5e09dd04c5a643704fe101a9" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1637,7 +1630,7 @@ checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" dependencies = [ "socket2 0.3.19", "widestring", - "winapi 0.3.9", + "winapi", "winreg 0.6.2", ] @@ -1686,20 +1679,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "jsonrpc_client" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc8515639023bf4260cf89475355fa77301685418f655c680528c380759e7782" -dependencies = [ - "async-trait", - "jsonrpc_client_macro 0.2.0", - "reqwest", - "serde", - "serde_json", - "url", -] - [[package]] name = "jsonrpc_client" version = "0.7.1" @@ -1707,23 +1686,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c1ec33c537dc1d5a8b597313db6d213fee54320f81ea0d19b0c3869b282e1a" dependencies = [ "async-trait", - "jsonrpc_client_macro 0.3.0", + "jsonrpc_client_macro", "reqwest", "serde", "serde_json", "url", ] -[[package]] -name = "jsonrpc_client_macro" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f3d1e50fefe4252d2e44c805663e73a8c0b2002b73f834ea055c8ed7fc46a8" -dependencies = [ - "quote", - "syn", -] - [[package]] name = "jsonrpc_client_macro" version = "0.3.0" @@ -2194,9 +2163,9 @@ checksum = "0c835948974f68e0bd58636fc6c5b1fbff7b297e3046f11b3b3c18bbac012c6d" [[package]] name = "miniscript" -version = "6.0.1" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d69450033bf162edf854d4aacaff82ca5ef34fa81f6cf69e1c81a103f0834997" +checksum = "da39fc7a8adea97a677337b0091779dd86349226b869053af496584a9b9e5847" dependencies = [ "bitcoin", "serde", @@ -2221,7 +2190,7 @@ dependencies = [ "log", "miow", "ntapi", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2231,7 +2200,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" dependencies = [ "socket2 0.3.19", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2283,7 +2252,7 @@ dependencies = [ "curve25519-dalek", "hex", "hex-literal", - "jsonrpc_client 0.7.1", + "jsonrpc_client", "monero", "monero-epee-bin-serde", "rand 0.7.3", @@ -2408,7 +2377,7 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2601,7 +2570,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2927,7 +2896,7 @@ dependencies = [ "libc", "rand_core 0.3.1", "rdrand", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2946,7 +2915,7 @@ dependencies = [ "rand_os", "rand_pcg", "rand_xorshift 0.1.1", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -3081,7 +3050,7 @@ checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" dependencies = [ "libc", "rand_core 0.4.2", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -3095,7 +3064,7 @@ dependencies = [ "libc", "rand_core 0.4.2", "rdrand", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -3187,7 +3156,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -3253,7 +3222,7 @@ dependencies = [ "spin", "untrusted", "web-sys", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -3298,19 +3267,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustls" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e" -dependencies = [ - "base64 0.10.1", - "log", - "ring", - "sct 0.6.0", - "webpki 0.21.4", -] - [[package]] name = "rustls" version = "0.19.0" @@ -3399,7 +3355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" dependencies = [ "lazy_static", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -3430,9 +3386,9 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.20.3" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" +checksum = "26947345339603ae8395f68e2f3d85a6b0a8ddfe6315818e80b8504415099db0" dependencies = [ "rand 0.6.5", "secp256k1-sys", @@ -3441,32 +3397,34 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e4b6455ee49f5901c8985b88f98fb0a0e1d90a6661f5a03f4888bd987dad29" +checksum = "152e20a0fd0519390fc43ab404663af8a0b794273d2a91d60ad4a39f13ffe110" dependencies = [ "cc", ] [[package]] name = "secp256kfun" -version = "0.6.2-alpha.0" -source = "git+https://github.com/LLFourn/secp256kfun#84134daf34845434d7f38cdae7ffc31730a3b1e9" +version = "0.7.1" +source = "git+https://github.com/LLFourn/secp256kfun#7c3d592bae20cd4b4309ed6cf6551dc971fed43e" dependencies = [ - "digest 0.9.0", + "digest 0.10.3", "rand_core 0.6.2", "secp256k1", - "secp256kfun_parity_backend", + "secp256kfun_k256_backend", "serde", "subtle-ng", ] [[package]] -name = "secp256kfun_parity_backend" -version = "0.1.6-alpha.0" -source = "git+https://github.com/LLFourn/secp256kfun#84134daf34845434d7f38cdae7ffc31730a3b1e9" +name = "secp256kfun_k256_backend" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "007b33ee2c671688cc9a6b400428440aac4af0d6bc517c4f71477f783fcee18d" dependencies = [ - "crunchy", + "cfg-if 1.0.0", + "generic-array", "subtle-ng", ] @@ -3513,9 +3471,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.143" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553" +checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" dependencies = [ "serde_derive", ] @@ -3542,9 +3500,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.143" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391" +checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" dependencies = [ "proc-macro2", "quote", @@ -3657,11 +3615,11 @@ dependencies = [ [[package]] name = "sigma_fun" -version = "0.3.2-alpha.0" -source = "git+https://github.com/LLFourn/secp256kfun#84134daf34845434d7f38cdae7ffc31730a3b1e9" +version = "0.4.1" +source = "git+https://github.com/LLFourn/secp256kfun#7c3d592bae20cd4b4309ed6cf6551dc971fed43e" dependencies = [ "curve25519-dalek-ng", - "digest 0.9.0", + "digest 0.10.3", "generic-array", "rand_core 0.6.2", "secp256kfun", @@ -3758,7 +3716,7 @@ checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" dependencies = [ "cfg-if 1.0.0", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -3768,19 +3726,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2" dependencies = [ "libc", - "winapi 0.3.9", -] - -[[package]] -name = "socks" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30f86c7635fadf2814201a4f67efefb0007588ae7422ce299f354ab5c97f61ae" -dependencies = [ - "byteorder", - "libc", - "winapi 0.2.8", - "ws2_32-sys", + "winapi", ] [[package]] @@ -4071,7 +4017,7 @@ dependencies = [ "serde_cbor", "serde_json", "serde_with", - "sha2 0.9.8", + "sha2 0.10.2", "sigma_fun", "spectral", "sqlx", @@ -4133,7 +4079,7 @@ dependencies = [ "libc", "redox_syscall", "remove_dir_all", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -4143,20 +4089,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86ca8ced750734db02076f44132d802af0b33b09942331f4459dde8636fd2406" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] [[package]] name = "testcontainers" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "959ba8f27f326db356678cb5d6ac8a418f3cb9c1ad2d677c1fe8d3afb9056d46" +checksum = "d5e3ed6e3598dbf32cba8cb356b881c085e0adea57597f387723430dd94b4084" dependencies = [ - "derivative", "hex", - "hmac 0.8.1", + "hmac 0.10.1", "log", - "rand 0.7.3", + "rand 0.8.3", "serde", "serde_json", "sha2 0.9.8", @@ -4164,17 +4109,19 @@ dependencies = [ [[package]] name = "testcontainers" -version = "0.12.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5e3ed6e3598dbf32cba8cb356b881c085e0adea57597f387723430dd94b4084" +checksum = "0e2b1567ca8a2b819ea7b28c92be35d9f76fb9edb214321dcc86eb96023d1f87" dependencies = [ + "bollard-stubs", + "futures", "hex", - "hmac 0.10.1", + "hmac 0.12.1", "log", "rand 0.8.3", "serde", "serde_json", - "sha2 0.9.8", + "sha2 0.10.2", ] [[package]] @@ -4222,7 +4169,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -4277,7 +4224,7 @@ dependencies = [ "pin-project-lite 0.2.9", "signal-hook-registry", "tokio-macros", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -4920,15 +4867,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "webpki-roots" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8eff4b7516a57307f9349c64bf34caa34b940b66fed4b2fb3136cb7386e5739" -dependencies = [ - "webpki 0.21.4", -] - [[package]] name = "webpki-roots" version = "0.21.0" @@ -4973,12 +4911,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - [[package]] name = "winapi" version = "0.3.9" @@ -4989,12 +4921,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -5056,7 +4982,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -5065,17 +4991,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", + "winapi", ] [[package]] diff --git a/README.md b/README.md index 5a8e39ec..d696f7b5 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Please have a look at the [contribution guidelines](./CONTRIBUTING.md). ## Rust Version Support Please note that only the latest stable Rust toolchain is supported. -All stable toolchains since 1.58 _should_ work. +All stable toolchains since 1.60 _should_ work. ## Contact diff --git a/monero-harness/src/lib.rs b/monero-harness/src/lib.rs index bdcfc206..5e1f2727 100644 --- a/monero-harness/src/lib.rs +++ b/monero-harness/src/lib.rs @@ -296,7 +296,7 @@ impl<'c> MoneroWalletRpc { /// Sends amount to address pub async fn transfer(&self, address: &str, amount: u64) -> Result { - Ok(self.client().transfer_single(0, amount, address).await?) + self.client().transfer_single(0, amount, address).await } pub async fn address(&self) -> Result { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 04d5285c..bcffd4a6 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.59" +channel = "1.60" components = ["clippy"] targets = ["armv7-unknown-linux-gnueabihf"] diff --git a/swap/Cargo.toml b/swap/Cargo.toml index 3635a3d5..bbd08476 100644 --- a/swap/Cargo.toml +++ b/swap/Cargo.toml @@ -15,9 +15,9 @@ async-trait = "0.1" atty = "0.2" backoff = { version = "0.4", features = [ "tokio" ] } base64 = "0.13" -bdk = "0.16" +bdk = "0.22" big-bytes = "1" -bitcoin = { version = "0.27", features = [ "rand", "use-serde" ] } +bitcoin = { version = "0.28", features = [ "rand", "use-serde" ] } bmrng = "0.5" comfy-table = "5.0" config = { version = "0.11", default-features = false, features = [ "toml" ] } @@ -26,7 +26,7 @@ curve25519-dalek = { package = "curve25519-dalek-ng", version = "4" } data-encoding = "2.3" dialoguer = "0.10" directories-next = "2" -ecdsa_fun = { git = "https://github.com/LLFourn/secp256kfun", default-features = false, features = [ "libsecp_compat", "serde" ] } +ecdsa_fun = { git = "https://github.com/LLFourn/secp256kfun", default-features = false, features = [ "libsecp_compat", "serde", "adaptor" ] } ed25519-dalek = "1" futures = { version = "0.3", default-features = false } hex = "0.4" @@ -46,8 +46,8 @@ serde = { version = "1", features = [ "derive" ] } serde_cbor = "0.11" serde_json = "1" serde_with = { version = "1", features = [ "macros" ] } -sha2 = "0.9" -sigma_fun = { git = "https://github.com/LLFourn/secp256kfun", default-features = false, features = [ "ed25519", "serde" ] } +sha2 = "0.10" +sigma_fun = { git = "https://github.com/LLFourn/secp256kfun", default-features = false, features = [ "ed25519", "serde", "secp256k1", "alloc" ] } sqlx = { version = "0.5", features = [ "sqlite", "runtime-tokio-rustls", "offline" ] } structopt = "0.3" strum = { version = "0.24", features = [ "derive" ] } @@ -74,7 +74,7 @@ tokio-tar = "0.3" zip = "0.5" [dev-dependencies] -bitcoin-harness = { git = "https://github.com/coblox/bitcoin-harness-rs" } +bitcoin-harness = { git = "https://github.com/coblox/bitcoin-harness-rs", rev = "bff9a64b5cd75dec2ce807cbfade7b98c2e1e0d4" } # waiting on crates.io release get-port = "3" hyper = "0.14" monero-harness = { path = "../monero-harness" } diff --git a/swap/src/bitcoin.rs b/swap/src/bitcoin.rs index cc9095e3..4215fe44 100644 --- a/swap/src/bitcoin.rs +++ b/swap/src/bitcoin.rs @@ -27,7 +27,7 @@ pub use wallet::WalletBuilder; use crate::bitcoin::wallet::ScriptStatus; use ::bitcoin::hashes::hex::ToHex; use ::bitcoin::hashes::Hash; -use ::bitcoin::{secp256k1, SigHash}; +use ::bitcoin::{secp256k1, Sighash}; use anyhow::{bail, Context, Result}; use bdk::miniscript::descriptor::Wsh; use bdk::miniscript::{Descriptor, Segwitv0}; @@ -78,7 +78,7 @@ impl SecretKey { self.inner.to_bytes() } - pub fn sign(&self, digest: SigHash) -> Signature { + pub fn sign(&self, digest: Sighash) -> Signature { let ecdsa = ECDSA::>::default(); ecdsa.sign(&self.inner, &digest.into_inner()) @@ -98,7 +98,7 @@ impl SecretKey { // alice now has s_a and s_b and can refund monero // self = a, Y = S_b, digest = tx_refund - pub fn encsign(&self, Y: PublicKey, digest: SigHash) -> EncryptedSignature { + pub fn encsign(&self, Y: PublicKey, digest: Sighash) -> EncryptedSignature { let adaptor = Adaptor::< HashTranscript, Deterministic, @@ -124,12 +124,12 @@ impl From for Point { } } -impl From for ::bitcoin::PublicKey { - fn from(from: PublicKey) -> Self { - ::bitcoin::PublicKey { - compressed: true, - key: from.0.into(), - } +impl TryFrom for bitcoin::PublicKey { + type Error = bitcoin::util::key::Error; + + fn try_from(pubkey: PublicKey) -> Result { + let bytes = pubkey.0.to_bytes(); + bitcoin::PublicKey::from_slice(&bytes) } } @@ -166,7 +166,7 @@ impl From for PublicKey { pub fn verify_sig( verification_key: &PublicKey, - transaction_sighash: &SigHash, + transaction_sighash: &Sighash, sig: &Signature, ) -> Result<()> { let ecdsa = ECDSA::verify_only(); @@ -185,7 +185,7 @@ pub struct InvalidSignature; pub fn verify_encsig( verification_key: PublicKey, encryption_key: PublicKey, - digest: &SigHash, + digest: &Sighash, encsig: &EncryptedSignature, ) -> Result<()> { let adaptor = Adaptor::, Deterministic>::default(); @@ -457,7 +457,7 @@ mod tests { // transactions have 2 signatures the weight can be up to 8 bytes less than // the static weight (4 bytes per signature). fn assert_weight(transaction: Transaction, expected_weight: usize, tx_name: &str) { - let is_weight = transaction.get_weight(); + let is_weight = transaction.weight(); assert!( expected_weight - is_weight <= 8, diff --git a/swap/src/bitcoin/cancel.rs b/swap/src/bitcoin/cancel.rs index f3f13032..eed2c590 100644 --- a/swap/src/bitcoin/cancel.rs +++ b/swap/src/bitcoin/cancel.rs @@ -3,8 +3,8 @@ use crate::bitcoin::wallet::Watchable; use crate::bitcoin::{ build_shared_output_descriptor, Address, Amount, BlockHeight, PublicKey, Transaction, TxLock, }; -use ::bitcoin::util::bip143::SigHashCache; -use ::bitcoin::{OutPoint, Script, SigHash, SigHashType, TxIn, TxOut, Txid}; +use ::bitcoin::util::sighash::SighashCache; +use ::bitcoin::{EcdsaSighashType, OutPoint, Script, Sighash, TxIn, TxOut, Txid}; use anyhow::Result; use bdk::miniscript::{Descriptor, DescriptorTrait}; use ecdsa_fun::Signature; @@ -91,7 +91,7 @@ impl PartialEq for u32 { #[derive(Debug)] pub struct TxCancel { inner: Transaction, - digest: SigHash, + digest: Sighash, pub(in crate::bitcoin) output_descriptor: Descriptor<::bitcoin::PublicKey>, lock_output_descriptor: Descriptor<::bitcoin::PublicKey>, } @@ -110,7 +110,7 @@ impl TxCancel { previous_output: tx_lock.as_outpoint(), script_sig: Default::default(), sequence: cancel_timelock.0, - witness: Vec::new(), + witness: Default::default(), }; let tx_out = TxOut { @@ -125,12 +125,14 @@ impl TxCancel { output: vec![tx_out], }; - let digest = SigHashCache::new(&transaction).signature_hash( - 0, // Only one input: lock_input (lock transaction) - &tx_lock.output_descriptor.script_code(), - tx_lock.lock_amount().as_sat(), - SigHashType::All, - ); + let digest = SighashCache::new(&transaction) + .segwit_signature_hash( + 0, // Only one input: lock_input (lock transaction) + &tx_lock.output_descriptor.script_code().expect("scriptcode"), + tx_lock.lock_amount().as_sat(), + EcdsaSighashType::All, + ) + .expect("sighash"); Self { inner: transaction, @@ -144,7 +146,7 @@ impl TxCancel { self.inner.txid() } - pub fn digest(&self) -> SigHash { + pub fn digest(&self) -> Sighash { self.digest } @@ -198,16 +200,22 @@ impl TxCancel { let A = ::bitcoin::PublicKey { compressed: true, - key: A.0.into(), + inner: A.0.into(), }; let B = ::bitcoin::PublicKey { compressed: true, - key: B.0.into(), + inner: B.0.into(), }; // The order in which these are inserted doesn't matter - satisfier.insert(A, (sig_a.into(), ::bitcoin::SigHashType::All)); - satisfier.insert(B, (sig_b.into(), ::bitcoin::SigHashType::All)); + satisfier.insert(A, ::bitcoin::EcdsaSig { + sig: sig_a.into(), + hash_ty: EcdsaSighashType::All, + }); + satisfier.insert(B, ::bitcoin::EcdsaSig { + sig: sig_b.into(), + hash_ty: EcdsaSighashType::All, + }); satisfier }; @@ -231,7 +239,7 @@ impl TxCancel { previous_output, script_sig: Default::default(), sequence: sequence.map(|seq| seq.0).unwrap_or(0xFFFF_FFFF), - witness: Vec::new(), + witness: Default::default(), }; let tx_out = TxOut { diff --git a/swap/src/bitcoin/lock.rs b/swap/src/bitcoin/lock.rs index 2f195ff7..1840997c 100644 --- a/swap/src/bitcoin/lock.rs +++ b/swap/src/bitcoin/lock.rs @@ -20,8 +20,8 @@ pub struct TxLock { } impl TxLock { - pub async fn new( - wallet: &Wallet, + pub async fn new( + wallet: &Wallet, amount: Amount, A: PublicKey, B: PublicKey, @@ -57,7 +57,7 @@ impl TxLock { B: PublicKey, btc: Amount, ) -> Result { - let shared_output_candidate = match psbt.global.unsigned_tx.output.as_slice() { + let shared_output_candidate = match psbt.unsigned_tx.output.as_slice() { [shared_output_candidate, _] if shared_output_candidate.value == btc.as_sat() => { shared_output_candidate } @@ -144,7 +144,7 @@ impl TxLock { previous_output, script_sig: Default::default(), sequence: sequence.unwrap_or(0xFFFF_FFFF), - witness: Vec::new(), + witness: Default::default(), }; let fee = spending_fee.as_sat(); @@ -212,7 +212,7 @@ mod tests { let psbt = bob_make_psbt(A, B, &wallet, agreed_amount).await; assert_eq!( - psbt.global.unsigned_tx.output.len(), + psbt.unsigned_tx.output.len(), 1, "psbt should only have a single output" ); @@ -264,7 +264,7 @@ mod tests { async fn bob_make_psbt( A: PublicKey, B: PublicKey, - wallet: &Wallet<(), bdk::database::MemoryDatabase, StaticFeeRate>, + wallet: &Wallet, amount: Amount, ) -> PartiallySignedTransaction { let change = wallet.new_address().await.unwrap(); diff --git a/swap/src/bitcoin/punish.rs b/swap/src/bitcoin/punish.rs index fda37155..0d21c3af 100644 --- a/swap/src/bitcoin/punish.rs +++ b/swap/src/bitcoin/punish.rs @@ -1,7 +1,7 @@ use crate::bitcoin::wallet::Watchable; use crate::bitcoin::{self, Address, Amount, PunishTimelock, Transaction, TxCancel, Txid}; -use ::bitcoin::util::bip143::SigHashCache; -use ::bitcoin::{SigHash, SigHashType}; +use ::bitcoin::util::sighash::SighashCache; +use ::bitcoin::{EcdsaSighashType, Sighash}; use anyhow::{Context, Result}; use bdk::bitcoin::Script; use bdk::miniscript::{Descriptor, DescriptorTrait}; @@ -10,7 +10,7 @@ use std::collections::HashMap; #[derive(Debug)] pub struct TxPunish { inner: Transaction, - digest: SigHash, + digest: Sighash, cancel_output_descriptor: Descriptor<::bitcoin::PublicKey>, watch_script: Script, } @@ -25,12 +25,17 @@ impl TxPunish { let tx_punish = tx_cancel.build_spend_transaction(punish_address, Some(punish_timelock), spending_fee); - let digest = SigHashCache::new(&tx_punish).signature_hash( - 0, // Only one input: cancel transaction - &tx_cancel.output_descriptor.script_code(), - tx_cancel.amount().as_sat(), - SigHashType::All, - ); + let digest = SighashCache::new(&tx_punish) + .segwit_signature_hash( + 0, // Only one input: cancel transaction + &tx_cancel + .output_descriptor + .script_code() + .expect("scriptcode"), + tx_cancel.amount().as_sat(), + EcdsaSighashType::All, + ) + .expect("sighash"); Self { inner: tx_punish, @@ -40,7 +45,7 @@ impl TxPunish { } } - pub fn digest(&self) -> SigHash { + pub fn digest(&self) -> Sighash { self.digest } @@ -56,12 +61,18 @@ impl TxPunish { let satisfier = { let mut satisfier = HashMap::with_capacity(2); - let A = a.public().into(); - let B = B.into(); + let A = a.public().try_into()?; + let B = B.try_into()?; // The order in which these are inserted doesn't matter - satisfier.insert(A, (sig_a.into(), ::bitcoin::SigHashType::All)); - satisfier.insert(B, (sig_b.into(), ::bitcoin::SigHashType::All)); + satisfier.insert(A, ::bitcoin::EcdsaSig { + sig: sig_a.into(), + hash_ty: EcdsaSighashType::All, + }); + satisfier.insert(B, ::bitcoin::EcdsaSig { + sig: sig_b.into(), + hash_ty: EcdsaSighashType::All, + }); satisfier }; diff --git a/swap/src/bitcoin/redeem.rs b/swap/src/bitcoin/redeem.rs index 8c8b502e..39e38ad6 100644 --- a/swap/src/bitcoin/redeem.rs +++ b/swap/src/bitcoin/redeem.rs @@ -3,11 +3,12 @@ use crate::bitcoin::{ verify_encsig, verify_sig, Address, Amount, EmptyWitnessStack, EncryptedSignature, NoInputs, NotThreeWitnesses, PublicKey, SecretKey, TooManyInputs, Transaction, TxLock, }; -use ::bitcoin::util::bip143::SigHashCache; -use ::bitcoin::{SigHash, SigHashType, Txid}; +use ::bitcoin::{Sighash, Txid}; use anyhow::{bail, Context, Result}; use bdk::miniscript::{Descriptor, DescriptorTrait}; -use bitcoin::Script; +use bitcoin::secp256k1::ecdsa; +use bitcoin::util::sighash::SighashCache; +use bitcoin::{EcdsaSighashType, Script}; use ecdsa_fun::adaptor::{Adaptor, HashTranscript}; use ecdsa_fun::fun::Scalar; use ecdsa_fun::nonce::Deterministic; @@ -18,7 +19,7 @@ use std::collections::HashMap; #[derive(Clone, Debug)] pub struct TxRedeem { inner: Transaction, - digest: SigHash, + digest: Sighash, lock_output_descriptor: Descriptor<::bitcoin::PublicKey>, watch_script: Script, } @@ -29,12 +30,14 @@ impl TxRedeem { // redeem transaction let tx_redeem = tx_lock.build_spend_transaction(redeem_address, None, spending_fee); - let digest = SigHashCache::new(&tx_redeem).signature_hash( - 0, // Only one input: lock_input (lock transaction) - &tx_lock.output_descriptor.script_code(), - tx_lock.lock_amount().as_sat(), - SigHashType::All, - ); + let digest = SighashCache::new(&tx_redeem) + .segwit_signature_hash( + 0, // Only one input: lock_input (lock transaction) + &tx_lock.output_descriptor.script_code().expect("scriptcode"), + tx_lock.lock_amount().as_sat(), + EcdsaSighashType::All, + ) + .expect("sighash"); Self { inner: tx_redeem, @@ -48,7 +51,7 @@ impl TxRedeem { self.inner.txid() } - pub fn digest(&self) -> SigHash { + pub fn digest(&self) -> Sighash { self.digest } @@ -76,16 +79,22 @@ impl TxRedeem { let A = ::bitcoin::PublicKey { compressed: true, - key: a.public.into(), + inner: a.public.into(), }; let B = ::bitcoin::PublicKey { compressed: true, - key: B.0.into(), + inner: B.0.into(), }; // The order in which these are inserted doesn't matter - satisfier.insert(A, (sig_a.into(), ::bitcoin::SigHashType::All)); - satisfier.insert(B, (sig_b.into(), ::bitcoin::SigHashType::All)); + satisfier.insert(A, ::bitcoin::EcdsaSig { + sig: sig_a.into(), + hash_ty: EcdsaSighashType::All, + }); + satisfier.insert(B, ::bitcoin::EcdsaSig { + sig: sig_b.into(), + hash_ty: EcdsaSighashType::All, + }); satisfier }; @@ -108,19 +117,10 @@ impl TxRedeem { [inputs @ ..] => bail!(TooManyInputs(inputs.len())), }; - let sigs = match input - .witness - .iter() - .map(|vec| vec.as_slice()) - .collect::>() - .as_slice() - { + let sigs = match input.witness.iter().collect::>().as_slice() { [sig_1, sig_2, _script] => [sig_1, sig_2] .iter() - .map(|sig| { - bitcoin::secp256k1::Signature::from_der(&sig[..sig.len() - 1]) - .map(Signature::from) - }) + .map(|sig| ecdsa::Signature::from_der(&sig[..sig.len() - 1]).map(Signature::from)) .collect::, _>>(), [] => bail!(EmptyWitnessStack), [witnesses @ ..] => bail!(NotThreeWitnesses(witnesses.len())), diff --git a/swap/src/bitcoin/refund.rs b/swap/src/bitcoin/refund.rs index f5fb44c5..ba7ac9ef 100644 --- a/swap/src/bitcoin/refund.rs +++ b/swap/src/bitcoin/refund.rs @@ -4,8 +4,9 @@ use crate::bitcoin::{ TooManyInputs, Transaction, TxCancel, }; use crate::{bitcoin, monero}; -use ::bitcoin::util::bip143::SigHashCache; -use ::bitcoin::{Script, SigHash, SigHashType, Txid}; +use ::bitcoin::secp256k1::ecdsa; +use ::bitcoin::util::sighash::SighashCache; +use ::bitcoin::{EcdsaSighashType, Script, Sighash, Txid}; use anyhow::{bail, Context, Result}; use bdk::miniscript::{Descriptor, DescriptorTrait}; use ecdsa_fun::Signature; @@ -14,7 +15,7 @@ use std::collections::HashMap; #[derive(Debug)] pub struct TxRefund { inner: Transaction, - digest: SigHash, + digest: Sighash, cancel_output_descriptor: Descriptor<::bitcoin::PublicKey>, watch_script: Script, } @@ -23,12 +24,17 @@ impl TxRefund { pub fn new(tx_cancel: &TxCancel, refund_address: &Address, spending_fee: Amount) -> Self { let tx_refund = tx_cancel.build_spend_transaction(refund_address, None, spending_fee); - let digest = SigHashCache::new(&tx_refund).signature_hash( - 0, // Only one input: cancel transaction - &tx_cancel.output_descriptor.script_code(), - tx_cancel.amount().as_sat(), - SigHashType::All, - ); + let digest = SighashCache::new(&tx_refund) + .segwit_signature_hash( + 0, // Only one input: cancel transaction + &tx_cancel + .output_descriptor + .script_code() + .expect("scriptcode"), + tx_cancel.amount().as_sat(), + EcdsaSighashType::All, + ) + .expect("sighash"); Self { inner: tx_refund, @@ -42,7 +48,7 @@ impl TxRefund { self.inner.txid() } - pub fn digest(&self) -> SigHash { + pub fn digest(&self) -> Sighash { self.digest } @@ -56,16 +62,22 @@ impl TxRefund { let A = ::bitcoin::PublicKey { compressed: true, - key: A.0.into(), + inner: A.0.into(), }; let B = ::bitcoin::PublicKey { compressed: true, - key: B.0.into(), + inner: B.0.into(), }; // The order in which these are inserted doesn't matter - satisfier.insert(A, (sig_a.into(), ::bitcoin::SigHashType::All)); - satisfier.insert(B, (sig_b.into(), ::bitcoin::SigHashType::All)); + satisfier.insert(A, ::bitcoin::EcdsaSig { + sig: sig_a.into(), + hash_ty: EcdsaSighashType::All, + }); + satisfier.insert(B, ::bitcoin::EcdsaSig { + sig: sig_b.into(), + hash_ty: EcdsaSighashType::All, + }); satisfier }; @@ -112,19 +124,10 @@ impl TxRefund { [inputs @ ..] => bail!(TooManyInputs(inputs.len())), }; - let sigs = match input - .witness - .iter() - .map(|vec| vec.as_slice()) - .collect::>() - .as_slice() - { + let sigs = match input.witness.iter().collect::>().as_slice() { [sig_1, sig_2, _script] => [sig_1, sig_2] .iter() - .map(|sig| { - bitcoin::secp256k1::Signature::from_der(&sig[..sig.len() - 1]) - .map(Signature::from) - }) + .map(|sig| ecdsa::Signature::from_der(&sig[..sig.len() - 1]).map(Signature::from)) .collect::, _>>(), [] => bail!(EmptyWitnessStack), [witnesses @ ..] => bail!(NotThreeWitnesses(witnesses.len())), diff --git a/swap/src/bitcoin/wallet.rs b/swap/src/bitcoin/wallet.rs index fc615911..44922dbb 100644 --- a/swap/src/bitcoin/wallet.rs +++ b/swap/src/bitcoin/wallet.rs @@ -4,14 +4,14 @@ use crate::env; use ::bitcoin::util::psbt::PartiallySignedTransaction; use ::bitcoin::Txid; use anyhow::{bail, Context, Result}; -use bdk::blockchain::{noop_progress, Blockchain, ElectrumBlockchain}; +use bdk::blockchain::{Blockchain, ElectrumBlockchain, GetTx}; use bdk::database::BatchDatabase; use bdk::descriptor::Segwitv0; use bdk::electrum_client::{ElectrumApi, GetHistoryRes}; use bdk::keys::DerivableKey; -use bdk::wallet::export::WalletExport; +use bdk::wallet::export::FullyNodedExport; use bdk::wallet::AddressIndex; -use bdk::{FeeRate, KeychainKind, SignOptions}; +use bdk::{FeeRate, KeychainKind, SignOptions, SyncOptions}; use bitcoin::{Network, Script}; use reqwest::Url; use rust_decimal::prelude::*; @@ -33,9 +33,9 @@ const MAX_RELATIVE_TX_FEE: Decimal = dec!(0.03); const MAX_ABSOLUTE_TX_FEE: Decimal = dec!(100_000); const DUST_AMOUNT: u64 = 546; -pub struct Wallet { +pub struct Wallet { client: Arc>, - wallet: Arc>>, + wallet: Arc>>, finality_confirmations: u32, network: Network, target_block: usize, @@ -49,12 +49,6 @@ impl Wallet { env_config: env::Config, target_block: usize, ) -> Result { - let config = bdk::electrum_client::ConfigBuilder::default() - .retry(5) - .build(); - let client = bdk::electrum_client::Client::from_config(electrum_rpc_url.as_str(), config) - .context("Failed to initialize Electrum RPC client")?; - let db = bdk::sled::open(wallet_dir)?.open_tree(SLED_TREE_NAME)?; let wallet = bdk::Wallet::new( @@ -62,19 +56,14 @@ impl Wallet { Some(bdk::template::Bip84(key, KeychainKind::Internal)), env_config.bitcoin_network, db, - ElectrumBlockchain::from(client), )?; - let electrum = bdk::electrum_client::Client::new(electrum_rpc_url.as_str()) - .context("Failed to initialize Electrum RPC client")?; + let client = Client::new(electrum_rpc_url, env_config.bitcoin_sync_interval())?; let network = wallet.network(); Ok(Self { - client: Arc::new(Mutex::new(Client::new( - electrum, - env_config.bitcoin_sync_interval(), - )?)), + client: Arc::new(Mutex::new(client)), wallet: Arc::new(Mutex::new(wallet)), finality_confirmations: env_config.bitcoin_finality_confirmations, network, @@ -99,13 +88,12 @@ impl Wallet { .subscribe_to((txid, transaction.output[0].script_pubkey.clone())) .await; - self.wallet - .lock() - .await - .broadcast(&transaction) - .with_context(|| { - format!("Failed to broadcast Bitcoin {} transaction {}", kind, txid) - })?; + let client = self.client.lock().await; + let blockchain = client.blockchain(); + + blockchain.broadcast(&transaction).with_context(|| { + format!("Failed to broadcast Bitcoin {} transaction {}", kind, txid) + })?; tracing::info!(%txid, %kind, "Published Bitcoin transaction"); @@ -179,9 +167,9 @@ impl Wallet { sub } - pub async fn wallet_export(&self, role: &str) -> Result { + pub async fn wallet_export(&self, role: &str) -> Result { let wallet = self.wallet.lock().await; - match bdk::wallet::export::WalletExport::export_wallet( + match bdk::wallet::export::FullyNodedExport::export_wallet( &wallet, &format!("{}-{}", role, self.network), true, @@ -269,7 +257,7 @@ impl Subscription { } } -impl Wallet +impl Wallet where C: EstimateFeeRate, D: BatchDatabase, @@ -293,6 +281,7 @@ where Ok(tx) } + /// Returns the total Bitcoin balance, which includes pending funds pub async fn balance(&self) -> Result { let balance = self .wallet @@ -301,7 +290,7 @@ where .get_balance() .context("Failed to calculate Bitcoin balance")?; - Ok(Amount::from_sat(balance)) + Ok(Amount::from_sat(balance.get_total())) } pub async fn new_address(&self) -> Result
{ @@ -362,11 +351,11 @@ where let (psbt, _details) = tx_builder.finish()?; let mut psbt: PartiallySignedTransaction = psbt; - match psbt.global.unsigned_tx.output.as_mut_slice() { + match psbt.unsigned_tx.output.as_mut_slice() { // our primary output is the 2nd one? reverse the vectors [_, second_txout] if second_txout.script_pubkey == script => { psbt.outputs.reverse(); - psbt.global.unsigned_tx.output.reverse(); + psbt.unsigned_tx.output.reverse(); } [first_txout, _] if first_txout.script_pubkey == script => { // no need to do anything @@ -378,7 +367,7 @@ where } if let ([_, change], [_, psbt_output], Some(change_override)) = ( - &mut psbt.global.unsigned_tx.output.as_mut_slice(), + &mut psbt.unsigned_tx.output.as_mut_slice(), &mut psbt.outputs.as_mut_slice(), change_override, ) { @@ -399,13 +388,13 @@ where pub async fn max_giveable(&self, locking_script_size: usize) -> Result { let wallet = self.wallet.lock().await; let balance = wallet.get_balance()?; - if balance < DUST_AMOUNT { + if balance.get_total() < DUST_AMOUNT { return Ok(Amount::ZERO); } let client = self.client.lock().await; let min_relay_fee = client.min_relay_fee()?.as_sat(); - if balance < min_relay_fee { + if balance.get_total() < min_relay_fee { return Ok(Amount::ZERO); } @@ -457,7 +446,7 @@ fn estimate_fee( if transfer_amount.as_sat() <= 546 { bail!("Amounts needs to be greater than Bitcoin dust amount.") } - let fee_rate_svb = fee_rate.as_sat_vb(); + let fee_rate_svb = fee_rate.as_sat_per_vb(); if fee_rate_svb <= 0.0 { bail!("Fee rate needs to be > 0") } @@ -518,29 +507,32 @@ fn estimate_fee( Ok(amount) } -impl Wallet +impl Wallet where - B: Blockchain, D: BatchDatabase, { pub async fn get_tx(&self, txid: Txid) -> Result> { - let tx = self.wallet.lock().await.client().get_tx(&txid)?; + let client = self.client.lock().await; + let tx = client.get_tx(&txid)?; Ok(tx) } pub async fn sync(&self) -> Result<()> { + let client = self.client.lock().await; + let blockchain = client.blockchain(); + let sync_opts = SyncOptions::default(); self.wallet .lock() .await - .sync(noop_progress(), None) + .sync(blockchain, sync_opts) .context("Failed to sync balance of Bitcoin wallet")?; Ok(()) } } -impl Wallet { +impl Wallet { // TODO: Get rid of this by changing bounds on bdk::Wallet pub fn get_network(&self) -> bitcoin::Network { self.network @@ -570,6 +562,7 @@ impl EstimateFeeRate for StaticFeeRate { } #[cfg(test)] +#[derive(Debug)] pub struct WalletBuilder { utxo_amount: u64, sats_per_vb: f32, @@ -621,9 +614,9 @@ impl WalletBuilder { } } - pub fn build(self) -> Wallet<(), bdk::database::MemoryDatabase, StaticFeeRate> { - use bdk::database::MemoryDatabase; - use bdk::testutils; + pub fn build(self) -> Wallet { + use bdk::database::{BatchOperations, MemoryDatabase, SyncTime}; + use bdk::{testutils, BlockTime}; let descriptors = testutils!(@descriptors (&format!("wpkh({}/*)", self.key))); @@ -638,9 +631,14 @@ impl WalletBuilder { Some(100) ); } + let block_time = bdk::BlockTime { + height: 100, + timestamp: 0, + }; + let sync_time = SyncTime { block_time }; + database.set_sync_time(sync_time).unwrap(); - let wallet = - bdk::Wallet::new_offline(&descriptors.0, None, Network::Regtest, database).unwrap(); + let wallet = bdk::Wallet::new(&descriptors.0, None, Network::Regtest, database).unwrap(); Wallet { client: Arc::new(Mutex::new(StaticFeeRate { @@ -678,6 +676,7 @@ impl Watchable for (Txid, Script) { pub struct Client { electrum: bdk::electrum_client::Client, + blockchain: ElectrumBlockchain, latest_block_height: BlockHeight, last_sync: Instant, sync_interval: Duration, @@ -686,15 +685,25 @@ pub struct Client { } impl Client { - fn new(electrum: bdk::electrum_client::Client, interval: Duration) -> Result { + fn new(electrum_rpc_url: Url, interval: Duration) -> Result { + let config = bdk::electrum_client::ConfigBuilder::default() + .retry(5) + .build(); + let electrum = bdk::electrum_client::Client::from_config(electrum_rpc_url.as_str(), config) + .context("Failed to initialize Electrum RPC client")?; // Initially fetch the latest block for storing the height. // We do not act on this subscription after this call. let latest_block = electrum .block_headers_subscribe() .context("Failed to subscribe to header notifications")?; + let client = bdk::electrum_client::Client::new(electrum_rpc_url.as_str()) + .context("Failed to initialize Electrum RPC client")?; + let blockchain = ElectrumBlockchain::from(client); + Ok(Self { electrum, + blockchain, latest_block_height: BlockHeight::try_from(latest_block)?, last_sync: Instant::now(), sync_interval: interval, @@ -703,6 +712,14 @@ impl Client { }) } + fn blockchain(&self) -> &ElectrumBlockchain { + &self.blockchain + } + + fn get_tx(&self, txid: &Txid) -> Result, bdk::Error> { + self.blockchain.get_tx(txid) + } + fn update_state(&mut self) -> Result<()> { let now = Instant::now(); if now < self.last_sync + self.sync_interval { diff --git a/swap/src/cli/event_loop.rs b/swap/src/cli/event_loop.rs index 2a9c16d3..1799d20b 100644 --- a/swap/src/cli/event_loop.rs +++ b/swap/src/cli/event_loop.rs @@ -248,9 +248,8 @@ impl EventLoopHandle { &mut self, tx_redeem_encsig: EncryptedSignature, ) -> Result<(), bmrng::error::RequestError> { - Ok(self - .encrypted_signature + self.encrypted_signature .send_receive(tx_redeem_encsig) - .await?) + .await } } diff --git a/swap/src/monero/wallet_rpc.rs b/swap/src/monero/wallet_rpc.rs index 8466a36b..e3fbb8f4 100644 --- a/swap/src/monero/wallet_rpc.rs +++ b/swap/src/monero/wallet_rpc.rs @@ -18,7 +18,7 @@ use tokio_util::io::StreamReader; compile_error!("unsupported operating system"); #[cfg(all(target_os = "macos", target_arch = "x86_64"))] -const DOWNLOAD_URL: &str = "http://downloads.getmonero.org/cli/monero-mac-x64-v0.18.0.0.tar.bz2"; +const DOWNLOAD_URL: &str = "https://downloads.getmonero.org/cli/monero-mac-x64-v0.18.0.0.tar.bz2"; #[cfg(all(target_os = "macos", target_arch = "arm"))] const DOWNLOAD_URL: &str = "https://downloads.getmonero.org/cli/monero-mac-armv8-v0.18.0.0.tar.bz2"; @@ -142,7 +142,7 @@ impl WalletRpc { tracing::debug!("{}%", percent); notified = percent; } - file.write(&bytes).await?; + file.write_all(&bytes).await?; } file.flush().await?; diff --git a/swap/src/proptest.rs b/swap/src/proptest.rs index 0a7ab460..1fa7e7e6 100644 --- a/swap/src/proptest.rs +++ b/swap/src/proptest.rs @@ -6,7 +6,8 @@ pub mod ecdsa_fun { use ::ecdsa_fun::fun::{Point, Scalar, G}; pub fn point() -> impl Strategy { - scalar().prop_map(|mut scalar| Point::from_scalar_mul(G, &mut scalar).mark::()) + scalar() + .prop_map(|mut scalar| Point::even_y_from_scalar_mul(G, &mut scalar).mark::()) } pub fn scalar() -> impl Strategy { diff --git a/swap/src/protocol/bob/state.rs b/swap/src/protocol/bob/state.rs index 90e5f9f8..13b7620f 100644 --- a/swap/src/protocol/bob/state.rs +++ b/swap/src/protocol/bob/state.rs @@ -149,9 +149,9 @@ impl State0 { } } - pub async fn receive( + pub async fn receive( self, - wallet: &bitcoin::Wallet, + wallet: &bitcoin::Wallet, msg: Message1, ) -> Result where diff --git a/swap/tests/harness/mod.rs b/swap/tests/harness/mod.rs index e7971e66..d17a580f 100644 --- a/swap/tests/harness/mod.rs +++ b/swap/tests/harness/mod.rs @@ -902,7 +902,7 @@ async fn mine(bitcoind_client: Client, reward_address: bitcoin::Address) -> Resu loop { tokio::time::sleep(Duration::from_secs(1)).await; bitcoind_client - .generatetoaddress(1, reward_address.clone(), None) + .generatetoaddress(1, reward_address.clone()) .await?; } } @@ -920,7 +920,7 @@ async fn init_bitcoind(node_url: Url, spendable_quantity: u32) -> Result .await?; bitcoind_client - .generatetoaddress(101 + spendable_quantity, reward_address.clone(), None) + .generatetoaddress(101 + spendable_quantity, reward_address.clone()) .await?; let _ = tokio::spawn(mine(bitcoind_client.clone(), reward_address)); Ok(bitcoind_client) @@ -940,9 +940,7 @@ pub async fn mint(node_url: Url, address: bitcoin::Address, amount: bitcoin::Amo .with_wallet(BITCOIN_TEST_WALLET_NAME)? .getnewaddress(None, None) .await?; - bitcoind_client - .generatetoaddress(1, reward_address, None) - .await?; + bitcoind_client.generatetoaddress(1, reward_address).await?; Ok(()) }