@@ -54,27 +54,35 @@ struct HtlcAcceptedResponse {
5454const TLV_FORWARD_AMT : u64 = 2 ;
5555const 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+
5777pub 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 ] ) ;
0 commit comments