URI: 
       tsubmarine_swaps: small clean-up - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 184920639446c2c44f901ea5089ebe9d041d1161
   DIR parent c887c910c6b8e63ec0fda305b997cd4099343f79
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Thu, 18 Jun 2020 18:18:33 +0200
       
       submarine_swaps: small clean-up
       
       Diffstat:
         M electrum/lnworker.py                |       2 ++
         M electrum/submarine_swaps.py         |      68 +++++++++++++++++++------------
         M electrum/transaction.py             |       1 +
       
       3 files changed, 46 insertions(+), 25 deletions(-)
       ---
   DIR diff --git a/electrum/lnworker.py b/electrum/lnworker.py
       t@@ -480,6 +480,8 @@ class LNGossip(LNWorker):
        
        class LNWallet(LNWorker):
        
       +    lnwatcher: 'LNWalletWatcher'
       +
            def __init__(self, wallet: 'Abstract_Wallet', xprv):
                Logger.__init__(self)
                self.wallet = wallet
   DIR diff --git a/electrum/submarine_swaps.py b/electrum/submarine_swaps.py
       t@@ -1,8 +1,9 @@
       -import attr
        import asyncio
        import json
        import os
       -from typing import TYPE_CHECKING
       +from typing import TYPE_CHECKING, Optional, Dict
       +
       +import attr
        
        from .crypto import sha256, hash_160
        from .ecc import ECPrivkey
       t@@ -64,20 +65,28 @@ WITNESS_TEMPLATE_REVERSE_SWAP = [
        class SwapData(StoredObject):
            is_reverse = attr.ib(type=bool)
            locktime = attr.ib(type=int)
       -    onchain_amount = attr.ib(type=int)
       -    lightning_amount = attr.ib(type=int)
       +    onchain_amount = attr.ib(type=int)  # in sats
       +    lightning_amount = attr.ib(type=int)  # in sats
            redeem_script = attr.ib(type=bytes, converter=hex_to_bytes)
            preimage = attr.ib(type=bytes, converter=hex_to_bytes)
       -    prepay_hash = attr.ib(type=bytes, converter=hex_to_bytes)
       +    prepay_hash = attr.ib(type=Optional[bytes], converter=hex_to_bytes)
            privkey = attr.ib(type=bytes, converter=hex_to_bytes)
            lockup_address = attr.ib(type=str)
       -    funding_txid = attr.ib(type=str)
       -    spending_txid = attr.ib(type=str)
       +    funding_txid = attr.ib(type=Optional[str])
       +    spending_txid = attr.ib(type=Optional[str])
            is_redeemed = attr.ib(type=bool)
        
        
       -def create_claim_tx(txin, witness_script, preimage, privkey:bytes, address, amount_sat, locktime):
       -    pubkey = ECPrivkey(privkey).get_public_key_bytes(compressed=True)
       +def create_claim_tx(
       +        *,
       +        txin: PartialTxInput,
       +        witness_script: bytes,
       +        preimage: bytes,
       +        privkey: bytes,
       +        address: str,
       +        amount_sat: int,
       +        locktime: int,
       +) -> PartialTransaction:
            if is_segwit_address(txin.address):
                txin.script_type = 'p2wsh'
                txin.script_sig = b''
       t@@ -86,7 +95,7 @@ def create_claim_tx(txin, witness_script, preimage, privkey:bytes, address, amou
                txin.redeem_script = bytes.fromhex(p2wsh_nested_script(witness_script.hex()))
                txin.script_sig = bytes.fromhex(push_script(txin.redeem_script.hex()))
            txin.witness_script = witness_script
       -    txout = PartialTxOutput(scriptpubkey=bytes.fromhex(address_to_script(address)), value=amount_sat)
       +    txout = PartialTxOutput.from_address_and_value(address, amount_sat)
            tx = PartialTransaction.from_io([txin], [txout], version=2, locktime=(None if preimage else locktime))
            #tx.set_rbf(True)
            sig = bytes.fromhex(tx.sign_txin(0, privkey))
       t@@ -97,7 +106,7 @@ def create_claim_tx(txin, witness_script, preimage, privkey:bytes, address, amou
        
        class SwapManager(Logger):
        
       -    def __init__(self, wallet: 'Abstract_Wallet', network:'Network'):
       +    def __init__(self, wallet: 'Abstract_Wallet', network: 'Network'):
                Logger.__init__(self)
                self.normal_fee = 0
                self.lockup_fee = 0
       t@@ -108,8 +117,8 @@ class SwapManager(Logger):
                self.wallet = wallet
                self.lnworker = wallet.lnworker
                self.lnwatcher = self.wallet.lnworker.lnwatcher
       -        self.swaps = self.wallet.db.get_dict('submarine_swaps')
       -        self.prepayments = {} # fee_preimage -> preimage
       +        self.swaps = self.wallet.db.get_dict('submarine_swaps')  # type: Dict[str, SwapData]
       +        self.prepayments = {}  # type: Dict[bytes, bytes] # fee_preimage -> preimage
                for k, swap in self.swaps.items():
                    if swap.is_reverse and swap.prepay_hash is not None:
                        self.prepayments[swap.prepay_hash] = bytes.fromhex(k)
       t@@ -118,7 +127,7 @@ class SwapManager(Logger):
                    self.add_lnwatcher_callback(swap)
        
            @log_exceptions
       -    async def _claim_swap(self, swap):
       +    async def _claim_swap(self, swap: SwapData) -> None:
                if not self.lnwatcher.is_up_to_date():
                    return
                current_height = self.network.get_local_height()
       t@@ -128,7 +137,7 @@ class SwapManager(Logger):
                    return
                txos = self.lnwatcher.get_addr_outputs(swap.lockup_address)
                for txin in txos.values():
       -            if swap.is_reverse and txin._trusted_value_sats < swap.onchain_amount:
       +            if swap.is_reverse and txin.value_sats() < swap.onchain_amount:
                        self.logger.info('amount too low, we should not reveal the preimage')
                        continue
                    spent_height = txin.spent_height
       t@@ -138,35 +147,43 @@ class SwapManager(Logger):
                            self.lnwatcher.remove_callback(swap.lockup_address)
                            swap.is_redeemed = True
                        continue
       -            amount_sat = txin._trusted_value_sats - self.get_claim_fee()
       +            amount_sat = txin.value_sats() - self.get_claim_fee()
                    if amount_sat < dust_threshold():
                        self.logger.info('utxo value below dust threshold')
                        continue
                    address = self.wallet.get_receiving_address()
                    preimage = swap.preimage if swap.is_reverse else 0
       -            tx = create_claim_tx(txin, swap.redeem_script, preimage, swap.privkey, address, amount_sat, swap.locktime)
       +            tx = create_claim_tx(txin=txin,
       +                                 witness_script=swap.redeem_script,
       +                                 preimage=preimage,
       +                                 privkey=swap.privkey,
       +                                 address=address,
       +                                 amount_sat=amount_sat,
       +                                 locktime=swap.locktime)
                    await self.network.broadcast_transaction(tx)
                    # save txid
                    if swap.is_reverse:
                        swap.spending_txid = tx.txid()
                    else:
       -                self.wallet.setlabel(tx.txid(), 'Swap refund')
       +                self.wallet.set_label(tx.txid(), 'Swap refund')
        
            def get_claim_fee(self):
                return self.lnwatcher.config.estimate_fee(136, allow_fallback_to_static_rates=True)
        
       -    def get_swap(self, payment_hash):
       +    def get_swap(self, payment_hash: bytes) -> Optional[SwapData]:
                # for history
                swap = self.swaps.get(payment_hash.hex())
                if swap:
                    return swap
        
       -    def add_lnwatcher_callback(self, swap):
       +    def add_lnwatcher_callback(self, swap: SwapData) -> None:
                callback = lambda: self._claim_swap(swap)
                self.lnwatcher.add_callback(swap.lockup_address, callback)
        
            @log_exceptions
       -    async def normal_swap(self, lightning_amount, expected_onchain_amount, password, *, tx=None):
       +    async def normal_swap(self, lightning_amount: int, expected_onchain_amount: int,
       +                          password, *, tx: PartialTransaction = None) -> str:
       +        """send on-chain BTC, receive on Lightning"""
                privkey = os.urandom(32)
                pubkey = ECPrivkey(privkey).get_public_key_bytes(compressed=True)
                key = await self.lnworker._add_request_coro(lightning_amount, 'swap', expiry=3600*24)
       t@@ -237,7 +254,8 @@ class SwapManager(Logger):
                return tx.txid()
        
            @log_exceptions
       -    async def reverse_swap(self, amount_sat, expected_amount):
       +    async def reverse_swap(self, amount_sat: int, expected_amount: int) -> bool:
       +        """send on Lightning, receive on-chain"""
                privkey = os.urandom(32)
                pubkey = ECPrivkey(privkey).get_public_key_bytes(compressed=True)
                preimage = os.urandom(32)
       t@@ -315,7 +333,7 @@ class SwapManager(Logger):
                return success
        
            @log_exceptions
       -    async def get_pairs(self):
       +    async def get_pairs(self) -> None:
                response = await self.network._send_http_on_proxy(
                    'get',
                    API_URL + '/getpairs',
       t@@ -329,7 +347,7 @@ class SwapManager(Logger):
                self.min_amount = limits['minimal']
                self.max_amount = limits['maximal']
        
       -    def get_recv_amount(self, send_amount, is_reverse):
       +    def get_recv_amount(self, send_amount: Optional[int], is_reverse: bool) -> Optional[int]:
                if send_amount is None:
                    return
                if send_amount < self.min_amount or send_amount > self.max_amount:
       t@@ -346,7 +364,7 @@ class SwapManager(Logger):
                    return
                return x
        
       -    def get_send_amount(self, recv_amount, is_reverse):
       +    def get_send_amount(self, recv_amount: Optional[int], is_reverse: bool) -> Optional[int]:
                if not recv_amount:
                    return
                x = recv_amount
   DIR diff --git a/electrum/transaction.py b/electrum/transaction.py
       t@@ -1141,6 +1141,7 @@ class PartialTxInput(TxInput, PSBTSection):
                self._trusted_value_sats = None  # type: Optional[int]
                self._trusted_address = None  # type: Optional[str]
                self.block_height = None  # type: Optional[int]  # height at which the TXO is mined; None means unknown
       +        self.spent_height = None  # type: Optional[int]  # height at which the TXO got spent
                self._is_p2sh_segwit = None  # type: Optional[bool]  # None means unknown
                self._is_native_segwit = None  # type: Optional[bool]  # None means unknown