@@ -29,6 +29,7 @@ use core::str::FromStr;
2929
3030use crate :: prelude:: { new_hash_map, HashMap , String } ;
3131
32+ use super :: msgs:: { Lsps5AppName , Lsps5WebhookUrl } ;
3233use super :: url_utils:: Url ;
3334use chrono:: Duration ;
3435use lightning:: sign:: EntropySource ;
@@ -51,9 +52,10 @@ impl Default for LSPS5ClientConfig {
5152}
5253
5354struct PeerState {
54- pending_set_webhook_requests : HashMap < LSPSRequestId , ( String , String , LSPSDateTime ) > , // RequestId -> (app_name, webhook_url, timestamp)
55+ pending_set_webhook_requests :
56+ HashMap < LSPSRequestId , ( Lsps5AppName , Lsps5WebhookUrl , LSPSDateTime ) > , // RequestId -> (app_name, webhook_url, timestamp)
5557 pending_list_webhooks_requests : HashMap < LSPSRequestId , LSPSDateTime > , // RequestId -> timestamp
56- pending_remove_webhook_requests : HashMap < LSPSRequestId , ( String , LSPSDateTime ) > , // RequestId -> (app_name, timestamp)
58+ pending_remove_webhook_requests : HashMap < LSPSRequestId , ( Lsps5AppName , LSPSDateTime ) > , // RequestId -> (app_name, timestamp)
5759 // Last cleanup time for garbage collection
5860 last_cleanup : LSPSDateTime , // Seconds since epoch
5961}
@@ -168,25 +170,18 @@ where
168170 pub fn set_webhook (
169171 & self , counterparty_node_id : PublicKey , app_name : String , webhook : String ,
170172 ) -> Result < LSPSRequestId , LightningError > {
171- if app_name. len ( ) > MAX_APP_NAME_LENGTH {
172- return Err ( LightningError {
173- err : format ! ( "App name exceeds maximum length of {} bytes" , MAX_APP_NAME_LENGTH ) ,
174- action : ErrorAction :: IgnoreAndLog ( Level :: Error ) ,
175- } ) ;
176- }
173+ let app_name = match Lsps5AppName :: new ( app_name) {
174+ Ok ( app_name) => app_name,
175+ Err ( e) => return Err ( e) ,
176+ } ;
177177
178- if webhook. len ( ) > MAX_WEBHOOK_URL_LENGTH {
179- return Err ( LightningError {
180- err : format ! (
181- "Webhook URL exceeds maximum length of {} bytes" ,
182- MAX_WEBHOOK_URL_LENGTH
183- ) ,
184- action : ErrorAction :: IgnoreAndLog ( Level :: Error ) ,
185- } ) ;
186- }
178+ let webhook = match Lsps5WebhookUrl :: new ( webhook) {
179+ Ok ( webhook) => webhook,
180+ Err ( e) => return Err ( e) ,
181+ } ;
187182
188183 // Validate URL format and protocol according to spec
189- let url = match Url :: parse ( & webhook) {
184+ let url = match Url :: parse ( & webhook. as_str ( ) ) {
190185 Ok ( url) => url,
191186 Err ( e) => {
192187 return Err ( LightningError {
@@ -208,8 +203,7 @@ where
208203 return Err ( e) ;
209204 }
210205
211- // Generate a unique request ID
212- let request_id = LSPSRequestId ( format ! ( "lsps5:webhook:{}" , self . generate_random_id( ) ) ) ;
206+ let request_id = crate :: utils:: generate_request_id ( & self . entropy_source ) ;
213207
214208 // Track this request with current timestamp
215209 self . with_peer_state ( counterparty_node_id, |peer_state| {
@@ -243,8 +237,7 @@ where
243237 pub fn list_webhooks (
244238 & self , counterparty_node_id : PublicKey ,
245239 ) -> Result < LSPSRequestId , LightningError > {
246- // Generate a unique request ID
247- let request_id = LSPSRequestId ( format ! ( "lsps5:list:{}" , self . generate_random_id( ) ) ) ;
240+ let request_id = crate :: utils:: generate_request_id ( & self . entropy_source ) ;
248241
249242 // Track this request with current timestamp
250243 self . with_peer_state ( counterparty_node_id, |peer_state| {
@@ -280,8 +273,13 @@ where
280273 pub fn remove_webhook (
281274 & self , counterparty_node_id : PublicKey , app_name : String ,
282275 ) -> Result < LSPSRequestId , LightningError > {
276+ let app_name = match Lsps5AppName :: new ( app_name) {
277+ Ok ( app_name) => app_name,
278+ Err ( e) => return Err ( e) ,
279+ } ;
280+
283281 // Generate a unique request ID
284- let request_id = LSPSRequestId ( format ! ( "lsps5:remove:{}" , self . generate_random_id ( ) ) ) ;
282+ let request_id = crate :: utils :: generate_request_id ( & self . entropy_source ) ;
285283
286284 // Track this request with current timestamp
287285 self . with_peer_state ( counterparty_node_id, |peer_state| {
@@ -365,23 +363,25 @@ where
365363 match response {
366364 LSPS5Response :: SetWebhook ( response) => {
367365 self . pending_events . enqueue ( LSPS5ClientEvent :: WebhookRegistered {
368- lsp : * counterparty_node_id,
366+ counterparty_node_id : * counterparty_node_id,
369367 num_webhooks : response. num_webhooks ,
370368 max_webhooks : response. max_webhooks ,
371369 no_change : response. no_change ,
372370 app_name,
373371 url : webhook_url,
372+ request_id,
374373 } ) ;
375374 result = Ok ( ( ) ) ;
376375 } ,
377376 LSPS5Response :: SetWebhookError ( error) => {
378377 self . pending_events . enqueue (
379378 LSPS5ClientEvent :: WebhookRegistrationFailed {
380- lsp : * counterparty_node_id,
379+ counterparty_node_id : * counterparty_node_id,
381380 error_code : error. code ,
382381 error_message : error. message ,
383382 app_name,
384383 url : webhook_url,
384+ request_id,
385385 } ,
386386 ) ;
387387 result = Ok ( ( ) ) ;
@@ -403,17 +403,19 @@ where
403403 match response {
404404 LSPS5Response :: ListWebhooks ( response) => {
405405 self . pending_events . enqueue ( LSPS5ClientEvent :: WebhooksListed {
406- lsp : * counterparty_node_id,
406+ counterparty_node_id : * counterparty_node_id,
407407 app_names : response. app_names ,
408408 max_webhooks : response. max_webhooks ,
409+ request_id,
409410 } ) ;
410411 result = Ok ( ( ) ) ;
411412 } ,
412413 LSPS5Response :: ListWebhooksError ( error) => {
413414 self . pending_events . enqueue ( LSPS5ClientEvent :: WebhooksListFailed {
414- lsp : * counterparty_node_id,
415+ counterparty_node_id : * counterparty_node_id,
415416 error_code : error. code ,
416417 error_message : error. message ,
418+ request_id,
417419 } ) ;
418420 result = Ok ( ( ) ) ;
419421 } ,
@@ -433,18 +435,20 @@ where
433435 LSPS5Response :: RemoveWebhook ( _) => {
434436 // Emit event
435437 self . pending_events . enqueue ( LSPS5ClientEvent :: WebhookRemoved {
436- lsp : * counterparty_node_id,
438+ counterparty_node_id : * counterparty_node_id,
437439 app_name,
440+ request_id,
438441 } ) ;
439442 result = Ok ( ( ) ) ;
440443 } ,
441444 LSPS5Response :: RemoveWebhookError ( error) => {
442445 self . pending_events . enqueue (
443446 LSPS5ClientEvent :: WebhookRemovalFailed {
444- lsp : * counterparty_node_id,
447+ counterparty_node_id : * counterparty_node_id,
445448 error_code : error. code ,
446449 error_message : error. message ,
447450 app_name,
451+ request_id,
448452 } ,
449453 ) ;
450454 result = Ok ( ( ) ) ;
@@ -663,13 +667,6 @@ where
663667 Err ( e) => Err ( e) ,
664668 }
665669 }
666-
667- // Helper method to generate random IDs for requests
668- fn generate_random_id ( & self ) -> String {
669- let mut bytes = [ 0u8 ; 16 ] ;
670- bytes. copy_from_slice ( & self . entropy_source . get_secure_random_bytes ( ) [ 0 ..16 ] ) ;
671- DisplayHex :: to_lower_hex_string ( & bytes)
672- }
673670}
674671
675672impl < ES : Deref > LSPSProtocolMessageHandler for LSPS5ClientHandler < ES >
@@ -680,9 +677,9 @@ where
680677 const PROTOCOL_NUMBER : Option < u16 > = Some ( 5 ) ;
681678
682679 fn handle_message (
683- & self , message : Self :: ProtocolMessage , counterparty_node_id : & PublicKey ,
680+ & self , message : Self :: ProtocolMessage , lsp_node_id : & PublicKey ,
684681 ) -> Result < ( ) , LightningError > {
685- self . handle_message ( message, counterparty_node_id )
682+ self . handle_message ( message, lsp_node_id )
686683 }
687684}
688685
@@ -754,11 +751,13 @@ mod tests {
754751 #[ test]
755752 fn test_pending_request_tracking ( ) {
756753 let ( client, _, _, peer, _) = setup_test_client ( ) ;
757-
754+ const APP_NAME : & str = "test-app" ;
755+ const WEBHOOK_URL : & str = "https://example.com/hook" ;
756+ let lsps5_app_name = Lsps5AppName :: new ( APP_NAME . to_string ( ) ) . unwrap ( ) ;
757+ let lsps5_webhook_url = Lsps5WebhookUrl :: new ( WEBHOOK_URL . to_string ( ) ) . unwrap ( ) ;
758758 // Create various requests
759- let set_req_id = client
760- . set_webhook ( peer, "test-app" . to_string ( ) , "https://example.com/hook" . to_string ( ) )
761- . unwrap ( ) ;
759+ let set_req_id =
760+ client. set_webhook ( peer, APP_NAME . to_string ( ) , WEBHOOK_URL . to_string ( ) ) . unwrap ( ) ;
762761 let list_req_id = client. list_webhooks ( peer) . unwrap ( ) ;
763762 let remove_req_id = client. remove_webhook ( peer, "test-app" . to_string ( ) ) . unwrap ( ) ;
764763
@@ -771,8 +770,8 @@ mod tests {
771770 assert_eq ! (
772771 peer_state. pending_set_webhook_requests. get( & set_req_id) . unwrap( ) ,
773772 & (
774- "test-app" . to_string ( ) ,
775- "https://example.com/hook" . to_string ( ) ,
773+ lsps5_app_name . clone ( ) ,
774+ lsps5_webhook_url ,
776775 peer_state. pending_set_webhook_requests. get( & set_req_id) . unwrap( ) . 2 . clone( )
777776 )
778777 ) ;
@@ -783,7 +782,7 @@ mod tests {
783782 // Check remove_webhook tracking
784783 assert_eq ! (
785784 peer_state. pending_remove_webhook_requests. get( & remove_req_id) . unwrap( ) . 0 ,
786- "test-app"
785+ lsps5_app_name
787786 ) ;
788787 }
789788 }
@@ -825,6 +824,12 @@ mod tests {
825824
826825 #[ test]
827826 fn test_cleanup_expired_responses ( ) {
827+ const OLD_APP_NAME : & str = "test-app-old" ;
828+ const NEW_APP_NAME : & str = "test-app-new" ;
829+ const WEBHOOK_URL : & str = "https://example.com/hook" ;
830+ let lsps5_old_app_name = Lsps5AppName :: new ( OLD_APP_NAME . to_string ( ) ) . unwrap ( ) ;
831+ let lsps5_new_app_name = Lsps5AppName :: new ( NEW_APP_NAME . to_string ( ) ) . unwrap ( ) ;
832+ let lsps5_webhook_url = Lsps5WebhookUrl :: new ( WEBHOOK_URL . to_string ( ) ) . unwrap ( ) ;
828833 // The current time for setting request timestamps
829834 let now = LSPSDateTime :: now ( ) ;
830835 // Create a mock PeerState with a very old cleanup time
@@ -839,8 +844,8 @@ mod tests {
839844 peer_state. pending_set_webhook_requests . insert (
840845 old_request_id. clone ( ) ,
841846 (
842- "test-app-old" . to_string ( ) ,
843- "https://example.com/hook" . to_string ( ) ,
847+ lsps5_old_app_name ,
848+ lsps5_webhook_url . clone ( ) ,
844849 now. checked_sub_signed ( Duration :: seconds ( 7200 ) ) . unwrap ( ) ,
845850 ) , // 2 hours old
846851 ) ;
@@ -849,8 +854,8 @@ mod tests {
849854 peer_state. pending_set_webhook_requests . insert (
850855 new_request_id. clone ( ) ,
851856 (
852- "test-app-new" . to_string ( ) ,
853- "https://example.com/hook" . to_string ( ) ,
857+ lsps5_new_app_name ,
858+ lsps5_webhook_url ,
854859 now. checked_sub_signed ( Duration :: seconds ( 600 ) ) . unwrap ( ) ,
855860 ) , // 10 minutes old
856861 ) ;
0 commit comments