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):