Skip to content
This repository was archived by the owner on Jan 6, 2025. It is now read-only.

Commit 6c5d4a2

Browse files
authored
Merge pull request #125 from tnull/2024-03-fix-deadlock
Fix more potential deadlock scenarios
2 parents f200eb2 + 6b7b875 commit 6c5d4a2

File tree

4 files changed

+439
-371
lines changed

4 files changed

+439
-371
lines changed

src/lsps1/client.rs

+106-84
Original file line numberDiff line numberDiff line change
@@ -243,20 +243,21 @@ where
243243
pub fn send_get_info_request(&self, counterparty_node_id: PublicKey, user_channel_id: u128) {
244244
let channel = InboundCRChannel::new(user_channel_id);
245245

246-
let mut outer_state_lock = self.per_peer_state.write().unwrap();
247-
let inner_state_lock = outer_state_lock
248-
.entry(counterparty_node_id)
249-
.or_insert(Mutex::new(PeerState::default()));
250-
let mut peer_state_lock = inner_state_lock.lock().unwrap();
251-
peer_state_lock.insert_inbound_channel(user_channel_id, channel);
252-
253246
let request_id = crate::utils::generate_request_id(&self.entropy_source);
254-
peer_state_lock.insert_request(request_id.clone(), user_channel_id);
247+
{
248+
let mut outer_state_lock = self.per_peer_state.write().unwrap();
249+
let inner_state_lock = outer_state_lock
250+
.entry(counterparty_node_id)
251+
.or_insert(Mutex::new(PeerState::default()));
252+
let mut peer_state_lock = inner_state_lock.lock().unwrap();
253+
peer_state_lock.insert_inbound_channel(user_channel_id, channel);
254+
255+
peer_state_lock.insert_request(request_id.clone(), user_channel_id);
256+
}
255257

256-
self.pending_messages.enqueue(
257-
&counterparty_node_id,
258-
LSPS1Message::Request(request_id, LSPS1Request::GetInfo(GetInfoRequest {})).into(),
259-
);
258+
let request = LSPS1Request::GetInfo(GetInfoRequest {});
259+
let msg = LSPS1Message::Request(request_id, request).into();
260+
self.pending_messages.enqueue(&counterparty_node_id, msg);
260261
}
261262

