1
0

Merge pull request #9880 from SomberNight/202505_refactor_chains2

constants.py: add datadir_subdir, cli_flag, config_key methods
This commit is contained in:
ThomasV
2025-05-30 09:50:36 +02:00
committed by GitHub
4 changed files with 51 additions and 48 deletions

View File

@@ -2090,21 +2090,10 @@ def add_global_options(parser, suppress=False):
group.add_argument( group.add_argument(
"-P", "--portable", action="store_true", dest="portable", default=False, "-P", "--portable", action="store_true", dest="portable", default=False,
help=argparse.SUPPRESS if suppress else "Use local 'electrum_data' directory") help=argparse.SUPPRESS if suppress else "Use local 'electrum_data' directory")
group.add_argument( for chain in constants.NETS_LIST:
"--testnet", action="store_true", dest="testnet", default=False, group.add_argument(
help=argparse.SUPPRESS if suppress else "Use Testnet") f"--{chain.cli_flag()}", action="store_true", dest=chain.config_key(), default=False,
group.add_argument( help=argparse.SUPPRESS if suppress else f"Use {chain.NET_NAME} chain")
"--testnet4", action="store_true", dest="testnet4", default=False,
help=argparse.SUPPRESS if suppress else "Use Testnet4")
group.add_argument(
"--regtest", action="store_true", dest="regtest", default=False,
help=argparse.SUPPRESS if suppress else "Use Regtest")
group.add_argument(
"--simnet", action="store_true", dest="simnet", default=False,
help=argparse.SUPPRESS if suppress else "Use Simnet")
group.add_argument(
"--signet", action="store_true", dest="signet", default=False,
help=argparse.SUPPRESS if suppress else "Use Signet")
group.add_argument( group.add_argument(
"-o", "--offline", action="store_true", dest=SimpleConfig.NETWORK_OFFLINE.key(), default=None, "-o", "--offline", action="store_true", dest=SimpleConfig.NETWORK_OFFLINE.key(), default=None,
help=argparse.SUPPRESS if suppress else "Run offline") help=argparse.SUPPRESS if suppress else "Run offline")
@@ -2134,11 +2123,8 @@ def get_simple_parser():
parser = PassThroughOptionParser() parser = PassThroughOptionParser()
parser.add_option("-D", "--dir", dest="electrum_path", help="electrum directory") parser.add_option("-D", "--dir", dest="electrum_path", help="electrum directory")
parser.add_option("-P", "--portable", action="store_true", dest="portable", default=False, help="Use local 'electrum_data' directory") parser.add_option("-P", "--portable", action="store_true", dest="portable", default=False, help="Use local 'electrum_data' directory")
parser.add_option("--testnet", action="store_true", dest="testnet", default=False, help="Use Testnet") for chain in constants.NETS_LIST:
parser.add_option("--testnet4", action="store_true", dest="testnet4", default=False, help="Use Testnet4") parser.add_option(f"--{chain.cli_flag()}", action="store_true", dest=chain.config_key(), default=False, help=f"Use {chain.NET_NAME} chain")
parser.add_option("--regtest", action="store_true", dest="regtest", default=False, help="Use Regtest")
parser.add_option("--simnet", action="store_true", dest="simnet", default=False, help="Use Simnet")
parser.add_option("--signet", action="store_true", dest="signet", default=False, help="Use Signet")
return parser return parser

View File

