Skip to content

Commit e6a3399

Browse files
committed
electrum plugin: Automatically enable --skipmerklecheck and --electrum-skip-merkle
For better out-of-the-box pruning support, and to save some resources. This also changes the way the server/oneserver/skipmerklecheck settings are set, to reduce the risk of accidentally connecting to public servers with inappropriate settings: - The configurations are no longer persisted to the config file and will get lost on restart, unless the plugin explicitly re-enables them. - The GUI for changing servers is disabled while the plugin is active, preventing the user from switching servers with the settings still on.
1 parent f868aca commit e6a3399

File tree

3 files changed

+52
-16
lines changed

3 files changed

+52
-16
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22

33
## Unreleased
44

5-
- Electrum: Implement `--electrum-skip-merkle` to avoid generating SPV proofs entirely, even when it's possible. (#34)
5+
- Electrum server: Implement `--electrum-skip-merkle` to save some resources by not generating SPV proofs entirely, even when it's possible. (#34)
6+
7+
- Electrum plugin: Automatically enable `--skipmerklecheck` and `--electrum-skip-merkle`, for better out-of-the-box pruning support and to save some resources. (#34)
68

79
- Indexer: Use `listsinceblock` instead of `listtransactions`. This makes syncing more bandwidth-efficient and simplifies the implementation. (#33)
810

11+
- Electrum server: Optimize dispatching notifications to subscribers.
12+
913
## 0.1.3 - 2020-06-02
1014

1115
- Electrum: Use dummy SPV proofs to support pruning with the `--skipmerklecheck` option.

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,9 @@ You can use bwt with pruning, but:
171171

172172
2. Electrum needs to be run with `--skipmerklecheck` to tolerate missing SPV proofs for transactions in pruned blocks.
173173

174-
If you're running Electrum with `--skipmerklecheck`, you may also configure bwt with `--electrum-skip-merkle` to save some resource by not generating SPV proofs even when it's possible.
174+
> If you're running Electrum with `--skipmerklecheck`, you may also configure bwt with `--electrum-skip-merkle` to save some resources by not generating SPV proofs even when it's possible.
175+
>
176+
> Both of these settings are automatically enabled when using the Electrum plugin.
175177
176178
### Real-time indexing
177179

contrib/electrum-plugin/bwt.py

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@
2020
bwt_bin = '%s.exe' % bwt_bin
2121

2222
class BwtPlugin(BasePlugin):
23+
wallets = set()
24+
proc = None
25+
prev_settings = None
2326

2427
def __init__(self, parent, config, name):
2528
BasePlugin.__init__(self, parent, config, name)
26-
self.proc = None
27-
self.wallets = set()
2829

2930
self.enabled = config.get('bwt_enabled')
3031
self.bitcoind_url = config.get('bwt_bitcoind_url', default_bitcoind_url())
@@ -36,22 +37,24 @@ def __init__(self, parent, config, name):
3637
self.socket_path = config.get('bwt_socket_path', default_socket_path())
3738
self.verbose = config.get('bwt_verbose', 0)
3839

39-
if config.get('bwt_was_oneserver') is None:
40-
config.set_key('bwt_was_oneserver', config.get('oneserver'))
41-
42-
self.start()
40+
if self.enabled:
41+
self.set_config()
42+
self.start()
4343

4444
def start(self):
4545
if not self.enabled or not self.wallets:
4646
return
4747

48+
self.stop()
49+
4850
self.rpc_port = free_port()
4951

5052
args = [
5153
'--network', get_network_name(),
5254
'--bitcoind-url', self.bitcoind_url,
5355
'--bitcoind-dir', self.bitcoind_dir,
5456
'--electrum-rpc-addr', '127.0.0.1:%d' % self.rpc_port,
57+
'--electrum-skip-merkle',
5558
]
5659

5760
if self.bitcoind_cred:
@@ -74,8 +77,9 @@ def start(self):
7477
# XXX this doesn't support arguments with spaces. thankfully bwt doesn't currently have any.
7578
args.extend(self.custom_opt.split(' '))
7679

77-
self.stop()
78-
_logger.info('Starting bwt daemon')
80+
self.set_config()
81+
82+
_logger.info('Starting the bwt daemon')
7983
_logger.debug('bwt options: %s' % ' '.join(args))
8084

8185
if platform.system() == 'Windows':
@@ -91,12 +95,34 @@ def start(self):
9195

9296
def stop(self):
9397
if self.proc:
94-
_logger.info('Stopping bwt daemon')
98+
_logger.info('Stopping the bwt daemon')
9599
self.proc.terminate()
96100
self.proc = None
97101
self.thread = None
98102

103+
# enable oneserver/skipmerklecheck and disable manual server selection
104+
def set_config(self):
105+
if self.prev_settings: return # run once
106+
107+
self.prev_settings = { setting: self.config.cmdline_options.get(setting)
108+
for setting in [ 'oneserver', 'skipmerklecheck', 'server' ] }
109+
110+
# setting `oneserver`/`skipmerklecheck` directly on `cmdline_options` keeps the settings in-memory only without
111+
# persisting them to the config file, reducing the chance of accidentally leaving them on with public servers.
112+
self.config.cmdline_options['oneserver'] = True
113+
114+
# for `skipmerklecheck`, this is also the only way to set it an runtime prior to v4 (see https://github.com/spesmilo/electrum/commit/61ccc1ccd3a437d98084089f1d4014ba46c96e3b)
115+
self.config.cmdline_options['skipmerklecheck'] = True
116+
117+
# set a dummy server so electrum won't attempt connecting to other servers on startup. setting this
118+
# in `cmdline_options` also prevents the user from switching servers using the gui, which further reduces
119+
# the chance of accidentally connecting to public servers with inappropriate settings.
120+
self.config.cmdline_options['server'] = '127.0.0.1:1:t'
121+
99122
def set_server(self):
123+
# first, remove the `server` config to allow `set_parameters()` below to update it and trigger the connection mechanism
124+
del self.config.cmdline_options['server']
125+
100126
network = Network.get_instance()
101127
net_params = network.get_parameters()._replace(
102128
host='127.0.0.1',
@@ -106,6 +132,9 @@ def set_server(self):
106132
)
107133
network.run_from_another_thread(network.set_parameters(net_params))
108134

135+
# now set the server in `cmdline_options` to lock it in
136+
self.config.cmdline_options['server'] = '127.0.0.1:%s:t' % self.rpc_port
137+
109138
@hook
110139
def load_wallet(self, wallet, main_window):
111140
if wallet.get_master_public_keys():
@@ -126,11 +155,12 @@ def close(self):
126155
BasePlugin.close(self)
127156
self.stop()
128157

129-
# restore the user's previous oneserver setting when the plugin is disabled
130-
was_oneserver = self.config.get('bwt_was_oneserver')
131-
if was_oneserver is not None:
132-
self.config.set_key('oneserver', was_oneserver)
133-
self.config.set_key('bwt_was_oneserver', None)
158+
# restore the user's previous settings when the plugin is disabled
159+
if self.prev_settings:
160+
for setting, prev_value in self.prev_settings.items():
161+
if prev_value is None: self.config.cmdline_options.pop(setting, None)
162+
else: self.config.cmdline_options[setting] = prev_value
163+
self.prev_settings = None
134164

135165
def handle_log(self, level, pkg, msg):
136166
if msg.startswith('Electrum RPC server running'):

0 commit comments

Comments
 (0)