Skip to content

Commit ff9840e

Browse files
Avoid unnecessary immediate retake per_peer_state lock
1 parent b8ca7c9 commit ff9840e

File tree

1 file changed

+55
-63
lines changed

1 file changed

+55
-63
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 55 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,12 +1515,19 @@ where
15151515
return Err(APIError::APIMisuseError { err: format!("Channel value must be at least 1000 satoshis. It was {}", channel_value_satoshis) });
15161516
}
15171517

1518-
let channel = {
1519-
let per_peer_state = self.per_peer_state.read().unwrap();
1520-
match per_peer_state.get(&their_network_key) {
1521-
Some(peer_state) => {
1518+
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
1519+
// We want to make sure the lock is actually acquired by PersistenceNotifierGuard.
1520+
debug_assert!(&self.total_consistency_lock.try_write().is_err());
1521+
1522+
let mut channel_state = self.channel_state.lock().unwrap();
1523+
let per_peer_state = self.per_peer_state.read().unwrap();
1524+
1525+
match per_peer_state.get(&their_network_key) {
1526+
None => return Err(APIError::ChannelUnavailable { err: format!("Not connected to node: {}", their_network_key) }),
1527+
Some(peer_state_mutex) => {
1528+
let mut peer_state = peer_state_mutex.lock().unwrap();
1529+
let channel = {
15221530
let outbound_scid_alias = self.create_and_insert_outbound_scid_alias();
1523-
let peer_state = peer_state.lock().unwrap();
15241531
let their_features = &peer_state.latest_features;
15251532
let config = if override_config.is_some() { override_config.as_ref().unwrap() } else { &self.default_configuration };
15261533
match Channel::new_outbound(&self.fee_estimator, &self.keys_manager, their_network_key,
@@ -1533,38 +1540,28 @@ where
15331540
return Err(e);
15341541
},
15351542
}
1536-
},
1537-
None => return Err(APIError::ChannelUnavailable { err: format!("Not connected to node: {}", their_network_key) }),
1538-
}
1539-
};
1540-
let res = channel.get_open_channel(self.genesis_hash.clone());
1541-
1542-
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
1543-
// We want to make sure the lock is actually acquired by PersistenceNotifierGuard.
1544-
debug_assert!(&self.total_consistency_lock.try_write().is_err());
1543+
};
1544+
let res = channel.get_open_channel(self.genesis_hash.clone());
15451545

1546-
let temporary_channel_id = channel.channel_id();
1547-
let mut channel_state = self.channel_state.lock().unwrap();
1548-
let per_peer_state = self.per_peer_state.read().unwrap();
1549-
if let Some(peer_state_mutex) = per_peer_state.get(&their_network_key){
1550-
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
1551-
let peer_state = &mut *peer_state_lock;
1552-
match peer_state.channel_by_id.entry(temporary_channel_id) {
1553-
hash_map::Entry::Occupied(_) => {
1554-
if cfg!(fuzzing) {
1555-
return Err(APIError::APIMisuseError { err: "Fuzzy bad RNG".to_owned() });
1556-
} else {
1557-
panic!("RNG is bad???");
1546+
let temporary_channel_id = channel.channel_id();
1547+
match peer_state.channel_by_id.entry(temporary_channel_id) {
1548+
hash_map::Entry::Occupied(_) => {
1549+
if cfg!(fuzzing) {
1550+
return Err(APIError::APIMisuseError { err: "Fuzzy bad RNG".to_owned() });
1551+
} else {
1552+
panic!("RNG is bad???");
1553+
}
1554+
},
1555+
hash_map::Entry::Vacant(entry) => { entry.insert(channel); }
15581556
}
1557+
1558+
channel_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
1559+
node_id: their_network_key,
1560+
msg: res,
1561+
});
1562+
Ok(temporary_channel_id)
15591563
},
1560-
hash_map::Entry::Vacant(entry) => { entry.insert(channel); }
1561-
}
1562-
} else { return Err(APIError::ChannelUnavailable { err: format!("Not connected to node: {}", their_network_key) }) }
1563-
channel_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
1564-
node_id: their_network_key,
1565-
msg: res,
1566-
});
1567-
Ok(temporary_channel_id)
1564+
}
15681565
}
15691566

