Skip to content

Commit 9b67db5

Browse files
committed
WIP: improve error message.
... for ChannelError and APIMisuseError Before this commit, When rl returns error, we don't know The actual parameter which caused the error. By returning parameterised `String` instead of predefined `&'static str`, We can give a caller improved error message.
1 parent bd2fa43 commit 9b67db5

File tree

3 files changed

+71
-26
lines changed

3 files changed

+71
-26
lines changed

lightning/src/ln/channel.rs

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpd
2121
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
2222
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys};
2323
use ln::chan_utils;
24+
use ln::checker::{predicates, check_or_close, checker_or_api_misuse, check_or_ignore};
2425
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
2526
use chain::transaction::OutPoint;
2627
use chain::keysinterface::{ChannelKeys, KeysInterface};
@@ -409,17 +410,17 @@ pub const MAX_FUNDING_SATOSHIS: u64 = 1 << 24;
409410
/// msgs::ErrorAction::SendErrorMessage or msgs::ErrorAction::IgnoreError as appropriate with our
410411
/// channel_id in ChannelManager.
411412
pub(super) enum ChannelError {
412-
Ignore(&'static str),
413-
Close(&'static str),
414-
CloseDelayBroadcast(&'static str),
413+
Ignore(String),
414+
Close(String),
415+
CloseDelayBroadcast(String),
415416
}
416417

417418
impl fmt::Debug for ChannelError {
418419
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
419420
match self {
420-
&ChannelError::Ignore(e) => write!(f, "Ignore : {}", e),
421-
&ChannelError::Close(e) => write!(f, "Close : {}", e),
422-
&ChannelError::CloseDelayBroadcast(e) => write!(f, "CloseDelayBroadcast : {}", e)
421+
&ChannelError::Ignore(ref e) => write!(f, "Ignore : {}", e),
422+
&ChannelError::Close(ref e) => write!(f, "Close : {}", e),
423+
&ChannelError::CloseDelayBroadcast(ref e) => write!(f, "CloseDelayBroadcast : {}", e)
423424
}
424425
}
425426
}
@@ -433,6 +434,7 @@ macro_rules! secp_check {
433434
};
434435
}
435436

437+
436438
impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
437439
// Convert constants + channel value to limits:
438440
fn get_our_max_htlc_value_in_flight_msat(channel_value_satoshis: u64) -> u64 {
@@ -459,17 +461,9 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
459461
{
460462
let chan_keys = keys_provider.get_channel_keys(false, channel_value_satoshis);
461463

462-
if channel_value_satoshis >= MAX_FUNDING_SATOSHIS {
463-
return Err(APIError::APIMisuseError{err: "funding value > 2^24"});
464-
}
465-
466-
if push_msat > channel_value_satoshis * 1000 {
467-
return Err(APIError::APIMisuseError{err: "push value > channel value"});
468-
}
469-
if config.own_channel_config.our_to_self_delay < BREAKDOWN_TIMEOUT {
470-
return Err(APIError::APIMisuseError{err: "Configured with an unreasonable our_to_self_delay putting user funds at risks"});
471-
}
472-
464+
check_or_api_misuse(channel_value_satoshis, MAX_FUNDING_SATOSHIS, predicates::lt, "Funding value must be smaller than {expected}. it was {actual}")?;
465+
check_or_api_misuse(push_msat, channel_value_satoshis * 1000, predicates::ge, "push value must be greater than or equal to {expected}. it was {actual}")?;
466+
check_or_api_misuse(config.own_channel_config.our_to_self_delay, BREAKDOWN_TIMEOUT, predicates::ge, "our configs, our_to_self_delay must be greater than or equal to {expected}. it was {actual}")?;
473467

474468
let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
475469
if Channel::<ChanSigner>::get_remote_channel_reserve_satoshis(channel_value_satoshis) < Channel::<ChanSigner>::derive_our_dust_limit_satoshis(background_feerate) {
@@ -558,12 +552,10 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
558552
fn check_remote_fee<F: Deref>(fee_estimator: &F, feerate_per_kw: u32) -> Result<(), ChannelError>
559553
where F::Target: FeeEstimator
560554
{
561-
if feerate_per_kw < fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background) {
562-
return Err(ChannelError::Close("Peer's feerate much too low"));
563-
}
564-
if feerate_per_kw as u64 > fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::HighPriority) as u64 * 2 {
565-
return Err(ChannelError::Close("Peer's feerate much too high"));
566-
}
555+
let lower_limit = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
556+
check_or_close(feerate_per_kw, lower_limit, predicates::ge, "Peer's feerate much too low. actual: ({actual}). expected lower limit({lower_limit})")?;
557+
let upper_limit = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::HighPriority) as u64 * 2;
558+
check_or_close(feerate_per_kw, upper_limit, predicates::le, "Peer's feerate much too high. actual: ({actual}). expected upper limit({lower_limit})")?;
567559
Ok(())
568560
}
569561

lightning/src/ln/checker.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
2+
pub fn check_or_error<T, Q, F>(actual: T, expected: Q, predicate: F, msg: &str) -> Result<(), String>
3+
where
4+
F: Fn(&T, &Q) -> bool
5+
{
6+
if predicate(&actual, &expected) {
7+
Ok(())
8+
} else {
9+
let astr = format!("{}", actual);
10+
let bstr = format!("{}", expected);
11+
let final_msg = msg.replace("{actual}", &astr[..]).replace("{expected}", &bstr[..]);
12+
Err(final_msg)
13+
}
14+
}
15+
16+
pub(crate) fn check_or_close<T, Q, F>(actual: T, expected: Q, predicate: F, msg: &str) -> Result<(), ChannelError>
17+
where
18+
F: Fn(&T, &Q) -> bool
19+
{
20+
check_or_error(actual, expected, predicate, msg).map_err(|err| { ChannelError::Close(err) })
21+
}
22+
23+
pub(crate) fn check_or_ignore<T, Q, F>(actual: T, expected: Q, predicate: F, msg: &str) -> Result<(), ChannelError>
24+
where
25+
F: Fn(&T, &Q) -> bool
26+
{
27+
check_or_error(actual, expected, predicate, msg).map_err(|err| { ChannelError::Ignore(err) })
28+
}
29+
30+
pub(crate) fn check_or_api_misuse<T, Q, F>(actual: T, expected: Q, predicate: F, msg: &str) -> Result<(), ChannelError>
31+
where
32+
F: Fn(&T, &Q) -> bool
33+
{
34+
check_or_error(actual, expected, predicate, msg).map_err(|err| { APIMisuseError{ err } })
35+
}
36+
37+
pub(crate) mod predicates {
38+
pub(crate) fn lt<T>(a: T, expected: T) -> bool
39+
where T: std::cmp::Ord
40+
{ a < expected }
41+
42+
pub(crate) fn le<T>(a: T, expected: T) -> bool
43+
where T: std::cmp::Ord
44+
{ a <= expected }
45+
46+
pub(crate) fn gt<T>(a: T, expected: T) -> bool
47+
where T: std::cmp::Ord
48+
{ a > expected }
49+
50+
pub(crate) fn ge<T>(a: T, expected: T) -> bool
51+
where T: std::cmp::Ord
52+
{ a >= expected }
53+
}

lightning/src/util/errors.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pub enum APIError {
99
/// are documented, but generally indicates some precondition of a function was violated.
1010
APIMisuseError {
1111
/// A human-readable error message
12-
err: &'static str
12+
err: String
1313
},
1414
/// Due to a high feerate, we were unable to complete the request.
1515
/// For example, this may be returned if the feerate implies we cannot open a channel at the
@@ -24,14 +24,14 @@ pub enum APIError {
2424
/// too-many-hops, etc).
2525
RouteError {
2626
/// A human-readable error message
27-
err: &'static str
27+
err: String
2828
},
2929
/// We were unable to complete the request as the Channel required to do so is unable to
3030
/// complete the request (or was not found). This can take many forms, including disconnected
3131
/// peer, channel at capacity, channel shutting down, etc.
3232
ChannelUnavailable {
3333
/// A human-readable error message
34-
err: &'static str
34+
err: String
3535
},
3636
/// An attempt to call add/update_monitor returned an Err (ie you did this!), causing the
3737
/// attempted action to fail.

0 commit comments

Comments
 (0)