Skip to content

Commit b2920db

Browse files
committed
config: enforce that SimpleConfig is singleton
related: spesmilo#5629
1 parent a43be66 commit b2920db

9 files changed

Lines changed: 33 additions & 25 deletions

File tree

electrum/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from .coinchooser import COIN_CHOOSERS
66
from .network import Network, pick_random_server
77
from .interface import Interface
8-
from .simple_config import SimpleConfig, get_config, set_config
8+
from .simple_config import SimpleConfig
99
from . import bitcoin
1010
from . import transaction
1111
from . import daemon

electrum/gui/qt/qrcodewidget.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
import electrum
1111
from electrum.i18n import _
12+
from electrum.simple_config import SimpleConfig
13+
1214
from .util import WindowModalDialog
1315

1416

@@ -105,7 +107,7 @@ def __init__(self, data, parent=None, title = "", show_text=False):
105107
hbox = QHBoxLayout()
106108
hbox.addStretch(1)
107109

108-
config = electrum.get_config()
110+
config = SimpleConfig.get_instance()
109111
if config:
110112
filename = os.path.join(config.path, "qrcode.png")
111113

electrum/gui/qt/qrtextedit.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from electrum.i18n import _
44
from electrum.plugin import run_hook
5+
from electrum.simple_config import SimpleConfig
56

67
from .util import ButtonsTextEdit, MessageBoxMixin, ColorScheme
78

@@ -54,9 +55,9 @@ def file_input(self):
5455
self.setText(data)
5556

5657
def qr_input(self):
57-
from electrum import qrscanner, get_config
58+
from electrum import qrscanner
5859
try:
59-
data = qrscanner.scan_barcode(get_config().get_video_device())
60+
data = qrscanner.scan_barcode(SimpleConfig.get_instance().get_video_device())
6061
except BaseException as e:
6162
self.show_error(repr(e))
6263
data = ''

electrum/lnchannel.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
from .bitcoin import TYPE_SCRIPT, TYPE_ADDRESS
3636
from .bitcoin import redeem_script_to_address
3737
from .crypto import sha256, sha256d
38-
from .simple_config import get_config
3938
from .transaction import Transaction
4039
from .logging import Logger
4140

electrum/lnpeer.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import aiorpcx
2020

21-
from .simple_config import get_config
2221
from .crypto import sha256, sha256d
2322
from . import bitcoin
2423
from . import ecc

electrum/network.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ def __repr__(self):
224224
return f"<UntrustedServerReturnedError original_exception: {repr(self.original_exception)}>"
225225

226226

227-
INSTANCE = None
227+
_INSTANCE = None
228228

229229

230230
class Network(Logger):
@@ -235,8 +235,9 @@ class Network(Logger):
235235
LOGGING_SHORTCUT = 'n'
236236

237237
def __init__(self, config: SimpleConfig):
238-
global INSTANCE
239-
INSTANCE = self
238+
global _INSTANCE
239+
assert _INSTANCE is None, "Network is a singleton!"
240+
_INSTANCE = self
240241

241242
Logger.__init__(self)
242243

@@ -322,7 +323,7 @@ def run_from_another_thread(self, coro, *, timeout=None):
322323

323324
@staticmethod
324325
def get_instance() -> Optional["Network"]:
325-
return INSTANCE
326+
return _INSTANCE
326327

327328
def with_recent_servers_lock(func):
328329
def func_wrapper(self, *args, **kwargs):

electrum/simple_config.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,9 @@
3131
FEERATE_REGTEST_HARDCODED = 180000 # for eclair compat
3232

3333

34-
config = {}
3534
_logger = get_logger(__name__)
3635

3736

38-
def get_config():
39-
global config
40-
return config
41-
42-
43-
def set_config(c):
44-
global config
45-
config = c
46-
4737
def estimate_fee(tx_size_bytes: int) -> int:
4838
def use_fallback_feerate():
4939
fee_per_kb = FEERATE_FALLBACK_STATIC_FEE
@@ -61,6 +51,10 @@ def use_fallback_feerate():
6151
FINAL_CONFIG_VERSION = 3
6252

6353

54+
_INSTANCE = None
55+
_ENFORCE_SIMPLECONFIG_SINGLETON = True # disabled in tests
56+
57+
6458
class SimpleConfig(Logger):
6559
"""
6660
The SimpleConfig class is responsible for handling operations involving
@@ -74,6 +68,12 @@ class SimpleConfig(Logger):
7468

7569
def __init__(self, options=None, read_user_config_function=None,
7670
read_user_dir_function=None):
71+
# note: To be honest, singletons are bad design... :/
72+
# However currently we somewhat rely on config being one.
73+
global _INSTANCE
74+
if _ENFORCE_SIMPLECONFIG_SINGLETON:
75+
assert _INSTANCE is None, "SimpleConfig is a singleton!"
76+
_INSTANCE = self
7777

7878
if options is None:
7979
options = {}
@@ -120,8 +120,9 @@ def __init__(self, options=None, read_user_config_function=None,
120120
if self.requires_upgrade():
121121
self.upgrade()
122122

123-
# Make a singleton instance of 'self'
124-
set_config(self)
123+
@staticmethod
124+
def get_instance() -> Optional["SimpleConfig"]:
125+
return _INSTANCE
125126

126127
def electrum_path(self):
127128
# Read electrum_path from command line

electrum/tests/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import threading
33

44
from electrum import constants
5+
from electrum import simple_config
56

67

78
# Set this locally to make the test suite run faster.
@@ -11,6 +12,9 @@
1112
FAST_TESTS = False
1213

1314

15+
simple_config._ENFORCE_SIMPLECONFIG_SINGLETON = False
16+
17+
1418
# some unit tests are modifying globals; sorry.
1519
class SequentialTestCase(unittest.TestCase):
1620

electrum/wallet.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
InvalidPassword, format_time, timestamp_to_datetime, Satoshis,
4848
Fiat, bfh, bh2u, TxMinedInfo, quantize_feerate, create_bip21_uri, OrderedDictWithIndex)
4949
from .util import PR_TYPE_ADDRESS, PR_TYPE_BIP70, PR_TYPE_LN
50-
from .simple_config import get_config
50+
from .simple_config import SimpleConfig
5151
from .bitcoin import (COIN, TYPE_ADDRESS, is_address, address_to_script,
5252
is_minikey, relayfee, dust_threshold)
5353
from .crypto import sha256d
@@ -71,7 +71,6 @@
7171

7272
if TYPE_CHECKING:
7373
from .network import Network
74-
from .simple_config import SimpleConfig
7574

7675

7776
_logger = get_logger(__name__)
@@ -236,7 +235,9 @@ def __init__(self, storage: WalletStorage):
236235

237236
self.contacts = Contacts(self.storage)
238237
self._coin_price_cache = {}
239-
self.config = get_config()
238+
# TODO config should be passed as a param instead? SimpleConfig should not be a singleton.
239+
self.config = SimpleConfig.get_instance()
240+
assert self.config is not None, "config must not be None"
240241
self.lnworker = LNWallet(self) if self.config.get('lightning') else None
241242

242243
def stop_threads(self):

0 commit comments

Comments
 (0)