electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 8ad6d5dddadda3df05da06a6a5634a8ebc5a8493
parent acb0d7ebac81a36ed6ce1fd01a392302aa675791
Author: SomberNight <somber.night@protonmail.com>
Date:   Mon, 30 Mar 2020 02:28:50 +0200

lnchannel: clean-up docstrings a bit

Removed lnd copyright as by now everything covered in this file
has been rewritten.

Diffstat:
Melectrum/lnchannel.py | 93++++++++++++++++++++++++++++++++-----------------------------------------------
Melectrum/lnutil.py | 2+-
Melectrum/tests/test_lnchannel.py | 3+++
3 files changed, 42 insertions(+), 56 deletions(-)

diff --git a/electrum/lnchannel.py b/electrum/lnchannel.py @@ -1,5 +1,4 @@ # Copyright (C) 2018 The Electrum developers -# Copyright (C) 2015-2018 The Lightning Network Developers # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -19,9 +18,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# API (method signatures and docstrings) partially copied from lnd -# 42de4400bff5105352d0552155f73589166d162b - import os from collections import namedtuple, defaultdict import binascii @@ -499,11 +495,8 @@ class Channel(Logger): return redeem_script_to_address('p2wsh', script) def add_htlc(self, htlc: UpdateAddHtlc) -> UpdateAddHtlc: - """ - AddHTLC adds an HTLC to the state machine's local update log. This method - should be called when preparing to send an outgoing HTLC. - - This docstring is from LND. + """Adds a new LOCAL HTLC to the channel. + Action must be initiated by LOCAL. """ if isinstance(htlc, dict): # legacy conversion # FIXME remove htlc = UpdateAddHtlc(**htlc) @@ -517,12 +510,8 @@ class Channel(Logger): return htlc def receive_htlc(self, htlc: UpdateAddHtlc, onion_packet:bytes = None) -> UpdateAddHtlc: - """ - ReceiveHTLC adds an HTLC to the state machine's remote update log. This - method should be called in response to receiving a new HTLC from the remote - party. - - This docstring is from LND. + """Adds a new REMOTE HTLC to the channel. + Action must be initiated by REMOTE. """ if isinstance(htlc, dict): # legacy conversion # FIXME remove htlc = UpdateAddHtlc(**htlc) @@ -543,17 +532,10 @@ class Channel(Logger): self.logger.info("receive_htlc") return htlc - def sign_next_commitment(self): - """ - SignNextCommitment signs a new commitment which includes any previous - unsettled HTLCs, any new HTLCs, and any modifications to prior HTLCs - committed in previous commitment updates. - The first return parameter is the signature for the commitment transaction - itself, while the second parameter is are all HTLC signatures concatenated. - any). The HTLC signatures are sorted according to the BIP 69 order of the - HTLC's on the commitment transaction. - - This docstring was adapted from LND. + def sign_next_commitment(self) -> Tuple[bytes, Sequence[bytes]]: + """Returns signatures for our next remote commitment tx. + Action must be initiated by LOCAL. + Finally, the next remote ctx becomes the latest remote ctx. """ next_remote_ctn = self.get_next_ctn(REMOTE) self.logger.info(f"sign_next_commitment {next_remote_ctn}") @@ -589,18 +571,10 @@ class Channel(Logger): self.hm.send_ctx() return sig_64, htlcsigs - def receive_new_commitment(self, sig, htlc_sigs): - """ - ReceiveNewCommitment process a signature for a new commitment state sent by - the remote party. This method should be called in response to the - remote party initiating a new change, or when the remote party sends a - signature fully accepting a new state we've initiated. If we are able to - successfully validate the signature, then the generated commitment is added - to our local commitment chain. Once we send a revocation for our prior - state, then this newly added commitment becomes our current accepted channel - state. - - This docstring is from LND. + def receive_new_commitment(self, sig: bytes, htlc_sigs: Sequence[bytes]) -> None: + """Processes signatures for our next local commitment tx, sent by the REMOTE. + Action must be initiated by REMOTE. + If all checks pass, the next local ctx becomes the latest local ctx. """ # TODO in many failure cases below, we should "fail" the channel (force-close) next_local_ctn = self.get_next_ctn(LOCAL) @@ -627,19 +601,19 @@ class Channel(Logger): raise Exception(f'htlc sigs failure. recv {len(htlc_sigs)} sigs, expected {len(htlc_to_ctx_output_idx_map)}') for (direction, htlc), (ctx_output_idx, htlc_relative_idx) in htlc_to_ctx_output_idx_map.items(): htlc_sig = htlc_sigs[htlc_relative_idx] - self.verify_htlc(htlc=htlc, - htlc_sig=htlc_sig, - htlc_direction=direction, - pcp=pcp, - ctx=pending_local_commitment, - ctx_output_idx=ctx_output_idx) + self._verify_htlc_sig(htlc=htlc, + htlc_sig=htlc_sig, + htlc_direction=direction, + pcp=pcp, + ctx=pending_local_commitment, + ctx_output_idx=ctx_output_idx) with self.db_lock: self.hm.recv_ctx() self.config[LOCAL].current_commitment_signature=sig self.config[LOCAL].current_htlc_signatures=htlc_sigs_string - def verify_htlc(self, *, htlc: UpdateAddHtlc, htlc_sig: bytes, htlc_direction: Direction, - pcp: bytes, ctx: Transaction, ctx_output_idx: int) -> None: + def _verify_htlc_sig(self, *, htlc: UpdateAddHtlc, htlc_sig: bytes, htlc_direction: Direction, + pcp: bytes, ctx: Transaction, ctx_output_idx: int) -> None: _script, htlc_tx = make_htlc_tx_with_open_channel(chan=self, pcp=pcp, subject=LOCAL, @@ -786,8 +760,8 @@ class Channel(Logger): return max_send_msat def included_htlcs(self, subject: HTLCOwner, direction: Direction, ctn: int = None) -> Sequence[UpdateAddHtlc]: - """ - return filter of non-dust htlcs for subjects commitment transaction, initiated by given party + """Returns list of non-dust HTLCs for subject's commitment tx at ctn, + filtered by direction (of HTLCs). """ assert type(subject) is HTLCOwner assert type(direction) is Direction @@ -859,14 +833,14 @@ class Channel(Logger): def get_next_ctn(self, subject: HTLCOwner) -> int: return self.hm.ctn_latest(subject) + 1 - def total_msat(self, direction): + def total_msat(self, direction: Direction) -> int: """Return the cumulative total msat amount received/sent so far.""" assert type(direction) is Direction return htlcsum(self.hm.all_settled_htlcs_ever_by_direction(LOCAL, direction)) - def settle_htlc(self, preimage, htlc_id): - """ - SettleHTLC attempts to settle an existing outstanding received HTLC. + def settle_htlc(self, preimage: bytes, htlc_id: int) -> None: + """Settle/fulfill a pending received HTLC. + Action must be initiated by LOCAL. """ self.logger.info("settle_htlc") assert self.can_send_ctx_updates(), f"cannot update channel. {self.get_state()!r} {self.peer_state!r}" @@ -889,7 +863,10 @@ class Channel(Logger): self.onion_keys[htlc_id]) return failure_msg, sender_idx - def receive_htlc_settle(self, preimage, htlc_id): + def receive_htlc_settle(self, preimage: bytes, htlc_id: int) -> None: + """Settle/fulfill a pending offered HTLC. + Action must be initiated by REMOTE. + """ self.logger.info("receive_htlc_settle") log = self.hm.log[LOCAL] htlc = log['adds'][htlc_id] @@ -898,7 +875,10 @@ class Channel(Logger): with self.db_lock: self.hm.recv_settle(htlc_id) - def fail_htlc(self, htlc_id): + def fail_htlc(self, htlc_id: int) -> None: + """Fail a pending received HTLC. + Action must be initiated by LOCAL. + """ self.logger.info("fail_htlc") assert self.can_send_ctx_updates(), f"cannot update channel. {self.get_state()!r} {self.peer_state!r}" with self.db_lock: @@ -906,7 +886,10 @@ class Channel(Logger): def receive_fail_htlc(self, htlc_id: int, *, error_bytes: Optional[bytes], - reason: Optional[OnionRoutingFailureMessage] = None): + reason: Optional[OnionRoutingFailureMessage] = None) -> None: + """Fail a pending offered HTLC. + Action must be initiated by REMOTE. + """ self.logger.info("receive_fail_htlc") with self.db_lock: self.hm.recv_fail(htlc_id) diff --git a/electrum/lnutil.py b/electrum/lnutil.py @@ -209,7 +209,7 @@ MAXIMUM_HTLC_MINIMUM_MSAT_ACCEPTED = 1000 MAXIMUM_REMOTE_TO_SELF_DELAY_ACCEPTED = 2016 class RevocationStore: - """ Taken from LND, see license in lnchannel.py. """ + # closely based on code in lightningnetwork/lnd START_INDEX = 2 ** 48 - 1 diff --git a/electrum/tests/test_lnchannel.py b/electrum/tests/test_lnchannel.py @@ -18,6 +18,9 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +# +# Many of these unit tests are heavily based on unit tests in lnd +# (around commit 42de4400bff5105352d0552155f73589166d162b). import unittest import os