mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-01-22 21:31:10 -05:00
Make bitcoin::WatchForRawTransaction infallible
And trigger refund if Alice's redeem transaction takes too long.
This commit is contained in:
parent
ba3011a9c9
commit
df4ffb65c9
@ -356,7 +356,7 @@ impl State3 {
|
||||
tracing::info!("watching for lock btc with txid: {}", self.tx_lock.txid());
|
||||
let tx = bitcoin_wallet
|
||||
.watch_for_raw_transaction(self.tx_lock.txid())
|
||||
.await?;
|
||||
.await;
|
||||
|
||||
tracing::info!("tx lock seen with txid: {}", tx.txid());
|
||||
|
||||
@ -554,7 +554,7 @@ impl State5 {
|
||||
|
||||
let tx_refund_candidate = bitcoin_wallet
|
||||
.watch_for_raw_transaction(tx_refund.txid())
|
||||
.await?;
|
||||
.await;
|
||||
|
||||
let tx_refund_sig =
|
||||
tx_refund.extract_signature_by_key(tx_refund_candidate, self.a.public())?;
|
||||
|
@ -189,7 +189,7 @@ pub trait BroadcastSignedTransaction {
|
||||
|
||||
#[async_trait]
|
||||
pub trait WatchForRawTransaction {
|
||||
async fn watch_for_raw_transaction(&self, txid: Txid) -> Result<Transaction>;
|
||||
async fn watch_for_raw_transaction(&self, txid: Txid) -> Transaction;
|
||||
}
|
||||
|
||||
pub fn recover(S: PublicKey, sig: Signature, encsig: EncryptedSignature) -> Result<SecretKey> {
|
||||
|
@ -472,7 +472,7 @@ impl State4 {
|
||||
|
||||
let tx_redeem_candidate = bitcoin_wallet
|
||||
.watch_for_raw_transaction(tx_redeem.txid())
|
||||
.await?;
|
||||
.await;
|
||||
|
||||
let tx_redeem_sig =
|
||||
tx_redeem.extract_signature_by_key(tx_redeem_candidate, self.b.public())?;
|
||||
|
@ -53,7 +53,10 @@ pub mod transport;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use ecdsa_fun::{adaptor::Adaptor, nonce::Deterministic};
|
||||
use futures::future::Either;
|
||||
use futures::{
|
||||
future::{select, Either},
|
||||
FutureExt,
|
||||
};
|
||||
use genawaiter::sync::{Gen, GenBoxed};
|
||||
use sha2::Sha256;
|
||||
|
||||
@ -133,7 +136,8 @@ where
|
||||
let swap_result: Result<(), SwapFailed> = async {
|
||||
co.yield_(Action::LockBitcoin(tx_lock.clone())).await;
|
||||
|
||||
let poll_until_expiry = poll_until_bitcoin_time(bitcoin_ledger, refund_timelock);
|
||||
let poll_until_expiry =
|
||||
poll_until_bitcoin_time(bitcoin_ledger, refund_timelock).shared();
|
||||
futures::pin_mut!(poll_until_expiry);
|
||||
|
||||
// the source of this could be the database, this layer doesn't care
|
||||
@ -144,7 +148,7 @@ where
|
||||
));
|
||||
let S = S_a_monero + S_b_monero;
|
||||
|
||||
match futures::future::select(
|
||||
match select(
|
||||
monero_ledger.watch_for_transfer(
|
||||
S,
|
||||
v.public(),
|
||||
@ -152,7 +156,7 @@ where
|
||||
xmr,
|
||||
monero::MIN_CONFIRMATIONS,
|
||||
),
|
||||
poll_until_expiry,
|
||||
poll_until_expiry.clone(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
@ -167,10 +171,15 @@ where
|
||||
co.yield_(Action::SendBitcoinRedeemEncsig(tx_redeem_encsig.clone()))
|
||||
.await;
|
||||
|
||||
let tx_redeem_published = bitcoin_ledger
|
||||
.watch_for_raw_transaction(tx_redeem.txid())
|
||||
let tx_redeem_published = match select(
|
||||
bitcoin_ledger.watch_for_raw_transaction(tx_redeem.txid()),
|
||||
poll_until_expiry,
|
||||
)
|
||||
.await
|
||||
.expect("TODO: implementor of this trait must make it infallible by retrying");
|
||||
{
|
||||
Either::Left((tx, _)) => tx,
|
||||
Either::Right(_) => return Err(SwapFailed::TimelockReached),
|
||||
};
|
||||
|
||||
// NOTE: If any of this fails, Bob will never be able to take the monero.
|
||||
// Therefore, there is no way to handle these errors other than aborting
|
||||
|
@ -112,13 +112,14 @@ impl BroadcastSignedTransaction for Wallet {
|
||||
|
||||
#[async_trait]
|
||||
impl WatchForRawTransaction for Wallet {
|
||||
async fn watch_for_raw_transaction(&self, txid: Txid) -> Result<Transaction> {
|
||||
loop {
|
||||
if let Ok(tx) = self.0.get_raw_transaction(txid).await {
|
||||
return Ok(tx);
|
||||
}
|
||||
time::delay_for(Duration::from_millis(200)).await;
|
||||
}
|
||||
async fn watch_for_raw_transaction(&self, txid: Txid) -> Transaction {
|
||||
(|| async { Ok(self.0.get_raw_transaction(txid).await?) })
|
||||
.retry(ExponentialBackoff {
|
||||
max_elapsed_time: None,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
.expect("transient errors to be retried")
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user