Skip to content

Commit 935145a

Browse files
committed
Improved error logging in ChannelManager::do_accept_inbound_channel
This commit ensures that all API errors in do_accept_inbound_channel are logged before they are returned.
1 parent 15b7f66 commit 935145a

File tree

10 files changed

+353
-261
lines changed

10 files changed

+353
-261
lines changed

ci/check-cfg-flags.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ def check_feature(feature):
3939
pass
4040
elif feature == "electrum":
4141
pass
42+
elif feature == "time":
43+
pass
4244
elif feature == "_test_utils":
4345
pass
4446
elif feature == "_test_vectors":

lightning-transaction-sync/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ all-features = true
1414
rustdoc-args = ["--cfg", "docsrs"]
1515

1616
[features]
17-
default = []
17+
default = ["time"]
18+
time = []
1819
esplora-async = ["async-interface", "esplora-client/async", "futures"]
1920
esplora-async-https = ["esplora-async", "esplora-client/async-https-rustls"]
2021
esplora-blocking = ["esplora-client/blocking"]

lightning-transaction-sync/src/esplora.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use esplora_client::r#async::AsyncClient;
1414
#[cfg(not(feature = "async-interface"))]
1515
use esplora_client::blocking::BlockingClient;
1616

17-
use std::time::Instant;
1817
use std::collections::HashSet;
1918
use core::ops::Deref;
2019

@@ -91,7 +90,8 @@ where
9190
let mut sync_state = self.sync_state.lock().await;
9291

9392
log_trace!(self.logger, "Starting transaction sync.");
94-
let start_time = Instant::now();
93+
#[cfg(feature = "time")]
94+
let start_time = std::time::Instant::now();
9595
let mut num_confirmed = 0;
9696
let mut num_unconfirmed = 0;
9797

@@ -227,8 +227,12 @@ where
227227
sync_state.pending_sync = false;
228228
}
229229
}
230+
#[cfg(feature = "time")]
230231
log_debug!(self.logger, "Finished transaction sync at tip {} in {}ms: {} confirmed, {} unconfirmed.",
231232
tip_hash, start_time.elapsed().as_millis(), num_confirmed, num_unconfirmed);
233+
#[cfg(not(feature = "time"))]
234+
log_debug!(self.logger, "Finished transaction sync at tip {}: {} confirmed, {} unconfirmed.",
235+
tip_hash, num_confirmed, num_unconfirmed);
232236
Ok(())
233237
}
234238

lightning/src/ln/chan_utils.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -485,9 +485,11 @@ impl TxCreationKeys {
485485
}
486486

487487
/// The maximum length of a script returned by get_revokeable_redeemscript.
488-
// Calculated as 6 bytes of opcodes, 1 byte push plus 2 bytes for contest_delay, and two public
489-
// keys of 33 bytes (+ 1 push).
490-
pub const REVOKEABLE_REDEEMSCRIPT_MAX_LENGTH: usize = 6 + 3 + 34*2;
488+
// Calculated as 6 bytes of opcodes, 1 byte push plus 3 bytes for contest_delay, and two public
489+
// keys of 33 bytes (+ 1 push). Generally, pushes are only 2 bytes (for values below 0x7fff, i.e.
490+
// around 7 months), however, a 7 month contest delay shouldn't result in being unable to reclaim
491+
// on-chain funds.
492+
pub const REVOKEABLE_REDEEMSCRIPT_MAX_LENGTH: usize = 6 + 4 + 34*2;
491493

492494
/// A script either spendable by the revocation
493495
/// key or the broadcaster_delayed_payment_key and satisfying the relative-locktime OP_CSV constrain.

lightning/src/ln/channel.rs

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -732,8 +732,8 @@ struct CommitmentStats<'a> {
732732
total_fee_sat: u64, // the total fee included in the transaction
733733
num_nondust_htlcs: usize, // the number of HTLC outputs (dust HTLCs *non*-included)
734734
htlcs_included: Vec<(HTLCOutputInCommitment, Option<&'a HTLCSource>)>, // the list of HTLCs (dust HTLCs *included*) which were not ignored when building the transaction
735-
local_balance_msat: u64, // local balance before fees but considering dust limits
736-
remote_balance_msat: u64, // remote balance before fees but considering dust limits
735+
local_balance_msat: u64, // local balance before fees *not* considering dust limits
736+
remote_balance_msat: u64, // remote balance before fees *not* considering dust limits
737737
outbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful offered HTLCs since last commitment
738738
inbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful received HTLCs since last commitment
739739
}
@@ -1728,13 +1728,13 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
17281728
}
17291729
}
17301730

