electrum-personal-server

Maximally lightweight electrum server for a single user
git clone https://git.parazyd.org/electrum-personal-server
Log | Files | Refs | README

commit 4a9f39dd8f28c7928f82d92d82b5694038b172d8
parent 70f764ebbc92f04f78843ffd641e58ab972d0a33
Author: chris-belcher <chris-belcher@users.noreply.github.com>
Date:   Wed, 10 Apr 2019 18:10:59 +0100

Add option to disable fee rate histogram calculation

The recent increase in mempool size causes a call to getrawmempool
to be slow which causes problems especially on low powered devices
like raspberry pi.

Diffstat:
Mconfig.cfg_sample | 23++++++++++++++---------
Melectrumpersonalserver/server/common.py | 58+++++++++++++++++++++++++++++++++-------------------------
2 files changed, 47 insertions(+), 34 deletions(-)

diff --git a/config.cfg_sample b/config.cfg_sample @@ -1,12 +1,12 @@ -## Electrum Personal Server configuration file -## Comments start with # +# Electrum Personal Server configuration file +# Comments start with # [master-public-keys] -## Add electrum master public keys to this section -## Create a wallet in electrum then go Wallet -> Information to get the mpk +# 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 @@ -15,10 +15,11 @@ #multisig_wallet = 2 xpub661MyMwAqRbcFseXCwRdRVkhVuzEiskg4QUp5XpUdNf2uGXvQmnD4zcofZ1MN6Fo8PjqQ5cemJQ39f7RTwDVVputHMFjPUn8VRp2pJQMgEF xpub661MyMwAqRbcFseXCwRdRVkhVuzEiskg4QUp5XpUdNf2uGXvQmnD4zcofZ1MN6Fo8PjqQ5cemJQ39f7RTwDVVputHMFjPUn8VRp2pJQMgEF xpub661MyMwAqRbcFseXCwRdRVkhVuzEiskg4QUp5XpUdNf2uGXvQmnD4zcofZ1MN6Fo8PjqQ5cemJQ39f7RTwDVVputHMFjPUn8VRp2pJQMgEF [watch-only-addresses] -## Add addresses to this section +#Add individual addresses to this section, for example paper wallets #addr = 1DuqpoeTB9zLvVCXQG53VbMxvMkijk494n -# A space separated list is accepted + +# 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) @@ -27,8 +28,9 @@ [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 +#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 datadir = #if you dont want to use the .cookie method with datadir, uncomment to config u/p here #rpc_user = @@ -69,3 +71,6 @@ ip_whitelist = * certfile = certs/cert.crt keyfile = certs/cert.key +# Option for disabling the fee histogram +# This is useful on low powered devices at times when the mempool is large +disable_fee_histogram = false diff --git a/electrumpersonalserver/server/common.py b/electrumpersonalserver/server/common.py @@ -105,7 +105,7 @@ def on_disconnect(txmonitor): subscribed_to_headers[0] = False txmonitor.unsubscribe_all_addresses() -def handle_query(sock, line, rpc, txmonitor): +def handle_query(sock, line, rpc, txmonitor, disable_fee_histogram): logger = logging.getLogger('ELECTRUMPERSONALSERVER') logger.debug("=> " + line) try: @@ -248,26 +248,30 @@ def handle_query(sock, line, rpc, txmonitor): result = str(e) send_response(sock, query, result) elif method == "mempool.get_fee_histogram": - mempool = rpc.call("getrawmempool", [True]) - #algorithm copied from the relevant place in ElectrumX - #https://github.com/kyuupichan/electrumx/blob/e92c9bd4861c1e35989ad2773d33e01219d33280/server/mempool.py - fee_hist = defaultdict(int) - for txid, details in mempool.items(): - fee_rate = 1e8*details["fee"] // details["size"] - fee_hist[fee_rate] += details["size"] - l = list(reversed(sorted(fee_hist.items()))) - out = [] - size = 0 - r = 0 - binsize = 100000 - for fee, s in l: - size += s - if size + r > binsize: - out.append((fee, size)) - r += size - binsize - size = 0 - binsize *= 1.1 - result = out + if disable_fee_histogram: + result = [[0, 0]] + logger.debug("fee histogram disabled, sending back empty mempool") + else: + mempool = rpc.call("getrawmempool", [True]) + #algorithm copied from the relevant place in ElectrumX + #https://github.com/kyuupichan/electrumx/blob/e92c9bd4861c1e35989ad2773d33e01219d33280/server/mempool.py + fee_hist = defaultdict(int) + for txid, details in mempool.items(): + fee_rate = 1e8*details["fee"] // details["size"] + fee_hist[fee_rate] += details["size"] + l = list(reversed(sorted(fee_hist.items()))) + out = [] + size = 0 + r = 0 + binsize = 100000 + for fee, s in l: + size += s + if size + r > binsize: + out.append((fee, size)) + r += size - binsize + size = 0 + binsize *= 1.1 + result = out send_response(sock, query, result) elif method == "blockchain.estimatefee": estimate = rpc.call("estimatesmartfee", [query["params"][0]]) @@ -409,7 +413,8 @@ def create_server_socket(hostport): return server_sock def run_electrum_server(rpc, txmonitor, hostport, ip_whitelist, - poll_interval_listening, poll_interval_connected, certfile, keyfile): + poll_interval_listening, poll_interval_connected, certfile, keyfile, + disable_fee_histogram): logger = logging.getLogger('ELECTRUMPERSONALSERVER') logger.info("Starting electrum server") server_sock = create_server_socket(hostport) @@ -450,7 +455,7 @@ def run_electrum_server(rpc, txmonitor, hostport, ip_whitelist, recv_buffer = recv_buffer[lb + 1:] lb = recv_buffer.find(b'\n') handle_query(sock, line.decode("utf-8"), rpc, - txmonitor) + txmonitor, disable_fee_histogram) except socket.timeout: on_heartbeat_connected(sock, rpc, txmonitor) except (IOError, EOFError) as e: @@ -686,7 +691,7 @@ def main(): " rescan, just restart this script") else: txmonitor = transactionmonitor.TransactionMonitor(rpc, - deterministic_wallets) + deterministic_wallets, logger) if not txmonitor.build_address_history(relevant_spks_addrs): return hostport = (config.get("electrum-server", "host"), @@ -704,10 +709,13 @@ def main(): poll_interval_connected = int(config.get("bitcoin-rpc", "poll_interval_connected")) certfile, keyfile = get_certs(config) + disable_fee_histogram = config.getboolean("electrum-server", + "disable_fee_histogram", fallback=False) try: run_electrum_server(rpc, txmonitor, hostport, ip_whitelist, poll_interval_listening, - poll_interval_connected, certfile, keyfile) + poll_interval_connected, certfile, keyfile, + disable_fee_histogram) except KeyboardInterrupt: logger.info('Received KeyboardInterrupt, quitting')