lnworker: imports, formatting, whitespace
This commit is contained in:
@@ -35,16 +35,17 @@ from . import constants, util
|
|||||||
from .util import (
|
from .util import (
|
||||||
profiler, OldTaskGroup, ESocksProxy, NetworkRetryManager, JsonRPCClient, NotEnoughFunds, EventListener,
|
profiler, OldTaskGroup, ESocksProxy, NetworkRetryManager, JsonRPCClient, NotEnoughFunds, EventListener,
|
||||||
event_listener, bfh, InvoiceError, resolve_dns_srv, is_ip_address, log_exceptions, ignore_exceptions,
|
event_listener, bfh, InvoiceError, resolve_dns_srv, is_ip_address, log_exceptions, ignore_exceptions,
|
||||||
make_aiohttp_session, timestamp_to_datetime, random_shuffled_copy, is_private_netaddress,
|
make_aiohttp_session, random_shuffled_copy, is_private_netaddress,
|
||||||
UnrelatedTransactionException, LightningHistoryItem
|
UnrelatedTransactionException, LightningHistoryItem
|
||||||
)
|
)
|
||||||
from .fee_policy import FeePolicy, FixedFeePolicy
|
from .fee_policy import (
|
||||||
from .fee_policy import (FEERATE_FALLBACK_STATIC_FEE, FEE_LN_ETA_TARGET, FEE_LN_LOW_ETA_TARGET,
|
FeePolicy, FEERATE_FALLBACK_STATIC_FEE, FEE_LN_ETA_TARGET, FEE_LN_LOW_ETA_TARGET,
|
||||||
FEERATE_PER_KW_MIN_RELAY_LIGHTNING, FEE_LN_MINIMUM_ETA_TARGET)
|
FEERATE_PER_KW_MIN_RELAY_LIGHTNING, FEE_LN_MINIMUM_ETA_TARGET
|
||||||
|
)
|
||||||
from .invoices import Invoice, PR_UNPAID, PR_PAID, PR_INFLIGHT, PR_FAILED, LN_EXPIRY_NEVER, BaseInvoice
|
from .invoices import Invoice, PR_UNPAID, PR_PAID, PR_INFLIGHT, PR_FAILED, LN_EXPIRY_NEVER, BaseInvoice
|
||||||
from .bitcoin import COIN, opcodes, make_op_return, address_to_scripthash, DummyAddress
|
from .bitcoin import COIN, opcodes, make_op_return, address_to_scripthash, DummyAddress
|
||||||
from .bip32 import BIP32Node
|
from .bip32 import BIP32Node
|
||||||
from .address_synchronizer import TX_HEIGHT_LOCAL, TX_TIMESTAMP_INF
|
from .address_synchronizer import TX_HEIGHT_LOCAL
|
||||||
from .transaction import (
|
from .transaction import (
|
||||||
Transaction, get_script_type_from_output_script, PartialTxOutput, PartialTransaction, PartialTxInput
|
Transaction, get_script_type_from_output_script, PartialTxOutput, PartialTransaction, PartialTxInput
|
||||||
)
|
)
|
||||||
@@ -53,7 +54,10 @@ from .crypto import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from .onion_message import OnionMessageManager
|
from .onion_message import OnionMessageManager
|
||||||
from .lntransport import LNTransport, LNResponderTransport, LNTransportBase, LNPeerAddr, split_host_port, extract_nodeid, ConnStringFormatError
|
from .lntransport import (
|
||||||
|
LNTransport, LNResponderTransport, LNTransportBase, LNPeerAddr, split_host_port, extract_nodeid,
|
||||||
|
ConnStringFormatError
|
||||||
|
)
|
||||||
from .lnpeer import Peer, LN_P2P_NETWORK_TIMEOUT
|
from .lnpeer import Peer, LN_P2P_NETWORK_TIMEOUT
|
||||||
from .lnaddr import lnencode, LnAddr, lndecode
|
from .lnaddr import lnencode, LnAddr, lndecode
|
||||||
from .lnchannel import Channel, AbstractChannel, ChannelState, PeerState, HTLCWithStatus, ChannelBackup
|
from .lnchannel import Channel, AbstractChannel, ChannelState, PeerState, HTLCWithStatus, ChannelBackup
|
||||||
@@ -844,7 +848,7 @@ class LNWallet(LNWorker):
|
|||||||
LNWorker.__init__(self, self.node_keypair, features, config=self.config)
|
LNWorker.__init__(self, self.node_keypair, features, config=self.config)
|
||||||
self.lnwatcher = LNWatcher(self)
|
self.lnwatcher = LNWatcher(self)
|
||||||
self.lnrater: LNRater = None
|
self.lnrater: LNRater = None
|
||||||
self.payment_info = self.db.get_dict('lightning_payments') # RHASH -> amount, direction, is_paid
|
self.payment_info = self.db.get_dict('lightning_payments') # RHASH -> amount, direction, is_paid
|
||||||
self._preimages = self.db.get_dict('lightning_preimages') # RHASH -> preimage
|
self._preimages = self.db.get_dict('lightning_preimages') # RHASH -> preimage
|
||||||
self._bolt11_cache = {}
|
self._bolt11_cache = {}
|
||||||
# note: this sweep_address is only used as fallback; as it might result in address-reuse
|
# note: this sweep_address is only used as fallback; as it might result in address-reuse
|
||||||
@@ -915,7 +919,7 @@ class LNWallet(LNWorker):
|
|||||||
def has_anchor_channels(self) -> bool:
|
def has_anchor_channels(self) -> bool:
|
||||||
"""Returns True if any active channel is an anchor channel."""
|
"""Returns True if any active channel is an anchor channel."""
|
||||||
return any(chan.has_anchors() and not chan.is_redeemed()
|
return any(chan.has_anchors() and not chan.is_redeemed()
|
||||||
for chan in self.channels.values())
|
for chan in self.channels.values())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def channels(self) -> Mapping[bytes, Channel]:
|
def channels(self) -> Mapping[bytes, Channel]:
|
||||||
@@ -989,7 +993,7 @@ class LNWallet(LNWorker):
|
|||||||
|
|
||||||
for coro in [
|
for coro in [
|
||||||
self.maybe_listen(),
|
self.maybe_listen(),
|
||||||
self.lnwatcher.trigger_callbacks(), # shortcut (don't block) if funding tx locked and verified
|
self.lnwatcher.trigger_callbacks(), # shortcut (don't block) if funding tx locked and verified
|
||||||
self.reestablish_peers_and_channels(),
|
self.reestablish_peers_and_channels(),
|
||||||
self.sync_with_remote_watchtower(),
|
self.sync_with_remote_watchtower(),
|
||||||
]:
|
]:
|
||||||
@@ -1044,7 +1048,8 @@ class LNWallet(LNWorker):
|
|||||||
|
|
||||||
def get_payment_value(
|
def get_payment_value(
|
||||||
self, info: Optional['PaymentInfo'],
|
self, info: Optional['PaymentInfo'],
|
||||||
plist: List[HTLCWithStatus]) -> Tuple[PaymentDirection, int, Optional[int], int]:
|
plist: List[HTLCWithStatus]
|
||||||
|
) -> Tuple[PaymentDirection, int, Optional[int], int]:
|
||||||
""" fee_msat is included in amount_msat"""
|
""" fee_msat is included in amount_msat"""
|
||||||
assert plist
|
assert plist
|
||||||
amount_msat = sum(int(x.direction) * x.htlc.amount_msat for x in plist)
|
amount_msat = sum(int(x.direction) * x.htlc.amount_msat for x in plist)
|
||||||
@@ -1085,13 +1090,13 @@ class LNWallet(LNWorker):
|
|||||||
preimage = self.get_preimage(payment_hash).hex()
|
preimage = self.get_preimage(payment_hash).hex()
|
||||||
group_id = self.swap_manager.get_group_id_for_payment_hash(payment_hash)
|
group_id = self.swap_manager.get_group_id_for_payment_hash(payment_hash)
|
||||||
item = LightningHistoryItem(
|
item = LightningHistoryItem(
|
||||||
type = 'payment',
|
type='payment',
|
||||||
payment_hash = payment_hash.hex(),
|
payment_hash=payment_hash.hex(),
|
||||||
preimage = preimage,
|
preimage=preimage,
|
||||||
amount_msat = amount_msat,
|
amount_msat=amount_msat,
|
||||||
fee_msat = fee_msat,
|
fee_msat=fee_msat,
|
||||||
group_id = group_id,
|
group_id=group_id,
|
||||||
timestamp = timestamp or 0,
|
timestamp=timestamp or 0,
|
||||||
label=label,
|
label=label,
|
||||||
direction=direction,
|
direction=direction,
|
||||||
)
|
)
|
||||||
@@ -1105,14 +1110,14 @@ class LNWallet(LNWorker):
|
|||||||
self.wallet.set_default_label(funding_txid, label)
|
self.wallet.set_default_label(funding_txid, label)
|
||||||
self.wallet.set_group_label(funding_txid, label)
|
self.wallet.set_group_label(funding_txid, label)
|
||||||
item = LightningHistoryItem(
|
item = LightningHistoryItem(
|
||||||
type = 'channel_opening',
|
type='channel_opening',
|
||||||
label = label,
|
label=label,
|
||||||
group_id = funding_txid,
|
group_id=funding_txid,
|
||||||
timestamp = funding_timestamp,
|
timestamp=funding_timestamp,
|
||||||
amount_msat = chan.balance(LOCAL, ctn=0),
|
amount_msat=chan.balance(LOCAL, ctn=0),
|
||||||
fee_msat = None,
|
fee_msat=None,
|
||||||
payment_hash = None,
|
payment_hash=None,
|
||||||
preimage = None,
|
preimage=None,
|
||||||
direction=None,
|
direction=None,
|
||||||
)
|
)
|
||||||
out[funding_txid] = item
|
out[funding_txid] = item
|
||||||
@@ -1124,14 +1129,14 @@ class LNWallet(LNWorker):
|
|||||||
self.wallet.set_default_label(closing_txid, label)
|
self.wallet.set_default_label(closing_txid, label)
|
||||||
self.wallet.set_group_label(closing_txid, label)
|
self.wallet.set_group_label(closing_txid, label)
|
||||||
item = LightningHistoryItem(
|
item = LightningHistoryItem(
|
||||||
type = 'channel_closing',
|
type='channel_closing',
|
||||||
label = label,
|
label=label,
|
||||||
group_id = closing_txid,
|
group_id=closing_txid,
|
||||||
timestamp = closing_timestamp,
|
timestamp=closing_timestamp,
|
||||||
amount_msat = -chan.balance(LOCAL),
|
amount_msat=-chan.balance(LOCAL),
|
||||||
fee_msat = None,
|
fee_msat=None,
|
||||||
payment_hash = None,
|
payment_hash=None,
|
||||||
preimage = None,
|
preimage=None,
|
||||||
direction=None,
|
direction=None,
|
||||||
)
|
)
|
||||||
out[closing_txid] = item
|
out[closing_txid] = item
|
||||||
@@ -1139,7 +1144,7 @@ class LNWallet(LNWorker):
|
|||||||
# sanity check
|
# sanity check
|
||||||
balance_msat = sum([x.amount_msat for x in out.values()])
|
balance_msat = sum([x.amount_msat for x in out.values()])
|
||||||
lb = sum(chan.balance(LOCAL) if not chan.is_closed_or_closing() else 0
|
lb = sum(chan.balance(LOCAL) if not chan.is_closed_or_closing() else 0
|
||||||
for chan in self.channels.values())
|
for chan in self.channels.values())
|
||||||
if balance_msat != lb:
|
if balance_msat != lb:
|
||||||
# this typically happens when a channel is recently force closed
|
# this typically happens when a channel is recently force closed
|
||||||
self.logger.info(f'get_lightning_history: balance mismatch {balance_msat - lb}')
|
self.logger.info(f'get_lightning_history: balance mismatch {balance_msat - lb}')
|
||||||
@@ -1447,14 +1452,16 @@ class LNWallet(LNWorker):
|
|||||||
return
|
return
|
||||||
fee_policy = FeePolicy(f'feerate:{FEERATE_FALLBACK_STATIC_FEE}')
|
fee_policy = FeePolicy(f'feerate:{FEERATE_FALLBACK_STATIC_FEE}')
|
||||||
try:
|
try:
|
||||||
self.mktx_for_open_channel(coins=coins, funding_sat=min_funding_sat, node_id=bytes(32), fee_policy=fee_policy)
|
self.mktx_for_open_channel(
|
||||||
|
coins=coins, funding_sat=min_funding_sat, node_id=bytes(32), fee_policy=fee_policy)
|
||||||
funding_sat = min_funding_sat
|
funding_sat = min_funding_sat
|
||||||
except NotEnoughFunds:
|
except NotEnoughFunds:
|
||||||
return
|
return
|
||||||
# if available, suggest twice that amount:
|
# if available, suggest twice that amount:
|
||||||
if 2 * min_funding_sat <= self.config.LIGHTNING_MAX_FUNDING_SAT:
|
if 2 * min_funding_sat <= self.config.LIGHTNING_MAX_FUNDING_SAT:
|
||||||
try:
|
try:
|
||||||
self.mktx_for_open_channel(coins=coins, funding_sat=2*min_funding_sat, node_id=bytes(32), fee_policy=fee_policy)
|
self.mktx_for_open_channel(
|
||||||
|
coins=coins, funding_sat=2*min_funding_sat, node_id=bytes(32), fee_policy=fee_policy)
|
||||||
funding_sat = 2 * min_funding_sat
|
funding_sat = 2 * min_funding_sat
|
||||||
except NotEnoughFunds:
|
except NotEnoughFunds:
|
||||||
pass
|
pass
|
||||||
@@ -1906,7 +1913,7 @@ class LNWallet(LNWorker):
|
|||||||
peer = self._peers.get(node_id)
|
peer = self._peers.get(node_id)
|
||||||
if not peer:
|
if not peer:
|
||||||
return False
|
return False
|
||||||
return (peer.their_features.supports(LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ECLAIR)\
|
return (peer.their_features.supports(LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ECLAIR)
|
||||||
or peer.their_features.supports(LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ELECTRUM))
|
or peer.their_features.supports(LnFeatures.OPTION_TRAMPOLINE_ROUTING_OPT_ELECTRUM))
|
||||||
|
|
||||||
def suggest_peer(self) -> Optional[bytes]:
|
def suggest_peer(self) -> Optional[bytes]:
|
||||||
@@ -2804,8 +2811,8 @@ class LNWallet(LNWorker):
|
|||||||
if (self.can_get_zeroconf_channel()
|
if (self.can_get_zeroconf_channel()
|
||||||
# we cannot receive the amount specified
|
# we cannot receive the amount specified
|
||||||
and ((amount_msat and self.num_sats_can_receive() < (amount_msat // 1000))
|
and ((amount_msat and self.num_sats_can_receive() < (amount_msat // 1000))
|
||||||
# or we cannot receive anything, and it's a 0 amount invoice
|
# or we cannot receive anything, and it's a 0 amount invoice
|
||||||
or (not amount_msat and self.num_sats_can_receive() < 1))):
|
or (not amount_msat and self.num_sats_can_receive() < 1))):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -2838,7 +2845,7 @@ class LNWallet(LNWorker):
|
|||||||
delta += delta // 100 + 1
|
delta += delta // 100 + 1
|
||||||
if func(deltas={chan:delta}) >= amount_sat:
|
if func(deltas={chan:delta}) >= amount_sat:
|
||||||
suggestions.append((chan, delta))
|
suggestions.append((chan, delta))
|
||||||
elif direction==RECEIVED and func(deltas={chan:2*delta}) >= amount_sat:
|
elif direction == RECEIVED and func(deltas={chan:2*delta}) >= amount_sat:
|
||||||
# MPP heuristics has a 0.5 slope
|
# MPP heuristics has a 0.5 slope
|
||||||
suggestions.append((chan, 2*delta))
|
suggestions.append((chan, 2*delta))
|
||||||
if not suggestions:
|
if not suggestions:
|
||||||
@@ -2867,10 +2874,10 @@ class LNWallet(LNWorker):
|
|||||||
continue
|
continue
|
||||||
if direction == SENT:
|
if direction == SENT:
|
||||||
if chan1.can_pay(delta*1000):
|
if chan1.can_pay(delta*1000):
|
||||||
return (chan1, chan2, delta)
|
return chan1, chan2, delta
|
||||||
else:
|
else:
|
||||||
if chan1.can_receive(delta*1000):
|
if chan1.can_receive(delta*1000):
|
||||||
return (chan2, chan1, delta)
|
return chan2, chan1, delta
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
@@ -3079,19 +3086,19 @@ class LNWallet(LNWorker):
|
|||||||
peer_addresses = list(chan.get_peer_addresses())
|
peer_addresses = list(chan.get_peer_addresses())
|
||||||
peer_addr = peer_addresses[0]
|
peer_addr = peer_addresses[0]
|
||||||
return ImportedChannelBackupStorage(
|
return ImportedChannelBackupStorage(
|
||||||
node_id = chan.node_id,
|
node_id=chan.node_id,
|
||||||
privkey = self.node_keypair.privkey,
|
privkey=self.node_keypair.privkey,
|
||||||
funding_txid = chan.funding_outpoint.txid,
|
funding_txid=chan.funding_outpoint.txid,
|
||||||
funding_index = chan.funding_outpoint.output_index,
|
funding_index=chan.funding_outpoint.output_index,
|
||||||
funding_address = chan.get_funding_address(),
|
funding_address=chan.get_funding_address(),
|
||||||
host = peer_addr.host,
|
host=peer_addr.host,
|
||||||
port = peer_addr.port,
|
port=peer_addr.port,
|
||||||
is_initiator = chan.constraints.is_initiator,
|
is_initiator=chan.constraints.is_initiator,
|
||||||
channel_seed = chan.config[LOCAL].channel_seed,
|
channel_seed=chan.config[LOCAL].channel_seed,
|
||||||
local_delay = chan.config[LOCAL].to_self_delay,
|
local_delay=chan.config[LOCAL].to_self_delay,
|
||||||
remote_delay = chan.config[REMOTE].to_self_delay,
|
remote_delay=chan.config[REMOTE].to_self_delay,
|
||||||
remote_revocation_pubkey = chan.config[REMOTE].revocation_basepoint.pubkey,
|
remote_revocation_pubkey=chan.config[REMOTE].revocation_basepoint.pubkey,
|
||||||
remote_payment_pubkey = chan.config[REMOTE].payment_basepoint.pubkey,
|
remote_payment_pubkey=chan.config[REMOTE].payment_basepoint.pubkey,
|
||||||
local_payment_pubkey=chan.config[LOCAL].payment_basepoint.pubkey,
|
local_payment_pubkey=chan.config[LOCAL].payment_basepoint.pubkey,
|
||||||
multisig_funding_privkey=chan.config[LOCAL].multisig_key.privkey,
|
multisig_funding_privkey=chan.config[LOCAL].multisig_key.privkey,
|
||||||
)
|
)
|
||||||
@@ -3234,11 +3241,11 @@ class LNWallet(LNWorker):
|
|||||||
return
|
return
|
||||||
funding_txid = tx.txid()
|
funding_txid = tx.txid()
|
||||||
cb_storage = OnchainChannelBackupStorage(
|
cb_storage = OnchainChannelBackupStorage(
|
||||||
node_id_prefix = node_id_prefix,
|
node_id_prefix=node_id_prefix,
|
||||||
funding_txid = funding_txid,
|
funding_txid=funding_txid,
|
||||||
funding_index = funding_index,
|
funding_index=funding_index,
|
||||||
funding_address = funding_address,
|
funding_address=funding_address,
|
||||||
is_initiator = True)
|
is_initiator=True)
|
||||||
channel_id = cb_storage.channel_id().hex()
|
channel_id = cb_storage.channel_id().hex()
|
||||||
if channel_id in self.db.get_dict("channels"):
|
if channel_id in self.db.get_dict("channels"):
|
||||||
return
|
return
|
||||||
@@ -3254,9 +3261,12 @@ class LNWallet(LNWorker):
|
|||||||
self.lnwatcher.add_channel(cb)
|
self.lnwatcher.add_channel(cb)
|
||||||
|
|
||||||
def save_forwarding_failure(
|
def save_forwarding_failure(
|
||||||
self, payment_key:str, *,
|
self,
|
||||||
|
payment_key: str,
|
||||||
|
*,
|
||||||
error_bytes: Optional[bytes] = None,
|
error_bytes: Optional[bytes] = None,
|
||||||
failure_message: Optional['OnionRoutingFailure'] = None):
|
failure_message: Optional['OnionRoutingFailure'] = None
|
||||||
|
) -> None:
|
||||||
error_hex = error_bytes.hex() if error_bytes else None
|
error_hex = error_bytes.hex() if error_bytes else None
|
||||||
failure_hex = failure_message.to_bytes().hex() if failure_message else None
|
failure_hex = failure_message.to_bytes().hex() if failure_message else None
|
||||||
self.forwarding_failures[payment_key] = (error_hex, failure_hex)
|
self.forwarding_failures[payment_key] = (error_hex, failure_hex)
|
||||||
|
|||||||
@@ -2288,9 +2288,10 @@ class OnchainHistoryItem(NamedTuple):
|
|||||||
'group_id': self.group_id,
|
'group_id': self.group_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class LightningHistoryItem(NamedTuple):
|
class LightningHistoryItem(NamedTuple):
|
||||||
payment_hash: str
|
payment_hash: Optional[str]
|
||||||
preimage: str
|
preimage: Optional[str]
|
||||||
amount_msat: int
|
amount_msat: int
|
||||||
fee_msat: Optional[int]
|
fee_msat: Optional[int]
|
||||||
type: str
|
type: str
|
||||||
|
|||||||
Reference in New Issue
Block a user