URI: 
       tMerge pull request #5652 from SomberNight/20190922_config_no_longer_singleton - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit f3eeb8817e847cf5b1f8fd7db92b8486937e6da9
   DIR parent d6c7dee547c844ecac6a5879721ae767efe4b9bd
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Sun, 22 Sep 2019 23:56:08 +0200
       
       Merge pull request #5652 from SomberNight/20190922_config_no_longer_singleton
       
       config: no longer singleton. it is passed to Wallet.__init__
       Diffstat:
         M electrum/commands.py                |       6 ++++--
         M electrum/daemon.py                  |       2 +-
         M electrum/gui/kivy/main_window.py    |       2 +-
         M electrum/gui/qt/__init__.py         |       2 +-
         M electrum/gui/qt/qrcodewidget.py     |      52 ++++++++++++++++---------------
         M electrum/gui/qt/qrtextedit.py       |       9 ++++++---
         M electrum/gui/stdio.py               |       2 +-
         M electrum/gui/text.py                |       2 +-
         M electrum/lnchannel.py               |       7 +++++--
         M electrum/lnsweep.py                 |      46 +++++++++++++++++++------------
         M electrum/lnworker.py                |       2 +-
         M electrum/plugins/trustedcoin/trust… |       4 ++--
         M electrum/scripts/quick_start.py     |       6 +++---
         M electrum/simple_config.py           |      37 +++++--------------------------
         M electrum/sql_db.py                  |       1 +
         M electrum/tests/__init__.py          |      22 ++++++++++++++++------
         M electrum/tests/test_bitcoin.py      |      10 +++++-----
         M electrum/tests/test_blockchain.py   |      12 ++++--------
         M electrum/tests/test_bolt11.py       |      11 ++++++++---
         M electrum/tests/test_commands.py     |      26 ++++++++++++++++----------
         M electrum/tests/test_dnssec.py       |       4 ++--
         M electrum/tests/test_lnchannel.py    |      15 ++++++++++-----
         M electrum/tests/test_lnhtlc.py       |       8 ++++++--
         M electrum/tests/test_lnpeer.py       |       4 ++--
         M electrum/tests/test_lnrouter.py     |      19 ++++++-------------
         M electrum/tests/test_lntransport.py  |      11 ++++++++---
         M electrum/tests/test_lnutil.py       |       7 ++++++-
         M electrum/tests/test_mnemonic.py     |      10 +++++-----
         M electrum/tests/test_network.py      |       7 +++++--
         M electrum/tests/test_revealer.py     |       4 ++--
         M electrum/tests/test_simple_config.… |       6 +++---
         M electrum/tests/test_storage_upgrad… |       8 ++++----
         M electrum/tests/test_transaction.py  |       6 +++---
         M electrum/tests/test_util.py         |       4 ++--
         M electrum/tests/test_wallet.py       |      24 ++++++++++++++----------
         M electrum/tests/test_wallet_vertica… |     248 +++++++++++++++++--------------
         M electrum/tests/test_x509.py         |       7 ++++++-
         M electrum/wallet.py                  |      39 +++++++++++++++----------------
         M run_electrum                        |       2 +-
       
       39 files changed, 374 insertions(+), 320 deletions(-)
       ---
   DIR diff --git a/electrum/commands.py b/electrum/commands.py
       t@@ -216,7 +216,8 @@ class Commands:
                                      passphrase=passphrase,
                                      password=password,
                                      encrypt_file=encrypt_file,
       -                              seed_type=seed_type)
       +                              seed_type=seed_type,
       +                              config=self.config)
                return {
                    'seed': d['seed'],
                    'path': d['wallet'].storage.path,
       t@@ -235,7 +236,8 @@ class Commands:
                                             path=wallet_path,
                                             passphrase=passphrase,
                                             password=password,
       -                                     encrypt_file=encrypt_file)
       +                                     encrypt_file=encrypt_file,
       +                                     config=self.config)
                return {
                    'path': d['wallet'].storage.path,
                    'msg': d['msg'],
   DIR diff --git a/electrum/daemon.py b/electrum/daemon.py
       t@@ -386,7 +386,7 @@ class Daemon(Logger):
                    return
                if storage.get_action():
                    return
       -        wallet = Wallet(storage)
       +        wallet = Wallet(storage, config=self.config)
                wallet.start_network(self.network)
                self._wallets[path] = wallet
                self.wallet = wallet
   DIR diff --git a/electrum/gui/kivy/main_window.py b/electrum/gui/kivy/main_window.py
       t@@ -576,7 +576,7 @@ class ElectrumWindow(App):
        
            def on_wizard_complete(self, wizard, storage):
                if storage:
       -            wallet = Wallet(storage)
       +            wallet = Wallet(storage, config=self.electrum_config)
                    wallet.start_network(self.daemon.network)
                    self.daemon.add_wallet(wallet)
                    self.load_wallet(wallet)
   DIR diff --git a/electrum/gui/qt/__init__.py b/electrum/gui/qt/__init__.py
       t@@ -308,7 +308,7 @@ class ElectrumGui(Logger):
                # return if wallet creation is not complete
                if storage is None or storage.get_action():
                    return
       -        wallet = Wallet(storage)
       +        wallet = Wallet(storage, config=self.config)
                wallet.start_network(self.daemon.network)
                self.daemon.add_wallet(wallet)
                return wallet
   DIR diff --git a/electrum/gui/qt/qrcodewidget.py b/electrum/gui/qt/qrcodewidget.py
       t@@ -1,17 +1,16 @@
       -import os
        import qrcode
        
        from PyQt5.QtGui import QColor, QPen
        import PyQt5.QtGui as QtGui
        from PyQt5.QtCore import Qt
        from PyQt5.QtWidgets import (
       -    QApplication, QVBoxLayout, QTextEdit, QHBoxLayout, QPushButton, QWidget)
       +    QApplication, QVBoxLayout, QTextEdit, QHBoxLayout, QPushButton, QWidget,
       +    QFileDialog,
       +)
        
       -import electrum
        from electrum.i18n import _
       -from electrum.simple_config import SimpleConfig
        
       -from .util import WindowModalDialog
       +from .util import WindowModalDialog, get_parent_main_window
        
        
        class QRCodeWidget(QWidget):
       t@@ -107,27 +106,30 @@ class QRDialog(WindowModalDialog):
                hbox = QHBoxLayout()
                hbox.addStretch(1)
        
       -        config = SimpleConfig.get_instance()
       -        if config:
       -            filename = os.path.join(config.path, "qrcode.png")
       -
       -            def print_qr():
       -                p = qrw.grab()  # FIXME also grabs neutral colored padding
       -                p.save(filename, 'png')
       -                self.show_message(_("QR code saved to file") + " " + filename)
       -
       -            def copy_to_clipboard():
       -                p = qrw.grab()
       -                QApplication.clipboard().setPixmap(p)
       -                self.show_message(_("QR code copied to clipboard"))
       -
       -            b = QPushButton(_("Copy"))
       -            hbox.addWidget(b)
       -            b.clicked.connect(copy_to_clipboard)
       +        def print_qr():
       +            main_window = get_parent_main_window(self)
       +            if main_window:
       +                filename = main_window.getSaveFileName(_("Select where to save file"), "qrcode.png")
       +            else:
       +                filename, __ = QFileDialog.getSaveFileName(self, _("Select where to save file"), "qrcode.png")
       +            if not filename:
       +                return
       +            p = qrw.grab()  # FIXME also grabs neutral colored padding
       +            p.save(filename, 'png')
       +            self.show_message(_("QR code saved to file") + " " + filename)
       +
       +        def copy_to_clipboard():
       +            p = qrw.grab()
       +            QApplication.clipboard().setPixmap(p)
       +            self.show_message(_("QR code copied to clipboard"))
       +
       +        b = QPushButton(_("Copy"))
       +        hbox.addWidget(b)
       +        b.clicked.connect(copy_to_clipboard)
        
       -            b = QPushButton(_("Save"))
       -            hbox.addWidget(b)
       -            b.clicked.connect(print_qr)
       +        b = QPushButton(_("Save"))
       +        hbox.addWidget(b)
       +        b.clicked.connect(print_qr)
        
                b = QPushButton(_("Close"))
                hbox.addWidget(b)
   DIR diff --git a/electrum/gui/qt/qrtextedit.py b/electrum/gui/qt/qrtextedit.py
       t@@ -4,7 +4,7 @@ from electrum.i18n import _
        from electrum.plugin import run_hook
        from electrum.simple_config import SimpleConfig
        
       -from .util import ButtonsTextEdit, MessageBoxMixin, ColorScheme
       +from .util import ButtonsTextEdit, MessageBoxMixin, ColorScheme, get_parent_main_window
        
        
        class ShowQRTextEdit(ButtonsTextEdit):
       t@@ -23,7 +23,7 @@ class ShowQRTextEdit(ButtonsTextEdit):
                    s = str(self.toPlainText())
                except:
                    s = self.toPlainText()
       -        QRDialog(s).exec_()
       +        QRDialog(s, parent=self).exec_()
        
            def contextMenuEvent(self, e):
                m = self.createStandardContextMenu()
       t@@ -56,8 +56,11 @@ class ScanQRTextEdit(ButtonsTextEdit, MessageBoxMixin):
        
            def qr_input(self):
                from electrum import qrscanner
       +        main_window = get_parent_main_window(self)
       +        assert main_window
       +        config = main_window.config
                try:
       -            data = qrscanner.scan_barcode(SimpleConfig.get_instance().get_video_device())
       +            data = qrscanner.scan_barcode(config.get_video_device())
                except BaseException as e:
                    self.show_error(repr(e))
                    data = ''
   DIR diff --git a/electrum/gui/stdio.py b/electrum/gui/stdio.py
       t@@ -39,7 +39,7 @@ class ElectrumGui:
                self.str_amount = ""
                self.str_fee = ""
        
       -        self.wallet = Wallet(storage)
       +        self.wallet = Wallet(storage, config=config)
                self.wallet.start_network(self.network)
                self.contacts = self.wallet.contacts
        
   DIR diff --git a/electrum/gui/text.py b/electrum/gui/text.py
       t@@ -33,7 +33,7 @@ class ElectrumGui:
                if storage.is_encrypted():
                    password = getpass.getpass('Password:', stream=None)
                    storage.decrypt(password)
       -        self.wallet = Wallet(storage)
       +        self.wallet = Wallet(storage, config=config)
                self.wallet.start_network(self.network)
                self.contacts = self.wallet.contacts
        
   DIR diff --git a/electrum/lnchannel.py b/electrum/lnchannel.py
       t@@ -27,7 +27,7 @@ from collections import namedtuple, defaultdict
        import binascii
        import json
        from enum import Enum, auto
       -from typing import Optional, Dict, List, Tuple, NamedTuple, Set, Callable, Iterable, Sequence
       +from typing import Optional, Dict, List, Tuple, NamedTuple, Set, Callable, Iterable, Sequence, TYPE_CHECKING
        import time
        
        from . import ecc
       t@@ -51,6 +51,9 @@ from .lnsweep import create_sweeptxs_for_our_ctx, create_sweeptxs_for_their_ctx
        from .lnsweep import create_sweeptx_for_their_revoked_htlc, SweepInfo
        from .lnhtlc import HTLCManager
        
       +if TYPE_CHECKING:
       +    from .lnworker import LNWallet
       +
        
        class ChannelJsonEncoder(json.JSONEncoder):
            def default(self, o):
       t@@ -110,7 +113,7 @@ class Channel(Logger):
            def __init__(self, state, *, sweep_address=None, name=None, lnworker=None, initial_feerate=None):
                self.name = name
                Logger.__init__(self)
       -        self.lnworker = lnworker
       +        self.lnworker = lnworker  # type: Optional[LNWallet]
                self.sweep_address = sweep_address
                assert 'local_state' not in state
                self.config = {}
   DIR diff --git a/electrum/lnsweep.py b/electrum/lnsweep.py
       t@@ -16,7 +16,7 @@ from .lnutil import (make_commitment_output_to_remote_address, make_commitment_o
                             RevocationStore, extract_ctn_from_tx_and_chan, UnableToDeriveSecret, SENT, RECEIVED,
                             map_htlcs_to_ctx_output_idxs, Direction)
        from .transaction import Transaction, TxOutput, construct_witness
       -from .simple_config import estimate_fee
       +from .simple_config import SimpleConfig
        from .logging import get_logger
        
        if TYPE_CHECKING:
       t@@ -61,7 +61,8 @@ def create_sweeptxs_for_watchtower(chan: 'Channel', ctx: Transaction, per_commit
                    output_idx=output_idx,
                    witness_script=witness_script,
                    privkey=other_revocation_privkey,
       -            is_revocation=True)
       +            is_revocation=True,
       +            config=chan.lnworker.config)
                if sweep_tx:
                    txs.append(sweep_tx)
            # HTLCs
       t@@ -80,7 +81,8 @@ def create_sweeptxs_for_watchtower(chan: 'Channel', ctx: Transaction, per_commit
                    htlctx_witness_script=htlc_tx_witness_script,
                    sweep_address=sweep_address,
                    privkey=other_revocation_privkey,
       -            is_revocation=True)
       +            is_revocation=True,
       +            config=chan.lnworker.config)
        
            ctn = extract_ctn_from_tx_and_chan(ctx, chan)
            htlc_to_ctx_output_idx_map = map_htlcs_to_ctx_output_idxs(chan=chan,
       t@@ -121,7 +123,8 @@ def create_sweeptx_for_their_revoked_ctx(chan: 'Channel', ctx: Transaction, per_
                    output_idx=output_idx,
                    witness_script=witness_script,
                    privkey=other_revocation_privkey,
       -            is_revocation=True)
       +            is_revocation=True,
       +            config=chan.lnworker.config)
                return sweep_tx
            return None
        
       t@@ -155,7 +158,8 @@ def create_sweeptx_for_their_revoked_htlc(chan: 'Channel', ctx: Transaction, htl
                output_idx=0,
                witness_script=witness_script,
                privkey=other_revocation_privkey,
       -        is_revocation=True)
       +        is_revocation=True,
       +        config=chan.lnworker.config)
        
            return SweepInfo(name='redeem_htlc2',
                             csv_delay=0,
       t@@ -213,7 +217,8 @@ def create_sweeptxs_for_our_ctx(*, chan: 'Channel', ctx: Transaction,
                    witness_script=to_local_witness_script,
                    privkey=our_localdelayed_privkey.get_secret_bytes(),
                    is_revocation=False,
       -            to_self_delay=to_self_delay)
       +            to_self_delay=to_self_delay,
       +            config=chan.lnworker.config)
                prevout = ctx.txid() + ':%d'%output_idx
                txs[prevout] = SweepInfo(name='our_ctx_to_local',
                                         csv_delay=to_self_delay,
       t@@ -246,7 +251,8 @@ def create_sweeptxs_for_our_ctx(*, chan: 'Channel', ctx: Transaction,
                    htlctx_witness_script=htlctx_witness_script,
                    sweep_address=sweep_address,
                    privkey=our_localdelayed_privkey.get_secret_bytes(),
       -            is_revocation=False)
       +            is_revocation=False,
       +            config=chan.lnworker.config)
                # side effect
                txs[htlc_tx.prevout(0)] = SweepInfo(name='first-stage-htlc',
                                                    csv_delay=0,
       t@@ -352,7 +358,8 @@ def create_sweeptxs_for_their_ctx(*, chan: 'Channel', ctx: Transaction,
                    sweep_address=sweep_address,
                    ctx=ctx,
                    output_idx=output_idx,
       -            our_payment_privkey=our_payment_privkey)
       +            our_payment_privkey=our_payment_privkey,
       +            config=chan.lnworker.config)
                txs[prevout] = SweepInfo(name='their_ctx_to_remote',
                                         csv_delay=0,
                                         cltv_expiry=0,
       t@@ -386,7 +393,8 @@ def create_sweeptxs_for_their_ctx(*, chan: 'Channel', ctx: Transaction,
                    output_idx=ctx_output_idx,
                    privkey=our_revocation_privkey if is_revocation else our_htlc_privkey.get_secret_bytes(),
                    is_revocation=is_revocation,
       -            cltv_expiry=cltv_expiry)
       +            cltv_expiry=cltv_expiry,
       +            config=chan.lnworker.config)
                txs[prevout] = SweepInfo(name=f'their_ctx_htlc_{ctx_output_idx}',
                                         csv_delay=0,
                                         cltv_expiry=cltv_expiry,
       t@@ -432,7 +440,7 @@ def create_htlctx_that_spends_from_our_ctx(chan: 'Channel', our_pcp: bytes,
        def create_sweeptx_their_ctx_htlc(ctx: Transaction, witness_script: bytes, sweep_address: str,
                                          preimage: Optional[bytes], output_idx: int,
                                          privkey: bytes, is_revocation: bool,
       -                                  cltv_expiry: int) -> Optional[Transaction]:
       +                                  cltv_expiry: int, config: SimpleConfig) -> Optional[Transaction]:
            assert type(cltv_expiry) is int
            preimage = preimage or b''  # preimage is required iff (not is_revocation and htlc is offered)
            val = ctx.outputs()[output_idx].value
       t@@ -448,7 +456,7 @@ def create_sweeptx_their_ctx_htlc(ctx: Transaction, witness_script: bytes, sweep
                'preimage_script': bh2u(witness_script),
            }]
            tx_size_bytes = 200  # TODO (depends on offered/received and is_revocation)
       -    fee = estimate_fee(tx_size_bytes)
       +    fee = config.estimate_fee(tx_size_bytes, allow_fallback_to_static_rates=True)
            outvalue = val - fee
            if outvalue <= dust_threshold(): return None
            sweep_outputs = [TxOutput(TYPE_ADDRESS, sweep_address, outvalue)]
       t@@ -465,7 +473,8 @@ def create_sweeptx_their_ctx_htlc(ctx: Transaction, witness_script: bytes, sweep
        
        
        def create_sweeptx_their_ctx_to_remote(sweep_address: str, ctx: Transaction, output_idx: int,
       -                                       our_payment_privkey: ecc.ECPrivkey) -> Optional[Transaction]:
       +                                       our_payment_privkey: ecc.ECPrivkey,
       +                                       config: SimpleConfig) -> Optional[Transaction]:
            our_payment_pubkey = our_payment_privkey.get_public_key_hex(compressed=True)
            val = ctx.outputs()[output_idx].value
            sweep_inputs = [{
       t@@ -479,7 +488,7 @@ def create_sweeptx_their_ctx_to_remote(sweep_address: str, ctx: Transaction, out
                'signatures': [None],
            }]
            tx_size_bytes = 110  # approx size of p2wpkh->p2wpkh
       -    fee = estimate_fee(tx_size_bytes)
       +    fee = config.estimate_fee(tx_size_bytes, allow_fallback_to_static_rates=True)
            outvalue = val - fee
            if outvalue <= dust_threshold(): return None
            sweep_outputs = [TxOutput(TYPE_ADDRESS, sweep_address, outvalue)]
       t@@ -491,8 +500,8 @@ def create_sweeptx_their_ctx_to_remote(sweep_address: str, ctx: Transaction, out
            return sweep_tx
        
        
       -def create_sweeptx_ctx_to_local(sweep_address: str, ctx: Transaction, output_idx: int, witness_script: str,
       -                                privkey: bytes, is_revocation: bool,
       +def create_sweeptx_ctx_to_local(*, sweep_address: str, ctx: Transaction, output_idx: int, witness_script: str,
       +                                privkey: bytes, is_revocation: bool, config: SimpleConfig,
                                        to_self_delay: int=None) -> Optional[Transaction]:
            """Create a txn that sweeps the 'to_local' output of a commitment
            transaction into our wallet.
       t@@ -516,7 +525,7 @@ def create_sweeptx_ctx_to_local(sweep_address: str, ctx: Transaction, output_idx
                assert isinstance(to_self_delay, int)
                sweep_inputs[0]['sequence'] = to_self_delay
            tx_size_bytes = 121  # approx size of to_local -> p2wpkh
       -    fee = estimate_fee(tx_size_bytes)
       +    fee = config.estimate_fee(tx_size_bytes, allow_fallback_to_static_rates=True)
            outvalue = val - fee
            if outvalue <= dust_threshold():
                return None
       t@@ -530,7 +539,8 @@ def create_sweeptx_ctx_to_local(sweep_address: str, ctx: Transaction, output_idx
        
        def create_sweeptx_that_spends_htlctx_that_spends_htlc_in_ctx(*,
                htlc_tx: Transaction, htlctx_witness_script: bytes, sweep_address: str,
       -        privkey: bytes, is_revocation: bool, to_self_delay: int) -> Optional[Transaction]:
       +        privkey: bytes, is_revocation: bool, to_self_delay: int,
       +        config: SimpleConfig) -> Optional[Transaction]:
            val = htlc_tx.outputs()[0].value
            sweep_inputs = [{
                'scriptSig': '',
       t@@ -547,7 +557,7 @@ def create_sweeptx_that_spends_htlctx_that_spends_htlc_in_ctx(*,
                assert isinstance(to_self_delay, int)
                sweep_inputs[0]['sequence'] = to_self_delay
            tx_size_bytes = 200  # TODO
       -    fee = estimate_fee(tx_size_bytes)
       +    fee = config.estimate_fee(tx_size_bytes, allow_fallback_to_static_rates=True)
            outvalue = val - fee
            if outvalue <= dust_threshold(): return None
            sweep_outputs = [TxOutput(TYPE_ADDRESS, sweep_address, outvalue)]
   DIR diff --git a/electrum/lnworker.py b/electrum/lnworker.py
       t@@ -312,6 +312,7 @@ class LNWallet(LNWorker):
                Logger.__init__(self)
                self.wallet = wallet
                self.storage = wallet.storage
       +        self.config = wallet.config
                xprv = self.storage.get('lightning_privkey2')
                if xprv is None:
                    # TODO derive this deterministically from wallet.keystore at keystore generation time
       t@@ -384,7 +385,6 @@ class LNWallet(LNWorker):
                        await watchtower.add_sweep_tx(outpoint, ctn, tx.prevout(0), str(tx))
        
            def start_network(self, network: 'Network'):
       -        self.config = network.config
                self.lnwatcher = LNWatcher(network)
                self.lnwatcher.start_network(network)
                self.network = network
   DIR diff --git a/electrum/plugins/trustedcoin/trustedcoin.py b/electrum/plugins/trustedcoin/trustedcoin.py
       t@@ -261,9 +261,9 @@ class Wallet_2fa(Multisig_Wallet):
        
            wallet_type = '2fa'
        
       -    def __init__(self, storage):
       +    def __init__(self, storage, *, config):
                self.m, self.n = 2, 3
       -        Deterministic_Wallet.__init__(self, storage)
       +        Deterministic_Wallet.__init__(self, storage, config=config)
                self.is_billing = False
                self.billing_info = None
                self._load_billing_addresses()
   DIR diff --git a/electrum/scripts/quick_start.py b/electrum/scripts/quick_start.py
       t@@ -18,15 +18,15 @@ assert network.asyncio_loop.is_running()
        wallet_dir = os.path.dirname(config.get_wallet_path())
        wallet_path = os.path.join(wallet_dir, "test_wallet")
        if not os.path.exists(wallet_path):
       -    create_new_wallet(path=wallet_path, segwit=True)
       +    create_new_wallet(path=wallet_path, config=config)
        
        # open wallet
        storage = WalletStorage(wallet_path)
       -wallet = Wallet(storage)
       +wallet = Wallet(storage, config=config)
        wallet.start_network(network)
        
        # you can use ~CLI commands by accessing command_runner
       -command_runner = Commands(config, wallet=None, network=network)
       +command_runner = Commands(config=config, daemon=daemon, network=network)
        command_runner.wallet = wallet
        print("balance", command_runner.getbalance())
        print("addr",    command_runner.getunusedaddress())
   DIR diff --git a/electrum/simple_config.py b/electrum/simple_config.py
       t@@ -36,27 +36,9 @@ FEERATE_REGTEST_HARDCODED = 180000  # for eclair compat
        _logger = get_logger(__name__)
        
        
       -def estimate_fee(tx_size_bytes: int) -> int:
       -    def use_fallback_feerate():
       -        fee_per_kb = FEERATE_FALLBACK_STATIC_FEE
       -        fee = SimpleConfig.estimate_fee_for_feerate(fee_per_kb, tx_size_bytes)
       -        return fee
       -
       -    global _INSTANCE
       -    if not _INSTANCE:
       -        return use_fallback_feerate()
       -    try:
       -        return _INSTANCE.estimate_fee(tx_size_bytes)
       -    except NoDynamicFeeEstimates:
       -        return use_fallback_feerate()
       -
        FINAL_CONFIG_VERSION = 3
        
        
       -_INSTANCE = None
       -_ENFORCE_SIMPLECONFIG_SINGLETON = True  # disabled in tests
       -
       -
        class SimpleConfig(Logger):
            """
            The SimpleConfig class is responsible for handling operations involving
       t@@ -70,13 +52,6 @@ class SimpleConfig(Logger):
        
            def __init__(self, options=None, read_user_config_function=None,
                         read_user_dir_function=None):
       -        # note: To be honest, singletons are bad design... :/
       -        #       However currently we somewhat rely on config being one.
       -        global _INSTANCE
       -        if _ENFORCE_SIMPLECONFIG_SINGLETON:
       -            assert _INSTANCE is None, "SimpleConfig is a singleton!"
       -        _INSTANCE = self
       -
                if options is None:
                    options = {}
        
       t@@ -122,10 +97,6 @@ class SimpleConfig(Logger):
                if self.requires_upgrade():
                    self.upgrade()
        
       -    @staticmethod
       -    def get_instance() -> Optional["SimpleConfig"]:
       -        return _INSTANCE
       -
            def electrum_path(self):
                # Read electrum_path from command line
                # Otherwise use the user's default data directory.
       t@@ -549,10 +520,14 @@ class SimpleConfig(Logger):
                fee_per_kb = self.fee_per_kb()
                return fee_per_kb / 1000 if fee_per_kb is not None else None
        
       -    def estimate_fee(self, size: Union[int, float, Decimal]) -> int:
       +    def estimate_fee(self, size: Union[int, float, Decimal], *,
       +                     allow_fallback_to_static_rates: bool = False) -> int:
                fee_per_kb = self.fee_per_kb()
                if fee_per_kb is None:
       -            raise NoDynamicFeeEstimates()
       +            if allow_fallback_to_static_rates:
       +                fee_per_kb = FEERATE_FALLBACK_STATIC_FEE
       +            else:
       +                raise NoDynamicFeeEstimates()
                return self.estimate_fee_for_feerate(fee_per_kb, size)
        
            @classmethod
   DIR diff --git a/electrum/sql_db.py b/electrum/sql_db.py
       t@@ -54,4 +54,5 @@ class SqlDB(Logger):
                            self.conn.commit()
                # write
                self.conn.commit()
       +        self.conn.close()
                self.logger.info("SQL thread terminated")
   DIR diff --git a/electrum/tests/__init__.py b/electrum/tests/__init__.py
       t@@ -1,8 +1,9 @@
        import unittest
        import threading
       +import tempfile
       +import shutil
        
        from electrum import constants
       -from electrum import simple_config
        
        
        # Set this locally to make the test suite run faster.
       t@@ -12,10 +13,7 @@ from electrum import simple_config
        FAST_TESTS = False
        
        
       -simple_config._ENFORCE_SIMPLECONFIG_SINGLETON = False
       -
       -
       -# some unit tests are modifying globals; sorry.
       +# some unit tests are modifying globals...
        class SequentialTestCase(unittest.TestCase):
        
            test_lock = threading.Lock()
       t@@ -29,7 +27,19 @@ class SequentialTestCase(unittest.TestCase):
                self.test_lock.release()
        
        
       -class TestCaseForTestnet(SequentialTestCase):
       +class ElectrumTestCase(SequentialTestCase):
       +    """Base class for our unit tests."""
       +
       +    def setUp(self):
       +        super().setUpClass()
       +        self.electrum_path = tempfile.mkdtemp()
       +
       +    def tearDown(self):
       +        super().tearDownClass()
       +        shutil.rmtree(self.electrum_path)
       +
       +
       +class TestCaseForTestnet(ElectrumTestCase):
        
            @classmethod
            def setUpClass(cls):
   DIR diff --git a/electrum/tests/test_bitcoin.py b/electrum/tests/test_bitcoin.py
       t@@ -22,7 +22,7 @@ from electrum.keystore import xtype_from_derivation
        
        from electrum import ecc_fast
        
       -from . import SequentialTestCase
       +from . import ElectrumTestCase
        from . import TestCaseForTestnet
        from . import FAST_TESTS
        
       t@@ -84,7 +84,7 @@ def needs_test_with_all_aes_implementations(func):
            return run_test
        
        
       -class Test_bitcoin(SequentialTestCase):
       +class Test_bitcoin(ElectrumTestCase):
        
            def test_libsecp256k1_is_available(self):
                # we want the unit testing framework to test with libsecp256k1 available.
       t@@ -393,7 +393,7 @@ class Test_bitcoin_testnet(TestCaseForTestnet):
                self.assertEqual(address_to_script('2NE4ZdmxFmUgwu5wtfoN2gVniyMgRDYq1kk'), 'a914e4567743d378957cd2ee7072da74b1203c1a7a0b87')
        
        
       -class Test_xprv_xpub(SequentialTestCase):
       +class Test_xprv_xpub(ElectrumTestCase):
        
            xprv_xpub = (
                # Taken from test vectors in https://en.bitcoin.it/wiki/BIP_0032_TestVectors
       t@@ -585,7 +585,7 @@ class Test_xprv_xpub_testnet(TestCaseForTestnet):
                    self.assertTrue(xkey_b58.startswith(xpub_headers_b58[xtype]))
        
        
       -class Test_keyImport(SequentialTestCase):
       +class Test_keyImport(ElectrumTestCase):
        
            priv_pub_addr = (
                   {'priv': 'KzMFjMC2MPadjvX5Cd7b8AKKjjpBSoRKUTpoAtN6B3J9ezWYyXS6',
       t@@ -751,7 +751,7 @@ class Test_keyImport(SequentialTestCase):
                                   raise_on_error=True)
        
        
       -class TestBaseEncode(SequentialTestCase):
       +class TestBaseEncode(ElectrumTestCase):
        
            def test_base43(self):
                tx_hex = "020000000001021cd0e96f9ca202e017ca3465e3c13373c0df3a4cdd91c1fd02ea42a1a65d2a410000000000fdffffff757da7cf8322e5063785e2d8ada74702d2648fa2add2d533ba83c52eb110df690200000000fdffffff02d07e010000000000160014b544c86eaf95e3bb3b6d2cabb12ab40fc59cad9ca086010000000000232102ce0d066fbfcf150a5a1bbc4f312cd2eb080e8d8a47e5f2ce1a63b23215e54fb5ac02483045022100a9856bf10a950810abceeabc9a86e6ba533e130686e3d7863971b9377e7c658a0220288a69ef2b958a7c2ecfa376841d4a13817ed24fa9a0e0a6b9cb48e6439794c701210324e291735f83ff8de47301b12034950b80fa4724926a34d67e413d8ff8817c53024830450221008f885978f7af746679200ed55fe2e86c1303620824721f95cc41eb7965a3dfcf02207872082ac4a3c433d41a203e6d685a459e70e551904904711626ac899238c20a0121023d4c9deae1aacf3f822dd97a28deaec7d4e4ff97be746d124a63d20e582f5b290a971600"
   DIR diff --git a/electrum/tests/test_blockchain.py b/electrum/tests/test_blockchain.py
       t@@ -7,10 +7,10 @@ from electrum.simple_config import SimpleConfig
        from electrum.blockchain import Blockchain, deserialize_header, hash_header
        from electrum.util import bh2u, bfh, make_dir
        
       -from . import SequentialTestCase
       +from . import ElectrumTestCase
        
        
       -class TestBlockchain(SequentialTestCase):
       +class TestBlockchain(ElectrumTestCase):
        
            HEADERS = {
                'A': deserialize_header(bfh("0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f2002000000"), 0),
       t@@ -57,15 +57,11 @@ class TestBlockchain(SequentialTestCase):
        
            def setUp(self):
                super().setUp()
       -        self.data_dir = tempfile.mkdtemp()
       +        self.data_dir = self.electrum_path
                make_dir(os.path.join(self.data_dir, 'forks'))
                self.config = SimpleConfig({'electrum_path': self.data_dir})
                blockchain.blockchains = {}
        
       -    def tearDown(self):
       -        super().tearDown()
       -        shutil.rmtree(self.data_dir)
       -
            def _append_header(self, chain: Blockchain, header: dict):
                self.assertTrue(chain.can_connect(header))
                chain.save_header(header)
       t@@ -341,7 +337,7 @@ class TestBlockchain(SequentialTestCase):
                    self.assertTrue(all([b.can_connect(b.read_header(i), False) for i in range(b.height())]))
        
        
       -class TestVerifyHeader(SequentialTestCase):
       +class TestVerifyHeader(ElectrumTestCase):
        
            # Data for Bitcoin block header #100.
            valid_header = "0100000095194b8567fe2e8bbda931afd01a7acd399b9325cb54683e64129bcd00000000660802c98f18fd34fd16d61c63cf447568370124ac5f3be626c2e1c3c9f0052d19a76949ffff001d33f3c25d"
   DIR diff --git a/electrum/tests/test_bolt11.py b/electrum/tests/test_bolt11.py
       t@@ -1,17 +1,22 @@
        from hashlib import sha256
       -from electrum.lnaddr import shorten_amount, unshorten_amount, LnAddr, lnencode, lndecode, u5_to_bitarray, bitarray_to_u5
        from decimal import Decimal
        from binascii import unhexlify, hexlify
       -from electrum.segwit_addr import bech32_encode, bech32_decode
        import pprint
        import unittest
        
       +from electrum.lnaddr import shorten_amount, unshorten_amount, LnAddr, lnencode, lndecode, u5_to_bitarray, bitarray_to_u5
       +from electrum.segwit_addr import bech32_encode, bech32_decode
       +
       +from . import ElectrumTestCase
       +
       +
        RHASH=unhexlify('0001020304050607080900010203040506070809000102030405060708090102')
        CONVERSION_RATE=1200
        PRIVKEY=unhexlify('e126f68f7eafcc8b74f54d269fe206be715000f94dac067d1c04a8ca3b2db734')
        PUBKEY=unhexlify('03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad')
        
       -class TestBolt11(unittest.TestCase):
       +
       +class TestBolt11(ElectrumTestCase):
            def test_shorten_amount(self):
                tests = {
                    Decimal(10)/10**12: '10p',
   DIR diff --git a/electrum/tests/test_commands.py b/electrum/tests/test_commands.py
       t@@ -6,15 +6,17 @@ from electrum.util import create_and_start_event_loop
        from electrum.commands import Commands, eval_bool
        from electrum import storage
        from electrum.wallet import restore_wallet_from_text
       +from electrum.simple_config import SimpleConfig
        
       -from . import TestCaseForTestnet
       +from . import TestCaseForTestnet, ElectrumTestCase
        
        
       -class TestCommands(unittest.TestCase):
       +class TestCommands(ElectrumTestCase):
        
            def setUp(self):
                super().setUp()
                self.asyncio_loop, self._stop_loop, self._loop_thread = create_and_start_event_loop()
       +        self.config = SimpleConfig({'electrum_path': self.electrum_path})
        
            def tearDown(self):
                super().tearDown()
       t@@ -56,7 +58,7 @@ class TestCommands(unittest.TestCase):
                self.assertTrue(eval_bool("1"))
        
            def test_convert_xkey(self):
       -        cmds = Commands(config=None)
       +        cmds = Commands(config=self.config)
                xpubs = {
                    ("xpub6CCWFbvCbqF92kGwm9nV7t7RvVoQUKaq5USMdyVP6jvv1NgN52KAX6NNYCeE8Ca7JQC4K5tZcnQrubQcjJ6iixfPs4pwAQJAQgTt6hBjg11", "standard"),
                    ("ypub6X2mZGb7kWnct3U4bWa7KyCw6TwrQwaKzaxaRNPGUkJo4UVbKgUj9A2WZQbp87E2i3Js4ZV85SmQnt2BSzWjXCLzjQXMkK7egQXXVHT4eKn", "p2wpkh-p2sh"),
       t@@ -78,8 +80,9 @@ class TestCommands(unittest.TestCase):
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_encrypt_decrypt(self, mock_write):
                wallet = restore_wallet_from_text('p2wpkh:L4rYY5QpfN6wJEF4SEKDpcGhTPnCe9zcGs6hiSnhpprZqVywFifN',
       -                                          path='if_this_exists_mocking_failed_648151893')['wallet']
       -        cmds = Commands(config=None)
       +                                          path='if_this_exists_mocking_failed_648151893',
       +                                          config=self.config)['wallet']
       +        cmds = Commands(config=self.config)
                cleartext = "asdasd this is the message"
                pubkey = "021f110909ded653828a254515b58498a6bafc96799fb0851554463ed44ca7d9da"
                ciphertext = cmds._run('encrypt', (pubkey, cleartext))
       t@@ -88,8 +91,9 @@ class TestCommands(unittest.TestCase):
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_export_private_key_imported(self, mock_write):
                wallet = restore_wallet_from_text('p2wpkh:L4rYY5QpfN6wJEF4SEKDpcGhTPnCe9zcGs6hiSnhpprZqVywFifN p2wpkh:L4jkdiXszG26SUYvwwJhzGwg37H2nLhrbip7u6crmgNeJysv5FHL',
       -                                          path='if_this_exists_mocking_failed_648151893')['wallet']
       -        cmds = Commands(config=None)
       +                                          path='if_this_exists_mocking_failed_648151893',
       +                                          config=self.config)['wallet']
       +        cmds = Commands(config=self.config)
                # single address tests
                with self.assertRaises(Exception):
                    cmds._run('getprivatekeys', ("asdasd",), wallet=wallet)  # invalid addr, though might raise "not in wallet"
       t@@ -107,8 +111,9 @@ class TestCommands(unittest.TestCase):
            def test_export_private_key_deterministic(self, mock_write):
                wallet = restore_wallet_from_text('bitter grass shiver impose acquire brush forget axis eager alone wine silver',
                                                  gap_limit=2,
       -                                          path='if_this_exists_mocking_failed_648151893')['wallet']
       -        cmds = Commands(config=None)
       +                                          path='if_this_exists_mocking_failed_648151893',
       +                                          config=self.config)['wallet']
       +        cmds = Commands(config=self.config)
                # single address tests
                with self.assertRaises(Exception):
                    cmds._run('getprivatekeys', ("asdasd",), wallet=wallet)  # invalid addr, though might raise "not in wallet"
       t@@ -128,6 +133,7 @@ class TestCommandsTestnet(TestCaseForTestnet):
            def setUp(self):
                super().setUp()
                self.asyncio_loop, self._stop_loop, self._loop_thread = create_and_start_event_loop()
       +        self.config = SimpleConfig({'electrum_path': self.electrum_path})
        
            def tearDown(self):
                super().tearDown()
       t@@ -135,7 +141,7 @@ class TestCommandsTestnet(TestCaseForTestnet):
                self._loop_thread.join(timeout=1)
        
            def test_convert_xkey(self):
       -        cmds = Commands(config=None)
       +        cmds = Commands(config=self.config)
                xpubs = {
                    ("tpubD8p5qNfjczgTGbh9qgNxsbFgyhv8GgfVkmp3L88qtRm5ibUYiDVCrn6WYfnGey5XVVw6Bc5QNQUZW5B4jFQsHjmaenvkFUgWtKtgj5AdPm9", "standard"),
                    ("upub59wfQ8qJTg6ZSuvwtR313Qdp8gP8TSBwTof5dPQ3QVsYp1N9t29Rr9TGF1pj8kAXUg3mKbmrTKasA2qmBJKb1bGUzB6ApDZpVC7LoHhyvBo", "p2wpkh-p2sh"),
   DIR diff --git a/electrum/tests/test_dnssec.py b/electrum/tests/test_dnssec.py
       t@@ -2,11 +2,11 @@ import dns
        
        from electrum import dnssec
        
       -from . import SequentialTestCase
       +from . import ElectrumTestCase
        from .test_bitcoin import needs_test_with_all_ecc_implementations
        
        
       -class TestDnsSec(SequentialTestCase):
       +class TestDnsSec(ElectrumTestCase):
        
            @needs_test_with_all_ecc_implementations
            def test_python_validate_rrsig_ecdsa(self):
   DIR diff --git a/electrum/tests/test_lnchannel.py b/electrum/tests/test_lnchannel.py
       t@@ -35,6 +35,9 @@ from electrum.lnutil import FeeUpdate
        from electrum.ecc import sig_string_from_der_sig
        from electrum.logging import console_stderr_handler
        
       +from . import ElectrumTestCase
       +
       +
        one_bitcoin_in_msat = bitcoin.COIN * 1000
        
        def create_channel_state(funding_txid, funding_index, funding_sat, is_initiator, local_amount, remote_amount, privkeys, other_pubkeys, seed, cur, nex, other_node_id, l_dust, r_dust, l_csv, r_csv):
       t@@ -160,7 +163,7 @@ def create_test_channels(feerate=6000, local=None, remote=None):
        
            return alice, bob
        
       -class TestFee(unittest.TestCase):
       +class TestFee(ElectrumTestCase):
            """
            test
            https://github.com/lightningnetwork/lightning-rfc/blob/e0c436bd7a3ed6a028e1cb472908224658a14eca/03-transactions.md#requirements-2
       t@@ -169,7 +172,7 @@ class TestFee(unittest.TestCase):
                alice_channel, bob_channel = create_test_channels(253, 10000000000, 5000000000)
                self.assertIn(9999817, [x[2] for x in alice_channel.get_latest_commitment(LOCAL).outputs()])
        
       -class TestChannel(unittest.TestCase):
       +class TestChannel(ElectrumTestCase):
            maxDiff = 999
        
            def assertOutputExistsByValue(self, tx, amt_sat):
       t@@ -181,9 +184,11 @@ class TestChannel(unittest.TestCase):
        
            @classmethod
            def setUpClass(cls):
       +        super().setUpClass()
                console_stderr_handler.setLevel(logging.DEBUG)
        
            def setUp(self):
       +        super().setUp()
                # Create a test channel which will be used for the duration of this
                # unittest. The channel will be funded evenly with Alice having 5 BTC,
                # and Bob having 5 BTC.
       t@@ -607,7 +612,7 @@ class TestChannel(unittest.TestCase):
                self.assertIn('Not enough local balance', cm.exception.args[0])
        
        
       -class TestAvailableToSpend(unittest.TestCase):
       +class TestAvailableToSpend(ElectrumTestCase):
            def test_DesyncHTLCs(self):
                alice_channel, bob_channel = create_test_channels()
        
       t@@ -645,7 +650,7 @@ class TestAvailableToSpend(unittest.TestCase):
                force_state_transition(alice_channel, bob_channel)
                alice_channel.add_htlc(htlc_dict)
        
       -class TestChanReserve(unittest.TestCase):
       +class TestChanReserve(ElectrumTestCase):
            def setUp(self):
                alice_channel, bob_channel = create_test_channels()
                alice_min_reserve = int(.5 * one_bitcoin_in_msat // 1000)
       t@@ -778,7 +783,7 @@ class TestChanReserve(unittest.TestCase):
                self.assertEqual(self.alice_channel.available_to_spend(REMOTE), amt2)
                self.assertEqual(self.bob_channel.available_to_spend(LOCAL), amt2)
        
       -class TestDust(unittest.TestCase):
       +class TestDust(ElectrumTestCase):
            def test_DustLimit(self):
                alice_channel, bob_channel = create_test_channels()
        
   DIR diff --git a/electrum/tests/test_lnhtlc.py b/electrum/tests/test_lnhtlc.py
       t@@ -1,14 +1,18 @@
        from pprint import pprint
        import unittest
       +from typing import NamedTuple
       +
        from electrum.lnutil import RECEIVED, LOCAL, REMOTE, SENT, HTLCOwner, Direction
        from electrum.lnhtlc import HTLCManager
       -from typing import NamedTuple
       +
       +from . import ElectrumTestCase
       +
        
        class H(NamedTuple):
            owner : str
            htlc_id : int
        
       -class TestHTLCManager(unittest.TestCase):
       +class TestHTLCManager(ElectrumTestCase):
            def test_adding_htlcs_race(self):
                A = HTLCManager()
                B = HTLCManager()
   DIR diff --git a/electrum/tests/test_lnpeer.py b/electrum/tests/test_lnpeer.py
       t@@ -24,7 +24,7 @@ from electrum.logging import console_stderr_handler
        from electrum.lnworker import InvoiceInfo, RECEIVED, PR_UNPAID
        
        from .test_lnchannel import create_test_channels
       -from . import SequentialTestCase
       +from . import ElectrumTestCase
        
        def keypair():
            priv = ECPrivkey.generate_random_key().get_secret_bytes()
       t@@ -173,7 +173,7 @@ def transport_pair(name1, name2):
            t2.other_mock_transport = t1
            return t1, t2
        
       -class TestPeer(SequentialTestCase):
       +class TestPeer(ElectrumTestCase):
        
            @classmethod
            def setUpClass(cls):
   DIR diff --git a/electrum/tests/test_lnrouter.py b/electrum/tests/test_lnrouter.py
       t@@ -29,25 +29,15 @@ class Test_LNRouter(TestCaseForTestnet):
            #    assert witness_bytes == b"", witness_bytes
            #    return res
        
       -    @classmethod
       -    def setUpClass(cls):
       -        super().setUpClass()
       -        cls.electrum_path = tempfile.mkdtemp()
       -        cls.config = SimpleConfig({'electrum_path': cls.electrum_path})
       -
            def setUp(self):
                super().setUp()
                self.asyncio_loop, self._stop_loop, self._loop_thread = create_and_start_event_loop()
       -
       -    @classmethod
       -    def tearDownClass(cls):
       -        super().tearDownClass()
       -        shutil.rmtree(cls.electrum_path)
       +        self.config = SimpleConfig({'electrum_path': self.electrum_path})
        
            def tearDown(self):
       -        super().tearDown()
                self.asyncio_loop.call_soon_threadsafe(self._stop_loop.set_result, 1)
                self._loop_thread.join(timeout=1)
       +        super().tearDown()
        
            def test_find_path_for_payment(self):
                class fake_network:
       t@@ -115,7 +105,10 @@ class Test_LNRouter(TestCaseForTestnet):
                self.assertEqual(route[0].node_id, start_node)
                self.assertEqual(route[0].short_channel_id, bfh('0000000000000003'))
        
       -
       +        # need to duplicate tear_down here, as we also need to wait for the sql thread to stop
       +        self.asyncio_loop.call_soon_threadsafe(self._stop_loop.set_result, 1)
       +        self._loop_thread.join(timeout=1)
       +        cdb.sql_thread.join(timeout=1)
        
            def test_new_onion_packet(self):
                # test vector from bolt-04
   DIR diff --git a/electrum/tests/test_lntransport.py b/electrum/tests/test_lntransport.py
       t@@ -1,10 +1,14 @@
       -from electrum.ecc import ECPrivkey
        import asyncio
       +
       +from electrum.ecc import ECPrivkey
        from electrum.lnutil import LNPeerAddr
        from electrum.lntransport import LNResponderTransport, LNTransport
       -from unittest import TestCase
        
       -class TestLNTransport(TestCase):
       +from . import ElectrumTestCase
       +
       +
       +class TestLNTransport(ElectrumTestCase):
       +
            def test_responder(self):
                # local static
                ls_priv=bytes.fromhex('2121212121212121212121212121212121212121212121212121212121212121')
       t@@ -32,6 +36,7 @@ class TestLNTransport(TestCase):
                            return bytes.fromhex('00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba')
                transport = LNResponderTransport(ls_priv, Reader(), Writer())
                asyncio.get_event_loop().run_until_complete(transport.handshake(epriv=e_priv))
       +
            def test_loop(self):
                l = asyncio.get_event_loop()
                responder_shaked = asyncio.Event()
   DIR diff --git a/electrum/tests/test_lnutil.py b/electrum/tests/test_lnutil.py
       t@@ -1,5 +1,6 @@
        import unittest
        import json
       +
        from electrum import bitcoin
        from electrum.lnutil import (RevocationStore, get_per_commitment_secret_from_seed, make_offered_htlc,
                                     make_received_htlc, make_commitment, make_htlc_tx_witness, make_htlc_tx_output,
       t@@ -10,6 +11,9 @@ from electrum.lnutil import (RevocationStore, get_per_commitment_secret_from_see
        from electrum.util import bh2u, bfh
        from electrum.transaction import Transaction
        
       +from . import ElectrumTestCase
       +
       +
        funding_tx_id = '8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be'
        funding_output_index = 0
        funding_amount_satoshi = 10000000
       t@@ -30,7 +34,8 @@ local_delayedpubkey = bytes.fromhex('03fd5960528dc152014952efdb702a88f71e3c1653b
        local_revocation_pubkey = bytes.fromhex('0212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b19')
        # funding wscript = 5221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae
        
       -class TestLNUtil(unittest.TestCase):
       +
       +class TestLNUtil(ElectrumTestCase):
            def test_shachain_store(self):
                tests = [
                    {
   DIR diff --git a/electrum/tests/test_mnemonic.py b/electrum/tests/test_mnemonic.py
       t@@ -7,7 +7,7 @@ from electrum.util import bh2u, bfh
        from electrum.mnemonic import is_new_seed, is_old_seed, seed_type
        from electrum.version import SEED_PREFIX_SW, SEED_PREFIX
        
       -from . import SequentialTestCase
       +from . import ElectrumTestCase
        from .test_wallet_vertical import UNICODE_HORROR, UNICODE_HORROR_HEX
        
        
       t@@ -95,7 +95,7 @@ SEED_TEST_CASES = {
        }
        
        
       -class Test_NewMnemonic(SequentialTestCase):
       +class Test_NewMnemonic(ElectrumTestCase):
        
            def test_mnemonic_to_seed_basic(self):
                # note: not a valid electrum seed
       t@@ -125,7 +125,7 @@ class Test_NewMnemonic(SequentialTestCase):
                    self.assertEqual(m.mnemonic_encode(i), seed)
        
        
       -class Test_OldMnemonic(SequentialTestCase):
       +class Test_OldMnemonic(ElectrumTestCase):
        
            def test(self):
                seed = '8edad31a95e7d59f8837667510d75a4d'
       t@@ -135,7 +135,7 @@ class Test_OldMnemonic(SequentialTestCase):
                self.assertEqual(old_mnemonic.mn_decode(result), seed)
        
        
       -class Test_BIP39Checksum(SequentialTestCase):
       +class Test_BIP39Checksum(ElectrumTestCase):
        
            def test(self):
                mnemonic = u'gravity machine north sort system female filter attitude volume fold club stay feature office ecology stable narrow fog'
       t@@ -144,7 +144,7 @@ class Test_BIP39Checksum(SequentialTestCase):
                self.assertTrue(is_checksum_valid)
        
        
       -class Test_seeds(SequentialTestCase):
       +class Test_seeds(ElectrumTestCase):
            """ Test old and new seeds. """
        
            mnemonics = {
   DIR diff --git a/electrum/tests/test_network.py b/electrum/tests/test_network.py
       t@@ -9,6 +9,8 @@ from electrum.interface import Interface
        from electrum.crypto import sha256
        from electrum.util import bh2u
        
       +from . import ElectrumTestCase
       +
        
        class MockTaskGroup:
            async def spawn(self, x): return
       t@@ -36,7 +38,7 @@ class MockInterface(Interface):
                assert assert_mode in item['mock'], (assert_mode, item)
                return item
        
       -class TestNetwork(unittest.TestCase):
       +class TestNetwork(ElectrumTestCase):
        
            @classmethod
            def setUpClass(cls):
       t@@ -49,7 +51,8 @@ class TestNetwork(unittest.TestCase):
                constants.set_mainnet()
        
            def setUp(self):
       -        self.config = SimpleConfig({'electrum_path': tempfile.mkdtemp(prefix="test_network")})
       +        super().setUp()
       +        self.config = SimpleConfig({'electrum_path': self.electrum_path})
                self.interface = MockInterface(self.config)
        
            def test_fork_noconflict(self):
   DIR diff --git a/electrum/tests/test_revealer.py b/electrum/tests/test_revealer.py
       t@@ -1,9 +1,9 @@
        from electrum.plugins.revealer.revealer import RevealerPlugin
        
       -from . import SequentialTestCase
       +from . import ElectrumTestCase
        
        
       -class TestRevealer(SequentialTestCase):
       +class TestRevealer(ElectrumTestCase):
        
            def test_version_0_noisemap(self):
                versioned_seed = RevealerPlugin.get_versioned_seed_from_user_input('03b0c557d6d0d4308a3393851d78bd8c7861')
   DIR diff --git a/electrum/tests/test_simple_config.py b/electrum/tests/test_simple_config.py
       t@@ -7,10 +7,10 @@ import shutil
        from io import StringIO
        from electrum.simple_config import (SimpleConfig, read_user_config)
        
       -from . import SequentialTestCase
       +from . import ElectrumTestCase
        
        
       -class Test_SimpleConfig(SequentialTestCase):
       +class Test_SimpleConfig(ElectrumTestCase):
        
            def setUp(self):
                super(Test_SimpleConfig, self).setUp()
       t@@ -147,7 +147,7 @@ class Test_SimpleConfig(SequentialTestCase):
                self.assertEqual(36495000, config.fee_to_depth(0.5))
        
        
       -class TestUserConfig(SequentialTestCase):
       +class TestUserConfig(ElectrumTestCase):
        
            def setUp(self):
                super(TestUserConfig, self).setUp()
   DIR diff --git a/electrum/tests/test_storage_upgrade.py b/electrum/tests/test_storage_upgrade.py
       t@@ -278,8 +278,8 @@ class TestStorageUpgrade(WalletTestCase):
                from electrum.plugin import Plugins
                from electrum.simple_config import SimpleConfig
        
       -        cls.electrum_path = tempfile.mkdtemp()
       -        config = SimpleConfig({'electrum_path': cls.electrum_path})
       +        cls.__electrum_path = tempfile.mkdtemp()
       +        config = SimpleConfig({'electrum_path': cls.__electrum_path})
        
                gui_name = 'cmdline'
                # TODO it's probably wasteful to load all plugins... only need Trezor
       t@@ -288,7 +288,7 @@ class TestStorageUpgrade(WalletTestCase):
            @classmethod
            def tearDownClass(cls):
                super().tearDownClass()
       -        shutil.rmtree(cls.electrum_path)
       +        shutil.rmtree(cls.__electrum_path)
        
            def _upgrade_storage(self, wallet_json, accounts=1):
                if accounts == 1:
       t@@ -326,7 +326,7 @@ class TestStorageUpgrade(WalletTestCase):
            def _sanity_check_upgraded_storage(self, storage):
                self.assertFalse(storage.requires_split())
                self.assertFalse(storage.requires_upgrade())
       -        w = Wallet(storage)
       +        w = Wallet(storage, config=self.config)
        
            @staticmethod
            def _load_storage_from_json_string(*, wallet_json, path, manual_upgrades):
   DIR diff --git a/electrum/tests/test_transaction.py b/electrum/tests/test_transaction.py
       t@@ -4,7 +4,7 @@ from electrum.bitcoin import TYPE_ADDRESS
        from electrum.keystore import xpubkey_to_address
        from electrum.util import bh2u, bfh
        
       -from . import SequentialTestCase, TestCaseForTestnet
       +from . import ElectrumTestCase, TestCaseForTestnet
        from .test_bitcoin import needs_test_with_all_ecc_implementations
        
        unsigned_blob = '45505446ff0001000000012a5c9a94fcde98f5581cd00162c60a13936ceb75389ea65bf38633b424eb4031000000005701ff4c53ff0488b21e03ef2afea18000000089689bff23e1e7fb2f161daa37270a97a3d8c2e537584b2d304ecb47b86d21fc021b010d3bd425f8cf2e04824bfdf1f1f5ff1d51fadd9a41f9e3fb8dd3403b1bfe00000000ffffffff0140420f00000000001976a914230ac37834073a42146f11ef8414ae929feaafc388ac00000000'
       t@@ -14,7 +14,7 @@ signed_segwit_blob = "01000000000101b66d722484f2db63e827ebf41d02684fed0c6550e850
        
        signed_blob_signatures = ['3046022100a82bbc57a0136751e5433f41cf000b3f1a99c6744775e76ec764fb78c54ee100022100f9e80b7de89de861dc6fb0c1429d5da72c2b6b2ee2406bc9bfb1beedd729d98501', ]
        
       -class TestBCDataStream(SequentialTestCase):
       +class TestBCDataStream(ElectrumTestCase):
        
            def test_compact_size(self):
                s = transaction.BCDataStream()
       t@@ -55,7 +55,7 @@ class TestBCDataStream(SequentialTestCase):
                self.assertEqual(s.read_bytes(4), b'r')
                self.assertEqual(s.read_bytes(1), b'')
        
       -class TestTransaction(SequentialTestCase):
       +class TestTransaction(ElectrumTestCase):
        
            @needs_test_with_all_ecc_implementations
            def test_tx_unsigned(self):
   DIR diff --git a/electrum/tests/test_util.py b/electrum/tests/test_util.py
       t@@ -3,10 +3,10 @@ from decimal import Decimal
        from electrum.util import (format_satoshis, format_fee_satoshis, parse_URI,
                                   is_hash256_str, chunks, is_ip_address, list_enabled_bits)
        
       -from . import SequentialTestCase
       +from . import ElectrumTestCase
        
        
       -class TestUtil(SequentialTestCase):
       +class TestUtil(ElectrumTestCase):
        
            def test_format_satoshis(self):
                self.assertEqual("0.00001234", format_satoshis(1234))
   DIR diff --git a/electrum/tests/test_wallet.py b/electrum/tests/test_wallet.py
       t@@ -15,8 +15,9 @@ from electrum.exchange_rate import ExchangeBase, FxThread
        from electrum.util import TxMinedInfo
        from electrum.bitcoin import COIN
        from electrum.json_db import JsonDB
       +from electrum.simple_config import SimpleConfig
        
       -from . import SequentialTestCase
       +from . import ElectrumTestCase
        
        
        class FakeSynchronizer(object):
       t@@ -28,11 +29,12 @@ class FakeSynchronizer(object):
                self.store.append(address)
        
        
       -class WalletTestCase(SequentialTestCase):
       +class WalletTestCase(ElectrumTestCase):
        
            def setUp(self):
                super(WalletTestCase, self).setUp()
                self.user_dir = tempfile.mkdtemp()
       +        self.config = SimpleConfig({'electrum_path': self.user_dir})
        
                self.wallet_path = os.path.join(self.user_dir, "somewallet")
        
       t@@ -114,7 +116,7 @@ class FakeWallet:
        txid = 'abc'
        ccy = 'TEST'
        
       -class TestFiat(SequentialTestCase):
       +class TestFiat(ElectrumTestCase):
            def setUp(self):
                super().setUp()
                self.value_sat = COIN
       t@@ -156,7 +158,8 @@ class TestCreateRestoreWallet(WalletTestCase):
                                      passphrase=passphrase,
                                      password=password,
                                      encrypt_file=encrypt_file,
       -                              gap_limit=1)
       +                              gap_limit=1,
       +                              config=self.config)
                wallet = d['wallet']  # type: Standard_Wallet
                wallet.check_password(password)
                self.assertEqual(passphrase, wallet.keystore.get_passphrase(password))
       t@@ -173,7 +176,8 @@ class TestCreateRestoreWallet(WalletTestCase):
                                             passphrase=passphrase,
                                             password=password,
                                             encrypt_file=encrypt_file,
       -                                     gap_limit=1)
       +                                     gap_limit=1,
       +                                     config=self.config)
                wallet = d['wallet']  # type: Standard_Wallet
                self.assertEqual(passphrase, wallet.keystore.get_passphrase(password))
                self.assertEqual(text, wallet.keystore.get_seed(password))
       t@@ -182,28 +186,28 @@ class TestCreateRestoreWallet(WalletTestCase):
        
            def test_restore_wallet_from_text_xpub(self):
                text = 'zpub6nydoME6CFdJtMpzHW5BNoPz6i6XbeT9qfz72wsRqGdgGEYeivso6xjfw8cGcCyHwF7BNW4LDuHF35XrZsovBLWMF4qXSjmhTXYiHbWqGLt'
       -        d = restore_wallet_from_text(text, path=self.wallet_path, gap_limit=1)
       +        d = restore_wallet_from_text(text, path=self.wallet_path, gap_limit=1, config=self.config)
                wallet = d['wallet']  # type: Standard_Wallet
                self.assertEqual(text, wallet.keystore.get_master_public_key())
                self.assertEqual('bc1q2ccr34wzep58d4239tl3x3734ttle92a8srmuw', wallet.get_receiving_addresses()[0])
        
            def test_restore_wallet_from_text_xkey_that_is_also_a_valid_electrum_seed_by_chance(self):
                text = 'yprvAJBpuoF4FKpK92ofzQ7ge6VJMtorow3maAGPvPGj38ggr2xd1xCrC9ojUVEf9jhW5L9SPu6fU2U3o64cLrRQ83zaQGNa6YP3ajZS6hHNPXj'
       -        d = restore_wallet_from_text(text, path=self.wallet_path, gap_limit=1)
       +        d = restore_wallet_from_text(text, path=self.wallet_path, gap_limit=1, config=self.config)
                wallet = d['wallet']  # type: Standard_Wallet
                self.assertEqual(text, wallet.keystore.get_master_private_key(password=None))
                self.assertEqual('3Pa4hfP3LFWqa2nfphYaF7PZfdJYNusAnp', wallet.get_receiving_addresses()[0])
        
            def test_restore_wallet_from_text_xprv(self):
                text = 'zprvAZzHPqhCMt51fskXBUYB1fTFYgG3CBjJUT4WEZTpGw6hPSDWBPZYZARC5sE9xAcX8NeWvvucFws8vZxEa65RosKAhy7r5MsmKTxr3hmNmea'
       -        d = restore_wallet_from_text(text, path=self.wallet_path, gap_limit=1)
       +        d = restore_wallet_from_text(text, path=self.wallet_path, gap_limit=1, config=self.config)
                wallet = d['wallet']  # type: Standard_Wallet
                self.assertEqual(text, wallet.keystore.get_master_private_key(password=None))
                self.assertEqual('bc1q2ccr34wzep58d4239tl3x3734ttle92a8srmuw', wallet.get_receiving_addresses()[0])
        
            def test_restore_wallet_from_text_addresses(self):
                text = 'bc1q2ccr34wzep58d4239tl3x3734ttle92a8srmuw bc1qnp78h78vp92pwdwq5xvh8eprlga5q8gu66960c'
       -        d = restore_wallet_from_text(text, path=self.wallet_path)
       +        d = restore_wallet_from_text(text, path=self.wallet_path, config=self.config)
                wallet = d['wallet']  # type: Imported_Wallet
                self.assertEqual('bc1q2ccr34wzep58d4239tl3x3734ttle92a8srmuw', wallet.get_receiving_addresses()[0])
                self.assertEqual(2, len(wallet.get_receiving_addresses()))
       t@@ -213,7 +217,7 @@ class TestCreateRestoreWallet(WalletTestCase):
        
            def test_restore_wallet_from_text_privkeys(self):
                text = 'p2wpkh:L4jkdiXszG26SUYvwwJhzGwg37H2nLhrbip7u6crmgNeJysv5FHL p2wpkh:L24GxnN7NNUAfCXA6hFzB1jt59fYAAiFZMcLaJ2ZSawGpM3uqhb1'
       -        d = restore_wallet_from_text(text, path=self.wallet_path)
       +        d = restore_wallet_from_text(text, path=self.wallet_path, config=self.config)
                wallet = d['wallet']  # type: Imported_Wallet
                addr0 = wallet.get_receiving_addresses()[0]
                self.assertEqual('bc1q2ccr34wzep58d4239tl3x3734ttle92a8srmuw', addr0)
   DIR diff --git a/electrum/tests/test_wallet_vertical.py b/electrum/tests/test_wallet_vertical.py
       t@@ -17,7 +17,7 @@ from electrum.mnemonic import seed_type
        from electrum.plugins.trustedcoin import trustedcoin
        
        from . import TestCaseForTestnet
       -from . import SequentialTestCase
       +from . import ElectrumTestCase
        from .test_bitcoin import needs_test_with_all_ecc_implementations
        
        
       t@@ -45,25 +45,26 @@ class WalletIntegrityHelper:
                test_obj.assertFalse(ks.has_seed())
        
            @classmethod
       -    def create_standard_wallet(cls, ks, gap_limit=None):
       +    def create_standard_wallet(cls, ks, *, config: SimpleConfig, gap_limit=None):
                store = storage.WalletStorage('if_this_exists_mocking_failed_648151893')
                store.put('keystore', ks.dump())
                store.put('gap_limit', gap_limit or cls.gap_limit)
       -        w = Standard_Wallet(store)
       +        w = Standard_Wallet(store, config=config)
                w.synchronize()
                return w
        
            @classmethod
       -    def create_imported_wallet(cls, privkeys=False):
       +    def create_imported_wallet(cls, *, config: SimpleConfig, privkeys: bool):
                store = storage.WalletStorage('if_this_exists_mocking_failed_648151893')
                if privkeys:
                    k = keystore.Imported_KeyStore({})
                    store.put('keystore', k.dump())
       -        w = Imported_Wallet(store)
       +        w = Imported_Wallet(store, config=config)
                return w
        
            @classmethod
       -    def create_multisig_wallet(cls, keystores: Sequence, multisig_type: str, gap_limit=None):
       +    def create_multisig_wallet(cls, keystores: Sequence, multisig_type: str, *,
       +                               config: SimpleConfig, gap_limit=None):
                """Creates a multisig wallet."""
                store = storage.WalletStorage('if_this_exists_mocking_failed_648151893')
                for i, ks in enumerate(keystores):
       t@@ -71,12 +72,16 @@ class WalletIntegrityHelper:
                    store.put('x%d/' % cosigner_index, ks.dump())
                store.put('wallet_type', multisig_type)
                store.put('gap_limit', gap_limit or cls.gap_limit)
       -        w = Multisig_Wallet(store)
       +        w = Multisig_Wallet(store, config=config)
                w.synchronize()
                return w
        
        
       -class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
       +class TestWalletKeystoreAddressIntegrityForMainnet(ElectrumTestCase):
       +
       +    def setUp(self):
       +        super().setUp()
       +        self.config = SimpleConfig({'electrum_path': self.electrum_path})
        
            @needs_test_with_all_ecc_implementations
            @mock.patch.object(storage.WalletStorage, '_write')
       t@@ -92,7 +97,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
                self.assertEqual(ks.xprv, 'xprv9s21ZrQH143K32jECVM729vWgGq4mUDJCk1ozqAStTphzQtCTuoFmFafNoG1g55iCnBTXUzz3zWnDb5CVLGiFvmaZjuazHDL8a81cPQ8KL6')
                self.assertEqual(ks.xpub, 'xpub661MyMwAqRbcFWohJWt7PHsFEJfZAvw9ZxwQoDa4SoMgsDDM1T7WK3u9E4edkC4ugRnZ8E4xDZRpk8Rnts3Nbt97dPwT52CwBdDWroaZf8U')
        
       -        w = WalletIntegrityHelper.create_standard_wallet(ks)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
                self.assertEqual(w.txin_type, 'p2pkh')
        
                self.assertEqual(w.get_receiving_addresses()[0], '1NNkttn1YvVGdqBW4PR6zvc3Zx3H5owKRf')
       t@@ -112,7 +117,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
                self.assertEqual(ks.xprv, 'zprvAZswDvNeJeha8qZ8g7efN3FXYVJLaEUsE9TW6qXDEbVe74AZ75c2sZFZXPNFzxnhChDQ89oC8C5AjWwHmH1HeRKE1c4kKBQAmjUDdKDUZw2')
                self.assertEqual(ks.xpub, 'zpub6nsHdRuY92FsMKdbn9BfjBCG6X8pyhCibNP6uDvpnw2cyrVhecvHRMa3Ne8kdJZxjxgwnpbHLkcR4bfnhHy6auHPJyDTQ3kianeuVLdkCYQ')
        
       -        w = WalletIntegrityHelper.create_standard_wallet(ks)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
                self.assertEqual(w.txin_type, 'p2wpkh')
        
                self.assertEqual(w.get_receiving_addresses()[0], 'bc1q3g5tmkmlvxryhh843v4dz026avatc0zzr6h3af')
       t@@ -132,7 +137,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
                self.assertEqual(ks.xprv, 'zprvAZDmEQiCLUcZXPfrBXoksCD2R6RMAzAre7SUyBotibisy9c7vGhLYvHaP3d9rYU12DKAWdZfscPNA7qEPgTkCDqX5sE93ryAJAQvkDbfLxU')
                self.assertEqual(ks.xpub, 'zpub6nD7dvF6ArArjskKHZLmEL9ky8FqaSti1LN5maDWGwFrqwwGTp1b6ic4EHwciFNaYDmCXcQYxXSiF9BjcLCMPcaYkVN2nQD6QjYQ8vpSR3Z')
        
       -        w = WalletIntegrityHelper.create_standard_wallet(ks)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
                self.assertEqual(w.txin_type, 'p2wpkh')
        
                self.assertEqual(w.get_receiving_addresses()[0], 'bc1qx94dutas7ysn2my645cyttujrms5d9p57f6aam')
       t@@ -151,7 +156,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
        
                self.assertEqual(ks.mpk, 'e9d4b7866dd1e91c862aebf62a49548c7dbf7bcc6e4b7b8c9da820c7737968df9c09d5a3e271dc814a29981f81b3faaf2737b551ef5dcc6189cf0f8252c442b3')
        
       -        w = WalletIntegrityHelper.create_standard_wallet(ks)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
                self.assertEqual(w.txin_type, 'p2pkh')
        
                self.assertEqual(w.get_receiving_addresses()[0], '1FJEEB8ihPMbzs2SkLmr37dHyRFzakqUmo')
       t@@ -186,7 +191,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
                WalletIntegrityHelper.check_xpub_keystore_sanity(self, ks3)
                self.assertTrue(isinstance(ks3, keystore.BIP32_KeyStore))
        
       -        w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2, ks3], '2of3')
       +        w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2, ks3], '2of3', config=self.config)
                self.assertEqual(w.txin_type, 'p2sh')
        
                self.assertEqual(w.get_receiving_addresses()[0], '35L8XmCDoEBKeaWRjvmZvoZvhp8BXMMMPV')
       t@@ -221,7 +226,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
                WalletIntegrityHelper.check_xpub_keystore_sanity(self, ks3)
                self.assertTrue(isinstance(ks3, keystore.BIP32_KeyStore))
        
       -        w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2, ks3], '2of3')
       +        w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2, ks3], '2of3', config=self.config)
                self.assertEqual(w.txin_type, 'p2wsh')
        
                self.assertEqual(w.get_receiving_addresses()[0], 'bc1qpmufh0zjp5prfsrk2yskcy82sa26srqkd97j0457andc6m0gh5asw7kqd2')
       t@@ -240,7 +245,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
                self.assertEqual(ks.xprv, 'xprv9zGLcNEb3cHUKizLVBz6RYeE9bEZAVPjH2pD1DEzCnPcsemWc3d3xTao8sfhfUmDLMq6e3RcEMEvJG1Et8dvfL8DV4h7mwm9J6AJsW9WXQD')
                self.assertEqual(ks.xpub, 'xpub6DFh1smUsyqmYD4obDX6ngaxhd53Zx7aeFjoobebm7vbkT6f9awJWFuGzBT9FQJEWFBL7UyhMXtYzRcwDuVbcxtv9Ce2W9eMm4KXLdvdbjv')
        
       -        w = WalletIntegrityHelper.create_standard_wallet(ks)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
                self.assertEqual(w.txin_type, 'p2pkh')
        
                self.assertEqual(w.get_receiving_addresses()[0], '16j7Dqk3Z9DdTdBtHcCVLaNQy9MTgywUUo')
       t@@ -259,7 +264,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
                self.assertEqual(ks.xprv, 'xprv9z8izheguGnLopSqkY7GcGFrP2Gu6rzBvvHo6uB9B8DWJhsows6WDZAsbBTaP3ncP2AVbTQphyEQkahrB9s1L7ihZtfz5WGQPMbXwsUtSik')
                self.assertEqual(ks.xpub, 'xpub6D85QDBajeLe2JXJrZeGyQCaw47PWKi3J9DPuHakjTkVBWCxVQQkmMVMSSfnw39tj9FntbozpRtb1AJ8ubjeVSBhyK4M5mzdvsXZzKPwodT')
        
       -        w = WalletIntegrityHelper.create_standard_wallet(ks)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
                self.assertEqual(w.txin_type, 'p2pkh')
        
                self.assertEqual(w.get_receiving_addresses()[0], '1F88g2naBMhDB7pYFttPWGQgryba3hPevM')
       t@@ -278,7 +283,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
                self.assertEqual(ks.xprv, 'yprvAJEYHeNEPcyBoQYM7sGCxDiNCTX65u4ANgZuSGTrKN5YCC9MP84SBayrgaMyZV7zvkHrr3HVPTK853s2SPk4EttPazBZBmz6QfDkXeE8Zr7')
                self.assertEqual(ks.xpub, 'ypub6XDth9u8DzXV1tcpDtoDKMf6kVMaVMn1juVWEesTshcX4zUVvfNgjPJLXrD9N7AdTLnbHFL64KmBn3SNaTe69iZYbYCqLCCNPZKbLz9niQ4')
        
       -        w = WalletIntegrityHelper.create_standard_wallet(ks)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
                self.assertEqual(w.txin_type, 'p2wpkh-p2sh')
        
                self.assertEqual(w.get_receiving_addresses()[0], '35ohQTdNykjkF1Mn9nAVEFjupyAtsPAK1W')
       t@@ -298,7 +303,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
                self.assertEqual(ks.xprv, 'zprvAdG4iTXWBoARxkkzNpNh8r6Qag3irQB8PzEMkAFeTRXxHpbF9z4QgEvBRmfvqWvGp42t42nvgGpNgYSJA9iefm1yYNZKEm7z6qUWCroSQnE')
                self.assertEqual(ks.xpub, 'zpub6rFR7y4Q2AijBEqTUquhVz398htDFrtymD9xYYfG1m4wAcvPhXNfE3EfH1r1ADqtfSdVCToUG868RvUUkgDKf31mGDtKsAYz2oz2AGutZYs')
        
       -        w = WalletIntegrityHelper.create_standard_wallet(ks)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
                self.assertEqual(w.txin_type, 'p2wpkh')
        
                self.assertEqual(w.get_receiving_addresses()[0], 'bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu')
       t@@ -321,7 +326,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
                WalletIntegrityHelper.check_xpub_keystore_sanity(self, ks2)
                self.assertTrue(isinstance(ks2, keystore.BIP32_KeyStore))
        
       -        w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2')
       +        w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2', config=self.config)
                self.assertEqual(w.txin_type, 'p2sh')
        
                self.assertEqual(w.get_receiving_addresses()[0], '32ji3QkAgXNz6oFoRfakyD3ys1XXiERQYN')
       t@@ -344,7 +349,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
                WalletIntegrityHelper.check_xpub_keystore_sanity(self, ks2)
                self.assertTrue(isinstance(ks2, keystore.BIP32_KeyStore))
        
       -        w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2')
       +        w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2', config=self.config)
                self.assertEqual(w.txin_type, 'p2wsh')
        
                self.assertEqual(w.get_receiving_addresses()[0], 'bc1qvzezdcv6vs5h45ugkavp896e0nde5c5lg5h0fwe2xyfhnpkxq6gq7pnwlc')
       t@@ -367,7 +372,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
                WalletIntegrityHelper.check_xpub_keystore_sanity(self, ks2)
                self.assertTrue(isinstance(ks2, keystore.BIP32_KeyStore))
        
       -        w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2')
       +        w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2', config=self.config)
                self.assertEqual(w.txin_type, 'p2sh')
        
                self.assertEqual(w.get_receiving_addresses()[0], '3JPTQ2nitVxXBJ1yhMeDwH6q417UifE3bN')
       t@@ -389,7 +394,7 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
                WalletIntegrityHelper.check_xpub_keystore_sanity(self, ks2)
                self.assertTrue(isinstance(ks2, keystore.BIP32_KeyStore))
        
       -        w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2')
       +        w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2', config=self.config)
                self.assertEqual(w.txin_type, 'p2wsh-p2sh')
        
                self.assertEqual(w.get_receiving_addresses()[0], '35LeC45QgCVeRor1tJD6LiDgPbybBXisns')
       t@@ -414,42 +419,42 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
                self.assertEqual('02bf27f41683d84183e4e930e66d64fc8af5508b4b5bf3c473c505e4dbddaeed80', ks.derive_pubkey(1, 0))
        
                ks = create_keystore_from_bip32seed(xtype='standard')  # p2pkh
       -        w = WalletIntegrityHelper.create_standard_wallet(ks)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
                self.assertEqual(ks.xprv, 'xprv9s21ZrQH143K3nyWMZVjzGL4KKAE1zahmhTHuV5pdw4eK3o3igC5QywgQG7UTRe6TGBniPDpPFWzXMeMUFbBj8uYsfXGjyMmF54wdNt8QBm')
                self.assertEqual(ks.xpub, 'xpub661MyMwAqRbcGH3yTb2kMQGnsLziRTJZ8vNthsVSCGbdBr8CGDWKxnGAFYgyKTzBtwvPPmfVAWJuFmxRXjSbUTg87wDkWQ5GmzpfUcN9t8Z')
                self.assertEqual(w.get_receiving_addresses()[0], '19fWEVaXqgJFFn7JYNr6ouxyjZy3uK7CdK')
                self.assertEqual(w.get_change_addresses()[0], '1EEX7da31qndYyeKdbM665w1ze5gbkkAZZ')
        
                ks = create_keystore_from_bip32seed(xtype='p2wpkh-p2sh')
       -        w = WalletIntegrityHelper.create_standard_wallet(ks)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
                self.assertEqual(ks.xprv, 'yprvABrGsX5C9janu6AdBvHNCMRZVHJfxcaCgoyWgsyi1wSXN9cGyLMe33bpRU54TLJ1ruJbTrpNqusYQeFvBx1CXNb9k1DhKtBFWo8b1sLbXhN')
                self.assertEqual(ks.xpub, 'ypub6QqdH2c5z7967aF6HwpNZVNJ3K9AN5J442u7VGPKaGyWEwwRWsftaqvJGkeZKNe7Jb3C9FG3dAfT94ZzFRrcGhMizGvB6Jtm3itJsEFhxMC')
                self.assertEqual(w.get_receiving_addresses()[0], '34SAT5gGF5UaBhhSZ8qEuuxYvZ2cm7Zi23')
                self.assertEqual(w.get_change_addresses()[0], '38unULZaetSGSKvDx7Krukh8zm8NQnxGiA')
        
                ks = create_keystore_from_bip32seed(xtype='p2wpkh')
       -        w = WalletIntegrityHelper.create_standard_wallet(ks)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
                self.assertEqual(ks.xprv, 'zprvAWgYBBk7JR8GkPMk2H4zQSX4fFT7uEZhbvVjUGsbPwpQRFRWDzXCf7FxSg2eTEwwGYRQDLQwJaE6HvsUueRDKcGkcLv7unzjnXCEQVWhrF9')
                self.assertEqual(ks.xpub, 'zpub6jftahH18ngZxsSD8JbzmaToDHHcJhHYy9RLGfHCxHMPJ3kemXqTCuaSHxc9KHJ2iE9ztirc5q212MBYy8Gd4w3KrccbgDiFKSwxFpYKEH6')
                self.assertEqual(w.get_receiving_addresses()[0], 'bc1qtuynwzd0d6wptvyqmc6ehkm70zcamxpshyzu5e')
                self.assertEqual(w.get_change_addresses()[0], 'bc1qjy5zunxh6hjysele86qqywfa437z4xwmleq8wk')
        
                ks = create_keystore_from_bip32seed(xtype='standard')  # p2sh
       -        w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1')
       +        w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1', config=self.config)
                self.assertEqual(ks.xprv, 'xprv9s21ZrQH143K3nyWMZVjzGL4KKAE1zahmhTHuV5pdw4eK3o3igC5QywgQG7UTRe6TGBniPDpPFWzXMeMUFbBj8uYsfXGjyMmF54wdNt8QBm')
                self.assertEqual(ks.xpub, 'xpub661MyMwAqRbcGH3yTb2kMQGnsLziRTJZ8vNthsVSCGbdBr8CGDWKxnGAFYgyKTzBtwvPPmfVAWJuFmxRXjSbUTg87wDkWQ5GmzpfUcN9t8Z')
                self.assertEqual(w.get_receiving_addresses()[0], '3F4nm8Vunb7mxVvqhUP238PYge2hpU5qYv')
                self.assertEqual(w.get_change_addresses()[0], '3N8jvKGmxzVHENn6B4zTdZt3N9bmRKjj96')
        
                ks = create_keystore_from_bip32seed(xtype='p2wsh-p2sh')
       -        w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1')
       +        w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1', config=self.config)
                self.assertEqual(ks.xprv, 'YprvANkMzkodih9AKfL18akM2RmND5LwAyFo15dBc9FFPiGvzLBBjjjv8ATkEB2Y1mWv6NNaLSpVj8G3XosgVBA9frhpaUL6jHeFQXQTbqVPcv2')
                self.assertEqual(ks.xpub, 'Ypub6bjiQGLXZ4hTY9QUEcHMPZi6m7BRaRyeNJYnQXerx3ous8WLHH4AfxnE5Tc2sos1Y47B1qGAWP3xGEBkYf1ZRBUPpk2aViMkwTABT6qoiBb')
                self.assertEqual(w.get_receiving_addresses()[0], '3L1BxLLASGKE3DR1ruraWm3hZshGCKqcJx')
                self.assertEqual(w.get_change_addresses()[0], '3NDGcbZVXTpaQWRhiuVPpXsNt4g2JiCX4E')
        
                ks = create_keystore_from_bip32seed(xtype='p2wsh')
       -        w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1')
       +        w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1', config=self.config)
                self.assertEqual(ks.xprv, 'ZprvAhadJRUYsNgeAxX7xwXyEWrsP3VP7bFHvC9QPY98miep3RzQzPuUkE7tFNz81gAqW1VP5vR4BncbR6VFCsaAU6PRSp2XKCTjgFU6zRpk6Xp')
                self.assertEqual(ks.xpub, 'Zpub6vZyhw1ShkEwPSbb4y4ybeobw5KsX3y9HR51BvYkL4BnvEKZXwDjJ2SN6fZcsiWvwhDymJriy3QW9WoKGMRaDR9zh5j15dBFDBDpqjK1ekQ')
                self.assertEqual(w.get_receiving_addresses()[0], 'bc1q84x0yrztvcjg88qef4d6978zccxulcmc9y88xcg4ghjdau999x7q7zv2qe')
       t@@ -458,6 +463,10 @@ class TestWalletKeystoreAddressIntegrityForMainnet(SequentialTestCase):
        
        class TestWalletKeystoreAddressIntegrityForTestnet(TestCaseForTestnet):
        
       +    def setUp(self):
       +        super().setUp()
       +        self.config = SimpleConfig({'electrum_path': self.electrum_path})
       +
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_bip39_multisig_seed_p2sh_segwit_testnet(self, mock_write):
                # bip39 seed: finish seminar arrange erosion sunny coil insane together pretty lunch lunch rose
       t@@ -473,7 +482,7 @@ class TestWalletKeystoreAddressIntegrityForTestnet(TestCaseForTestnet):
                WalletIntegrityHelper.check_xpub_keystore_sanity(self, ks2)
                self.assertTrue(isinstance(ks2, keystore.BIP32_KeyStore))
        
       -        w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2')
       +        w = WalletIntegrityHelper.create_multisig_wallet([ks1, ks2], '2of2', config=self.config)
                self.assertEqual(w.txin_type, 'p2wsh-p2sh')
        
                self.assertEqual(w.get_receiving_addresses()[0], '2MzsfTfTGomPRne6TkctMmoDj6LwmVkDrMt')
       t@@ -498,42 +507,42 @@ class TestWalletKeystoreAddressIntegrityForTestnet(TestCaseForTestnet):
                self.assertEqual('02bf27f41683d84183e4e930e66d64fc8af5508b4b5bf3c473c505e4dbddaeed80', ks.derive_pubkey(1, 0))
        
                ks = create_keystore_from_bip32seed(xtype='standard')  # p2pkh
       -        w = WalletIntegrityHelper.create_standard_wallet(ks)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
                self.assertEqual(ks.xprv, 'tprv8ZgxMBicQKsPecD328MF9ux3dSaSFWci7FNQmuWH7uZ86eY8i3XpvjK8KSH8To2QphiZiUqaYc6nzDC6bTw8YCB9QJjaQL5pAApN4z7vh2B')
                self.assertEqual(ks.xpub, 'tpubD6NzVbkrYhZ4Y5Epun1qZKcACU6NQqocgYyC4RYaYBMWw8nuLSMR7DvzVamkqxwRgrTJ1MBMhc8wwxT2vbHqMu8RBXy4BvjWMxR5EdZroxE')
                self.assertEqual(w.get_receiving_addresses()[0], 'mpBTXYfWehjW2tavFwpUdqBJbZZkup13k2')
                self.assertEqual(w.get_change_addresses()[0], 'mtkUQgf1psDtL67wMAKTv19LrdgPWy6GDQ')
        
                ks = create_keystore_from_bip32seed(xtype='p2wpkh-p2sh')
       -        w = WalletIntegrityHelper.create_standard_wallet(ks)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
                self.assertEqual(ks.xprv, 'uprv8tXDerPXZ1QsVuQ9rV8sN13YoQitC8cD2MtdZJQAVuw19kMMxhhPYnyGLeEiThgLELqNTxS91GTLsVofKAM9LRrkGeRzzEuJRtt1Tcostr7')
                self.assertEqual(ks.xpub, 'upub57Wa4MvRPNyAiPUcxWfsj8zHMSZNbbL4PapEMgon4FTz2YgWWF1e6bHkBvpDKk2Rg2Zy9LsonXFFbv7jNeCZ5kdKWv8UkfcoxpdjJrZuBX6')
                self.assertEqual(w.get_receiving_addresses()[0], '2MuzNWpcHrXyvPVKzEGT7Xrwp8uEnXXjWnK')
                self.assertEqual(w.get_change_addresses()[0], '2MzTzY5VcGLwce7YmdEwjXhgQD7LYEKLJTm')
        
                ks = create_keystore_from_bip32seed(xtype='p2wpkh')
       -        w = WalletIntegrityHelper.create_standard_wallet(ks)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, config=self.config)
                self.assertEqual(ks.xprv, 'vprv9DMUxX4ShgxMMCbGgqvVa693yNsL8kbhwUQrLhJ3svJtCrAbDMrxArdQMrCJTcLFdyxBDS2hTvotknRE2rmA8fYM8z8Ra9inhcwerEsG6Ev')
                self.assertEqual(ks.xpub, 'vpub5SLqN2bLY4WeZgfjnsTVwE5nXQhpYDKZJhLT95hfSFqs5eVjkuBCiewtD8moKegM5fgmtpUNFBboVCjJ6LcZszJvPFpuLaSJEYhNhUAnrCS')
                self.assertEqual(w.get_receiving_addresses()[0], 'tb1qtuynwzd0d6wptvyqmc6ehkm70zcamxpsaze002')
                self.assertEqual(w.get_change_addresses()[0], 'tb1qjy5zunxh6hjysele86qqywfa437z4xwm4lm549')
        
                ks = create_keystore_from_bip32seed(xtype='standard')  # p2sh
       -        w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1')
       +        w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1', config=self.config)
                self.assertEqual(ks.xprv, 'tprv8ZgxMBicQKsPecD328MF9ux3dSaSFWci7FNQmuWH7uZ86eY8i3XpvjK8KSH8To2QphiZiUqaYc6nzDC6bTw8YCB9QJjaQL5pAApN4z7vh2B')
                self.assertEqual(ks.xpub, 'tpubD6NzVbkrYhZ4Y5Epun1qZKcACU6NQqocgYyC4RYaYBMWw8nuLSMR7DvzVamkqxwRgrTJ1MBMhc8wwxT2vbHqMu8RBXy4BvjWMxR5EdZroxE')
                self.assertEqual(w.get_receiving_addresses()[0], '2N6czpsRwQ3d8AHZPNbztf5NotzEsaZmVQ8')
                self.assertEqual(w.get_change_addresses()[0], '2NDgwz4CoaSzdSAQdrCcLFWsJaVowCNgiPA')
        
                ks = create_keystore_from_bip32seed(xtype='p2wsh-p2sh')
       -        w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1')
       +        w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1', config=self.config)
                self.assertEqual(ks.xprv, 'Uprv95RJn67y7xyEvUZXo9brC5PMXCm9QVHoLdYJUZfhsgmQmvvGj75fduqC9MCC28uETouMLYSFtUqqzfRRcPW6UuyR77YQPeNJKd9t3XutF8b')
                self.assertEqual(ks.xpub, 'Upub5JQfBberxLXY8xdzuB8rZDL65Ebdox1ehrTuGx5KS2JPejFRGePvBi9fzdmgtBFKuVdx1vsvfjdkj5jVfsMWEEjzMPEtA55orYubtrCZmRr')
                self.assertEqual(w.get_receiving_addresses()[0], '2NBZQ25GC3ipaF13ZY3UT8i2xnDuS17pJqx')
                self.assertEqual(w.get_change_addresses()[0], '2NDmUgLVX8vKvcJ4FQ37GSUre6QtBzKkb6k')
        
                ks = create_keystore_from_bip32seed(xtype='p2wsh')
       -        w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1')
       +        w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1', config=self.config)
                self.assertEqual(ks.xprv, 'Vprv16YtLrHXxePM6noKqtFtMtmUgBE9bEpF3fPLmpvuPksssLostujtdHBwqhEeVuzESz22UY8hyPx9ed684SQpCmUKSVhpxPFbvVNY7qnviNR')
                self.assertEqual(ks.xpub, 'Vpub5dEvVGKn7251zFq7jXvUmJRbFCk5ka19cxz84LyCp2gGhq4eXJZUomop1qjGt5uFK8kkmQUV8PzJcNM4PZmX2URbDiwJjyuJ8GyFHRrEmmG')
                self.assertEqual(w.get_receiving_addresses()[0], 'tb1q84x0yrztvcjg88qef4d6978zccxulcmc9y88xcg4ghjdau999x7qf2696k')
       t@@ -542,20 +551,13 @@ class TestWalletKeystoreAddressIntegrityForTestnet(TestCaseForTestnet):
        
        class TestWalletSending(TestCaseForTestnet):
        
       -    @classmethod
       -    def setUpClass(cls):
       -        super().setUpClass()
       -        cls.electrum_path = tempfile.mkdtemp()
       -        cls.config = SimpleConfig({'electrum_path': cls.electrum_path})
       -
       -    @classmethod
       -    def tearDownClass(cls):
       -        super().tearDownClass()
       -        shutil.rmtree(cls.electrum_path)
       +    def setUp(self):
       +        super().setUp()
       +        self.config = SimpleConfig({'electrum_path': self.electrum_path})
        
            def create_standard_wallet_from_seed(self, seed_words):
                ks = keystore.from_seed(seed_words, '', False)
       -        return WalletIntegrityHelper.create_standard_wallet(ks, gap_limit=2)
       +        return WalletIntegrityHelper.create_standard_wallet(ks, gap_limit=2, config=self.config)
        
            @needs_test_with_all_ecc_implementations
            @mock.patch.object(storage.WalletStorage, '_write')
       t@@ -623,7 +625,8 @@ class TestWalletSending(TestCaseForTestnet):
                        keystore.from_xpub('tpubD6NzVbkrYhZ4YTPEgwk4zzr8wyo7pXGmbbVUnfYNtx6SgAMF5q3LN3Kch58P9hxGNsTmP7Dn49nnrmpE6upoRb1Xojg12FGLuLHkVpVtS44'),
                        keystore.from_xpub('tpubD6NzVbkrYhZ4XJzYkhsCbDCcZRmDAKSD7bXi9mdCni7acVt45fxbTVZyU6jRGh29ULKTjoapkfFsSJvQHitcVKbQgzgkkYsAmaovcro7Mhf')
                    ],
       -            '2of3', gap_limit=2
       +            '2of3', gap_limit=2,
       +            config=self.config
                )
                wallet1b = WalletIntegrityHelper.create_multisig_wallet(
                    [
       t@@ -631,7 +634,8 @@ class TestWalletSending(TestCaseForTestnet):
                        keystore.from_xpub('tpubD6NzVbkrYhZ4YTPEgwk4zzr8wyo7pXGmbbVUnfYNtx6SgAMF5q3LN3Kch58P9hxGNsTmP7Dn49nnrmpE6upoRb1Xojg12FGLuLHkVpVtS44'),
                        keystore.from_xpub('tpubD6NzVbkrYhZ4YARFMEZPckrqJkw59GZD1PXtQnw14ukvWDofR7Z1HMeSCxfYEZVvg4VdZ8zGok5VxHwdrLqew5cMdQntWc5mT7mh1CSgrnX')
                    ],
       -            '2of3', gap_limit=2
       +            '2of3', gap_limit=2,
       +            config=self.config
                )
                # ^ third seed: ghost into match ivory badge robot record tackle radar elbow traffic loud
                wallet2 = self.create_standard_wallet_from_seed('powerful random nobody notice nothing important anyway look away hidden message over')
       t@@ -699,7 +703,8 @@ class TestWalletSending(TestCaseForTestnet):
                        keystore.from_xpub('Vpub5fcdcgEwTJmbmqAktuK8Kyq92fMf7sWkcP6oqAii2tG47dNbfkGEGUbfS9NuZaRywLkHE6EmUksrqo32ZL3ouLN1HTar6oRiHpDzKMAF1tf'),
                        keystore.from_xpub('Vpub5fjkKyYnvSS4wBuakWTkNvZDaBM2vQ1MeXWq368VJHNr2eT8efqhpmZ6UUkb7s2dwCXv2Vuggjdhk4vZVyiAQTwUftvff73XcUGq2NQmWra')
                    ],
       -            '2of3', gap_limit=2
       +            '2of3', gap_limit=2,
       +            config=self.config
                )
                wallet1b = WalletIntegrityHelper.create_multisig_wallet(
                    [
       t@@ -707,7 +712,8 @@ class TestWalletSending(TestCaseForTestnet):
                        keystore.from_xpub('Vpub5fjkKyYnvSS4wBuakWTkNvZDaBM2vQ1MeXWq368VJHNr2eT8efqhpmZ6UUkb7s2dwCXv2Vuggjdhk4vZVyiAQTwUftvff73XcUGq2NQmWra'),
                        keystore.from_xpub('Vpub5gSKXzxK7FeKQedu2q1z9oJWxqvX72AArW3HSWpEhc8othDH8xMDu28gr7gf17sp492BuJod8Tn7anjvJrKpETwqnQqX7CS8fcYyUtedEMk')
                    ],
       -            '2of3', gap_limit=2
       +            '2of3', gap_limit=2,
       +            config=self.config
                )
                # ^ third seed: hedgehog sunset update estate number jungle amount piano friend donate upper wool
                wallet2a = WalletIntegrityHelper.create_multisig_wallet(
       t@@ -716,7 +722,8 @@ class TestWalletSending(TestCaseForTestnet):
                        keystore.from_xprv('Uprv9CvELvByqm8k2dpecJVjgLMX1z5DufEjY4fBC5YvdGF5WjGCa7GVJJ2fYni1tyuF7Hw83E6W2ZBjAhaFLZv2ri3rEsubkCd5avg4EHKoDBN'),
                        keystore.from_xpub('Upub5Qb8ik4Cnu8g97KLXKgVXHqY6tH8emQvqtBncjSKsyfTZuorPtTZgX7ovKKZHuuVGBVd1MTTBkWez1XXt2weN1sWBz6SfgRPQYEkNgz81QF')
                    ],
       -            '2of2', gap_limit=2
       +            '2of2', gap_limit=2,
       +            config=self.config
                )
                wallet2b = WalletIntegrityHelper.create_multisig_wallet(
                    [
       t@@ -724,7 +731,8 @@ class TestWalletSending(TestCaseForTestnet):
                        keystore.from_xprv('Uprv9BbnKEXJxXaNvdEsRJ9VA9toYrSeFJh5UfGBpM2iKe8Uh7UhrM9K8ioL53s8gvCoGfirHHaqpABDAE7VUNw8LNU1DMJKVoWyeNKu9XcDC19'),
                        keystore.from_xpub('Upub5RuakRisg8h3F7u7iL2k3UJFa1uiK7xauHamzTxYBbn4PXbM7eajr6M9Q2VCr6cVGhfhqWQqxnABvtSATuVM1xzxk4nA189jJwzaMn1QX7V')
                    ],
       -            '2of2', gap_limit=2
       +            '2of2', gap_limit=2,
       +            config=self.config
                )
        
                # bootstrap wallet1
       t@@ -798,13 +806,15 @@ class TestWalletSending(TestCaseForTestnet):
                        keystore.from_seed('phone guilt ancient scan defy gasp off rotate approve ill word exchange', '', True),
                        keystore.from_xpub('tpubD6NzVbkrYhZ4YPZ3ntVjqSCxiUUv2jikrUBU73Q3iJ7Y8iR41oYf991L5fanv7ciHjbjokdK2bjYqg1BzEUDxucU9qM5WRdBiY738wmgLP4')
                    ],
       -            '1of2', gap_limit=2
       +            '1of2', gap_limit=2,
       +            config=self.config
                )
                # ^ second seed: kingdom now gift initial age right velvet exotic harbor enforce kingdom kick
                wallet2 = WalletIntegrityHelper.create_standard_wallet(
                    # bip39: uniform tank success logic lesson awesome stove elegant regular desert drip device, der: m/49'/1'/0'
                    keystore.from_xprv('uprv91HGbrNZTK4x8u22nbdYGzEuWPxjaHMREUi7CNhY64KsG5ZGnVM99uCa16EMSfrnaPTFxjbRdBZ2WiBkokoM8anzAy3Vpc52o88WPkitnxi'),
       -            gap_limit=2
       +            gap_limit=2,
       +            config=self.config
                )
        
                # bootstrap wallet1
       t@@ -1306,27 +1316,22 @@ class TestWalletSending(TestCaseForTestnet):
        
        class TestWalletOfflineSigning(TestCaseForTestnet):
        
       -    @classmethod
       -    def setUpClass(cls):
       -        super().setUpClass()
       -        cls.electrum_path = tempfile.mkdtemp()
       -        cls.config = SimpleConfig({'electrum_path': cls.electrum_path})
       -
       -    @classmethod
       -    def tearDownClass(cls):
       -        super().tearDownClass()
       -        shutil.rmtree(cls.electrum_path)
       +    def setUp(self):
       +        super().setUp()
       +        self.config = SimpleConfig({'electrum_path': self.electrum_path})
        
            @needs_test_with_all_ecc_implementations
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_sending_offline_old_electrum_seed_online_mpk(self, mock_write):
                wallet_offline = WalletIntegrityHelper.create_standard_wallet(
                    keystore.from_seed('alone body father children lead goodbye phone twist exist grass kick join', '', False),
       -            gap_limit=4
       +            gap_limit=4,
       +            config=self.config
                )
                wallet_online = WalletIntegrityHelper.create_standard_wallet(
                    keystore.from_master_key('cd805ed20aec61c7a8b409c121c6ba60a9221f46d20edbc2be83ebd91460e97937cd7d782e77c1cb08364c6bc1c98bc040fdad53f22f29f7d3a85c8e51f9c875'),
       -            gap_limit=4
       +            gap_limit=4,
       +            config=self.config
                )
        
                # bootstrap wallet_online
       t@@ -1365,11 +1370,13 @@ class TestWalletOfflineSigning(TestCaseForTestnet):
                wallet_offline = WalletIntegrityHelper.create_standard_wallet(
                    # bip39: "qwe", der: m/44'/1'/0'
                    keystore.from_xprv('tprv8gfKwjuAaqtHgqxMh1tosAQ28XvBMkcY5NeFRA3pZMpz6MR4H4YZ3MJM4fvNPnRKeXR1Td2vQGgjorNXfo94WvT5CYDsPAqjHxSn436G1Eu'),
       -            gap_limit=4
       +            gap_limit=4,
       +            config=self.config
                )
                wallet_online = WalletIntegrityHelper.create_standard_wallet(
                    keystore.from_xpub('tpubDDMN69wQjDZxaJz9afZQGa48hZS7X5oSegF2hg67yddNvqfpuTN9DqvDEp7YyVf7AzXnqBqHdLhzTAStHvsoMDDb8WoJQzNrcHgDJHVYgQF'),
       -            gap_limit=4
       +            gap_limit=4,
       +            config=self.config
                )
        
                # bootstrap wallet_online
       t@@ -1406,11 +1413,13 @@ class TestWalletOfflineSigning(TestCaseForTestnet):
                wallet_offline = WalletIntegrityHelper.create_standard_wallet(
                    # bip39: "qwe", der: m/49'/1'/0'
                    keystore.from_xprv('uprv8zHHrMQMQ26utWwNJ5MK2SXpB9hbmy7pbPaneii69xT8cZTyFpxQFxkknGWKP8dxBTZhzy7yP6cCnLrRCQjzJDk3G61SjZpxhFQuB2NR8a5'),
       -            gap_limit=4
       +            gap_limit=4,
       +            config=self.config
                )
                wallet_online = WalletIntegrityHelper.create_standard_wallet(
                    keystore.from_xpub('upub5DGeFrwFEPfD711qQ6tKPaUYjBY6BRqfxcWPT77hiHz7VMo7oNGeom5EdXoKXEazePyoN3ueJMqHBfp3MwmsaD8k9dFHoa8KGeVXev7Pbg2'),
       -            gap_limit=4
       +            gap_limit=4,
       +            config=self.config
                )
        
                # bootstrap wallet_online
       t@@ -1448,11 +1457,13 @@ class TestWalletOfflineSigning(TestCaseForTestnet):
                wallet_offline = WalletIntegrityHelper.create_standard_wallet(
                    # bip39: "qwe", der: m/84'/1'/0'
                    keystore.from_xprv('vprv9K9hbuA23Bidgj1KRSHUZMa59jJLeZBpXPVn4RP7sBLArNhZxJjw4AX7aQmVTErDt4YFC11ptMLjbwxgrsH8GLQ1cx77KggWeVPeDBjr9xM'),
       -            gap_limit=4
       +            gap_limit=4,
       +            config=self.config
                )
                wallet_online = WalletIntegrityHelper.create_standard_wallet(
                    keystore.from_xpub('vpub5Y941QgusZGvuD5nXTpUvVWohm8q41uftcRNronjRWs9jB2iVr4BbxqbRfAoQjWHgJtDCQEXChgfsPbEuBnidtkFztZSD3zDKTrtwXa2LCa'),
       -            gap_limit=4
       +            gap_limit=4,
       +            config=self.config
                )
        
                # bootstrap wallet_online
       t@@ -1487,9 +1498,9 @@ class TestWalletOfflineSigning(TestCaseForTestnet):
            @needs_test_with_all_ecc_implementations
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_sending_offline_wif_online_addr_p2pkh(self, mock_write):  # compressed pubkey
       -        wallet_offline = WalletIntegrityHelper.create_imported_wallet(privkeys=True)
       +        wallet_offline = WalletIntegrityHelper.create_imported_wallet(privkeys=True, config=self.config)
                wallet_offline.import_private_key('p2pkh:cQDxbmQfwRV3vP1mdnVHq37nJekHLsuD3wdSQseBRA2ct4MFk5Pq', password=None)
       -        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False)
       +        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
                wallet_online.import_address('mg2jk6S5WGDhUPA8mLSxDLWpUoQnX1zzoG')
        
                # bootstrap wallet_online
       t@@ -1522,9 +1533,9 @@ class TestWalletOfflineSigning(TestCaseForTestnet):
            @needs_test_with_all_ecc_implementations
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_sending_offline_wif_online_addr_p2wpkh_p2sh(self, mock_write):
       -        wallet_offline = WalletIntegrityHelper.create_imported_wallet(privkeys=True)
       +        wallet_offline = WalletIntegrityHelper.create_imported_wallet(privkeys=True, config=self.config)
                wallet_offline.import_private_key('p2wpkh-p2sh:cU9hVzhpvfn91u2zTVn8uqF2ymS7ucYH8V5TmsTDmuyMHgRk9WsJ', password=None)
       -        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False)
       +        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
                wallet_online.import_address('2NA2JbUVK7HGWUCK5RXSVNHrkgUYF8d9zV8')
        
                # bootstrap wallet_online
       t@@ -1557,9 +1568,9 @@ class TestWalletOfflineSigning(TestCaseForTestnet):
            @needs_test_with_all_ecc_implementations
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_sending_offline_wif_online_addr_p2wpkh(self, mock_write):
       -        wallet_offline = WalletIntegrityHelper.create_imported_wallet(privkeys=True)
       +        wallet_offline = WalletIntegrityHelper.create_imported_wallet(privkeys=True, config=self.config)
                wallet_offline.import_private_key('p2wpkh:cPuQzcNEgbeYZ5at9VdGkCwkPA9r34gvEVJjuoz384rTfYpahfe7', password=None)
       -        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False)
       +        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
                wallet_online.import_address('tb1qm2eh4787lwanrzr6pf0ekf5c7jnmghm2y9k529')
        
                # bootstrap wallet_online
       t@@ -1595,9 +1606,10 @@ class TestWalletOfflineSigning(TestCaseForTestnet):
                wallet_offline = WalletIntegrityHelper.create_standard_wallet(
                    # bip39: "qwe", der: m/44'/1'/0'
                    keystore.from_xprv('tprv8gfKwjuAaqtHgqxMh1tosAQ28XvBMkcY5NeFRA3pZMpz6MR4H4YZ3MJM4fvNPnRKeXR1Td2vQGgjorNXfo94WvT5CYDsPAqjHxSn436G1Eu'),
       -            gap_limit=4
       +            gap_limit=4,
       +            config=self.config
                )
       -        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False)
       +        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
                wallet_online.import_address('mg2jk6S5WGDhUPA8mLSxDLWpUoQnX1zzoG')
        
                # bootstrap wallet_online
       t@@ -1633,9 +1645,10 @@ class TestWalletOfflineSigning(TestCaseForTestnet):
                wallet_offline = WalletIntegrityHelper.create_standard_wallet(
                    # bip39: "qwe", der: m/49'/1'/0'
                    keystore.from_xprv('uprv8zHHrMQMQ26utWwNJ5MK2SXpB9hbmy7pbPaneii69xT8cZTyFpxQFxkknGWKP8dxBTZhzy7yP6cCnLrRCQjzJDk3G61SjZpxhFQuB2NR8a5'),
       -            gap_limit=4
       +            gap_limit=4,
       +            config=self.config
                )
       -        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False)
       +        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
                wallet_online.import_address('2NA2JbUVK7HGWUCK5RXSVNHrkgUYF8d9zV8')
        
                # bootstrap wallet_online
       t@@ -1671,9 +1684,10 @@ class TestWalletOfflineSigning(TestCaseForTestnet):
                wallet_offline = WalletIntegrityHelper.create_standard_wallet(
                    # bip39: "qwe", der: m/84'/1'/0'
                    keystore.from_xprv('vprv9K9hbuA23Bidgj1KRSHUZMa59jJLeZBpXPVn4RP7sBLArNhZxJjw4AX7aQmVTErDt4YFC11ptMLjbwxgrsH8GLQ1cx77KggWeVPeDBjr9xM'),
       -            gap_limit=4
       +            gap_limit=4,
       +            config=self.config
                )
       -        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False)
       +        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
                wallet_online.import_address('tb1qm2eh4787lwanrzr6pf0ekf5c7jnmghm2y9k529')
        
                # bootstrap wallet_online
       t@@ -1713,7 +1727,8 @@ class TestWalletOfflineSigning(TestCaseForTestnet):
                        keystore.from_xpub('tpubD6NzVbkrYhZ4YTPEgwk4zzr8wyo7pXGmbbVUnfYNtx6SgAMF5q3LN3Kch58P9hxGNsTmP7Dn49nnrmpE6upoRb1Xojg12FGLuLHkVpVtS44'),
                        keystore.from_xpub('tpubD6NzVbkrYhZ4XJzYkhsCbDCcZRmDAKSD7bXi9mdCni7acVt45fxbTVZyU6jRGh29ULKTjoapkfFsSJvQHitcVKbQgzgkkYsAmaovcro7Mhf')
                    ],
       -            '2of3', gap_limit=2
       +            '2of3', gap_limit=2,
       +            config=self.config
                )
                wallet_offline2 = WalletIntegrityHelper.create_multisig_wallet(
                    [
       t@@ -1721,9 +1736,10 @@ class TestWalletOfflineSigning(TestCaseForTestnet):
                        keystore.from_xpub('tpubD6NzVbkrYhZ4YTPEgwk4zzr8wyo7pXGmbbVUnfYNtx6SgAMF5q3LN3Kch58P9hxGNsTmP7Dn49nnrmpE6upoRb1Xojg12FGLuLHkVpVtS44'),
                        keystore.from_xpub('tpubD6NzVbkrYhZ4YARFMEZPckrqJkw59GZD1PXtQnw14ukvWDofR7Z1HMeSCxfYEZVvg4VdZ8zGok5VxHwdrLqew5cMdQntWc5mT7mh1CSgrnX')
                    ],
       -            '2of3', gap_limit=2
       +            '2of3', gap_limit=2,
       +            config=self.config
                )
       -        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False)
       +        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
                wallet_online.import_address('2N4z38eTKcWTZnfugCCfRyXtXWMLnn8HDfw')
        
                # bootstrap wallet_online
       t@@ -1771,7 +1787,8 @@ class TestWalletOfflineSigning(TestCaseForTestnet):
                        keystore.from_xprv('Uprv9CvELvByqm8k2dpecJVjgLMX1z5DufEjY4fBC5YvdGF5WjGCa7GVJJ2fYni1tyuF7Hw83E6W2ZBjAhaFLZv2ri3rEsubkCd5avg4EHKoDBN'),
                        keystore.from_xpub('Upub5Qb8ik4Cnu8g97KLXKgVXHqY6tH8emQvqtBncjSKsyfTZuorPtTZgX7ovKKZHuuVGBVd1MTTBkWez1XXt2weN1sWBz6SfgRPQYEkNgz81QF')
                    ],
       -            '2of2', gap_limit=2
       +            '2of2', gap_limit=2,
       +            config=self.config
                )
                wallet_offline2 = WalletIntegrityHelper.create_multisig_wallet(
                    [
       t@@ -1779,9 +1796,10 @@ class TestWalletOfflineSigning(TestCaseForTestnet):
                        keystore.from_xprv('Uprv9BbnKEXJxXaNvdEsRJ9VA9toYrSeFJh5UfGBpM2iKe8Uh7UhrM9K8ioL53s8gvCoGfirHHaqpABDAE7VUNw8LNU1DMJKVoWyeNKu9XcDC19'),
                        keystore.from_xpub('Upub5RuakRisg8h3F7u7iL2k3UJFa1uiK7xauHamzTxYBbn4PXbM7eajr6M9Q2VCr6cVGhfhqWQqxnABvtSATuVM1xzxk4nA189jJwzaMn1QX7V')
                    ],
       -            '2of2', gap_limit=2
       +            '2of2', gap_limit=2,
       +            config=self.config
                )
       -        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False)
       +        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
                wallet_online.import_address('2MsHQRm1pNi6VsmXYRxYMcCTdPu7Xa1RyFe')
        
                # bootstrap wallet_online
       t@@ -1830,7 +1848,8 @@ class TestWalletOfflineSigning(TestCaseForTestnet):
                        keystore.from_xpub('Vpub5fcdcgEwTJmbmqAktuK8Kyq92fMf7sWkcP6oqAii2tG47dNbfkGEGUbfS9NuZaRywLkHE6EmUksrqo32ZL3ouLN1HTar6oRiHpDzKMAF1tf'),
                        keystore.from_xpub('Vpub5fjkKyYnvSS4wBuakWTkNvZDaBM2vQ1MeXWq368VJHNr2eT8efqhpmZ6UUkb7s2dwCXv2Vuggjdhk4vZVyiAQTwUftvff73XcUGq2NQmWra')
                    ],
       -            '2of3', gap_limit=2
       +            '2of3', gap_limit=2,
       +            config=self.config
                )
                wallet_offline2 = WalletIntegrityHelper.create_multisig_wallet(
                    [
       t@@ -1838,10 +1857,11 @@ class TestWalletOfflineSigning(TestCaseForTestnet):
                        keystore.from_xpub('Vpub5fjkKyYnvSS4wBuakWTkNvZDaBM2vQ1MeXWq368VJHNr2eT8efqhpmZ6UUkb7s2dwCXv2Vuggjdhk4vZVyiAQTwUftvff73XcUGq2NQmWra'),
                        keystore.from_xpub('Vpub5gSKXzxK7FeKQedu2q1z9oJWxqvX72AArW3HSWpEhc8othDH8xMDu28gr7gf17sp492BuJod8Tn7anjvJrKpETwqnQqX7CS8fcYyUtedEMk')
                    ],
       -            '2of3', gap_limit=2
       +            '2of3', gap_limit=2,
       +            config=self.config
                )
                # ^ third seed: hedgehog sunset update estate number jungle amount piano friend donate upper wool
       -        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False)
       +        wallet_online = WalletIntegrityHelper.create_imported_wallet(privkeys=False, config=self.config)
                wallet_online.import_address('tb1q83p6eqxkuvq4eumcha46crpzg4nj84s9p0hnynkxg8nhvfzqcc7q4erju6')
        
                # bootstrap wallet_online
       t@@ -1905,11 +1925,14 @@ class TestWalletHistory_SimpleRandomOrder(TestCaseForTestnet):
            }
            txid_list = sorted(list(transactions))
        
       -    @classmethod
       -    def create_old_wallet(cls):
       +    def setUp(self):
       +        super().setUp()
       +        self.config = SimpleConfig({'electrum_path': self.electrum_path})
       +
       +    def create_old_wallet(self):
                ks = keystore.from_old_mpk('e9d4b7866dd1e91c862aebf62a49548c7dbf7bcc6e4b7b8c9da820c7737968df9c09d5a3e271dc814a29981f81b3faaf2737b551ef5dcc6189cf0f8252c442b3')
                # seed words: powerful random nobody notice nothing important anyway look away hidden message over
       -        w = WalletIntegrityHelper.create_standard_wallet(ks, gap_limit=20)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, gap_limit=20, config=self.config)
                # some txns are beyond gap limit:
                w.create_new_address(for_change=True)
                return w
       t@@ -1949,28 +1972,17 @@ class TestWalletHistory_EvilGapLimit(TestCaseForTestnet):
                "268fce617aaaa4847835c2212b984d7b7741fdab65de22813288341819bc5656": "010000000001014f1bdc64da8056d08f79db7f5348d1de55946e57aa7c8279499c703889b6e0fd0100000000fdffffff0260e316000000000016001445e9879cf7cd5b4a15df7ddcaf5c6dca0e1508bacc242600000000001600141bc12094a4475dcfbf24f9920dafddf9104ca95b02483045022100ae3618912f341fefee11b67e0047c47c88c4fa031561c3fafe993259dd14d846022056fa0a5b5d8a65942fa68bcc2f848fd71fa455ba42bc2d421b67eb49ba62aa4e01210394d8f4f06c2ea9c569eb050c897737a7315e7f2104d9b536b49968cc89a1f11033181400",
            }
        
       -    @classmethod
       -    def setUpClass(cls):
       -        super().setUpClass()
       -        cls.electrum_path = tempfile.mkdtemp()
       -        cls.config = SimpleConfig({
       -            'electrum_path': cls.electrum_path,
       +    def setUp(self):
       +        super().setUp()
       +        self.config = SimpleConfig({
       +            'electrum_path': self.electrum_path,
                    'skipmerklecheck': True,  # needed for Synchronizer to generate new addresses without SPV
                })
        
       -    @classmethod
       -    def tearDownClass(cls):
       -        super().tearDownClass()
       -        shutil.rmtree(cls.electrum_path)
       -        # horrible hack. create a new config to ensure custom settings
       -        # don't get persisted in the "singleton" config:
       -        SimpleConfig({'electrum_path': cls.electrum_path})
       -
       -    @classmethod
       -    def create_wallet(cls):
       +    def create_wallet(self):
                ks = keystore.from_xpub('vpub5Vhmk4dEJKanDTTw6immKXa3thw45u3gbd1rPYjREB6viP13sVTWcH6kvbR2YeLtGjradr6SFLVt9PxWDBSrvw1Dc1nmd3oko3m24CQbfaJ')
                # seed words: nephew work weather maze pyramid employ check permit garment scene kiwi smooth
       -        w = WalletIntegrityHelper.create_standard_wallet(ks, gap_limit=20)
       +        w = WalletIntegrityHelper.create_standard_wallet(ks, gap_limit=20, config=self.config)
                return w
        
            @mock.patch.object(storage.WalletStorage, '_write')
       t@@ -2017,11 +2029,16 @@ class TestWalletHistory_DoubleSpend(TestCaseForTestnet):
                "2c9aa33d9c8ec649f9bfb84af027a5414b760be5231fe9eca4a95b9eb3f8a017": "020000000001012516fade5b5938336a11815d02787ba1580b3189432aa11b150527f8409084a30100000000fdffffff01d2410f00000000001600147880a7c79744b908a5f6d6235f2eb46c174c84f002483045022100974d27c872f09115e57c6acb674cd4da6d0b26656ad967ddb2678ff409714b9502206d91b49cf778ced6ca9e40b4094fb57b86c86fac09ce46ce53aea4afa68ff311012102254b5b20ed21c3bba75ec2a9ff230257d13a2493f6b7da066d8195dcdd484310788d1700",
            }
        
       +    def setUp(self):
       +        super().setUp()
       +        self.config = SimpleConfig({'electrum_path': self.electrum_path})
       +
            @mock.patch.object(storage.WalletStorage, '_write')
            def test_restoring_wallet_without_manual_delete(self, mock_write):
                w = restore_wallet_from_text("small rapid pattern language comic denial donate extend tide fever burden barrel",
                                             path='if_this_exists_mocking_failed_648151893',
       -                                     gap_limit=5)['wallet']
       +                                     gap_limit=5,
       +                                     config=self.config)['wallet']
                for txid in self.transactions:
                    tx = Transaction(self.transactions[txid])
                    w.add_transaction(tx.txid(), tx)
       t@@ -2034,7 +2051,8 @@ class TestWalletHistory_DoubleSpend(TestCaseForTestnet):
            def test_restoring_wallet_with_manual_delete(self, mock_write):
                w = restore_wallet_from_text("small rapid pattern language comic denial donate extend tide fever burden barrel",
                                             path='if_this_exists_mocking_failed_648151893',
       -                                     gap_limit=5)['wallet']
       +                                     gap_limit=5,
       +                                     config=self.config)['wallet']
                # txn A is an external incoming txn funding the wallet
                txA = Transaction(self.transactions["a3849040f82705151ba12a4389310b58a17b78025d81116a3338595bdefa1625"])
                w.add_transaction(txA.txid(), txA)
   DIR diff --git a/electrum/tests/test_x509.py b/electrum/tests/test_x509.py
       t@@ -1,6 +1,11 @@
        import unittest
       +
        from electrum.x509 import X509
       -class TestX509(unittest.TestCase):
       +
       +from . import ElectrumTestCase
       +
       +
       +class TestX509(ElectrumTestCase):
            def test_generalizedtime(self):
parazyd.org:70 /git/electrum/commit/f3eeb8817e847cf5b1f8fd7db92b8486937e6da9.gph:2029: line too long