From 0c9b46480ea6a71e42ea14286e26cefb0a3a52bf Mon Sep 17 00:00:00 2001 From: okjodom Date: Wed, 23 Aug 2023 17:19:32 +0200 Subject: [PATCH] feat: tack payment on cln nodes --- sim-lib/src/cln.rs | 52 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/sim-lib/src/cln.rs b/sim-lib/src/cln.rs index 04933dc2..0999233e 100644 --- a/sim-lib/src/cln.rs +++ b/sim-lib/src/cln.rs @@ -1,18 +1,24 @@ +use std::time::Duration; + use async_trait::async_trait; use bitcoin::secp256k1::PublicKey; use cln_grpc::pb::{ - node_client::NodeClient, Amount, GetinfoRequest, GetinfoResponse, KeysendRequest, - KeysendResponse, ListnodesRequest, + listpays_pays::ListpaysPaysStatus, node_client::NodeClient, Amount, GetinfoRequest, + GetinfoResponse, KeysendRequest, KeysendResponse, ListnodesRequest, ListpaysRequest, + ListpaysResponse, }; use lightning::ln::features::NodeFeatures; use lightning::ln::PaymentHash; use tokio::fs::File; use tokio::io::{AsyncReadExt, Error}; +use tokio::time; use tonic::transport::{Certificate, Channel, ClientTlsConfig, Identity}; use triggered::Listener; -use crate::{ClnConnection, LightningError, LightningNode, NodeInfo, PaymentResult}; +use crate::{ + ClnConnection, LightningError, LightningNode, NodeInfo, PaymentOutcome, PaymentResult, +}; pub struct ClnNode { pub client: NodeClient, @@ -101,10 +107,44 @@ impl LightningNode for ClnNode { async fn track_payment( &mut self, - _hash: PaymentHash, - _shutdown: Listener, + hash: PaymentHash, + shutdown: Listener, ) -> Result { - unimplemented!() + loop { + tokio::select! { + biased; + _ = shutdown.clone() => { + break Err(LightningError::TrackPaymentError("Shutdown before tracking results".to_string())); + }, + response = self + .client + .list_pays(ListpaysRequest { + payment_hash: Some(hash.0.to_vec()), + ..Default::default() + }) => { + let ListpaysResponse { pays } = response.map_err(|err| LightningError::TrackPaymentError(err.to_string()))?.into_inner(); + if let Some(pay) = pays.first() { + let payment_status = ListpaysPaysStatus::from_i32(pay.status) + .ok_or(LightningError::TrackPaymentError("Invalid payment status".to_string()))?; + + let payment_outcome = match payment_status { + ListpaysPaysStatus::Pending => continue, + ListpaysPaysStatus::Complete => PaymentOutcome::Success, + // Task: https://github.com/bitcoin-dev-project/sim-ln/issues/26#issuecomment-1691780018 + ListpaysPaysStatus::Failed => PaymentOutcome::UnexpectedError, + }; + + break Ok(PaymentResult { + // Task: https://github.com/bitcoin-dev-project/sim-ln/issues/26#issuecomment-1691780018 + htlc_count: 1, + payment_outcome, + }); + } + } + } + + time::sleep(Duration::from_millis(100)).await; + } } async fn get_node_features(&mut self, node: PublicKey) -> Result {