262263
fn handle_get_info_response(
@@ -360,46 +361,55 @@ where
360361
pub fn place_order(
361362
&self, user_channel_id: u128, counterparty_node_id: &PublicKey, order: OrderParams,
362363
) -> Result<(), APIError> {
363-
let outer_state_lock = self.per_peer_state.write().unwrap();
364-
365-
match outer_state_lock.get(counterparty_node_id) {
366-
Some(inner_state_lock) => {
367-
let mut peer_state_lock = inner_state_lock.lock().unwrap();
368-
369-
let inbound_channel = peer_state_lock
370-
.inbound_channels_by_id
371-
.get_mut(&user_channel_id)
372-
.ok_or(APIError::APIMisuseError {
373-
err: format!("Channel with user_channel_id {} not found", user_channel_id),
374-
})?;
375-
376-
match inbound_channel.order_requested(order.clone()) {
377-
Ok(()) => (),
378-
Err(e) => {
379-
peer_state_lock.remove_inbound_channel(user_channel_id);
380-
return Err(APIError::APIMisuseError { err: e.err });
381-
},
382-
};
364+
let (result, request_msg) = {
365+
let outer_state_lock = self.per_peer_state.write().unwrap();
366+
367+
match outer_state_lock.get(counterparty_node_id) {
368+
Some(inner_state_lock) => {
369+
let mut peer_state_lock = inner_state_lock.lock().unwrap();
370+
371+
let inbound_channel = peer_state_lock
372+
.inbound_channels_by_id
373+
.get_mut(&user_channel_id)
374+
.ok_or(APIError::APIMisuseError {
375+
err: format!(
376+
"Channel with user_channel_id {} not found",
377+
user_channel_id
378+
),
379+
})?;
380+
381+
match inbound_channel.order_requested(order.clone()) {
382+
Ok(()) => (),
383+
Err(e) => {
384+
peer_state_lock.remove_inbound_channel(user_channel_id);
385+
return Err(APIError::APIMisuseError { err: e.err });
386+
},
387+
};
383388

384-
let request_id = crate::utils::generate_request_id(&self.entropy_source);
385-
peer_state_lock.insert_request(request_id.clone(), user_channel_id);
389+
let request_id = crate::utils::generate_request_id(&self.entropy_source);
390+
let request = LSPS1Request::CreateOrder(CreateOrderRequest { order });
391+
let msg = LSPS1Message::Request(request_id.clone(), request).into();
392+
peer_state_lock.insert_request(request_id, user_channel_id);
386393

387-
self.pending_messages.enqueue(
388-
counterparty_node_id,
389-
LSPS1Message::Request(
390-
request_id,
391-
LSPS1Request::CreateOrder(CreateOrderRequest { order }),
392-
)
393-
.into(),
394-
);
395-
},
396-
None => {
397-
return Err(APIError::APIMisuseError {
398-
err: format!("No existing state with counterparty {}", counterparty_node_id),
399-
})
400-
},
394+
(Ok(()), Some(msg))
395+
},
396+
None => (
397+
Err(APIError::APIMisuseError {
398+
err: format!(
399+
"No existing state with counterparty {}",
400+
counterparty_node_id
401+
),
402+
}),
403+
None,
404+
),
405+
}
406+
};
407+
408+
if let Some(msg) = request_msg {
409+
self.pending_messages.enqueue(&counterparty_node_id, msg);
401410
}
402-
Ok(())
411+
412+
result
403413
}
404414

405415
fn handle_create_order_response(
@@ -518,44 +528,56 @@ where
518528
pub fn check_order_status(
519529
&self, counterparty_node_id: &PublicKey, order_id: OrderId, user_channel_id: u128,
520530
) -> Result<(), APIError> {
521-
let outer_state_lock = self.per_peer_state.write().unwrap();
522-
match outer_state_lock.get(&counterparty_node_id) {
523-
Some(inner_state_lock) => {
524-
let mut peer_state_lock = inner_state_lock.lock().unwrap();
525-
526-
if let Some(inbound_channel) =
527-
peer_state_lock.inbound_channels_by_id.get_mut(&user_channel_id)
528-
{
529-
if let Err(e) = inbound_channel.pay_for_channel(user_channel_id) {
530-
peer_state_lock.remove_inbound_channel(user_channel_id);
531-
return Err(APIError::APIMisuseError { err: e.err });
532-
}
533-
534-
let request_id = crate::utils::generate_request_id(&self.entropy_source);
535-
peer_state_lock.insert_request(request_id.clone(), user_channel_id);
536-
537-
self.pending_messages.enqueue(
538-
counterparty_node_id,
539-
LSPS1Message::Request(
540-
request_id,
541-
LSPS1Request::GetOrder(GetOrderRequest { order_id: order_id.clone() }),
531+
let (result, request_msg) = {
532+
let outer_state_lock = self.per_peer_state.write().unwrap();
533+
match outer_state_lock.get(&counterparty_node_id) {
534+
Some(inner_state_lock) => {
535+
let mut peer_state_lock = inner_state_lock.lock().unwrap();
536+
537+
if let Some(inbound_channel) =
538+
peer_state_lock.inbound_channels_by_id.get_mut(&user_channel_id)
539+
{
540+
if let Err(e) = inbound_channel.pay_for_channel(user_channel_id) {
541+
peer_state_lock.remove_inbound_channel(user_channel_id);
542+
return Err(APIError::APIMisuseError { err: e.err });
543+
}
544+
545+
let request_id = crate::utils::generate_request_id(&self.entropy_source);
546+
peer_state_lock.insert_request(request_id.clone(), user_channel_id);
547+
548+
let request =
549+
LSPS1Request::GetOrder(GetOrderRequest { order_id: order_id.clone() });
550+
let msg = LSPS1Message::Request(request_id, request).into();
551+
(Ok(()), Some(msg))
552+
} else {
553+
(
554+
Err(APIError::APIMisuseError {
555+
err: format!(
556+
"Channel with user_channel_id {} not found",
557+
user_channel_id
558+
),
559+
}),
560+
None,
542561
)
543-
.into(),
544-
);
545-
} else {
546-
return Err(APIError::APIMisuseError {
547-
err: format!("Channel with user_channel_id {} not found", user_channel_id),
548-
});
549-
}
550-
},
551-
None => {
552-
return Err(APIError::APIMisuseError {
553-
err: format!("No existing state with counterparty {}", counterparty_node_id),
554-
})
555-
},
562+
}
563+
},
564+
None => (
565+
Err(APIError::APIMisuseError {
566+
err: format!(
567+
"No existing state with counterparty {}",
568+
counterparty_node_id
569+
),
570+
}),
571+
None,
572+
),
573+
}
574+
};
575+
576+
if let Some(msg) = request_msg {
577+
self.pending_messages.enqueue(&counterparty_node_id, msg);
556578
}
557579

558-
Ok(())
580+
result
559581
}
560582

561583
fn handle_get_order_response(

0 commit comments

Comments
 (0)