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