Skip to content

Commit d92d744

Browse files
nepetcdecker
authored andcommitted
plugin: Add macro to shortcut the hook flow
Adds a macro that allows us to replace `unwrap`s in order to prevent panics. The macro shortcuts further execution and returns from the htlc_accepted_hook. Signed-off-by: Peter Neuroth <[email protected]>
1 parent e704fcb commit d92d744

File tree

2 files changed

+38
-32
lines changed

2 files changed

+38
-32
lines changed

libs/gl-plugin/src/lsp.rs

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -54,27 +54,35 @@ struct HtlcAcceptedResponse {
5454
const TLV_FORWARD_AMT: u64 = 2;
5555
const TLV_PAYMENT_SECRET: u64 = 8;
5656

57+
/// A macro to break out of the current hook flow and return a `continue`
58+
/// signal to core-lightning. This is to be used when we don't know how to
59+
/// handle a given payload or as a shortcut in case we could identify that the
60+
/// incoming htlc is not part of a LSP jit channel opening.
61+
macro_rules! unwrap_or_continue {
62+
($res:expr) => {
63+
match $res {
64+
Ok(x) => x,
65+
Err(e) => {
66+
log::debug!("Lsp-plugin continue, reason: {}", e.to_string());
67+
return Ok(serde_json::to_value(HtlcAcceptedResponse {
68+
result: "continue".to_string(),
69+
..Default::default()
70+
})
71+
.expect("Could not serialize json value"));
72+
}
73+
}
74+
};
75+
}
76+
5777
pub async fn on_htlc_accepted(plugin: Plugin, v: Value) -> Result<Value, anyhow::Error> {
58-
let req: HtlcAcceptedRequest = serde_json::from_value(v).unwrap();
78+
let req: HtlcAcceptedRequest = unwrap_or_continue!(serde_json::from_value(v));
5979
log::debug!("Decoded {:?}", &req);
6080

6181
let htlc_amt = req.htlc.amount_msat;
62-
let onion_amt = match req.onion.forward_msat {
63-
Some(a) => a,
64-
None => {
65-
// An onion payload without an `amt_to_forward` is unorthodox and
66-
// can not be processed by this plugin. Skip it.
67-
log::debug!(
68-
"lsp-plugin: got an onion payload={} without an amt forward_msat.",
69-
req.onion.payload
70-
);
71-
return Ok(serde_json::to_value(HtlcAcceptedResponse {
72-
result: "continue".to_string(),
73-
..Default::default()
74-
})
75-
.unwrap());
76-
}
77-
};
82+
let onion_amt = unwrap_or_continue!(req.onion.forward_msat.ok_or(format!(
83+
"payload={} is missing forward_msat",
84+
&req.onion.payload
85+
)));
7886

7987
let res = if htlc_amt.msat() < onion_amt.msat() {
8088
log::info!(
@@ -85,7 +93,10 @@ pub async fn on_htlc_accepted(plugin: Plugin, v: Value) -> Result<Value, anyhow:
8593

8694
let mut payload = req.onion.payload.clone();
8795
payload.set_tu64(TLV_FORWARD_AMT, htlc_amt.msat());
88-
let payment_secret = payload.get(TLV_PAYMENT_SECRET).unwrap();
96+
let payment_secret = unwrap_or_continue!(payload.get(TLV_PAYMENT_SECRET).ok_or(format!(
97+
"payload={} is missing payment_secret",
98+
&payload.to_string()
99+
)));
89100

90101
let mut rpc = cln_rpc::ClnRpc::new(plugin.configuration().rpc_file).await?;
91102
let res: cln_rpc::model::responses::ListinvoicesResponse = rpc
@@ -99,19 +110,14 @@ pub async fn on_htlc_accepted(plugin: Plugin, v: Value) -> Result<Value, anyhow:
99110
limit: None,
100111
})
101112
.await?;
102-
if res.invoices.len() != 1 {
103-
log::warn!(
104-
"No invoice matching incoming HTLC payment_hash={} found, continuing",
105-
hex::encode(&req.htlc.payment_hash)
106-
);
107-
return Ok(serde_json::to_value(HtlcAcceptedResponse {
108-
result: "continue".to_string(),
109-
..Default::default()
110-
})
111-
.unwrap());
112-
}
113113

114-
let total_msat = res.invoices.iter().next().unwrap().amount_msat.unwrap();
114+
let invoice = unwrap_or_continue!(res.invoices.first().ok_or(format!(
115+
"no invoice matching incoming HTLC payment_hash={} found",
116+
hex::encode(&req.htlc.payment_hash),
117+
)));
118+
let total_msat = unwrap_or_continue!(invoice
119+
.amount_msat
120+
.ok_or("invoice has no total amount msat"));
115121

116122
let mut ps = bytes::BytesMut::new();
117123
ps.put(&payment_secret.value[0..32]);

libs/gl-testing/tests/test_node.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ def test_lsp_jit_fee(clients, node_factory, bitcoind):
238238
We test multiple parts and overpay slightly to verify that even
239239
that works out ok.
240240
241-
We also check that we can handle unorthodox onion payloads that
241+
We also check that we can handle unorthodox onion payloads that
242242
don't carry fields that we expect.
243243
244244
"""
@@ -384,7 +384,7 @@ def test_lsp_jit_fee(clients, node_factory, bitcoind):
384384

385385
# The htlc should be passed on to the next consumer.
386386
c.find_node().process.wait_for_log(
387-
r"lsp-plugin: got an onion payload=.* without an amt forward_msat.",
387+
r"Lsp-plugin continue, reason: payload=.* is missing forward_msat",
388388
timeout=10,
389389
)
390390

0 commit comments

Comments
 (0)