Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: track payment on cln nodes #75

Merged
merged 1 commit into from
Sep 11, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 45 additions & 6 deletions sim-lib/src/cln.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
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::{self, Duration};
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<Channel>,
Expand Down Expand Up @@ -101,10 +105,45 @@ impl LightningNode for ClnNode {

async fn track_payment(
&mut self,
_hash: PaymentHash,
_shutdown: Listener,
hash: PaymentHash,
shutdown: Listener,
) -> Result<PaymentResult, LightningError> {
unimplemented!()
loop {
tokio::select! {
biased;
_ = shutdown.clone() => {
return Err(LightningError::TrackPaymentError("Shutdown before tracking results".to_string()));
},
_ = time::sleep(Duration::from_millis(500)) => {
let ListpaysResponse { pays } = self
.client
.list_pays(ListpaysRequest {
payment_hash: Some(hash.0.to_vec()),
..Default::default()
})
.await
.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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll look into this.

ListpaysPaysStatus::Failed => PaymentOutcome::UnexpectedError,
};
let htlc_count = pay.number_of_parts.unwrap_or(1).try_into().map_err(|_| LightningError::TrackPaymentError("Invalid number of parts".to_string()))?;
return Ok(PaymentResult {
htlc_count,
payment_outcome,
});
}
},
}
}
}

async fn get_node_features(&mut self, node: PublicKey) -> Result<NodeFeatures, LightningError> {
Expand Down