diff --git a/Cargo.lock b/Cargo.lock index dafe08d5..116a079b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -241,13 +241,12 @@ checksum = "5f0dc55f2d8a1a85650ac47858bb001b4c0dd73d79e3c455a842925e68d29cd3" [[package]] name = "bitcoin" -version = "0.23.0" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a32c9d2fa897cfbb0db45d71e3d2838666194abc4828c0f994e4b5c3bf85ba4" +checksum = "aefc9be9f17185f4ebccae6575d342063f775924d57df0000edb1880c0fb7095" dependencies = [ "bech32", "bitcoin_hashes", - "hex 0.3.2", "secp256k1", "serde", ] @@ -255,27 +254,7 @@ dependencies = [ [[package]] name = "bitcoin-harness" version = "0.1.0" -source = "git+https://github.com/d4nte/bitcoin-harness-rs?rev=2869620689f7e54bdb8ab3d1838560cb9bc8fd60#2869620689f7e54bdb8ab3d1838560cb9bc8fd60" -dependencies = [ - "base64 0.12.3", - "bitcoin", - "bitcoincore-rpc-json", - "futures", - "hex 0.4.2", - "reqwest", - "serde", - "serde_json", - "testcontainers", - "thiserror", - "tokio", - "tracing", - "url", -] - -[[package]] -name = "bitcoin-harness" -version = "0.1.0" -source = "git+https://github.com/coblox/bitcoin-harness-rs?rev=3be644cd9512c157d3337a189298b8257ed54d04#3be644cd9512c157d3337a189298b8257ed54d04" +source = "git+https://github.com/d4nte/bitcoin-harness-rs?branch=rust-bitcoin-0.25#e773e37a070fb38f982c5b80919071420e4ead21" dependencies = [ "base64 0.12.3", "bitcoin", @@ -294,18 +273,18 @@ dependencies = [ [[package]] name = "bitcoin_hashes" -version = "0.7.6" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b375d62f341cef9cd9e77793ec8f1db3fc9ce2e4d57e982c8fe697a2c16af3b6" +checksum = "0aaf87b776808e26ae93289bc7d025092b6d909c193f0cdee0b3a86e7bd3c776" dependencies = [ "serde", ] [[package]] name = "bitcoincore-rpc-json" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6d55f23cd516d515ae10911164c603ea1040024670ec109715a20d7f6c9d0c" +checksum = "76d488ec31e9cb6726c361be5160f7d2aaace89a0681acf1f476b8fada770b6e" dependencies = [ "bitcoin", "hex 0.3.2", @@ -626,7 +605,7 @@ dependencies = [ [[package]] name = "cross-curve-dleq" version = "0.1.0" -source = "git+https://github.com/comit-network/cross-curve-dleq?rev=a19608734da1e8803cb4c806022483df4e7d5588#a19608734da1e8803cb4c806022483df4e7d5588" +source = "git+https://github.com/comit-network/cross-curve-dleq?rev=b43c73ac93a79fdce90cd11a458564c613048f0e#b43c73ac93a79fdce90cd11a458564c613048f0e" dependencies = [ "bit-vec", "curve25519-dalek 2.1.0", @@ -846,7 +825,7 @@ checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b" [[package]] name = "ecdsa_fun" version = "0.3.2-alpha.0" -source = "git+https://github.com/LLFourn/secp256kfun?rev=510d48ef6a2b19805f7f5c70c598e5b03f668e7a#510d48ef6a2b19805f7f5c70c598e5b03f668e7a" +source = "git+https://github.com/LLFourn/secp256kfun?rev=cdfbc766045ea678a41780919d6228dd5acee3be#cdfbc766045ea678a41780919d6228dd5acee3be" dependencies = [ "secp256kfun", "serde", @@ -1960,9 +1939,9 @@ dependencies = [ [[package]] name = "miniscript" -version = "1.0.0" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f196216a07ade53d91a263b3721057f1f0cfd6f95f3d324626f3f9cf7cdfce" +checksum = "cc7da049151be4bc7f8da628f5e862e6fae3fe5d7c8201a746cb8373735e789b" dependencies = [ "bitcoin", "serde", @@ -2947,9 +2926,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "secp256k1" -version = "0.17.2" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2932dc07acd2066ff2e3921a4419606b220ba6cd03a9935123856cc534877056" +checksum = "c6179428c22c73ac0fbb7b5579a56353ce78ba29759b3b8575183336ea74cdfb" dependencies = [ "rand 0.6.5", "secp256k1-sys", @@ -2958,9 +2937,9 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.1.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab2c26f0d3552a0f12e639ae8a64afc2e3db9c52fe32f5fc6c289d38519f220" +checksum = "11553d210db090930f4432bea123b31f70bbf693ace14504ea2a35e796c28dd2" dependencies = [ "cc", ] @@ -2968,7 +2947,7 @@ dependencies = [ [[package]] name = "secp256kfun" version = "0.3.2-alpha.0" -source = "git+https://github.com/LLFourn/secp256kfun?rev=510d48ef6a2b19805f7f5c70c598e5b03f668e7a#510d48ef6a2b19805f7f5c70c598e5b03f668e7a" +source = "git+https://github.com/LLFourn/secp256kfun?rev=cdfbc766045ea678a41780919d6228dd5acee3be#cdfbc766045ea678a41780919d6228dd5acee3be" dependencies = [ "digest 0.9.0", "rand_core 0.5.1", @@ -2980,9 +2959,8 @@ dependencies = [ [[package]] name = "secp256kfun_parity_backend" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "959911ff66eae1b170a4eec00aa9b987647ad604dc57982014d85e635b7b4f99" +version = "0.1.3-alpha.0" +source = "git+https://github.com/LLFourn/secp256kfun?rev=cdfbc766045ea678a41780919d6228dd5acee3be#cdfbc766045ea678a41780919d6228dd5acee3be" dependencies = [ "crunchy 0.2.2", "subtle 2.3.0", @@ -3389,7 +3367,7 @@ dependencies = [ "backoff", "base64 0.12.3", "bitcoin", - "bitcoin-harness 0.1.0 (git+https://github.com/d4nte/bitcoin-harness-rs?rev=2869620689f7e54bdb8ab3d1838560cb9bc8fd60)", + "bitcoin-harness", "conquer-once", "derivative", "ecdsa_fun", @@ -4167,7 +4145,7 @@ dependencies = [ "backoff", "base64 0.12.3", "bitcoin", - "bitcoin-harness 0.1.0 (git+https://github.com/coblox/bitcoin-harness-rs?rev=3be644cd9512c157d3337a189298b8257ed54d04)", + "bitcoin-harness", "conquer-once", "cross-curve-dleq", "curve25519-dalek 2.1.0", diff --git a/swap/Cargo.toml b/swap/Cargo.toml index 686dec6c..0b21b322 100644 --- a/swap/Cargo.toml +++ b/swap/Cargo.toml @@ -12,11 +12,11 @@ async-trait = "0.1" atty = "0.2" backoff = { version = "0.2", features = ["tokio"] } base64 = "0.12" -bitcoin = { version = "0.23", features = ["rand", "use-serde"] } # TODO: Upgrade other crates in this repo to use this version. -bitcoin-harness = { git = "https://github.com/d4nte/bitcoin-harness-rs", rev = "2869620689f7e54bdb8ab3d1838560cb9bc8fd60" } +bitcoin = { version = "0.25", features = ["rand", "use-serde"] } +bitcoin-harness = { git = "https://github.com/d4nte/bitcoin-harness-rs", branch = "rust-bitcoin-0.25" } conquer-once = "0.3" derivative = "2" -ecdsa_fun = { git = "https://github.com/LLFourn/secp256kfun", rev = "510d48ef6a2b19805f7f5c70c598e5b03f668e7a", features = ["libsecp_compat", "serde", "serialization"] } +ecdsa_fun = { git = "https://github.com/LLFourn/secp256kfun", rev = "cdfbc766045ea678a41780919d6228dd5acee3be", features = ["libsecp_compat", "serde"] } futures = { version = "0.3", default-features = false } genawaiter = "0.99.1" libp2p = { version = "0.29", default-features = false, features = ["tcp-tokio", "yamux", "mplex", "dns", "noise", "request-response"] } diff --git a/swap/src/alice/execution.rs b/swap/src/alice/execution.rs index cd7115f2..89ffa8fa 100644 --- a/swap/src/alice/execution.rs +++ b/swap/src/alice/execution.rs @@ -207,7 +207,7 @@ pub fn build_bitcoin_redeem_transaction( let tx_redeem = bitcoin::TxRedeem::new(tx_lock, redeem_address); bitcoin::verify_encsig( - B.clone(), + B, s_a.into_secp256k1().into(), &tx_redeem.digest(), &encrypted_signature, @@ -258,7 +258,7 @@ where .await; poll_until_block_height_is_gte(bitcoin_wallet.as_ref(), tx_lock_height + refund_timelock).await; - let tx_cancel = bitcoin::TxCancel::new(&tx_lock, refund_timelock, a.public(), B.clone()); + let tx_cancel = bitcoin::TxCancel::new(&tx_lock, refund_timelock, a.public(), B); // If Bob hasn't yet broadcasted the tx cancel, we do it if bitcoin_wallet @@ -274,7 +274,7 @@ where let tx_cancel = tx_cancel .clone() - .add_signatures(&tx_lock, (a.public(), sig_a), (B.clone(), sig_b)) + .add_signatures(&tx_lock, (a.public(), sig_a), (B, sig_b)) .expect("sig_{a,b} to be valid signatures for tx_cancel"); // TODO(Franck): Error handling is delicate, why can't we broadcast? @@ -331,7 +331,7 @@ pub fn extract_monero_private_key( let tx_refund_sig = tx_refund .extract_signature_by_key(published_refund_tx, a.public()) .context("Failed to extract signature from Bitcoin refund tx")?; - let tx_refund_encsig = a.encsign(S_b_bitcoin.clone(), tx_refund.digest()); + let tx_refund_encsig = a.encsign(S_b_bitcoin, tx_refund.digest()); let s_b = bitcoin::recover(S_b_bitcoin, tx_refund_sig, tx_refund_encsig) .context("Failed to recover Monero secret key from Bitcoin signature")?; @@ -351,7 +351,7 @@ pub fn build_bitcoin_punish_transaction( a: bitcoin::SecretKey, B: bitcoin::PublicKey, ) -> Result { - let tx_cancel = bitcoin::TxCancel::new(&tx_lock, refund_timelock, a.public(), B.clone()); + let tx_cancel = bitcoin::TxCancel::new(&tx_lock, refund_timelock, a.public(), B); let tx_punish = bitcoin::TxPunish::new(&tx_cancel, &punish_address, punish_timelock); let sig_a = a.sign(tx_punish.digest()); diff --git a/swap/src/alice/swap.rs b/swap/src/alice/swap.rs index 3bcb255f..2864eba8 100644 --- a/swap/src/alice/swap.rs +++ b/swap/src/alice/swap.rs @@ -208,7 +208,7 @@ pub async fn swap( &state3.tx_lock, state3.a.clone(), state3.s_a, - state3.B.clone(), + state3.B, &state3.redeem_address, ) { Ok(tx) => tx, @@ -243,7 +243,7 @@ pub async fn swap( let tx_cancel = publish_cancel_transaction( state3.tx_lock.clone(), state3.a.clone(), - state3.B.clone(), + state3.B, state3.refund_timelock, state3.tx_cancel_sig_bob.clone(), bitcoin_wallet.clone(), @@ -329,7 +329,7 @@ pub async fn swap( state3.punish_timelock, state3.tx_punish_sig_bob.clone(), state3.a.clone(), - state3.B.clone(), + state3.B, )?; let punish_tx_finalised = publish_bitcoin_punish_transaction( diff --git a/swap/src/recover.rs b/swap/src/recover.rs index 5f41112f..aa5c2f51 100644 --- a/swap/src/recover.rs +++ b/swap/src/recover.rs @@ -55,7 +55,7 @@ pub async fn alice_recover( &state.tx_lock, state.refund_timelock, state.a.public(), - state.B.clone(), + state.B, ); info!("Checking if the Bitcoin cancel transaction has been published"); @@ -81,11 +81,7 @@ pub async fn alice_recover( let tx_cancel = tx_cancel .clone() - .add_signatures( - &state.tx_lock, - (state.a.public(), sig_a), - (state.B.clone(), sig_b), - ) + .add_signatures(&state.tx_lock, (state.a.public(), sig_a), (state.B, sig_b)) .expect("sig_{a,b} to be valid signatures for tx_cancel"); // TODO: We should not fail if the transaction is already on the blockchain @@ -123,9 +119,7 @@ pub async fn alice_recover( let tx_refund_sig = tx_refund .extract_signature_by_key(tx_refund_published, state.a.public())?; - let tx_refund_encsig = state - .a - .encsign(state.S_b_bitcoin.clone(), tx_refund.digest()); + let tx_refund_encsig = state.a.encsign(state.S_b_bitcoin, tx_refund.digest()); let s_b = bitcoin::recover(state.S_b_bitcoin, tx_refund_sig, tx_refund_encsig)?; let s_b = monero::PrivateKey::from_scalar( @@ -152,7 +146,7 @@ pub async fn alice_recover( let sig_tx_punish = tx_punish.add_signatures( &tx_cancel, (state.a.public(), sig_a), - (state.B.clone(), sig_b), + (state.B, sig_b), )?; bitcoin_wallet @@ -187,7 +181,7 @@ pub async fn alice_recover( &state.tx_lock, state.refund_timelock, state.a.public(), - state.B.clone(), + state.B, ); info!("Checking if the Bitcoin cancel transaction has been published"); @@ -202,11 +196,7 @@ pub async fn alice_recover( let tx_cancel = tx_cancel .clone() - .add_signatures( - &state.tx_lock, - (state.a.public(), sig_a), - (state.B.clone(), sig_b), - ) + .add_signatures(&state.tx_lock, (state.a.public(), sig_a), (state.B, sig_b)) .expect("sig_{a,b} to be valid signatures for tx_cancel"); // TODO: We should not fail if the transaction is already on the blockchain @@ -244,9 +234,8 @@ pub async fn alice_recover( let tx_refund_sig = tx_refund .extract_signature_by_key(tx_refund_published, state.a.public())?; - let tx_refund_encsig = state - .a - .encsign(state.S_b_bitcoin.clone(), tx_refund.digest()); + let tx_refund_encsig = + state.a.encsign(state.S_b_bitcoin, tx_refund.digest()); let s_b = bitcoin::recover(state.S_b_bitcoin, tx_refund_sig, tx_refund_encsig)?; @@ -274,7 +263,7 @@ pub async fn alice_recover( let sig_tx_punish = tx_punish.add_signatures( &tx_cancel, (state.a.public(), sig_a), - (state.B.clone(), sig_b), + (state.B, sig_b), )?; bitcoin_wallet @@ -292,7 +281,7 @@ pub async fn alice_recover( &state.tx_lock, state.refund_timelock, state.a.public(), - state.B.clone(), + state.B, ); let tx_refund = bitcoin::TxRefund::new(&tx_cancel, &state.refund_address); @@ -310,9 +299,7 @@ pub async fn alice_recover( let tx_refund_sig = tx_refund .extract_signature_by_key(tx_refund_published, state.a.public())?; - let tx_refund_encsig = state - .a - .encsign(state.S_b_bitcoin.clone(), tx_refund.digest()); + let tx_refund_encsig = state.a.encsign(state.S_b_bitcoin, tx_refund.digest()); let s_b = bitcoin::recover(state.S_b_bitcoin, tx_refund_sig, tx_refund_encsig)?; let s_b = monero::PrivateKey::from_scalar( @@ -339,7 +326,7 @@ pub async fn alice_recover( let sig_tx_punish = tx_punish.add_signatures( &tx_cancel, (state.a.public(), sig_a), - (state.B.clone(), sig_b), + (state.B, sig_b), )?; bitcoin_wallet @@ -381,7 +368,7 @@ pub async fn bob_recover( let tx_cancel = bitcoin::TxCancel::new( &state.tx_lock, state.refund_timelock, - state.A.clone(), + state.A, state.b.public(), ); @@ -408,11 +395,7 @@ pub async fn bob_recover( let tx_cancel = tx_cancel .clone() - .add_signatures( - &state.tx_lock, - (state.A.clone(), sig_a), - (state.b.public(), sig_b), - ) + .add_signatures(&state.tx_lock, (state.A, sig_a), (state.b.public(), sig_b)) .expect("sig_{a,b} to be valid signatures for tx_cancel"); // TODO: We should not fail if the transaction is already on the blockchain @@ -431,11 +414,7 @@ pub async fn bob_recover( let sig_b = state.b.sign(tx_refund.digest()); tx_refund - .add_signatures( - &tx_cancel, - (state.A.clone(), sig_a), - (state.b.public(), sig_b), - ) + .add_signatures(&tx_cancel, (state.A, sig_a), (state.b.public(), sig_b)) .expect("sig_{a,b} to be valid signatures for tx_refund") }; @@ -455,9 +434,7 @@ pub async fn bob_recover( .get_raw_transaction(tx_redeem.txid()) .await?; - let tx_redeem_encsig = state - .b - .encsign(state.S_a_bitcoin.clone(), tx_redeem.digest()); + let tx_redeem_encsig = state.b.encsign(state.S_a_bitcoin, tx_redeem.digest()); let tx_redeem_sig = tx_redeem.extract_signature_by_key(tx_redeem_published, state.b.public())?; diff --git a/xmr-btc/Cargo.toml b/xmr-btc/Cargo.toml index 66430caa..4a8ba4f8 100644 --- a/xmr-btc/Cargo.toml +++ b/xmr-btc/Cargo.toml @@ -9,15 +9,15 @@ edition = "2018" [dependencies] anyhow = "1" async-trait = "0.1" -bitcoin = { version = "0.23", features = ["rand", "serde"] } +bitcoin = { version = "0.25", features = ["rand", "serde"] } conquer-once = "0.3" -cross-curve-dleq = { git = "https://github.com/comit-network/cross-curve-dleq", rev = "a19608734da1e8803cb4c806022483df4e7d5588", features = ["serde"] } +cross-curve-dleq = { git = "https://github.com/comit-network/cross-curve-dleq", rev = "b43c73ac93a79fdce90cd11a458564c613048f0e", features = ["serde"] } curve25519-dalek = "2" -ecdsa_fun = { git = "https://github.com/LLFourn/secp256kfun", rev = "510d48ef6a2b19805f7f5c70c598e5b03f668e7a", features = ["libsecp_compat", "serde", "serialization"] } +ecdsa_fun = { git = "https://github.com/LLFourn/secp256kfun", rev = "cdfbc766045ea678a41780919d6228dd5acee3be", features = ["libsecp_compat", "serde"] } ed25519-dalek = { version = "1.0.0-pre.4", features = ["serde"] }# Cannot be 1 because they depend on curve25519-dalek version 3 futures = "0.3" genawaiter = "0.99.1" -miniscript = { version = "1", features = ["serde"] } +miniscript = { version = "4", features = ["serde"] } monero = { version = "0.9", features = ["serde_support"] } rand = "0.7" serde = { version = "1", features = ["derive"] } @@ -29,7 +29,7 @@ tracing = "0.1" [dev-dependencies] backoff = { version = "0.2", features = ["tokio"] } base64 = "0.12" -bitcoin-harness = { git = "https://github.com/coblox/bitcoin-harness-rs", rev = "3be644cd9512c157d3337a189298b8257ed54d04" } +bitcoin-harness = { git = "https://github.com/d4nte/bitcoin-harness-rs", branch = "rust-bitcoin-0.25" } futures = "0.3" monero-harness = { path = "../monero-harness" } reqwest = { version = "0.10", default-features = false } diff --git a/xmr-btc/src/alice.rs b/xmr-btc/src/alice.rs index 477df236..9a1ea914 100644 --- a/xmr-btc/src/alice.rs +++ b/xmr-btc/src/alice.rs @@ -179,7 +179,7 @@ where let tx_redeem = bitcoin::TxRedeem::new(&tx_lock, &redeem_address); bitcoin::verify_encsig( - B.clone(), + B, s_a.into_secp256k1().into(), &tx_redeem.digest(), &tx_redeem_encsig, @@ -191,7 +191,7 @@ where adaptor.decrypt_signature(&s_a.into_secp256k1(), tx_redeem_encsig.clone()); let tx = tx_redeem - .add_signatures(&tx_lock, (a.public(), sig_a), (B.clone(), sig_b)) + .add_signatures(&tx_lock, (a.public(), sig_a), (B, sig_b)) .expect("sig_{a,b} to be valid signatures for tx_redeem"); let txid = tx.txid(); @@ -220,15 +220,14 @@ where if let Err(SwapFailed::AfterXmrLock(Reason::BtcExpired)) = swap_result { let refund_result: Result<(), RefundFailed> = async { - let tx_cancel = - bitcoin::TxCancel::new(&tx_lock, refund_timelock, a.public(), B.clone()); + let tx_cancel = bitcoin::TxCancel::new(&tx_lock, refund_timelock, a.public(), B); let signed_tx_cancel = { let sig_a = a.sign(tx_cancel.digest()); let sig_b = tx_cancel_sig_bob.clone(); tx_cancel .clone() - .add_signatures(&tx_lock, (a.public(), sig_a), (B.clone(), sig_b)) + .add_signatures(&tx_lock, (a.public(), sig_a), (B, sig_b)) .expect("sig_{a,b} to be valid signatures for tx_cancel") }; @@ -266,7 +265,7 @@ where let tx_refund_sig = tx_refund .extract_signature_by_key(tx_refund_published, a.public()) .map_err(|_| RefundFailed::BtcRefundSignature)?; - let tx_refund_encsig = a.encsign(S_b_bitcoin.clone(), tx_refund.digest()); + let tx_refund_encsig = a.encsign(S_b_bitcoin, tx_refund.digest()); let s_b = bitcoin::recover(S_b_bitcoin, tx_refund_sig, tx_refund_encsig) .map_err(|_| RefundFailed::SecretRecovery)?; @@ -292,8 +291,7 @@ where // with the refund on Monero. Doing so may be too verbose with the current, // linear approach. A different design may be required if let Err(RefundFailed::BtcPunishable) = refund_result { - let tx_cancel = - bitcoin::TxCancel::new(&tx_lock, refund_timelock, a.public(), B.clone()); + let tx_cancel = bitcoin::TxCancel::new(&tx_lock, refund_timelock, a.public(), B); let tx_punish = bitcoin::TxPunish::new(&tx_cancel, &punish_address, punish_timelock); let tx_punish_txid = tx_punish.txid(); @@ -580,12 +578,8 @@ pub struct State2 { impl State2 { pub fn next_message(&self) -> Message1 { - let tx_cancel = bitcoin::TxCancel::new( - &self.tx_lock, - self.refund_timelock, - self.a.public(), - self.B.clone(), - ); + let tx_cancel = + bitcoin::TxCancel::new(&self.tx_lock, self.refund_timelock, self.a.public(), self.B); let tx_refund = bitcoin::TxRefund::new(&tx_cancel, &self.refund_address); // Alice encsigns the refund transaction(bitcoin) digest with Bob's monero @@ -593,7 +587,7 @@ impl State2 { // tx_lock_bitcoin to Bob's refund address. // recover(encsign(a, S_b, d), sign(a, d), S_b) = s_b where d is a digest, (a, // A) is alice's keypair and (s_b, S_b) is bob's keypair. - let tx_refund_encsig = self.a.encsign(self.S_b_bitcoin.clone(), tx_refund.digest()); + let tx_refund_encsig = self.a.encsign(self.S_b_bitcoin, tx_refund.digest()); let tx_cancel_sig = self.a.sign(tx_cancel.digest()); Message1 { @@ -603,12 +597,8 @@ impl State2 { } pub fn receive(self, msg: bob::Message2) -> Result { - let tx_cancel = bitcoin::TxCancel::new( - &self.tx_lock, - self.refund_timelock, - self.a.public(), - self.B.clone(), - ); + let tx_cancel = + bitcoin::TxCancel::new(&self.tx_lock, self.refund_timelock, self.a.public(), self.B); bitcoin::verify_sig(&self.B, &tx_cancel.digest(), &msg.tx_cancel_sig)?; let tx_punish = bitcoin::TxPunish::new(&tx_cancel, &self.punish_address, self.punish_timelock); @@ -751,12 +741,8 @@ impl State4 { &self, bitcoin_wallet: &W, ) -> Result<()> { - let tx_cancel = bitcoin::TxCancel::new( - &self.tx_lock, - self.refund_timelock, - self.a.public(), - self.B.clone(), - ); + let tx_cancel = + bitcoin::TxCancel::new(&self.tx_lock, self.refund_timelock, self.a.public(), self.B); let tx_punish = bitcoin::TxPunish::new(&tx_cancel, &self.punish_address, self.punish_timelock); @@ -767,7 +753,7 @@ impl State4 { let signed_tx_cancel = tx_cancel.clone().add_signatures( &self.tx_lock, (self.a.public(), sig_a), - (self.B.clone(), sig_b), + (self.B, sig_b), )?; let _ = bitcoin_wallet @@ -779,11 +765,8 @@ impl State4 { let sig_a = self.a.sign(tx_punish.digest()); let sig_b = self.tx_punish_sig_bob.clone(); - let signed_tx_punish = tx_punish.add_signatures( - &tx_cancel, - (self.a.public(), sig_a), - (self.B.clone(), sig_b), - )?; + let signed_tx_punish = + tx_punish.add_signatures(&tx_cancel, (self.a.public(), sig_a), (self.B, sig_b))?; let _ = bitcoin_wallet .broadcast_signed_transaction(signed_tx_punish) @@ -854,16 +837,12 @@ impl State5 { B: WatchForRawTransaction, M: CreateWalletForOutput, { - let tx_cancel = bitcoin::TxCancel::new( - &self.tx_lock, - self.refund_timelock, - self.a.public(), - self.B.clone(), - ); + let tx_cancel = + bitcoin::TxCancel::new(&self.tx_lock, self.refund_timelock, self.a.public(), self.B); let tx_refund = bitcoin::TxRefund::new(&tx_cancel, &self.refund_address); - let tx_refund_encsig = self.a.encsign(self.S_b_bitcoin.clone(), tx_refund.digest()); + let tx_refund_encsig = self.a.encsign(self.S_b_bitcoin, tx_refund.digest()); let tx_refund_candidate = bitcoin_wallet .watch_for_raw_transaction(tx_refund.txid()) @@ -923,11 +902,8 @@ impl State6 { let sig_b = adaptor.decrypt_signature(&self.s_a.into_secp256k1(), self.tx_redeem_encsig.clone()); - let sig_tx_redeem = tx_redeem.add_signatures( - &self.tx_lock, - (self.a.public(), sig_a), - (self.B.clone(), sig_b), - )?; + let sig_tx_redeem = + tx_redeem.add_signatures(&self.tx_lock, (self.a.public(), sig_a), (self.B, sig_b))?; bitcoin_wallet .broadcast_signed_transaction(sig_tx_redeem) .await?; diff --git a/xmr-btc/src/bitcoin.rs b/xmr-btc/src/bitcoin.rs index 531420dc..d0dab9ea 100644 --- a/xmr-btc/src/bitcoin.rs +++ b/xmr-btc/src/bitcoin.rs @@ -37,7 +37,7 @@ impl SecretKey { } pub fn public(&self) -> PublicKey { - PublicKey(self.public.clone()) + PublicKey(self.public) } pub fn to_bytes(&self) -> [u8; 32] { @@ -72,7 +72,7 @@ impl SecretKey { } } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)] pub struct PublicKey(Point); impl From for Point { diff --git a/xmr-btc/src/bitcoin/transactions.rs b/xmr-btc/src/bitcoin/transactions.rs index 3242f471..aec6bb86 100644 --- a/xmr-btc/src/bitcoin/transactions.rs +++ b/xmr-btc/src/bitcoin/transactions.rs @@ -3,11 +3,11 @@ use crate::bitcoin::{ }; use anyhow::{bail, Context, Result}; use bitcoin::{ - util::{bip143::SighashComponents, psbt::PartiallySignedTransaction}, - Address, Amount, Network, SigHash, Transaction, TxIn, TxOut, + util::{bip143::SigHashCache, psbt::PartiallySignedTransaction}, + Address, Amount, Network, SigHash, SigHashType, Transaction, TxIn, TxOut, }; use ecdsa_fun::Signature; -use miniscript::Descriptor; +use miniscript::{Descriptor, NullCtx}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -24,7 +24,7 @@ impl TxLock { { let lock_output_descriptor = build_shared_output_descriptor(A.0, B.0); let address = lock_output_descriptor - .address(Network::Regtest) + .address(Network::Regtest, NullCtx) .expect("can derive address from descriptor"); // We construct a psbt for convenience @@ -59,7 +59,9 @@ impl TxLock { self.inner .output .iter() - .position(|output| output.script_pubkey == self.output_descriptor.script_pubkey()) + .position(|output| { + output.script_pubkey == self.output_descriptor.script_pubkey(NullCtx) + }) .expect("transaction contains lock output") } @@ -67,7 +69,7 @@ impl TxLock { &self, spend_address: &Address, sequence: Option, - ) -> (Transaction, TxIn) { + ) -> Transaction { let previous_output = self.as_outpoint(); let tx_in = TxIn { @@ -82,14 +84,12 @@ impl TxLock { script_pubkey: spend_address.script_pubkey(), }; - let transaction = Transaction { + Transaction { version: 2, lock_time: 0, - input: vec![tx_in.clone()], + input: vec![tx_in], output: vec![tx_out], - }; - - (transaction, tx_in) + } } } @@ -109,12 +109,13 @@ impl TxRedeem { pub fn new(tx_lock: &TxLock, redeem_address: &Address) -> Self { // lock_input is the shared output that is now being used as an input for the // redeem transaction - let (tx_redeem, lock_input) = tx_lock.build_spend_transaction(redeem_address, None); + let tx_redeem = tx_lock.build_spend_transaction(redeem_address, None); - let digest = SighashComponents::new(&tx_redeem).sighash_all( - &lock_input, - &tx_lock.output_descriptor.witness_script(), + let digest = SigHashCache::new(&tx_redeem).signature_hash( + 0, // Only one input: lock_input (lock transaction) + &tx_lock.output_descriptor.witness_script(NullCtx), tx_lock.lock_amount().as_sat(), + SigHashType::All, ); Self { @@ -159,7 +160,7 @@ impl TxRedeem { let mut tx_redeem = self.inner; tx_lock .output_descriptor - .satisfy(&mut tx_redeem.input[0], satisfier)?; + .satisfy(&mut tx_redeem.input[0], satisfier, NullCtx)?; Ok(tx_redeem) } @@ -238,20 +239,21 @@ impl TxCancel { let tx_out = TxOut { value: tx_lock.lock_amount().as_sat() - TX_FEE, - script_pubkey: cancel_output_descriptor.script_pubkey(), + script_pubkey: cancel_output_descriptor.script_pubkey(NullCtx), }; let transaction = Transaction { version: 2, lock_time: 0, - input: vec![tx_in.clone()], + input: vec![tx_in], output: vec![tx_out], }; - let digest = SighashComponents::new(&transaction).sighash_all( - &tx_in, - &tx_lock.output_descriptor.witness_script(), + let digest = SigHashCache::new(&transaction).signature_hash( + 0, // Only one input: lock_input (lock transaction) + &tx_lock.output_descriptor.witness_script(NullCtx), tx_lock.lock_amount().as_sat(), + SigHashType::All, ); Self { @@ -305,7 +307,7 @@ impl TxCancel { let mut tx_cancel = self.inner; tx_lock .output_descriptor - .satisfy(&mut tx_cancel.input[0], satisfier)?; + .satisfy(&mut tx_cancel.input[0], satisfier, NullCtx)?; Ok(tx_cancel) } @@ -314,7 +316,7 @@ impl TxCancel { &self, spend_address: &Address, sequence: Option, - ) -> (Transaction, TxIn) { + ) -> Transaction { let previous_output = self.as_outpoint(); let tx_in = TxIn { @@ -329,14 +331,12 @@ impl TxCancel { script_pubkey: spend_address.script_pubkey(), }; - let transaction = Transaction { + Transaction { version: 2, lock_time: 0, - input: vec![tx_in.clone()], + input: vec![tx_in], output: vec![tx_out], - }; - - (transaction, tx_in) + } } } @@ -348,12 +348,13 @@ pub struct TxRefund { impl TxRefund { pub fn new(tx_cancel: &TxCancel, refund_address: &Address) -> Self { - let (tx_punish, cancel_input) = tx_cancel.build_spend_transaction(refund_address, None); + let tx_punish = tx_cancel.build_spend_transaction(refund_address, None); - let digest = SighashComponents::new(&tx_punish).sighash_all( - &cancel_input, - &tx_cancel.output_descriptor.witness_script(), + let digest = SigHashCache::new(&tx_punish).signature_hash( + 0, // Only one input: cancel transaction + &tx_cancel.output_descriptor.witness_script(NullCtx), tx_cancel.amount().as_sat(), + SigHashType::All, ); Self { @@ -398,7 +399,7 @@ impl TxRefund { let mut tx_refund = self.inner; tx_cancel .output_descriptor - .satisfy(&mut tx_refund.input[0], satisfier)?; + .satisfy(&mut tx_refund.input[0], satisfier, NullCtx)?; Ok(tx_refund) } @@ -449,13 +450,13 @@ pub struct TxPunish { impl TxPunish { pub fn new(tx_cancel: &TxCancel, punish_address: &Address, punish_timelock: u32) -> Self { - let (tx_punish, lock_input) = - tx_cancel.build_spend_transaction(punish_address, Some(punish_timelock)); + let tx_punish = tx_cancel.build_spend_transaction(punish_address, Some(punish_timelock)); - let digest = SighashComponents::new(&tx_punish).sighash_all( - &lock_input, - &tx_cancel.output_descriptor.witness_script(), + let digest = SigHashCache::new(&tx_punish).signature_hash( + 0, // Only one input: cancel transaction + &tx_cancel.output_descriptor.witness_script(NullCtx), tx_cancel.amount().as_sat(), + SigHashType::All, ); Self { @@ -500,7 +501,7 @@ impl TxPunish { let mut tx_punish = self.inner; tx_cancel .output_descriptor - .satisfy(&mut tx_punish.input[0], satisfier)?; + .satisfy(&mut tx_punish.input[0], satisfier, NullCtx)?; Ok(tx_punish) } diff --git a/xmr-btc/src/bob.rs b/xmr-btc/src/bob.rs index 64c45f48..3d0c15ae 100644 --- a/xmr-btc/src/bob.rs +++ b/xmr-btc/src/bob.rs @@ -180,7 +180,7 @@ where } let tx_redeem = bitcoin::TxRedeem::new(&tx_lock, &redeem_address); - let tx_redeem_encsig = b.encsign(S_a_bitcoin.clone(), tx_redeem.digest()); + let tx_redeem_encsig = b.encsign(S_a_bitcoin, tx_redeem.digest()); co.yield_(Action::SendBtcRedeemEncsig(tx_redeem_encsig.clone())) .await; @@ -221,8 +221,7 @@ where } if let Err(SwapFailed::AfterBtcLock(_)) = swap_result { - let tx_cancel = - bitcoin::TxCancel::new(&tx_lock, refund_timelock, A.clone(), b.public()); + let tx_cancel = bitcoin::TxCancel::new(&tx_lock, refund_timelock, A, b.public()); let tx_cancel_txid = tx_cancel.txid(); let signed_tx_cancel = { let sig_a = tx_cancel_sig_a.clone(); @@ -230,7 +229,7 @@ where tx_cancel .clone() - .add_signatures(&tx_lock, (A.clone(), sig_a), (b.public(), sig_b)) + .add_signatures(&tx_lock, (A, sig_a), (b.public(), sig_b)) .expect("sig_{a,b} to be valid signatures for tx_cancel") }; @@ -250,7 +249,7 @@ where let sig_b = b.sign(tx_refund.digest()); tx_refund - .add_signatures(&tx_cancel, (A.clone(), sig_a), (b.public(), sig_b)) + .add_signatures(&tx_cancel, (A, sig_a), (b.public(), sig_b)) .expect("sig_{a,b} to be valid signatures for tx_refund") }; @@ -412,8 +411,7 @@ impl State0 { .ok_or_else(|| anyhow!("S_a is not a monero curve point"))?, )?; - let tx_lock = - bitcoin::TxLock::new(wallet, self.btc, msg.A.clone(), self.b.public()).await?; + let tx_lock = bitcoin::TxLock::new(wallet, self.btc, msg.A, self.b.public()).await?; let v = msg.v_a + self.v_b; Ok(State1 { @@ -462,17 +460,12 @@ impl State1 { } pub fn receive(self, msg: alice::Message1) -> Result { - let tx_cancel = TxCancel::new( - &self.tx_lock, - self.refund_timelock, - self.A.clone(), - self.b.public(), - ); + let tx_cancel = TxCancel::new(&self.tx_lock, self.refund_timelock, self.A, self.b.public()); let tx_refund = bitcoin::TxRefund::new(&tx_cancel, &self.refund_address); bitcoin::verify_sig(&self.A, &tx_cancel.digest(), &msg.tx_cancel_sig)?; bitcoin::verify_encsig( - self.A.clone(), + self.A, self.s_b.into_secp256k1().into(), &tx_refund.digest(), &msg.tx_refund_encsig, @@ -522,12 +515,7 @@ pub struct State2 { impl State2 { pub fn next_message(&self) -> Message2 { - let tx_cancel = TxCancel::new( - &self.tx_lock, - self.refund_timelock, - self.A.clone(), - self.b.public(), - ); + let tx_cancel = TxCancel::new(&self.tx_lock, self.refund_timelock, self.A, self.b.public()); let tx_cancel_sig = self.b.sign(tx_cancel.digest()); let tx_punish = bitcoin::TxPunish::new(&tx_cancel, &self.punish_address, self.punish_timelock); @@ -636,12 +624,8 @@ impl State3 { &self, bitcoin_wallet: &W, ) -> Result<()> { - let tx_cancel = bitcoin::TxCancel::new( - &self.tx_lock, - self.refund_timelock, - self.A.clone(), - self.b.public(), - ); + let tx_cancel = + bitcoin::TxCancel::new(&self.tx_lock, self.refund_timelock, self.A, self.b.public()); let tx_refund = bitcoin::TxRefund::new(&tx_cancel, &self.refund_address); { @@ -650,7 +634,7 @@ impl State3 { let signed_tx_cancel = tx_cancel.clone().add_signatures( &self.tx_lock, - (self.A.clone(), sig_a), + (self.A, sig_a), (self.b.public(), sig_b), )?; @@ -668,7 +652,7 @@ impl State3 { let signed_tx_refund = tx_refund.add_signatures( &tx_cancel.clone(), - (self.A.clone(), sig_a), + (self.A, sig_a), (self.b.public(), sig_b), )?; @@ -707,26 +691,22 @@ pub struct State4 { impl State4 { pub fn next_message(&self) -> Message3 { let tx_redeem = bitcoin::TxRedeem::new(&self.tx_lock, &self.redeem_address); - let tx_redeem_encsig = self.b.encsign(self.S_a_bitcoin.clone(), tx_redeem.digest()); + let tx_redeem_encsig = self.b.encsign(self.S_a_bitcoin, tx_redeem.digest()); Message3 { tx_redeem_encsig } } pub fn tx_redeem_encsig(&self) -> EncryptedSignature { let tx_redeem = bitcoin::TxRedeem::new(&self.tx_lock, &self.redeem_address); - self.b.encsign(self.S_a_bitcoin.clone(), tx_redeem.digest()) + self.b.encsign(self.S_a_bitcoin, tx_redeem.digest()) } pub async fn check_for_tx_cancel(&self, bitcoin_wallet: &W) -> Result where W: GetRawTransaction, { - let tx_cancel = bitcoin::TxCancel::new( - &self.tx_lock, - self.refund_timelock, - self.A.clone(), - self.b.public(), - ); + let tx_cancel = + bitcoin::TxCancel::new(&self.tx_lock, self.refund_timelock, self.A, self.b.public()); // todo: check if this is correct let sig_a = self.tx_cancel_sig_a.clone(); @@ -734,11 +714,7 @@ impl State4 { let tx_cancel = tx_cancel .clone() - .add_signatures( - &self.tx_lock, - (self.A.clone(), sig_a), - (self.b.public(), sig_b), - ) + .add_signatures(&self.tx_lock, (self.A, sig_a), (self.b.public(), sig_b)) .expect( "sig_{a,b} to be valid signatures for tx_cancel", @@ -753,12 +729,8 @@ impl State4 { where W: BroadcastSignedTransaction, { - let tx_cancel = bitcoin::TxCancel::new( - &self.tx_lock, - self.refund_timelock, - self.A.clone(), - self.b.public(), - ); + let tx_cancel = + bitcoin::TxCancel::new(&self.tx_lock, self.refund_timelock, self.A, self.b.public()); // todo: check if this is correct let sig_a = self.tx_cancel_sig_a.clone(); @@ -766,11 +738,7 @@ impl State4 { let tx_cancel = tx_cancel .clone() - .add_signatures( - &self.tx_lock, - (self.A.clone(), sig_a), - (self.b.public(), sig_b), - ) + .add_signatures(&self.tx_lock, (self.A, sig_a), (self.b.public(), sig_b)) .expect( "sig_{a,b} to be valid signatures for tx_cancel", @@ -787,7 +755,7 @@ impl State4 { W: WatchForRawTransaction, { let tx_redeem = bitcoin::TxRedeem::new(&self.tx_lock, &self.redeem_address); - let tx_redeem_encsig = self.b.encsign(self.S_a_bitcoin.clone(), tx_redeem.digest()); + let tx_redeem_encsig = self.b.encsign(self.S_a_bitcoin, tx_redeem.digest()); let tx_redeem_candidate = bitcoin_wallet .watch_for_raw_transaction(tx_redeem.txid()) @@ -795,16 +763,16 @@ impl State4 { let tx_redeem_sig = tx_redeem.extract_signature_by_key(tx_redeem_candidate, self.b.public())?; - let s_a = bitcoin::recover(self.S_a_bitcoin.clone(), tx_redeem_sig, tx_redeem_encsig)?; + let s_a = bitcoin::recover(self.S_a_bitcoin, tx_redeem_sig, tx_redeem_encsig)?; let s_a = monero::private_key_from_secp256k1_scalar(s_a.into()); Ok(State5 { - A: self.A.clone(), + A: self.A, b: self.b.clone(), s_a, s_b: self.s_b, S_a_monero: self.S_a_monero, - S_a_bitcoin: self.S_a_bitcoin.clone(), + S_a_bitcoin: self.S_a_bitcoin, v: self.v, btc: self.btc, xmr: self.xmr,