Skip to content

Commit 16dfb81

Browse files
committed
validate zeroconf channel once mined
1 parent 7030f3d commit 16dfb81

File tree

2 files changed

+35
-30
lines changed

2 files changed

+35
-30
lines changed

electrum/lnchannel.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ class AbstractChannel(Logger, ABC):
191191
short_channel_id: Optional[ShortChannelID] = None
192192
funding_outpoint: Outpoint
193193
node_id: bytes # note that it might not be the full 33 bytes; for OCB it is only the prefix
194+
should_request_force_close: bool = False
194195
_state: ChannelState
195196

196197
def set_short_channel_id(self, short_id: ShortChannelID) -> None:
@@ -398,13 +399,20 @@ def update_funded_state(self, *, funding_txid: str, funding_height: TxMinedInfo)
398399
if funding_height.conf>0:
399400
self.set_short_channel_id(ShortChannelID.from_components(
400401
funding_height.height, funding_height.txpos, self.funding_outpoint.output_index))
401-
if self.is_zeroconf():
402-
# remove zeroconf flag as we are now confirmed, this is to prevent an electrum server causing
403-
# us to remove a channel later in update_unfunded_state by omitting its funding tx
404-
self.remove_zeroconf_flag()
405402
if self.get_state() == ChannelState.OPENING:
406403
if self.is_funding_tx_mined(funding_height):
407404
self.set_state(ChannelState.FUNDED)
405+
elif self.is_zeroconf() and funding_height.conf >= 3 and not self.should_request_force_close:
406+
if not self.is_funding_tx_mined(funding_height):
407+
# funding tx is invalid (invalid amount or address) we need to get rid of the channel again
408+
self.should_request_force_close = True
409+
if self.lnworker and self.node_id in self.lnworker.peers:
410+
# reconnect to trigger force close request
411+
self.lnworker.peers[self.node_id].close_and_cleanup()
412+
else:
413+
# remove zeroconf flag as we are now confirmed, this is to prevent an electrum server causing
414+
# us to remove a channel later in update_unfunded_state by omitting its funding tx
415+
self.remove_zeroconf_flag()
408416

409417
def update_closed_state(self, *, funding_txid: str, funding_height: TxMinedInfo,
410418
closing_txid: str, closing_height: TxMinedInfo, keep_watching: bool) -> None:
@@ -775,7 +783,6 @@ def __init__(self, state: 'StoredDict', *, name=None, lnworker=None, initial_fee
775783
self.revocation_store = RevocationStore(state["revocation_store"])
776784
self._can_send_ctx_updates = True # type: bool
777785
self._receive_fail_reasons = {} # type: Dict[int, (bytes, OnionRoutingFailure)]
778-
self.should_request_force_close = False
779786
self.unconfirmed_closing_txid = None # not a state, only for GUI
780787
self.sent_channel_ready = False # no need to persist this, because channel_ready is re-sent in channel_reestablish
781788
self.sent_announcement_signatures = False

tests/regtest.py

+23-25
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
import subprocess
55
from typing import Mapping, Any
66

7-
from electrum.simple_config import SimpleConfig
8-
97

108
class TestLightning(unittest.TestCase):
119
agents: Mapping[str, Mapping[str, Any]]
@@ -51,7 +49,7 @@ class TestLightningAB(TestLightning):
5149
'alice': {
5250
},
5351
'bob': {
54-
SimpleConfig.LIGHTNING_LISTEN.key(): 'localhost:9735',
52+
'lightning_listen': 'localhost:9735',
5553
}
5654
}
5755

@@ -83,15 +81,15 @@ def test_breach_with_spent_htlc(self):
8381
class TestLightningSwapserver(TestLightning):
8482
agents = {
8583
'alice': {
86-
SimpleConfig.LIGHTNING_USE_GOSSIP.key(): 'false',
87-
SimpleConfig.SWAPSERVER_URL.key(): 'http://localhost:5455',
88-
SimpleConfig.NOSTR_RELAYS.key(): "''",
84+
'use_gossip': 'false',
85+
'swapserver_url': 'http://localhost:5455',
86+
'nostr_relays': "''",
8987
},
9088
'bob': {
91-
SimpleConfig.LIGHTNING_LISTEN.key(): 'localhost:9735',
89+
'lightning_listen': 'localhost:9735',
9290
'enable_plugin_swapserver': 'true',
93-
SimpleConfig.SWAPSERVER_PORT.key(): '5455',
94-
SimpleConfig.NOSTR_RELAYS.key(): "''",
91+
'swapserver_port': '5455',
92+
'nostr_relays': "''",
9593
}
9694
}
9795

@@ -111,14 +109,14 @@ class TestLightningWatchtower(TestLightning):
111109
'alice': {
112110
},
113111
'bob': {
114-
SimpleConfig.LIGHTNING_LISTEN.key(): 'localhost:9735',
115-
SimpleConfig.WATCHTOWER_CLIENT_URL.key(): 'http://wtuser:[email protected]:12345',
112+
'lightning_listen': 'localhost:9735',
113+
'watchtower_url': 'http://wtuser:[email protected]:12345',
116114
},
117115
'carol': {
118116
'enable_plugin_watchtower': 'true',
119-
SimpleConfig.WATCHTOWER_SERVER_USER.key(): 'wtuser',
120-
SimpleConfig.WATCHTOWER_SERVER_PASSWORD.key(): 'wtpassword',
121-
SimpleConfig.WATCHTOWER_SERVER_PORT.key(): '12345',
117+
'watchtower_user': 'wtuser',
118+
'watchtower_password': 'wtpassword',
119+
'watchtower_port': '12345',
122120
}
123121
}
124122

@@ -129,12 +127,12 @@ def test_watchtower(self):
129127
class TestLightningJIT(TestLightning):
130128
agents = {
131129
'alice': {
132-
SimpleConfig.ACCEPT_ZEROCONF_CHANNELS.key(): 'true',
130+
'accept_zeroconf_channels': 'true',
133131
},
134132
'bob': {
135-
SimpleConfig.LIGHTNING_LISTEN.key(): 'localhost:9735',
136-
SimpleConfig.EXPERIMENTAL_LN_FORWARD_PAYMENTS.key(): 'true',
137-
SimpleConfig.ACCEPT_ZEROCONF_CHANNELS.key(): 'true',
133+
'lightning_listen': 'localhost:9735',
134+
'lightning_forward_payments': 'true',
135+
'accept_zeroconf_channels': 'true',
138136
},
139137
'carol': {
140138
}
@@ -147,16 +145,16 @@ def test_just_in_time(self):
147145
class TestLightningJITTrampoline(TestLightningJIT):
148146
agents = {
149147
'alice': {
150-
SimpleConfig.LIGHTNING_USE_GOSSIP.key(): 'false',
151-
SimpleConfig.ACCEPT_ZEROCONF_CHANNELS.key(): 'true',
148+
'use_gossip': 'false',
149+
'accept_zeroconf_channels': 'true',
152150
},
153151
'bob': {
154-
SimpleConfig.LIGHTNING_LISTEN.key(): 'localhost:9735',
155-
SimpleConfig.EXPERIMENTAL_LN_FORWARD_PAYMENTS.key(): 'true',
156-
SimpleConfig.EXPERIMENTAL_LN_FORWARD_TRAMPOLINE_PAYMENTS.key(): 'true',
157-
SimpleConfig.ACCEPT_ZEROCONF_CHANNELS.key(): 'true',
152+
'lightning_listen': 'localhost:9735',
153+
'lightning_forward_payments': 'true',
154+
'lightning_forward_trampoline_payments': 'true',
155+
'accept_zeroconf_channels': 'true',
158156
},
159157
'carol': {
160-
SimpleConfig.LIGHTNING_USE_GOSSIP.key(): 'false',
158+
'use_gossip': 'false',
161159
}
162160
}

0 commit comments

Comments
 (0)