Skip to content

exchange_rate: some clean-up - #10990

Merged
f321x merged 15 commits into
spesmilo:masterfrom
SomberNight:202609_fxrate_cleanup
Sep 25, 2026
Merged

f321x merged 15 commits into
spesmilo:masterfrom
SomberNight:202609_fxrate_cleanup

Conversation

@SomberNight

@SomberNight SomberNight commented Sep 23, 2026 •

Copy link
Copy Markdown
Member
  • Mostly boiler-plate boring maintenance stuff:
    • renaming methods, for clarity
    • moving stuff around a tiny bit, for clarity
    • rm some dead code
  • Also
    • rm broken exchanges/APIs
    • some small robustness improvements against malformed data

@SomberNight
SomberNight marked this pull request as draft September 23, 2026 17:03
@SomberNight
SomberNight force-pushed the 202609_fxrate_cleanup branch 2 times, most recently from 4bf4c80 to ec22c14 Compare September 23, 2026 18:24
Previously encountering a corrupted cache file would crash the application at startup.

Example:
```
$ cat ~/.electrum/testnet/cache/MempoolSpace_EUR
5
```

```
  0.53 | I | exchange_rate.FxThread | using exchange MempoolSpace
  0.53 | E | __main__ |
Traceback (most recent call last):
  File "/home/user/wspace/electrum/run_electrum", line 502, in main
    handle_cmd(
    ~~~~~~~~~~^
        cmdname=cmdname,
        ^^^^^^^^^^^^^^^^
        config=config,
        ^^^^^^^^^^^^^^
        config_options=config_options,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/user/wspace/electrum/run_electrum", line 519, in handle_cmd
    d = daemon.Daemon(config, fd, start_network=False, only_minimal_jsonrpc=only_minimal_jsonrpc)
  File "/home/user/wspace/electrum/electrum/util.py", line 500, in do_profile
    o = func(*args, **kw_args)
  File "/home/user/wspace/electrum/electrum/daemon.py", line 427, in __init__
    self.fx = FxThread(config=config)
              ~~~~~~~~^^^^^^^^^^^^^^^
  File "/home/user/wspace/electrum/electrum/exchange_rate.py", line 676, in __init__
    self.set_exchange(self.config_exchange())
    ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/wspace/electrum/electrum/exchange_rate.py", line 784, in set_exchange
    self.exchange.read_historical_rates(self.ccy, self.cache_dir)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/wspace/electrum/electrum/exchange_rate.py", line 127, in read_historical_rates
    h, timestamp = self._read_historical_rates_from_file(
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        exchange_name=self.name(),
        ^^^^^^^^^^^^^^^^^^^^^^^^^^
        ccy=ccy,
        ^^^^^^^^
        cache_dir=cache_dir,
        ^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/user/wspace/electrum/electrum/exchange_rate.py", line 123, in _read_historical_rates_from_file
    h = {date_str: str(rate) for (date_str, rate) in h.items()}
                                                     ^^^^^^^
AttributeError: 'int' object has no attribute 'items'

```
Most of these were not even in currencies.json, so likely broken for a long time.
If an exchange is not in currencies.json, it cannot actually be selected in the GUI...

- Bitcointoyou: api broken: returns website html instead of json
- BitcoinVenezuela: api returns http error 521. main website has not worked for ~2 years based on archive.org
- itBit: SSL cert expired over 2 years ago
- winkdex: domain does not resolve
- api.bitragem.com: domain does not resolve
- api.biscoint.io: domain does not resolve
- Walltime: response is a broken xml saying "access denied"
- Bitvalor/MercadoBitcoin: api.bitvalor.com returns json saying price is zero. main website looks broken for 2+ yrs
- api.coincap.io: domain does not resolve
already none of the subclasses could have a None value there
drop obviously malformed items, and negative rates
…alues

drop too large or too high resolutions prices, as
we store these in memory and on-disk
drop "future" data, and data that is impossibly old:
this limits disk/mem-usage
@SomberNight
SomberNight marked this pull request as ready for review September 23, 2026 21:19
Comment thread electrum/exchange_rate.py
- mainly for the exchange_rate usage, where we use to_decimal to parse
"number-like" data received from any exchange's HTTP API.
- change seems harmless for other existing callers of to_decimal

---

f321x said:

> We had the issue before that a `null` value would render a provider broken, maybe we could make `to_decimal` convert `null` to `Decimal(NaN)` so they are handled without discarding the remaining rates?
> See spesmilo#10572
@f321x
f321x merged commit a4c770c into spesmilo:master Sep 25, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants