Skip to content

Commit

Permalink
f
Browse files Browse the repository at this point in the history
  • Loading branch information
jbesraa committed Jul 19, 2024
1 parent b64d6fc commit 9ce890d
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 60 deletions.
22 changes: 17 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ use graph::NetworkGraph;
use liquidity::LiquiditySource;
use payment::store::PaymentStore;
use payment::{
Bolt11Payment, Bolt12Payment, OnchainPayment, PayjoinPayment, PaymentDetails, SpontaneousPayment,
UnifiedQrPayment,
Bolt11Payment, Bolt12Payment, OnchainPayment, PayjoinPayment, PaymentDetails,
SpontaneousPayment, UnifiedQrPayment,
};
use peer_store::{PeerInfo, PeerStore};
use types::{
Expand Down Expand Up @@ -382,6 +382,10 @@ impl Node {
let archive_cmon = Arc::clone(&self.chain_monitor);
let sync_sweeper = Arc::clone(&self.output_sweeper);
let sync_logger = Arc::clone(&self.logger);
let sync_payjoin = match &self.payjoin_handler {
Some(pj_handler) => Some(Arc::clone(pj_handler)),
None => None,
};
let sync_wallet_timestamp = Arc::clone(&self.latest_wallet_sync_timestamp);
let sync_monitor_archival_height = Arc::clone(&self.latest_channel_monitor_archival_height);
let mut stop_sync = self.stop_sender.subscribe();
Expand All @@ -401,11 +405,14 @@ impl Node {
return;
}
_ = wallet_sync_interval.tick() => {
let confirmables = vec![
let mut confirmables = vec![
&*sync_cman as &(dyn Confirm + Sync + Send),
&*sync_cmon as &(dyn Confirm + Sync + Send),
&*sync_sweeper as &(dyn Confirm + Sync + Send),
];
if let Some(sync_payjoin) = sync_payjoin.as_ref() {
confirmables.push(sync_payjoin.as_ref() as &(dyn Confirm + Sync + Send));
}
let now = Instant::now();
let timeout_fut = tokio::time::timeout(Duration::from_secs(LDK_WALLET_SYNC_TIMEOUT_SECS), tx_sync.sync(confirmables));
match timeout_fut.await {
Expand Down Expand Up @@ -1108,7 +1115,8 @@ impl Node {
self.bolt12_payment(),
Arc::clone(&self.config),
Arc::clone(&self.logger),
))}
))
}

