mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-10-01 01:45:40 -04:00
Add steps from EncSignLearned
This commit is contained in:
parent
8976a03b3d
commit
8e31a3af6a
@ -3,7 +3,7 @@
|
||||
use self::{amounts::*, message0::*, message1::*, message2::*, message3::*};
|
||||
use crate::{
|
||||
bitcoin,
|
||||
bitcoin::TX_LOCK_MINE_TIMEOUT,
|
||||
bitcoin::{EncryptedSignature, TX_LOCK_MINE_TIMEOUT},
|
||||
monero,
|
||||
network::{
|
||||
peer_tracker::{self, PeerTracker},
|
||||
@ -19,6 +19,7 @@ use anyhow::{anyhow, bail, Context, Result};
|
||||
use async_recursion::async_recursion;
|
||||
use async_trait::async_trait;
|
||||
use backoff::{backoff::Constant as ConstantBackoff, future::FutureOperation as _};
|
||||
use ecdsa_fun::{adaptor::Adaptor, nonce::Deterministic};
|
||||
use genawaiter::GeneratorState;
|
||||
use libp2p::{
|
||||
core::{identity::Keypair, Multiaddr},
|
||||
@ -26,6 +27,7 @@ use libp2p::{
|
||||
NetworkBehaviour, PeerId,
|
||||
};
|
||||
use rand::{rngs::OsRng, CryptoRng, RngCore};
|
||||
use sha2::Sha256;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use tokio::{sync::Mutex, time::timeout};
|
||||
use tracing::{debug, info, warn};
|
||||
@ -61,10 +63,16 @@ pub enum AliceState {
|
||||
amounts: SwapAmounts,
|
||||
state3: State3,
|
||||
},
|
||||
XmrLocked,
|
||||
XmrLocked {
|
||||
state3: State3,
|
||||
},
|
||||
EncSignLearned {
|
||||
state3: State3,
|
||||
encrypted_signature: EncryptedSignature,
|
||||
},
|
||||
BtcRedeemed,
|
||||
XmrRefunded,
|
||||
Cancelled,
|
||||
WaitingToCancel,
|
||||
Punished,
|
||||
SafelyAborted,
|
||||
}
|
||||
@ -239,11 +247,11 @@ where
|
||||
// primitive to execute the protocol 2. the more general/business
|
||||
// state that contains the crypto + other business data such as network
|
||||
// communication, amounts to verify, swap id, etc.
|
||||
db.insert_latest_state(swap_id, state::Alice::XmrLocked(state3).into())
|
||||
db.insert_latest_state(swap_id, state::Alice::XmrLocked(state3.clone()).into())
|
||||
.await?;
|
||||
|
||||
simple_swap(
|
||||
AliceState::XmrLocked,
|
||||
AliceState::XmrLocked { state3 },
|
||||
rng,
|
||||
swarm,
|
||||
db,
|
||||
@ -252,12 +260,110 @@ where
|
||||
)
|
||||
.await
|
||||
}
|
||||
AliceState::XmrLocked => {
|
||||
// Alice has locked Xmr
|
||||
// Alice waits until Bob sends her key to redeem BTC
|
||||
// Todo: Poll the swarm here until msg from Bob arrives or t1
|
||||
if unimplemented!("key_received") {
|
||||
// Alice redeems BTC
|
||||
AliceState::XmrLocked { state3 } => {
|
||||
let encsig = timeout(
|
||||
// TODO(Franck): This is now inefficient as time has been spent since btc was
|
||||
// locked
|
||||
Duration::from_secs(TX_LOCK_MINE_TIMEOUT),
|
||||
async {
|
||||
match swarm.next().await {
|
||||
OutEvent::Message3(msg) => Ok(msg.tx_redeem_encsig),
|
||||
other => Err(anyhow!(
|
||||
"Expected Bob's Bitcoin redeem encsig, got: {:?}",
|
||||
other
|
||||
)),
|
||||
}
|
||||
},
|
||||
)
|
||||
.await
|
||||
.context("Timed out, Bob did not send redeem encsign in time");
|
||||
|
||||
match encsig {
|
||||
Err(_timeout_error) => {
|
||||
// TODO(Franck): Insert in DB
|
||||
|
||||
simple_swap(
|
||||
AliceState::WaitingToCancel,
|
||||
rng,
|
||||
swarm,
|
||||
db,
|
||||
bitcoin_wallet,
|
||||
monero_wallet,
|
||||
)
|
||||
.await
|
||||
}
|
||||
Ok(Err(_unexpected_msg_error)) => {
|
||||
// TODO(Franck): Insert in DB
|
||||
|
||||
simple_swap(
|
||||
AliceState::WaitingToCancel,
|
||||
rng,
|
||||
swarm,
|
||||
db,
|
||||
bitcoin_wallet,
|
||||
monero_wallet,
|
||||
)
|
||||
.await
|
||||
}
|
||||
Ok(Ok(encrypted_signature)) => {
|
||||
// TODO(Franck): Insert in DB
|
||||
|
||||
simple_swap(
|
||||
AliceState::EncSignLearned {
|
||||
state3,
|
||||
encrypted_signature,
|
||||
},
|
||||
rng,
|
||||
swarm,
|
||||
db,
|
||||
bitcoin_wallet,
|
||||
monero_wallet,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
AliceState::EncSignLearned {
|
||||
state3,
|
||||
encrypted_signature,
|
||||
} => {
|
||||
let (signed_tx_redeem, tx_redeem_txid) = {
|
||||
let adaptor = Adaptor::<Sha256, Deterministic<Sha256>>::default();
|
||||
|
||||
let tx_redeem = bitcoin::TxRedeem::new(&state3.tx_lock, &state3.redeem_address);
|
||||
|
||||
bitcoin::verify_encsig(
|
||||
state3.B.clone(),
|
||||
state3.s_a.into_secp256k1().into(),
|
||||
&tx_redeem.digest(),
|
||||
&encrypted_signature,
|
||||
)
|
||||
.context("Invalid encrypted signature received")?;
|
||||
|
||||
let sig_a = state3.a.sign(tx_redeem.digest());
|
||||
let sig_b = adaptor
|
||||
.decrypt_signature(&state3.s_a.into_secp256k1(), encrypted_signature.clone());
|
||||
|
||||
let tx = tx_redeem
|
||||
.add_signatures(
|
||||
&state3.tx_lock,
|
||||
(state3.a.public(), sig_a),
|
||||
(state3.B.clone(), sig_b),
|
||||
)
|
||||
.expect("sig_{a,b} to be valid signatures for tx_redeem");
|
||||
let txid = tx.txid();
|
||||
|
||||
(tx, txid)
|
||||
};
|
||||
|
||||
// TODO(Franck): Insert in db
|
||||
|
||||
let _ = bitcoin_wallet
|
||||
.broadcast_signed_transaction(signed_tx_redeem)
|
||||
.await?;
|
||||
|
||||
// TODO(Franck) Wait for confirmations
|
||||
|
||||
simple_swap(
|
||||
AliceState::BtcRedeemed,
|
||||
rng,
|
||||
@ -267,20 +373,8 @@ where
|
||||
monero_wallet,
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
// submit TxCancel
|
||||
simple_swap(
|
||||
AliceState::Cancelled,
|
||||
rng,
|
||||
swarm,
|
||||
db,
|
||||
bitcoin_wallet,
|
||||
monero_wallet,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
AliceState::Cancelled => {
|
||||
AliceState::WaitingToCancel => {
|
||||
// Wait until t2 or if TxRefund is seen
|
||||
// If Bob has refunded the Alice should extract Bob's monero secret key and move
|
||||
// the TxLockXmr output to her wallet.
|
||||
@ -330,7 +424,7 @@ pub async fn abort(state: AliceState) -> Result<AliceState> {
|
||||
// Alice does not need to do anything to recover
|
||||
abort(AliceState::SafelyAborted).await
|
||||
}
|
||||
AliceState::XmrLocked => {
|
||||
AliceState::XmrLocked { state3 } => {
|
||||
// Alice has locked XMR
|
||||
// Alice watches for TxRedeem until t1
|
||||
if unimplemented!("TxRedeemSeen") {
|
||||
@ -338,12 +432,13 @@ pub async fn abort(state: AliceState) -> Result<AliceState> {
|
||||
abort(AliceState::BtcRedeemed).await
|
||||
} else if unimplemented!("T1Elapsed") {
|
||||
// publish TxCancel or see if it has been published
|
||||
abort(AliceState::Cancelled).await
|
||||
abort(AliceState::WaitingToCancel).await
|
||||
} else {
|
||||
Err(unimplemented!())
|
||||
}
|
||||
}
|
||||
AliceState::Cancelled => {
|
||||
AliceState::EncSignLearned { .. } => todo!(),
|
||||
AliceState::WaitingToCancel => {
|
||||
// Alice has cancelled the swap
|
||||
// Alice waits watches for t2 or TxRefund
|
||||
if unimplemented!("TxRefundSeen") {
|
||||
|
Loading…
Reference in New Issue
Block a user