mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-23 17:47:31 +00:00
more type annotations in core lib
This commit is contained in:
parent
6958c0ccc3
commit
81cc20039e
14 changed files with 90 additions and 49 deletions
|
@ -34,6 +34,9 @@ from .synchronizer import Synchronizer
|
||||||
from .verifier import SPV
|
from .verifier import SPV
|
||||||
from .blockchain import hash_header
|
from .blockchain import hash_header
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
|
from .storage import WalletStorage
|
||||||
|
from .network import Network
|
||||||
|
|
||||||
|
|
||||||
TX_HEIGHT_LOCAL = -2
|
TX_HEIGHT_LOCAL = -2
|
||||||
TX_HEIGHT_UNCONF_PARENT = -1
|
TX_HEIGHT_UNCONF_PARENT = -1
|
||||||
|
@ -53,9 +56,9 @@ class AddressSynchronizer(PrintError):
|
||||||
inherited by wallet
|
inherited by wallet
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, storage):
|
def __init__(self, storage: WalletStorage):
|
||||||
self.storage = storage
|
self.storage = storage
|
||||||
self.network = None
|
self.network = None # type: Network
|
||||||
# verifier (SPV) and synchronizer are started in start_network
|
# verifier (SPV) and synchronizer are started in start_network
|
||||||
self.synchronizer = None # type: Synchronizer
|
self.synchronizer = None # type: Synchronizer
|
||||||
self.verifier = None # type: SPV
|
self.verifier = None # type: SPV
|
||||||
|
@ -807,3 +810,6 @@ class AddressSynchronizer(PrintError):
|
||||||
def is_empty(self, address):
|
def is_empty(self, address):
|
||||||
c, u, x = self.get_addr_balance(address)
|
c, u, x = self.get_addr_balance(address)
|
||||||
return c+u+x == 0
|
return c+u+x == 0
|
||||||
|
|
||||||
|
def synchronize(self):
|
||||||
|
pass
|
||||||
|
|
|
@ -31,10 +31,15 @@ from functools import partial
|
||||||
from . import bitcoin
|
from . import bitcoin
|
||||||
from . import keystore
|
from . import keystore
|
||||||
from .keystore import bip44_derivation, purpose48_derivation
|
from .keystore import bip44_derivation, purpose48_derivation
|
||||||
from .wallet import Imported_Wallet, Standard_Wallet, Multisig_Wallet, wallet_types, Wallet
|
from .wallet import (Imported_Wallet, Standard_Wallet, Multisig_Wallet,
|
||||||
from .storage import STO_EV_USER_PW, STO_EV_XPUB_PW, get_derivation_used_for_hw_device_encryption
|
wallet_types, Wallet, Abstract_Wallet)
|
||||||
|
from .storage import (WalletStorage, STO_EV_USER_PW, STO_EV_XPUB_PW,
|
||||||
|
get_derivation_used_for_hw_device_encryption)
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
from .util import UserCancelled, InvalidPassword, WalletFileException
|
from .util import UserCancelled, InvalidPassword, WalletFileException
|
||||||
|
from .simple_config import SimpleConfig
|
||||||
|
from .plugin import Plugins
|
||||||
|
|
||||||
|
|
||||||
# hardware device setup purpose
|
# hardware device setup purpose
|
||||||
HWD_SETUP_NEW_WALLET, HWD_SETUP_DECRYPT_WALLET = range(0, 2)
|
HWD_SETUP_NEW_WALLET, HWD_SETUP_DECRYPT_WALLET = range(0, 2)
|
||||||
|
@ -48,12 +53,12 @@ class GoBack(Exception): pass
|
||||||
|
|
||||||
class BaseWizard(object):
|
class BaseWizard(object):
|
||||||
|
|
||||||
def __init__(self, config, plugins, storage):
|
def __init__(self, config: SimpleConfig, plugins: Plugins, storage: WalletStorage):
|
||||||
super(BaseWizard, self).__init__()
|
super(BaseWizard, self).__init__()
|
||||||
self.config = config
|
self.config = config
|
||||||
self.plugins = plugins
|
self.plugins = plugins
|
||||||
self.storage = storage
|
self.storage = storage
|
||||||
self.wallet = None
|
self.wallet = None # type: Abstract_Wallet
|
||||||
self.stack = []
|
self.stack = []
|
||||||
self.plugin = None
|
self.plugin = None
|
||||||
self.keystores = []
|
self.keystores = []
|
||||||
|
|
|
@ -28,6 +28,7 @@ from . import util
|
||||||
from .bitcoin import Hash, hash_encode, int_to_hex, rev_hex
|
from .bitcoin import Hash, hash_encode, int_to_hex, rev_hex
|
||||||
from . import constants
|
from . import constants
|
||||||
from .util import bfh, bh2u
|
from .util import bfh, bh2u
|
||||||
|
from .simple_config import SimpleConfig
|
||||||
|
|
||||||
|
|
||||||
HEADER_SIZE = 80 # bytes
|
HEADER_SIZE = 80 # bytes
|
||||||
|
@ -77,7 +78,7 @@ blockchains = {} # type: Dict[int, Blockchain]
|
||||||
blockchains_lock = threading.Lock()
|
blockchains_lock = threading.Lock()
|
||||||
|
|
||||||
|
|
||||||
def read_blockchains(config):
|
def read_blockchains(config: 'SimpleConfig') -> Dict[int, 'Blockchain']:
|
||||||
blockchains[0] = Blockchain(config, 0, None)
|
blockchains[0] = Blockchain(config, 0, None)
|
||||||
fdir = os.path.join(util.get_headers_dir(config), 'forks')
|
fdir = os.path.join(util.get_headers_dir(config), 'forks')
|
||||||
util.make_dir(fdir)
|
util.make_dir(fdir)
|
||||||
|
@ -100,7 +101,7 @@ class Blockchain(util.PrintError):
|
||||||
Manages blockchain headers and their verification
|
Manages blockchain headers and their verification
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, config, forkpoint: int, parent_id: Optional[int]):
|
def __init__(self, config: SimpleConfig, forkpoint: int, parent_id: Optional[int]):
|
||||||
self.config = config
|
self.config = config
|
||||||
self.forkpoint = forkpoint
|
self.forkpoint = forkpoint
|
||||||
self.checkpoints = constants.net.CHECKPOINTS
|
self.checkpoints = constants.net.CHECKPOINTS
|
||||||
|
|
|
@ -32,6 +32,7 @@ import ast
|
||||||
import base64
|
import base64
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from .import util, ecc
|
from .import util, ecc
|
||||||
from .util import bfh, bh2u, format_satoshis, json_decode, print_error, json_encode
|
from .util import bfh, bh2u, format_satoshis, json_decode, print_error, json_encode
|
||||||
|
@ -43,8 +44,11 @@ from .paymentrequest import PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED
|
||||||
from .synchronizer import Notifier
|
from .synchronizer import Notifier
|
||||||
from .storage import WalletStorage
|
from .storage import WalletStorage
|
||||||
from . import keystore
|
from . import keystore
|
||||||
from .wallet import Wallet, Imported_Wallet
|
from .wallet import Wallet, Imported_Wallet, Abstract_Wallet
|
||||||
from .mnemonic import Mnemonic
|
from .mnemonic import Mnemonic
|
||||||
|
from .network import Network
|
||||||
|
from .simple_config import SimpleConfig
|
||||||
|
|
||||||
|
|
||||||
known_commands = {}
|
known_commands = {}
|
||||||
|
|
||||||
|
@ -95,7 +99,8 @@ def command(s):
|
||||||
|
|
||||||
class Commands:
|
class Commands:
|
||||||
|
|
||||||
def __init__(self, config, wallet, network, callback = None):
|
def __init__(self, config: 'SimpleConfig', wallet: Abstract_Wallet,
|
||||||
|
network: Optional['Network'], callback=None):
|
||||||
self.config = config
|
self.config = config
|
||||||
self.wallet = wallet
|
self.wallet = wallet
|
||||||
self.network = network
|
self.network = network
|
||||||
|
|
|
@ -29,7 +29,7 @@ import time
|
||||||
import traceback
|
import traceback
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
from typing import Dict
|
from typing import Dict, Optional, Tuple
|
||||||
|
|
||||||
import jsonrpclib
|
import jsonrpclib
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ from .exchange_rate import FxThread
|
||||||
from .plugin import run_hook
|
from .plugin import run_hook
|
||||||
|
|
||||||
|
|
||||||
def get_lockfile(config):
|
def get_lockfile(config: SimpleConfig):
|
||||||
return os.path.join(config.path, 'daemon')
|
return os.path.join(config.path, 'daemon')
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ def remove_lockfile(lockfile):
|
||||||
os.unlink(lockfile)
|
os.unlink(lockfile)
|
||||||
|
|
||||||
|
|
||||||
def get_fd_or_server(config):
|
def get_fd_or_server(config: SimpleConfig):
|
||||||
'''Tries to create the lockfile, using O_EXCL to
|
'''Tries to create the lockfile, using O_EXCL to
|
||||||
prevent races. If it succeeds it returns the FD.
|
prevent races. If it succeeds it returns the FD.
|
||||||
Otherwise try and connect to the server specified in the lockfile.
|
Otherwise try and connect to the server specified in the lockfile.
|
||||||
|
@ -73,7 +73,7 @@ def get_fd_or_server(config):
|
||||||
remove_lockfile(lockfile)
|
remove_lockfile(lockfile)
|
||||||
|
|
||||||
|
|
||||||
def get_server(config):
|
def get_server(config: SimpleConfig) -> Optional[jsonrpclib.Server]:
|
||||||
lockfile = get_lockfile(config)
|
lockfile = get_lockfile(config)
|
||||||
while True:
|
while True:
|
||||||
create_time = None
|
create_time = None
|
||||||
|
@ -99,7 +99,7 @@ def get_server(config):
|
||||||
time.sleep(1.0)
|
time.sleep(1.0)
|
||||||
|
|
||||||
|
|
||||||
def get_rpc_credentials(config):
|
def get_rpc_credentials(config: SimpleConfig) -> Tuple[str, str]:
|
||||||
rpc_user = config.get('rpcuser', None)
|
rpc_user = config.get('rpcuser', None)
|
||||||
rpc_password = config.get('rpcpassword', None)
|
rpc_password = config.get('rpcpassword', None)
|
||||||
if rpc_user is None or rpc_password is None:
|
if rpc_user is None or rpc_password is None:
|
||||||
|
@ -121,7 +121,7 @@ def get_rpc_credentials(config):
|
||||||
|
|
||||||
class Daemon(DaemonThread):
|
class Daemon(DaemonThread):
|
||||||
|
|
||||||
def __init__(self, config, fd=None, *, listen_jsonrpc=True):
|
def __init__(self, config: SimpleConfig, fd=None, *, listen_jsonrpc=True):
|
||||||
DaemonThread.__init__(self)
|
DaemonThread.__init__(self)
|
||||||
self.config = config
|
self.config = config
|
||||||
if fd is None and listen_jsonrpc:
|
if fd is None and listen_jsonrpc:
|
||||||
|
@ -142,7 +142,7 @@ class Daemon(DaemonThread):
|
||||||
self.init_server(config, fd)
|
self.init_server(config, fd)
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
def init_server(self, config, fd):
|
def init_server(self, config: SimpleConfig, fd):
|
||||||
host = config.get('rpchost', '127.0.0.1')
|
host = config.get('rpchost', '127.0.0.1')
|
||||||
port = config.get('rpcport', 0)
|
port = config.get('rpcport', 0)
|
||||||
rpc_user, rpc_password = get_rpc_credentials(config)
|
rpc_user, rpc_password = get_rpc_credentials(config)
|
||||||
|
@ -230,7 +230,7 @@ class Daemon(DaemonThread):
|
||||||
response = "Error: Electrum is running in daemon mode. Please stop the daemon first."
|
response = "Error: Electrum is running in daemon mode. Please stop the daemon first."
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def load_wallet(self, path, password):
|
def load_wallet(self, path, password) -> Optional[Abstract_Wallet]:
|
||||||
# wizard will be launched if we return
|
# wizard will be launched if we return
|
||||||
if path in self.wallets:
|
if path in self.wallets:
|
||||||
wallet = self.wallets[path]
|
wallet = self.wallets[path]
|
||||||
|
@ -251,7 +251,7 @@ class Daemon(DaemonThread):
|
||||||
self.wallets[path] = wallet
|
self.wallets[path] = wallet
|
||||||
return wallet
|
return wallet
|
||||||
|
|
||||||
def add_wallet(self, wallet):
|
def add_wallet(self, wallet: Abstract_Wallet):
|
||||||
path = wallet.storage.path
|
path = wallet.storage.path
|
||||||
self.wallets[path] = wallet
|
self.wallets[path] = wallet
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@ from .i18n import _
|
||||||
from .util import PrintError, ThreadJob, make_dir, log_exceptions
|
from .util import PrintError, ThreadJob, make_dir, log_exceptions
|
||||||
from .util import make_aiohttp_session
|
from .util import make_aiohttp_session
|
||||||
from .network import Network
|
from .network import Network
|
||||||
|
from .simple_config import SimpleConfig
|
||||||
|
|
||||||
|
|
||||||
# See https://en.wikipedia.org/wiki/ISO_4217
|
# See https://en.wikipedia.org/wiki/ISO_4217
|
||||||
CCY_PRECISIONS = {'BHD': 3, 'BIF': 0, 'BYR': 0, 'CLF': 4, 'CLP': 0,
|
CCY_PRECISIONS = {'BHD': 3, 'BIF': 0, 'BYR': 0, 'CLF': 4, 'CLP': 0,
|
||||||
|
@ -434,7 +436,7 @@ def get_exchanges_by_ccy(history=True):
|
||||||
|
|
||||||
class FxThread(ThreadJob):
|
class FxThread(ThreadJob):
|
||||||
|
|
||||||
def __init__(self, config, network):
|
def __init__(self, config: SimpleConfig, network: Network):
|
||||||
self.config = config
|
self.config = config
|
||||||
self.network = network
|
self.network = network
|
||||||
if self.network:
|
if self.network:
|
||||||
|
|
|
@ -28,7 +28,7 @@ import ssl
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
import asyncio
|
import asyncio
|
||||||
from typing import Tuple, Union, List
|
from typing import Tuple, Union, List, TYPE_CHECKING
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
import aiorpcx
|
import aiorpcx
|
||||||
|
@ -43,6 +43,9 @@ from . import blockchain
|
||||||
from .blockchain import Blockchain
|
from .blockchain import Blockchain
|
||||||
from . import constants
|
from . import constants
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .network import Network
|
||||||
|
|
||||||
|
|
||||||
class NotificationSession(ClientSession):
|
class NotificationSession(ClientSession):
|
||||||
|
|
||||||
|
@ -129,7 +132,7 @@ def serialize_server(host: str, port: Union[str, int], protocol: str) -> str:
|
||||||
|
|
||||||
class Interface(PrintError):
|
class Interface(PrintError):
|
||||||
|
|
||||||
def __init__(self, network, server, config_path, proxy):
|
def __init__(self, network: 'Network', server: str, config_path, proxy: dict):
|
||||||
self.ready = asyncio.Future()
|
self.ready = asyncio.Future()
|
||||||
self.got_disconnected = asyncio.Future()
|
self.got_disconnected = asyncio.Future()
|
||||||
self.server = server
|
self.server = server
|
||||||
|
|
|
@ -164,12 +164,12 @@ class Network(PrintError):
|
||||||
"""
|
"""
|
||||||
verbosity_filter = 'n'
|
verbosity_filter = 'n'
|
||||||
|
|
||||||
def __init__(self, config=None):
|
def __init__(self, config: SimpleConfig=None):
|
||||||
global INSTANCE
|
global INSTANCE
|
||||||
INSTANCE = self
|
INSTANCE = self
|
||||||
if config is None:
|
if config is None:
|
||||||
config = {} # Do not use mutables as default values!
|
config = {} # Do not use mutables as default values!
|
||||||
self.config = SimpleConfig(config) if isinstance(config, dict) else config
|
self.config = SimpleConfig(config) if isinstance(config, dict) else config # type: SimpleConfig
|
||||||
self.num_server = 10 if not self.config.get('oneserver') else 0
|
self.num_server = 10 if not self.config.get('oneserver') else 0
|
||||||
blockchain.blockchains = blockchain.read_blockchains(self.config)
|
blockchain.blockchains = blockchain.read_blockchains(self.config)
|
||||||
self.print_error("blockchains", list(blockchain.blockchains))
|
self.print_error("blockchains", list(blockchain.blockchains))
|
||||||
|
|
|
@ -30,11 +30,13 @@ import pkgutil
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from .util import print_error
|
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
from .util import profiler, PrintError, DaemonThread, UserCancelled, ThreadJob
|
from .util import (profiler, PrintError, DaemonThread, UserCancelled,
|
||||||
|
ThreadJob, print_error)
|
||||||
from . import bitcoin
|
from . import bitcoin
|
||||||
from . import plugins
|
from . import plugins
|
||||||
|
from .simple_config import SimpleConfig
|
||||||
|
|
||||||
|
|
||||||
plugin_loaders = {}
|
plugin_loaders = {}
|
||||||
hook_names = set()
|
hook_names = set()
|
||||||
|
@ -45,7 +47,7 @@ class Plugins(DaemonThread):
|
||||||
verbosity_filter = 'p'
|
verbosity_filter = 'p'
|
||||||
|
|
||||||
@profiler
|
@profiler
|
||||||
def __init__(self, config, is_local, gui_name):
|
def __init__(self, config: SimpleConfig, is_local, gui_name):
|
||||||
DaemonThread.__init__(self)
|
DaemonThread.__init__(self)
|
||||||
self.setName('Plugins')
|
self.setName('Plugins')
|
||||||
self.pkgpath = os.path.dirname(plugins.__file__)
|
self.pkgpath = os.path.dirname(plugins.__file__)
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
import asyncio
|
import asyncio
|
||||||
import hashlib
|
import hashlib
|
||||||
from typing import Dict, List
|
from typing import Dict, List, TYPE_CHECKING
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from aiorpcx import TaskGroup, run_in_thread
|
from aiorpcx import TaskGroup, run_in_thread
|
||||||
|
@ -33,6 +33,10 @@ from .transaction import Transaction
|
||||||
from .util import bh2u, make_aiohttp_session, NetworkJobOnDefaultServer
|
from .util import bh2u, make_aiohttp_session, NetworkJobOnDefaultServer
|
||||||
from .bitcoin import address_to_scripthash
|
from .bitcoin import address_to_scripthash
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .network import Network
|
||||||
|
from .address_synchronizer import AddressSynchronizer
|
||||||
|
|
||||||
|
|
||||||
def history_status(h):
|
def history_status(h):
|
||||||
if not h:
|
if not h:
|
||||||
|
@ -47,7 +51,7 @@ class SynchronizerBase(NetworkJobOnDefaultServer):
|
||||||
"""Subscribe over the network to a set of addresses, and monitor their statuses.
|
"""Subscribe over the network to a set of addresses, and monitor their statuses.
|
||||||
Every time a status changes, run a coroutine provided by the subclass.
|
Every time a status changes, run a coroutine provided by the subclass.
|
||||||
"""
|
"""
|
||||||
def __init__(self, network):
|
def __init__(self, network: 'Network'):
|
||||||
self.asyncio_loop = network.asyncio_loop
|
self.asyncio_loop = network.asyncio_loop
|
||||||
NetworkJobOnDefaultServer.__init__(self, network)
|
NetworkJobOnDefaultServer.__init__(self, network)
|
||||||
|
|
||||||
|
@ -112,7 +116,7 @@ class Synchronizer(SynchronizerBase):
|
||||||
we don't have the full history of, and requests binary transaction
|
we don't have the full history of, and requests binary transaction
|
||||||
data of any transactions the wallet doesn't have.
|
data of any transactions the wallet doesn't have.
|
||||||
'''
|
'''
|
||||||
def __init__(self, wallet):
|
def __init__(self, wallet: 'AddressSynchronizer'):
|
||||||
self.wallet = wallet
|
self.wallet = wallet
|
||||||
SynchronizerBase.__init__(self, wallet.network)
|
SynchronizerBase.__init__(self, wallet.network)
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
import binascii
|
import binascii
|
||||||
import os, sys, re, json
|
import os, sys, re, json
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from typing import NamedTuple, Union
|
from typing import NamedTuple, Union, TYPE_CHECKING
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import decimal
|
import decimal
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
@ -46,6 +46,10 @@ from aiorpcx import TaskGroup
|
||||||
|
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .network import Network
|
||||||
|
from .interface import Interface
|
||||||
|
|
||||||
|
|
||||||
def inv_dict(d):
|
def inv_dict(d):
|
||||||
return {v: k for k, v in d.items()}
|
return {v: k for k, v in d.items()}
|
||||||
|
@ -923,10 +927,10 @@ class NetworkJobOnDefaultServer(PrintError):
|
||||||
interface. Every time the main interface changes, the job is
|
interface. Every time the main interface changes, the job is
|
||||||
restarted, and some of its internals are reset.
|
restarted, and some of its internals are reset.
|
||||||
"""
|
"""
|
||||||
def __init__(self, network):
|
def __init__(self, network: 'Network'):
|
||||||
asyncio.set_event_loop(network.asyncio_loop)
|
asyncio.set_event_loop(network.asyncio_loop)
|
||||||
self.network = network
|
self.network = network
|
||||||
self.interface = None
|
self.interface = None # type: Interface
|
||||||
self._restart_lock = asyncio.Lock()
|
self._restart_lock = asyncio.Lock()
|
||||||
self._reset()
|
self._reset()
|
||||||
asyncio.run_coroutine_threadsafe(self._restart(), network.asyncio_loop)
|
asyncio.run_coroutine_threadsafe(self._restart(), network.asyncio_loop)
|
||||||
|
@ -938,7 +942,7 @@ class NetworkJobOnDefaultServer(PrintError):
|
||||||
"""
|
"""
|
||||||
self.group = SilentTaskGroup()
|
self.group = SilentTaskGroup()
|
||||||
|
|
||||||
async def _start(self, interface):
|
async def _start(self, interface: 'Interface'):
|
||||||
self.interface = interface
|
self.interface = interface
|
||||||
await interface.group.spawn(self._start_tasks)
|
await interface.group.spawn(self._start_tasks)
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from typing import Sequence, Optional
|
from typing import Sequence, Optional, TYPE_CHECKING
|
||||||
|
|
||||||
import aiorpcx
|
import aiorpcx
|
||||||
|
|
||||||
|
@ -33,6 +33,10 @@ from .blockchain import hash_header
|
||||||
from .interface import GracefulDisconnect
|
from .interface import GracefulDisconnect
|
||||||
from . import constants
|
from . import constants
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .network import Network
|
||||||
|
from .address_synchronizer import AddressSynchronizer
|
||||||
|
|
||||||
|
|
||||||
class MerkleVerificationFailure(Exception): pass
|
class MerkleVerificationFailure(Exception): pass
|
||||||
class MissingBlockHeader(MerkleVerificationFailure): pass
|
class MissingBlockHeader(MerkleVerificationFailure): pass
|
||||||
|
@ -43,7 +47,7 @@ class InnerNodeOfSpvProofIsValidTx(MerkleVerificationFailure): pass
|
||||||
class SPV(NetworkJobOnDefaultServer):
|
class SPV(NetworkJobOnDefaultServer):
|
||||||
""" Simple Payment Verification """
|
""" Simple Payment Verification """
|
||||||
|
|
||||||
def __init__(self, network, wallet):
|
def __init__(self, network: 'Network', wallet: 'AddressSynchronizer'):
|
||||||
self.wallet = wallet
|
self.wallet = wallet
|
||||||
NetworkJobOnDefaultServer.__init__(self, network)
|
NetworkJobOnDefaultServer.__init__(self, network)
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ from .util import (NotEnoughFunds, PrintError, UserCancelled, profiler,
|
||||||
from .bitcoin import *
|
from .bitcoin import *
|
||||||
from .version import *
|
from .version import *
|
||||||
from .keystore import load_keystore, Hardware_KeyStore
|
from .keystore import load_keystore, Hardware_KeyStore
|
||||||
from .storage import multisig_type, STO_EV_PLAINTEXT, STO_EV_USER_PW, STO_EV_XPUB_PW
|
from .storage import multisig_type, STO_EV_PLAINTEXT, STO_EV_USER_PW, STO_EV_XPUB_PW, WalletStorage
|
||||||
from . import transaction, bitcoin, coinchooser, paymentrequest, contacts
|
from . import transaction, bitcoin, coinchooser, paymentrequest, contacts
|
||||||
from .transaction import Transaction, TxOutput, TxOutputHwInfo
|
from .transaction import Transaction, TxOutput, TxOutputHwInfo
|
||||||
from .plugin import run_hook
|
from .plugin import run_hook
|
||||||
|
@ -57,6 +57,9 @@ from .address_synchronizer import (AddressSynchronizer, TX_HEIGHT_LOCAL,
|
||||||
from .paymentrequest import PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED
|
from .paymentrequest import PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED
|
||||||
from .paymentrequest import InvoiceStore
|
from .paymentrequest import InvoiceStore
|
||||||
from .contacts import Contacts
|
from .contacts import Contacts
|
||||||
|
from .network import Network
|
||||||
|
from .simple_config import SimpleConfig
|
||||||
|
|
||||||
|
|
||||||
TX_STATUS = [
|
TX_STATUS = [
|
||||||
_('Unconfirmed'),
|
_('Unconfirmed'),
|
||||||
|
@ -67,18 +70,18 @@ TX_STATUS = [
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def relayfee(network):
|
def relayfee(network: Network):
|
||||||
from .simple_config import FEERATE_DEFAULT_RELAY
|
from .simple_config import FEERATE_DEFAULT_RELAY
|
||||||
MAX_RELAY_FEE = 50000
|
MAX_RELAY_FEE = 50000
|
||||||
f = network.relay_fee if network and network.relay_fee else FEERATE_DEFAULT_RELAY
|
f = network.relay_fee if network and network.relay_fee else FEERATE_DEFAULT_RELAY
|
||||||
return min(f, MAX_RELAY_FEE)
|
return min(f, MAX_RELAY_FEE)
|
||||||
|
|
||||||
def dust_threshold(network):
|
def dust_threshold(network: Network):
|
||||||
# Change <= dust threshold is added to the tx fee
|
# Change <= dust threshold is added to the tx fee
|
||||||
return 182 * 3 * relayfee(network) / 1000
|
return 182 * 3 * relayfee(network) / 1000
|
||||||
|
|
||||||
|
|
||||||
def append_utxos_to_inputs(inputs, network, pubkey, txin_type, imax):
|
def append_utxos_to_inputs(inputs, network: Network, pubkey, txin_type, imax):
|
||||||
if txin_type != 'p2pk':
|
if txin_type != 'p2pk':
|
||||||
address = bitcoin.pubkey_to_address(txin_type, pubkey)
|
address = bitcoin.pubkey_to_address(txin_type, pubkey)
|
||||||
scripthash = bitcoin.address_to_scripthash(address)
|
scripthash = bitcoin.address_to_scripthash(address)
|
||||||
|
@ -101,7 +104,7 @@ def append_utxos_to_inputs(inputs, network, pubkey, txin_type, imax):
|
||||||
item['num_sig'] = 1
|
item['num_sig'] = 1
|
||||||
inputs.append(item)
|
inputs.append(item)
|
||||||
|
|
||||||
def sweep_preparations(privkeys, network, imax=100):
|
def sweep_preparations(privkeys, network: Network, imax=100):
|
||||||
|
|
||||||
def find_utxos_for_privkey(txin_type, privkey, compressed):
|
def find_utxos_for_privkey(txin_type, privkey, compressed):
|
||||||
pubkey = ecc.ECPrivkey(privkey).get_public_key_hex(compressed=compressed)
|
pubkey = ecc.ECPrivkey(privkey).get_public_key_hex(compressed=compressed)
|
||||||
|
@ -127,7 +130,7 @@ def sweep_preparations(privkeys, network, imax=100):
|
||||||
return inputs, keypairs
|
return inputs, keypairs
|
||||||
|
|
||||||
|
|
||||||
def sweep(privkeys, network, config, recipient, fee=None, imax=100):
|
def sweep(privkeys, network: Network, config: SimpleConfig, recipient, fee=None, imax=100):
|
||||||
inputs, keypairs = sweep_preparations(privkeys, network, imax)
|
inputs, keypairs = sweep_preparations(privkeys, network, imax)
|
||||||
total = sum(i.get('value') for i in inputs)
|
total = sum(i.get('value') for i in inputs)
|
||||||
if fee is None:
|
if fee is None:
|
||||||
|
@ -164,7 +167,7 @@ class Abstract_Wallet(AddressSynchronizer):
|
||||||
gap_limit_for_change = 6
|
gap_limit_for_change = 6
|
||||||
verbosity_filter = 'w'
|
verbosity_filter = 'w'
|
||||||
|
|
||||||
def __init__(self, storage):
|
def __init__(self, storage: WalletStorage):
|
||||||
AddressSynchronizer.__init__(self, storage)
|
AddressSynchronizer.__init__(self, storage)
|
||||||
|
|
||||||
# saved fields
|
# saved fields
|
||||||
|
@ -220,9 +223,6 @@ class Abstract_Wallet(AddressSynchronizer):
|
||||||
if not bitcoin.is_address(addrs[0]):
|
if not bitcoin.is_address(addrs[0]):
|
||||||
raise WalletFileException('The addresses in this wallet are not bitcoin addresses.')
|
raise WalletFileException('The addresses in this wallet are not bitcoin addresses.')
|
||||||
|
|
||||||
def synchronize(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def calc_unused_change_addresses(self):
|
def calc_unused_change_addresses(self):
|
||||||
with self.lock:
|
with self.lock:
|
||||||
if hasattr(self, '_unused_change_addresses'):
|
if hasattr(self, '_unused_change_addresses'):
|
||||||
|
|
|
@ -27,7 +27,7 @@ import os
|
||||||
import json
|
import json
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import asyncio
|
import asyncio
|
||||||
from typing import Dict, List, Tuple
|
from typing import Dict, List, Tuple, TYPE_CHECKING
|
||||||
import traceback
|
import traceback
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
@ -40,6 +40,11 @@ from .util import PrintError
|
||||||
from . import bitcoin
|
from . import bitcoin
|
||||||
from .synchronizer import SynchronizerBase
|
from .synchronizer import SynchronizerBase
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .network import Network
|
||||||
|
from .simple_config import SimpleConfig
|
||||||
|
|
||||||
|
|
||||||
request_queue = asyncio.Queue()
|
request_queue = asyncio.Queue()
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,7 +66,7 @@ class ElectrumWebSocket(WebSocket, PrintError):
|
||||||
|
|
||||||
class BalanceMonitor(SynchronizerBase):
|
class BalanceMonitor(SynchronizerBase):
|
||||||
|
|
||||||
def __init__(self, config, network):
|
def __init__(self, config: 'SimpleConfig', network: 'Network'):
|
||||||
SynchronizerBase.__init__(self, network)
|
SynchronizerBase.__init__(self, network)
|
||||||
self.config = config
|
self.config = config
|
||||||
self.expected_payments = defaultdict(list) # type: Dict[str, List[Tuple[WebSocket, int]]]
|
self.expected_payments = defaultdict(list) # type: Dict[str, List[Tuple[WebSocket, int]]]
|
||||||
|
@ -104,7 +109,7 @@ class BalanceMonitor(SynchronizerBase):
|
||||||
|
|
||||||
class WebSocketServer(threading.Thread):
|
class WebSocketServer(threading.Thread):
|
||||||
|
|
||||||
def __init__(self, config, network):
|
def __init__(self, config: 'SimpleConfig', network: 'Network'):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
self.config = config
|
self.config = config
|
||||||
self.network = network
|
self.network = network
|
||||||
|
|
Loading…
Add table
Reference in a new issue