Skip to content

Commit cf23e91

Browse files
Remove peerState if there are no pending requests with that peer
1 parent 9ab2d27 commit cf23e91

File tree

1 file changed

+97
-30
lines changed

1 file changed

+97
-30
lines changed

lightning-liquidity/src/lsps5/client.rs

Lines changed: 97 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ impl PeerState {
9595
None
9696
}
9797
}
98+
99+
fn is_empty(&self) -> bool {
100+
self.pending_set_webhook_requests.is_empty()
101+
&& self.pending_list_webhooks_requests.is_empty()
102+
&& self.pending_remove_webhook_requests.is_empty()
103+
}
98104
}
99105

100106
/// Client-side handler for the LSPS5 (bLIP-55) webhook registration protocol.
@@ -389,8 +395,26 @@ where
389395
}
390396
};
391397
self.with_peer_state(*counterparty_node_id, handle_response);
398+
399+
self.check_and_remove_empty_peer_state(counterparty_node_id);
400+
392401
result
393402
}
403+
404+
fn check_and_remove_empty_peer_state(&self, counterparty_node_id: &PublicKey) {
405+
let mut outer_state_lock = self.per_peer_state.write().unwrap();
406+
let should_remove =
407+
if let Some(peer_state_mutex) = outer_state_lock.get(counterparty_node_id) {
408+
let peer_state = peer_state_mutex.lock().unwrap();
409+
peer_state.is_empty()
410+
} else {
411+
false
412+
};
413+
414+
if should_remove {
415+
outer_state_lock.remove(counterparty_node_id);
416+
}
417+
}
394418
}
395419

396420
impl<ES: Deref> LSPSProtocolMessageHandler for LSPS5ClientHandler<ES>
@@ -515,36 +539,6 @@ mod tests {
515539
}
516540
}
517541

518-
#[test]
519-
fn test_handle_response_clears_pending_state() {
520-
let (client, _, _, peer, _) = setup_test_client();
521-
522-
let req_id = client
523-
.set_webhook(peer, "test-app".to_string(), "https://example.com/hook".to_string())
524-
.unwrap();
525-
526-
let response = LSPS5Response::SetWebhook(SetWebhookResponse {
527-
num_webhooks: 1,
528-
max_webhooks: 5,
529-
no_change: false,
530-
});
531-
let response_msg = LSPS5Message::Response(req_id.clone(), response);
532-
533-
{
534-
let outer_state_lock = client.per_peer_state.read().unwrap();
535-
let peer_state = outer_state_lock.get(&peer).unwrap().lock().unwrap();
536-
assert!(peer_state.pending_set_webhook_requests.contains_key(&req_id));
537-
}
538-
539-
client.handle_message(response_msg, &peer).unwrap();
540-
541-
{
542-
let outer_state_lock = client.per_peer_state.read().unwrap();
543-
let peer_state = outer_state_lock.get(&peer).unwrap().lock().unwrap();
544-
assert!(!peer_state.pending_set_webhook_requests.contains_key(&req_id));
545-
}
546-
}
547-
548542
#[test]
549543
fn test_unknown_request_id_handling() {
550544
let (client, _message_queue, _, peer, _) = setup_test_client();
@@ -612,4 +606,77 @@ mod tests {
612606
.any(|(id, _)| id == &new_req_id));
613607
}
614608
}
609+
610+
#[test]
611+
fn test_peer_state_cleanup_and_recreation() {
612+
let (client, _, _, peer, _) = setup_test_client();
613+
614+
let set_webhook_req_id = client
615+
.set_webhook(peer, "test-app".to_string(), "https://example.com/hook".to_string())
616+
.unwrap();
617+
618+
let list_webhooks_req_id = client.list_webhooks(peer);
619+
620+
{
621+
let state = client.per_peer_state.read().unwrap();
622+
assert!(state.contains_key(&peer));
623+
let peer_state = state.get(&peer).unwrap().lock().unwrap();
624+
assert!(peer_state
625+
.pending_set_webhook_requests
626+
.iter()
627+
.any(|(id, _)| id == &set_webhook_req_id));
628+
assert!(peer_state.pending_list_webhooks_requests.contains(&list_webhooks_req_id));
629+
}
630+
631+
let set_webhook_response = LSPS5Response::SetWebhook(SetWebhookResponse {
632+
num_webhooks: 1,
633+
max_webhooks: 5,
634+
no_change: false,
635+
});
636+
let response_msg = LSPS5Message::Response(set_webhook_req_id.clone(), set_webhook_response);
637+
// trigger cleanup but there is still a pending request
638+
// so the peer state should not be removed
639+
client.handle_message(response_msg, &peer).unwrap();
640+
641+
{
642+
let state = client.per_peer_state.read().unwrap();
643+
assert!(state.contains_key(&peer));
644+
let peer_state = state.get(&peer).unwrap().lock().unwrap();
645+
assert!(!peer_state
646+
.pending_set_webhook_requests
647+
.iter()
648+
.any(|(id, _)| id == &set_webhook_req_id));
649+
assert!(peer_state.pending_list_webhooks_requests.contains(&list_webhooks_req_id));
650+
}
651+
652+
let list_webhooks_response =
653+
LSPS5Response::ListWebhooks(crate::lsps5::msgs::ListWebhooksResponse {
654+
app_names: vec![],
655+
max_webhooks: 5,
656+
});
657+
let response_msg = LSPS5Message::Response(list_webhooks_req_id, list_webhooks_response);
658+
659+
// now the pending request is handled, so the peer state should be removed
660+
client.handle_message(response_msg, &peer).unwrap();
661+
662+
{
663+
let state = client.per_peer_state.read().unwrap();
664+
assert!(!state.contains_key(&peer));
665+
}
666+
667+
// check that it's possible to recreate the peer state by sending a new request
668+
let new_req_id = client
669+
.set_webhook(peer, "test-app-2".to_string(), "https://example.com/hook2".to_string())
670+
.unwrap();
671+
672+
{
673+
let state = client.per_peer_state.read().unwrap();
674+
assert!(state.contains_key(&peer));
675+
let peer_state = state.get(&peer).unwrap().lock().unwrap();
676+
assert!(peer_state
677+
.pending_set_webhook_requests
678+
.iter()
679+
.any(|(id, _)| id == &new_req_id));
680+
}
681+
}
615682
}

0 commit comments

Comments
 (0)