tlnutil: restructure channel config namedtuples (local/remote config) - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit 521fadb8cb565ff683a1c7a06092da5277a67b94 DIR parent 14256286047a015dc5124d99d13bbbe3c605f9b7 HTML Author: SomberNight <somber.night@protonmail.com> Date: Wed, 7 Nov 2018 17:54:46 +0100 lnutil: restructure channel config namedtuples (local/remote config) Diffstat: M electrum/lnbase.py | 44 ++++++++++++------------------- M electrum/lnutil.py | 78 +++++++++++++++++++------------ 2 files changed, 64 insertions(+), 58 deletions(-) --- DIR diff --git a/electrum/lnbase.py b/electrum/lnbase.py t@@ -26,7 +26,7 @@ from .transaction import Transaction, TxOutput from .lnonion import (new_onion_packet, decode_onion_error, OnionFailureCode, calc_hops_data_for_payment, process_onion_packet, OnionPacket, construct_onion_error, OnionRoutingFailureMessage) from .lnchan import Channel, RevokeAndAck, htlcsum -from .lnutil import (Outpoint, LocalConfig, ChannelConfig, +from .lnutil import (Outpoint, LocalConfig, RemoteConfig, OnlyPubkeyKeypair, ChannelConstraints, RevocationStore, funding_output_script, get_per_commitment_secret_from_seed, secret_to_pubkey, LNPeerAddr, PaymentFailure, LnLocalFeatures, t@@ -381,7 +381,7 @@ class Peer(PrintError): chan.set_state('DISCONNECTED') self.network.trigger_callback('channel', chan) - def make_local_config(self, funding_sat: int, push_msat: int, initiator: HTLCOwner) -> Tuple[ChannelConfig, bytes]: + def make_local_config(self, funding_sat: int, push_msat: int, initiator: HTLCOwner) -> LocalConfig: # key derivation channel_counter = self.lnworker.get_and_inc_counter_for_channel_keys() keypair_generator = lambda family: generate_keypair(self.lnworker.ln_keystore, family, channel_counter) t@@ -389,7 +389,7 @@ class Peer(PrintError): initial_msat = funding_sat * 1000 - push_msat else: initial_msat = push_msat - local_config=ChannelConfig( + local_config=LocalConfig( payment_basepoint=keypair_generator(LnKeyFamily.PAYMENT_BASE), multisig_key=keypair_generator(LnKeyFamily.MULTISIG), htlc_basepoint=keypair_generator(LnKeyFamily.HTLC_BASE), t@@ -404,9 +404,13 @@ class Peer(PrintError): next_htlc_id=0, amount_msat=initial_msat, reserve_sat=546, + per_commitment_secret_seed=keypair_generator(LnKeyFamily.REVOCATION_ROOT).privkey, + funding_locked_received=False, + was_announced=False, + current_commitment_signature=None, + current_htlc_signatures=[], ) - per_commitment_secret_seed = keypair_generator(LnKeyFamily.REVOCATION_ROOT).privkey - return local_config, per_commitment_secret_seed + return local_config @log_exceptions async def channel_establishment_flow(self, password: Optional[str], funding_sat: int, t@@ -417,9 +421,10 @@ class Peer(PrintError): password, self.lnworker.config, nonlocal_only=True) await self.initialized feerate = self.current_feerate_per_kw() - local_config, per_commitment_secret_seed = self.make_local_config(funding_sat, push_msat, LOCAL) + local_config = self.make_local_config(funding_sat, push_msat, LOCAL) # for the first commitment transaction - per_commitment_secret_first = get_per_commitment_secret_from_seed(per_commitment_secret_seed, RevocationStore.START_INDEX) + per_commitment_secret_first = get_per_commitment_secret_from_seed(local_config.per_commitment_secret_seed, + RevocationStore.START_INDEX) per_commitment_point_first = secret_to_pubkey(int.from_bytes(per_commitment_secret_first, 'big')) self.send_message( "open_channel", t@@ -488,14 +493,7 @@ class Peer(PrintError): "short_channel_id": None, "funding_outpoint": Outpoint(funding_txid, funding_index), "remote_config": remote_config, - "local_config": LocalConfig( - **local_config._asdict(), - per_commitment_secret_seed=per_commitment_secret_seed, - funding_locked_received = False, - was_announced = False, - current_commitment_signature = None, - current_htlc_signatures = None, - ), + "local_config": local_config, "constraints": ChannelConstraints(capacity=funding_sat, is_initiator=True, funding_txn_minimum_depth=funding_txn_minimum_depth, feerate=feerate), "remote_commitment_to_be_revoked": None, } t@@ -530,12 +528,11 @@ class Peer(PrintError): feerate = int.from_bytes(payload['feerate_per_kw'], 'big') temp_chan_id = payload['temporary_channel_id'] - local_config, per_commitment_secret_seed = self.make_local_config(funding_sat * 1000, push_msat, REMOTE) - + local_config = self.make_local_config(funding_sat * 1000, push_msat, REMOTE) # for the first commitment transaction - per_commitment_secret_first = get_per_commitment_secret_from_seed(per_commitment_secret_seed, RevocationStore.START_INDEX) + per_commitment_secret_first = get_per_commitment_secret_from_seed(local_config.per_commitment_secret_seed, + RevocationStore.START_INDEX) per_commitment_point_first = secret_to_pubkey(int.from_bytes(per_commitment_secret_first, 'big')) - min_depth = 3 self.send_message('accept_channel', temporary_channel_id=temp_chan_id, t@@ -586,14 +583,7 @@ class Peer(PrintError): current_per_commitment_point=None, revocation_store=their_revocation_store, ), - "local_config": LocalConfig( - **local_config._asdict(), - per_commitment_secret_seed=per_commitment_secret_seed, - funding_locked_received = False, - was_announced = False, - current_commitment_signature = None, - current_htlc_signatures = None, - ), + "local_config": local_config, "constraints": ChannelConstraints(capacity=funding_sat, is_initiator=False, funding_txn_minimum_depth=min_depth, feerate=feerate), "remote_commitment_to_be_revoked": None, } DIR diff --git a/electrum/lnutil.py b/electrum/lnutil.py t@@ -27,32 +27,53 @@ HTLC_SUCCESS_WEIGHT = 703 Keypair = namedtuple("Keypair", ["pubkey", "privkey"]) OnlyPubkeyKeypair = namedtuple("OnlyPubkeyKeypair", ["pubkey"]) -common = [ - ('ctn' , int), - ('amount_msat' , int), - ('next_htlc_id' , int), - ('payment_basepoint' , Keypair), - ('multisig_key' , Keypair), - ('htlc_basepoint' , Keypair), - ('delayed_basepoint' , Keypair), - ('revocation_basepoint' , Keypair), - ('to_self_delay' , int), - ('dust_limit_sat' , int), - ('max_htlc_value_in_flight_msat' , int), - ('max_accepted_htlcs' , int), - ('initial_msat' , int), - ('reserve_sat', int), -] - -ChannelConfig = NamedTuple('ChannelConfig', common) - -LocalConfig = NamedTuple('LocalConfig', common + [ - ('per_commitment_secret_seed', bytes), - ('funding_locked_received', bool), - ('was_announced', bool), - ('current_commitment_signature', bytes), - ('current_htlc_signatures', List[bytes]), -]) + +# NamedTuples cannot subclass NamedTuples :'( https://github.com/python/typing/issues/427 +class LocalConfig(NamedTuple): + # shared channel config fields (DUPLICATED code!!) + ctn: int + amount_msat: int + next_htlc_id: int + payment_basepoint: 'Keypair' + multisig_key: 'Keypair' + htlc_basepoint: 'Keypair' + delayed_basepoint: 'Keypair' + revocation_basepoint: 'Keypair' + to_self_delay: int + dust_limit_sat: int + max_htlc_value_in_flight_msat: int + max_accepted_htlcs: int + initial_msat: int + reserve_sat: int + # specific to "LOCAL" config + per_commitment_secret_seed: bytes + funding_locked_received: bool + was_announced: bool + current_commitment_signature: Optional[bytes] + current_htlc_signatures: List[bytes] + + +class RemoteConfig(NamedTuple): + # shared channel config fields (DUPLICATED code!!) + ctn: int + amount_msat: int + next_htlc_id: int + payment_basepoint: 'Keypair' + multisig_key: 'Keypair' + htlc_basepoint: 'Keypair' + delayed_basepoint: 'Keypair' + revocation_basepoint: 'Keypair' + to_self_delay: int + dust_limit_sat: int + max_htlc_value_in_flight_msat: int + max_accepted_htlcs: int + initial_msat: int + reserve_sat: int + # specific to "REMOTE" config + next_per_commitment_point: bytes + revocation_store: 'RevocationStore' + current_per_commitment_point: Optional[bytes] + ChannelConstraints = namedtuple("ChannelConstraints", ["capacity", "is_initiator", "funding_txn_minimum_depth", "feerate"]) t@@ -129,11 +150,6 @@ class RevocationStore: def __hash__(self): return hash(json.dumps(self.serialize(), sort_keys=True)) -RemoteConfig = NamedTuple('RemoteConfig', common + [ - ('next_per_commitment_point' , bytes), - ('revocation_store' , RevocationStore), - ('current_per_commitment_point' , bytes), -]) def count_trailing_zeros(index): """ BOLT-03 (where_to_put_secret) """