Browse Source

wizard: copy/restore storage when stepping through the wizard

When interacting with wizard, there is a single shared storage instance.
If you go down the tree of dialogs, press "back" a couple times, go
down another branch of dialogs, etc, there are side-effects on storage,
which are never undone.

fixes #5057
fixes #4496
sqlite_db
SomberNight 6 years ago
parent
commit
8412b53ed5
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 27
      electrum/base_wizard.py
  2. 14
      electrum/storage.py

27
electrum/base_wizard.py

@ -27,7 +27,7 @@ import os
import sys
import traceback
from functools import partial
from typing import List, TYPE_CHECKING, Tuple
from typing import List, TYPE_CHECKING, Tuple, NamedTuple, Any
from . import bitcoin
from . import keystore
@ -56,6 +56,12 @@ class ScriptTypeNotSupported(Exception): pass
class GoBack(Exception): pass
class WizardStackItem(NamedTuple):
action: Any
args: Any
storage_data: dict
class BaseWizard(object):
def __init__(self, config: SimpleConfig, plugins: Plugins, storage: WalletStorage):
@ -64,7 +70,7 @@ class BaseWizard(object):
self.plugins = plugins
self.storage = storage
self.wallet = None # type: Abstract_Wallet
self._stack = []
self._stack = [] # type: List[WizardStackItem]
self.plugin = None
self.keystores = []
self.is_kivy = config.get('gui') == 'kivy'
@ -76,7 +82,8 @@ class BaseWizard(object):
def run(self, *args):
action = args[0]
args = args[1:]
self._stack.append((action, args))
storage_data = self.storage.get_all_data()
self._stack.append(WizardStackItem(action, args, storage_data))
if not action:
return
if type(action) is tuple:
@ -96,9 +103,15 @@ class BaseWizard(object):
def go_back(self):
if not self.can_go_back():
return
# pop 'current' frame
self._stack.pop()
action, args = self._stack.pop()
self.run(action, *args)
# pop 'previous' frame
stack_item = self._stack.pop()
# try to undo side effects since we last entered 'previous' frame
# FIXME only self.storage is properly restored
self.storage.overwrite_all_data(stack_item.storage_data)
# rerun 'previous' frame
self.run(stack_item.action, *stack_item.args)
def reset_stack(self):
self._stack = []
@ -154,8 +167,8 @@ class BaseWizard(object):
def choose_multisig(self):
def on_multisig(m, n):
self.multisig_type = "%dof%d"%(m, n)
self.storage.put('wallet_type', self.multisig_type)
multisig_type = "%dof%d" % (m, n)
self.storage.put('wallet_type', multisig_type)
self.n = n
self.run('choose_keystore')
self.multisig_dialog(run_next=on_multisig)

14
electrum/storage.py

@ -101,6 +101,20 @@ class JsonDB(PrintError):
self.modified = True
self.data.pop(key)
def get_all_data(self) -> dict:
with self.db_lock:
return copy.deepcopy(self.data)
def overwrite_all_data(self, data: dict) -> None:
try:
json.dumps(data, cls=util.MyEncoder)
except:
self.print_error(f"json error: cannot save {repr(data)}")
return
with self.db_lock:
self.modified = True
self.data = copy.deepcopy(data)
@profiler
def write(self):
with self.db_lock:

Loading…
Cancel
Save