URI: 
       tlnpeer: reestablish_channel - fix data_loss_protect edge case - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 940fc86749831265c8b4accd9d500b6b9ece2ce2
   DIR parent 107f271e583405ea6e3f4fbe7d72733b740a3b98
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Mon,  5 Aug 2019 17:43:06 +0200
       
       lnpeer: reestablish_channel - fix data_loss_protect edge case
       
       Diffstat:
         M electrum/lnchannel.py               |       1 +
         M electrum/lnpeer.py                  |      11 ++++++++++-
         M electrum/lnutil.py                  |       1 +
       
       3 files changed, 12 insertions(+), 1 deletion(-)
       ---
   DIR diff --git a/electrum/lnchannel.py b/electrum/lnchannel.py
       t@@ -490,6 +490,7 @@ class Channel(Logger):
        
            def get_secret_and_point(self, subject, ctn) -> Tuple[Optional[bytes], bytes]:
                assert type(subject) is HTLCOwner
       +        assert ctn >= 0, ctn
                offset = ctn - self.get_oldest_unrevoked_ctn(subject)
                if subject == REMOTE:
                    if offset > 1:
   DIR diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py
       t@@ -743,6 +743,11 @@ class Peer(Logger):
                their_oldest_unrevoked_remote_ctn = int.from_bytes(channel_reestablish_msg["next_remote_revocation_number"], 'big')
                their_local_pcp = channel_reestablish_msg.get("my_current_per_commitment_point")
                their_claim_of_our_last_per_commitment_secret = channel_reestablish_msg.get("your_last_per_commitment_secret")
       +        # sanity checks of received values
       +        if their_next_local_ctn < 0:
       +            raise RemoteMisbehaving(f"channel reestablish: their_next_local_ctn < 0")
       +        if their_oldest_unrevoked_remote_ctn < 0:
       +            raise RemoteMisbehaving(f"channel reestablish: their_oldest_unrevoked_remote_ctn < 0")
        
                should_close_we_are_ahead = False
                should_close_they_are_ahead = False
       t@@ -788,7 +793,11 @@ class Peer(Logger):
                    if their_local_pcp is None or their_claim_of_our_last_per_commitment_secret is None:
                        # if DLP was enabled, absence of fields is not OK
                        return not dlp_enabled
       -            our_pcs, __ = chan.get_secret_and_point(LOCAL, their_oldest_unrevoked_remote_ctn - 1)
       +            if their_oldest_unrevoked_remote_ctn > 0:
       +                our_pcs, __ = chan.get_secret_and_point(LOCAL, their_oldest_unrevoked_remote_ctn - 1)
       +            else:
       +                assert their_oldest_unrevoked_remote_ctn == 0
       +                our_pcs = bytes(32)
                    if our_pcs != their_claim_of_our_last_per_commitment_secret:
                        self.logger.error(f"channel_reestablish: (DLP) local PCS mismatch: {bh2u(our_pcs)} != {bh2u(their_claim_of_our_last_per_commitment_secret)}")
                        return False
   DIR diff --git a/electrum/lnutil.py b/electrum/lnutil.py
       t@@ -151,6 +151,7 @@ class RevocationStore:
                self.index -= 1
        
            def retrieve_secret(self, index: int) -> bytes:
       +        assert index <= self.START_INDEX, index
                for bucket in self.buckets:
                    if bucket is None:
                        raise UnableToDeriveSecret()