Skip to content

Commit aa2021d

Browse files
committed
Introduce a Channel-specific Err type and return it in a few places
This is way simpler than writing out the whole ErrorAction mess and we can just convert it as appropriate in ChannelManager.
1 parent 6c1123c commit aa2021d

File tree

2 files changed

+78
-37
lines changed

2 files changed

+78
-37
lines changed

src/ln/channel.rs

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,14 @@ const B_OUTPUT_PLUS_SPENDING_INPUT_WEIGHT: u64 = 104; // prevout: 40, nSequence:
374374
/// it's 2^24.
375375
pub const MAX_FUNDING_SATOSHIS: u64 = (1 << 24);
376376

377+
/// Used to return a simple Error back to ChannelManager. Will get converted to a
378+
/// msgs::ErrorAction::SendErrorMessage or msgs::ErrorAction::IgnoreError as appropriate with our
379+
/// channel_id in ChannelManager.
380+
pub(super) enum ChannelError {
381+
Ignore(&'static str),
382+
Close(&'static str),
383+
}
384+
377385
macro_rules! secp_call {
378386
( $res: expr, $err: expr, $chan_id: expr ) => {
379387
match $res {
@@ -506,95 +514,85 @@ impl Channel {
506514
})
507515
}
508516

509-
fn check_remote_fee(fee_estimator: &FeeEstimator, feerate_per_kw: u32) -> Result<(), HandleError> {
517+
fn check_remote_fee(fee_estimator: &FeeEstimator, feerate_per_kw: u32) -> Result<(), ChannelError> {
510518
if (feerate_per_kw as u64) < fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background) {
511-
return Err(HandleError{err: "Peer's feerate much too low", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
519+
return Err(ChannelError::Close("Peer's feerate much too low"));
512520
}
513521
if (feerate_per_kw as u64) > fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::HighPriority) * 2 {
514-
return Err(HandleError{err: "Peer's feerate much too high", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
522+
return Err(ChannelError::Close("Peer's feerate much too high"));
515523
}
516524
Ok(())
517525
}
518526

519527
/// Creates a new channel from a remote sides' request for one.
520528
/// Assumes chain_hash has already been checked and corresponds with what we expect!
521-
/// Generally prefers to take the DisconnectPeer action on failure, as a notice to the sender
522-
/// that we're rejecting the new channel.
523-
pub fn new_from_req(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, require_announce: bool, allow_announce: bool, logger: Arc<Logger>) -> Result<Channel, HandleError> {
524-
macro_rules! return_error_message {
525-
( $msg: expr ) => {
526-
return Err(HandleError{err: $msg, action: Some(msgs::ErrorAction::SendErrorMessage{ msg: msgs::ErrorMessage { channel_id: msg.temporary_channel_id, data: $msg.to_string() }})});
527-
}
528-
}
529-
529+
pub fn new_from_req(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, require_announce: bool, allow_announce: bool, logger: Arc<Logger>) -> Result<Channel, ChannelError> {
530530
// Check sanity of message fields:
531531
if msg.funding_satoshis >= MAX_FUNDING_SATOSHIS {
532-
return_error_message!("funding value > 2^24");
532+
return Err(ChannelError::Close("funding value > 2^24"));
533533
}
534534
if msg.channel_reserve_satoshis > msg.funding_satoshis {
535-
return_error_message!("Bogus channel_reserve_satoshis");
535+
return Err(ChannelError::Close("Bogus channel_reserve_satoshis"));
536536
}
537537
if msg.push_msat > (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000 {
538-
return_error_message!("push_msat larger than funding value");
538+
return Err(ChannelError::Close("push_msat larger than funding value"));
539539
}
540540
if msg.dust_limit_satoshis > msg.funding_satoshis {
541-
return_error_message!("Peer never wants payout outputs?");
541+
return Err(ChannelError::Close("Peer never wants payout outputs?"));
542542
}
543543
if msg.dust_limit_satoshis > msg.channel_reserve_satoshis {
544-
return_error_message!("Bogus; channel reserve is less than dust limit");
544+
return Err(ChannelError::Close("Bogus; channel reserve is less than dust limit"));
545545
}
546546
if msg.htlc_minimum_msat >= (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000 {
547-
return_error_message!("Miminum htlc value is full channel value");
547+
return Err(ChannelError::Close("Miminum htlc value is full channel value"));
548548
}
549-
Channel::check_remote_fee(fee_estimator, msg.feerate_per_kw).map_err(|e|
550-
HandleError{err: e.err, action: Some(msgs::ErrorAction::SendErrorMessage{ msg: msgs::ErrorMessage { channel_id: msg.temporary_channel_id, data: e.err.to_string() }})}
551-
)?;
549+
Channel::check_remote_fee(fee_estimator, msg.feerate_per_kw)?;
552550

553551
if msg.to_self_delay > MAX_LOCAL_BREAKDOWN_TIMEOUT {
554-
return_error_message!("They wanted our payments to be delayed by a needlessly long period");
552+
return Err(ChannelError::Close("They wanted our payments to be delayed by a needlessly long period"));
555553
}
556554
if msg.max_accepted_htlcs < 1 {
557-
return_error_message!("0 max_accpted_htlcs makes for a useless channel");
555+
return Err(ChannelError::Close("0 max_accpted_htlcs makes for a useless channel"));
558556
}
559557
if msg.max_accepted_htlcs > 483 {
560-
return_error_message!("max_accpted_htlcs > 483");
558+
return Err(ChannelError::Close("max_accpted_htlcs > 483"));
561559
}
562560

563561
// Convert things into internal flags and prep our state:
564562

565563
let their_announce = if (msg.channel_flags & 1) == 1 { true } else { false };
566564
if require_announce && !their_announce {
567-
return_error_message!("Peer tried to open unannounced channel, but we require public ones");
565+
return Err(ChannelError::Close("Peer tried to open unannounced channel, but we require public ones"));
568566
}
569567
if !allow_announce && their_announce {
570-
return_error_message!("Peer tried to open announced channel, but we require private ones");
568+
return Err(ChannelError::Close("Peer tried to open announced channel, but we require private ones"));
571569
}
572570

573571
let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
574572

575573
let our_dust_limit_satoshis = Channel::derive_our_dust_limit_satoshis(background_feerate);
576574
let our_channel_reserve_satoshis = Channel::get_our_channel_reserve_satoshis(msg.funding_satoshis);
577575
if our_channel_reserve_satoshis < our_dust_limit_satoshis {
578-
return_error_message!("Suitalbe channel reserve not found. aborting");
576+
return Err(ChannelError::Close("Suitalbe channel reserve not found. aborting"));
579577
}
580578
if msg.channel_reserve_satoshis < our_dust_limit_satoshis {
581-
return_error_message!("channel_reserve_satoshis too small");
579+
return Err(ChannelError::Close("channel_reserve_satoshis too small"));
582580
}
583581
if our_channel_reserve_satoshis < msg.dust_limit_satoshis {
584-
return_error_message!("Dust limit too high for our channel reserve");
582+
return Err(ChannelError::Close("Dust limit too high for our channel reserve"));
585583
}
586584

587585
// check if the funder's amount for the initial commitment tx is sufficient
588586
// for full fee payment
589587
let funders_amount_msat = msg.funding_satoshis * 1000 - msg.push_msat;
590588
if funders_amount_msat < background_feerate * COMMITMENT_TX_BASE_WEIGHT {
591-
return_error_message!("Insufficient funding amount for initial commitment");
589+
return Err(ChannelError::Close("Insufficient funding amount for initial commitment"));
592590
}
593591

594592
let to_local_msat = msg.push_msat;
595593
let to_remote_msat = funders_amount_msat - background_feerate * COMMITMENT_TX_BASE_WEIGHT;
596594
if to_local_msat <= msg.channel_reserve_satoshis * 1000 && to_remote_msat <= our_channel_reserve_satoshis * 1000 {
597-
return_error_message!("Insufficient funding amount for initial commitment");
595+
return Err(ChannelError::Close("Insufficient funding amount for initial commitment"));
598596
}
599597

600598
let secp_ctx = Secp256k1::new();
@@ -2005,12 +2003,12 @@ impl Channel {
20052003
outbound_drops
20062004
}
20072005

2008-
pub fn update_fee(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::UpdateFee) -> Result<(), HandleError> {
2006+
pub fn update_fee(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::UpdateFee) -> Result<(), ChannelError> {
20092007
if self.channel_outbound {
2010-
return Err(HandleError{err: "Non-funding remote tried to update channel fee", action: None});
2008+
return Err(ChannelError::Close("Non-funding remote tried to update channel fee"));
20112009
}
20122010
if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 {
2013-
return Err(HandleError{err: "Peer sent update_fee when we needed a channel_reestablish", action: Some(msgs::ErrorAction::SendErrorMessage{msg: msgs::ErrorMessage{data: "Peer sent update_fee when we needed a channel_reestablish".to_string(), channel_id: msg.channel_id}})});
2011+
return Err(ChannelError::Close("Peer sent update_fee when we needed a channel_reestablish"));
20142012
}
20152013
Channel::check_remote_fee(fee_estimator, msg.feerate_per_kw)?;
20162014

src/ln/channelmanager.rs

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use secp256k1;
2222

2323
use chain::chaininterface::{BroadcasterInterface,ChainListener,ChainWatchInterface,FeeEstimator};
2424
use chain::transaction::OutPoint;
25-
use ln::channel::{Channel, ChannelKeys};
25+
use ln::channel::{Channel, ChannelError, ChannelKeys};
2626
use ln::channelmonitor::ManyChannelMonitor;
2727
use ln::router::{Route,RouteHop};
2828
use ln::msgs;
@@ -173,6 +173,48 @@ impl MsgHandleErrInternal {
173173
fn from_no_close(err: msgs::HandleError) -> Self {
174174
Self { err, needs_channel_force_close: false }
175175
}
176+
#[inline]
177+
fn from_chan_no_close(err: ChannelError, channel_id: [u8; 32]) -> Self {
178+
Self {
179+
err: match err {
180+
ChannelError::Ignore(msg) => HandleError {
181+
err: msg,
182+
action: Some(msgs::ErrorAction::IgnoreError),
183+
},
184+
ChannelError::Close(msg) => HandleError {
185+
err: msg,
186+
action: Some(msgs::ErrorAction::SendErrorMessage {
187+
msg: msgs::ErrorMessage {
188+
channel_id,
189+
data: msg.to_string()
190+
},
191+
}),
192+
},
193+
},
194+
needs_channel_force_close: false,
195+
}
196+
}
197+
#[inline]
198+
fn from_chan_maybe_close(err: ChannelError, channel_id: [u8; 32]) -> Self {
199+
Self {
200+
err: match err {
201+
ChannelError::Ignore(msg) => HandleError {
202+
err: msg,
203+
action: Some(msgs::ErrorAction::IgnoreError),
204+
},
205+
ChannelError::Close(msg) => HandleError {
206+
err: msg,
207+
action: Some(msgs::ErrorAction::SendErrorMessage {
208+
msg: msgs::ErrorMessage {
209+
channel_id,
210+
data: msg.to_string()
211+
},
212+
}),
213+
},
214+
},
215+
needs_channel_force_close: true,
216+
}
217+
}
176218
}
177219

178220
/// We hold back HTLCs we intend to relay for a random interval in the range (this, 5*this). This
@@ -1467,7 +1509,8 @@ impl ChannelManager {
14671509
}
14681510
};
14691511

1470-
let channel = Channel::new_from_req(&*self.fee_estimator, chan_keys, their_node_id.clone(), msg, 0, false, self.announce_channels_publicly, Arc::clone(&self.logger)).map_err(|e| MsgHandleErrInternal::from_no_close(e))?;
1512+
let channel = Channel::new_from_req(&*self.fee_estimator, chan_keys, their_node_id.clone(), msg, 0, false, self.announce_channels_publicly, Arc::clone(&self.logger))
1513+
.map_err(|e| MsgHandleErrInternal::from_chan_no_close(e, msg.temporary_channel_id))?;
14711514
let accept_msg = channel.get_accept_channel();
14721515
channel_state.by_id.insert(channel.channel_id(), channel);
14731516
Ok(accept_msg)
@@ -1868,7 +1911,7 @@ impl ChannelManager {
18681911
//TODO: here and below MsgHandleErrInternal, #153 case
18691912
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", msg.channel_id));
18701913
}
1871-
chan.update_fee(&*self.fee_estimator, &msg).map_err(|e| MsgHandleErrInternal::from_maybe_close(e))
1914+
chan.update_fee(&*self.fee_estimator, &msg).map_err(|e| MsgHandleErrInternal::from_chan_maybe_close(e, msg.channel_id))
18721915
},
18731916
None => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id))
18741917
}

0 commit comments

Comments
 (0)