mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-01-11 07:29:39 -05:00
Alice to validate Bob's PSBT for correctness
In order for the re-construction of TxLock to be meaningful, we limit `Message2` to the PSBT instead of the full struct. This is a breaking change in the network layer. The PSBT is valid if: - It has at most two outputs (we allow a change output) - One of the outputs pays the agreed upon amount to a shared output script Resolves #260.
This commit is contained in:
parent
8576894c10
commit
52b9a78de2
@ -17,4 +17,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
failing on non-english language systems preventing users from starting the swap-cli
|
||||
and asb.
|
||||
|
||||
### Security
|
||||
|
||||
- Fixed an issue where Alice would not verify if Bob's Bitcoin lock transaction is semantically correct, i.e. pays the agreed upon amount to an output owned by both of them.
|
||||
Fixing this required a **breaking change** on the network layer and hence old versions are not compatible with this version.
|
||||
|
||||
[Unreleased]: https://github.com/comit-network/xmr-btc-swap/compare/v0.3...HEAD
|
||||
|
355
Cargo.lock
generated
355
Cargo.lock
generated
@ -221,6 +221,16 @@ dependencies = [
|
||||
"keccak-hash 0.1.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"safemem",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.10.1"
|
||||
@ -251,9 +261,9 @@ dependencies = [
|
||||
"async-trait",
|
||||
"bdk-macros",
|
||||
"bitcoin",
|
||||
"electrum-client",
|
||||
"electrum-client 0.7.0",
|
||||
"js-sys",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"miniscript",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
@ -273,6 +283,22 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bdk-testutils"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6d9382c8dfda457f2be9b700ffd580f12babec5d34ee39343768f65724ddd64"
|
||||
dependencies = [
|
||||
"bitcoin",
|
||||
"bitcoincore-rpc",
|
||||
"electrum-client 0.6.0",
|
||||
"log 0.4.14",
|
||||
"miniscript",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serial_test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bech32"
|
||||
version = "0.7.3"
|
||||
@ -326,7 +352,7 @@ dependencies = [
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"url",
|
||||
"url 2.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -338,6 +364,19 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitcoincore-rpc"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d708433972bf78bd5f909d1d288f9ac1cceeab1460edb954e962f83e1f440a3"
|
||||
dependencies = [
|
||||
"bitcoincore-rpc-json",
|
||||
"jsonrpc",
|
||||
"log 0.4.14",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitcoincore-rpc-json"
|
||||
version = "0.13.0"
|
||||
@ -886,6 +925,22 @@ version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "electrum-client"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21453800c95bb1aaa57490458c42d60c6277cb8a3e386030ec2381d5c2d4fa77"
|
||||
dependencies = [
|
||||
"bitcoin",
|
||||
"log 0.4.14",
|
||||
"rustls 0.16.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"socks",
|
||||
"webpki",
|
||||
"webpki-roots 0.19.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "electrum-client"
|
||||
version = "0.7.0"
|
||||
@ -893,7 +948,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cab4d90cc575a7daab4cfed9e315912a88071bc47462e6be57516a2f01ccc89"
|
||||
dependencies = [
|
||||
"bitcoin",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"rustls 0.16.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -1050,7 +1105,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
"percent-encoding 2.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1194,7 +1249,7 @@ checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"typenum",
|
||||
"version_check",
|
||||
"version_check 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1395,6 +1450,25 @@ version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.10.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273"
|
||||
dependencies = [
|
||||
"base64 0.9.3",
|
||||
"httparse",
|
||||
"language-tags",
|
||||
"log 0.3.9",
|
||||
"mime 0.2.6",
|
||||
"num_cpus",
|
||||
"time 0.1.43",
|
||||
"traitobject",
|
||||
"typeable",
|
||||
"unicase",
|
||||
"url 1.7.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.5"
|
||||
@ -1426,14 +1500,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"hyper",
|
||||
"log",
|
||||
"hyper 0.14.4",
|
||||
"log 0.4.14",
|
||||
"rustls 0.19.0",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.2"
|
||||
@ -1545,6 +1630,18 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpc"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "436f3455a8a4e9c7b14de9f1206198ee5d0bdc2db1b560339d2141093d7dd389"
|
||||
dependencies = [
|
||||
"hyper 0.10.16",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpc_client"
|
||||
version = "0.5.1"
|
||||
@ -1556,7 +1653,7 @@ dependencies = [
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"url",
|
||||
"url 2.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1589,6 +1686,12 @@ dependencies = [
|
||||
"tiny-keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "language-tags"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
@ -1634,7 +1737,7 @@ dependencies = [
|
||||
"libp2p-tcp",
|
||||
"libp2p-yamux",
|
||||
"parity-multiaddr",
|
||||
"parking_lot",
|
||||
"parking_lot 0.11.1",
|
||||
"pin-project 1.0.5",
|
||||
"smallvec",
|
||||
"wasm-timer",
|
||||
@ -1646,7 +1749,7 @@ version = "0.1.0"
|
||||
source = "git+https://github.com/comit-network/rust-libp2p-async-await#7a9006ceddd132ef5d40a597936cf15381a5cfe1"
|
||||
dependencies = [
|
||||
"libp2p",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1664,11 +1767,11 @@ dependencies = [
|
||||
"futures-timer",
|
||||
"lazy_static",
|
||||
"libsecp256k1",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"multihash",
|
||||
"multistream-select",
|
||||
"parity-multiaddr",
|
||||
"parking_lot",
|
||||
"parking_lot 0.11.1",
|
||||
"pin-project 1.0.5",
|
||||
"prost",
|
||||
"prost-build",
|
||||
@ -1691,7 +1794,7 @@ checksum = "9712eb3e9f7dcc77cc5ca7d943b6a85ce4b1faaf91a67e003442412a26d6d6f8"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"libp2p-core",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"smallvec",
|
||||
"trust-dns-resolver",
|
||||
]
|
||||
@ -1706,9 +1809,9 @@ dependencies = [
|
||||
"bytes",
|
||||
"futures",
|
||||
"libp2p-core",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"nohash-hasher",
|
||||
"parking_lot",
|
||||
"parking_lot 0.11.1",
|
||||
"rand 0.7.3",
|
||||
"smallvec",
|
||||
"unsigned-varint 0.7.0",
|
||||
@ -1725,7 +1828,7 @@ dependencies = [
|
||||
"futures",
|
||||
"lazy_static",
|
||||
"libp2p-core",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"prost",
|
||||
"prost-build",
|
||||
"rand 0.7.3",
|
||||
@ -1747,7 +1850,7 @@ dependencies = [
|
||||
"futures",
|
||||
"libp2p-core",
|
||||
"libp2p-swarm",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"lru",
|
||||
"minicbor",
|
||||
"rand 0.7.3",
|
||||
@ -1765,7 +1868,7 @@ dependencies = [
|
||||
"either",
|
||||
"futures",
|
||||
"libp2p-core",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"rand 0.7.3",
|
||||
"smallvec",
|
||||
"void",
|
||||
@ -1794,7 +1897,7 @@ dependencies = [
|
||||
"ipnet",
|
||||
"libc",
|
||||
"libp2p-core",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"socket2 0.4.0",
|
||||
"tokio",
|
||||
]
|
||||
@ -1807,7 +1910,7 @@ checksum = "96d6144cc94143fb0a8dd1e7c2fbcc32a2808168bcd1d69920635424d5993b7b"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"libp2p-core",
|
||||
"parking_lot",
|
||||
"parking_lot 0.11.1",
|
||||
"thiserror",
|
||||
"yamux",
|
||||
]
|
||||
@ -1834,6 +1937,15 @@ version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.2"
|
||||
@ -1843,6 +1955,15 @@ dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
||||
dependencies = [
|
||||
"log 0.4.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
@ -1906,6 +2027,15 @@ dependencies = [
|
||||
"autocfg 1.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0"
|
||||
dependencies = [
|
||||
"log 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.16"
|
||||
@ -1958,7 +2088,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2182a122f3b7f3f5329cb1972cee089ba2459a0a80a56935e6e674f096f8d839"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"miow",
|
||||
"ntapi",
|
||||
"winapi 0.3.9",
|
||||
@ -2059,7 +2189,7 @@ checksum = "7d91ec0a2440aaff5f78ec35631a7027d50386c6163aa975f7caa0d5da4b6ff8"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"pin-project 1.0.5",
|
||||
"smallvec",
|
||||
"unsigned-varint 0.7.0",
|
||||
@ -2079,7 +2209,7 @@ checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
|
||||
dependencies = [
|
||||
"lexical-core",
|
||||
"memchr",
|
||||
"version_check",
|
||||
"version_check 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2208,11 +2338,11 @@ dependencies = [
|
||||
"byteorder",
|
||||
"data-encoding",
|
||||
"multihash",
|
||||
"percent-encoding",
|
||||
"percent-encoding 2.1.0",
|
||||
"serde",
|
||||
"static_assertions 1.1.0",
|
||||
"unsigned-varint 0.7.0",
|
||||
"url",
|
||||
"url 2.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2227,6 +2357,16 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e"
|
||||
dependencies = [
|
||||
"lock_api 0.3.4",
|
||||
"parking_lot_core 0.7.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.1"
|
||||
@ -2234,8 +2374,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
|
||||
dependencies = [
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
"lock_api 0.4.2",
|
||||
"parking_lot_core 0.8.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"cloudabi",
|
||||
"libc",
|
||||
"redox_syscall 0.1.57",
|
||||
"smallvec",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2263,6 +2417,12 @@ dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
@ -2414,7 +2574,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
"version_check 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2425,7 +2585,7 @@ checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
"version_check 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2468,7 +2628,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"heck",
|
||||
"itertools",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"multimap",
|
||||
"petgraph",
|
||||
"prost",
|
||||
@ -2826,14 +2986,14 @@ dependencies = [
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"hyper 0.14.4",
|
||||
"hyper-rustls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
"log 0.4.14",
|
||||
"mime 0.3.16",
|
||||
"percent-encoding 2.1.0",
|
||||
"pin-project-lite",
|
||||
"rustls 0.19.0",
|
||||
"serde",
|
||||
@ -2841,7 +3001,7 @@ dependencies = [
|
||||
"serde_urlencoded",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"url",
|
||||
"url 2.2.1",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
@ -2925,7 +3085,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e"
|
||||
dependencies = [
|
||||
"base64 0.10.1",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"ring",
|
||||
"sct",
|
||||
"webpki",
|
||||
@ -2938,7 +3098,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "064fd21ff87c6e87ed4506e68beb42459caa4a0e2eb144932e6776768556980b"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"ring",
|
||||
"sct",
|
||||
"webpki",
|
||||
@ -2961,6 +3121,12 @@ version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "safemem"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
@ -3097,6 +3263,28 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serial_test"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fef5f7c7434b2f2c598adc6f9494648a1e41274a75c0ba4056f680ae0c117fd6"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"parking_lot 0.10.2",
|
||||
"serial_test_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serial_test_derive"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d08338d8024b227c62bd68a12c7c9883f5c66780abaef15c550dc56f46ee6515"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.9.4"
|
||||
@ -3196,8 +3384,8 @@ dependencies = [
|
||||
"fs2",
|
||||
"fxhash",
|
||||
"libc",
|
||||
"log",
|
||||
"parking_lot",
|
||||
"log 0.4.14",
|
||||
"parking_lot 0.11.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3278,7 +3466,7 @@ version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2beb4d1860a61f571530b3f855a1b538d0200f7871c63331ecd6f17b1f014f8"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
"version_check 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3426,6 +3614,7 @@ dependencies = [
|
||||
"backoff",
|
||||
"base64 0.13.0",
|
||||
"bdk",
|
||||
"bdk-testutils",
|
||||
"big-bytes",
|
||||
"bitcoin",
|
||||
"bitcoin-harness",
|
||||
@ -3437,7 +3626,7 @@ dependencies = [
|
||||
"ecdsa_fun",
|
||||
"futures",
|
||||
"get-port",
|
||||
"hyper",
|
||||
"hyper 0.14.4",
|
||||
"libp2p",
|
||||
"libp2p-async-await",
|
||||
"miniscript",
|
||||
@ -3472,7 +3661,7 @@ dependencies = [
|
||||
"tracing",
|
||||
"tracing-futures",
|
||||
"tracing-subscriber",
|
||||
"url",
|
||||
"url 2.2.1",
|
||||
"uuid",
|
||||
"void",
|
||||
"zip",
|
||||
@ -3545,7 +3734,7 @@ dependencies = [
|
||||
"derivative",
|
||||
"hex 0.4.3",
|
||||
"hmac 0.8.1",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -3560,7 +3749,7 @@ checksum = "d5e3ed6e3598dbf32cba8cb356b881c085e0adea57597f387723430dd94b4084"
|
||||
dependencies = [
|
||||
"hex 0.4.3",
|
||||
"hmac 0.10.1",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"rand 0.8.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -3626,7 +3815,7 @@ dependencies = [
|
||||
"standback",
|
||||
"stdweb",
|
||||
"time-macros",
|
||||
"version_check",
|
||||
"version_check 0.9.3",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
@ -3690,7 +3879,7 @@ dependencies = [
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"parking_lot 0.11.1",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"tokio-macros",
|
||||
@ -3751,7 +3940,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e96bb520beab540ab664bd5a9cfeaa1fcd846fa68c830b42e2c8963071251d2"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"pin-project 1.0.5",
|
||||
"rustls 0.19.0",
|
||||
"tokio",
|
||||
@ -3770,7 +3959,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
@ -3841,7 +4030,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
@ -3863,6 +4052,12 @@ dependencies = [
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "traitobject"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
|
||||
|
||||
[[package]]
|
||||
name = "trust-dns-proto"
|
||||
version = "0.20.1"
|
||||
@ -3876,16 +4071,16 @@ dependencies = [
|
||||
"futures-channel",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"idna",
|
||||
"idna 0.2.2",
|
||||
"ipnet",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"rand 0.8.3",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
"tinyvec",
|
||||
"tokio",
|
||||
"url",
|
||||
"url 2.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3898,9 +4093,9 @@ dependencies = [
|
||||
"futures-util",
|
||||
"ipconfig",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"lru-cache",
|
||||
"parking_lot",
|
||||
"parking_lot 0.11.1",
|
||||
"resolv-conf",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
@ -3926,17 +4121,23 @@ dependencies = [
|
||||
"http",
|
||||
"httparse",
|
||||
"input_buffer",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"rand 0.8.3",
|
||||
"rustls 0.19.0",
|
||||
"sha-1",
|
||||
"thiserror",
|
||||
"url",
|
||||
"url 2.2.1",
|
||||
"utf-8",
|
||||
"webpki",
|
||||
"webpki-roots 0.21.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typeable"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.13.0"
|
||||
@ -3967,6 +4168,15 @@ dependencies = [
|
||||
"static_assertions 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
|
||||
dependencies = [
|
||||
"version_check 0.1.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.4"
|
||||
@ -4037,6 +4247,17 @@ version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "1.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
|
||||
dependencies = [
|
||||
"idna 0.1.5",
|
||||
"matches",
|
||||
"percent-encoding 1.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.2.1"
|
||||
@ -4044,9 +4265,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"idna 0.2.2",
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
"percent-encoding 2.1.0",
|
||||
"serde",
|
||||
]
|
||||
|
||||
@ -4072,6 +4293,12 @@ version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.3"
|
||||
@ -4090,7 +4317,7 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
@ -4126,7 +4353,7 @@ checksum = "5b7d8b6942b8bb3a9b0e73fc79b98095a27de6fa247615e59d096754a3bc2aa8"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
@ -4182,7 +4409,7 @@ checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"js-sys",
|
||||
"parking_lot",
|
||||
"parking_lot 0.11.1",
|
||||
"pin-utils",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
@ -4332,9 +4559,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cc7bd8c983209ed5d527f44b01c41b7dc146fd960c61cf9e1d25399841dc271"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"log",
|
||||
"log 0.4.14",
|
||||
"nohash-hasher",
|
||||
"parking_lot",
|
||||
"parking_lot 0.11.1",
|
||||
"rand 0.7.3",
|
||||
"static_assertions 1.1.0",
|
||||
]
|
||||
|
@ -64,6 +64,7 @@ tokio-tar = { path = "../tokio-tar" }
|
||||
zip = "0.5"
|
||||
|
||||
[dev-dependencies]
|
||||
bdk-testutils = { version = "0.3" }
|
||||
bitcoin-harness = { git = "https://github.com/coblox/bitcoin-harness-rs" }
|
||||
get-port = "3"
|
||||
hyper = "0.14"
|
||||
|
@ -14,6 +14,7 @@ pub use crate::bitcoin::redeem::TxRedeem;
|
||||
pub use crate::bitcoin::refund::TxRefund;
|
||||
pub use crate::bitcoin::timelocks::{BlockHeight, ExpiredTimelocks};
|
||||
pub use ::bitcoin::util::amount::Amount;
|
||||
pub use ::bitcoin::util::psbt::PartiallySignedTransaction;
|
||||
pub use ::bitcoin::{Address, Network, Transaction, Txid};
|
||||
pub use ecdsa_fun::adaptor::EncryptedSignature;
|
||||
pub use ecdsa_fun::fun::Scalar;
|
||||
|
@ -4,7 +4,8 @@ use crate::bitcoin::{
|
||||
};
|
||||
use ::bitcoin::util::psbt::PartiallySignedTransaction;
|
||||
use ::bitcoin::{OutPoint, TxIn, TxOut, Txid};
|
||||
use anyhow::Result;
|
||||
use anyhow::{bail, Result};
|
||||
use bdk::database::BatchDatabase;
|
||||
use bitcoin::Script;
|
||||
use ecdsa_fun::fun::Point;
|
||||
use miniscript::{Descriptor, DescriptorTrait};
|
||||
@ -18,7 +19,15 @@ pub struct TxLock {
|
||||
}
|
||||
|
||||
impl TxLock {
|
||||
pub async fn new(wallet: &Wallet, amount: Amount, A: PublicKey, B: PublicKey) -> Result<Self> {
|
||||
pub async fn new<B, D, C>(
|
||||
wallet: &Wallet<B, D, C>,
|
||||
amount: Amount,
|
||||
A: PublicKey,
|
||||
B: PublicKey,
|
||||
) -> Result<Self>
|
||||
where
|
||||
D: BatchDatabase,
|
||||
{
|
||||
let lock_output_descriptor = build_shared_output_descriptor(A.0, B.0);
|
||||
let address = lock_output_descriptor
|
||||
.address(wallet.get_network())
|
||||
@ -32,6 +41,56 @@ impl TxLock {
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates an instance of `TxLock` from a PSBT, the public keys of the
|
||||
/// parties and the specified amount.
|
||||
///
|
||||
/// This function validates that the given PSBT does indeed pay that
|
||||
/// specified amount to a shared output.
|
||||
pub fn from_psbt(
|
||||
psbt: PartiallySignedTransaction,
|
||||
A: PublicKey,
|
||||
B: PublicKey,
|
||||
btc: Amount,
|
||||
) -> Result<Self> {
|
||||
let shared_output_candidate = match psbt.global.unsigned_tx.output.as_slice() {
|
||||
[shared_output_candidate, _] if shared_output_candidate.value == btc.as_sat() => {
|
||||
shared_output_candidate
|
||||
}
|
||||
[_, shared_output_candidate] if shared_output_candidate.value == btc.as_sat() => {
|
||||
shared_output_candidate
|
||||
}
|
||||
// A single output is possible if Bob funds without any change necessary
|
||||
[shared_output_candidate] if shared_output_candidate.value == btc.as_sat() => {
|
||||
shared_output_candidate
|
||||
}
|
||||
[_, _] => {
|
||||
bail!("Neither of the two provided outputs pays the right amount!");
|
||||
}
|
||||
[_] => {
|
||||
bail!("The provided output does not pay the right amount!");
|
||||
}
|
||||
other => {
|
||||
let num_outputs = other.len();
|
||||
bail!(
|
||||
"PSBT has {} outputs, expected one or two. Something is fishy!",
|
||||
num_outputs
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let descriptor = build_shared_output_descriptor(A.0, B.0);
|
||||
let legit_shared_output_script = descriptor.script_pubkey();
|
||||
|
||||
if shared_output_candidate.script_pubkey != legit_shared_output_script {
|
||||
bail!("Output script is not a shared output")
|
||||
}
|
||||
|
||||
Ok(TxLock {
|
||||
inner: psbt,
|
||||
output_descriptor: descriptor,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn lock_amount(&self) -> Amount {
|
||||
Amount::from_sat(self.inner.clone().extract_tx().output[self.lock_output_vout()].value)
|
||||
}
|
||||
@ -116,3 +175,84 @@ impl Watchable for TxLock {
|
||||
self.output_descriptor.script_pubkey()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn given_bob_sends_good_psbt_when_reconstructing_then_succeeeds() {
|
||||
let (A, B) = alice_and_bob();
|
||||
let wallet = Wallet::new_funded(50000);
|
||||
let agreed_amount = Amount::from_sat(10000);
|
||||
|
||||
let psbt = bob_make_psbt(A, B, &wallet, agreed_amount).await;
|
||||
let result = TxLock::from_psbt(psbt, A, B, agreed_amount);
|
||||
|
||||
result.expect("PSBT to be valid");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn bob_can_fund_without_a_change_output() {
|
||||
let (A, B) = alice_and_bob();
|
||||
let fees = 610;
|
||||
let agreed_amount = Amount::from_sat(10000);
|
||||
let wallet = Wallet::new_funded(agreed_amount.as_sat() + fees);
|
||||
|
||||
let psbt = bob_make_psbt(A, B, &wallet, agreed_amount).await;
|
||||
assert_eq!(
|
||||
psbt.global.unsigned_tx.output.len(),
|
||||
1,
|
||||
"psbt should only have a single output"
|
||||
);
|
||||
let result = TxLock::from_psbt(psbt, A, B, agreed_amount);
|
||||
|
||||
result.expect("PSBT to be valid");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn given_bob_is_sending_less_than_agreed_when_reconstructing_txlock_then_fails() {
|
||||
let (A, B) = alice_and_bob();
|
||||
let wallet = Wallet::new_funded(50000);
|
||||
let agreed_amount = Amount::from_sat(10000);
|
||||
|
||||
let bad_amount = Amount::from_sat(5000);
|
||||
let psbt = bob_make_psbt(A, B, &wallet, bad_amount).await;
|
||||
let result = TxLock::from_psbt(psbt, A, B, agreed_amount);
|
||||
|
||||
result.expect_err("PSBT to be invalid");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn given_bob_is_sending_to_a_bad_output_reconstructing_txlock_then_fails() {
|
||||
let (A, B) = alice_and_bob();
|
||||
let wallet = Wallet::new_funded(50000);
|
||||
let agreed_amount = Amount::from_sat(10000);
|
||||
|
||||
let E = eve();
|
||||
let psbt = bob_make_psbt(E, B, &wallet, agreed_amount).await;
|
||||
let result = TxLock::from_psbt(psbt, A, B, agreed_amount);
|
||||
|
||||
result.expect_err("PSBT to be invalid");
|
||||
}
|
||||
|
||||
/// Helper function that represents Bob's action of constructing the PSBT.
|
||||
///
|
||||
/// Extracting this allows us to keep the tests concise.
|
||||
async fn bob_make_psbt(
|
||||
A: PublicKey,
|
||||
B: PublicKey,
|
||||
wallet: &Wallet<(), bdk::database::MemoryDatabase, ()>,
|
||||
amount: Amount,
|
||||
) -> PartiallySignedTransaction {
|
||||
TxLock::new(&wallet, amount, A, B).await.unwrap().into()
|
||||
}
|
||||
|
||||
fn alice_and_bob() -> (PublicKey, PublicKey) {
|
||||
(PublicKey::random(), PublicKey::random())
|
||||
}
|
||||
|
||||
fn eve() -> PublicKey {
|
||||
PublicKey::random()
|
||||
}
|
||||
}
|
||||
|
@ -348,6 +348,39 @@ impl<B, D, C> Wallet<B, D, C> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl Wallet<(), bdk::database::MemoryDatabase, ()> {
|
||||
/// Creates a new, funded wallet to be used within tests.
|
||||
pub fn new_funded(amount: u64) -> Self {
|
||||
use bdk::database::MemoryDatabase;
|
||||
use bdk::{LocalUtxo, TransactionDetails};
|
||||
use bitcoin::OutPoint;
|
||||
use std::str::FromStr;
|
||||
use testutils::testutils;
|
||||
|
||||
let descriptors = testutils!(@descriptors ("wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)"));
|
||||
|
||||
let mut database = MemoryDatabase::new();
|
||||
bdk::populate_test_db!(
|
||||
&mut database,
|
||||
testutils! {
|
||||
@tx ( (@external descriptors, 0) => amount ) (@confirmations 1)
|
||||
},
|
||||
Some(100)
|
||||
);
|
||||
|
||||
let wallet =
|
||||
bdk::Wallet::new_offline(&descriptors.0, None, Network::Regtest, database).unwrap();
|
||||
|
||||
Self {
|
||||
client: Arc::new(Mutex::new(())),
|
||||
wallet: Arc::new(Mutex::new(wallet)),
|
||||
finality_confirmations: 1,
|
||||
network: Network::Regtest,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines a watchable transaction.
|
||||
///
|
||||
/// For a transaction to be watchable, we need to know two things: Its
|
||||
|
@ -47,7 +47,7 @@ pub struct Message1 {
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Message2 {
|
||||
tx_lock: bitcoin::TxLock,
|
||||
psbt: bitcoin::PartiallySignedTransaction,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
|
@ -57,7 +57,9 @@ impl Behaviour {
|
||||
let message2 =
|
||||
serde_cbor::from_slice::<Message2>(&substream.read_message(BUF_SIZE).await?)
|
||||
.context("Failed to deserialize message2")?;
|
||||
let state2 = state1.receive(message2);
|
||||
let state2 = state1
|
||||
.receive(message2)
|
||||
.context("Failed to receive Message2")?;
|
||||
|
||||
substream
|
||||
.write_message(
|
||||
|
@ -200,8 +200,11 @@ impl State1 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn receive(self, msg: Message2) -> State2 {
|
||||
State2 {
|
||||
pub fn receive(self, msg: Message2) -> Result<State2> {
|
||||
let tx_lock = bitcoin::TxLock::from_psbt(msg.psbt, self.a.public(), self.B, self.btc)
|
||||
.context("Failed to re-construct TxLock from received PSBT")?;
|
||||
|
||||
Ok(State2 {
|
||||
a: self.a,
|
||||
B: self.B,
|
||||
s_a: self.s_a,
|
||||
@ -215,8 +218,8 @@ impl State1 {
|
||||
refund_address: self.refund_address,
|
||||
redeem_address: self.redeem_address,
|
||||
punish_address: self.punish_address,
|
||||
tx_lock: msg.tx_lock,
|
||||
}
|
||||
tx_lock,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ pub struct State1 {
|
||||
impl State1 {
|
||||
pub fn next_message(&self) -> Message2 {
|
||||
Message2 {
|
||||
tx_lock: self.tx_lock.clone(),
|
||||
psbt: self.tx_lock.clone().into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user