electrum

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

commit 79d57784c15dc4debf13c36c871df515db48ada0
parent db84de5493604a956c6d6492e7098e367b4b573f
Author: SomberNight <somber.night@protonmail.com>
Date:   Mon, 30 Mar 2020 03:49:50 +0200

lnchannel: add more type hints

Diffstat:
Melectrum/lnchannel.py | 113+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Melectrum/lnutil.py | 30++++++++++++++++++++++--------
Melectrum/lnwatcher.py | 3++-
Melectrum/tests/test_lnchannel.py | 20++++++++++----------
Melectrum/tests/test_lnutil.py | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
5 files changed, 160 insertions(+), 103 deletions(-)

diff --git a/electrum/lnchannel.py b/electrum/lnchannel.py @@ -23,7 +23,8 @@ from collections import namedtuple, defaultdict import binascii import json from enum import IntEnum -from typing import Optional, Dict, List, Tuple, NamedTuple, Set, Callable, Iterable, Sequence, TYPE_CHECKING, Iterator +from typing import (Optional, Dict, List, Tuple, NamedTuple, Set, Callable, + Iterable, Sequence, TYPE_CHECKING, Iterator, Union) import time import threading @@ -63,7 +64,7 @@ if TYPE_CHECKING: # lightning channel states # Note: these states are persisted by name (for a given channel) in the wallet file, # so consider doing a wallet db upgrade when changing them. -class channel_states(IntEnum): +class channel_states(IntEnum): # TODO rename to use CamelCase PREOPENING = 0 # Initial negotiation. Channel will not be reestablished OPENING = 1 # Channel will be reestablished. (per BOLT2) # - Funding node: has received funding_signed (can broadcast the funding tx) @@ -75,7 +76,7 @@ class channel_states(IntEnum): CLOSED = 6 # closing tx has been mined REDEEMED = 7 # we can stop watching -class peer_states(IntEnum): +class peer_states(IntEnum): # TODO rename to use CamelCase DISCONNECTED = 0 REESTABLISHING = 1 GOOD = 2 @@ -138,15 +139,15 @@ class Channel(Logger): self.sweep_address = sweep_address self.storage = state self.db_lock = self.storage.db.lock if self.storage.db else threading.RLock() - self.config = {} # type: Dict[HTLCOwner, lnutil.Config] + self.config = {} # type: Dict[HTLCOwner, Union[LocalConfig, RemoteConfig]] self.config[LOCAL] = state["local_config"] self.config[REMOTE] = state["remote_config"] self.channel_id = bfh(state["channel_id"]) - self.constraints = state["constraints"] - self.funding_outpoint = state["funding_outpoint"] + self.constraints = state["constraints"] # type: ChannelConstraints + self.funding_outpoint = state["funding_outpoint"] # type: Outpoint self.node_id = bfh(state["node_id"]) self.short_channel_id = ShortChannelID.normalize(state["short_channel_id"]) - self.onion_keys = state['onion_keys'] + self.onion_keys = state['onion_keys'] # type: Dict[int, bytes] self.data_loss_protect_remote_pcp = state['data_loss_protect_remote_pcp'] self.hm = HTLCManager(log=state['log'], initial_feerate=initial_feerate) self._state = channel_states[state['state']] @@ -165,10 +166,10 @@ class Channel(Logger): return str(scid) return self.channel_id.hex() - def set_onion_key(self, key, value): + def set_onion_key(self, key: int, value: bytes): self.onion_keys[key] = value - def get_onion_key(self, key): + def get_onion_key(self, key: int) -> bytes: return self.onion_keys.get(key) def set_data_loss_protect_remote_pcp(self, key, value): @@ -262,23 +263,24 @@ class Channel(Logger): self._chan_ann_without_sigs = chan_ann return chan_ann - def is_static_remotekey_enabled(self): - return self.storage.get('static_remotekey_enabled') + def is_static_remotekey_enabled(self) -> bool: + return bool(self.storage.get('static_remotekey_enabled')) - def set_short_channel_id(self, short_id): + def set_short_channel_id(self, short_id: ShortChannelID) -> None: self.short_channel_id = short_id self.storage["short_channel_id"] = short_id - def get_feerate(self, subject, ctn): + def get_feerate(self, subject: HTLCOwner, *, ctn: int) -> int: + # returns feerate in sat/kw return self.hm.get_feerate(subject, ctn) - def get_oldest_unrevoked_feerate(self, subject): + def get_oldest_unrevoked_feerate(self, subject: HTLCOwner) -> int: return self.hm.get_feerate_in_oldest_unrevoked_ctx(subject) - def get_latest_feerate(self, subject): + def get_latest_feerate(self, subject: HTLCOwner) -> int: return self.hm.get_feerate_in_latest_ctx(subject) - def get_next_feerate(self, subject): + def get_next_feerate(self, subject: HTLCOwner) -> int: return self.hm.get_feerate_in_next_ctx(subject) def get_payments(self): @@ -316,7 +318,7 @@ class Channel(Logger): self.hm.channel_open_finished() self.peer_state = peer_states.GOOD - def set_state(self, state): + def set_state(self, state: channel_states) -> None: """ set on-chain state """ old_state = self._state if (old_state, state) not in state_transitions: @@ -329,7 +331,7 @@ class Channel(Logger): self.lnworker.save_channel(self) self.lnworker.network.trigger_callback('channel', self) - def get_state(self): + def get_state(self) -> channel_states: return self._state def get_state_for_GUI(self): @@ -767,7 +769,7 @@ class Channel(Logger): assert type(direction) is Direction if ctn is None: ctn = self.get_oldest_unrevoked_ctn(subject) - feerate = self.get_feerate(subject, ctn) + feerate = self.get_feerate(subject, ctn=ctn) conf = self.config[subject] if direction == RECEIVED: threshold_sat = received_htlc_trim_threshold_sat(dust_limit_sat=conf.dust_limit_sat, feerate=feerate) @@ -798,30 +800,30 @@ class Channel(Logger): point = secret_to_pubkey(int.from_bytes(secret, 'big')) return secret, point - def get_secret_and_commitment(self, subject, ctn): + def get_secret_and_commitment(self, subject: HTLCOwner, *, ctn: int) -> Tuple[Optional[bytes], PartialTransaction]: secret, point = self.get_secret_and_point(subject, ctn) ctx = self.make_commitment(subject, point, ctn) return secret, ctx - def get_commitment(self, subject, ctn) -> PartialTransaction: - secret, ctx = self.get_secret_and_commitment(subject, ctn) + def get_commitment(self, subject: HTLCOwner, *, ctn: int) -> PartialTransaction: + secret, ctx = self.get_secret_and_commitment(subject, ctn=ctn) return ctx def get_next_commitment(self, subject: HTLCOwner) -> PartialTransaction: ctn = self.get_next_ctn(subject) - return self.get_commitment(subject, ctn) + return self.get_commitment(subject, ctn=ctn) def get_latest_commitment(self, subject: HTLCOwner) -> PartialTransaction: ctn = self.get_latest_ctn(subject) - return self.get_commitment(subject, ctn) + return self.get_commitment(subject, ctn=ctn) def get_oldest_unrevoked_commitment(self, subject: HTLCOwner) -> PartialTransaction: ctn = self.get_oldest_unrevoked_ctn(subject) - return self.get_commitment(subject, ctn) + return self.get_commitment(subject, ctn=ctn) def create_sweeptxs(self, ctn: int) -> List[Transaction]: from .lnsweep import create_sweeptxs_for_watchtower - secret, ctx = self.get_secret_and_commitment(REMOTE, ctn) + secret, ctx = self.get_secret_and_commitment(REMOTE, ctn=ctn) return create_sweeptxs_for_watchtower(self, ctx, secret, self.sweep_address) def get_oldest_unrevoked_ctn(self, subject: HTLCOwner) -> int: @@ -850,9 +852,9 @@ class Channel(Logger): assert htlc_id not in log['settles'] self.hm.send_settle(htlc_id) - def get_payment_hash(self, htlc_id): + def get_payment_hash(self, htlc_id: int) -> bytes: log = self.hm.log[LOCAL] - htlc = log['adds'][htlc_id] + htlc = log['adds'][htlc_id] # type: UpdateAddHtlc return htlc.payment_hash def decode_onion_error(self, reason: bytes, route: Sequence['RouteEdge'], @@ -898,13 +900,13 @@ class Channel(Logger): error_bytes=error_bytes, error_reason=reason) - def pending_local_fee(self): - return self.constraints.capacity - sum(x.value for x in self.get_next_commitment(LOCAL).outputs()) + def get_next_fee(self, subject: HTLCOwner) -> int: + return self.constraints.capacity - sum(x.value for x in self.get_next_commitment(subject).outputs()) - def get_latest_fee(self, subject): + def get_latest_fee(self, subject: HTLCOwner) -> int: return self.constraints.capacity - sum(x.value for x in self.get_latest_commitment(subject).outputs()) - def update_fee(self, feerate: int, from_us: bool): + def update_fee(self, feerate: int, from_us: bool) -> None: # feerate uses sat/kw if self.constraints.is_initiator != from_us: raise Exception(f"Cannot update_fee: wrong initiator. us: {from_us}") @@ -917,9 +919,9 @@ class Channel(Logger): else: self.hm.recv_update_fee(feerate) - def make_commitment(self, subject, this_point, ctn) -> PartialTransaction: + def make_commitment(self, subject: HTLCOwner, this_point: bytes, ctn: int) -> PartialTransaction: assert type(subject) is HTLCOwner - feerate = self.get_feerate(subject, ctn) + feerate = self.get_feerate(subject, ctn=ctn) other = subject.inverted() local_msat = self.balance(subject, ctx_owner=subject, ctn=ctn) remote_msat = self.balance(other, ctx_owner=subject, ctn=ctn) @@ -969,23 +971,24 @@ class Channel(Logger): payment_pubkey = derive_pubkey(other_config.payment_basepoint.pubkey, this_point) return make_commitment( - ctn, - this_config.multisig_key.pubkey, - other_config.multisig_key.pubkey, - payment_pubkey, - self.config[LOCAL if self.constraints.is_initiator else REMOTE].payment_basepoint.pubkey, - self.config[LOCAL if not self.constraints.is_initiator else REMOTE].payment_basepoint.pubkey, - other_revocation_pubkey, - derive_pubkey(this_config.delayed_basepoint.pubkey, this_point), - other_config.to_self_delay, - self.funding_outpoint.txid, - self.funding_outpoint.output_index, - self.constraints.capacity, - local_msat, - remote_msat, - this_config.dust_limit_sat, - onchain_fees, - htlcs=htlcs) + ctn=ctn, + local_funding_pubkey=this_config.multisig_key.pubkey, + remote_funding_pubkey=other_config.multisig_key.pubkey, + remote_payment_pubkey=payment_pubkey, + funder_payment_basepoint=self.config[LOCAL if self.constraints.is_initiator else REMOTE].payment_basepoint.pubkey, + fundee_payment_basepoint=self.config[LOCAL if not self.constraints.is_initiator else REMOTE].payment_basepoint.pubkey, + revocation_pubkey=other_revocation_pubkey, + delayed_pubkey=derive_pubkey(this_config.delayed_basepoint.pubkey, this_point), + to_self_delay=other_config.to_self_delay, + funding_txid=self.funding_outpoint.txid, + funding_pos=self.funding_outpoint.output_index, + funding_sat=self.constraints.capacity, + local_amount=local_msat, + remote_amount=remote_msat, + dust_limit_sat=this_config.dust_limit_sat, + fees_per_participant=onchain_fees, + htlcs=htlcs, + ) def make_closing_tx(self, local_script: bytes, remote_script: bytes, fee_sat: int, *, drop_remote = False) -> Tuple[bytes, PartialTransaction]: @@ -1013,7 +1016,7 @@ class Channel(Logger): sig = ecc.sig_string_from_der_sig(der_sig[:-1]) return sig, closing_tx - def signature_fits(self, tx: PartialTransaction): + def signature_fits(self, tx: PartialTransaction) -> bool: remote_sig = self.config[LOCAL].current_commitment_signature preimage_hex = tx.serialize_preimage(0) msg_hash = sha256d(bfh(preimage_hex)) @@ -1021,7 +1024,7 @@ class Channel(Logger): res = ecc.verify_signature(self.config[REMOTE].multisig_key.pubkey, remote_sig, msg_hash) return res - def force_close_tx(self): + def force_close_tx(self) -> PartialTransaction: tx = self.get_latest_commitment(LOCAL) assert self.signature_fits(tx) tx.sign({bh2u(self.config[LOCAL].multisig_key.pubkey): (self.config[LOCAL].multisig_key.privkey, True)}) @@ -1048,11 +1051,11 @@ class Channel(Logger): self.sweep_info[txid] = {} return self.sweep_info[txid] - def sweep_htlc(self, ctx:Transaction, htlc_tx: Transaction): + def sweep_htlc(self, ctx: Transaction, htlc_tx: Transaction) -> Optional[SweepInfo]: # look at the output address, check if it matches return create_sweeptx_for_their_revoked_htlc(self, ctx, htlc_tx, self.sweep_address) - def has_pending_changes(self, subject): + def has_pending_changes(self, subject: HTLCOwner) -> bool: next_htlcs = self.hm.get_htlcs_in_next_ctx(subject) latest_htlcs = self.hm.get_htlcs_in_latest_ctx(subject) return not (next_htlcs == latest_htlcs and self.get_next_feerate(subject) == self.get_latest_feerate(subject)) diff --git a/electrum/lnutil.py b/electrum/lnutil.py @@ -599,13 +599,27 @@ def calc_fees_for_commitment_tx(*, num_htlcs: int, feerate: int, REMOTE: fee if not is_local_initiator else 0, } -def make_commitment(ctn, local_funding_pubkey, remote_funding_pubkey, - remote_payment_pubkey, funder_payment_basepoint, - fundee_payment_basepoint, revocation_pubkey, - delayed_pubkey, to_self_delay, funding_txid, - funding_pos, funding_sat, local_amount, remote_amount, - dust_limit_sat, fees_per_participant, - htlcs: List[ScriptHtlc]) -> PartialTransaction: + +def make_commitment( + *, + ctn: int, + local_funding_pubkey: bytes, + remote_funding_pubkey: bytes, + remote_payment_pubkey: bytes, + funder_payment_basepoint: bytes, + fundee_payment_basepoint: bytes, + revocation_pubkey: bytes, + delayed_pubkey: bytes, + to_self_delay: int, + funding_txid: str, + funding_pos: int, + funding_sat: int, + local_amount: int, + remote_amount: int, + dust_limit_sat: int, + fees_per_participant: Mapping[HTLCOwner, int], + htlcs: List[ScriptHtlc] +) -> PartialTransaction: c_input = make_funding_input(local_funding_pubkey, remote_funding_pubkey, funding_pos, funding_txid, funding_sat) obs = get_obscured_ctn(ctn, funder_payment_basepoint, fundee_payment_basepoint) @@ -618,7 +632,7 @@ def make_commitment(ctn, local_funding_pubkey, remote_funding_pubkey, # commitment tx outputs local_address = make_commitment_output_to_local_address(revocation_pubkey, to_self_delay, delayed_pubkey) remote_address = make_commitment_output_to_remote_address(remote_payment_pubkey) - # TODO trim htlc outputs here while also considering 2nd stage htlc transactions + # note: it is assumed that the given 'htlcs' are all non-dust (dust htlcs already trimmed) # BOLT-03: "Transaction Input and Output Ordering # Lexicographic ordering: see BIP69. In the case of identical HTLC outputs, diff --git a/electrum/lnwatcher.py b/electrum/lnwatcher.py @@ -23,6 +23,7 @@ from .transaction import Transaction if TYPE_CHECKING: from .network import Network from .lnsweep import SweepInfo + from .lnworker import LNWallet class ListenerItem(NamedTuple): # this is triggered when the lnwatcher is all done with the outpoint used as index in LNWatcher.tx_progress @@ -332,7 +333,7 @@ CHANNEL_OPENING_TIMEOUT = 24*60*60 class LNWalletWatcher(LNWatcher): - def __init__(self, lnworker, network): + def __init__(self, lnworker: 'LNWallet', network: 'Network'): LNWatcher.__init__(self, network) self.network = network self.lnworker = lnworker diff --git a/electrum/tests/test_lnchannel.py b/electrum/tests/test_lnchannel.py @@ -786,15 +786,15 @@ class TestChanReserve(ElectrumTestCase): alice_idx = self.alice_channel.add_htlc(htlc_dict).htlc_id bob_idx = self.bob_channel.receive_htlc(htlc_dict).htlc_id force_state_transition(self.alice_channel, self.bob_channel) - self.check_bals(one_bitcoin_in_msat*3\ - - self.alice_channel.pending_local_fee(), - one_bitcoin_in_msat*5) + self.check_bals(one_bitcoin_in_msat * 3 + - self.alice_channel.get_next_fee(LOCAL), + one_bitcoin_in_msat * 5) self.bob_channel.settle_htlc(paymentPreimage, bob_idx) self.alice_channel.receive_htlc_settle(paymentPreimage, alice_idx) force_state_transition(self.alice_channel, self.bob_channel) - self.check_bals(one_bitcoin_in_msat*3\ - - self.alice_channel.pending_local_fee(), - one_bitcoin_in_msat*7) + self.check_bals(one_bitcoin_in_msat * 3 + - self.alice_channel.get_next_fee(LOCAL), + one_bitcoin_in_msat * 7) # And now let Bob add an HTLC of 1 BTC. This will take Bob's balance # all the way down to his channel reserve, but since he is not paying # the fee this is okay. @@ -802,9 +802,9 @@ class TestChanReserve(ElectrumTestCase): self.bob_channel.add_htlc(htlc_dict) self.alice_channel.receive_htlc(htlc_dict) force_state_transition(self.alice_channel, self.bob_channel) - self.check_bals(one_bitcoin_in_msat*3\ - - self.alice_channel.pending_local_fee(), - one_bitcoin_in_msat*6) + self.check_bals(one_bitcoin_in_msat * 3 \ + - self.alice_channel.get_next_fee(LOCAL), + one_bitcoin_in_msat * 6) def check_bals(self, amt1, amt2): self.assertEqual(self.alice_channel.available_to_spend(LOCAL), amt1) @@ -840,7 +840,7 @@ class TestDust(ElectrumTestCase): self.assertEqual(len(alice_ctx.outputs()), 3) self.assertEqual(len(bob_ctx.outputs()), 2) default_fee = calc_static_fee(0) - self.assertEqual(bob_channel.pending_local_fee(), default_fee + htlcAmt) + self.assertEqual(bob_channel.get_next_fee(LOCAL), default_fee + htlcAmt) bob_channel.settle_htlc(paymentPreimage, bobHtlcIndex) alice_channel.receive_htlc_settle(paymentPreimage, aliceHtlcIndex) force_state_transition(bob_channel, alice_channel) diff --git a/electrum/tests/test_lnutil.py b/electrum/tests/test_lnutil.py @@ -510,13 +510,23 @@ class TestLNUtil(ElectrumTestCase): htlcs = [ScriptHtlc(htlc[x], htlc_obj[x]) for x in range(5)] our_commit_tx = make_commitment( - commitment_number, - local_funding_pubkey, remote_funding_pubkey, remotepubkey, - local_payment_basepoint, remote_payment_basepoint, - local_revocation_pubkey, local_delayedpubkey, local_delay, - funding_tx_id, funding_output_index, funding_amount_satoshi, - to_local_msat, to_remote_msat, local_dust_limit_satoshi, - calc_fees_for_commitment_tx(num_htlcs=len(htlcs), feerate=local_feerate_per_kw, is_local_initiator=True), htlcs=htlcs) + ctn=commitment_number, + local_funding_pubkey=local_funding_pubkey, + remote_funding_pubkey=remote_funding_pubkey, + remote_payment_pubkey=remotepubkey, + funder_payment_basepoint=local_payment_basepoint, + fundee_payment_basepoint=remote_payment_basepoint, + revocation_pubkey=local_revocation_pubkey, + delayed_pubkey=local_delayedpubkey, + to_self_delay=local_delay, + funding_txid=funding_tx_id, + funding_pos=funding_output_index, + funding_sat=funding_amount_satoshi, + local_amount=to_local_msat, + remote_amount=to_remote_msat, + dust_limit_sat=local_dust_limit_satoshi, + fees_per_participant=calc_fees_for_commitment_tx(num_htlcs=len(htlcs), feerate=local_feerate_per_kw, is_local_initiator=True), + htlcs=htlcs) self.sign_and_insert_remote_sig(our_commit_tx, remote_funding_pubkey, remote_signature, local_funding_pubkey, local_funding_privkey) self.assertEqual(str(our_commit_tx), output_commit_tx) @@ -587,13 +597,23 @@ class TestLNUtil(ElectrumTestCase): output_commit_tx= "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8001c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de8431100400473044022031a82b51bd014915fe68928d1abf4b9885353fb896cac10c3fdd88d7f9c7f2e00220716bda819641d2c63e65d3549b6120112e1aeaf1742eed94a471488e79e206b101473044022064901950be922e62cbe3f2ab93de2b99f37cff9fc473e73e394b27f88ef0731d02206d1dfa227527b4df44a07599289e207d6fd9cca60c0365682dcd3deaf739567e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220" our_commit_tx = make_commitment( - commitment_number, - local_funding_pubkey, remote_funding_pubkey, remotepubkey, - local_payment_basepoint, remote_payment_basepoint, - local_revocation_pubkey, local_delayedpubkey, local_delay, - funding_tx_id, funding_output_index, funding_amount_satoshi, - to_local_msat, to_remote_msat, local_dust_limit_satoshi, - calc_fees_for_commitment_tx(num_htlcs=0, feerate=local_feerate_per_kw, is_local_initiator=True), htlcs=[]) + ctn=commitment_number, + local_funding_pubkey=local_funding_pubkey, + remote_funding_pubkey=remote_funding_pubkey, + remote_payment_pubkey=remotepubkey, + funder_payment_basepoint=local_payment_basepoint, + fundee_payment_basepoint=remote_payment_basepoint, + revocation_pubkey=local_revocation_pubkey, + delayed_pubkey=local_delayedpubkey, + to_self_delay=local_delay, + funding_txid=funding_tx_id, + funding_pos=funding_output_index, + funding_sat=funding_amount_satoshi, + local_amount=to_local_msat, + remote_amount=to_remote_msat, + dust_limit_sat=local_dust_limit_satoshi, + fees_per_participant=calc_fees_for_commitment_tx(num_htlcs=0, feerate=local_feerate_per_kw, is_local_initiator=True), + htlcs=[]) self.sign_and_insert_remote_sig(our_commit_tx, remote_funding_pubkey, remote_signature, local_funding_pubkey, local_funding_privkey) self.assertEqual(str(our_commit_tx), output_commit_tx) @@ -606,13 +626,23 @@ class TestLNUtil(ElectrumTestCase): output_commit_tx= "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8001c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de8431100400473044022031a82b51bd014915fe68928d1abf4b9885353fb896cac10c3fdd88d7f9c7f2e00220716bda819641d2c63e65d3549b6120112e1aeaf1742eed94a471488e79e206b101473044022064901950be922e62cbe3f2ab93de2b99f37cff9fc473e73e394b27f88ef0731d02206d1dfa227527b4df44a07599289e207d6fd9cca60c0365682dcd3deaf739567e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220" our_commit_tx = make_commitment( - commitment_number, - local_funding_pubkey, remote_funding_pubkey, remotepubkey, - local_payment_basepoint, remote_payment_basepoint, - local_revocation_pubkey, local_delayedpubkey, local_delay, - funding_tx_id, funding_output_index, funding_amount_satoshi, - to_local_msat, to_remote_msat, local_dust_limit_satoshi, - calc_fees_for_commitment_tx(num_htlcs=0, feerate=local_feerate_per_kw, is_local_initiator=True), htlcs=[]) + ctn=commitment_number, + local_funding_pubkey=local_funding_pubkey, + remote_funding_pubkey=remote_funding_pubkey, + remote_payment_pubkey=remotepubkey, + funder_payment_basepoint=local_payment_basepoint, + fundee_payment_basepoint=remote_payment_basepoint, + revocation_pubkey=local_revocation_pubkey, + delayed_pubkey=local_delayedpubkey, + to_self_delay=local_delay, + funding_txid=funding_tx_id, + funding_pos=funding_output_index, + funding_sat=funding_amount_satoshi, + local_amount=to_local_msat, + remote_amount=to_remote_msat, + dust_limit_sat=local_dust_limit_satoshi, + fees_per_participant=calc_fees_for_commitment_tx(num_htlcs=0, feerate=local_feerate_per_kw, is_local_initiator=True), + htlcs=[]) self.sign_and_insert_remote_sig(our_commit_tx, remote_funding_pubkey, remote_signature, local_funding_pubkey, local_funding_privkey) self.assertEqual(str(our_commit_tx), output_commit_tx) @@ -662,15 +692,24 @@ class TestLNUtil(ElectrumTestCase): # to_remote amount 3000000 P2WPKH(0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b) remote_signature = "3045022100f51d2e566a70ba740fc5d8c0f07b9b93d2ed741c3c0860c613173de7d39e7968022041376d520e9c0e1ad52248ddf4b22e12be8763007df977253ef45a4ca3bdb7c0" # local_signature = 3044022051b75c73198c6deee1a875871c3961832909acd297c6b908d59e3319e5185a46022055c419379c5051a78d00dbbce11b5b664a0c22815fbcc6fcef6b1937c3836939 - htlcs=[] our_commit_tx = make_commitment( - commitment_number, - local_funding_pubkey, remote_funding_pubkey, remotepubkey, - local_payment_basepoint, remote_payment_basepoint, - local_revocation_pubkey, local_delayedpubkey, local_delay, - funding_tx_id, funding_output_index, funding_amount_satoshi, - to_local_msat, to_remote_msat, local_dust_limit_satoshi, - calc_fees_for_commitment_tx(num_htlcs=0, feerate=local_feerate_per_kw, is_local_initiator=True), htlcs=[]) + ctn=commitment_number, + local_funding_pubkey=local_funding_pubkey, + remote_funding_pubkey=remote_funding_pubkey, + remote_payment_pubkey=remotepubkey, + funder_payment_basepoint=local_payment_basepoint, + fundee_payment_basepoint=remote_payment_basepoint, + revocation_pubkey=local_revocation_pubkey, + delayed_pubkey=local_delayedpubkey, + to_self_delay=local_delay, + funding_txid=funding_tx_id, + funding_pos=funding_output_index, + funding_sat=funding_amount_satoshi, + local_amount=to_local_msat, + remote_amount=to_remote_msat, + dust_limit_sat=local_dust_limit_satoshi, + fees_per_participant=calc_fees_for_commitment_tx(num_htlcs=0, feerate=local_feerate_per_kw, is_local_initiator=True), + htlcs=[]) self.sign_and_insert_remote_sig(our_commit_tx, remote_funding_pubkey, remote_signature, local_funding_pubkey, local_funding_privkey) ref_commit_tx_str = '02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8002c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de84311054a56a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400473044022051b75c73198c6deee1a875871c3961832909acd297c6b908d59e3319e5185a46022055c419379c5051a78d00dbbce11b5b664a0c22815fbcc6fcef6b1937c383693901483045022100f51d2e566a70ba740fc5d8c0f07b9b93d2ed741c3c0860c613173de7d39e7968022041376d520e9c0e1ad52248ddf4b22e12be8763007df977253ef45a4ca3bdb7c001475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220' self.assertEqual(str(our_commit_tx), ref_commit_tx_str)