Merge pull request #1504 from TheBlueMatt/2022-05-pub-io
[rust-lightning] / lightning / src / ln / channelmanager.rs
index f92787a0a48b11ef1d405e4dfe7395eaf9bfa0c9..17a52e29e4a5eecb210fe9d3f10c2edc4306f233 100644 (file)
@@ -93,6 +93,8 @@ use util::crypto::sign;
 pub(super) enum PendingHTLCRouting {
        Forward {
                onion_packet: msgs::OnionPacket,
+               /// The SCID from the onion that we should forward to. This could be a "real" SCID, an
+               /// outbound SCID alias, or a phantom node SCID.
                short_channel_id: u64, // This should be NonZero<u64> eventually when we bump MSRV
        },
        Receive {
@@ -136,6 +138,8 @@ pub(super) enum HTLCForwardInfo {
                // `process_pending_htlc_forwards()` for constructing the
                // `HTLCSource::PreviousHopData` for failed and forwarded
                // HTLCs.
+               //
+               // Note that this may be an outbound SCID alias for the associated channel.
                prev_short_channel_id: u64,
                prev_htlc_id: u64,
                prev_funding_outpoint: OutPoint,
@@ -149,6 +153,7 @@ pub(super) enum HTLCForwardInfo {
 /// Tracks the inbound corresponding to an outbound HTLC
 #[derive(Clone, Hash, PartialEq, Eq)]
 pub(crate) struct HTLCPreviousHopData {
+       // Note that this may be an outbound SCID alias for the associated channel.
        short_channel_id: u64,
        htlc_id: u64,
        incoming_packet_shared_secret: [u8; 32],
@@ -414,7 +419,9 @@ pub(super) struct ChannelHolder<Signer: Sign> {
        /// guarantees are made about the existence of a channel with the short id here, nor the short
        /// ids in the PendingHTLCInfo!
        pub(super) forward_htlcs: HashMap<u64, Vec<HTLCForwardInfo>>,
-       /// Map from payment hash to any HTLCs which are to us and can be failed/claimed by the user.
+       /// Map from payment hash to the payment data and any HTLCs which are to us and can be
+       /// failed/claimed by the user.
+       ///
        /// Note that while this is held in the same mutex as the channels themselves, no consistency
        /// guarantees are made about the channels given here actually existing anymore by the time you
        /// go to read them!
@@ -963,9 +970,25 @@ pub struct ChannelDetails {
        /// Note that if [`inbound_scid_alias`] is set, it must be used for invoices and inbound
        /// payments instead of this. See [`get_inbound_payment_scid`].
        ///
+       /// For channels with [`confirmations_required`] set to `Some(0)`, [`outbound_scid_alias`] may
+       /// be used in place of this in outbound routes. See [`get_outbound_payment_scid`].
+       ///
        /// [`inbound_scid_alias`]: Self::inbound_scid_alias
+       /// [`outbound_scid_alias`]: Self::outbound_scid_alias
        /// [`get_inbound_payment_scid`]: Self::get_inbound_payment_scid
+       /// [`get_outbound_payment_scid`]: Self::get_outbound_payment_scid
+       /// [`confirmations_required`]: Self::confirmations_required
        pub short_channel_id: Option<u64>,
+       /// An optional [`short_channel_id`] alias for this channel, randomly generated by us and
+       /// usable in place of [`short_channel_id`] to reference the channel in outbound routes when
+       /// the channel has not yet been confirmed (as long as [`confirmations_required`] is
+       /// `Some(0)`).
+       ///
+       /// This will be `None` as long as the channel is not available for routing outbound payments.
+       ///
+       /// [`short_channel_id`]: Self::short_channel_id
+       /// [`confirmations_required`]: Self::confirmations_required
+       pub outbound_scid_alias: Option<u64>,
        /// An optional [`short_channel_id`] alias for this channel, randomly generated by our
        /// counterparty and usable in place of [`short_channel_id`] in invoice route hints. Our
        /// counterparty will recognize the alias provided here in place of the [`short_channel_id`]
@@ -1051,18 +1074,18 @@ pub struct ChannelDetails {
        pub force_close_spend_delay: Option<u16>,
        /// True if the channel was initiated (and thus funded) by us.
        pub is_outbound: bool,
-       /// True if the channel is confirmed, funding_locked messages have been exchanged, and the
-       /// channel is not currently being shut down. `funding_locked` message exchange implies the
+       /// True if the channel is confirmed, channel_ready messages have been exchanged, and the
+       /// channel is not currently being shut down. `channel_ready` message exchange implies the
        /// required confirmation count has been reached (and we were connected to the peer at some
        /// point after the funding transaction received enough confirmations). The required
        /// confirmation count is provided in [`confirmations_required`].
        ///
        /// [`confirmations_required`]: ChannelDetails::confirmations_required
-       pub is_funding_locked: bool,
-       /// True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b)
+       pub is_channel_ready: bool,
+       /// True if the channel is (a) confirmed and channel_ready messages have been exchanged, (b)
        /// the peer is connected, and (c) the channel is not currently negotiating a shutdown.
        ///
-       /// This is a strict superset of `is_funding_locked`.
+       /// This is a strict superset of `is_channel_ready`.
        pub is_usable: bool,
        /// True if this channel is (or will be) publicly-announced.
        pub is_public: bool,
@@ -1083,6 +1106,16 @@ impl ChannelDetails {
        pub fn get_inbound_payment_scid(&self) -> Option<u64> {
                self.inbound_scid_alias.or(self.short_channel_id)
        }
+
+       /// Gets the current SCID which should be used to identify this channel for outbound payments.
+       /// This should be used in [`Route`]s to describe the first hop or in other contexts where
+       /// we're sending or forwarding a payment outbound over this channel.
+       ///
+       /// This is either the [`ChannelDetails::short_channel_id`], if set, or the
+       /// [`ChannelDetails::outbound_scid_alias`]. See those for more information.
+       pub fn get_outbound_payment_scid(&self) -> Option<u64> {
+               self.short_channel_id.or(self.outbound_scid_alias)
+       }
 }
 
 /// If a payment fails to send, it can be in one of several states. This enum is returned as the
@@ -1281,7 +1314,7 @@ macro_rules! remove_channel {
 }
 
 macro_rules! handle_monitor_err {
-       ($self: ident, $err: expr, $short_to_id: expr, $chan: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr, $failed_forwards: expr, $failed_fails: expr, $failed_finalized_fulfills: expr, $chan_id: expr) => {
+       ($self: ident, $err: expr, $short_to_id: expr, $chan: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr, $resend_channel_ready: expr, $failed_forwards: expr, $failed_fails: expr, $failed_finalized_fulfills: expr, $chan_id: expr) => {
                match $err {
                        ChannelMonitorUpdateErr::PermanentFailure => {
                                log_error!($self.logger, "Closing channel {} due to monitor update ChannelMonitorUpdateErr::PermanentFailure", log_bytes!($chan_id[..]));
@@ -1319,13 +1352,13 @@ macro_rules! handle_monitor_err {
                                if !$resend_raa {
                                        debug_assert!($action_type == RAACommitmentOrder::CommitmentFirst || !$resend_commitment);
                                }
-                               $chan.monitor_update_failed($resend_raa, $resend_commitment, $failed_forwards, $failed_fails, $failed_finalized_fulfills);
+                               $chan.monitor_update_failed($resend_raa, $resend_commitment, $resend_channel_ready, $failed_forwards, $failed_fails, $failed_finalized_fulfills);
                                (Err(MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore("Failed to update ChannelMonitor".to_owned()), *$chan_id)), false)
                        },
                }
        };
-       ($self: ident, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr, $failed_forwards: expr, $failed_fails: expr, $failed_finalized_fulfills: expr) => { {
-               let (res, drop) = handle_monitor_err!($self, $err, $channel_state.short_to_id, $entry.get_mut(), $action_type, $resend_raa, $resend_commitment, $failed_forwards, $failed_fails, $failed_finalized_fulfills, $entry.key());
+       ($self: ident, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr, $resend_channel_ready: expr, $failed_forwards: expr, $failed_fails: expr, $failed_finalized_fulfills: expr) => { {
+               let (res, drop) = handle_monitor_err!($self, $err, $channel_state.short_to_id, $entry.get_mut(), $action_type, $resend_raa, $resend_commitment, $resend_channel_ready, $failed_forwards, $failed_fails, $failed_finalized_fulfills, $entry.key());
                if drop {
                        $entry.remove_entry();
                }
@@ -1333,16 +1366,19 @@ macro_rules! handle_monitor_err {
        } };
        ($self: ident, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $chan_id: expr, COMMITMENT_UPDATE_ONLY) => { {
                debug_assert!($action_type == RAACommitmentOrder::CommitmentFirst);
-               handle_monitor_err!($self, $err, $channel_state, $entry, $action_type, false, true, Vec::new(), Vec::new(), Vec::new(), $chan_id)
+               handle_monitor_err!($self, $err, $channel_state, $entry, $action_type, false, true, false, Vec::new(), Vec::new(), Vec::new(), $chan_id)
        } };
        ($self: ident, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $chan_id: expr, NO_UPDATE) => {
-               handle_monitor_err!($self, $err, $channel_state, $entry, $action_type, false, false, Vec::new(), Vec::new(), Vec::new(), $chan_id)
+               handle_monitor_err!($self, $err, $channel_state, $entry, $action_type, false, false, false, Vec::new(), Vec::new(), Vec::new(), $chan_id)
+       };
+       ($self: ident, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $resend_channel_ready: expr, OPTIONALLY_RESEND_FUNDING_LOCKED) => {
+               handle_monitor_err!($self, $err, $channel_state, $entry, $action_type, false, false, $resend_channel_ready, Vec::new(), Vec::new(), Vec::new())
        };
        ($self: ident, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr) => {
-               handle_monitor_err!($self, $err, $channel_state, $entry, $action_type, $resend_raa, $resend_commitment, Vec::new(), Vec::new(), Vec::new())
+               handle_monitor_err!($self, $err, $channel_state, $entry, $action_type, $resend_raa, $resend_commitment, false, Vec::new(), Vec::new(), Vec::new())
        };
        ($self: ident, $err: expr, $channel_state: expr, $entry: expr, $action_type: path, $resend_raa: expr, $resend_commitment: expr, $failed_forwards: expr, $failed_fails: expr) => {
-               handle_monitor_err!($self, $err, $channel_state, $entry, $action_type, $resend_raa, $resend_commitment, $failed_forwards, $failed_fails, Vec::new())
+               handle_monitor_err!($self, $err, $channel_state, $entry, $action_type, $resend_raa, $resend_commitment, false, $failed_forwards, $failed_fails, Vec::new())
        };
 }
 
@@ -1367,13 +1403,13 @@ macro_rules! maybe_break_monitor_err {
        }
 }
 
-macro_rules! send_funding_locked {
-       ($short_to_id: expr, $pending_msg_events: expr, $channel: expr, $funding_locked_msg: expr) => {
-               $pending_msg_events.push(events::MessageSendEvent::SendFundingLocked {
+macro_rules! send_channel_ready {
+       ($short_to_id: expr, $pending_msg_events: expr, $channel: expr, $channel_ready_msg: expr) => {
+               $pending_msg_events.push(events::MessageSendEvent::SendChannelReady {
                        node_id: $channel.get_counterparty_node_id(),
-                       msg: $funding_locked_msg,
+                       msg: $channel_ready_msg,
                });
-               // Note that we may send a funding locked multiple times for a channel if we reconnect, so
+               // Note that we may send a `channel_ready` multiple times for a channel if we reconnect, so
                // we allow collisions, but we shouldn't ever be updating the channel ID pointed to.
                let outbound_alias_insert = $short_to_id.insert($channel.outbound_scid_alias(), $channel.channel_id());
                assert!(outbound_alias_insert.is_none() || outbound_alias_insert.unwrap() == $channel.channel_id(),
@@ -1389,7 +1425,7 @@ macro_rules! send_funding_locked {
 macro_rules! handle_chan_restoration_locked {
        ($self: ident, $channel_lock: expr, $channel_state: expr, $channel_entry: expr,
         $raa: expr, $commitment_update: expr, $order: expr, $chanmon_update: expr,
-        $pending_forwards: expr, $funding_broadcastable: expr, $funding_locked: expr, $announcement_sigs: expr) => { {
+        $pending_forwards: expr, $funding_broadcastable: expr, $channel_ready: expr, $announcement_sigs: expr) => { {
                let mut htlc_forwards = None;
 
                let chanmon_update: Option<ChannelMonitorUpdate> = $chanmon_update; // Force type-checking to resolve
@@ -1398,29 +1434,29 @@ macro_rules! handle_chan_restoration_locked {
                let res = loop {
                        let forwards: Vec<(PendingHTLCInfo, u64)> = $pending_forwards; // Force type-checking to resolve
                        if !forwards.is_empty() {
-                               htlc_forwards = Some(($channel_entry.get().get_short_channel_id().expect("We can't have pending forwards before funding confirmation"),
+                               htlc_forwards = Some(($channel_entry.get().get_short_channel_id().unwrap_or($channel_entry.get().outbound_scid_alias()),
                                        $channel_entry.get().get_funding_txo().unwrap(), forwards));
                        }
 
                        if chanmon_update.is_some() {
-                               // On reconnect, we, by definition, only resend a funding_locked if there have been
+                               // On reconnect, we, by definition, only resend a channel_ready if there have been
                                // no commitment updates, so the only channel monitor update which could also be
-                               // associated with a funding_locked would be the funding_created/funding_signed
+                               // associated with a channel_ready would be the funding_created/funding_signed
                                // monitor update. That monitor update failing implies that we won't send
-                               // funding_locked until it's been updated, so we can't have a funding_locked and a
+                               // channel_ready until it's been updated, so we can't have a channel_ready and a
                                // monitor update here (so we don't bother to handle it correctly below).
-                               assert!($funding_locked.is_none());
-                               // A channel monitor update makes no sense without either a funding_locked or a
-                               // commitment update to process after it. Since we can't have a funding_locked, we
+                               assert!($channel_ready.is_none());
+                               // A channel monitor update makes no sense without either a channel_ready or a
+                               // commitment update to process after it. Since we can't have a channel_ready, we
                                // only bother to handle the monitor-update + commitment_update case below.
                                assert!($commitment_update.is_some());
                        }
 
-                       if let Some(msg) = $funding_locked {
-                               // Similar to the above, this implies that we're letting the funding_locked fly
+                       if let Some(msg) = $channel_ready {
+                               // Similar to the above, this implies that we're letting the channel_ready fly
                                // before it should be allowed to.
                                assert!(chanmon_update.is_none());
-                               send_funding_locked!($channel_state.short_to_id, $channel_state.pending_msg_events, $channel_entry.get(), msg);
+                               send_channel_ready!($channel_state.short_to_id, $channel_state.pending_msg_events, $channel_entry.get(), msg);
                        }
                        if let Some(msg) = $announcement_sigs {
                                $channel_state.pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures {
@@ -1706,6 +1742,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        // `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,
@@ -1717,7 +1754,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        confirmations_required: channel.minimum_depth(),
                                        force_close_spend_delay: channel.get_counterparty_selected_contest_delay(),
                                        is_outbound: channel.is_outbound(),
-                                       is_funding_locked: channel.is_usable(),
+                                       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()),
@@ -2258,7 +2295,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                        msg.cltv_expiry.write(&mut res).expect("Writes cannot fail");
                                                }
                                                else if code == 0x1000 | 20 {
-                                                       // TODO: underspecified, follow https://github.com/lightningnetwork/lightning-rfc/issues/791
+                                                       // TODO: underspecified, follow https://github.com/lightning/bolts/issues/791
                                                        0u16.write(&mut res).expect("Writes cannot fail");
                                                }
                                                (chan_update.serialized_length() as u16 + 2).write(&mut res).expect("Writes cannot fail");
@@ -2285,6 +2322,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                action: msgs::ErrorAction::IgnoreError
                        });
                }
+               if chan.get_short_channel_id().is_none() {
+                       return Err(LightningError{err: "Channel not yet established".to_owned(), action: msgs::ErrorAction::IgnoreError});
+               }
                log_trace!(self.logger, "Attempting to generate broadcast channel update for channel {}", log_bytes!(chan.channel_id()));
                self.get_channel_update_for_unicast(chan)
        }
@@ -2296,7 +2336,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        /// May be called with channel_state already locked!
        fn get_channel_update_for_unicast(&self, chan: &Channel<Signer>) -> Result<msgs::ChannelUpdate, LightningError> {
                log_trace!(self.logger, "Attempting to generate channel update for channel {}", log_bytes!(chan.channel_id()));
-               let short_channel_id = match chan.get_short_channel_id() {
+               let short_channel_id = match chan.get_short_channel_id().or(chan.latest_inbound_scid_alias()) {
                        None => return Err(LightningError{err: "Channel not yet established".to_owned(), action: msgs::ErrorAction::IgnoreError}),
                        Some(id) => id,
                };
@@ -2861,7 +2901,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                });
                                announced_chans = true;
                        } else {
-                               // If the channel is not public or has not yet reached funding_locked, check the
+                               // If the channel is not public or has not yet reached channel_ready, check the
                                // next channel. If we don't yet have any public channels, we'll skip the broadcast
                                // below as peers may not accept it without channels on chain first.
                        }
@@ -3182,7 +3222,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                                        new_events.push(events::Event::PaymentReceived {
                                                                                                payment_hash,
                                                                                                purpose: purpose(),
-                                                                                               amt: total_value,
+                                                                                               amount_msat: total_value,
                                                                                        });
                                                                                        payment_received_generated = true;
                                                                                } else {
@@ -3223,7 +3263,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                                                                e.insert((purpose.clone(), vec![claimable_htlc]));
                                                                                                                new_events.push(events::Event::PaymentReceived {
                                                                                                                        payment_hash,
-                                                                                                                       amt: amt_to_forward,
+                                                                                                                       amount_msat: amt_to_forward,
                                                                                                                        purpose,
                                                                                                                });
                                                                                                        },
@@ -3500,9 +3540,17 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        /// Indicates that the preimage for payment_hash is unknown or the received amount is incorrect
        /// after a PaymentReceived event, failing the HTLC back to its origin and freeing resources
        /// along the path (including in our own channel on which we received it).
-       /// Returns false if no payment was found to fail backwards, true if the process of failing the
-       /// HTLC backwards has been started.
-       pub fn fail_htlc_backwards(&self, payment_hash: &PaymentHash) -> bool {
+       ///
+       /// Note that in some cases around unclean shutdown, it is possible the payment may have
+       /// already been claimed by you via [`ChannelManager::claim_funds`] prior to you seeing (a
+       /// second copy of) the [`events::Event::PaymentReceived`] event. Alternatively, the payment
+       /// may have already been failed automatically by LDK if it was nearing its expiration time.
+       ///
+       /// While LDK will never claim a payment automatically on your behalf (i.e. without you calling
+       /// [`ChannelManager::claim_funds`]), you should still monitor for
+       /// [`events::Event::PaymentClaimed`] events even for payments you intend to fail, especially on
+       /// startup during which time claims that were in-progress at shutdown may be replayed.
+       pub fn fail_htlc_backwards(&self, payment_hash: &PaymentHash) {
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
 
                let mut channel_state = Some(self.channel_state.lock().unwrap());
@@ -3517,8 +3565,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                HTLCSource::PreviousHopData(htlc.prev_hop), payment_hash,
                                                HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: htlc_msat_height_data });
                        }
-                       true
-               } else { false }
+               }
        }
 
        /// Gets an HTLC onion failure code and error data for an `UPDATE` error, given the error code
@@ -3899,7 +3946,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                self.pending_events.lock().unwrap().push(events::Event::PaymentClaimed {
                                        payment_hash,
                                        purpose: payment_purpose,
-                                       amt: claimable_amt_msat,
+                                       amount_msat: claimable_amt_msat,
                                });
                        }
 
@@ -4128,9 +4175,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                        }
 
                        let updates = channel.get_mut().monitor_updating_restored(&self.logger, self.get_our_node_id(), self.genesis_hash, self.best_block.read().unwrap().height());
-                       let channel_update = if updates.funding_locked.is_some() && channel.get().is_usable() {
+                       let channel_update = if updates.channel_ready.is_some() && channel.get().is_usable() {
                                // We only send a channel_update in the case where we are just now sending a
-                               // funding_locked and the channel is in a usable state. We may re-send a
+                               // channel_ready and the channel is in a usable state. We may re-send a
                                // channel_update later through the announcement_signatures process for public
                                // channels, but there's no reason not to just inform our counterparty of our fees
                                // now.
@@ -4141,7 +4188,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        })
                                } else { None }
                        } else { None };
-                       chan_restoration_res = handle_chan_restoration_locked!(self, channel_lock, channel_state, channel, updates.raa, updates.commitment_update, updates.order, None, updates.accepted_htlcs, updates.funding_broadcastable, updates.funding_locked, updates.announcement_sigs);
+                       chan_restoration_res = handle_chan_restoration_locked!(self, channel_lock, channel_state, channel, updates.raa, updates.commitment_update, updates.order, None, updates.accepted_htlcs, updates.funding_broadcastable, updates.channel_ready, updates.announcement_sigs);
                        if let Some(upd) = channel_update {
                                channel_state.pending_msg_events.push(upd);
                        }
@@ -4154,20 +4201,45 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                }
        }
 
-       /// Called to accept a request to open a channel after [`Event::OpenChannelRequest`] has been
-       /// triggered.
+       /// Accepts a request to open a channel after a [`Event::OpenChannelRequest`].
        ///
        /// The `temporary_channel_id` parameter indicates which inbound channel should be accepted,
        /// and the `counterparty_node_id` parameter is the id of the peer which has requested to open
        /// the channel.
        ///
-       /// For inbound channels, the `user_channel_id` parameter will be provided back in
+       /// The `user_channel_id` parameter will be provided back in
        /// [`Event::ChannelClosed::user_channel_id`] to allow tracking of which events correspond
-       /// with which `accept_inbound_channel` call.
+       /// with which `accept_inbound_channel`/`accept_inbound_channel_from_trusted_peer_0conf` call.
        ///
        /// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
        /// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
        pub fn accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, user_channel_id: u64) -> Result<(), APIError> {
+               self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, false, user_channel_id)
+       }
+
+       /// Accepts a request to open a channel after a [`events::Event::OpenChannelRequest`], treating
+       /// it as confirmed immediately.
+       ///
+       /// The `user_channel_id` parameter will be provided back in
+       /// [`Event::ChannelClosed::user_channel_id`] to allow tracking of which events correspond
+       /// with which `accept_inbound_channel`/`accept_inbound_channel_from_trusted_peer_0conf` call.
+       ///
+       /// Unlike [`ChannelManager::accept_inbound_channel`], this method accepts the incoming channel
+       /// and (if the counterparty agrees), enables forwarding of payments immediately.
+       ///
+       /// This fully trusts that the counterparty has honestly and correctly constructed the funding
+       /// transaction and blindly assumes that it will eventually confirm.
+       ///
+       /// If it does not confirm before we decide to close the channel, or if the funding transaction
+       /// does not pay to the correct script the correct amount, *you will lose funds*.
+       ///
+       /// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
+       /// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
+       pub fn accept_inbound_channel_from_trusted_peer_0conf(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, user_channel_id: u64) -> Result<(), APIError> {
+               self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, true, user_channel_id)
+       }
+
+       fn do_accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, accept_0conf: bool, user_channel_id: u64) -> Result<(), APIError> {
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
 
                let mut channel_state_lock = self.channel_state.lock().unwrap();
@@ -4180,6 +4252,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                if *counterparty_node_id != channel.get().get_counterparty_node_id() {
                                        return Err(APIError::APIMisuseError { err: "The passed counterparty_node_id doesn't match the channel's counterparty node_id".to_owned() });
                                }
+                               if accept_0conf { channel.get_mut().set_0conf(); }
                                channel_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
                                        node_id: channel.get().get_counterparty_node_id(),
                                        msg: channel.get_mut().accept_inbound_channel(user_channel_id),
@@ -4271,7 +4344,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        }
 
        fn internal_funding_created(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result<(), MsgHandleErrInternal> {
-               let ((funding_msg, monitor), mut chan) = {
+               let ((funding_msg, monitor, mut channel_ready), mut chan) = {
                        let best_block = *self.best_block.read().unwrap();
                        let mut channel_lock = self.channel_state.lock().unwrap();
                        let channel_state = &mut *channel_lock;
@@ -4304,9 +4377,10 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                ChannelMonitorUpdateErr::TemporaryFailure => {
                                        // There's no problem signing a counterparty's funding transaction if our monitor
                                        // hasn't persisted to disk yet - we can't lose money on a transaction that we haven't
-                                       // accepted payment from yet. We do, however, need to wait to send our funding_locked
+                                       // accepted payment from yet. We do, however, need to wait to send our channel_ready
                                        // until we have persisted our monitor.
-                                       chan.monitor_update_failed(false, false, Vec::new(), Vec::new(), Vec::new());
+                                       chan.monitor_update_failed(false, false, channel_ready.is_some(), Vec::new(), Vec::new(), Vec::new());
+                                       channel_ready = None; // Don't send the channel_ready now
                                },
                        }
                }
@@ -4321,6 +4395,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        node_id: counterparty_node_id.clone(),
                                        msg: funding_msg,
                                });
+                               if let Some(msg) = channel_ready {
+                                       send_channel_ready!(channel_state.short_to_id, channel_state.pending_msg_events, chan, msg);
+                               }
                                e.insert(chan);
                        }
                }
@@ -4337,12 +4414,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        if chan.get().get_counterparty_node_id() != *counterparty_node_id {
                                                return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
                                        }
-                                       let (monitor, funding_tx) = match chan.get_mut().funding_signed(&msg, best_block, &self.logger) {
+                                       let (monitor, funding_tx, channel_ready) = match chan.get_mut().funding_signed(&msg, best_block, &self.logger) {
                                                Ok(update) => update,
                                                Err(e) => try_chan_entry!(self, Err(e), channel_state, chan),
                                        };
                                        if let Err(e) = self.chain_monitor.watch_channel(chan.get().get_funding_txo().unwrap(), monitor) {
-                                               let mut res = handle_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::RevokeAndACKFirst, false, false);
+                                               let mut res = handle_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::RevokeAndACKFirst, channel_ready.is_some(), OPTIONALLY_RESEND_FUNDING_LOCKED);
                                                if let Err(MsgHandleErrInternal { ref mut shutdown_finish, .. }) = res {
                                                        // We weren't able to watch the channel to begin with, so no updates should be made on
                                                        // it. Previously, full_stack_target found an (unreachable) panic when the
@@ -4353,6 +4430,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                }
                                                return res
                                        }
+                                       if let Some(msg) = channel_ready {
+                                               send_channel_ready!(channel_state.short_to_id, channel_state.pending_msg_events, chan.get(), msg);
+                                       }
                                        funding_tx
                                },
                                hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
@@ -4363,7 +4443,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                Ok(())
        }
 
-       fn internal_funding_locked(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingLocked) -> Result<(), MsgHandleErrInternal> {
+       fn internal_channel_ready(&self, counterparty_node_id: &PublicKey, msg: &msgs::ChannelReady) -> Result<(), MsgHandleErrInternal> {
                let mut channel_state_lock = self.channel_state.lock().unwrap();
                let channel_state = &mut *channel_state_lock;
                match channel_state.by_id.entry(msg.channel_id) {
@@ -4371,7 +4451,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                if chan.get().get_counterparty_node_id() != *counterparty_node_id {
                                        return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
                                }
-                               let announcement_sigs_opt = try_chan_entry!(self, chan.get_mut().funding_locked(&msg, self.get_our_node_id(),
+                               let announcement_sigs_opt = try_chan_entry!(self, chan.get_mut().channel_ready(&msg, self.get_our_node_id(),
                                        self.genesis_hash.clone(), &self.best_block.read().unwrap(), &self.logger), channel_state, chan);
                                if let Some(announcement_sigs) = announcement_sigs_opt {
                                        log_trace!(self.logger, "Sending announcement_signatures for channel {}", log_bytes!(chan.get().channel_id()));
@@ -4703,7 +4783,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                } else {
                                                        if let Err(e) = handle_monitor_err!(self, e, channel_state, chan,
                                                                        RAACommitmentOrder::CommitmentFirst, false,
-                                                                       raa_updates.commitment_update.is_some(),
+                                                                       raa_updates.commitment_update.is_some(), false,
                                                                        raa_updates.accepted_htlcs, raa_updates.failed_htlcs,
                                                                        raa_updates.finalized_claimed_htlcs) {
                                                                break Err(e);
@@ -4719,7 +4799,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        break Ok((raa_updates.accepted_htlcs, raa_updates.failed_htlcs,
                                                        raa_updates.finalized_claimed_htlcs,
                                                        chan.get().get_short_channel_id()
-                                                               .expect("RAA should only work on a short-id-available channel"),
+                                                               .unwrap_or(chan.get().outbound_scid_alias()),
                                                        chan.get().get_funding_txo().unwrap()))
                                },
                                hash_map::Entry::Vacant(_) => break Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
@@ -4855,7 +4935,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        let need_lnd_workaround = chan.get_mut().workaround_lnd_bug_4006.take();
                                        chan_restoration_res = handle_chan_restoration_locked!(
                                                self, channel_state_lock, channel_state, chan, responses.raa, responses.commitment_update, responses.order,
-                                               responses.mon_update, Vec::new(), None, responses.funding_locked, responses.announcement_sigs);
+                                               responses.mon_update, Vec::new(), None, responses.channel_ready, responses.announcement_sigs);
                                        if let Some(upd) = channel_update {
                                                channel_state.pending_msg_events.push(upd);
                                        }
@@ -4867,8 +4947,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                post_handle_chan_restoration!(self, chan_restoration_res);
                self.fail_holding_cell_htlcs(htlcs_failed_forward, msg.channel_id);
 
-               if let Some(funding_locked_msg) = need_lnd_workaround {
-                       self.internal_funding_locked(counterparty_node_id, &funding_locked_msg)?;
+               if let Some(channel_ready_msg) = need_lnd_workaround {
+                       self.internal_channel_ready(counterparty_node_id, &channel_ready_msg)?;
                }
                Ok(())
        }
@@ -4884,7 +4964,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        MonitorEvent::HTLCEvent(htlc_update) => {
                                                if let Some(preimage) = htlc_update.payment_preimage {
                                                        log_trace!(self.logger, "Claiming HTLC with preimage {} from our monitor", log_bytes!(preimage.0));
-                                                       self.claim_funds_internal(self.channel_state.lock().unwrap(), htlc_update.source, preimage, htlc_update.onchain_value_satoshis.map(|v| v * 1000), true, funding_outpoint.to_channel_id());
+                                                       self.claim_funds_internal(self.channel_state.lock().unwrap(), htlc_update.source, preimage, htlc_update.htlc_value_satoshis.map(|v| v * 1000), true, funding_outpoint.to_channel_id());
                                                } else {
                                                        log_trace!(self.logger, "Failing HTLC with hash {} from our monitor", log_bytes!(htlc_update.payment_hash.0));
                                                        self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_update.source, &htlc_update.payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() });
@@ -5505,7 +5585,7 @@ where
        /// Calls a function which handles an on-chain event (blocks dis/connected, transactions
        /// un/confirmed, etc) on each channel, handling any resulting errors or messages generated by
        /// the function.
-       fn do_chain_event<FN: Fn(&mut Channel<Signer>) -> Result<(Option<msgs::FundingLocked>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason>>
+       fn do_chain_event<FN: Fn(&mut Channel<Signer>) -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason>>
                        (&self, height_opt: Option<u32>, f: FN) {
                // Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
                // during initialization prior to the chain_monitor being fully configured in some cases.
@@ -5520,17 +5600,17 @@ where
                        let pending_msg_events = &mut channel_state.pending_msg_events;
                        channel_state.by_id.retain(|_, channel| {
                                let res = f(channel);
-                               if let Ok((funding_locked_opt, mut timed_out_pending_htlcs, announcement_sigs)) = res {
+                               if let Ok((channel_ready_opt, mut timed_out_pending_htlcs, announcement_sigs)) = res {
                                        for (source, payment_hash) in timed_out_pending_htlcs.drain(..) {
                                                let (failure_code, data) = self.get_htlc_inbound_temp_fail_err_and_data(0x1000|14 /* expiry_too_soon */, &channel);
                                                timed_out_htlcs.push((source, payment_hash, HTLCFailReason::Reason {
                                                        failure_code, data,
                                                }));
                                        }
-                                       if let Some(funding_locked) = funding_locked_opt {
-                                               send_funding_locked!(short_to_id, pending_msg_events, channel, funding_locked);
+                                       if let Some(channel_ready) = channel_ready_opt {
+                                               send_channel_ready!(short_to_id, pending_msg_events, channel, channel_ready);
                                                if channel.is_usable() {
-                                                       log_trace!(self.logger, "Sending funding_locked with private initial channel_update for our counterparty on channel {}", log_bytes!(channel.channel_id()));
+                                                       log_trace!(self.logger, "Sending channel_ready with private initial channel_update for our counterparty on channel {}", log_bytes!(channel.channel_id()));
                                                        if let Ok(msg) = self.get_channel_update_for_unicast(channel) {
                                                                pending_msg_events.push(events::MessageSendEvent::SendChannelUpdate {
                                                                        node_id: channel.get_counterparty_node_id(),
@@ -5538,7 +5618,7 @@ where
                                                                });
                                                        }
                                                } else {
-                                                       log_trace!(self.logger, "Sending funding_locked WITHOUT channel_update for {}", log_bytes!(channel.channel_id()));
+                                                       log_trace!(self.logger, "Sending channel_ready WITHOUT channel_update for {}", log_bytes!(channel.channel_id()));
                                                }
                                        }
                                        if let Some(announcement_sigs) = announcement_sigs {
@@ -5558,6 +5638,19 @@ where
                                                        }
                                                }
                                        }
+                                       if channel.is_our_channel_ready() {
+                                               if let Some(real_scid) = channel.get_short_channel_id() {
+                                                       // If we sent a 0conf channel_ready, and now have an SCID, we add it
+                                                       // to the short_to_id map here. Note that we check whether we can relay
+                                                       // using the real SCID at relay-time (i.e. enforce option_scid_alias
+                                                       // then), and if the funding tx is ever un-confirmed we force-close the
+                                                       // channel, ensuring short_to_id is always consistent.
+                                                       let scid_insert = short_to_id.insert(real_scid, channel.channel_id());
+                                                       assert!(scid_insert.is_none() || scid_insert.unwrap() == channel.channel_id(),
+                                                               "SCIDs should never collide - ensure you weren't behind by a full {} blocks when creating channels",
+                                                               fake_scid::MAX_SCID_BLOCKS_FROM_NOW);
+                                               }
+                                       }
                                } else if let Err(reason) = res {
                                        update_maps_on_chan_removal!(self, short_to_id, channel);
                                        // It looks like our counterparty went on-chain or funding transaction was
@@ -5672,9 +5765,9 @@ impl<Signer: Sign, M: Deref , T: Deref , K: Deref , F: Deref , L: Deref >
                let _ = handle_error!(self, self.internal_funding_signed(counterparty_node_id, msg), *counterparty_node_id);
        }
 
-       fn handle_funding_locked(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingLocked) {
+       fn handle_channel_ready(&self, counterparty_node_id: &PublicKey, msg: &msgs::ChannelReady) {
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
-               let _ = handle_error!(self, self.internal_funding_locked(counterparty_node_id, msg), *counterparty_node_id);
+               let _ = handle_error!(self, self.internal_channel_ready(counterparty_node_id, msg), *counterparty_node_id);
        }
 
        fn handle_shutdown(&self, counterparty_node_id: &PublicKey, their_features: &InitFeatures, msg: &msgs::Shutdown) {
@@ -5772,7 +5865,7 @@ impl<Signer: Sign, M: Deref , T: Deref , K: Deref , F: Deref , L: Deref >
                                        &events::MessageSendEvent::SendOpenChannel { ref node_id, .. } => node_id != counterparty_node_id,
                                        &events::MessageSendEvent::SendFundingCreated { ref node_id, .. } => node_id != counterparty_node_id,
                                        &events::MessageSendEvent::SendFundingSigned { ref node_id, .. } => node_id != counterparty_node_id,
-                                       &events::MessageSendEvent::SendFundingLocked { ref node_id, .. } => node_id != counterparty_node_id,
+                                       &events::MessageSendEvent::SendChannelReady { ref node_id, .. } => node_id != counterparty_node_id,
                                        &events::MessageSendEvent::SendAnnouncementSignatures { ref node_id, .. } => node_id != counterparty_node_id,
                                        &events::MessageSendEvent::UpdateHTLCs { ref node_id, .. } => node_id != counterparty_node_id,
                                        &events::MessageSendEvent::SendRevokeAndACK { ref node_id, .. } => node_id != counterparty_node_id,
@@ -5970,6 +6063,7 @@ impl_writeable_tlv_based!(ChannelDetails, {
        (2, channel_id, required),
        (3, channel_type, option),
        (4, counterparty, required),
+       (5, outbound_scid_alias, option),
        (6, funding_txo, option),
        (8, short_channel_id, option),
        (10, channel_value_satoshis, required),
@@ -5984,7 +6078,7 @@ impl_writeable_tlv_based!(ChannelDetails, {
        (22, confirmations_required, option),
        (24, force_close_spend_delay, option),
        (26, is_outbound, required),
-       (28, is_funding_locked, required),
+       (28, is_channel_ready, required),
        (30, is_usable, required),
        (32, is_public, required),
        (33, inbound_htlc_minimum_msat, option),
@@ -6897,7 +6991,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
                                        pending_events_read.push(events::Event::PaymentClaimed {
                                                payment_hash,
                                                purpose: payment_purpose,
-                                               amt: claimable_amt_msat,
+                                               amount_msat: claimable_amt_msat,
                                        });
                                }
                        }
@@ -7558,12 +7652,12 @@ pub mod bench {
                Listen::block_connected(&node_a, &block, 1);
                Listen::block_connected(&node_b, &block, 1);
 
-               node_a.handle_funding_locked(&node_b.get_our_node_id(), &get_event_msg!(node_b_holder, MessageSendEvent::SendFundingLocked, node_a.get_our_node_id()));
+               node_a.handle_channel_ready(&node_b.get_our_node_id(), &get_event_msg!(node_b_holder, MessageSendEvent::SendChannelReady, node_a.get_our_node_id()));
                let msg_events = node_a.get_and_clear_pending_msg_events();
                assert_eq!(msg_events.len(), 2);
                match msg_events[0] {
-                       MessageSendEvent::SendFundingLocked { ref msg, .. } => {
-                               node_b.handle_funding_locked(&node_a.get_our_node_id(), msg);
+                       MessageSendEvent::SendChannelReady { ref msg, .. } => {
+                               node_b.handle_channel_ready(&node_a.get_our_node_id(), msg);
                                get_event_msg!(node_b_holder, MessageSendEvent::SendChannelUpdate, node_a.get_our_node_id());
                        },
                        _ => panic!(),