Print each monero confirmation for Bob

This is to provide more context to the user.
demo
Daniel Karzel 3 years ago
parent f8848aca55
commit 7248af9498

@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
use tracing::debug; use tracing::debug;
/// JSON RPC client for monero-wallet-rpc. /// JSON RPC client for monero-wallet-rpc.
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct Client { pub struct Client {
pub inner: reqwest::Client, pub inner: reqwest::Client,
pub url: Url, pub url: Url,

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

Loading…
Cancel
Save