mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-24 15:02:20 +01:00
Add list_channels_by_counterparty
method
While we already provide a `list_channels` method, it could result in quite a large `Vec<ChannelDetails>`. Here, we provide the means to query our channels by `counterparty_node_id` and DRY up the code.
This commit is contained in:
parent
d355ce1b78
commit
8419d13d4c
1 changed files with 76 additions and 48 deletions
|
@ -53,7 +53,7 @@ use crate::ln::msgs::{ChannelMessageHandler, DecodeError, LightningError, MAX_VA
|
|||
use crate::ln::outbound_payment;
|
||||
use crate::ln::outbound_payment::{OutboundPayments, PaymentAttempts, PendingOutboundPayment};
|
||||
use crate::ln::wire::Encode;
|
||||
use crate::chain::keysinterface::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider, ChannelSigner};
|
||||
use crate::chain::keysinterface::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider, ChannelSigner, WriteableEcdsaChannelSigner};
|
||||
use crate::util::config::{UserConfig, ChannelConfig};
|
||||
use crate::util::events::{Event, EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination};
|
||||
use crate::util::events;
|
||||
|
@ -1229,6 +1229,55 @@ impl ChannelDetails {
|
|||
pub fn get_outbound_payment_scid(&self) -> Option<u64> {
|
||||
self.short_channel_id.or(self.outbound_scid_alias)
|
||||
}
|
||||
|
||||
fn from_channel<Signer: WriteableEcdsaChannelSigner>(channel: &Channel<Signer>,
|
||||
best_block_height: u32, latest_features: InitFeatures) -> Self {
|
||||
|
||||
let balance = channel.get_available_balances();
|
||||
let (to_remote_reserve_satoshis, to_self_reserve_satoshis) =
|
||||
channel.get_holder_counterparty_selected_channel_reserve_satoshis();
|
||||
ChannelDetails {
|
||||
channel_id: channel.channel_id(),
|
||||
counterparty: ChannelCounterparty {
|
||||
node_id: channel.get_counterparty_node_id(),
|
||||
features: latest_features,
|
||||
unspendable_punishment_reserve: to_remote_reserve_satoshis,
|
||||
forwarding_info: channel.counterparty_forwarding_info(),
|
||||
// Ensures that we have actually received the `htlc_minimum_msat` value
|
||||
// from the counterparty through the `OpenChannel` or `AcceptChannel`
|
||||
// message (as they are always the first message from the counterparty).
|
||||
// Else `Channel::get_counterparty_htlc_minimum_msat` could return the
|
||||
// default `0` value set by `Channel::new_outbound`.
|
||||
outbound_htlc_minimum_msat: if channel.have_received_message() {
|
||||
Some(channel.get_counterparty_htlc_minimum_msat()) } else { None },
|
||||
outbound_htlc_maximum_msat: channel.get_counterparty_htlc_maximum_msat(),
|
||||
},
|
||||
funding_txo: channel.get_funding_txo(),
|
||||
// Note that accept_channel (or open_channel) is always the first message, so
|
||||
// `have_received_message` indicates that type negotiation has completed.
|
||||
channel_type: if channel.have_received_message() { Some(channel.get_channel_type().clone()) } else { None },
|
||||
short_channel_id: channel.get_short_channel_id(),
|
||||
outbound_scid_alias: if channel.is_usable() { Some(channel.outbound_scid_alias()) } else { None },
|
||||
inbound_scid_alias: channel.latest_inbound_scid_alias(),
|
||||
channel_value_satoshis: channel.get_value_satoshis(),
|
||||
unspendable_punishment_reserve: to_self_reserve_satoshis,
|
||||
balance_msat: balance.balance_msat,
|
||||
inbound_capacity_msat: balance.inbound_capacity_msat,
|
||||
outbound_capacity_msat: balance.outbound_capacity_msat,
|
||||
next_outbound_htlc_limit_msat: balance.next_outbound_htlc_limit_msat,
|
||||
user_channel_id: channel.get_user_id(),
|
||||
confirmations_required: channel.minimum_depth(),
|
||||
confirmations: Some(channel.get_funding_tx_confirmations(best_block_height)),
|
||||
force_close_spend_delay: channel.get_counterparty_selected_contest_delay(),
|
||||
is_outbound: channel.is_outbound(),
|
||||
is_channel_ready: channel.is_usable(),
|
||||
is_usable: channel.is_live(),
|
||||
is_public: channel.should_announce(),
|
||||
inbound_htlc_minimum_msat: Some(channel.get_holder_htlc_minimum_msat()),
|
||||
inbound_htlc_maximum_msat: channel.get_holder_htlc_maximum_msat(),
|
||||
config: Some(channel.config()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Used by [`ChannelManager::list_recent_payments`] to express the status of recent payments.
|
||||
|
@ -1716,51 +1765,10 @@ where
|
|||
for (_cp_id, peer_state_mutex) in per_peer_state.iter() {
|
||||
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
|
||||
let peer_state = &mut *peer_state_lock;
|
||||
for (channel_id, channel) in peer_state.channel_by_id.iter().filter(f) {
|
||||
let balance = channel.get_available_balances();
|
||||
let (to_remote_reserve_satoshis, to_self_reserve_satoshis) =
|
||||
channel.get_holder_counterparty_selected_channel_reserve_satoshis();
|
||||
res.push(ChannelDetails {
|
||||
channel_id: (*channel_id).clone(),
|
||||
counterparty: ChannelCounterparty {
|
||||
node_id: channel.get_counterparty_node_id(),
|
||||
features: peer_state.latest_features.clone(),
|
||||
unspendable_punishment_reserve: to_remote_reserve_satoshis,
|
||||
forwarding_info: channel.counterparty_forwarding_info(),
|
||||
// Ensures that we have actually received the `htlc_minimum_msat` value
|
||||
// from the counterparty through the `OpenChannel` or `AcceptChannel`
|
||||
// message (as they are always the first message from the counterparty).
|
||||
// Else `Channel::get_counterparty_htlc_minimum_msat` could return the
|
||||
// default `0` value set by `Channel::new_outbound`.
|
||||
outbound_htlc_minimum_msat: if channel.have_received_message() {
|
||||
Some(channel.get_counterparty_htlc_minimum_msat()) } else { None },
|
||||
outbound_htlc_maximum_msat: channel.get_counterparty_htlc_maximum_msat(),
|
||||
},
|
||||
funding_txo: channel.get_funding_txo(),
|
||||
// Note that accept_channel (or open_channel) is always the first message, so
|
||||
// `have_received_message` indicates that type negotiation has completed.
|
||||
channel_type: if channel.have_received_message() { Some(channel.get_channel_type().clone()) } else { None },
|
||||
short_channel_id: channel.get_short_channel_id(),
|
||||
outbound_scid_alias: if channel.is_usable() { Some(channel.outbound_scid_alias()) } else { None },
|
||||
inbound_scid_alias: channel.latest_inbound_scid_alias(),
|
||||
channel_value_satoshis: channel.get_value_satoshis(),
|
||||
unspendable_punishment_reserve: to_self_reserve_satoshis,
|
||||
balance_msat: balance.balance_msat,
|
||||
inbound_capacity_msat: balance.inbound_capacity_msat,
|
||||
outbound_capacity_msat: balance.outbound_capacity_msat,
|
||||
next_outbound_htlc_limit_msat: balance.next_outbound_htlc_limit_msat,
|
||||
user_channel_id: channel.get_user_id(),
|
||||
confirmations_required: channel.minimum_depth(),
|
||||
confirmations: Some(channel.get_funding_tx_confirmations(best_block_height)),
|
||||
force_close_spend_delay: channel.get_counterparty_selected_contest_delay(),
|
||||
is_outbound: channel.is_outbound(),
|
||||
is_channel_ready: channel.is_usable(),
|
||||
is_usable: channel.is_live(),
|
||||
is_public: channel.should_announce(),
|
||||
inbound_htlc_minimum_msat: Some(channel.get_holder_htlc_minimum_msat()),
|
||||
inbound_htlc_maximum_msat: channel.get_holder_htlc_maximum_msat(),
|
||||
config: Some(channel.config()),
|
||||
});
|
||||
for (_channel_id, channel) in peer_state.channel_by_id.iter().filter(f) {
|
||||
let details = ChannelDetails::from_channel(channel, best_block_height,
|
||||
peer_state.latest_features.clone());
|
||||
res.push(details);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1786,6 +1794,24 @@ where
|
|||
self.list_channels_with_filter(|&(_, ref channel)| channel.is_live())
|
||||
}
|
||||
|
||||
/// Gets the list of channels we have with a given counterparty, in random order.
|
||||
pub fn list_channels_with_counterparty(&self, counterparty_node_id: &PublicKey) -> Vec<ChannelDetails> {
|
||||
let best_block_height = self.best_block.read().unwrap().height();
|
||||
let per_peer_state = self.per_peer_state.read().unwrap();
|
||||
|
||||
if let Some(peer_state_mutex) = per_peer_state.get(counterparty_node_id) {
|
||||
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
|
||||
let peer_state = &mut *peer_state_lock;
|
||||
let features = &peer_state.latest_features;
|
||||
return peer_state.channel_by_id
|
||||
.iter()
|
||||
.map(|(_, channel)|
|
||||
ChannelDetails::from_channel(channel, best_block_height, features.clone()))
|
||||
.collect();
|
||||
}
|
||||
vec![]
|
||||
}
|
||||
|
||||
/// Returns in an undefined order recent payments that -- if not fulfilled -- have yet to find a
|
||||
/// successful path, or have unresolved HTLCs.
|
||||
///
|
||||
|
@ -7854,8 +7880,10 @@ mod tests {
|
|||
// to connect messages with new values
|
||||
chan.0.contents.fee_base_msat *= 2;
|
||||
chan.1.contents.fee_base_msat *= 2;
|
||||
let node_a_chan_info = nodes[0].node.list_channels()[0].clone();
|
||||
let node_b_chan_info = nodes[1].node.list_channels()[0].clone();
|
||||
let node_a_chan_info = nodes[0].node.list_channels_with_counterparty(
|
||||
&nodes[1].node.get_our_node_id()).pop().unwrap();
|
||||
let node_b_chan_info = nodes[1].node.list_channels_with_counterparty(
|
||||
&nodes[0].node.get_our_node_id()).pop().unwrap();
|
||||
|
||||
// The first two nodes (which opened a channel) should now require fresh persistence
|
||||
assert!(nodes[0].node.await_persistable_update_timeout(Duration::from_millis(1)));
|
||||
|
|
Loading…
Add table
Reference in a new issue