/// Returns a Payjoin payment handler allowing to send Payjoin transactions
///
Expand Down Expand Up @@ -1347,11 +1355,15 @@ impl Node {
let fee_estimator = Arc::clone(&self.fee_estimator);
let sync_sweeper = Arc::clone(&self.output_sweeper);
let sync_logger = Arc::clone(&self.logger);
let confirmables = vec![
let sync_payjoin = &self.payjoin_handler.as_ref();
let mut confirmables = vec![
&*sync_cman as &(dyn Confirm + Sync + Send),
&*sync_cmon as &(dyn Confirm + Sync + Send),
&*sync_sweeper as &(dyn Confirm + Sync + Send),
];
if let Some(sync_payjoin) = sync_payjoin {
confirmables.push(sync_payjoin.as_ref() as &(dyn Confirm + Sync + Send));
}
let sync_wallet_timestamp = Arc::clone(&self.latest_wallet_sync_timestamp);
let sync_fee_rate_update_timestamp =
Arc::clone(&self.latest_fee_rate_cache_update_timestamp);
Expand Down
103 changes: 48 additions & 55 deletions src/payment/payjoin/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,80 +134,72 @@ impl PayjoinHandler {
) -> Result<Transaction, Error> {
let wallet = self.wallet.clone();
wallet.sign_payjoin_proposal(payjoin_proposal, original_psbt)?;

let proposal_tx = payjoin_proposal.clone().extract_tx();
match self
.transactions
.read()
.unwrap()
.iter()
.position(|t| t.original_psbt() == original_psbt)
{
Some(pos) => {
let pj_tx = self.transactions.write().unwrap().remove(pos);
pj_tx.waiting_first_confirmation(proposal_tx.clone())?;
let txid = proposal_tx.txid();
// watch proposal transaction
self.chain_source.register_tx(&txid, Script::empty());
Ok(proposal_tx)
},
None => {
log_error!(
self.logger,
"Failed to process Payjoin response: transaction not found"
);
Err(Error::PayjoinResponseProcessingFailed)
},
let mut transactions = self.transactions.write().unwrap();
let pos = transactions.iter().position(|t| t.original_psbt() == original_psbt);
if let Some(pos) = pos {
let pj_tx = transactions.remove(pos);
pj_tx.waiting_first_confirmation(proposal_tx.clone())?;
let txid = proposal_tx.txid();
// watch proposal transaction
self.chain_source.register_tx(&txid, Script::empty());
self.event_queue.add_event(Event::PayjoinPaymentBroadcasted {
txid,
amount_sats: pj_tx.amount().to_sat(),
recipient: pj_tx.receiver().clone().into(),
})?;
Ok(proposal_tx)
} else {
log_error!(self.logger, "Failed to process Payjoin response: transaction not found");
Err(Error::PayjoinResponseProcessingFailed)
}
}

pub(crate) fn handle_request_failure(
&self, original_psbt: &Psbt, reason: PayjoinPaymentFailureReason,
) -> Result<(), Error> {
match self
.transactions
.read()
.unwrap()
.iter()
.position(|o| o.original_psbt() == original_psbt)
{
Some(pos) => {
let mut transactions = self.transactions.write().unwrap();
let tx = transactions.remove(pos);
let payment_id: [u8; 32] =
tx.original_psbt().unsigned_tx.txid()[..].try_into().map_err(|_| {
log_error!(
let mut transactions = self.transactions.write().unwrap();
let pos = transactions.iter().position(|t| t.original_psbt() == original_psbt);
if let Some(pos) = pos {
let tx = transactions.remove(pos);
let payment_id: [u8; 32] =
tx.original_psbt().unsigned_tx.txid()[..].try_into().map_err(|_| {
log_error!(
self.logger,
"Failed to handle request failure for Payjoin payment: invalid payment id"
);
Error::PayjoinRequestSendingFailed
})?;
let mut update_details = PaymentDetailsUpdate::new(PaymentId(payment_id));
update_details.status = Some(PaymentStatus::Failed);
let _ = self.payment_store.update(&update_details);
self.event_queue.add_event(Event::PayjoinPaymentFailed {
txid: original_psbt.unsigned_tx.txid(),
recipient: tx.receiver().clone().into(),
amount_sats: tx.amount().to_sat(),
reason,
})
},
None => {
log_error!(
self.logger,
"Failed to handle request failure for Payjoin payment: transaction not found"
);
Err(Error::PayjoinRequestSendingFailed)
},
Error::PayjoinRequestSendingFailed
})?;
let mut update_details = PaymentDetailsUpdate::new(PaymentId(payment_id));
update_details.status = Some(PaymentStatus::Failed);
let _ = self.payment_store.update(&update_details);
self.event_queue.add_event(Event::PayjoinPaymentFailed {
txid: original_psbt.unsigned_tx.txid(),
recipient: tx.receiver().clone().into(),
amount_sats: tx.amount().to_sat(),
reason,
})
}
else {
log_error!(
self.logger,
"Failed to handle request failure for Payjoin payment: transaction not found"
);
Err(Error::PayjoinRequestSendingFailed)
}
}

fn internal_transactions_confirmed(
&self, header: &Header, txdata: &TransactionData, height: u32,
) {
dbg!("internal transactions confirmed");
let (_, tx) = txdata[0];
let confirmed_tx_txid = tx.txid();
let mut transactions = self.transactions.write().unwrap();
if let Some(pos) = transactions.iter().position(|o| o.txid() == confirmed_tx_txid) {
let pos = transactions.iter().position(|t| t.txid() == confirmed_tx_txid);
dbg!(&pos);
if let Some(pos) = pos {
match transactions.remove(pos) {
PayjoinTransaction::PendingReceiverResponse { original_psbt, receiver, amount } => {
println!("Payjoin receiver broadcasted original psbt transaction!");
Expand Down Expand Up @@ -300,6 +292,7 @@ impl PayjoinHandler {
}
}


impl Confirm for PayjoinHandler {
fn transactions_confirmed(&self, header: &Header, txdata: &TransactionData, height: u32) {
self.internal_transactions_confirmed(header, txdata, height);
Expand Down
2 changes: 2 additions & 0 deletions src/payment/payjoin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,12 @@ impl PayjoinPayment {
break;
},
Ok(None) => {
dbg!("Payjoin request sent, waiting for response...");
log_info!(logger, "Payjoin request sent, waiting for response...");
continue;
}
Err(e) => {
dbg!(&e);
log_error!(logger, "Failed to send Payjoin request : {}", e);
let _ = payjoin_handler.handle_request_failure(&original_psbt, PayjoinPaymentFailureReason::RequestSendingFailed);
break;
Expand Down

0 comments on commit 9ce890d

Please sign in to comment.