|
|
|
@ -4,12 +4,15 @@ use async_trait::async_trait;
|
|
|
|
|
use backoff::{backoff::Constant as ConstantBackoff, future::FutureOperation as _};
|
|
|
|
|
use monero_harness::rpc::wallet;
|
|
|
|
|
use std::{str::FromStr, time::Duration};
|
|
|
|
|
use tracing::info;
|
|
|
|
|
use url::Url;
|
|
|
|
|
|
|
|
|
|
use crate::monero::{
|
|
|
|
|
Amount, CreateWalletForOutput, InsufficientFunds, PrivateViewKey, PublicViewKey, Transfer,
|
|
|
|
|
TransferProof, TxHash, WatchForTransfer,
|
|
|
|
|
};
|
|
|
|
|
use bitcoin::hashes::core::sync::atomic::AtomicU32;
|
|
|
|
|
use std::sync::{atomic::Ordering, Arc};
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub struct Wallet {
|
|
|
|
@ -109,13 +112,18 @@ impl WatchForTransfer for Wallet {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let address = Address::standard(self.network, public_spend_key, public_view_key.into());
|
|
|
|
|
|
|
|
|
|
let res = (|| async {
|
|
|
|
|
let wallet = self.inner.clone();
|
|
|
|
|
|
|
|
|
|
let confirmations = Arc::new(AtomicU32::new(0u32));
|
|
|
|
|
let res = (move || {
|
|
|
|
|
let confirmations = confirmations.clone();
|
|
|
|
|
let transfer_proof = transfer_proof.clone();
|
|
|
|
|
let wallet = wallet.clone();
|
|
|
|
|
async move {
|
|
|
|
|
// NOTE: Currently, this is conflating IO errors with the transaction not being
|
|
|
|
|
// in the blockchain yet, or not having enough confirmations on it. All these
|
|
|
|
|
// errors warrant a retry, but the strategy should probably differ per case
|
|
|
|
|
let proof = self
|
|
|
|
|
.inner
|
|
|
|
|
let proof = wallet
|
|
|
|
|
.check_tx_key(
|
|
|
|
|
&String::from(transfer_proof.tx_hash()),
|
|
|
|
|
&transfer_proof.tx_key().to_string(),
|
|
|
|
@ -131,11 +139,20 @@ impl WatchForTransfer for Wallet {
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if proof.confirmations > confirmations.load(Ordering::SeqCst) {
|
|
|
|
|
confirmations.store(proof.confirmations, Ordering::SeqCst);
|
|
|
|
|
info!(
|
|
|
|
|
"Monero lock tx received {} out of {} confirmations",
|
|
|
|
|
proof.confirmations, expected_confirmations
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if proof.confirmations < expected_confirmations {
|
|
|
|
|
return Err(backoff::Error::Transient(Error::InsufficientConfirmations));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(proof)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.retry(ConstantBackoff::new(Duration::from_secs(1)))
|
|
|
|
|
.await;
|
|
|
|
|