+/// Details of a channel, as returned by ChannelManager::list_channels and ChannelManager::list_usable_channels
+pub struct ChannelDetails {
+ /// The channel's ID (prior to funding transaction generation, this is a random 32 bytes,
+ /// thereafter this is the txid of the funding transaction xor the funding transaction output).
+ /// Note that this means this value is *not* persistent - it can change once during the
+ /// lifetime of the channel.
+ pub channel_id: [u8; 32],
+ /// The position of the funding transaction in the chain. None if the funding transaction has
+ /// not yet been confirmed and the channel fully opened.
+ pub short_channel_id: Option<u64>,
+ /// The node_id of our counterparty
+ pub remote_network_id: PublicKey,
+ /// The value, in satoshis, of this channel as appears in the funding output
+ pub channel_value_satoshis: u64,
+ /// The user_id passed in to create_channel, or 0 if the channel was inbound.
+ pub user_id: u64,
+}
+
+macro_rules! handle_error {
+ ($self: ident, $internal: expr, $their_node_id: expr) => {
+ match $internal {
+ Ok(msg) => Ok(msg),
+ Err(MsgHandleErrInternal { err, shutdown_finish }) => {
+ if let Some((shutdown_res, update_option)) = shutdown_finish {
+ $self.finish_force_close_channel(shutdown_res);
+ if let Some(update) = update_option {
+ let mut channel_state = $self.channel_state.lock().unwrap();
+ channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
+ msg: update
+ });
+ }
+ }
+ Err(err)
+ },
+ }
+ }
+}
+
+macro_rules! break_chan_entry {
+ ($self: ident, $res: expr, $channel_state: expr, $entry: expr) => {
+ match $res {
+ Ok(res) => res,
+ Err(ChannelError::Ignore(msg)) => {
+ break Err(MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore(msg), $entry.key().clone()))
+ },
+ Err(ChannelError::Close(msg)) => {
+ log_trace!($self, "Closing channel {} due to Close-required error: {}", log_bytes!($entry.key()[..]), msg);
+ let (channel_id, mut chan) = $entry.remove_entry();
+ if let Some(short_id) = chan.get_short_channel_id() {
+ $channel_state.short_to_id.remove(&short_id);
+ }
+ break Err(MsgHandleErrInternal::from_finish_shutdown(msg, channel_id, chan.force_shutdown(), $self.get_channel_update(&chan).ok()))
+ },
+ }
+ }
+}
+
+macro_rules! try_chan_entry {
+ ($self: ident, $res: expr, $channel_state: expr, $entry: expr) => {
+ match $res {
+ Ok(res) => res,
+ Err(ChannelError::Ignore(msg)) => {
+ return Err(MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore(msg), $entry.key().clone()))
+ },
+ Err(ChannelError::Close(msg)) => {
+ log_trace!($self, "Closing channel {} due to Close-required error: {}", log_bytes!($entry.key()[..]), msg);
+ let (channel_id, mut chan) = $entry.remove_entry();
+ if let Some(short_id) = chan.get_short_channel_id() {
+ $channel_state.short_to_id.remove(&short_id);
+ }
+ return Err(MsgHandleErrInternal::from_finish_shutdown(msg, channel_id, chan.force_shutdown(), $self.get_channel_update(&chan).ok()))
+ },
+ }
+ }
+}
+
+macro_rules! return_monitor_err {
+ ($self: expr, $err: expr, $channel_state: expr, $entry: expr, $action_type: path) => {
+ return_monitor_err!($self, $err, $channel_state, $entry, $action_type, Vec::new(), Vec::new())
+ };
+ ($self: expr, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $raa_first_dropped_cs: expr) => {
+ if $action_type != RAACommitmentOrder::RevokeAndACKFirst { panic!("Bad return_monitor_err call!"); }
+ return_monitor_err!($self, $err, $channel_state, $entry, $action_type, Vec::new(), Vec::new(), $raa_first_dropped_cs)
+ };
+ ($self: expr, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $failed_forwards: expr, $failed_fails: expr) => {
+ return_monitor_err!($self, $err, $channel_state, $entry, $action_type, $failed_forwards, $failed_fails, false)
+ };
+ ($self: expr, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $failed_forwards: expr, $failed_fails: expr, $raa_first_dropped_cs: expr) => {
+ match $err {
+ ChannelMonitorUpdateErr::PermanentFailure => {
+ let (channel_id, mut chan) = $entry.remove_entry();
+ if let Some(short_id) = chan.get_short_channel_id() {
+ $channel_state.short_to_id.remove(&short_id);
+ }
+ // TODO: $failed_fails is dropped here, which will cause other channels to hit the
+ // chain in a confused state! We need to move them into the ChannelMonitor which
+ // will be responsible for failing backwards once things confirm on-chain.
+ // It's ok that we drop $failed_forwards here - at this point we'd rather they
+ // broadcast HTLC-Timeout and pay the associated fees to get their funds back than
+ // us bother trying to claim it just to forward on to another peer. If we're
+ // splitting hairs we'd prefer to claim payments that were to us, but we haven't
+ // given up the preimage yet, so might as well just wait until the payment is
+ // retried, avoiding the on-chain fees.
+ return Err(MsgHandleErrInternal::from_finish_shutdown("ChannelMonitor storage failure", channel_id, chan.force_shutdown(), $self.get_channel_update(&chan).ok()))
+ },
+ ChannelMonitorUpdateErr::TemporaryFailure => {
+ $entry.get_mut().monitor_update_failed($action_type, $failed_forwards, $failed_fails, $raa_first_dropped_cs);
+ return Err(MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore("Failed to update ChannelMonitor"), *$entry.key()));
+ },
+ }
+ }
+}
+
+// Does not break in case of TemporaryFailure!
+macro_rules! maybe_break_monitor_err {
+ ($self: expr, $err: expr, $channel_state: expr, $entry: expr, $action_type: path) => {
+ match $err {
+ ChannelMonitorUpdateErr::PermanentFailure => {
+ let (channel_id, mut chan) = $entry.remove_entry();
+ if let Some(short_id) = chan.get_short_channel_id() {
+ $channel_state.short_to_id.remove(&short_id);
+ }
+ break Err(MsgHandleErrInternal::from_finish_shutdown("ChannelMonitor storage failure", channel_id, chan.force_shutdown(), $self.get_channel_update(&chan).ok()))
+ },
+ ChannelMonitorUpdateErr::TemporaryFailure => {
+ $entry.get_mut().monitor_update_failed($action_type, Vec::new(), Vec::new(), false);
+ },
+ }
+ }