1731-
let mut value_to_self_msat: i64 = (self.value_to_self_msat - local_htlc_total_msat) as i64 + value_to_self_msat_offset;
1731+
let value_to_self_msat: i64 = (self.value_to_self_msat - local_htlc_total_msat) as i64 + value_to_self_msat_offset;
17321732
assert!(value_to_self_msat >= 0);
17331733
// Note that in case they have several just-awaiting-last-RAA fulfills in-progress (ie
17341734
// AwaitingRemoteRevokeToRemove or AwaitingRemovedRemoteRevoke) we may have allowed them to
17351735
// "violate" their reserve value by couting those against it. Thus, we have to convert
17361736
// everything to i64 before subtracting as otherwise we can overflow.
1737-
let mut value_to_remote_msat: i64 = (self.channel_value_satoshis * 1000) as i64 - (self.value_to_self_msat as i64) - (remote_htlc_total_msat as i64) - value_to_self_msat_offset;
1737+
let value_to_remote_msat: i64 = (self.channel_value_satoshis * 1000) as i64 - (self.value_to_self_msat as i64) - (remote_htlc_total_msat as i64) - value_to_self_msat_offset;
17381738
assert!(value_to_remote_msat >= 0);
17391739

17401740
#[cfg(debug_assertions)]
@@ -1800,10 +1800,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
18001800
htlcs_included.sort_unstable_by_key(|h| h.0.transaction_output_index.unwrap());
18011801
htlcs_included.append(&mut included_dust_htlcs);
18021802

1803-
// For the stats, trimmed-to-0 the value in msats accordingly
1804-
value_to_self_msat = if (value_to_self_msat * 1000) < broadcaster_dust_limit_satoshis as i64 { 0 } else { value_to_self_msat };
1805-
value_to_remote_msat = if (value_to_remote_msat * 1000) < broadcaster_dust_limit_satoshis as i64 { 0 } else { value_to_remote_msat };
1806-
18071803
CommitmentStats {
18081804
tx,
18091805
feerate_per_kw,
@@ -1876,7 +1872,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
18761872
if let Some(feerate) = outbound_feerate_update {
18771873
feerate_per_kw = cmp::max(feerate_per_kw, feerate);
18781874
}
1879-
cmp::max(2530, feerate_per_kw * 1250 / 1000)
1875+
let feerate_plus_quarter = feerate_per_kw.checked_mul(1250).map(|v| v / 1000);
1876+
cmp::max(2530, feerate_plus_quarter.unwrap_or(u32::max_value()))
18801877
}
18811878

18821879
/// Get forwarding information for the counterparty.
@@ -6848,6 +6845,41 @@ pub(super) struct InboundV1Channel<SP: Deref> where SP::Target: SignerProvider {
68486845
pub unfunded_context: UnfundedChannelContext,
68496846
}
68506847

