URI: 
       tchannel open: allow REMOTE to set htlc_minimum_msat to 0 - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit ea329063bff80856673c04486accc0caed491cc3
   DIR parent 937d8a1f0f14a36bf34d993e2e85f92a2626c599
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Fri, 19 Jun 2020 18:15:09 +0200
       
       channel open: allow REMOTE to set htlc_minimum_msat to 0
       
       non-positive values do not make sense... but some nodes set it to 0
       and if we enforce >= 1 then we can't open channels with those...
       lnchannel._assert_can_add_htlc enforces positive values for HTLCs in any case.
       
       Diffstat:
         M electrum/lnutil.py                  |      33 +++++++++++++++++++++-----------
       
       1 file changed, 22 insertions(+), 11 deletions(-)
       ---
   DIR diff --git a/electrum/lnutil.py b/electrum/lnutil.py
       t@@ -82,6 +82,7 @@ class Config(StoredObject):
            htlc_minimum_msat = attr.ib(type=int)  # smallest value for INCOMING htlc
        
            def validate_params(self, *, funding_sat: int) -> None:
       +        conf_name = type(self).__name__
                for key in (
                        self.payment_basepoint,
                        self.multisig_key,
       t@@ -90,27 +91,28 @@ class Config(StoredObject):
                        self.revocation_basepoint
                ):
                    if not (len(key.pubkey) == 33 and ecc.ECPubkey.is_pubkey_bytes(key.pubkey)):
       -                raise Exception("invalid pubkey in channel config")
       +                raise Exception(f"{conf_name}. invalid pubkey in channel config")
                if self.reserve_sat < self.dust_limit_sat:
       -            raise Exception("MUST set channel_reserve_satoshis greater than or equal to dust_limit_satoshis")
       +            raise Exception(f"{conf_name}. MUST set channel_reserve_satoshis greater than or equal to dust_limit_satoshis")
                # technically this could be using the lower DUST_LIMIT_DEFAULT_SAT_SEGWIT
                # but other implementations are checking against this value too; also let's be conservative
                if self.dust_limit_sat < bitcoin.DUST_LIMIT_DEFAULT_SAT_LEGACY:
       -            raise Exception(f"dust limit too low: {self.dust_limit_sat} sat")
       +            raise Exception(f"{conf_name}. dust limit too low: {self.dust_limit_sat} sat")
                if self.reserve_sat > funding_sat // 100:
       -            raise Exception(f'reserve too high: {self.reserve_sat}, funding_sat: {funding_sat}')
       +            raise Exception(f"{conf_name}. reserve too high: {self.reserve_sat}, funding_sat: {funding_sat}")
                if self.htlc_minimum_msat > 1_000:
       -            raise Exception(f"htlc_minimum_msat too high: {self.htlc_minimum_msat} msat")
       -        if self.htlc_minimum_msat < 1:
       -            raise Exception(f"htlc_minimum_msat too low: {self.htlc_minimum_msat} msat")
       +            raise Exception(f"{conf_name}. htlc_minimum_msat too high: {self.htlc_minimum_msat} msat")
       +        HTLC_MINIMUM_MSAT_MIN = 0  # should be at least 1 really, but apparently some nodes are sending zero...
       +        if self.htlc_minimum_msat < HTLC_MINIMUM_MSAT_MIN:
       +            raise Exception(f"{conf_name}. htlc_minimum_msat too low: {self.htlc_minimum_msat} msat < {HTLC_MINIMUM_MSAT_MIN}")
                if self.max_accepted_htlcs < 1:
       -            raise Exception(f"max_accepted_htlcs too low: {self.max_accepted_htlcs}")
       +            raise Exception(f"{conf_name}. max_accepted_htlcs too low: {self.max_accepted_htlcs}")
                if self.max_accepted_htlcs > 483:
       -            raise Exception(f"max_accepted_htlcs too high: {self.max_accepted_htlcs}")
       +            raise Exception(f"{conf_name}. max_accepted_htlcs too high: {self.max_accepted_htlcs}")
                if self.to_self_delay > MAXIMUM_REMOTE_TO_SELF_DELAY_ACCEPTED:
       -            raise Exception(f"to_self_delay too high: {self.to_self_delay} > {MAXIMUM_REMOTE_TO_SELF_DELAY_ACCEPTED}")
       +            raise Exception(f"{conf_name}. to_self_delay too high: {self.to_self_delay} > {MAXIMUM_REMOTE_TO_SELF_DELAY_ACCEPTED}")
                if self.max_htlc_value_in_flight_msat < min(1000 * funding_sat, 100_000_000):
       -            raise Exception(f"max_htlc_value_in_flight_msat is too small: {self.max_htlc_value_in_flight_msat}")
       +            raise Exception(f"{conf_name}. max_htlc_value_in_flight_msat is too small: {self.max_htlc_value_in_flight_msat}")
        
        
        @attr.s
       t@@ -136,6 +138,15 @@ class LocalConfig(Config):
                kwargs['payment_basepoint'] = OnlyPubkeyKeypair(static_remotekey) if static_remotekey else keypair_generator(LnKeyFamily.PAYMENT_BASE)
                return LocalConfig(**kwargs)
        
       +    def validate_params(self, *, funding_sat: int) -> None:
       +        conf_name = type(self).__name__
       +        # run base checks regardless whether LOCAL/REMOTE config
       +        super().validate_params(funding_sat=funding_sat)
       +        # run some stricter checks on LOCAL config (make sure we ourselves do the sane thing,
       +        # even if we are lenient with REMOTE for compatibility reasons)
       +        HTLC_MINIMUM_MSAT_MIN = 1
       +        if self.htlc_minimum_msat < HTLC_MINIMUM_MSAT_MIN:
       +            raise Exception(f"{conf_name}. htlc_minimum_msat too low: {self.htlc_minimum_msat} msat < {HTLC_MINIMUM_MSAT_MIN}")
        
        @attr.s
        class RemoteConfig(Config):