URI: 
       tlnhtlc: generalize balance/pending_commitment code over htlc direction - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit a071aafcc7b5be45f801fa03776e9ba63c3b1ce8
   DIR parent c8dc17012f9d201040c05e7418310f9e6206244b
  HTML Author: Janus <ysangkok@gmail.com>
       Date:   Fri, 28 Sep 2018 16:40:32 +0200
       
       lnhtlc: generalize balance/pending_commitment code over htlc direction
       
       Diffstat:
         M electrum/lnhtlc.py                  |     134 ++++++++++++-------------------
       
       1 file changed, 53 insertions(+), 81 deletions(-)
       ---
   DIR diff --git a/electrum/lnhtlc.py b/electrum/lnhtlc.py
       t@@ -17,7 +17,7 @@ from .lnutil import sign_and_get_sig_string
        from .lnutil import make_htlc_tx_with_open_channel, make_commitment, make_received_htlc, make_offered_htlc
        from .lnutil import HTLC_TIMEOUT_WEIGHT, HTLC_SUCCESS_WEIGHT
        from .lnutil import funding_output_script, LOCAL, REMOTE, HTLCOwner, make_closing_tx, make_outputs
       -from .lnutil import ScriptHtlc
       +from .lnutil import ScriptHtlc, SENT, RECEIVED
        from .transaction import Transaction
        
        
       t@@ -474,19 +474,15 @@ class HTLCStateMachine(PrintError):
            def balance(self, subject):
                initial = self.local_config.initial_msat if subject == LOCAL else self.remote_config.initial_msat
        
       -        for x in self.log[-subject]:
       -            if type(x) is not SettleHtlc: continue
       -            htlc = self.lookup_htlc(self.log[subject], x.htlc_id)
       -            htlc_height = htlc.settled[subject]
       -            if htlc_height is not None and htlc_height <= self.current_height[subject]:
       -                initial -= htlc.amount_msat
       -
       -        for x in self.log[subject]:
       -            if type(x) is not SettleHtlc: continue
       -            htlc = self.lookup_htlc(self.log[-subject], x.htlc_id)
       -            htlc_height = htlc.settled[-subject]
       -            if htlc_height is not None and htlc_height <= self.current_height[-subject]:
       -                initial += htlc.amount_msat
       +        for direction in (SENT, RECEIVED):
       +           for x in self.log[-direction]:
       +               if type(x) is not SettleHtlc: continue
       +               htlc = self.lookup_htlc(self.log[direction], x.htlc_id)
       +               htlc_height = htlc.settled[direction]
       +               if htlc_height is not None and htlc_height <= self.current_height[direction]:
       +                   # so we will subtract when direction == subject.
       +                   # example subject=LOCAL, direction=SENT: we subtract
       +                   initial -= htlc.amount_msat * subject * direction
        
                assert initial == (self.local_state.amount_msat if subject == LOCAL else self.remote_state.amount_msat)
                return initial
       t@@ -518,30 +514,8 @@ class HTLCStateMachine(PrintError):
        
            @property
            def pending_remote_commitment(self):
       -        remote_msat, local_msat = self.amounts()
       -        assert local_msat >= 0
       -        assert remote_msat >= 0
       -
                this_point = self.remote_state.next_per_commitment_point
       -
       -        remote_htlc_pubkey = derive_pubkey(self.remote_config.htlc_basepoint.pubkey, this_point)
       -        local_htlc_pubkey = derive_pubkey(self.local_config.htlc_basepoint.pubkey, this_point)
       -        local_revocation_pubkey = derive_blinded_pubkey(self.local_config.revocation_basepoint.pubkey, this_point)
       -
       -        htlcs_in_local = []
       -        for htlc in self.included_htlcs(REMOTE, LOCAL):
       -            htlcs_in_local.append(
       -                ScriptHtlc( make_received_htlc(local_revocation_pubkey, local_htlc_pubkey, remote_htlc_pubkey, htlc.payment_hash, htlc.cltv_expiry), htlc))
       -
       -        htlcs_in_remote = []
       -        for htlc in self.included_htlcs(REMOTE, REMOTE):
       -            htlcs_in_remote.append(
       -                ScriptHtlc( make_offered_htlc(local_revocation_pubkey, local_htlc_pubkey, remote_htlc_pubkey, htlc.payment_hash), htlc))
       -
       -        commit = self.make_commitment(self.remote_state.ctn + 1,
       -            False, this_point,
       -            remote_msat, local_msat, htlcs_in_local + htlcs_in_remote)
       -        return commit
       +        return self.make_commitment(REMOTE, this_point)
        
            def pending_feerate(self, subject):
                candidate = None
       t@@ -559,32 +533,8 @@ class HTLCStateMachine(PrintError):
        
            @property
            def pending_local_commitment(self):
       -        remote_msat, local_msat = self.amounts()
       -        assert local_msat >= 0
       -        assert remote_msat >= 0
       -
                _, this_point, _ = self.points
       -
       -        remote_htlc_pubkey = derive_pubkey(self.remote_config.htlc_basepoint.pubkey, this_point)
       -        local_htlc_pubkey = derive_pubkey(self.local_config.htlc_basepoint.pubkey, this_point)
       -        remote_revocation_pubkey = derive_blinded_pubkey(self.remote_config.revocation_basepoint.pubkey, this_point)
       -
       -        feerate = self.pending_feerate(LOCAL)
       -
       -        htlcs_in_local = []
       -        for htlc in self.included_htlcs(LOCAL, LOCAL):
       -            htlcs_in_local.append(
       -                ScriptHtlc( make_offered_htlc(remote_revocation_pubkey, remote_htlc_pubkey, local_htlc_pubkey, htlc.payment_hash), htlc))
       -
       -        htlcs_in_remote = []
       -        for htlc in self.included_htlcs(LOCAL, REMOTE):
       -            htlcs_in_remote.append(
       -                ScriptHtlc( make_received_htlc(remote_revocation_pubkey, remote_htlc_pubkey, local_htlc_pubkey, htlc.payment_hash, htlc.cltv_expiry), htlc))
       -
       -        commit = self.make_commitment(self.local_state.ctn + 1,
       -            True, this_point,
       -            local_msat, remote_msat, htlcs_in_local + htlcs_in_remote)
       -        return commit
       +        return self.make_commitment(LOCAL, this_point)
        
            @property
            def total_msat(self):
       t@@ -758,29 +708,51 @@ class HTLCStateMachine(PrintError):
            def __str__(self):
                return self.serialize()
        
       -    def make_commitment(chan, ctn, for_us, pcp, local_msat, remote_msat, htlcs=[]):
       -        conf = chan.local_config if for_us else chan.remote_config
       -        other_conf = chan.local_config if not for_us else chan.remote_config
       -        payment_pubkey = derive_pubkey(other_conf.payment_basepoint.pubkey, pcp)
       -        remote_revocation_pubkey = derive_blinded_pubkey(other_conf.revocation_basepoint.pubkey, pcp)
       +    def make_commitment(self, subject, this_point) -> Transaction:
       +        remote_msat, local_msat = self.amounts()
       +        assert local_msat >= 0
       +        assert remote_msat >= 0
       +        this_config = self.remote_config if subject != LOCAL else self.local_config
       +        other_config = self.remote_config if subject == LOCAL else self.local_config
       +        other_htlc_pubkey = derive_pubkey(other_config.htlc_basepoint.pubkey, this_point)
       +        this_htlc_pubkey = derive_pubkey(this_config.htlc_basepoint.pubkey, this_point)
       +        other_revocation_pubkey = derive_blinded_pubkey(other_config.revocation_basepoint.pubkey, this_point)
       +        htlcs = []
       +        for htlc in self.included_htlcs(subject, -subject):
       +            htlcs.append( ScriptHtlc( make_received_htlc(
       +                other_revocation_pubkey,
       +                other_htlc_pubkey,
       +                this_htlc_pubkey,
       +                htlc.payment_hash,
       +                htlc.cltv_expiry), htlc))
       +        for htlc in self.included_htlcs(subject, subject):
       +            htlcs.append(
       +                ScriptHtlc( make_offered_htlc(
       +                    other_revocation_pubkey,
       +                    other_htlc_pubkey,
       +                    this_htlc_pubkey,
       +                    htlc.payment_hash), htlc))
       +        if subject != LOCAL:
       +            remote_msat, local_msat = local_msat, remote_msat
       +        payment_pubkey = derive_pubkey(other_config.payment_basepoint.pubkey, this_point)
                return make_commitment(
       -            ctn,
       -            conf.multisig_key.pubkey,
       -            other_conf.multisig_key.pubkey,
       +            (self.local_state.ctn if subject == LOCAL else self.remote_state.ctn) + 1,
       +            this_config.multisig_key.pubkey,
       +            other_config.multisig_key.pubkey,
                    payment_pubkey,
       -            chan.local_config.payment_basepoint.pubkey,
       -            chan.remote_config.payment_basepoint.pubkey,
       -            remote_revocation_pubkey,
       -            derive_pubkey(conf.delayed_basepoint.pubkey, pcp),
       -            other_conf.to_self_delay,
       -            *chan.funding_outpoint,
       -            chan.constraints.capacity,
       +            self.local_config.payment_basepoint.pubkey,
       +            self.remote_config.payment_basepoint.pubkey,
       +            other_revocation_pubkey,
       +            derive_pubkey(this_config.delayed_basepoint.pubkey, this_point),
       +            other_config.to_self_delay,
       +            *self.funding_outpoint,
       +            self.constraints.capacity,
                    local_msat,
                    remote_msat,
       -            conf.dust_limit_sat,
       -            chan.pending_feerate(LOCAL if for_us else REMOTE),
       -            for_us,
       -            chan.constraints.is_initiator,
       +            this_config.dust_limit_sat,
       +            self.pending_feerate(subject),
       +            subject == LOCAL,
       +            self.constraints.is_initiator,
                    htlcs=htlcs)
        
            def make_closing_tx(self, local_script: bytes, remote_script: bytes, fee_sat: Optional[int] = None) -> (bytes, int):