| t@@ -2,11 +2,13 @@
# Electrum Personal Server configuration file
# Comments start with #
+# The most important options are towards the top of the file
+
[master-public-keys]
# Add electrum wallet master public keys to this section
# In electrum then go Wallet -> Information to get the mpk
-# any_name_works = xpub661MyMwAqRbcFseXCwRdRVkhVuzEiskg4QUp5XpUdNf2uGXvQmnD4zcofZ1MN6Fo8PjqQ5cemJQ39f7RTwDVVputHMFjPUn8VRp2pJQMgEF
+#any_name_works = xpub661MyMwAqRbcFseXCwRdRVkhVuzEiskg4QUp5XpUdNf2uGXvQmnD4zcofZ1MN6Fo8PjqQ5cemJQ39f7RTwDVVputHMFjPUn8VRp2pJQMgEF
# Multiple master public keys maybe added by simply adding another line
#my_second_wallet = xpubanotherkey
t@@ -15,23 +17,12 @@
# this example is a 2-of-3 multisig wallet
#multisig_wallet = 2 xpub661MyMwAqRbcFseXCwRdRVkhVuzEiskg4QUp5XpUdNf2uGXvQmnD4zcofZ1MN6Fo8PjqQ5cemJQ39f7RTwDVVputHMFjPUn8VRp2pJQMgEF xpub661MyMwAqRbcFseXCwRdRVkhVuzEiskg4QUp5XpUdNf2uGXvQmnD4zcofZ1MN6Fo8PjqQ5cemJQ39f7RTwDVVputHMFjPUn8VRp2pJQMgEF xpub661MyMwAqRbcFseXCwRdRVkhVuzEiskg4QUp5XpUdNf2uGXvQmnD4zcofZ1MN6Fo8PjqQ5cemJQ39f7RTwDVVputHMFjPUn8VRp2pJQMgEF
-[watch-only-addresses]
-#Add individual addresses to this section, for example paper wallets
-
-#addr = 1DuqpoeTB9zLvVCXQG53VbMxvMkijk494n
-
-# A space separated list is also accepted
-#my_test_addresses = 3Hh7QujVLqz11tiQsnUE5CSL16WEHBmiyR 1PXRLo1FQoZyF1Jhnz4qbG5x8Bo3pFpybz bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq
-
-# multiple addresses may also be added in separate lines (like master public keys above)
-#addr2 = 3anotheraddress
-
[bitcoin-rpc]
host = 127.0.0.1
port = 8332
#add the bitcoin datadir to search for the .cookie file created by the
-# node, which avoids the need to configure rpc_user/pass, leave empty to
-# have it look in the default location
+# node, which avoids the need to configure rpc_user/pass
+#leave this option empty to have it look in the default location
datadir =
#if you dont want to use the .cookie method with datadir, uncomment to config u/p here
#rpc_user =
t@@ -76,3 +67,36 @@ keyfile = certs/cert.key
# It improves server responsiveness but stops mempool-based Electrum features
# This is useful on low powered devices at times when the node mempool is large
disable_mempool_fee_histogram = false
+
+[watch-only-addresses]
+#Add individual addresses to this section, for example paper wallets
+#Dont use this section for adding entire wallets, instead use the
+# above section `master-public-keys`
+
+#addr = 1DuqpoeTB9zLvVCXQG53VbMxvMkijk494n
+
+# A space separated list is also accepted
+#my_test_addresses = 3Hh7QujVLqz11tiQsnUE5CSL16WEHBmiyR 1PXRLo1FQoZyF1Jhnz4qbG5x8Bo3pFpybz bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq
+
+# multiple addresses may also be added in separate lines (like master public keys above)
+#addr2 = 3anotheraddress
+
+
+[logging]
+# Section for configuring the logging output
+
+# The log level. Logging messages less severe than this will not be displayed
+#options are 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'
+#Information printed to the log file is always at level DEBUG
+log_level_stdout = INFO
+
+# Location of log file, leave empty to use the default location in temp dir
+log_file_location =
+
+# Whether to append to log file or delete and overwrite on startup
+append_log = false
+
+# Format to use for logging messages
+#see docs https://docs.python.org/3/library/logging.html#logging.Formatter
+log_format = %(levelname)s:%(asctime)s: %(message)s
+ |
| t@@ -1,9 +1,10 @@
import socket, time, json, datetime, struct, binascii, ssl, os, os.path
-from configparser import ConfigParser, NoSectionError, NoOptionError
+from configparser import RawConfigParser, NoSectionError, NoOptionError
from collections import defaultdict
import traceback, sys, platform
from ipaddress import ip_network, ip_address
import logging
+from tempfile import gettempdir
from electrumpersonalserver.server.jsonrpc import JsonRpc, JsonRpcError
import electrumpersonalserver.server.hashes as hashes
t@@ -606,57 +607,47 @@ def obtain_rpc_username_password(datadir):
def parse_args():
from argparse import ArgumentParser
- from tempfile import gettempdir
parser = ArgumentParser(description='Electrum Personal Server daemon')
parser.add_argument('config_file',
help='configuration file (mandatory)')
- parser.add_argument('-l', '--log', help='log file',
- default='{}/electrumpersonalserver.log'.format(
- gettempdir()))
- parser.add_argument('-a', '--appendlog', action='store_true',
- help='append to log file')
- logfmt = '%(levelname)s:%(asctime)s: %(message)s'
- parser.add_argument('-f', '--logfmt', default=logfmt,
- help='log format')
- loglvls = [l for l in ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')]
- parser.add_argument('--loglevel', default='INFO', choices=loglvls,
- help='Log level when echoing to terminal. Log file '
- + 'is always at DEBUG level')
return parser.parse_args()
#log for checking up/seeing your wallet, debug for when something has gone wrong
-def logger_config(logger, fmt, filename, logfilemode, stdout_loglevel):
- formatter = logging.Formatter(fmt)
+def logger_config(logger, config):
+ formatter = logging.Formatter(config.get("logging", "log_format",
+ fallback="%(levelname)s:%(asctime)s: %(message)s"))
logstream = logging.StreamHandler()
logstream.setFormatter(formatter)
- logstream.setLevel(stdout_loglevel)
+ logstream.setLevel(config.get("logging", "log_level_stdout", fallback=
+ "INFO"))
logger.addHandler(logstream)
- if filename:
- logfile = logging.FileHandler(filename, mode=logfilemode)
- logfile.setFormatter(formatter)
- logfile.setLevel(logging.DEBUG)
- logger.addHandler(logfile)
+ filename = config.get("logging", "log_file_location", fallback="")
+ if len(filename.strip()) == 0:
+ filename= gettempdir() + "/electrumpersonalserver.log"
+ logfile = logging.FileHandler(filename, mode=('a' if
+ config.get("logging", "append_log", fallback="false") else 'w'))
+ logfile.setFormatter(formatter)
+ logfile.setLevel(logging.DEBUG)
+ logger.addHandler(logfile)
logger.setLevel(logging.DEBUG)
- return logger
+ return logger, filename
def main():
opts = parse_args()
- logger = logging.getLogger('ELECTRUMPERSONALSERVER')
- logger = logger_config(logger, fmt=opts.logfmt, filename=opts.log,
- logfilemode='a' if opts.appendlog else 'w',
- stdout_loglevel=opts.loglevel)
- logger.info('Starting Electrum Personal Server')
- logger.info('Logging to ' + opts.log)
try:
- config = ConfigParser()
+ config = RawConfigParser()
config.read(opts.config_file)
config.options("master-public-keys")
except NoSectionError:
- logger.error("Non-existant configuration file {}".format(
+ print("ERROR: Non-existant configuration file {}".format(
opts.config_file))
return
+ logger = logging.getLogger('ELECTRUMPERSONALSERVER')
+ logger, logfilename = logger_config(logger, config)
+ logger.info('Starting Electrum Personal Server')
+ logger.info('Logging to ' + logfilename)
try:
rpc_u = config.get("bitcoin-rpc", "rpc_user")
rpc_p = config.get("bitcoin-rpc", "rpc_password")
t@@ -760,21 +751,18 @@ def search_for_block_height_of_date(datestr, rpc):
def rescan():
opts = parse_args()
- logger = logging.getLogger('ELECTRUMPERSONALSERVER')
- logger = logger_config(logger, fmt=opts.logfmt, filename=opts.log,
- logfilemode='a' if opts.appendlog else 'w',
- stdout_loglevel=opts.loglevel)
- logger.setLevel(opts.loglevel)
- logger.info('Starting the Electrum Personal Server rescan script')
- logger.info('Logging to ' + opts.log)
try:
- config = ConfigParser()
+ config = RawConfigParser()
config.read(opts.config_file)
config.options("master-public-keys")
except NoSectionError:
- logger.error("Non-existant configuration file {}".format(
+ print("ERROR: Non-existant configuration file {}".format(
opts.config_file))
return
+ logger = logging.getLogger('ELECTRUMPERSONALSERVER')
+ logger, logfilename = logger_config(logger, config)
+ logger.info('Starting Electrum Personal Server rescan script')
+ logger.info('Logging to ' + logfilename)
try:
rpc_u = config.get("bitcoin-rpc", "rpc_user")
rpc_p = config.get("bitcoin-rpc", "rpc_password") |