@@ -603,9 +603,6 @@ class Peer(Logger):
|
|||||||
def is_shutdown_anysegwit(self):
|
def is_shutdown_anysegwit(self):
|
||||||
return self.features.supports(LnFeatures.OPTION_SHUTDOWN_ANYSEGWIT_OPT)
|
return self.features.supports(LnFeatures.OPTION_SHUTDOWN_ANYSEGWIT_OPT)
|
||||||
|
|
||||||
def supports_large_channels(self):
|
|
||||||
return self.features.supports(LnFeatures.OPTION_SUPPORT_LARGE_CHANNELS)
|
|
||||||
|
|
||||||
def is_channel_type(self):
|
def is_channel_type(self):
|
||||||
return self.features.supports(LnFeatures.OPTION_CHANNEL_TYPE_OPT)
|
return self.features.supports(LnFeatures.OPTION_CHANNEL_TYPE_OPT)
|
||||||
|
|
||||||
@@ -662,7 +659,7 @@ class Peer(Logger):
|
|||||||
current_htlc_signatures=b'',
|
current_htlc_signatures=b'',
|
||||||
htlc_minimum_msat=1,
|
htlc_minimum_msat=1,
|
||||||
)
|
)
|
||||||
local_config.validate_params(funding_sat=funding_sat)
|
local_config.validate_params(funding_sat=funding_sat, config=self.network.config, peer_features=self.features)
|
||||||
return local_config
|
return local_config
|
||||||
|
|
||||||
def temporarily_reserve_funding_tx_change_address(func):
|
def temporarily_reserve_funding_tx_change_address(func):
|
||||||
@@ -807,6 +804,8 @@ class Peer(Logger):
|
|||||||
funding_sat=funding_sat,
|
funding_sat=funding_sat,
|
||||||
is_local_initiator=True,
|
is_local_initiator=True,
|
||||||
initial_feerate_per_kw=feerate,
|
initial_feerate_per_kw=feerate,
|
||||||
|
config=self.network.config,
|
||||||
|
peer_features=self.features,
|
||||||
)
|
)
|
||||||
|
|
||||||
# -> funding created
|
# -> funding created
|
||||||
@@ -967,6 +966,8 @@ class Peer(Logger):
|
|||||||
funding_sat=funding_sat,
|
funding_sat=funding_sat,
|
||||||
is_local_initiator=False,
|
is_local_initiator=False,
|
||||||
initial_feerate_per_kw=feerate,
|
initial_feerate_per_kw=feerate,
|
||||||
|
config=self.network.config,
|
||||||
|
peer_features=self.features,
|
||||||
)
|
)
|
||||||
|
|
||||||
# note: we ignore payload['channel_flags'], which e.g. contains 'announce_channel'.
|
# note: we ignore payload['channel_flags'], which e.g. contains 'announce_channel'.
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ if TYPE_CHECKING:
|
|||||||
from .lnchannel import Channel, AbstractChannel
|
from .lnchannel import Channel, AbstractChannel
|
||||||
from .lnrouter import LNPaymentRoute
|
from .lnrouter import LNPaymentRoute
|
||||||
from .lnonion import OnionRoutingFailure
|
from .lnonion import OnionRoutingFailure
|
||||||
|
from .simple_config import SimpleConfig
|
||||||
|
|
||||||
|
|
||||||
_logger = get_logger(__name__)
|
_logger = get_logger(__name__)
|
||||||
@@ -49,6 +50,7 @@ HTLC_SUCCESS_WEIGHT = 703
|
|||||||
COMMITMENT_TX_WEIGHT = 724
|
COMMITMENT_TX_WEIGHT = 724
|
||||||
HTLC_OUTPUT_WEIGHT = 172
|
HTLC_OUTPUT_WEIGHT = 172
|
||||||
|
|
||||||
|
LN_MAX_FUNDING_SAT_LEGACY = pow(2, 24) - 1
|
||||||
DUST_LIMIT_MAX = 1000
|
DUST_LIMIT_MAX = 1000
|
||||||
|
|
||||||
# dummy address for fee estimation of funding tx
|
# dummy address for fee estimation of funding tx
|
||||||
@@ -92,7 +94,7 @@ class ChannelConfig(StoredObject):
|
|||||||
htlc_minimum_msat = attr.ib(type=int) # smallest value for INCOMING htlc
|
htlc_minimum_msat = attr.ib(type=int) # smallest value for INCOMING htlc
|
||||||
upfront_shutdown_script = attr.ib(type=bytes, converter=hex_to_bytes)
|
upfront_shutdown_script = attr.ib(type=bytes, converter=hex_to_bytes)
|
||||||
|
|
||||||
def validate_params(self, *, funding_sat: int) -> None:
|
def validate_params(self, *, funding_sat: int, config: 'SimpleConfig', peer_features: 'LnFeatures') -> None:
|
||||||
conf_name = type(self).__name__
|
conf_name = type(self).__name__
|
||||||
for key in (
|
for key in (
|
||||||
self.payment_basepoint,
|
self.payment_basepoint,
|
||||||
@@ -105,6 +107,12 @@ class ChannelConfig(StoredObject):
|
|||||||
raise Exception(f"{conf_name}. invalid pubkey in channel config")
|
raise Exception(f"{conf_name}. invalid pubkey in channel config")
|
||||||
if funding_sat < MIN_FUNDING_SAT:
|
if funding_sat < MIN_FUNDING_SAT:
|
||||||
raise Exception(f"funding_sat too low: {funding_sat} sat < {MIN_FUNDING_SAT}")
|
raise Exception(f"funding_sat too low: {funding_sat} sat < {MIN_FUNDING_SAT}")
|
||||||
|
if not peer_features.supports(LnFeatures.OPTION_SUPPORT_LARGE_CHANNEL_OPT):
|
||||||
|
# MUST set funding_satoshis to less than 2^24 satoshi
|
||||||
|
if funding_sat > LN_MAX_FUNDING_SAT_LEGACY:
|
||||||
|
raise Exception(f"funding_sat too high: {funding_sat} sat > {LN_MAX_FUNDING_SAT_LEGACY} (legacy limit)")
|
||||||
|
if funding_sat > config.LIGHTNING_MAX_FUNDING_SAT:
|
||||||
|
raise Exception(f"funding_sat too high: {funding_sat} sat > {config.LIGHTNING_MAX_FUNDING_SAT} (config setting)")
|
||||||
# MUST set push_msat to equal or less than 1000 * funding_satoshis
|
# MUST set push_msat to equal or less than 1000 * funding_satoshis
|
||||||
if not (0 <= self.initial_msat <= 1000 * funding_sat):
|
if not (0 <= self.initial_msat <= 1000 * funding_sat):
|
||||||
raise Exception(f"{conf_name}. insane initial_msat={self.initial_msat}. (funding_sat={funding_sat})")
|
raise Exception(f"{conf_name}. insane initial_msat={self.initial_msat}. (funding_sat={funding_sat})")
|
||||||
@@ -139,10 +147,12 @@ class ChannelConfig(StoredObject):
|
|||||||
funding_sat: int,
|
funding_sat: int,
|
||||||
is_local_initiator: bool, # whether we are the funder
|
is_local_initiator: bool, # whether we are the funder
|
||||||
initial_feerate_per_kw: int,
|
initial_feerate_per_kw: int,
|
||||||
|
config: 'SimpleConfig',
|
||||||
|
peer_features: 'LnFeatures',
|
||||||
) -> None:
|
) -> None:
|
||||||
# first we validate the configs separately
|
# first we validate the configs separately
|
||||||
local_config.validate_params(funding_sat=funding_sat)
|
local_config.validate_params(funding_sat=funding_sat, config=config, peer_features=peer_features)
|
||||||
remote_config.validate_params(funding_sat=funding_sat)
|
remote_config.validate_params(funding_sat=funding_sat, config=config, peer_features=peer_features)
|
||||||
# now do tests that need access to both configs
|
# now do tests that need access to both configs
|
||||||
if is_local_initiator:
|
if is_local_initiator:
|
||||||
funder, fundee = LOCAL, REMOTE
|
funder, fundee = LOCAL, REMOTE
|
||||||
@@ -209,10 +219,10 @@ class LocalConfig(ChannelConfig):
|
|||||||
kwargs['payment_basepoint'] = keypair_generator(LnKeyFamily.PAYMENT_BASE)
|
kwargs['payment_basepoint'] = keypair_generator(LnKeyFamily.PAYMENT_BASE)
|
||||||
return LocalConfig(**kwargs)
|
return LocalConfig(**kwargs)
|
||||||
|
|
||||||
def validate_params(self, *, funding_sat: int) -> None:
|
def validate_params(self, *, funding_sat: int, config: 'SimpleConfig', peer_features: 'LnFeatures') -> None:
|
||||||
conf_name = type(self).__name__
|
conf_name = type(self).__name__
|
||||||
# run base checks regardless whether LOCAL/REMOTE config
|
# run base checks regardless whether LOCAL/REMOTE config
|
||||||
super().validate_params(funding_sat=funding_sat)
|
super().validate_params(funding_sat=funding_sat, config=config, peer_features=peer_features)
|
||||||
# run some stricter checks on LOCAL config (make sure we ourselves do the sane thing,
|
# 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)
|
# even if we are lenient with REMOTE for compatibility reasons)
|
||||||
HTLC_MINIMUM_MSAT_MIN = 1
|
HTLC_MINIMUM_MSAT_MIN = 1
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ from . import invoices
|
|||||||
from .util import base_units, base_unit_name_to_decimal_point, decimal_point_to_base_unit_name, UnknownBaseUnit, DECIMAL_POINT_DEFAULT
|
from .util import base_units, base_unit_name_to_decimal_point, decimal_point_to_base_unit_name, UnknownBaseUnit, DECIMAL_POINT_DEFAULT
|
||||||
from .util import format_satoshis, format_fee_satoshis, os_chmod
|
from .util import format_satoshis, format_fee_satoshis, os_chmod
|
||||||
from .util import user_dir, make_dir, NoDynamicFeeEstimates, quantize_feerate
|
from .util import user_dir, make_dir, NoDynamicFeeEstimates, quantize_feerate
|
||||||
|
from .lnutil import LN_MAX_FUNDING_SAT_LEGACY
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
from .logging import get_logger, Logger
|
from .logging import get_logger, Logger
|
||||||
|
|
||||||
@@ -888,7 +889,7 @@ class SimpleConfig(Logger):
|
|||||||
LIGHTNING_USE_RECOVERABLE_CHANNELS = ConfigVar('use_recoverable_channels', default=True, type_=bool)
|
LIGHTNING_USE_RECOVERABLE_CHANNELS = ConfigVar('use_recoverable_channels', default=True, type_=bool)
|
||||||
LIGHTNING_ALLOW_INSTANT_SWAPS = ConfigVar('allow_instant_swaps', default=False, type_=bool)
|
LIGHTNING_ALLOW_INSTANT_SWAPS = ConfigVar('allow_instant_swaps', default=False, type_=bool)
|
||||||
LIGHTNING_TO_SELF_DELAY_CSV = ConfigVar('lightning_to_self_delay', default=7 * 144, type_=int)
|
LIGHTNING_TO_SELF_DELAY_CSV = ConfigVar('lightning_to_self_delay', default=7 * 144, type_=int)
|
||||||
LIGHTNING_MAX_FUNDING_SAT = ConfigVar('lightning_max_funding_sat', default=pow(2, 24) - 1, type_=int)
|
LIGHTNING_MAX_FUNDING_SAT = ConfigVar('lightning_max_funding_sat', default=LN_MAX_FUNDING_SAT_LEGACY, type_=int)
|
||||||
|
|
||||||
EXPERIMENTAL_LN_FORWARD_PAYMENTS = ConfigVar('lightning_forward_payments', default=False, type_=bool)
|
EXPERIMENTAL_LN_FORWARD_PAYMENTS = ConfigVar('lightning_forward_payments', default=False, type_=bool)
|
||||||
EXPERIMENTAL_LN_FORWARD_TRAMPOLINE_PAYMENTS = ConfigVar('lightning_forward_trampoline_payments', default=False, type_=bool)
|
EXPERIMENTAL_LN_FORWARD_TRAMPOLINE_PAYMENTS = ConfigVar('lightning_forward_trampoline_payments', default=False, type_=bool)
|
||||||
|
|||||||
Reference in New Issue
Block a user