From a4128c6eff34908233c87626e8b21acb1621e350 Mon Sep 17 00:00:00 2001 From: chris-belcher Date: Sat, 2 Jan 2021 23:38:52 +0000 Subject: [PATCH] Make taker disconnect while waiting for tx confirm Taker will reconnect to maker after transactions confirm. --- src/taker_protocol.rs | 458 ++++++++++++++++++++++-------------------- 1 file changed, 240 insertions(+), 218 deletions(-) diff --git a/src/taker_protocol.rs b/src/taker_protocol.rs index c4b5c552..08e9fdad 100644 --- a/src/taker_protocol.rs +++ b/src/taker_protocol.rs @@ -123,9 +123,6 @@ async fn send_coinswap( let my_tx_count: u32 = 3; let maker_tx_count: u32 = 3; - let mut socket = TcpStream::connect("localhost:6102").await?; - let (mut reader, mut socket_writer) = connect_to_maker(&mut socket).await?; - let mut preimage = [0u8; 32]; OsRng.fill_bytes(&mut preimage); let hashvalue = Hash160::hash(&preimage).into_inner(); @@ -156,62 +153,69 @@ async fn send_coinswap( my_locktime, ); - send_message( - &mut socket_writer, - TakerToMakerMessage::SignSendersContractTx(SignSendersContractTx { - txes_info: izip!( - maker_multisig_key_nonces.iter(), - maker_hashlock_key_nonces.iter(), - timelock_pubkeys.iter(), - outgoing_swapcoins.iter() - ) - .map( - |( - &multisig_key_nonce, - &hashlock_key_nonce, - &timelock_pubkey, - outgoing_swapcoin, - )| SenderContractTxNoncesInfo { - multisig_key_nonce, - hashlock_key_nonce, - timelock_pubkey, - senders_contract_tx: outgoing_swapcoin.contract_tx.clone(), - multisig_redeemscript: outgoing_swapcoin.get_multisig_redeemscript(), - funding_input_value: outgoing_swapcoin.funding_amount, - }, - ) - .collect::>(), - hashvalue, - locktime: my_locktime, - }), - ) - .await?; - //TODO this pattern of let = if let else err could probably be replaced by - //one of the methods in Result, such as ok_or() or something - let senders_contract_sig = - if let MakerToTakerMessage::SendersContractSig(m) = read_message(&mut reader).await? { - m - } else { - return Err(Box::new(IOError::new(ErrorKind::InvalidData, ""))); - }; - - if senders_contract_sig.sigs.len() != outgoing_swapcoins.len() { - panic!("wrong number of signatures from maker, ending"); - } - if senders_contract_sig - .sigs - .iter() - .zip(outgoing_swapcoins.iter()) - .any(|(sig, outgoing_swapcoin)| !outgoing_swapcoin.verify_contract_tx_sig(&sig)) { - panic!("invalid signature from maker, ending"); - //TODO go back to the start and try with another maker, in a loop + let mut socket = TcpStream::connect("localhost:6102").await?; + let (mut reader, mut socket_writer) = connect_to_maker(&mut socket).await?; + send_message( + &mut socket_writer, + TakerToMakerMessage::SignSendersContractTx(SignSendersContractTx { + txes_info: izip!( + maker_multisig_key_nonces.iter(), + maker_hashlock_key_nonces.iter(), + timelock_pubkeys.iter(), + outgoing_swapcoins.iter() + ) + .map( + |( + &multisig_key_nonce, + &hashlock_key_nonce, + &timelock_pubkey, + outgoing_swapcoin, + )| SenderContractTxNoncesInfo { + multisig_key_nonce, + hashlock_key_nonce, + timelock_pubkey, + senders_contract_tx: outgoing_swapcoin.contract_tx.clone(), + multisig_redeemscript: outgoing_swapcoin.get_multisig_redeemscript(), + funding_input_value: outgoing_swapcoin.funding_amount, + }, + ) + .collect::>(), + hashvalue, + locktime: my_locktime, + }), + ) + .await?; + //TODO this pattern of let = if let else err could probably be replaced by + //one of the methods in Result, such as ok_or() or something + let senders_contract_sig = + if let MakerToTakerMessage::SendersContractSig(m) = read_message(&mut reader).await? { + m + } else { + return Err(Box::new(IOError::new(ErrorKind::InvalidData, ""))); + }; + + if senders_contract_sig.sigs.len() != outgoing_swapcoins.len() { + panic!("wrong number of signatures from maker, ending"); + } + if senders_contract_sig + .sigs + .iter() + .zip(outgoing_swapcoins.iter()) + .any(|(sig, outgoing_swapcoin)| !outgoing_swapcoin.verify_contract_tx_sig(&sig)) + { + panic!("invalid signature from maker, ending"); + //TODO go back to the start and try with another maker, in a loop + } + senders_contract_sig + .sigs + .iter() + .zip(outgoing_swapcoins.iter_mut()) + .for_each(|(sig, outgoing_swapcoin)| { + outgoing_swapcoin.others_contract_sig = Some(*sig) + }); } - senders_contract_sig - .sigs - .iter() - .zip(outgoing_swapcoins.iter_mut()) - .for_each(|(sig, outgoing_swapcoin)| outgoing_swapcoin.others_contract_sig = Some(*sig)); + for my_funding_tx in my_funding_txes.iter() { let txid = if let Ok(t) = rpc.send_raw_transaction(my_funding_tx) { t @@ -270,148 +274,158 @@ async fn send_coinswap( my_receiving_hashlock_pubkeys.push(my_receiving_hashlock_pubkey); my_receiving_hashlock_privkeys.push(my_receiving_hashlock_privkey); } - send_message( - &mut socket_writer, - TakerToMakerMessage::ProofOfFunding(ProofOfFunding { - confirmed_funding_txes: izip!( - my_funding_txes.iter(), - funding_tx_merkleproofs.iter(), - outgoing_swapcoins.iter(), - maker_multisig_key_nonces.iter(), - maker_hashlock_key_nonces.iter() - ) - .map( - |( - funding_tx, - funding_tx_merkleproof, - outgoing_swapcoin, - &multisig_key_nonce, - &hashlock_key_nonce, - )| ConfirmedCoinSwapTxInfo { - funding_tx: funding_tx.clone(), - funding_tx_merkleproof: funding_tx_merkleproof.clone(), - multisig_redeemscript: outgoing_swapcoin.get_multisig_redeemscript(), - multisig_key_nonce, - contract_redeemscript: outgoing_swapcoin.contract_redeemscript.clone(), - hashlock_key_nonce, - }, - ) - .collect::>(), - next_coinswap_info: maker_funded_multisig_pubkeys - .iter() - .zip(my_receiving_hashlock_pubkeys.iter()) + + let (sign_sender_and_receiver_contract, next_contract_redeemscripts) = { + let mut socket = TcpStream::connect("localhost:6102").await?; + let (mut reader, mut socket_writer) = connect_to_maker(&mut socket).await?; + send_message( + &mut socket_writer, + TakerToMakerMessage::ProofOfFunding(ProofOfFunding { + confirmed_funding_txes: izip!( + my_funding_txes.iter(), + funding_tx_merkleproofs.iter(), + outgoing_swapcoins.iter(), + maker_multisig_key_nonces.iter(), + maker_hashlock_key_nonces.iter() + ) .map( - |(&next_coinswap_multisig_pubkey, &next_hashlock_pubkey)| NextCoinSwapTxInfo { - next_coinswap_multisig_pubkey, - next_hashlock_pubkey, + |( + funding_tx, + funding_tx_merkleproof, + outgoing_swapcoin, + &multisig_key_nonce, + &hashlock_key_nonce, + )| ConfirmedCoinSwapTxInfo { + funding_tx: funding_tx.clone(), + funding_tx_merkleproof: funding_tx_merkleproof.clone(), + multisig_redeemscript: outgoing_swapcoin.get_multisig_redeemscript(), + multisig_key_nonce, + contract_redeemscript: outgoing_swapcoin.contract_redeemscript.clone(), + hashlock_key_nonce, }, ) - .collect::>(), - next_locktime: REFUND_LOCKTIME, - }), - ) - .await?; - let sign_sender_and_receiver_contract = - if let MakerToTakerMessage::SignSendersAndReceiversContractTxes(m) = - read_message(&mut reader).await? - { - m - } else { - return Err(Box::new(IOError::new(ErrorKind::InvalidData, ""))); - }; - if sign_sender_and_receiver_contract - .receivers_contract_txes - .len() - != outgoing_swapcoins.len() - { - panic!("wrong number of signatures from maker, ending"); - } - for (receivers_contract_tx, outgoing_swapcoin) in sign_sender_and_receiver_contract - .receivers_contract_txes - .iter() - .zip(outgoing_swapcoins.iter()) - { - validate_contract_tx( - &receivers_contract_tx, - Some(&outgoing_swapcoin.contract_tx.input[0].previous_output), - &outgoing_swapcoin.contract_redeemscript, + .collect::>(), + next_coinswap_info: maker_funded_multisig_pubkeys + .iter() + .zip(my_receiving_hashlock_pubkeys.iter()) + .map(|(&next_coinswap_multisig_pubkey, &next_hashlock_pubkey)| { + NextCoinSwapTxInfo { + next_coinswap_multisig_pubkey, + next_hashlock_pubkey, + } + }) + .collect::>(), + next_locktime: REFUND_LOCKTIME, + }), ) - .unwrap(); //TODO make it not just crash if invalid contract tx - } - let receivers_sigs = sign_sender_and_receiver_contract - .receivers_contract_txes - .iter() - .zip(outgoing_swapcoins.iter()) - .map(|(receivers_contract_tx, outgoing_swapcoin)| { - outgoing_swapcoin.sign_contract_tx_with_my_privkey(receivers_contract_tx) - }) - .collect::>(); - - if my_receiving_hashlock_pubkeys.len() - != sign_sender_and_receiver_contract - .senders_contract_txes_info + .await?; + let sign_sender_and_receiver_contract = + if let MakerToTakerMessage::SignSendersAndReceiversContractTxes(m) = + read_message(&mut reader).await? + { + m + } else { + return Err(Box::new(IOError::new(ErrorKind::InvalidData, ""))); + }; + if sign_sender_and_receiver_contract + .receivers_contract_txes .len() - { - panic!("wrong number of senders contract txes from maker, ending"); - } - let mut next_contract_redeemscripts = Vec::