Support option_data_loss_protect for remote peer
authorAntoine Riard <ariard@student.42.fr>
Wed, 10 Jul 2019 19:48:23 +0000 (15:48 -0400)
committerAntoine Riard <ariard@student.42.fr>
Tue, 30 Jul 2019 04:38:20 +0000 (00:38 -0400)
In case of sending channel_reestablish message, we join
our current per_commitment_point and their highest revocation
secret we know about

We set data_loss_protect by default and adjust encoding_init
test in consequence

src/ln/channel.rs
src/ln/msgs.rs
src/ln/peer_handler.rs

index 5abbd4a29d0ea71cfa69b7b60363c936ccffea29..72b9fab1430beda48a2578a4bf0e211abec11e60 100644 (file)
@@ -16,7 +16,7 @@ use secp256k1::{Secp256k1,Signature};
 use secp256k1;
 
 use ln::msgs;
-use ln::msgs::{DecodeError, OptionalField, LocalFeatures};
+use ln::msgs::{DecodeError, OptionalField, LocalFeatures, DataLossProtect};
 use ln::channelmonitor::ChannelMonitor;
 use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingForwardHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
 use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGHT,HTLC_TIMEOUT_TX_WEIGHT};
@@ -3256,6 +3256,20 @@ impl Channel {
        pub fn get_channel_reestablish(&self) -> msgs::ChannelReestablish {
                assert_eq!(self.channel_state & ChannelState::PeerDisconnected as u32, ChannelState::PeerDisconnected as u32);
                assert_ne!(self.cur_remote_commitment_transaction_number, INITIAL_COMMITMENT_NUMBER);
+               let data_loss_protect = if self.cur_remote_commitment_transaction_number + 1 < INITIAL_COMMITMENT_NUMBER {
+                       let remote_last_secret = self.channel_monitor.get_secret(self.cur_remote_commitment_transaction_number + 2).unwrap();
+                       log_trace!(self, "Enough info to generate a Data Loss Protect with per_commitment_secret {}", log_bytes!(remote_last_secret));
+                       OptionalField::Present(DataLossProtect {
+                               your_last_per_commitment_secret: remote_last_secret,
+                               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");
+                       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))
+                       })
+               };
                msgs::ChannelReestablish {
                        channel_id: self.channel_id(),
                        // The protocol has two different commitment number concepts - the "commitment
@@ -3276,7 +3290,7 @@ impl Channel {
                        // dropped this channel on disconnect as it hasn't yet reached FundingSent so we can't
                        // overflow here.
                        next_remote_commitment_number: INITIAL_COMMITMENT_NUMBER - self.cur_remote_commitment_transaction_number - 1,
-                       data_loss_protect: OptionalField::Absent,
+                       data_loss_protect,
                }
        }
 
index f6968c5d3a32dfd4b0b20915ee5db02839943efb..0e6c4b95ee32645d4e43a5ead08331e99d4784f6 100644 (file)
@@ -63,23 +63,19 @@ impl LocalFeatures {
        #[cfg(not(feature = "fuzztarget"))]
        pub(crate) fn new() -> LocalFeatures {
                LocalFeatures {
-                       flags: vec![1 << 5],
+                       flags: vec![2 | 1 << 5],
                }
        }
        #[cfg(feature = "fuzztarget")]
        pub fn new() -> LocalFeatures {
                LocalFeatures {
-                       flags: vec![1 << 5],
+                       flags: vec![2 | 1 << 5],
                }
        }
 
        pub(crate) fn supports_data_loss_protect(&self) -> bool {
                self.flags.len() > 0 && (self.flags[0] & 3) != 0
        }
-       pub(crate) fn requires_data_loss_protect(&self) -> bool {
-               self.flags.len() > 0 && (self.flags[0] & 1) != 0
-       }
-
        pub(crate) fn initial_routing_sync(&self) -> bool {
                self.flags.len() > 0 && (self.flags[0] & (1 << 3)) != 0
        }
@@ -2018,9 +2014,9 @@ mod tests {
                        target_value.append(&mut hex::decode("0000").unwrap());
                }
                if initial_routing_sync {
-                       target_value.append(&mut hex::decode("000128").unwrap());
+                       target_value.append(&mut hex::decode("00012a").unwrap());
                } else {
-                       target_value.append(&mut hex::decode("000120").unwrap());
+                       target_value.append(&mut hex::decode("000122").unwrap());
                }
                assert_eq!(encoded_value, target_value);
        }
index 03aeedcdac31453f4d76eabb0d3812bb01b81194..0e390bd32fc9d777dbd7dddbc45e071683c69514 100644 (file)
@@ -621,10 +621,6 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
                                                                                                        log_info!(self, "Peer local features required unknown version bits");
                                                                                                        return Err(PeerHandleError{ no_connection_possible: true });
                                                                                                }
-                                                                                               if msg.local_features.requires_data_loss_protect() {
-                                                                                                       log_info!(self, "Peer local features required data_loss_protect");
-                                                                                                       return Err(PeerHandleError{ no_connection_possible: true });
-                                                                                               }
                                                                                                if peer.their_global_features.is_some() {
                                                                                                        return Err(PeerHandleError{ no_connection_possible: false });
                                                                                                }