6848+
/// Fetches the [`ChannelTypeFeatures`] that will be used for a channel built from a given
6849+
/// [`msgs::OpenChannel`].
6850+
pub(super) fn channel_type_from_open_channel(
6851+
msg: &msgs::OpenChannel, their_features: &InitFeatures,
6852+
our_supported_features: &ChannelTypeFeatures
6853+
) -> Result<ChannelTypeFeatures, ChannelError> {
6854+
if let Some(channel_type) = &msg.channel_type {
6855+
if channel_type.supports_any_optional_bits() {
6856+
return Err(ChannelError::Close("Channel Type field contained optional bits - this is not allowed".to_owned()));
6857+
}
6858+
6859+
// We only support the channel types defined by the `ChannelManager` in
6860+
// `provided_channel_type_features`. The channel type must always support
6861+
// `static_remote_key`.
6862+
if !channel_type.requires_static_remote_key() {
6863+
return Err(ChannelError::Close("Channel Type was not understood - we require static remote key".to_owned()));
6864+
}
6865+
// Make sure we support all of the features behind the channel type.
6866+
if !channel_type.is_subset(our_supported_features) {
6867+
return Err(ChannelError::Close("Channel Type contains unsupported features".to_owned()));
6868+
}
6869+
let announced_channel = if (msg.channel_flags & 1) == 1 { true } else { false };
6870+
if channel_type.requires_scid_privacy() && announced_channel {
6871+
return Err(ChannelError::Close("SCID Alias/Privacy Channel Type cannot be set on a public channel".to_owned()));
6872+
}
6873+
Ok(channel_type.clone())
6874+
} else {
6875+
let channel_type = ChannelTypeFeatures::from_init(&their_features);
6876+
if channel_type != ChannelTypeFeatures::only_static_remote_key() {
6877+
return Err(ChannelError::Close("Only static_remote_key is supported for non-negotiated channel types".to_owned()));
6878+
}
6879+
Ok(channel_type)
6880+
}
6881+
}
6882+
68516883
impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
68526884
/// Creates a new channel from a remote sides' request for one.
68536885
/// Assumes chain_hash has already been checked and corresponds with what we expect!
@@ -6866,32 +6898,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
68666898

68676899
// First check the channel type is known, failing before we do anything else if we don't
68686900
// support this channel type.
6869-
let channel_type = if let Some(channel_type) = &msg.channel_type {
6870-
if channel_type.supports_any_optional_bits() {
6871-
return Err(ChannelError::Close("Channel Type field contained optional bits - this is not allowed".to_owned()));
6872-
}
6873-
6874-
// We only support the channel types defined by the `ChannelManager` in
6875-
// `provided_channel_type_features`. The channel type must always support
6876-
// `static_remote_key`.
6877-
if !channel_type.requires_static_remote_key() {
6878-
return Err(ChannelError::Close("Channel Type was not understood - we require static remote key".to_owned()));
6879-
}
6880-
// Make sure we support all of the features behind the channel type.
6881-
if !channel_type.is_subset(our_supported_features) {
6882-
return Err(ChannelError::Close("Channel Type contains unsupported features".to_owned()));
6883-
}
6884-
if channel_type.requires_scid_privacy() && announced_channel {
6885-
return Err(ChannelError::Close("SCID Alias/Privacy Channel Type cannot be set on a public channel".to_owned()));
6886-
}
6887-
channel_type.clone()
6888-
} else {
6889-
let channel_type = ChannelTypeFeatures::from_init(&their_features);
6890-
if channel_type != ChannelTypeFeatures::only_static_remote_key() {
6891-
return Err(ChannelError::Close("Only static_remote_key is supported for non-negotiated channel types".to_owned()));
6892-
}
6893-
channel_type
6894-
};
6901+
let channel_type = channel_type_from_open_channel(msg, their_features, our_supported_features)?;
68956902

68966903
let channel_keys_id = signer_provider.generate_channel_keys_id(true, msg.funding_satoshis, user_id);
68976904
let holder_signer = signer_provider.derive_channel_signer(msg.funding_satoshis, channel_keys_id);