15701567
fn list_channels_with_filter<Fn: FnMut(&(&[u8; 32], &Channel<<K::Target as SignerProvider>::Signer>)) -> bool + Copy>(&self, f: Fn) -> Vec<ChannelDetails> {
@@ -2533,12 +2530,13 @@ where
25332530
fn funding_transaction_generated_intern<FundingOutput: Fn(&Channel<<K::Target as SignerProvider>::Signer>, &Transaction) -> Result<OutPoint, APIError>>(
25342531
&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, funding_transaction: Transaction, find_funding_output: FundingOutput
25352532
) -> Result<(), APIError> {
2536-
let (chan, msg) = {
2537-
let (res, chan) = {
2538-
let per_peer_state = self.per_peer_state.read().unwrap();
2539-
if let Some(peer_state_mutex) = per_peer_state.get(counterparty_node_id) {
2540-
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
2541-
let peer_state = &mut *peer_state_lock;
2533+
let mut channel_state = self.channel_state.lock().unwrap();
2534+
let per_peer_state = self.per_peer_state.read().unwrap();
2535+
if let Some(peer_state_mutex) = per_peer_state.get(counterparty_node_id) {
2536+
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
2537+
let peer_state = &mut *peer_state_lock;
2538+
let (chan, msg) = {
2539+
let (res, chan) = {
25422540
match peer_state.channel_by_id.remove(temporary_channel_id) {
25432541
Some(mut chan) => {
25442542
let funding_txo = find_funding_output(&chan, &funding_transaction)?;
@@ -2551,30 +2549,22 @@ where
25512549
},
25522550
None => { return Err(APIError::ChannelUnavailable { err: "No such channel".to_owned() }) },
25532551
}
2554-
} else {
2555-
return Err(APIError::APIMisuseError { err: format!("Can't find a peer with a node_id matching the passed counterparty_node_id {}", counterparty_node_id) })
2552+
};
2553+
match handle_error!(self, res, chan.get_counterparty_node_id()) {
2554+
Ok(funding_msg) => {
2555+
(chan, funding_msg)
2556+
},
2557+
Err(_) => { return Err(APIError::ChannelUnavailable {
2558+
err: "Error deriving keys or signing initial commitment transactions - either our RNG or our counterparty's RNG is broken or the Signer refused to sign".to_owned()
2559+
}) },
25562560
}
25572561
};
2558-
match handle_error!(self, res, chan.get_counterparty_node_id()) {
2559-
Ok(funding_msg) => {
2560-
(chan, funding_msg)
2561-
},
2562-
Err(_) => { return Err(APIError::ChannelUnavailable {
2563-
err: "Error deriving keys or signing initial commitment transactions - either our RNG or our counterparty's RNG is broken or the Signer refused to sign".to_owned()
2564-
}) },
2565-
}
2566-
};
25672562

2568-
let mut channel_state = self.channel_state.lock().unwrap();
2569-
channel_state.pending_msg_events.push(events::MessageSendEvent::SendFundingCreated {
2570-
node_id: chan.get_counterparty_node_id(),
2571-
msg,
2572-
});
2573-
mem::drop(channel_state);
2574-
let per_peer_state = self.per_peer_state.read().unwrap();
2575-
if let Some(peer_state_mutex) = per_peer_state.get(counterparty_node_id) {
2576-
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
2577-
let peer_state = &mut *peer_state_lock;
2563+
channel_state.pending_msg_events.push(events::MessageSendEvent::SendFundingCreated {
2564+
node_id: chan.get_counterparty_node_id(),
2565+
msg,
2566+
});
2567+
mem::drop(channel_state);
25782568
match peer_state.channel_by_id.entry(chan.channel_id()) {
25792569
hash_map::Entry::Occupied(_) => {
25802570
panic!("Generated duplicate funding txid?");
@@ -2587,8 +2577,10 @@ where
25872577
e.insert(chan);
25882578
}
25892579
}
2590-
} else { return Err(APIError::ChannelUnavailable { err: format!("Peer with counterparty_node_id {} disconnected and closed the channel", counterparty_node_id) }) }
2591-
Ok(())
2580+
Ok(())
2581+
} else {
2582+
return Err(APIError::APIMisuseError { err: format!("Can't find a peer with a node_id matching the passed counterparty_node_id {}", counterparty_node_id) })
2583+
}
25922584
}
25932585

25942586
#[cfg(test)]

0 commit comments

Comments
 (0)