@@ -25,7 +25,7 @@
import os import os
import json import json
from typing import Sequence, Tuple, Mapping, Type, List from typing import Sequence, Tuple, Mapping, Type, List, Optional
from .lntransport import LNPeerAddr from .lntransport import LNPeerAddr
from .util import inv_dict, all_subclasses, classproperty from .util import inv_dict, all_subclasses, classproperty
@@ -118,6 +118,23 @@ class AbstractNet:
cls._cached_checkpoints = read_json(os.path.join('chains', cls.NET_NAME, 'checkpoints.json'), default_file) cls._cached_checkpoints = read_json(os.path.join('chains', cls.NET_NAME, 'checkpoints.json'), default_file)
return cls._cached_checkpoints return cls._cached_checkpoints
@classmethod
def datadir_subdir(cls) -> Optional[str]:
"""The name of the folder in the filesystem.
None means top-level, used by mainnet.
"""
return cls.NET_NAME
@classmethod
def cli_flag(cls) -> str:
"""as used in e.g. `$ run_electrum --testnet4`"""
return cls.NET_NAME
@classmethod
def config_key(cls) -> str:
"""as used for SimpleConfig.get()"""
return cls.NET_NAME
class BitcoinMainnet(AbstractNet): class BitcoinMainnet(AbstractNet):
@@ -156,6 +173,10 @@ class BitcoinMainnet(AbstractNet):
'lseed.darosior.ninja', 'lseed.darosior.ninja',
] ]
@classmethod
def datadir_subdir(cls):
return None
class BitcoinTestnet(AbstractNet): class BitcoinTestnet(AbstractNet):
@@ -229,7 +250,12 @@ class BitcoinSignet(BitcoinTestnet):
LN_DNS_SEEDS = [] LN_DNS_SEEDS = []
NETS_LIST = tuple(all_subclasses(AbstractNet)) NETS_LIST = tuple(all_subclasses(AbstractNet)) # type: Sequence[Type[AbstractNet]]
assert len(NETS_LIST) == len(set([chain.NET_NAME for chain in NETS_LIST])), "NET_NAME must be unique for each concrete AbstractNet"
assert len(NETS_LIST) == len(set([chain.datadir_subdir() for chain in NETS_LIST])), "datadir must be unique for each concrete AbstractNet"
assert len(NETS_LIST) == len(set([chain.cli_flag() for chain in NETS_LIST])), "cli_flag must be unique for each concrete AbstractNet"
assert len(NETS_LIST) == len(set([chain.config_key() for chain in NETS_LIST])), "config_key must be unique for each concrete AbstractNet"
# don't import net directly, import the module instead (so that net is singleton) # don't import net directly, import the module instead (so that net is singleton)
net = BitcoinMainnet # type: Type[AbstractNet] net = BitcoinMainnet # type: Type[AbstractNet]

View File

@@ -2,11 +2,12 @@ import json
import threading import threading
import os import os
import stat import stat
from typing import Union, Optional, Dict, Sequence, Any, Set, Callable, AbstractSet from typing import Union, Optional, Dict, Sequence, Any, Set, Callable, AbstractSet, Type
from functools import cached_property from functools import cached_property
from copy import deepcopy from copy import deepcopy
from . import constants
from . import util from . import util
from . import invoices from . import invoices
from .util import base_units, base_unit_name_to_decimal_point, decimal_point_to_base_unit_name, UnknownBaseUnit, DECIMAL_POINT_DEFAULT from .util import base_units, base_unit_name_to_decimal_point, decimal_point_to_base_unit_name, UnknownBaseUnit, DECIMAL_POINT_DEFAULT
@@ -232,25 +233,23 @@ class SimpleConfig(Logger):
make_dir(path, allow_symlink=False) make_dir(path, allow_symlink=False)
return path return path
def get_selected_chain(self) -> Type[constants.AbstractNet]:
selected_chains = [
chain for chain in constants.NETS_LIST
if self.get(chain.config_key())]
if selected_chains:
# note: if multiple are selected, we just pick one deterministically random
return selected_chains[0]
return constants.BitcoinMainnet
def electrum_path(self): def electrum_path(self):
path = self.electrum_path_root() path = self.electrum_path_root()
if self.get('testnet'): chain = self.get_selected_chain()
path = os.path.join(path, 'testnet') if subdir := chain.datadir_subdir():
make_dir(path, allow_symlink=False) path = os.path.join(path, subdir)
elif self.get('testnet4'):
path = os.path.join(path, 'testnet4')
make_dir(path, allow_symlink=False)
elif self.get('regtest'):
path = os.path.join(path, 'regtest')
make_dir(path, allow_symlink=False)
elif self.get('simnet'):
path = os.path.join(path, 'simnet')
make_dir(path, allow_symlink=False)
elif self.get('signet'):
path = os.path.join(path, 'signet')
make_dir(path, allow_symlink=False) make_dir(path, allow_symlink=False)
self.logger.info(f"electrum directory {path}") self.logger.info(f"electrum directory {path} (chain={chain.NET_NAME})")
return path return path
def rename_config_keys(self, config, keypairs, deprecation_warning=False): def rename_config_keys(self, config, keypairs, deprecation_warning=False):

View File

@@ -420,16 +420,8 @@ def main():
_logger.info(f"get_default_language: failed. got exc={e!r}") _logger.info(f"get_default_language: failed. got exc={e!r}")
set_language(lang) set_language(lang)
if config.get('testnet'): chain = config.get_selected_chain()
constants.BitcoinTestnet.set_as_network() chain.set_as_network()
elif config.get('testnet4'):
constants.BitcoinTestnet4.set_as_network()
elif config.get('regtest'):
constants.BitcoinRegtest.set_as_network()
elif config.get('simnet'):
constants.BitcoinSimnet.set_as_network()
elif config.get('signet'):
constants.BitcoinSignet.set_as_network()
# check if we received a valid payment identifier # check if we received a valid payment identifier
uri = config_options.get('url') uri = config_options.get('url')