lightning/src/ln/channelmanager.rs

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use crate::events::{Event, EventHandler, EventsProvider, MessageSendEvent, Messa
4343
// Since this struct is returned in `list_channels` methods, expose it here in case users want to
4444
// construct one themselves.
4545
use crate::ln::{inbound_payment, ChannelId, PaymentHash, PaymentPreimage, PaymentSecret};
46-
use crate::ln::channel::{Channel, ChannelPhase, ChannelContext, ChannelError, ChannelUpdateStatus, ShutdownResult, UnfundedChannelContext, UpdateFulfillCommitFetch, OutboundV1Channel, InboundV1Channel, WithChannelContext};
46+
use crate::ln::channel::{self, Channel, ChannelPhase, ChannelContext, ChannelError, ChannelUpdateStatus, ShutdownResult, UnfundedChannelContext, UpdateFulfillCommitFetch, OutboundV1Channel, InboundV1Channel, WithChannelContext};
4747
use crate::ln::features::{Bolt12InvoiceFeatures, ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
4848
#[cfg(any(feature = "_test_utils", test))]
4949
use crate::ln::features::Bolt11InvoiceFeatures;
@@ -6002,13 +6002,20 @@ where
60026002
}
60036003

60046004
fn do_accept_inbound_channel(&self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey, accept_0conf: bool, user_channel_id: u128) -> Result<(), APIError> {
6005+
6006+
let logger = WithContext::from(&self.logger, Some(*counterparty_node_id), Some(*temporary_channel_id));
60056007
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
60066008

60076009
let peers_without_funded_channels =
60086010
self.peers_without_funded_channels(|peer| { peer.total_channel_count() > 0 });
60096011
let per_peer_state = self.per_peer_state.read().unwrap();
60106012
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
6011-
.ok_or_else(|| APIError::ChannelUnavailable { err: format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id) })?;
6013+
.ok_or_else(|| {
6014+
let err_str = format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id);
6015+
log_error!(logger, "{}", err_str);
6016+
6017+
APIError::ChannelUnavailable { err: err_str }
6018+
})?;
60126019
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
60136020
let peer_state = &mut *peer_state_lock;
60146021
let is_only_peer_channel = peer_state.total_channel_count() == 1;
@@ -6023,9 +6030,19 @@ where
60236030
InboundV1Channel::new(&self.fee_estimator, &self.entropy_source, &self.signer_provider,
60246031
counterparty_node_id.clone(), &self.channel_type_features(), &peer_state.latest_features,
60256032
&unaccepted_channel.open_channel_msg, user_channel_id, &self.default_configuration, best_block_height,
6026-
&self.logger, accept_0conf).map_err(|e| APIError::ChannelUnavailable { err: e.to_string() })
6033+
&self.logger, accept_0conf).map_err(|e| {
6034+
let err_str = e.to_string();
6035+
log_error!(logger, "{}", err_str);
6036+
6037+
APIError::ChannelUnavailable { err: err_str }
6038+
})
6039+
}
6040+
_ => {
6041+
let err_str = "No such channel awaiting to be accepted.".to_owned();
6042+
log_error!(logger, "{}", err_str);
6043+
6044+
Err(APIError::APIMisuseError { err: err_str })
60276045
}
6028-
_ => Err(APIError::APIMisuseError { err: "No such channel awaiting to be accepted.".to_owned() })
60296046
}?;
60306047

60316048
if accept_0conf {
@@ -6039,7 +6056,10 @@ where
60396056
}
60406057
};
60416058
peer_state.pending_msg_events.push(send_msg_err_event);
6042-
return Err(APIError::APIMisuseError { err: "Please use accept_inbound_channel_from_trusted_peer_0conf to accept channels with zero confirmations.".to_owned() });
6059+
let err_str = "Please use accept_inbound_channel_from_trusted_peer_0conf to accept channels with zero confirmations.".to_owned();
6060+
log_error!(logger, "{}", err_str);
6061+
6062+
return Err(APIError::APIMisuseError { err: err_str });
60436063
} else {
60446064
// If this peer already has some channels, a new channel won't increase our number of peers
60456065
// with unfunded channels, so as long as we aren't over the maximum number of unfunded
@@ -6052,7 +6072,10 @@ where
60526072
}
60536073
};
60546074
peer_state.pending_msg_events.push(send_msg_err_event);
6055-
return Err(APIError::APIMisuseError { err: "Too many peers with unfunded channels, refusing to accept new ones".to_owned() });
6075+
let err_str = "Too many peers with unfunded channels, refusing to accept new ones".to_owned();
6076+
log_error!(logger, "{}", err_str);
6077+
6078+
return Err(APIError::APIMisuseError { err: err_str });
60566079
}
60576080
}
60586081

@@ -6175,13 +6198,18 @@ where
61756198

