(trivial) rename lnchannel.channel_states to ChannelState
This commit is contained in:
@@ -11,7 +11,7 @@ from PyQt5.QtGui import QFont, QStandardItem, QBrush
|
||||
|
||||
from electrum.util import bh2u, NotEnoughFunds, NoDynamicFeeEstimates
|
||||
from electrum.i18n import _
|
||||
from electrum.lnchannel import Channel, peer_states
|
||||
from electrum.lnchannel import Channel, PeerState
|
||||
from electrum.wallet import Abstract_Wallet
|
||||
from electrum.lnutil import LOCAL, REMOTE, format_short_channel_id, LN_MAX_FUNDING_SAT
|
||||
from electrum.lnworker import LNWallet
|
||||
@@ -179,7 +179,7 @@ class ChannelsList(MyTreeView):
|
||||
menu.addAction(_("View funding transaction"), lambda: self.parent.show_transaction(funding_tx))
|
||||
if not chan.is_closed():
|
||||
menu.addSeparator()
|
||||
if chan.peer_state == peer_states.GOOD:
|
||||
if chan.peer_state == PeerState.GOOD:
|
||||
menu.addAction(_("Close channel"), lambda: self.close_channel(channel_id))
|
||||
menu.addAction(_("Force-close channel"), lambda: self.force_close(channel_id))
|
||||
else:
|
||||
|
||||
@@ -69,25 +69,27 @@ if TYPE_CHECKING:
|
||||
# lightning channel states
|
||||
# Note: these states are persisted by name (for a given channel) in the wallet file,
|
||||
# so consider doing a wallet db upgrade when changing them.
|
||||
class channel_states(IntEnum): # TODO rename to use CamelCase
|
||||
PREOPENING = 0 # Initial negotiation. Channel will not be reestablished
|
||||
OPENING = 1 # Channel will be reestablished. (per BOLT2)
|
||||
# - Funding node: has received funding_signed (can broadcast the funding tx)
|
||||
# - Non-funding node: has sent the funding_signed message.
|
||||
FUNDED = 2 # Funding tx was mined (requires min_depth and tx verification)
|
||||
OPEN = 3 # both parties have sent funding_locked
|
||||
CLOSING = 4 # shutdown has been sent, and closing tx is unconfirmed.
|
||||
FORCE_CLOSING = 5 # we force-closed, and closing tx is unconfirmed. (otherwise we remain OPEN)
|
||||
CLOSED = 6 # closing tx has been mined
|
||||
REDEEMED = 7 # we can stop watching
|
||||
class ChannelState(IntEnum):
|
||||
PREOPENING = 0 # Initial negotiation. Channel will not be reestablished
|
||||
OPENING = 1 # Channel will be reestablished. (per BOLT2)
|
||||
# - Funding node: has received funding_signed (can broadcast the funding tx)
|
||||
# - Non-funding node: has sent the funding_signed message.
|
||||
FUNDED = 2 # Funding tx was mined (requires min_depth and tx verification)
|
||||
OPEN = 3 # both parties have sent funding_locked
|
||||
CLOSING = 4 # shutdown has been sent, and closing tx is unconfirmed.
|
||||
FORCE_CLOSING = 5 # we force-closed, and closing tx is unconfirmed. (otherwise we remain OPEN)
|
||||
CLOSED = 6 # closing tx has been mined
|
||||
REDEEMED = 7 # we can stop watching
|
||||
|
||||
class peer_states(IntEnum): # TODO rename to use CamelCase
|
||||
|
||||
class PeerState(IntEnum):
|
||||
DISCONNECTED = 0
|
||||
REESTABLISHING = 1
|
||||
GOOD = 2
|
||||
BAD = 3
|
||||
|
||||
cs = channel_states
|
||||
|
||||
cs = ChannelState
|
||||
state_transitions = [
|
||||
(cs.PREOPENING, cs.OPENING),
|
||||
(cs.OPENING, cs.FUNDED),
|
||||
@@ -102,14 +104,14 @@ state_transitions = [
|
||||
(cs.OPENING, cs.CLOSED),
|
||||
(cs.FUNDED, cs.CLOSED),
|
||||
(cs.OPEN, cs.CLOSED),
|
||||
(cs.CLOSING, cs.CLOSING), # if we reestablish
|
||||
(cs.CLOSING, cs.CLOSING), # if we reestablish
|
||||
(cs.CLOSING, cs.CLOSED),
|
||||
(cs.FORCE_CLOSING, cs.FORCE_CLOSING), # allow multiple attempts
|
||||
(cs.FORCE_CLOSING, cs.FORCE_CLOSING), # allow multiple attempts
|
||||
(cs.FORCE_CLOSING, cs.CLOSED),
|
||||
(cs.FORCE_CLOSING, cs.REDEEMED),
|
||||
(cs.CLOSED, cs.REDEEMED),
|
||||
(cs.OPENING, cs.REDEEMED), # channel never funded (dropped from mempool)
|
||||
(cs.PREOPENING, cs.REDEEMED), # channel never funded
|
||||
(cs.OPENING, cs.REDEEMED), # channel never funded (dropped from mempool)
|
||||
(cs.PREOPENING, cs.REDEEMED), # channel never funded
|
||||
]
|
||||
del cs # delete as name is ambiguous without context
|
||||
|
||||
@@ -135,7 +137,7 @@ class AbstractChannel(Logger, ABC):
|
||||
channel_id: bytes
|
||||
funding_outpoint: Outpoint
|
||||
node_id: bytes
|
||||
_state: channel_states
|
||||
_state: ChannelState
|
||||
|
||||
def set_short_channel_id(self, short_id: ShortChannelID) -> None:
|
||||
self.short_channel_id = short_id
|
||||
@@ -150,7 +152,7 @@ class AbstractChannel(Logger, ABC):
|
||||
def short_id_for_GUI(self) -> str:
|
||||
return format_short_channel_id(self.short_channel_id)
|
||||
|
||||
def set_state(self, state: channel_states) -> None:
|
||||
def set_state(self, state: ChannelState) -> None:
|
||||
""" set on-chain state """
|
||||
old_state = self._state
|
||||
if (old_state, state) not in state_transitions:
|
||||
@@ -161,24 +163,24 @@ class AbstractChannel(Logger, ABC):
|
||||
if self.lnworker:
|
||||
self.lnworker.channel_state_changed(self)
|
||||
|
||||
def get_state(self) -> channel_states:
|
||||
def get_state(self) -> ChannelState:
|
||||
return self._state
|
||||
|
||||
def is_funded(self):
|
||||
return self.get_state() >= channel_states.FUNDED
|
||||
return self.get_state() >= ChannelState.FUNDED
|
||||
|
||||
def is_open(self):
|
||||
return self.get_state() == channel_states.OPEN
|
||||
return self.get_state() == ChannelState.OPEN
|
||||
|
||||
def is_closing(self):
|
||||
return self.get_state() in [channel_states.CLOSING, channel_states.FORCE_CLOSING]
|
||||
return self.get_state() in [ChannelState.CLOSING, ChannelState.FORCE_CLOSING]
|
||||
|
||||
def is_closed(self):
|
||||
# the closing txid has been saved
|
||||
return self.get_state() >= channel_states.CLOSED
|
||||
return self.get_state() >= ChannelState.CLOSED
|
||||
|
||||
def is_redeemed(self):
|
||||
return self.get_state() == channel_states.REDEEMED
|
||||
return self.get_state() == ChannelState.REDEEMED
|
||||
|
||||
def save_funding_height(self, *, txid: str, height: int, timestamp: Optional[int]) -> None:
|
||||
self.storage['funding_height'] = txid, height, timestamp
|
||||
@@ -241,7 +243,7 @@ class AbstractChannel(Logger, ABC):
|
||||
def update_unfunded_state(self):
|
||||
self.delete_funding_height()
|
||||
self.delete_closing_height()
|
||||
if self.get_state() in [channel_states.PREOPENING, channel_states.OPENING, channel_states.FORCE_CLOSING] and self.lnworker:
|
||||
if self.get_state() in [ChannelState.PREOPENING, ChannelState.OPENING, ChannelState.FORCE_CLOSING] and self.lnworker:
|
||||
if self.is_initiator():
|
||||
# set channel state to REDEEMED so that it can be removed manually
|
||||
# to protect ourselves against a server lying by omission,
|
||||
@@ -249,7 +251,7 @@ class AbstractChannel(Logger, ABC):
|
||||
inputs = self.storage.get('funding_inputs', [])
|
||||
if not inputs:
|
||||
self.logger.info(f'channel funding inputs are not provided')
|
||||
self.set_state(channel_states.REDEEMED)
|
||||
self.set_state(ChannelState.REDEEMED)
|
||||
for i in inputs:
|
||||
spender_txid = self.lnworker.wallet.db.get_spent_outpoint(*i)
|
||||
if spender_txid is None:
|
||||
@@ -258,7 +260,7 @@ class AbstractChannel(Logger, ABC):
|
||||
tx_mined_height = self.lnworker.wallet.get_tx_height(spender_txid)
|
||||
if tx_mined_height.conf > lnutil.REDEEM_AFTER_DOUBLE_SPENT_DELAY:
|
||||
self.logger.info(f'channel is double spent {inputs}')
|
||||
self.set_state(channel_states.REDEEMED)
|
||||
self.set_state(ChannelState.REDEEMED)
|
||||
break
|
||||
else:
|
||||
now = int(time.time())
|
||||
@@ -271,24 +273,24 @@ class AbstractChannel(Logger, ABC):
|
||||
if funding_height.conf>0:
|
||||
self.set_short_channel_id(ShortChannelID.from_components(
|
||||
funding_height.height, funding_height.txpos, self.funding_outpoint.output_index))
|
||||
if self.get_state() == channel_states.OPENING:
|
||||
if self.get_state() == ChannelState.OPENING:
|
||||
if self.is_funding_tx_mined(funding_height):
|
||||
self.set_state(channel_states.FUNDED)
|
||||
self.set_state(ChannelState.FUNDED)
|
||||
|
||||
def update_closed_state(self, *, funding_txid: str, funding_height: TxMinedInfo,
|
||||
closing_txid: str, closing_height: TxMinedInfo, keep_watching: bool) -> None:
|
||||
self.save_funding_height(txid=funding_txid, height=funding_height.height, timestamp=funding_height.timestamp)
|
||||
self.save_closing_height(txid=closing_txid, height=closing_height.height, timestamp=closing_height.timestamp)
|
||||
if self.get_state() < channel_states.CLOSED:
|
||||
if self.get_state() < ChannelState.CLOSED:
|
||||
conf = closing_height.conf
|
||||
if conf > 0:
|
||||
self.set_state(channel_states.CLOSED)
|
||||
self.set_state(ChannelState.CLOSED)
|
||||
else:
|
||||
# we must not trust the server with unconfirmed transactions
|
||||
# if the remote force closed, we remain OPEN until the closing tx is confirmed
|
||||
pass
|
||||
if self.get_state() == channel_states.CLOSED and not keep_watching:
|
||||
self.set_state(channel_states.REDEEMED)
|
||||
if self.get_state() == ChannelState.CLOSED and not keep_watching:
|
||||
self.set_state(ChannelState.REDEEMED)
|
||||
|
||||
@abstractmethod
|
||||
def is_initiator(self) -> bool:
|
||||
@@ -368,7 +370,7 @@ class ChannelBackup(AbstractChannel):
|
||||
self._sweep_info = {}
|
||||
self.sweep_address = sweep_address
|
||||
self.storage = {} # dummy storage
|
||||
self._state = channel_states.OPENING
|
||||
self._state = ChannelState.OPENING
|
||||
self.config = {}
|
||||
self.config[LOCAL] = LocalConfig.from_seed(
|
||||
channel_seed=cb.channel_seed,
|
||||
@@ -473,8 +475,8 @@ class Channel(AbstractChannel):
|
||||
self.onion_keys = state['onion_keys'] # type: Dict[int, bytes]
|
||||
self.data_loss_protect_remote_pcp = state['data_loss_protect_remote_pcp']
|
||||
self.hm = HTLCManager(log=state['log'], initial_feerate=initial_feerate)
|
||||
self._state = channel_states[state['state']]
|
||||
self.peer_state = peer_states.DISCONNECTED
|
||||
self._state = ChannelState[state['state']]
|
||||
self.peer_state = PeerState.DISCONNECTED
|
||||
self._sweep_info = {}
|
||||
self._outgoing_channel_update = None # type: Optional[bytes]
|
||||
self._chan_ann_without_sigs = None # type: Optional[bytes]
|
||||
@@ -644,7 +646,7 @@ class Channel(AbstractChannel):
|
||||
self.config[REMOTE].next_per_commitment_point = None
|
||||
self.config[LOCAL].current_commitment_signature = remote_sig
|
||||
self.hm.channel_open_finished()
|
||||
self.peer_state = peer_states.GOOD
|
||||
self.peer_state = PeerState.GOOD
|
||||
|
||||
def get_state_for_GUI(self):
|
||||
# status displayed in the GUI
|
||||
@@ -652,7 +654,7 @@ class Channel(AbstractChannel):
|
||||
if self.is_closed():
|
||||
return cs.name
|
||||
ps = self.peer_state
|
||||
if ps != peer_states.GOOD:
|
||||
if ps != PeerState.GOOD:
|
||||
return ps.name
|
||||
return cs.name
|
||||
|
||||
@@ -663,7 +665,7 @@ class Channel(AbstractChannel):
|
||||
"""Whether we can send update_fee, update_*_htlc changes to the remote."""
|
||||
if not (self.is_open() or self.is_closing()):
|
||||
return False
|
||||
if self.peer_state != peer_states.GOOD:
|
||||
if self.peer_state != PeerState.GOOD:
|
||||
return False
|
||||
if not self._can_send_ctx_updates:
|
||||
return False
|
||||
@@ -699,7 +701,7 @@ class Channel(AbstractChannel):
|
||||
chan_config = self.config[htlc_receiver]
|
||||
if self.is_closed():
|
||||
raise PaymentFailure('Channel closed')
|
||||
if self.get_state() != channel_states.OPEN:
|
||||
if self.get_state() != ChannelState.OPEN:
|
||||
raise PaymentFailure('Channel not open', self.get_state())
|
||||
if htlc_proposer == LOCAL:
|
||||
if not self.can_send_ctx_updates():
|
||||
@@ -763,7 +765,7 @@ class Channel(AbstractChannel):
|
||||
return True
|
||||
|
||||
def should_try_to_reestablish_peer(self) -> bool:
|
||||
return channel_states.PREOPENING < self._state < channel_states.FORCE_CLOSING and self.peer_state == peer_states.DISCONNECTED
|
||||
return ChannelState.PREOPENING < self._state < ChannelState.FORCE_CLOSING and self.peer_state == PeerState.DISCONNECTED
|
||||
|
||||
def get_funding_address(self):
|
||||
script = funding_output_script(self.config[LOCAL], self.config[REMOTE])
|
||||
|
||||
@@ -31,7 +31,7 @@ from .lnonion import (new_onion_packet, decode_onion_error, OnionFailureCode, ca
|
||||
process_onion_packet, OnionPacket, construct_onion_error, OnionRoutingFailureMessage,
|
||||
ProcessedOnionPacket, UnsupportedOnionPacketVersion, InvalidOnionMac, InvalidOnionPubkey,
|
||||
OnionFailureCodeMetaFlag)
|
||||
from .lnchannel import Channel, RevokeAndAck, htlcsum, RemoteCtnTooFarInFuture, channel_states, peer_states
|
||||
from .lnchannel import Channel, RevokeAndAck, htlcsum, RemoteCtnTooFarInFuture, ChannelState, PeerState
|
||||
from . import lnutil
|
||||
from .lnutil import (Outpoint, LocalConfig, RECEIVED, UpdateAddHtlc,
|
||||
RemoteConfig, OnlyPubkeyKeypair, ChannelConstraints, RevocationStore,
|
||||
@@ -619,7 +619,7 @@ class Peer(Logger):
|
||||
remote_sig = payload['signature']
|
||||
chan.receive_new_commitment(remote_sig, [])
|
||||
chan.open_with_first_pcp(remote_per_commitment_point, remote_sig)
|
||||
chan.set_state(channel_states.OPENING)
|
||||
chan.set_state(ChannelState.OPENING)
|
||||
self.lnworker.add_new_channel(chan)
|
||||
return chan, funding_tx
|
||||
|
||||
@@ -633,7 +633,7 @@ class Peer(Logger):
|
||||
"local_config": local_config,
|
||||
"constraints": constraints,
|
||||
"remote_update": None,
|
||||
"state": channel_states.PREOPENING.name,
|
||||
"state": ChannelState.PREOPENING.name,
|
||||
'onion_keys': {},
|
||||
'data_loss_protect_remote_pcp': {},
|
||||
"log": {},
|
||||
@@ -714,7 +714,7 @@ class Peer(Logger):
|
||||
)
|
||||
self.funding_signed_sent.add(chan.channel_id)
|
||||
chan.open_with_first_pcp(payload['first_per_commitment_point'], remote_sig)
|
||||
chan.set_state(channel_states.OPENING)
|
||||
chan.set_state(ChannelState.OPENING)
|
||||
self.lnworker.add_new_channel(chan)
|
||||
|
||||
def validate_remote_reserve(self, remote_reserve_sat: int, dust_limit: int, funding_sat: int) -> int:
|
||||
@@ -738,12 +738,12 @@ class Peer(Logger):
|
||||
async def reestablish_channel(self, chan: Channel):
|
||||
await self.initialized
|
||||
chan_id = chan.channel_id
|
||||
assert channel_states.PREOPENING < chan.get_state() < channel_states.FORCE_CLOSING
|
||||
if chan.peer_state != peer_states.DISCONNECTED:
|
||||
assert ChannelState.PREOPENING < chan.get_state() < ChannelState.FORCE_CLOSING
|
||||
if chan.peer_state != PeerState.DISCONNECTED:
|
||||
self.logger.info(f'reestablish_channel was called but channel {chan.get_id_for_log()} '
|
||||
f'already in peer_state {chan.peer_state}')
|
||||
return
|
||||
chan.peer_state = peer_states.REESTABLISHING
|
||||
chan.peer_state = PeerState.REESTABLISHING
|
||||
self.network.trigger_callback('channel', chan)
|
||||
# BOLT-02: "A node [...] upon disconnection [...] MUST reverse any uncommitted updates sent by the other side"
|
||||
chan.hm.discard_unsigned_remote_updates()
|
||||
@@ -878,21 +878,21 @@ class Peer(Logger):
|
||||
# data_loss_protect_remote_pcp is used in lnsweep
|
||||
chan.set_data_loss_protect_remote_pcp(their_next_local_ctn - 1, their_local_pcp)
|
||||
self.lnworker.save_channel(chan)
|
||||
chan.peer_state = peer_states.BAD
|
||||
chan.peer_state = PeerState.BAD
|
||||
return
|
||||
elif we_are_ahead:
|
||||
self.logger.warning(f"channel_reestablish ({chan.get_id_for_log()}): we are ahead of remote! trying to force-close.")
|
||||
await self.lnworker.try_force_closing(chan_id)
|
||||
return
|
||||
|
||||
chan.peer_state = peer_states.GOOD
|
||||
chan.peer_state = PeerState.GOOD
|
||||
if chan.is_funded() and their_next_local_ctn == next_local_ctn == 1:
|
||||
self.send_funding_locked(chan)
|
||||
# checks done
|
||||
if chan.is_funded() and chan.config[LOCAL].funding_locked_received:
|
||||
self.mark_open(chan)
|
||||
self.network.trigger_callback('channel', chan)
|
||||
if chan.get_state() == channel_states.CLOSING:
|
||||
if chan.get_state() == ChannelState.CLOSING:
|
||||
await self.send_shutdown(chan)
|
||||
|
||||
def send_funding_locked(self, chan: Channel):
|
||||
@@ -972,13 +972,13 @@ class Peer(Logger):
|
||||
assert chan.is_funded()
|
||||
# only allow state transition from "FUNDED" to "OPEN"
|
||||
old_state = chan.get_state()
|
||||
if old_state == channel_states.OPEN:
|
||||
if old_state == ChannelState.OPEN:
|
||||
return
|
||||
if old_state != channel_states.FUNDED:
|
||||
if old_state != ChannelState.FUNDED:
|
||||
self.logger.info(f"cannot mark open ({chan.get_id_for_log()}), current state: {repr(old_state)}")
|
||||
return
|
||||
assert chan.config[LOCAL].funding_locked_received
|
||||
chan.set_state(channel_states.OPEN)
|
||||
chan.set_state(ChannelState.OPEN)
|
||||
self.network.trigger_callback('channel', chan)
|
||||
# peer may have sent us a channel update for the incoming direction previously
|
||||
pending_channel_update = self.orphan_channel_updates.get(chan.short_channel_id)
|
||||
@@ -1071,7 +1071,7 @@ class Peer(Logger):
|
||||
self.maybe_send_commitment(chan)
|
||||
|
||||
def on_commitment_signed(self, chan: Channel, payload):
|
||||
if chan.peer_state == peer_states.BAD:
|
||||
if chan.peer_state == PeerState.BAD:
|
||||
return
|
||||
self.logger.info(f'on_commitment_signed. chan {chan.short_channel_id}. ctn: {chan.get_next_ctn(LOCAL)}.')
|
||||
# make sure there were changes to the ctx, otherwise the remote peer is misbehaving
|
||||
@@ -1116,7 +1116,7 @@ class Peer(Logger):
|
||||
cltv_expiry = payload["cltv_expiry"]
|
||||
amount_msat_htlc = payload["amount_msat"]
|
||||
onion_packet = payload["onion_routing_packet"]
|
||||
if chan.get_state() != channel_states.OPEN:
|
||||
if chan.get_state() != ChannelState.OPEN:
|
||||
raise RemoteMisbehaving(f"received update_add_htlc while chan.get_state() != OPEN. state was {chan.get_state()}")
|
||||
if cltv_expiry > bitcoin.NLOCKTIME_BLOCKHEIGHT_MAX:
|
||||
asyncio.ensure_future(self.lnworker.try_force_closing(chan.channel_id))
|
||||
@@ -1285,7 +1285,7 @@ class Peer(Logger):
|
||||
failure_code=reason.code)
|
||||
|
||||
def on_revoke_and_ack(self, chan: Channel, payload):
|
||||
if chan.peer_state == peer_states.BAD:
|
||||
if chan.peer_state == PeerState.BAD:
|
||||
return
|
||||
self.logger.info(f'on_revoke_and_ack. chan {chan.short_channel_id}. ctn: {chan.get_oldest_unrevoked_ctn(REMOTE)}')
|
||||
rev = RevokeAndAck(payload["per_commitment_secret"], payload["next_per_commitment_point"])
|
||||
@@ -1360,7 +1360,7 @@ class Peer(Logger):
|
||||
self.logger.info(f'({chan.get_id_for_log()}) Channel closed by remote peer {txid}')
|
||||
|
||||
def can_send_shutdown(self, chan):
|
||||
if chan.get_state() >= channel_states.OPENING:
|
||||
if chan.get_state() >= ChannelState.OPENING:
|
||||
return True
|
||||
if chan.constraints.is_initiator and chan.channel_id in self.funding_created_sent:
|
||||
return True
|
||||
@@ -1377,7 +1377,7 @@ class Peer(Logger):
|
||||
while chan.has_pending_changes(REMOTE):
|
||||
await asyncio.sleep(0.1)
|
||||
self.send_message('shutdown', channel_id=chan.channel_id, len=len(scriptpubkey), scriptpubkey=scriptpubkey)
|
||||
chan.set_state(channel_states.CLOSING)
|
||||
chan.set_state(ChannelState.CLOSING)
|
||||
# can fullfill or fail htlcs. cannot add htlcs, because of CLOSING state
|
||||
chan.set_can_send_ctx_updates(True)
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ from .lnpeer import Peer, LN_P2P_NETWORK_TIMEOUT
|
||||
from .lnaddr import lnencode, LnAddr, lndecode
|
||||
from .ecc import der_sig_from_sig_string
|
||||
from .lnchannel import Channel
|
||||
from .lnchannel import channel_states, peer_states
|
||||
from .lnchannel import ChannelState, PeerState
|
||||
from . import lnutil
|
||||
from .lnutil import funding_output_script
|
||||
from .bitcoin import redeem_script_to_address
|
||||
@@ -514,7 +514,7 @@ class LNWallet(LNWorker):
|
||||
|
||||
def peer_closed(self, peer):
|
||||
for chan in self.channels_for_peer(peer.pubkey).values():
|
||||
chan.peer_state = peer_states.DISCONNECTED
|
||||
chan.peer_state = PeerState.DISCONNECTED
|
||||
self.network.trigger_callback('channel', chan)
|
||||
super().peer_closed(peer)
|
||||
|
||||
@@ -664,23 +664,23 @@ class LNWallet(LNWorker):
|
||||
|
||||
async def on_channel_update(self, chan):
|
||||
|
||||
if chan.get_state() == channel_states.OPEN and chan.should_be_closed_due_to_expiring_htlcs(self.network.get_local_height()):
|
||||
if chan.get_state() == ChannelState.OPEN and chan.should_be_closed_due_to_expiring_htlcs(self.network.get_local_height()):
|
||||
self.logger.info(f"force-closing due to expiring htlcs")
|
||||
await self.try_force_closing(chan.channel_id)
|
||||
|
||||
elif chan.get_state() == channel_states.FUNDED:
|
||||
elif chan.get_state() == ChannelState.FUNDED:
|
||||
peer = self.peers.get(chan.node_id)
|
||||
if peer and peer.is_initialized():
|
||||
peer.send_funding_locked(chan)
|
||||
|
||||
elif chan.get_state() == channel_states.OPEN:
|
||||
elif chan.get_state() == ChannelState.OPEN:
|
||||
peer = self.peers.get(chan.node_id)
|
||||
if peer:
|
||||
await peer.maybe_update_fee(chan)
|
||||
conf = self.lnwatcher.get_tx_height(chan.funding_outpoint.txid).conf
|
||||
peer.on_network_update(chan, conf)
|
||||
|
||||
elif chan.get_state() == channel_states.FORCE_CLOSING:
|
||||
elif chan.get_state() == ChannelState.FORCE_CLOSING:
|
||||
force_close_tx = chan.force_close_tx()
|
||||
txid = force_close_tx.txid()
|
||||
height = self.lnwatcher.get_tx_height(txid).height
|
||||
@@ -1235,19 +1235,19 @@ class LNWallet(LNWorker):
|
||||
chan = self.channels[chan_id]
|
||||
tx = chan.force_close_tx()
|
||||
await self.network.broadcast_transaction(tx)
|
||||
chan.set_state(channel_states.FORCE_CLOSING)
|
||||
chan.set_state(ChannelState.FORCE_CLOSING)
|
||||
return tx.txid()
|
||||
|
||||
async def try_force_closing(self, chan_id):
|
||||
# fails silently but sets the state, so that we will retry later
|
||||
chan = self.channels[chan_id]
|
||||
tx = chan.force_close_tx()
|
||||
chan.set_state(channel_states.FORCE_CLOSING)
|
||||
chan.set_state(ChannelState.FORCE_CLOSING)
|
||||
await self.network.try_broadcasting(tx, 'force-close')
|
||||
|
||||
def remove_channel(self, chan_id):
|
||||
chan = self.channels[chan_id]
|
||||
assert chan.get_state() == channel_states.REDEEMED
|
||||
assert chan.get_state() == ChannelState.REDEEMED
|
||||
with self.lock:
|
||||
self.channels.pop(chan_id)
|
||||
self.db.get('channels').pop(chan_id.hex())
|
||||
|
||||
@@ -37,7 +37,7 @@ from electrum.lnutil import SENT, LOCAL, REMOTE, RECEIVED
|
||||
from electrum.lnutil import FeeUpdate
|
||||
from electrum.ecc import sig_string_from_der_sig
|
||||
from electrum.logging import console_stderr_handler
|
||||
from electrum.lnchannel import channel_states
|
||||
from electrum.lnchannel import ChannelState
|
||||
from electrum.json_db import StoredDict
|
||||
|
||||
from . import ElectrumTestCase
|
||||
@@ -143,8 +143,8 @@ def create_test_channels(*, feerate=6000, local_msat=None, remote_msat=None):
|
||||
alice.hm.log[LOCAL]['ctn'] = 0
|
||||
bob.hm.log[LOCAL]['ctn'] = 0
|
||||
|
||||
alice._state = channel_states.OPEN
|
||||
bob._state = channel_states.OPEN
|
||||
alice._state = ChannelState.OPEN
|
||||
bob._state = ChannelState.OPEN
|
||||
|
||||
a_out = alice.get_latest_commitment(LOCAL).outputs()
|
||||
b_out = bob.get_next_commitment(REMOTE).outputs()
|
||||
|
||||
@@ -22,7 +22,7 @@ from electrum.lnpeer import Peer
|
||||
from electrum.lnutil import LNPeerAddr, Keypair, privkey_to_pubkey
|
||||
from electrum.lnutil import LightningPeerConnectionClosed, RemoteMisbehaving
|
||||
from electrum.lnutil import PaymentFailure, LnFeatures, HTLCOwner
|
||||
from electrum.lnchannel import channel_states, peer_states, Channel
|
||||
from electrum.lnchannel import ChannelState, PeerState, Channel
|
||||
from electrum.lnrouter import LNPathFinder
|
||||
from electrum.channel_db import ChannelDB
|
||||
from electrum.lnworker import LNWallet, NoPathFound
|
||||
@@ -219,8 +219,8 @@ class TestPeer(ElectrumTestCase):
|
||||
w2.peer = p2
|
||||
# mark_open won't work if state is already OPEN.
|
||||
# so set it to FUNDED
|
||||
alice_channel._state = channel_states.FUNDED
|
||||
bob_channel._state = channel_states.FUNDED
|
||||
alice_channel._state = ChannelState.FUNDED
|
||||
bob_channel._state = ChannelState.FUNDED
|
||||
# this populates the channel graph:
|
||||
p1.mark_open(alice_channel)
|
||||
p2.mark_open(bob_channel)
|
||||
@@ -250,13 +250,13 @@ class TestPeer(ElectrumTestCase):
|
||||
alice_channel, bob_channel = create_test_channels()
|
||||
p1, p2, w1, w2, _q1, _q2 = self.prepare_peers(alice_channel, bob_channel)
|
||||
for chan in (alice_channel, bob_channel):
|
||||
chan.peer_state = peer_states.DISCONNECTED
|
||||
chan.peer_state = PeerState.DISCONNECTED
|
||||
async def reestablish():
|
||||
await asyncio.gather(
|
||||
p1.reestablish_channel(alice_channel),
|
||||
p2.reestablish_channel(bob_channel))
|
||||
self.assertEqual(alice_channel.peer_state, peer_states.GOOD)
|
||||
self.assertEqual(bob_channel.peer_state, peer_states.GOOD)
|
||||
self.assertEqual(alice_channel.peer_state, PeerState.GOOD)
|
||||
self.assertEqual(bob_channel.peer_state, PeerState.GOOD)
|
||||
gath.cancel()
|
||||
gath = asyncio.gather(reestablish(), p1._message_loop(), p2._message_loop(), p1.htlc_switch(), p1.htlc_switch())
|
||||
async def f():
|
||||
@@ -282,13 +282,13 @@ class TestPeer(ElectrumTestCase):
|
||||
|
||||
p1, p2, w1, w2, _q1, _q2 = self.prepare_peers(alice_channel_0, bob_channel)
|
||||
for chan in (alice_channel_0, bob_channel):
|
||||
chan.peer_state = peer_states.DISCONNECTED
|
||||
chan.peer_state = PeerState.DISCONNECTED
|
||||
async def reestablish():
|
||||
await asyncio.gather(
|
||||
p1.reestablish_channel(alice_channel_0),
|
||||
p2.reestablish_channel(bob_channel))
|
||||
self.assertEqual(alice_channel_0.peer_state, peer_states.BAD)
|
||||
self.assertEqual(bob_channel._state, channel_states.FORCE_CLOSING)
|
||||
self.assertEqual(alice_channel_0.peer_state, PeerState.BAD)
|
||||
self.assertEqual(bob_channel._state, ChannelState.FORCE_CLOSING)
|
||||
# wait so that pending messages are processed
|
||||
#await asyncio.sleep(1)
|
||||
gath.cancel()
|
||||
|
||||
Reference in New Issue
Block a user