Skip to content

Commit b0218a4

Browse files
Cache peers in Flow
In upcoming commits, we'll move to creating multi-hop blinded paths during the process of creating a revoke_and_ack message within the Channel struct. These paths will be included in said RAA to be used as reply paths for often-offline senders held_htlc_available messages. Because we hold the per-peer lock corresponding to the Channel while creating this RAA, we can't use our typical approach of calling ChannelManager::get_peers_for_blinded_path to create these blinded paths. The ::get_peers method takes each peer's lock in turn in order to check for usable channels/onion message feature support, and it's not permitted to hold multiple peer state locks at the same time due to the potential for deadlocks (see the debug_sync module). To avoid taking other peer state locks while holding a particular Channel's peer state lock, here we cache the set of peers in the OffersMessageFlow, which is the struct that ultimately creates the blinded paths for the RAA.
1 parent c2e3ae0 commit b0218a4

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8077,6 +8077,8 @@ where
80778077

80788078
should_persist
80798079
});
8080+
8081+
self.flow.set_peers(self.get_peers_for_blinded_path());
80808082
}
80818083

80828084
/// Indicates that the preimage for payment_hash is unknown or the received amount is incorrect
@@ -10427,16 +10429,20 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1042710429
emit_initial_channel_ready_event!(pending_events, chan);
1042810430
}
1042910431

10430-
Ok(())
1043110432
} else {
1043210433
try_channel_entry!(self, peer_state, Err(ChannelError::close(
1043310434
"Got a channel_ready message for an unfunded channel!".into())), chan_entry)
1043410435
}
1043510436
},
1043610437
hash_map::Entry::Vacant(_) => {
10437-
Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
10438+
return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
1043810439
}
1043910440
}
10441+
core::mem::drop(peer_state_lock);
10442+
core::mem::drop(per_peer_state);
10443+
10444+
self.flow.set_peers(self.get_peers_for_blinded_path());
10445+
Ok(())
1044010446
}
1044110447

1044210448
fn internal_shutdown(
@@ -10530,6 +10536,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1053010536
self.fail_htlc_backwards_internal(&source, &hash, &reason, receiver, None);
1053110537
}
1053210538

10539+
self.flow.set_peers(self.get_peers_for_blinded_path());
1053310540
Ok(())
1053410541
}
1053510542

@@ -13391,6 +13398,8 @@ where
1339113398
for (err, counterparty_node_id) in failed_channels.drain(..) {
1339213399
let _ = handle_error!(self, err, counterparty_node_id);
1339313400
}
13401+
13402+
self.flow.set_peers(self.get_peers_for_blinded_path());
1339413403
}
1339513404

1339613405
#[rustfmt::skip]
@@ -13503,6 +13512,7 @@ where
1350313512
// until we have some peer connection(s) to receive onion messages over, so as a minor optimization
1350413513
// refresh the cache when a peer connects.
1350513514
self.check_refresh_async_receive_offer_cache(false);
13515+
self.flow.set_peers(self.get_peers_for_blinded_path());
1350613516
res
1350713517
}
1350813518

lightning/src/offers/flow.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ where
100100

101101
pending_async_payments_messages: Mutex<Vec<(AsyncPaymentsMessage, MessageSendInstructions)>>,
102102
async_receive_offer_cache: Mutex<AsyncReceiveOfferCache>,
103+
peers_cache: Mutex<Vec<MessageForwardNode>>,
103104

104105
#[cfg(feature = "dnssec")]
105106
pub(crate) hrn_resolver: OMNameResolver,
@@ -136,6 +137,7 @@ where
136137

137138
pending_offers_messages: Mutex::new(Vec::new()),
138139
pending_async_payments_messages: Mutex::new(Vec::new()),
140+
peers_cache: Mutex::new(Vec::new()),
139141

140142
#[cfg(feature = "dnssec")]
141143
hrn_resolver: OMNameResolver::new(current_timestamp, best_block.height),
@@ -1739,4 +1741,15 @@ where
17391741
pub fn writeable_async_receive_offer_cache(&self) -> Vec<u8> {
17401742
self.async_receive_offer_cache.encode()
17411743
}
1744+
1745+
/// Provides a set of connected peers of this node that can be used in [`BlindedMessagePath`]s
1746+
/// created by the [`OffersMessageFlow`].
1747+
///
1748+
/// All provided peers MUST advertise support for onion messages in their [`InitFeatures`].
1749+
///
1750+
/// [`InitFeatures`]: crate::types::features::InitFeatures
1751+
pub fn set_peers(&self, mut peers: Vec<MessageForwardNode>) {
1752+
let mut peers_cache = self.peers_cache.lock().unwrap();
1753+
core::mem::swap(&mut *peers_cache, &mut peers);
1754+
}
17421755
}

0 commit comments

Comments
 (0)