Merge pull request #1505 from tnull/2022-05-support-0conf-channeltype
[rust-lightning] / lightning / src / ln / channel.rs
index 43032c51a3c09cdc67988e96050835fd7a17d9d7..4daaf630ac4e57bd7c96ed73e401badf986236d1 100644 (file)
@@ -126,7 +126,7 @@ enum InboundHTLCState {
        /// signatures in a commitment_signed message.
        /// Implies AwaitingRemoteRevoke.
        ///
-       /// [BOLT #2]: https://github.com/lightningnetwork/lightning-rfc/blob/master/02-peer-protocol.md
+       /// [BOLT #2]: https://github.com/lightning/bolts/blob/master/02-peer-protocol.md
        AwaitingRemoteRevokeToAnnounce(PendingHTLCStatus),
        /// Included in a received commitment_signed message (implying we've revoke_and_ack'd it).
        /// We have also included this HTLC in our latest commitment_signed and are now just waiting
@@ -243,7 +243,7 @@ enum HTLCUpdateAwaitingACK {
 
 /// There are a few "states" and then a number of flags which can be applied:
 /// We first move through init with OurInitSent -> TheirInitSent -> FundingCreated -> FundingSent.
-/// TheirFundingLocked and OurFundingLocked then get set on FundingSent, and when both are set we
+/// TheirChannelReady and OurChannelReady then get set on FundingSent, and when both are set we
 /// move on to ChannelFunded.
 /// Note that PeerDisconnected can be set on both ChannelFunded and FundingSent.
 /// ChannelFunded can then get all remaining flags set on it, until we finish shutdown, then we
@@ -258,15 +258,15 @@ enum ChannelState {
        /// upon receipt of funding_created, so simply skip this state.
        FundingCreated = 4,
        /// Set when we have received/sent funding_created and funding_signed and are thus now waiting
-       /// on the funding transaction to confirm. The FundingLocked flags are set to indicate when we
+       /// on the funding transaction to confirm. The ChannelReady flags are set to indicate when we
        /// and our counterparty consider the funding transaction confirmed.
        FundingSent = 8,
-       /// Flag which can be set on FundingSent to indicate they sent us a funding_locked message.
-       /// Once both TheirFundingLocked and OurFundingLocked are set, state moves on to ChannelFunded.
-       TheirFundingLocked = 1 << 4,
-       /// Flag which can be set on FundingSent to indicate we sent them a funding_locked message.
-       /// Once both TheirFundingLocked and OurFundingLocked are set, state moves on to ChannelFunded.
-       OurFundingLocked = 1 << 5,
+       /// Flag which can be set on FundingSent to indicate they sent us a channel_ready message.
+       /// Once both TheirChannelReady and OurChannelReady are set, state moves on to ChannelFunded.
+       TheirChannelReady = 1 << 4,
+       /// Flag which can be set on FundingSent to indicate we sent them a channel_ready message.
+       /// Once both TheirChannelReady and OurChannelReady are set, state moves on to ChannelFunded.
+       OurChannelReady = 1 << 5,
        ChannelFunded = 64,
        /// Flag which is set on ChannelFunded and FundingSent indicating remote side is considered
        /// "disconnected" and no updates are allowed until after we've done a channel_reestablish
@@ -429,13 +429,13 @@ pub(super) struct MonitorRestoreUpdates {
        pub failed_htlcs: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>,
        pub finalized_claimed_htlcs: Vec<HTLCSource>,
        pub funding_broadcastable: Option<Transaction>,
-       pub funding_locked: Option<msgs::FundingLocked>,
+       pub channel_ready: Option<msgs::ChannelReady>,
        pub announcement_sigs: Option<msgs::AnnouncementSignatures>,
 }
 
 /// The return value of `channel_reestablish`
 pub(super) struct ReestablishResponses {
-       pub funding_locked: Option<msgs::FundingLocked>,
+       pub channel_ready: Option<msgs::ChannelReady>,
        pub raa: Option<msgs::RevokeAndACK>,
        pub commitment_update: Option<msgs::CommitmentUpdate>,
        pub order: RAACommitmentOrder,
@@ -543,7 +543,7 @@ pub(super) struct Channel<Signer: Sign> {
        /// send it first.
        resend_order: RAACommitmentOrder,
 
-       monitor_pending_funding_locked: bool,
+       monitor_pending_channel_ready: bool,
        monitor_pending_revoke_and_ack: bool,
        monitor_pending_commitment_signed: bool,
        monitor_pending_forwards: Vec<(PendingHTLCInfo, u64)>,
@@ -688,12 +688,12 @@ pub(super) struct Channel<Signer: Sign> {
 
        /// lnd has a long-standing bug where, upon reconnection, if the channel is not yet confirmed
        /// they will not send a channel_reestablish until the channel locks in. Then, they will send a
-       /// funding_locked *before* sending the channel_reestablish (which is clearly a violation of
-       /// the BOLT specs). We copy c-lightning's workaround here and simply store the funding_locked
+       /// channel_ready *before* sending the channel_reestablish (which is clearly a violation of
+       /// the BOLT specs). We copy c-lightning's workaround here and simply store the channel_ready
        /// message until we receive a channel_reestablish.
        ///
        /// See-also <https://github.com/lightningnetwork/lnd/issues/4006>
-       pub workaround_lnd_bug_4006: Option<msgs::FundingLocked>,
+       pub workaround_lnd_bug_4006: Option<msgs::ChannelReady>,
 
        #[cfg(any(test, fuzzing))]
        // When we receive an HTLC fulfill on an outbound path, we may immediately fulfill the
@@ -710,6 +710,11 @@ pub(super) struct Channel<Signer: Sign> {
        // Our counterparty can offer us SCID aliases which they will map to this channel when routing
        // outbound payments. These can be used in invoice route hints to avoid explicitly revealing
        // the channel's funding UTXO.
+       //
+       // We also use this when sending our peer a channel_update that isn't to be broadcasted
+       // publicly - allowing them to re-use their map of SCID -> channel for channel_update ->
+       // associated channel mapping.
+       //
        // We only bother storing the most recent SCID alias at any time, though our counterparty has
        // to store all of them.
        latest_inbound_scid_alias: Option<u64>,
@@ -775,7 +780,7 @@ pub const MAX_CHAN_DUST_LIMIT_SATOSHIS: u64 = MAX_STD_OUTPUT_DUST_LIMIT_SATOSHIS
 /// In order to avoid having to concern ourselves with standardness during the closing process, we
 /// simply require our counterparty to use a dust limit which will leave any segwit output
 /// standard.
-/// See https://github.com/lightningnetwork/lightning-rfc/issues/905 for more details.
+/// See https://github.com/lightning/bolts/issues/905 for more details.
 pub const MIN_CHAN_DUST_LIMIT_SATOSHIS: u64 = 354;
 
 /// Used to return a simple Error back to ChannelManager. Will get converted to a
@@ -955,7 +960,7 @@ impl<Signer: Sign> Channel<Signer> {
 
                        resend_order: RAACommitmentOrder::CommitmentFirst,
 
-                       monitor_pending_funding_locked: false,
+                       monitor_pending_channel_ready: false,
                        monitor_pending_revoke_and_ack: false,
                        monitor_pending_commitment_signed: false,
                        monitor_pending_forwards: Vec::new(),
@@ -1076,16 +1081,22 @@ impl<Signer: Sign> Channel<Signer> {
                        if channel_type.supports_any_optional_bits() {
                                return Err(ChannelError::Close("Channel Type field contained optional bits - this is not allowed".to_owned()));
                        }
-                       // We currently only allow two channel types, so write it all out here - we allow
-                       // `only_static_remote_key` in all contexts, and further allow
-                       // `static_remote_key|scid_privacy` if the channel is not publicly announced.
-                       let mut allowed_type = ChannelTypeFeatures::only_static_remote_key();
-                       if *channel_type != allowed_type {
-                               allowed_type.set_scid_privacy_required();
-                               if *channel_type != allowed_type {
+
+                       if channel_type.requires_unknown_bits() {
+                               return Err(ChannelError::Close("Channel Type field contains unknown bits".to_owned()));
+                       }
+
+                       // We currently only allow four channel types, so write it all out here - we allow
+                       // `only_static_remote_key` or `static_remote_key | zero_conf` in all contexts, and
+                       // further allow `static_remote_key | scid_privacy` or
+                       // `static_remote_key | scid_privacy | zero_conf`, if the channel is not
+                       // publicly announced.
+                       if *channel_type != ChannelTypeFeatures::only_static_remote_key() {
+                               if !channel_type.requires_scid_privacy() && !channel_type.requires_zero_conf() {
                                        return Err(ChannelError::Close("Channel Type was not understood".to_owned()));
                                }
-                               if announced_channel {
+
+                               if channel_type.requires_scid_privacy() && announced_channel {
                                        return Err(ChannelError::Close("SCID Alias/Privacy Channel Type cannot be set on a public channel".to_owned()));
                                }
                        }
@@ -1272,7 +1283,7 @@ impl<Signer: Sign> Channel<Signer> {
 
                        resend_order: RAACommitmentOrder::CommitmentFirst,
 
-                       monitor_pending_funding_locked: false,
+                       monitor_pending_channel_ready: false,
                        monitor_pending_revoke_and_ack: false,
                        monitor_pending_commitment_signed: false,
                        monitor_pending_forwards: Vec::new(),
@@ -1307,7 +1318,7 @@ impl<Signer: Sign> Channel<Signer> {
                        counterparty_htlc_minimum_msat: msg.htlc_minimum_msat,
                        holder_htlc_minimum_msat: if config.own_channel_config.our_htlc_minimum_msat == 0 { 1 } else { config.own_channel_config.our_htlc_minimum_msat },
                        counterparty_max_accepted_htlcs: msg.max_accepted_htlcs,
-                       minimum_depth: Some(config.own_channel_config.minimum_depth),
+                       minimum_depth: Some(cmp::max(config.own_channel_config.minimum_depth, 1)),
 
                        counterparty_forwarding_info: None,
 
@@ -1703,6 +1714,28 @@ impl<Signer: Sign> Channel<Signer> {
                make_funding_redeemscript(&self.get_holder_pubkeys().funding_pubkey, self.counterparty_funding_pubkey())
        }
 
+       /// Claims an HTLC while we're disconnected from a peer, dropping the [`ChannelMonitorUpdate`]
+       /// entirely.
+       ///
+       /// The [`ChannelMonitor`] for this channel MUST be updated out-of-band with the preimage
+       /// provided (i.e. without calling [`crate::chain::Watch::update_channel`]).
+       ///
+       /// The HTLC claim will end up in the holding cell (because the caller must ensure the peer is
+       /// disconnected).
+       pub fn claim_htlc_while_disconnected_dropping_mon_update<L: Deref>
+               (&mut self, htlc_id_arg: u64, payment_preimage_arg: PaymentPreimage, logger: &L)
+       where L::Target: Logger {
+               // Assert that we'll add the HTLC claim to the holding cell in `get_update_fulfill_htlc`
+               // (see equivalent if condition there).
+               assert!(self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32) != 0);
+               let mon_update_id = self.latest_monitor_update_id; // Forget the ChannelMonitor update
+               let fulfill_resp = self.get_update_fulfill_htlc(htlc_id_arg, payment_preimage_arg, logger);
+               self.latest_monitor_update_id = mon_update_id;
+               if let UpdateFulfillFetch::NewClaim { msg, .. } = fulfill_resp {
+                       assert!(msg.is_none()); // The HTLC must have ended up in the holding cell.
+               }
+       }
+
        fn get_update_fulfill_htlc<L: Deref>(&mut self, htlc_id_arg: u64, payment_preimage_arg: PaymentPreimage, logger: &L) -> UpdateFulfillFetch where L::Target: Logger {
                // Either ChannelFunded got set (which means it won't be unset) or there is no way any
                // caller thought we could have something claimed (cause we wouldn't have accepted in an
@@ -1765,6 +1798,10 @@ impl<Signer: Sign> Channel<Signer> {
                };
 
                if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32)) != 0 {
+                       // Note that this condition is the same as the assertion in
+                       // `claim_htlc_while_disconnected_dropping_mon_update` and must match exactly -
+                       // `claim_htlc_while_disconnected_dropping_mon_update` would not work correctly if we
+                       // do not not get into this branch.
                        for pending_update in self.holding_cell_htlc_updates.iter() {
                                match pending_update {
                                        &HTLCUpdateAwaitingACK::ClaimHTLC { htlc_id, .. } => {
@@ -1987,12 +2024,6 @@ impl<Signer: Sign> Channel<Signer> {
                if msg.minimum_depth > peer_limits.max_minimum_depth {
                        return Err(ChannelError::Close(format!("We consider the minimum depth to be unreasonably large. Expected minimum: ({}). Actual: ({})", peer_limits.max_minimum_depth, msg.minimum_depth)));
                }
-               if msg.minimum_depth == 0 {
-                       // Note that if this changes we should update the serialization minimum version to
-                       // indicate to older clients that they don't understand some features of the current
-                       // channel.
-                       return Err(ChannelError::Close("Minimum confirmation depth must be at least 1".to_owned()));
-               }
 
                if let Some(ty) = &msg.channel_type {
                        if *ty != self.channel_type {
@@ -2029,7 +2060,12 @@ impl<Signer: Sign> Channel<Signer> {
                self.counterparty_selected_channel_reserve_satoshis = Some(msg.channel_reserve_satoshis);
                self.counterparty_htlc_minimum_msat = msg.htlc_minimum_msat;
                self.counterparty_max_accepted_htlcs = msg.max_accepted_htlcs;
-               self.minimum_depth = Some(msg.minimum_depth);
+
+               if peer_limits.trust_own_funding_0conf {
+                       self.minimum_depth = Some(msg.minimum_depth);
+               } else {
+                       self.minimum_depth = Some(cmp::max(1, msg.minimum_depth));
+               }
 
                let counterparty_pubkeys = ChannelPublicKeys {
                        funding_pubkey: msg.funding_pubkey,
@@ -2089,7 +2125,7 @@ impl<Signer: Sign> Channel<Signer> {
                &self.get_counterparty_pubkeys().funding_pubkey
        }
 
-       pub fn funding_created<L: Deref>(&mut self, msg: &msgs::FundingCreated, best_block: BestBlock, logger: &L) -> Result<(msgs::FundingSigned, ChannelMonitor<Signer>), ChannelError> where L::Target: Logger {
+       pub fn funding_created<L: Deref>(&mut self, msg: &msgs::FundingCreated, best_block: BestBlock, logger: &L) -> Result<(msgs::FundingSigned, ChannelMonitor<Signer>, Option<msgs::ChannelReady>), ChannelError> where L::Target: Logger {
                if self.is_outbound() {
                        return Err(ChannelError::Close("Received funding_created for an outbound channel?".to_owned()));
                }
@@ -2164,12 +2200,12 @@ impl<Signer: Sign> Channel<Signer> {
                Ok((msgs::FundingSigned {
                        channel_id: self.channel_id,
                        signature
-               }, channel_monitor))
+               }, channel_monitor, self.check_get_channel_ready(0)))
        }
 
        /// Handles a funding_signed message from the remote end.
        /// If this call is successful, broadcast the funding transaction (and not before!)
-       pub fn funding_signed<L: Deref>(&mut self, msg: &msgs::FundingSigned, best_block: BestBlock, logger: &L) -> Result<(ChannelMonitor<Signer>, Transaction), ChannelError> where L::Target: Logger {
+       pub fn funding_signed<L: Deref>(&mut self, msg: &msgs::FundingSigned, best_block: BestBlock, logger: &L) -> Result<(ChannelMonitor<Signer>, Transaction, Option<msgs::ChannelReady>), ChannelError> where L::Target: Logger {
                if !self.is_outbound() {
                        return Err(ChannelError::Close("Received funding_signed for an inbound channel?".to_owned()));
                }
@@ -2238,16 +2274,16 @@ impl<Signer: Sign> Channel<Signer> {
 
                log_info!(logger, "Received funding_signed from peer for channel {}", log_bytes!(self.channel_id()));
 
-               Ok((channel_monitor, self.funding_transaction.as_ref().cloned().unwrap()))
+               Ok((channel_monitor, self.funding_transaction.as_ref().cloned().unwrap(), self.check_get_channel_ready(0)))
        }
 
-       /// Handles a funding_locked message from our peer. If we've already sent our funding_locked
+       /// Handles a channel_ready message from our peer. If we've already sent our channel_ready
        /// and the channel is now usable (and public), this may generate an announcement_signatures to
        /// reply with.
-       pub fn funding_locked<L: Deref>(&mut self, msg: &msgs::FundingLocked, node_pk: PublicKey, genesis_block_hash: BlockHash, best_block: &BestBlock, logger: &L) -> Result<Option<msgs::AnnouncementSignatures>, ChannelError> where L::Target: Logger {
+       pub fn channel_ready<L: Deref>(&mut self, msg: &msgs::ChannelReady, node_pk: PublicKey, genesis_block_hash: BlockHash, best_block: &BestBlock, logger: &L) -> Result<Option<msgs::AnnouncementSignatures>, ChannelError> where L::Target: Logger {
                if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 {
                        self.workaround_lnd_bug_4006 = Some(msg.clone());
-                       return Err(ChannelError::Ignore("Peer sent funding_locked when we needed a channel_reestablish. The peer is likely lnd, see https://github.com/lightningnetwork/lnd/issues/4006".to_owned()));
+                       return Err(ChannelError::Ignore("Peer sent channel_ready when we needed a channel_reestablish. The peer is likely lnd, see https://github.com/lightningnetwork/lnd/issues/4006".to_owned()));
                }
 
                if let Some(scid_alias) = msg.short_channel_id_alias {
@@ -2262,16 +2298,16 @@ impl<Signer: Sign> Channel<Signer> {
                let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
 
                if non_shutdown_state == ChannelState::FundingSent as u32 {
-                       self.channel_state |= ChannelState::TheirFundingLocked as u32;
-               } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) {
+                       self.channel_state |= ChannelState::TheirChannelReady as u32;
+               } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurChannelReady as u32) {
                        self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & MULTI_STATE_FLAGS);
                        self.update_time_counter += 1;
                } else if self.channel_state & (ChannelState::ChannelFunded as u32) != 0 ||
-                       // If we reconnected before sending our funding locked they may still resend theirs:
-                       (self.channel_state & (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) ==
-                                             (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32))
+                       // If we reconnected before sending our `channel_ready` they may still resend theirs:
+                       (self.channel_state & (ChannelState::FundingSent as u32 | ChannelState::TheirChannelReady as u32) ==
+                                             (ChannelState::FundingSent as u32 | ChannelState::TheirChannelReady as u32))
                {
-                       // They probably disconnected/reconnected and re-sent the funding_locked, which is
+                       // They probably disconnected/reconnected and re-sent the channel_ready, which is
                        // required, or they're sending a fresh SCID alias.
                        let expected_point =
                                if self.cur_counterparty_commitment_transaction_number == INITIAL_COMMITMENT_NUMBER - 1 {
@@ -2279,24 +2315,24 @@ impl<Signer: Sign> Channel<Signer> {
                                        // the current one.
                                        self.counterparty_cur_commitment_point
                                } else {
-                                       // If they have sent updated points, funding_locked is always supposed to match
+                                       // If they have sent updated points, channel_ready is always supposed to match
                                        // their "first" point, which we re-derive here.
                                        Some(PublicKey::from_secret_key(&self.secp_ctx, &SecretKey::from_slice(
                                                        &self.commitment_secrets.get_secret(INITIAL_COMMITMENT_NUMBER - 1).expect("We should have all prev secrets available")
                                                ).expect("We already advanced, so previous secret keys should have been validated already")))
                                };
                        if expected_point != Some(msg.next_per_commitment_point) {
-                               return Err(ChannelError::Close("Peer sent a reconnect funding_locked with a different point".to_owned()));
+                               return Err(ChannelError::Close("Peer sent a reconnect channel_ready with a different point".to_owned()));
                        }
                        return Ok(None);
                } else {
-                       return Err(ChannelError::Close("Peer sent a funding_locked at a strange time".to_owned()));
+                       return Err(ChannelError::Close("Peer sent a channel_ready at a strange time".to_owned()));
                }
 
                self.counterparty_prev_commitment_point = self.counterparty_cur_commitment_point;
                self.counterparty_cur_commitment_point = Some(msg.next_per_commitment_point);
 
-               log_info!(logger, "Received funding_locked from peer for channel {}", log_bytes!(self.channel_id()));
+               log_info!(logger, "Received channel_ready from peer for channel {}", log_bytes!(self.channel_id()));
 
                Ok(self.get_announcement_sigs(node_pk, genesis_block_hash, best_block.height(), logger))
        }
@@ -3540,12 +3576,13 @@ impl<Signer: Sign> Channel<Signer> {
        /// monitor update failure must *not* have been sent to the remote end, and must instead
        /// have been dropped. They will be regenerated when monitor_updating_restored is called.
        pub fn monitor_update_failed(&mut self, resend_raa: bool, resend_commitment: bool,
-               mut pending_forwards: Vec<(PendingHTLCInfo, u64)>,
+               resend_channel_ready: bool, mut pending_forwards: Vec<(PendingHTLCInfo, u64)>,
                mut pending_fails: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>,
                mut pending_finalized_claimed_htlcs: Vec<HTLCSource>
        ) {
                self.monitor_pending_revoke_and_ack |= resend_raa;
                self.monitor_pending_commitment_signed |= resend_commitment;
+               self.monitor_pending_channel_ready |= resend_channel_ready;
                self.monitor_pending_forwards.append(&mut pending_forwards);
                self.monitor_pending_failures.append(&mut pending_fails);
                self.monitor_pending_finalized_fulfills.append(&mut pending_finalized_claimed_htlcs);
@@ -3559,20 +3596,31 @@ impl<Signer: Sign> Channel<Signer> {
                assert_eq!(self.channel_state & ChannelState::MonitorUpdateFailed as u32, ChannelState::MonitorUpdateFailed as u32);
                self.channel_state &= !(ChannelState::MonitorUpdateFailed as u32);
 
-               let funding_broadcastable = if self.channel_state & (ChannelState::FundingSent as u32) != 0 && self.is_outbound() {
-                       self.funding_transaction.take()
-               } else { None };
+               // If we're past (or at) the FundingSent stage on an outbound channel, try to
+               // (re-)broadcast the funding transaction as we may have declined to broadcast it when we
+               // first received the funding_signed.
+               let mut funding_broadcastable =
+                       if self.is_outbound() && self.channel_state & !MULTI_STATE_FLAGS >= ChannelState::FundingSent as u32 {
+                               self.funding_transaction.take()
+                       } else { None };
+               // That said, if the funding transaction is already confirmed (ie we're active with a
+               // minimum_depth over 0) don't bother re-broadcasting the confirmed funding tx.
+               if self.channel_state & !MULTI_STATE_FLAGS >= ChannelState::ChannelFunded as u32 && self.minimum_depth != Some(0) {
+                       funding_broadcastable = None;
+               }
 
                // We will never broadcast the funding transaction when we're in MonitorUpdateFailed (and
                // we assume the user never directly broadcasts the funding transaction and waits for us to
-               // do it). Thus, we can only ever hit monitor_pending_funding_locked when we're an inbound
-               // channel which failed to persist the monitor on funding_created, and we got the funding
-               // transaction confirmed before the monitor was persisted.
-               let funding_locked = if self.monitor_pending_funding_locked {
-                       assert!(!self.is_outbound(), "Funding transaction broadcast by the local client before it should have - LDK didn't do it!");
-                       self.monitor_pending_funding_locked = false;
+               // do it). Thus, we can only ever hit monitor_pending_channel_ready when we're
+               // * an inbound channel that failed to persist the monitor on funding_created and we got
+               //   the funding transaction confirmed before the monitor was persisted, or
+               // * a 0-conf channel and intended to send the channel_ready before any broadcast at all.
+               let channel_ready = if self.monitor_pending_channel_ready {
+                       assert!(!self.is_outbound() || self.minimum_depth == Some(0),
+                               "Funding transaction broadcast by the local client before it should have - LDK didn't do it!");
+                       self.monitor_pending_channel_ready = false;
                        let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
-                       Some(msgs::FundingLocked {
+                       Some(msgs::ChannelReady {
                                channel_id: self.channel_id(),
                                next_per_commitment_point,
                                short_channel_id_alias: Some(self.outbound_scid_alias),
@@ -3593,7 +3641,7 @@ impl<Signer: Sign> Channel<Signer> {
                        self.monitor_pending_commitment_signed = false;
                        return MonitorRestoreUpdates {
                                raa: None, commitment_update: None, order: RAACommitmentOrder::RevokeAndACKFirst,
-                               accepted_htlcs, failed_htlcs, finalized_claimed_htlcs, funding_broadcastable, funding_locked, announcement_sigs
+                               accepted_htlcs, failed_htlcs, finalized_claimed_htlcs, funding_broadcastable, channel_ready, announcement_sigs
                        };
                }
 
@@ -3612,7 +3660,7 @@ impl<Signer: Sign> Channel<Signer> {
                        if commitment_update.is_some() { "a" } else { "no" }, if raa.is_some() { "an" } else { "no" },
                        match order { RAACommitmentOrder::CommitmentFirst => "commitment", RAACommitmentOrder::RevokeAndACKFirst => "RAA"});
                MonitorRestoreUpdates {
-                       raa, commitment_update, order, accepted_htlcs, failed_htlcs, finalized_claimed_htlcs, funding_broadcastable, funding_locked, announcement_sigs
+                       raa, commitment_update, order, accepted_htlcs, failed_htlcs, finalized_claimed_htlcs, funding_broadcastable, channel_ready, announcement_sigs
                }
        }
 
@@ -3784,15 +3832,15 @@ impl<Signer: Sign> Channel<Signer> {
                let announcement_sigs = self.get_announcement_sigs(node_pk, genesis_block_hash, best_block.height(), logger);
 
                if self.channel_state & (ChannelState::FundingSent as u32) == ChannelState::FundingSent as u32 {
-                       // If we're waiting on a monitor update, we shouldn't re-send any funding_locked's.
-                       if self.channel_state & (ChannelState::OurFundingLocked as u32) == 0 ||
+                       // If we're waiting on a monitor update, we shouldn't re-send any channel_ready's.
+                       if self.channel_state & (ChannelState::OurChannelReady as u32) == 0 ||
                                        self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 {
                                if msg.next_remote_commitment_number != 0 {
-                                       return Err(ChannelError::Close("Peer claimed they saw a revoke_and_ack but we haven't sent funding_locked yet".to_owned()));
+                                       return Err(ChannelError::Close("Peer claimed they saw a revoke_and_ack but we haven't sent channel_ready yet".to_owned()));
                                }
                                // Short circuit the whole handler as there is nothing we can resend them
                                return Ok(ReestablishResponses {
-                                       funding_locked: None,
+                                       channel_ready: None,
                                        raa: None, commitment_update: None, mon_update: None,
                                        order: RAACommitmentOrder::CommitmentFirst,
                                        holding_cell_failed_htlcs: Vec::new(),
@@ -3800,10 +3848,10 @@ impl<Signer: Sign> Channel<Signer> {
                                });
                        }
 
-                       // We have OurFundingLocked set!
+                       // We have OurChannelReady set!
                        let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
                        return Ok(ReestablishResponses {
-                               funding_locked: Some(msgs::FundingLocked {
+                               channel_ready: Some(msgs::ChannelReady {
                                        channel_id: self.channel_id(),
                                        next_per_commitment_point,
                                        short_channel_id_alias: Some(self.outbound_scid_alias),
@@ -3817,7 +3865,7 @@ impl<Signer: Sign> Channel<Signer> {
 
                let required_revoke = if msg.next_remote_commitment_number + 1 == INITIAL_COMMITMENT_NUMBER - self.cur_holder_commitment_transaction_number {
                        // Remote isn't waiting on any RevokeAndACK from us!
-                       // Note that if we need to repeat our FundingLocked we'll do that in the next if block.
+                       // Note that if we need to repeat our ChannelReady we'll do that in the next if block.
                        None
                } else if msg.next_remote_commitment_number + 1 == (INITIAL_COMMITMENT_NUMBER - 1) - self.cur_holder_commitment_transaction_number {
                        if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 {
@@ -3836,10 +3884,10 @@ impl<Signer: Sign> Channel<Signer> {
                // the corresponding revoke_and_ack back yet.
                let next_counterparty_commitment_number = INITIAL_COMMITMENT_NUMBER - self.cur_counterparty_commitment_transaction_number + if (self.channel_state & ChannelState::AwaitingRemoteRevoke as u32) != 0 { 1 } else { 0 };
 
-               let funding_locked = if msg.next_local_commitment_number == 1 && INITIAL_COMMITMENT_NUMBER - self.cur_holder_commitment_transaction_number == 1 {
-                       // We should never have to worry about MonitorUpdateFailed resending FundingLocked
+               let channel_ready = if msg.next_local_commitment_number == 1 && INITIAL_COMMITMENT_NUMBER - self.cur_holder_commitment_transaction_number == 1 {
+                       // We should never have to worry about MonitorUpdateFailed resending ChannelReady
                        let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
-                       Some(msgs::FundingLocked {
+                       Some(msgs::ChannelReady {
                                channel_id: self.channel_id(),
                                next_per_commitment_point,
                                short_channel_id_alias: Some(self.outbound_scid_alias),
@@ -3864,7 +3912,7 @@ impl<Signer: Sign> Channel<Signer> {
                                                panic!("Got non-channel-failing result from free_holding_cell_htlcs"),
                                        Ok((Some((commitment_update, monitor_update)), holding_cell_failed_htlcs)) => {
                                                Ok(ReestablishResponses {
-                                                       funding_locked, shutdown_msg, announcement_sigs,
+                                                       channel_ready, shutdown_msg, announcement_sigs,
                                                        raa: required_revoke,
                                                        commitment_update: Some(commitment_update),
                                                        order: self.resend_order.clone(),
@@ -3874,7 +3922,7 @@ impl<Signer: Sign> Channel<Signer> {
                                        },
                                        Ok((None, holding_cell_failed_htlcs)) => {
                                                Ok(ReestablishResponses {
-                                                       funding_locked, shutdown_msg, announcement_sigs,
+                                                       channel_ready, shutdown_msg, announcement_sigs,
                                                        raa: required_revoke,
                                                        commitment_update: None,
                                                        order: self.resend_order.clone(),
@@ -3885,7 +3933,7 @@ impl<Signer: Sign> Channel<Signer> {
                                }
                        } else {
                                Ok(ReestablishResponses {
-                                       funding_locked, shutdown_msg, announcement_sigs,
+                                       channel_ready, shutdown_msg, announcement_sigs,
                                        raa: required_revoke,
                                        commitment_update: None,
                                        order: self.resend_order.clone(),
@@ -3903,14 +3951,14 @@ impl<Signer: Sign> Channel<Signer> {
                        if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 {
                                self.monitor_pending_commitment_signed = true;
                                Ok(ReestablishResponses {
-                                       funding_locked, shutdown_msg, announcement_sigs,
+                                       channel_ready, shutdown_msg, announcement_sigs,
                                        commitment_update: None, raa: None, mon_update: None,
                                        order: self.resend_order.clone(),
                                        holding_cell_failed_htlcs: Vec::new(),
                                })
                        } else {
                                Ok(ReestablishResponses {
-                                       funding_locked, shutdown_msg, announcement_sigs,
+                                       channel_ready, shutdown_msg, announcement_sigs,
                                        raa: required_revoke,
                                        commitment_update: Some(self.get_last_commitment_update(logger)),
                                        order: self.resend_order.clone(),
@@ -4325,7 +4373,7 @@ impl<Signer: Sign> Channel<Signer> {
                &self.channel_type
        }
 
-       /// Guaranteed to be Some after both FundingLocked messages have been exchanged (and, thus,
+       /// Guaranteed to be Some after both ChannelReady messages have been exchanged (and, thus,
        /// is_usable() returns true).
        /// Allowed in any state (including after shutdown)
        pub fn get_short_channel_id(&self) -> Option<u64> {
@@ -4530,7 +4578,7 @@ impl<Signer: Sign> Channel<Signer> {
        /// Allowed in any state (including after shutdown)
        pub fn is_usable(&self) -> bool {
                let mask = ChannelState::ChannelFunded as u32 | BOTH_SIDES_SHUTDOWN_MASK;
-               (self.channel_state & mask) == (ChannelState::ChannelFunded as u32) && !self.monitor_pending_funding_locked
+               (self.channel_state & mask) == (ChannelState::ChannelFunded as u32) && !self.monitor_pending_channel_ready
        }
 
        /// Returns true if this channel is currently available for use. This is a superset of
@@ -4551,6 +4599,11 @@ impl<Signer: Sign> Channel<Signer> {
                self.channel_state >= ChannelState::FundingSent as u32
        }
 
+       /// Returns true if our channel_ready has been sent
+       pub fn is_our_channel_ready(&self) -> bool {
+               (self.channel_state & ChannelState::OurChannelReady as u32) != 0 || self.channel_state >= ChannelState::ChannelFunded as u32
+       }
+
        /// Returns true if our peer has either initiated or agreed to shut down the channel.
        pub fn received_shutdown(&self) -> bool {
                (self.channel_state & ChannelState::RemoteShutdownSent as u32) != 0
@@ -4580,8 +4633,8 @@ impl<Signer: Sign> Channel<Signer> {
                self.channel_update_status = status;
        }
 
-       fn check_get_funding_locked(&mut self, height: u32) -> Option<msgs::FundingLocked> {
-               if self.funding_tx_confirmation_height == 0 {
+       fn check_get_channel_ready(&mut self, height: u32) -> Option<msgs::ChannelReady> {
+               if self.funding_tx_confirmation_height == 0 && self.minimum_depth != Some(0) {
                        return None;
                }
 
@@ -4596,13 +4649,13 @@ impl<Signer: Sign> Channel<Signer> {
 
                let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
                let need_commitment_update = if non_shutdown_state == ChannelState::FundingSent as u32 {
-                       self.channel_state |= ChannelState::OurFundingLocked as u32;
+                       self.channel_state |= ChannelState::OurChannelReady as u32;
                        true
-               } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) {
+               } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::TheirChannelReady as u32) {
                        self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & MULTI_STATE_FLAGS);
                        self.update_time_counter += 1;
                        true
-               } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) {
+               } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurChannelReady as u32) {
                        // We got a reorg but not enough to trigger a force close, just ignore.
                        false
                } else if self.channel_state < ChannelState::ChannelFunded as u32 {
@@ -4617,14 +4670,14 @@ impl<Signer: Sign> Channel<Signer> {
                                if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
                                        let next_per_commitment_point =
                                                self.holder_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, &self.secp_ctx);
-                                       return Some(msgs::FundingLocked {
+                                       return Some(msgs::ChannelReady {
                                                channel_id: self.channel_id,
                                                next_per_commitment_point,
                                                short_channel_id_alias: Some(self.outbound_scid_alias),
                                        });
                                }
                        } else {
-                               self.monitor_pending_funding_locked = true;
+                               self.monitor_pending_channel_ready = true;
                        }
                }
                None
@@ -4635,13 +4688,12 @@ impl<Signer: Sign> Channel<Signer> {
        /// In the second, we simply return an Err indicating we need to be force-closed now.
        pub fn transactions_confirmed<L: Deref>(&mut self, block_hash: &BlockHash, height: u32,
                txdata: &TransactionData, genesis_block_hash: BlockHash, node_pk: PublicKey, logger: &L)
-       -> Result<(Option<msgs::FundingLocked>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
-               let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
+       -> Result<(Option<msgs::ChannelReady>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
                if let Some(funding_txo) = self.get_funding_txo() {
                        for &(index_in_block, tx) in txdata.iter() {
-                               // If we haven't yet sent a funding_locked, but are in FundingSent (ignoring
-                               // whether they've sent a funding_locked or not), check if we should send one.
-                               if non_shutdown_state & !(ChannelState::TheirFundingLocked as u32) == ChannelState::FundingSent as u32 {
+                               // Check if the transaction is the expected funding transaction, and if it is,
+                               // check that it pays the right amount to the right script.
+                               if self.funding_tx_confirmation_height == 0 {
                                        if tx.txid() == funding_txo.txid {
                                                let txo_idx = funding_txo.index as usize;
                                                if txo_idx >= tx.output.len() || tx.output[txo_idx].script_pubkey != self.get_funding_redeemscript().to_v0_p2wsh() ||
@@ -4677,13 +4729,13 @@ impl<Signer: Sign> Channel<Signer> {
                                                        }
                                                }
                                        }
-                                       // If we allow 1-conf funding, we may need to check for funding_locked here and
+                                       // If we allow 1-conf funding, we may need to check for channel_ready here and
                                        // send it immediately instead of waiting for a best_block_updated call (which
                                        // may have already happened for this block).
-                                       if let Some(funding_locked) = self.check_get_funding_locked(height) {
-                                               log_info!(logger, "Sending a funding_locked to our peer for channel {}", log_bytes!(self.channel_id));
+                                       if let Some(channel_ready) = self.check_get_channel_ready(height) {
+                                               log_info!(logger, "Sending a channel_ready to our peer for channel {}", log_bytes!(self.channel_id));
                                                let announcement_sigs = self.get_announcement_sigs(node_pk, genesis_block_hash, height, logger);
-                                               return Ok((Some(funding_locked), announcement_sigs));
+                                               return Ok((Some(channel_ready), announcement_sigs));
                                        }
                                }
                                for inp in tx.input.iter() {
@@ -4709,12 +4761,12 @@ impl<Signer: Sign> Channel<Signer> {
        /// May return some HTLCs (and their payment_hash) which have timed out and should be failed
        /// back.
        pub fn best_block_updated<L: Deref>(&mut self, height: u32, highest_header_time: u32, genesis_block_hash: BlockHash, node_pk: PublicKey, logger: &L)
-       -> Result<(Option<msgs::FundingLocked>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
+       -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
                self.do_best_block_updated(height, highest_header_time, Some((genesis_block_hash, node_pk)), logger)
        }
 
        fn do_best_block_updated<L: Deref>(&mut self, height: u32, highest_header_time: u32, genesis_node_pk: Option<(BlockHash, PublicKey)>, logger: &L)
-       -> Result<(Option<msgs::FundingLocked>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
+       -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
                let mut timed_out_htlcs = Vec::new();
                // This mirrors the check in ChannelManager::decode_update_add_htlc_onion, refusing to
                // forward an HTLC when our counterparty should almost certainly just fail it for expiring
@@ -4734,33 +4786,33 @@ impl<Signer: Sign> Channel<Signer> {
 
                self.update_time_counter = cmp::max(self.update_time_counter, highest_header_time);
 
-               if let Some(funding_locked) = self.check_get_funding_locked(height) {
+               if let Some(channel_ready) = self.check_get_channel_ready(height) {
                        let announcement_sigs = if let Some((genesis_block_hash, node_pk)) = genesis_node_pk {
                                self.get_announcement_sigs(node_pk, genesis_block_hash, height, logger)
                        } else { None };
-                       log_info!(logger, "Sending a funding_locked to our peer for channel {}", log_bytes!(self.channel_id));
-                       return Ok((Some(funding_locked), timed_out_htlcs, announcement_sigs));
+                       log_info!(logger, "Sending a channel_ready to our peer for channel {}", log_bytes!(self.channel_id));
+                       return Ok((Some(channel_ready), timed_out_htlcs, announcement_sigs));
                }
 
                let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
                if non_shutdown_state >= ChannelState::ChannelFunded as u32 ||
-                  (non_shutdown_state & ChannelState::OurFundingLocked as u32) == ChannelState::OurFundingLocked as u32 {
+                  (non_shutdown_state & ChannelState::OurChannelReady as u32) == ChannelState::OurChannelReady as u32 {
                        let mut funding_tx_confirmations = height as i64 - self.funding_tx_confirmation_height as i64 + 1;
                        if self.funding_tx_confirmation_height == 0 {
-                               // Note that check_get_funding_locked may reset funding_tx_confirmation_height to
+                               // Note that check_get_channel_ready may reset funding_tx_confirmation_height to
                                // zero if it has been reorged out, however in either case, our state flags
-                               // indicate we've already sent a funding_locked
+                               // indicate we've already sent a channel_ready
                                funding_tx_confirmations = 0;
                        }
 
-                       // If we've sent funding_locked (or have both sent and received funding_locked), and
+                       // If we've sent channel_ready (or have both sent and received channel_ready), and
                        // the funding transaction has become unconfirmed,
                        // close the channel and hope we can get the latest state on chain (because presumably
                        // the funding transaction is at least still in the mempool of most nodes).
                        //
-                       // Note that ideally we wouldn't force-close if we see *any* reorg on a 1-conf channel,
-                       // but not doing so may lead to the `ChannelManager::short_to_id` map being
-                       // inconsistent, so we currently have to.
+                       // Note that ideally we wouldn't force-close if we see *any* reorg on a 1-conf or
+                       // 0-conf channel, but not doing so may lead to the `ChannelManager::short_to_id` map
+                       // being inconsistent, so we currently have to.
                        if funding_tx_confirmations == 0 && self.funding_tx_confirmed_in.is_some() {
                                let err_reason = format!("Funding transaction was un-confirmed. Locked at {} confs, now have {} confs.",
                                        self.minimum_depth.unwrap(), funding_tx_confirmations);
@@ -4771,7 +4823,7 @@ impl<Signer: Sign> Channel<Signer> {
                        log_info!(logger, "Closing channel {} due to funding timeout", log_bytes!(self.channel_id));
                        // If funding_tx_confirmed_in is unset, the channel must not be active
                        assert!(non_shutdown_state <= ChannelState::ChannelFunded as u32);
-                       assert_eq!(non_shutdown_state & ChannelState::OurFundingLocked as u32, 0);
+                       assert_eq!(non_shutdown_state & ChannelState::OurChannelReady as u32, 0);
                        return Err(ClosureReason::FundingTimedOut);
                }
 
@@ -4783,7 +4835,7 @@ impl<Signer: Sign> Channel<Signer> {
 
        /// Indicates the funding transaction is no longer confirmed in the main chain. This may
        /// force-close the channel, but may also indicate a harmless reorganization of a block or two
-       /// before the channel has reached funding_locked and we can just wait for more blocks.
+       /// before the channel has reached channel_ready and we can just wait for more blocks.
        pub fn funding_transaction_unconfirmed<L: Deref>(&mut self, logger: &L) -> Result<(), ClosureReason> where L::Target: Logger {
                if self.funding_tx_confirmation_height != 0 {
                        // We handle the funding disconnection by calling best_block_updated with a height one
@@ -4794,8 +4846,8 @@ impl<Signer: Sign> Channel<Signer> {
                        // time we saw and it will be ignored.
                        let best_time = self.update_time_counter;
                        match self.do_best_block_updated(reorg_height, best_time, None, logger) {
-                               Ok((funding_locked, timed_out_htlcs, announcement_sigs)) => {
-                                       assert!(funding_locked.is_none(), "We can't generate a funding with 0 confirmations?");
+                               Ok((channel_ready, timed_out_htlcs, announcement_sigs)) => {
+                                       assert!(channel_ready.is_none(), "We can't generate a funding with 0 confirmations?");
                                        assert!(timed_out_htlcs.is_empty(), "We can't have accepted HTLCs with a timeout before our funding confirmation?");
                                        assert!(announcement_sigs.is_none(), "We can't generate an announcement_sigs with 0 confirmations?");
                                        Ok(())
@@ -4857,6 +4909,12 @@ impl<Signer: Sign> Channel<Signer> {
                self.inbound_awaiting_accept
        }
 
+       /// Sets this channel to accepting 0conf, must be done before `get_accept_channel`
+       pub fn set_0conf(&mut self) {
+               assert!(self.inbound_awaiting_accept);
+               self.minimum_depth = Some(0);
+       }
+
        /// Marks an inbound channel as accepted and generates a [`msgs::AcceptChannel`] message which
        /// should be sent back to the counterparty node.
        ///
@@ -4979,7 +5037,7 @@ impl<Signer: Sign> Channel<Signer> {
        }
 
        /// Gets an UnsignedChannelAnnouncement for this channel. The channel must be publicly
-       /// announceable and available for use (have exchanged FundingLocked messages in both
+       /// announceable and available for use (have exchanged ChannelReady messages in both
        /// directions). Should be used for both broadcasted announcements and in response to an
        /// AnnouncementSignatures message from the remote peer.
        ///
@@ -5400,7 +5458,7 @@ impl<Signer: Sign> Channel<Signer> {
                                commitment_txid: counterparty_commitment_txid,
                                htlc_outputs: htlcs.clone(),
                                commitment_number: self.cur_counterparty_commitment_transaction_number,
-                               their_revocation_point: self.counterparty_cur_commitment_point.unwrap()
+                               their_per_commitment_point: self.counterparty_cur_commitment_point.unwrap()
                        }]
                };
                self.channel_state |= ChannelState::AwaitingRemoteRevoke as u32;
@@ -5619,7 +5677,7 @@ impl<Signer: Sign> Channel<Signer> {
 }
 
 const SERIALIZATION_VERSION: u8 = 2;
-const MIN_SERIALIZATION_VERSION: u8 = 1;
+const MIN_SERIALIZATION_VERSION: u8 = 2;
 
 impl_writeable_tlv_based_enum!(InboundHTLCRemovalReason,;
        (0, FailRelay),
@@ -5684,12 +5742,10 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
 
                self.user_id.write(writer)?;
 
-               // Write out the old serialization for the config object. This is read by version-1
-               // deserializers, but we will read the version in the TLV at the end instead.
-               self.config.forwarding_fee_proportional_millionths.write(writer)?;
-               self.config.cltv_expiry_delta.write(writer)?;
-               self.config.announced_channel.write(writer)?;
-               self.config.commit_upfront_shutdown_pubkey.write(writer)?;
+               // Version 1 deserializers expected to read parts of the config object here. Version 2
+               // deserializers (0.0.99) now read config through TLVs, and as we now require them for
+               // `minimum_depth` we simply write dummy values here.
+               writer.write_all(&[0; 8])?;
 
                self.channel_id.write(writer)?;
                (self.channel_state | ChannelState::PeerDisconnected as u32).write(writer)?;
@@ -5821,7 +5877,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
                        RAACommitmentOrder::RevokeAndACKFirst => 1u8.write(writer)?,
                }
 
-               self.monitor_pending_funding_locked.write(writer)?;
+               self.monitor_pending_channel_ready.write(writer)?;
                self.monitor_pending_revoke_and_ack.write(writer)?;
                self.monitor_pending_commitment_signed.write(writer)?;
 
@@ -6082,7 +6138,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
                        _ => return Err(DecodeError::InvalidValue),
                };
 
-               let monitor_pending_funding_locked = Readable::read(reader)?;
+               let monitor_pending_channel_ready = Readable::read(reader)?;
                let monitor_pending_revoke_and_ack = Readable::read(reader)?;
                let monitor_pending_commitment_signed = Readable::read(reader)?;
 
@@ -6292,7 +6348,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
 
                        resend_order,
 
-                       monitor_pending_funding_locked,
+                       monitor_pending_channel_ready,
                        monitor_pending_revoke_and_ack,
                        monitor_pending_commitment_signed,
                        monitor_pending_forwards,
@@ -6383,7 +6439,7 @@ mod tests {
        use ln::channelmanager::{HTLCSource, PaymentId};
        use ln::channel::{Channel, InboundHTLCOutput, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator};
        use ln::channel::{MAX_FUNDING_SATOSHIS_NO_WUMBO, TOTAL_BITCOIN_SUPPLY_SATOSHIS};
-       use ln::features::InitFeatures;
+       use ln::features::{InitFeatures, ChannelTypeFeatures};
        use ln::msgs::{ChannelUpdate, DataLossProtect, DecodeError, OptionalField, UnsignedChannelUpdate};
        use ln::script::ShutdownScript;
        use ln::chan_utils;
@@ -6667,7 +6723,7 @@ mod tests {
                }]};
                let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
                let funding_created_msg = node_a_chan.get_outbound_funding_created(tx.clone(), funding_outpoint, &&logger).unwrap();
-               let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&logger).unwrap();
+               let (funding_signed_msg, _, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&logger).unwrap();
 
                // Node B --> Node A: funding signed
                let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&logger);
@@ -7698,4 +7754,29 @@ mod tests {
                assert_eq!(chan_utils::derive_private_revocation_key(&secp_ctx, &per_commitment_secret, &base_secret).unwrap(),
                                SecretKey::from_slice(&hex::decode("d09ffff62ddb2297ab000cc85bcb4283fdeb6aa052affbc9dddcf33b61078110").unwrap()[..]).unwrap());
        }
+
+       #[test]
+       fn test_zero_conf_channel_type_support() {
+               let feeest = TestFeeEstimator{fee_est: 15000};
+               let secp_ctx = Secp256k1::new();
+               let seed = [42; 32];
+               let network = Network::Testnet;
+               let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
+               let logger = test_utils::TestLogger::new();
+
+               let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
+               let config = UserConfig::default();
+               let node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider,
+                       node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0, 42).unwrap();
+
+               let mut channel_type_features = ChannelTypeFeatures::only_static_remote_key();
+               channel_type_features.set_zero_conf_required();
+
+               let mut open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
+               open_channel_msg.channel_type = Some(channel_type_features);
+               let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
+               let res = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider,
+                       node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config, 0, &&logger, 42);
+               assert!(res.is_ok());
+       }
 }