61766199
// If we're doing manual acceptance checks on the channel, then defer creation until we're sure we want to accept.
61776200
if self.default_configuration.manually_accept_inbound_channels {
6201+
let channel_type = channel::channel_type_from_open_channel(
6202+
&msg, &peer_state.latest_features, &self.channel_type_features()
6203+
).map_err(|e|
6204+
MsgHandleErrInternal::from_chan_no_close(e, msg.temporary_channel_id)
6205+
)?;
61786206
let mut pending_events = self.pending_events.lock().unwrap();
61796207
pending_events.push_back((events::Event::OpenChannelRequest {
61806208
temporary_channel_id: msg.temporary_channel_id.clone(),
61816209
counterparty_node_id: counterparty_node_id.clone(),
61826210
funding_satoshis: msg.funding_satoshis,
61836211
push_msat: msg.push_msat,
6184-
channel_type: msg.channel_type.clone().unwrap(),
6212+
channel_type,
61856213
}, None));
61866214
peer_state.inbound_channel_request_by_id.insert(channel_id, InboundChannelRequest {
61876215
open_channel_msg: msg.clone(),
@@ -8984,13 +9012,7 @@ where
89849012
let pending_msg_events = &mut peer_state.pending_msg_events;
89859013

89869014
peer_state.channel_by_id.iter_mut().filter_map(|(_, phase)|
8987-
if let ChannelPhase::Funded(chan) = phase { Some(chan) } else {
8988-
// Since unfunded channel maps are cleared upon disconnecting a peer, and they're not persisted
8989-
// (so won't be recovered after a crash), they shouldn't exist here and we would never need to
8990-
// worry about closing and removing them.
8991-
debug_assert!(false);
8992-
None
8993-
}
9015+
if let ChannelPhase::Funded(chan) = phase { Some(chan) } else { None }
89949016
).for_each(|chan| {
89959017
let logger = WithChannelContext::from(&self.logger, &chan.context);
89969018
pending_msg_events.push(events::MessageSendEvent::SendChannelReestablish {

lightning/src/ln/features.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,12 +469,24 @@ impl<T: sealed::Context> Clone for Features<T> {
469469
}
470470
impl<T: sealed::Context> Hash for Features<T> {
471471
fn hash<H: Hasher>(&self, hasher: &mut H) {
472-
self.flags.hash(hasher);
472+
let mut nonzero_flags = &self.flags[..];
473+
while nonzero_flags.last() == Some(&0) {
474+
nonzero_flags = &nonzero_flags[..nonzero_flags.len() - 1];
475+
}
476+
nonzero_flags.hash(hasher);
473477
}
474478
}
475479
impl<T: sealed::Context> PartialEq for Features<T> {
476480
fn eq(&self, o: &Self) -> bool {
477-
self.flags.eq(&o.flags)
481+
let mut o_iter = o.flags.iter();
482+
let mut self_iter = self.flags.iter();
483+
loop {
484+
match (o_iter.next(), self_iter.next()) {
485+
(Some(o), Some(us)) => if o != us { return false },
486+
(Some(b), None) | (None, Some(b)) => if *b != 0 { return false },
487+
(None, None) => return true,
488+
}
489+
}
478490
}
479491
}
480492
impl<T: sealed::Context> PartialOrd for Features<T> {
@@ -1215,4 +1227,26 @@ mod tests {
12151227
assert!(!converted_features.supports_any_optional_bits());
12161228
assert!(converted_features.requires_static_remote_key());
12171229
}
1230+
1231+
#[test]
1232+
#[cfg(feature = "std")]
1233+
fn test_excess_zero_bytes_ignored() {
1234+
// Checks that `Hash` and `PartialEq` ignore excess zero bytes, which may appear due to
1235+
// feature conversion or because a peer serialized their feature poorly.
1236+
use std::collections::hash_map::DefaultHasher;
1237+
use std::hash::{Hash, Hasher};
1238+
1239+
let mut zerod_features = InitFeatures::empty();
1240+
zerod_features.flags = vec![0];
1241+
let empty_features = InitFeatures::empty();
1242+
assert!(empty_features.flags.is_empty());
1243+
1244+
assert_eq!(zerod_features, empty_features);
1245+
1246+
let mut zerod_hash = DefaultHasher::new();
1247+
zerod_features.hash(&mut zerod_hash);
1248+
let mut empty_hash = DefaultHasher::new();
1249+
empty_features.hash(&mut empty_hash);
1250+
assert_eq!(zerod_hash.finish(), empty_hash.finish());
1251+
}
12181252
}

0 commit comments

Comments
 (0)