Browse Source

invoice.get_amount_sat: handle None in more places

I believe lightning requests created before https://github.com/spesmilo/electrum/pull/7730
can have an amount of None - ones created after have amount 0 instead.
We could do a wallet db upgrade potentially.
Regardless, the type hint is `get_amount_sat(self) -> Union[int, str, None]`,
so None should be handled. (well, arguably "!" should be handled too...)

```
E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
  File "...\electrum\electrum\gui\qt\request_list.py", line 101, in item_changed
    self.parent.show_receive_request(req)
  File "...\electrum\electrum\gui\qt\main_window.py", line 1279, in show_receive_request
    URI = req.get_bip21_URI(lightning=bip21_lightning)
  File "...\electrum\electrum\invoices.py", line 164, in get_bip21_URI
    amount = int(self.get_amount_sat())
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
```

```
E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
  File "...\electrum\electrum\gui\qt\request_list.py", line 101, in item_changed
    self.parent.show_receive_request(req)
  File "...\electrum\electrum\gui\qt\main_window.py", line 1281, in show_receive_request
    can_receive_lightning = self.wallet.lnworker and req.get_amount_sat() <= self.wallet.lnworker.num_sats_can_receive()
TypeError: '<=' not supported between instances of 'NoneType' and 'decimal.Decimal'
```
master
SomberNight 4 years ago
parent
commit
2ec9e869b3
No known key found for this signature in database
GPG Key ID: B33B5F232C6271E9
  1. 2
      electrum/gui/qt/main_window.py
  2. 4
      electrum/invoices.py
  3. 4
      electrum/lnworker.py
  4. 2
      electrum/submarine_swaps.py
  5. 2
      electrum/wallet.py

2
electrum/gui/qt/main_window.py

@ -1278,7 +1278,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
bip21_lightning = lnaddr if self.config.get('bip21_lightning', False) else None bip21_lightning = lnaddr if self.config.get('bip21_lightning', False) else None
URI = req.get_bip21_URI(lightning=bip21_lightning) URI = req.get_bip21_URI(lightning=bip21_lightning)
lightning_online = self.wallet.lnworker and self.wallet.lnworker.num_peers() > 0 lightning_online = self.wallet.lnworker and self.wallet.lnworker.num_peers() > 0
can_receive_lightning = self.wallet.lnworker and req.get_amount_sat() <= self.wallet.lnworker.num_sats_can_receive() can_receive_lightning = self.wallet.lnworker and (req.get_amount_sat() or 0) <= self.wallet.lnworker.num_sats_can_receive()
if lnaddr is None: if lnaddr is None:
ln_help = _('This request does not have a Lightning invoice.') ln_help = _('This request does not have a Lightning invoice.')
lnaddr = '' lnaddr = ''

4
electrum/invoices.py

@ -161,7 +161,9 @@ class Invoice(StoredObject):
def get_bip21_URI(self, lightning=None): def get_bip21_URI(self, lightning=None):
from electrum.util import create_bip21_uri from electrum.util import create_bip21_uri
addr = self.get_address() addr = self.get_address()
amount = int(self.get_amount_sat()) amount = self.get_amount_sat()
if amount is not None:
amount = int(amount)
message = self.message message = self.message
extra = {} extra = {}
if self.time and self.exp: if self.time and self.exp:

4
electrum/lnworker.py

@ -1098,7 +1098,7 @@ class LNWallet(LNWorker):
def can_pay_invoice(self, invoice: Invoice) -> bool: def can_pay_invoice(self, invoice: Invoice) -> bool:
assert invoice.is_lightning() assert invoice.is_lightning()
return invoice.get_amount_sat() <= self.num_sats_can_send() return (invoice.get_amount_sat() or 0) <= self.num_sats_can_send()
@log_exceptions @log_exceptions
async def pay_invoice( async def pay_invoice(
@ -2126,7 +2126,7 @@ class LNWallet(LNWorker):
def can_receive_invoice(self, invoice: Invoice) -> bool: def can_receive_invoice(self, invoice: Invoice) -> bool:
assert invoice.is_lightning() assert invoice.is_lightning()
return invoice.get_amount_sat() <= self.num_sats_can_receive() return (invoice.get_amount_sat() or 0) <= self.num_sats_can_receive()
async def close_channel(self, chan_id): async def close_channel(self, chan_id):
chan = self._channels[chan_id] chan = self._channels[chan_id]

2
electrum/submarine_swaps.py

@ -419,7 +419,7 @@ class SwapManager(Logger):
raise Exception("rswap check failed: locktime too close") raise Exception("rswap check failed: locktime too close")
# verify invoice preimage_hash # verify invoice preimage_hash
lnaddr = self.lnworker._check_invoice(invoice) lnaddr = self.lnworker._check_invoice(invoice)
invoice_amount = lnaddr.get_amount_sat() invoice_amount = int(lnaddr.get_amount_sat())
if lnaddr.paymenthash != preimage_hash: if lnaddr.paymenthash != preimage_hash:
raise Exception("rswap check failed: inconsistent RHASH and invoice") raise Exception("rswap check failed: inconsistent RHASH and invoice")
# check that the lightning amount is what we requested # check that the lightning amount is what we requested

2
electrum/wallet.py

@ -2167,7 +2167,7 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
def get_onchain_request_status(self, r: Invoice) -> Tuple[bool, Optional[int]]: def get_onchain_request_status(self, r: Invoice) -> Tuple[bool, Optional[int]]:
address = r.get_address() address = r.get_address()
amount = r.get_amount_sat() amount = int(r.get_amount_sat() or 0)
received, sent = self.get_addr_io(address) received, sent = self.get_addr_io(address)
l = [] l = []
for txo, x in received.items(): for txo, x in received.items():

Loading…
Cancel
Save