Merge pull request #537 from TheBlueMatt/2020-03-data-loss-spec-550
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Tue, 17 Mar 2020 18:49:06 +0000 (18:49 +0000)
committerGitHub <noreply@github.com>
Tue, 17 Mar 2020 18:49:06 +0000 (18:49 +0000)
Update pre-HTLC DataLossProtect to match new spec changes

1  2 
lightning/src/ln/channel.rs

index 86074627523ca3c7b7ea4f2c5f55b43a756ffbfd,64f7e4f0b682d78db36cecd00d3cdaa0251cf387..81762923fda224f83874ff4413dc3e4d7605ef3c
@@@ -295,7 -295,7 +295,7 @@@ pub(super) struct Channel<ChanSigner: C
        holding_cell_update_fee: Option<u64>,
        next_local_htlc_id: u64,
        next_remote_htlc_id: u64,
 -      channel_update_count: u32,
 +      update_time_counter: u32,
        feerate_per_kw: u64,
  
        #[cfg(debug_assertions)]
@@@ -433,6 -433,10 +433,6 @@@ impl<ChanSigner: ChannelKeys> Channel<C
                cmp::max(at_open_background_feerate * B_OUTPUT_PLUS_SPENDING_INPUT_WEIGHT / 1000, 546) //TODO
        }
  
 -      fn derive_our_htlc_minimum_msat(_at_open_channel_feerate_per_kw: u64) -> u64 {
 -              1000 // TODO
 -      }
 -
        // Constructors:
        pub fn new_outbound<K: Deref, F: Deref>(fee_estimator: &F, keys_provider: &K, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel<ChanSigner>, APIError>
        where K::Target: KeysInterface<ChanKeySigner = ChanSigner>,
                        holding_cell_update_fee: None,
                        next_local_htlc_id: 0,
                        next_remote_htlc_id: 0,
 -                      channel_update_count: 1,
 +                      update_time_counter: 1,
  
                        resend_order: RAACommitmentOrder::CommitmentFirst,
  
                        their_max_htlc_value_in_flight_msat: 0,
                        their_channel_reserve_satoshis: 0,
                        their_htlc_minimum_msat: 0,
 -                      our_htlc_minimum_msat: Channel::<ChanSigner>::derive_our_htlc_minimum_msat(feerate),
 +                      our_htlc_minimum_msat: if config.own_channel_config.our_htlc_minimum_msat == 0 { 1 } else { config.own_channel_config.our_htlc_minimum_msat },
                        their_to_self_delay: 0,
                        our_to_self_delay: config.own_channel_config.our_to_self_delay,
                        their_max_accepted_htlcs: 0,
                        holding_cell_update_fee: None,
                        next_local_htlc_id: 0,
                        next_remote_htlc_id: 0,
 -                      channel_update_count: 1,
 +                      update_time_counter: 1,
  
                        resend_order: RAACommitmentOrder::CommitmentFirst,
  
                        their_max_htlc_value_in_flight_msat: cmp::min(msg.max_htlc_value_in_flight_msat, msg.funding_satoshis * 1000),
                        their_channel_reserve_satoshis: msg.channel_reserve_satoshis,
                        their_htlc_minimum_msat: msg.htlc_minimum_msat,
 -                      our_htlc_minimum_msat: Channel::<ChanSigner>::derive_our_htlc_minimum_msat(msg.feerate_per_kw as u64),
 +                      our_htlc_minimum_msat: if config.own_channel_config.our_htlc_minimum_msat == 0 { 1 } else { config.own_channel_config.our_htlc_minimum_msat },
                        their_to_self_delay: msg.to_self_delay,
                        our_to_self_delay: config.own_channel_config.our_to_self_delay,
                        their_max_accepted_htlcs: msg.max_accepted_htlcs,
                        self.channel_state |= ChannelState::TheirFundingLocked as u32;
                } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) {
                        self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & MULTI_STATE_FLAGS);
 -                      self.channel_update_count += 1;
 +                      self.update_time_counter += 1;
                } else if (self.channel_state & (ChannelState::ChannelFunded as u32) != 0 &&
                                 // Note that funding_signed/funding_created will have decremented both by 1!
                                 self.cur_local_commitment_transaction_number == INITIAL_COMMITMENT_NUMBER - 1 &&
                if msg.amount_msat > self.channel_value_satoshis * 1000 {
                        return Err(ChannelError::Close("Remote side tried to send more than the total value of the channel"));
                }
 +              if msg.amount_msat == 0 {
 +                      return Err(ChannelError::Close("Remote side tried to send a 0-msat HTLC"));
 +              }
                if msg.amount_msat < self.our_htlc_minimum_msat {
                        return Err(ChannelError::Close("Remote side tried to send less than our minimum HTLC value"));
                }
                }
                Channel::<ChanSigner>::check_remote_fee(fee_estimator, msg.feerate_per_kw)?;
                self.pending_update_fee = Some(msg.feerate_per_kw as u64);
 -              self.channel_update_count += 1;
 +              self.update_time_counter += 1;
                Ok(())
        }
  
                // From here on out, we may not fail!
  
                self.channel_state |= ChannelState::RemoteShutdownSent as u32;
 -              self.channel_update_count += 1;
 +              self.update_time_counter += 1;
  
                // We can't send our shutdown until we've committed all of our pending HTLCs, but the
                // remote side is unlikely to accept any new HTLCs, so we go ahead and "free" any holding
                };
  
                self.channel_state |= ChannelState::LocalShutdownSent as u32;
 -              self.channel_update_count += 1;
 +              self.update_time_counter += 1;
  
                Ok((our_shutdown, self.maybe_propose_first_closing_signed(fee_estimator), dropped_outbound_htlcs))
        }
                        if last_fee == msg.fee_satoshis {
                                self.build_signed_closing_transaction(&mut closing_tx, &msg.signature, &our_sig);
                                self.channel_state = ChannelState::ShutdownComplete as u32;
 -                              self.channel_update_count += 1;
 +                              self.update_time_counter += 1;
                                return Ok((None, Some(closing_tx)));
                        }
                }
                self.build_signed_closing_transaction(&mut closing_tx, &msg.signature, &our_sig);
  
                self.channel_state = ChannelState::ShutdownComplete as u32;
 -              self.channel_update_count += 1;
 +              self.update_time_counter += 1;
  
                Ok((Some(msgs::ClosingSigned {
                        channel_id: self.channel_id,
        }
  
        /// Allowed in any state (including after shutdown)
 -      pub fn get_channel_update_count(&self) -> u32 {
 -              self.channel_update_count
 +      pub fn get_update_time_counter(&self) -> u32 {
 +              self.update_time_counter
        }
  
        pub fn get_latest_monitor_update_id(&self) -> u64 {
                                                        panic!("Client called ChannelManager::funding_transaction_generated with bogus transaction!");
                                                }
                                                self.channel_state = ChannelState::ShutdownComplete as u32;
 -                                              self.channel_update_count += 1;
 +                                              self.update_time_counter += 1;
                                                return Err(msgs::ErrorMessage {
                                                        channel_id: self.channel_id(),
                                                        data: "funding tx had wrong script/value".to_owned()
                }
                if header.bitcoin_hash() != self.last_block_connected {
                        self.last_block_connected = header.bitcoin_hash();
 +                      self.update_time_counter = cmp::max(self.update_time_counter, header.time);
                        if let Some(channel_monitor) = self.channel_monitor.as_mut() {
                                channel_monitor.last_block_hash = self.last_block_connected;
                        }
                                                true
                                        } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) {
                                                self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & MULTI_STATE_FLAGS);
 -                                              self.channel_update_count += 1;
 +                                              self.update_time_counter += 1;
                                                true
                                        } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) {
                                                // We got a reorg but not enough to trigger a force close, just update
                                my_current_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number + 1))
                        })
                } else {
-                       log_debug!(self, "We don't seen yet any revoked secret, if this channnel has already been updated it means we are fallen-behind, you should wait for other peer closing");
+                       log_info!(self, "Sending a data_loss_protect with no previous remote per_commitment_secret");
                        OptionalField::Present(DataLossProtect {
                                your_last_per_commitment_secret: [0;32],
-                               my_current_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number))
+                               my_current_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number + 1))
                        })
                };
                msgs::ChannelReestablish {
                if amount_msat > self.channel_value_satoshis * 1000 {
                        return Err(ChannelError::Ignore("Cannot send more than the total value of the channel"));
                }
 +
 +              if amount_msat == 0 {
 +                      return Err(ChannelError::Ignore("Cannot send 0-msat HTLC"));
 +              }
 +
                if amount_msat < self.their_htlc_minimum_msat {
                        return Err(ChannelError::Ignore("Cannot send less than their minimum HTLC value"));
                }
                } else {
                        self.channel_state |= ChannelState::LocalShutdownSent as u32;
                }
 -              self.channel_update_count += 1;
 +              self.update_time_counter += 1;
  
                // Go ahead and drop holding cell updates as we'd rather fail payments than wait to send
                // our shutdown until we've committed all of the pending changes.
                }
  
                self.channel_state = ChannelState::ShutdownComplete as u32;
 -              self.channel_update_count += 1;
 +              self.update_time_counter += 1;
                if self.channel_monitor.is_some() {
                        (self.channel_monitor.as_mut().unwrap().get_latest_local_commitment_txn(), dropped_outbound_htlcs)
                } else {
@@@ -3969,7 -3964,7 +3969,7 @@@ impl<ChanSigner: ChannelKeys + Writeabl
  
                self.next_local_htlc_id.write(writer)?;
                (self.next_remote_htlc_id - dropped_inbound_htlcs).write(writer)?;
 -              self.channel_update_count.write(writer)?;
 +              self.update_time_counter.write(writer)?;
                self.feerate_per_kw.write(writer)?;
  
                match self.last_sent_closing_fee {
@@@ -4129,7 -4124,7 +4129,7 @@@ impl<ChanSigner: ChannelKeys + Readable
  
                let next_local_htlc_id = Readable::read(reader)?;
                let next_remote_htlc_id = Readable::read(reader)?;
 -              let channel_update_count = Readable::read(reader)?;
 +              let update_time_counter = Readable::read(reader)?;
                let feerate_per_kw = Readable::read(reader)?;
  
                let last_sent_closing_fee = match <u8 as Readable>::read(reader)? {
                        holding_cell_update_fee,
                        next_local_htlc_id,
                        next_remote_htlc_id,
 -                      channel_update_count,
 +                      update_time_counter,
                        feerate_per_kw,
  
                        #[cfg(debug_assertions)]