mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-06-24 14:50:38 -04: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
5 changed files with 29 additions and 19 deletions
|
@ -356,7 +356,7 @@ impl State3 {
|
||||||
tracing::info!("watching for lock btc with txid: {}", self.tx_lock.txid());
|
tracing::info!("watching for lock btc with txid: {}", self.tx_lock.txid());
|
||||||
let tx = bitcoin_wallet
|
let tx = bitcoin_wallet
|
||||||
.watch_for_raw_transaction(self.tx_lock.txid())
|
.watch_for_raw_transaction(self.tx_lock.txid())
|
||||||
.await?;
|
.await;
|
||||||
|
|
||||||
tracing::info!("tx lock seen with txid: {}", tx.txid());
|
tracing::info!("tx lock seen with txid: {}", tx.txid());
|
||||||
|
|
||||||
|
@ -554,7 +554,7 @@ impl State5 {
|
||||||
|
|
||||||
let tx_refund_candidate = bitcoin_wallet
|
let tx_refund_candidate = bitcoin_wallet
|
||||||
.watch_for_raw_transaction(tx_refund.txid())
|
.watch_for_raw_transaction(tx_refund.txid())
|
||||||
.await?;
|
.await;
|
||||||
|
|
||||||
let tx_refund_sig =
|
let tx_refund_sig =
|
||||||
tx_refund.extract_signature_by_key(tx_refund_candidate, self.a.public())?;
|
tx_refund.extract_signature_by_key(tx_refund_candidate, self.a.public())?;
|
||||||
|
|
|
@ -189,7 +189,7 @@ pub trait BroadcastSignedTransaction {
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait WatchForRawTransaction {
|
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> {
|
pub fn recover(S: PublicKey, sig: Signature, encsig: EncryptedSignature) -> Result<SecretKey> {
|
||||||
|
|
|
@ -472,7 +472,7 @@ impl State4 {
|
||||||
|
|
||||||
let tx_redeem_candidate = bitcoin_wallet
|
let tx_redeem_candidate = bitcoin_wallet
|
||||||
.watch_for_raw_transaction(tx_redeem.txid())
|
.watch_for_raw_transaction(tx_redeem.txid())
|
||||||
.await?;
|
.await;
|
||||||
|
|
||||||
let tx_redeem_sig =
|
let tx_redeem_sig =
|
||||||
tx_redeem.extract_signature_by_key(tx_redeem_candidate, self.b.public())?;
|
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 async_trait::async_trait;
|
||||||
use ecdsa_fun::{adaptor::Adaptor, nonce::Deterministic};
|
use ecdsa_fun::{adaptor::Adaptor, nonce::Deterministic};
|
||||||
use futures::future::Either;
|
use futures::{
|
||||||
|
future::{select, Either},
|
||||||
|
FutureExt,
|
||||||
|
};
|
||||||
use genawaiter::sync::{Gen, GenBoxed};
|
use genawaiter::sync::{Gen, GenBoxed};
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
|
|
||||||
|
@ -133,7 +136,8 @@ where
|
||||||
let swap_result: Result<(), SwapFailed> = async {
|
let swap_result: Result<(), SwapFailed> = async {
|
||||||
co.yield_(Action::LockBitcoin(tx_lock.clone())).await;
|
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);
|
futures::pin_mut!(poll_until_expiry);
|
||||||
|
|
||||||
// the source of this could be the database, this layer doesn't care
|
// 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;
|
let S = S_a_monero + S_b_monero;
|
||||||
|
|
||||||
match futures::future::select(
|
match select(
|
||||||
monero_ledger.watch_for_transfer(
|
monero_ledger.watch_for_transfer(
|
||||||
S,
|
S,
|
||||||
v.public(),
|
v.public(),
|
||||||
|
@ -152,7 +156,7 @@ where
|
||||||
xmr,
|
xmr,
|
||||||
monero::MIN_CONFIRMATIONS,
|
monero::MIN_CONFIRMATIONS,
|
||||||
),
|
),
|
||||||
poll_until_expiry,
|
poll_until_expiry.clone(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
|
@ -167,10 +171,15 @@ where
|
||||||
co.yield_(Action::SendBitcoinRedeemEncsig(tx_redeem_encsig.clone()))
|
co.yield_(Action::SendBitcoinRedeemEncsig(tx_redeem_encsig.clone()))
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let tx_redeem_published = bitcoin_ledger
|
let tx_redeem_published = match select(
|
||||||
.watch_for_raw_transaction(tx_redeem.txid())
|
bitcoin_ledger.watch_for_raw_transaction(tx_redeem.txid()),
|
||||||
.await
|
poll_until_expiry,
|
||||||
.expect("TODO: implementor of this trait must make it infallible by retrying");
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
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.
|
// 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
|
// Therefore, there is no way to handle these errors other than aborting
|
||||||
|
|
|
@ -112,13 +112,14 @@ impl BroadcastSignedTransaction for Wallet {
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl WatchForRawTransaction for Wallet {
|
impl WatchForRawTransaction for Wallet {
|
||||||
async fn watch_for_raw_transaction(&self, txid: Txid) -> Result<Transaction> {
|
async fn watch_for_raw_transaction(&self, txid: Txid) -> Transaction {
|
||||||
loop {
|
(|| async { Ok(self.0.get_raw_transaction(txid).await?) })
|
||||||
if let Ok(tx) = self.0.get_raw_transaction(txid).await {
|
.retry(ExponentialBackoff {
|
||||||
return Ok(tx);
|
max_elapsed_time: None,
|
||||||
}
|
..Default::default()
|
||||||
time::delay_for(Duration::from_millis(200)).await;
|
})
|
||||||
}
|
.await
|
||||||
|
.expect("transient errors to be retried")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue