diff --git a/electrum/lnchannel.py b/electrum/lnchannel.py index b013a48b5..3359c07d4 100644 --- a/electrum/lnchannel.py +++ b/electrum/lnchannel.py @@ -191,7 +191,6 @@ class AbstractChannel(Logger, ABC): funding_outpoint: Outpoint node_id: bytes # note that it might not be the full 33 bytes; for OCB it is only the prefix _state: ChannelState - sweep_address: str def set_short_channel_id(self, short_id: ShortChannelID) -> None: self.short_channel_id = short_id @@ -284,10 +283,10 @@ class AbstractChannel(Logger, ABC): self.storage.pop('closing_height', None) def create_sweeptxs_for_our_ctx(self, ctx): - return create_sweeptxs_for_our_ctx(chan=self, ctx=ctx, sweep_address=self.sweep_address) + return create_sweeptxs_for_our_ctx(chan=self, ctx=ctx, sweep_address=self.get_sweep_address()) def create_sweeptxs_for_their_ctx(self, ctx): - return create_sweeptxs_for_their_ctx(chan=self, ctx=ctx, sweep_address=self.sweep_address) + return create_sweeptxs_for_their_ctx(chan=self, ctx=ctx, sweep_address=self.get_sweep_address()) def is_backup(self): return False @@ -416,6 +415,14 @@ class AbstractChannel(Logger, ABC): def get_funding_address(self) -> str: pass + @abstractmethod + def get_sweep_address(self) -> str: + """Returns a wallet address we can use to sweep coins to. + It could be something static to the channel (fixed for its lifecycle), + or it might just ask the wallet now for an unused address. + """ + pass + def get_state_for_GUI(self) -> str: cs = self.get_state() if cs <= ChannelState.OPEN and self.unconfirmed_closing_txid: @@ -575,7 +582,7 @@ class ChannelBackup(AbstractChannel): def create_sweeptxs_for_our_ctx(self, ctx): if self.is_imported: - return create_sweeptxs_for_our_ctx(chan=self, ctx=ctx, sweep_address=self.sweep_address) + return create_sweeptxs_for_our_ctx(chan=self, ctx=ctx, sweep_address=self.get_sweep_address()) else: # backup from op_return return {} @@ -613,8 +620,7 @@ class ChannelBackup(AbstractChannel): def is_frozen_for_receiving(self) -> bool: return False - @property - def sweep_address(self) -> str: + def get_sweep_address(self) -> str: return self.lnworker.wallet.get_new_sweep_address_for_channel() def get_local_pubkey(self) -> bytes: @@ -846,10 +852,8 @@ class Channel(AbstractChannel): channel_type = ChannelType(self.storage.get('channel_type')) return bool(channel_type & ChannelType.OPTION_ZEROCONF) - @property - def sweep_address(self) -> str: + def get_sweep_address(self) -> str: # TODO: in case of unilateral close with pending HTLCs, this address will be reused - addr = None assert self.is_static_remotekey_enabled() our_payment_pubkey = self.config[LOCAL].payment_basepoint.pubkey addr = make_commitment_output_to_remote_address(our_payment_pubkey) @@ -1415,10 +1419,10 @@ class Channel(AbstractChannel): ctn = self.get_oldest_unrevoked_ctn(subject) return self.get_commitment(subject, ctn=ctn) - def create_sweeptxs(self, ctn: int) -> List[Transaction]: + def create_sweeptxs_for_watchtower(self, ctn: int) -> List[Transaction]: from .lnsweep import create_sweeptxs_for_watchtower secret, ctx = self.get_secret_and_commitment(REMOTE, ctn=ctn) - return create_sweeptxs_for_watchtower(self, ctx, secret, self.sweep_address) + return create_sweeptxs_for_watchtower(self, ctx, secret, self.get_sweep_address()) def get_oldest_unrevoked_ctn(self, subject: HTLCOwner) -> int: return self.hm.ctn_oldest_unrevoked(subject) @@ -1645,7 +1649,7 @@ class Channel(AbstractChannel): def maybe_sweep_revoked_htlc(self, ctx: Transaction, htlc_tx: Transaction) -> Optional[SweepInfo]: # look at the output address, check if it matches - return create_sweeptx_for_their_revoked_htlc(self, ctx, htlc_tx, self.sweep_address) + return create_sweeptx_for_their_revoked_htlc(self, ctx, htlc_tx, self.get_sweep_address()) def has_pending_changes(self, subject: HTLCOwner) -> bool: next_htlcs = self.hm.get_htlcs_in_next_ctx(subject) diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py index 27d750948..d4b628559 100644 --- a/electrum/lnpeer.py +++ b/electrum/lnpeer.py @@ -2377,7 +2377,7 @@ class Peer(Logger): if chan.config[LOCAL].upfront_shutdown_script: scriptpubkey = chan.config[LOCAL].upfront_shutdown_script else: - scriptpubkey = bitcoin.address_to_script(chan.sweep_address) + scriptpubkey = bitcoin.address_to_script(chan.get_sweep_address()) assert scriptpubkey # wait until no more pending updates (bolt2) chan.set_can_send_ctx_updates(False) @@ -2430,7 +2430,7 @@ class Peer(Logger): if chan.config[LOCAL].upfront_shutdown_script: our_scriptpubkey = chan.config[LOCAL].upfront_shutdown_script else: - our_scriptpubkey = bitcoin.address_to_script(chan.sweep_address) + our_scriptpubkey = bitcoin.address_to_script(chan.get_sweep_address()) assert our_scriptpubkey # estimate fee of closing tx dummy_sig, dummy_tx = chan.make_closing_tx(our_scriptpubkey, their_scriptpubkey, fee_sat=0) diff --git a/electrum/lnsweep.py b/electrum/lnsweep.py index 74825e455..90221dfb8 100644 --- a/electrum/lnsweep.py +++ b/electrum/lnsweep.py @@ -376,7 +376,7 @@ def create_sweeptxs_for_their_ctx( chan.logger.debug(f'(lnsweep) found their ctx: {to_local_address} {to_remote_address}') if is_revocation: our_revocation_privkey = derive_blinded_privkey(our_conf.revocation_basepoint.privkey, per_commitment_secret) - gen_tx = create_sweeptx_for_their_revoked_ctx(chan, ctx, per_commitment_secret, chan.sweep_address) + gen_tx = create_sweeptx_for_their_revoked_ctx(chan, ctx, per_commitment_secret, sweep_address) if gen_tx: tx = gen_tx() txs[tx.inputs()[0].prevout.to_str()] = SweepInfo( diff --git a/electrum/lnworker.py b/electrum/lnworker.py index 8195d2d0e..c0be79bf0 100644 --- a/electrum/lnworker.py +++ b/electrum/lnworker.py @@ -947,7 +947,7 @@ class LNWallet(LNWorker): current_ctn = chan.get_oldest_unrevoked_ctn(REMOTE) watchtower_ctn = await watchtower.get_ctn(outpoint, addr) for ctn in range(watchtower_ctn + 1, current_ctn): - sweeptxs = chan.create_sweeptxs(ctn) + sweeptxs = chan.create_sweeptxs_for_watchtower(ctn) for tx in sweeptxs: await watchtower.add_sweep_tx(outpoint, ctn, tx.inputs()[0].prevout.to_str(), tx.serialize())