Skip to content

Commit

Permalink
introduce HtlcIdentifier
Browse files Browse the repository at this point in the history
  • Loading branch information
daywalker90 committed Jun 21, 2023
1 parent 546d424 commit 276b662
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 32 deletions.
66 changes: 41 additions & 25 deletions plugins/grpc-plugin-hold/src/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use tokio::time;

use crate::{
util::{cleanup_htlc_state, listinvoices, make_rpc_path},
HoldHtlc, HoldInvoice, PluginState,
HoldHtlc, HoldInvoice, HtlcIdentifier, PluginState,
};

pub(crate) async fn htlc_handler(
Expand All @@ -37,7 +37,8 @@ pub(crate) async fn htlc_handler(

let invoice;
let scid;
let htlc_id;
let chan_htlc_id;
let global_htlc_ident;
let hold_state;

{
Expand Down Expand Up @@ -96,7 +97,7 @@ pub(crate) async fn htlc_handler(
}
}

htlc_id = match htlc.get("id") {
chan_htlc_id = match htlc.get("id") {
Some(ce) => ce.as_u64().unwrap(),
None => {
warn!(
Expand All @@ -108,7 +109,7 @@ pub(crate) async fn htlc_handler(
};

scid = match htlc.get("short_channel_id") {
Some(ce) => ce.as_str().unwrap(),
Some(ce) => ce.as_str().unwrap().to_string(),
None => {
warn!(
"payment_hash: `{}`. short_channel_id not found! Rejecting htlc...",
Expand All @@ -118,6 +119,11 @@ pub(crate) async fn htlc_handler(
}
};

global_htlc_ident = HtlcIdentifier {
scid: scid.clone(),
htlc_id: chan_htlc_id,
};

cltv_expiry = match htlc.get("cltv_expiry") {
Some(ce) => ce.as_u64().unwrap() as u32,
None => {
Expand All @@ -134,7 +140,7 @@ pub(crate) async fn htlc_handler(
None => {
warn!(
"payment_hash: `{}` scid: `{}` htlc_id: {}: amount_msat not found! Rejecting htlc...",
pay_hash, scid, htlc_id
pay_hash, scid.to_string(), chan_htlc_id
);
return Ok(json!({"result": "fail"}));
}
Expand All @@ -146,7 +152,7 @@ pub(crate) async fn htlc_handler(

let mut htlc_data = HashMap::new();
htlc_data.insert(
scid.to_string() + &htlc_id.to_string(),
global_htlc_ident.clone(),
HoldHtlc {
amount_msat,
cltv_expiry,
Expand Down Expand Up @@ -179,7 +185,7 @@ pub(crate) async fn htlc_handler(
.await?;
}
holdinvoice.htlc_data.insert(
scid.to_string() + &htlc_id.to_string(),
global_htlc_ident.clone(),
HoldHtlc {
amount_msat,
cltv_expiry,
Expand All @@ -194,7 +200,7 @@ pub(crate) async fn htlc_handler(
pay_hash
);

cleanup_htlc_state(plugin.clone(), pay_hash, scid, htlc_id).await;
cleanup_htlc_state(plugin.clone(), pay_hash, &global_htlc_ident).await;

return Ok(json!({"result": "fail"}));
}
Expand All @@ -203,7 +209,7 @@ pub(crate) async fn htlc_handler(
"payment_hash: `{}` scid: `{}` htlc_id: `{}`. Holding {}msat",
pay_hash,
scid.to_string(),
htlc_id,
chan_htlc_id,
amount_msat
);

Expand All @@ -222,7 +228,7 @@ pub(crate) async fn htlc_handler(
if invoice.expires_at <= now + 60 {
warn!(
"payment_hash: `{}` scid: `{}` htlc: `{}`. Hold-invoice expired! State=CANCELED",
pay_hash, scid, htlc_id
pay_hash, scid, chan_htlc_id
);
match datastore_update_state(
&rpc_path,
Expand All @@ -239,15 +245,16 @@ pub(crate) async fn htlc_handler(
}
};

cleanup_htlc_state(plugin.clone(), pay_hash, scid, htlc_id).await;
cleanup_htlc_state(plugin.clone(), pay_hash, &global_htlc_ident)
.await;

return Ok(json!({"result": "fail"}));
}

if cltv_expiry <= plugin.state().blockheight.lock().clone() + 6 {
warn!(
"payment_hash: `{}` scid: `{}` htlc: `{}`. HTLC timed out. Rejecting htlc...",
pay_hash, scid, htlc_id
pay_hash, scid, chan_htlc_id
);
let cur_amt: u64 = hold_invoice_data
.htlc_data
Expand All @@ -274,11 +281,12 @@ pub(crate) async fn htlc_handler(
};
info!(
"payment_hash: `{}` scid: `{}` htlc: `{}`. No longer enough msats for the hold-invoice. State=OPEN",
pay_hash, scid, htlc_id
pay_hash, scid, chan_htlc_id
);
}

cleanup_htlc_state(plugin.clone(), pay_hash, scid, htlc_id).await;
cleanup_htlc_state(plugin.clone(), pay_hash, &global_htlc_ident)
.await;

return Ok(json!({"result": "fail"}));
}
Expand Down Expand Up @@ -309,12 +317,12 @@ pub(crate) async fn htlc_handler(
};
info!(
"payment_hash: `{}` scid: `{}` htlc: `{}`. Got enough msats for the hold-invoice. State=ACCEPTED",
pay_hash, scid, htlc_id
pay_hash, scid, chan_htlc_id
);
} else {
debug!(
"payment_hash: `{}` scid: `{}` htlc: `{}`. Not enough msats for the hold-invoice yet.",
pay_hash, scid, htlc_id
pay_hash, scid, chan_htlc_id
);
}
}
Expand Down Expand Up @@ -343,41 +351,49 @@ pub(crate) async fn htlc_handler(
};
info!(
"payment_hash: `{}` scid: `{}` htlc: `{}`. No longer enough msats for the hold-invoice. State=OPEN",
pay_hash, scid, htlc_id
pay_hash, scid, chan_htlc_id
);
} else {
debug!(
"payment_hash: `{}` scid: `{}` htlc: `{}`. Holding accepted hold-invoice.",
pay_hash, scid, htlc_id
pay_hash, scid, chan_htlc_id
);
}
}
Holdstate::Settled => {
info!(
"payment_hash: `{}` scid: `{}` htlc: `{}`. Settling htlc for hold-invoice. State=SETTLED",
pay_hash, scid, htlc_id
pay_hash, scid, chan_htlc_id
);

cleanup_htlc_state(plugin.clone(), pay_hash, scid, htlc_id)
.await;
cleanup_htlc_state(
plugin.clone(),
pay_hash,
&global_htlc_ident,
)
.await;

return Ok(json!({"result": "continue"}));
}
Holdstate::Canceled => {
info!(
"payment_hash: `{}` scid: `{}` htlc: `{}`. Rejecting htlc for canceled hold-invoice. State=CANCELED",
pay_hash, scid, htlc_id
pay_hash, scid, chan_htlc_id
);

cleanup_htlc_state(plugin.clone(), pay_hash, scid, htlc_id)
.await;
cleanup_htlc_state(
plugin.clone(),
pay_hash,
&global_htlc_ident,
)
.await;

return Ok(json!({"result": "fail"}));
}
}
}
None => {
warn!("payment_hash: `{}` scid: `{}` htlc: `{}`. DROPPED INVOICE from internal state!", pay_hash, scid, htlc_id);
warn!("payment_hash: `{}` scid: `{}` htlc: `{}`. DROPPED INVOICE from internal state!", pay_hash, scid, chan_htlc_id);
return Err(anyhow!(
"Invoice dropped from internal state unexpectedly: {}",
pay_hash
Expand Down
8 changes: 7 additions & 1 deletion plugins/grpc-plugin-hold/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,17 @@ pub struct HoldHtlc {
pub cltv_expiry: u32,
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct HtlcIdentifier {
pub scid: String,
pub htlc_id: u64,
}

#[derive(Clone, Debug)]
pub struct HoldInvoice {
pub hold_state: Holdstate,
pub generation: u64,
pub htlc_data: HashMap<String, HoldHtlc>,
pub htlc_data: HashMap<HtlcIdentifier, HoldHtlc>,
pub invoice: ListinvoicesInvoices,
}

Expand Down
9 changes: 3 additions & 6 deletions plugins/grpc-plugin-hold/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use cln_rpc::{
ClnRpc, Request, Response,
};

use crate::PluginState;
use crate::{HtlcIdentifier, PluginState};

pub async fn listinvoices(
rpc_path: &PathBuf,
Expand Down Expand Up @@ -37,14 +37,11 @@ pub fn make_rpc_path(plugin: &Plugin<PluginState>) -> PathBuf {
pub async fn cleanup_htlc_state(
plugin: Plugin<PluginState>,
pay_hash: &str,
scid: &str,
htlc_id: u64,
global_htlc_ident: &HtlcIdentifier,
) {
let mut hold_invoices = plugin.state().holdinvoices.lock().await;
if let Some(h_inv) = hold_invoices.get_mut(pay_hash) {
h_inv
.htlc_data
.remove(&(scid.to_string() + &htlc_id.to_string()));
h_inv.htlc_data.remove(global_htlc_ident);
if h_inv.htlc_data.is_empty() {
hold_invoices.remove(pay_hash);
}
Expand Down

0 comments on commit 276b662

Please sign in to comment.