What changed, and why it matters
This commit simply moves a helper method that builds settings for new Lightning channels from one internal file to another. The commit message says 'no functional changes' and the diff confirms that: the same code, same values, and same checks are preserved. There is no user-visible change and no security fix or vulnerability introduced.
No action needed. This is a benign refactor with no security relevance.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change relocates make_local_config from lnpeer.Peer to lnworker.LNWallet, renaming it make_local_config_for_new_channel. The implementation is copied almost verbatim, with the only interface change being that peer_features is now passed as an explicit parameter instead of accessed via self.features. Call sites in lnpeer.py are updated accordingly. No logic, constants, validation, or cryptographic handling changed.
Changed components
electrum/lnpeer.pyelectrum/lnworker.pyInspect captured patch +72 / −68
diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py
index 73fc701..17b836d 100644
--- a/electrum/lnpeer.py
+++ b/electrum/lnpeer.py
@@ -917,71 +917,6 @@ class Peer(Logger, EventListener):
self.logger.info(f"upfront shutdown script received: {upfront_shutdown_script}")
return upfront_shutdown_script
- def make_local_config(
- self,
- *,
- funding_sat: int,
- push_msat: int,
- initiator: HTLCOwner,
- channel_type: ChannelType,
- multisig_funding_keypair: Optional[Keypair], # if None, will get derived from channel_seed
- ) -> LocalConfig:
- channel_seed = os.urandom(32)
- initial_msat = funding_sat * 1000 - push_msat if initiator == LOCAL else push_msat
-
- # sending empty bytes as the upfront_shutdown_script will give us the
- # flexibility to decide an address at closing time
- upfront_shutdown_script = b''
-
- assert channel_type is not None
- if channel_type & ChannelType.OPTION_ANCHORS_ZERO_FEE_HTLC_TX: # anchors
- static_payment_key = self.lnworker.static_payment_key
- static_remotekey = None
- else: # static_remotekey
- assert channel_type & channel_type.OPTION_STATIC_REMOTEKEY
- wallet = self.lnworker.wallet
- assert wallet.txin_type == 'p2wpkh'
- addr = wallet.get_new_sweep_address_for_channel()
- static_payment_key = None
- static_remotekey = bytes.fromhex(wallet.get_public_key(addr))
-
- if multisig_funding_keypair:
- for chan in self.lnworker.channels.values(): # check against all chans of lnworker, for sanity
- if multisig_funding_keypair.pubkey == chan.config[LOCAL].multisig_key.pubkey:
- raise Exception(
- "Refusing to reuse multisig_funding_keypair for new channel. "
- "Wait one block before opening another channel with this peer."
- )
-
- dust_limit_sat = bitcoin.DUST_LIMIT_P2PKH
- reserve_sat = max(funding_sat // 100, dust_limit_sat)
- # for comparison of defaults, see
- # https://github.com/ACINQ/eclair/blob/afa378fbb73c265da44856b4ad0f2128a88ae6c6/eclair-core/src/main/resources/reference.conf#L66
- # https://github.com/ElementsProject/lightning/blob/0056dd75572a8857cff36fcbdb1a2295a1ac9253/lightningd/options.c#L657
- # https://github.com/lightningnetwork/lnd/blob/56b61078c5b2be007d318673a5f3b40c6346883a/config.go#L81
- max_htlc_value_in_flight_msat = self.network.config.LIGHTNING_MAX_HTLC_VALUE_IN_FLIGHT_MSAT or funding_sat * 1000
- local_config = LocalConfig.from_seed(
- channel_seed=channel_seed,
- static_remotekey=static_remotekey,
- static_payment_key=static_payment_key,
- multisig_key=multisig_funding_keypair,
- upfront_shutdown_script=upfront_shutdown_script,
- to_self_delay=self.network.config.LIGHTNING_TO_SELF_DELAY_CSV,
- dust_limit_sat=dust_limit_sat,
- max_htlc_value_in_flight_msat=max_htlc_value_in_flight_msat,
- max_accepted_htlcs=30,
- initial_msat=initial_msat,
- reserve_sat=reserve_sat,
- funding_locked_received=False,
- current_commitment_signature=None,
- current_htlc_signatures=b'',
- htlc_minimum_msat=1,
- announcement_node_sig=b'',
- announcement_bitcoin_sig=b'',
- )
- local_config.validate_params(funding_sat=funding_sat, config=self.network.config, peer_features=self.features)
- return local_config
-
def temporarily_reserve_funding_tx_change_address(func):
# During the channel open flow, if we initiated, we might have used a change address
# of ours in the funding tx. The funding tx is not part of the wallet history
@@ -1066,12 +1001,13 @@ class Peer(Logger, EventListener):
)
else:
multisig_funding_keypair = None
- local_config = self.make_local_config(
+ local_config = self.lnworker.make_local_config_for_new_channel(
funding_sat=funding_sat,
push_msat=push_msat,
initiator=LOCAL,
channel_type=our_channel_type,
multisig_funding_keypair=multisig_funding_keypair,
+ peer_features=self.features,
)
# if it includes open_channel_tlvs: MUST include upfront_shutdown_script.
open_channel_tlvs['upfront_shutdown_script'] = {
@@ -1327,12 +1263,13 @@ class Peer(Logger, EventListener):
)
else:
multisig_funding_keypair = None
- local_config = self.make_local_config(
+ local_config = self.lnworker.make_local_config_for_new_channel(
funding_sat=funding_sat,
push_msat=push_msat,
initiator=REMOTE,
channel_type=channel_type,
multisig_funding_keypair=multisig_funding_keypair,
+ peer_features=self.features,
)
upfront_shutdown_script = self.upfront_shutdown_script_from_payload(
diff --git a/electrum/lnworker.py b/electrum/lnworker.py
index 6add346..6f17ebc 100644
--- a/electrum/lnworker.py
+++ b/electrum/lnworker.py
@@ -35,6 +35,7 @@ from .json_db import stored_in
from .channel_db import UpdateStatus, ChannelDBNotLoaded, get_mychannel_info, get_mychannel_policy
from . import constants, util, lnutil
+from . import bitcoin
from .util import (
profiler, OldTaskGroup, ESocksProxy, NetworkRetryManager, JsonRPCClient, NotEnoughFunds, EventListener,
event_listener, bfh, InvoiceError, resolve_dns_srv, is_ip_address, log_exceptions, ignore_exceptions,
@@ -73,7 +74,7 @@ from .lnutil import (
OnchainChannelBackupStorage, ln_compare_features, IncompatibleLightningFeatures, PaymentFeeBudget,
NBLOCK_CLTV_DELTA_TOO_FAR_INTO_FUTURE, GossipForwardingMessage, MIN_FUNDING_SAT,
MIN_FINAL_CLTV_DELTA_BUFFER_INVOICE, RecvMPPResolution, ReceivedMPPStatus, ReceivedMPPHtlc,
- PaymentSuccess,
+ PaymentSuccess, ChannelType, LocalConfig, Keypair,
)
from .lnonion import (
decode_onion_error, OnionFailureCode, OnionRoutingFailure, OnionPacket,
@@ -1601,6 +1602,72 @@ class LNWallet(Logger):
self.remove_channel(chan.channel_id)
raise
+ def make_local_config_for_new_channel(
+ self,
+ *,
+ funding_sat: int,
+ push_msat: int,
+ initiator: HTLCOwner,
+ channel_type: ChannelType,
+ multisig_funding_keypair: Optional[Keypair], # if None, will get derived from channel_seed
+ peer_features: LnFeatures,
+ ) -> LocalConfig:
+ channel_seed = os.urandom(32)
+ initial_msat = funding_sat * 1000 - push_msat if initiator == LOCAL else push_msat
+
+ # sending empty bytes as the upfront_shutdown_script will give us the
+ # flexibility to decide an address at closing time
+ upfront_shutdown_script = b''
+
+ assert channel_type is not None
+ if channel_type & ChannelType.OPTION_ANCHORS_ZERO_FEE_HTLC_TX: # anchors
+ static_payment_key = self.static_payment_key
+ static_remotekey = None
+ else: # static_remotekey
+ assert channel_type & channel_type.OPTION_STATIC_REMOTEKEY
+ wallet = self.wallet
+ assert wallet.txin_type == 'p2wpkh'
+ addr = wallet.get_new_sweep_address_for_channel()
+ static_payment_key = None
+ static_remotekey = bytes.fromhex(wallet.get_public_key(addr))
+
+ if multisig_funding_keypair:
+ for chan in self.channels.values(): # check against all chans of lnworker, for sanity
+ if multisig_funding_keypair.pubkey == chan.config[LOCAL].multisig_key.pubkey:
+ raise Exception(
+ "Refusing to reuse multisig_funding_keypair for new channel. "
+ "Wait one block before opening another channel with this peer."
+ )
+
+ dust_limit_sat = bitcoin.DUST_LIMIT_P2PKH
+ reserve_sat = max(funding_sat // 100, dust_limit_sat)
+ # for comparison of defaults, see
+ # https://github.com/ACINQ/eclair/blob/afa378fbb73c265da44856b4ad0f2128a88ae6c6/eclair-core/src/main/resources/reference.conf#L66
+ # https://github.com/ElementsProject/lightning/blob/0056dd75572a8857cff36fcbdb1a2295a1ac9253/lightningd/options.c#L657
+ # https://github.com/lightningnetwork/lnd/blob/56b61078c5b2be007d318673a5f3b40c6346883a/config.go#L81
+ max_htlc_value_in_flight_msat = self.network.config.LIGHTNING_MAX_HTLC_VALUE_IN_FLIGHT_MSAT or funding_sat * 1000
+ local_config = LocalConfig.from_seed(
+ channel_seed=channel_seed,
+ static_remotekey=static_remotekey,
+ static_payment_key=static_payment_key,
+ multisig_key=multisig_funding_keypair,
+ upfront_shutdown_script=upfront_shutdown_script,
+ to_self_delay=self.network.config.LIGHTNING_TO_SELF_DELAY_CSV,
+ dust_limit_sat=dust_limit_sat,
+ max_htlc_value_in_flight_msat=max_htlc_value_in_flight_msat,
+ max_accepted_htlcs=30,
+ initial_msat=initial_msat,
+ reserve_sat=reserve_sat,
+ funding_locked_received=False,
+ current_commitment_signature=None,
+ current_htlc_signatures=b'',
+ htlc_minimum_msat=1,
+ announcement_node_sig=b'',
+ announcement_bitcoin_sig=b'',
+ )
+ local_config.validate_params(funding_sat=funding_sat, config=self.network.config, peer_features=peer_features)
+ return local_config
+
def cb_data(self, node_id: bytes) -> bytes:
return CB_MAGIC_BYTES + node_id[0:NODE_ID_PREFIX_LEN]
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.