Browse Source

Ensure coinjoin state is reset if wallet switches.

Prior to this commit, a lock of one wallet followed by
an unlock of another, or an unlock of a new wallet, overriding
the old one, if it occurred during a running taker-side
coinjoin, would not reset the coinjoin_state to CJ_NOT_RUNNING,
resulting in an inability of the newly loaded wallet to function
correctly.
After this commit, all subservices, including the quasi-service
of taker-side coinjoin, are fully shut down whenever a wallet is
locked, or a new wallet is unlocked. This may be suboptimal (see
TODO) but is logical for now.
The main effect is to ensure that a new wallet will always start
in the correct coinjoin state (CJ_NOT_RUNNING).
Also worth noting, a running Taker will have its abort parameter
set to True on the wallet lock event, meaning that it will not
proceed to the next step on the next asynchronous message coming
from counterparties.
master
Adam Gibson 4 years ago
parent
commit
d493343858
No known key found for this signature in database
GPG Key ID: 141001A1AF77F20B
  1. 41
      jmclient/jmclient/wallet_rpc.py

41
jmclient/jmclient/wallet_rpc.py

@ -217,19 +217,40 @@ class JMWalletDaemon(Service):
return (listener_rpc, listener_ws) return (listener_rpc, listener_ws)
def stopService(self): def stopService(self):
""" Encapsulates shut down actions. """ Top-level service (JMWalletDaemon itself) shutdown.
"""
self.stopSubServices()
super().stopService()
def stopSubServices(self):
""" This:
- shuts down the wallet service, and deletes its name.
- removes the currently valid auth token.
- shuts down any other running sub-services, such as yieldgenerator.
- shuts down (aborts) any taker-side coinjoining happening.
""" """
# Currently valid authorization tokens must be removed # Currently valid authorization tokens must be removed
# from the daemon: # from the daemon:
self.cookie = None self.cookie = None
if self.wss_factory: if self.wss_factory:
self.wss_factory.valid_token = None self.wss_factory.valid_token = None
self.wallet_name = None
# if the wallet-daemon is shut down, all services # if the wallet-daemon is shut down, all services
# it encapsulates must also be shut down. # it encapsulates must also be shut down.
for name, service in self.services.items(): for name, service in self.services.items():
if service: if service:
service.stopService() service.stopService()
super().stopService() # these Services cannot be guaranteed to be
# re-startable (the WalletService for example,
# is explicitly not). So we remove these references
# after stopping.
for n in self.services:
self.services[n] = None
# taker is not currently encapsulated with a Service;
# if it is running, shut down:
if self.coinjoin_state == CJ_TAKER_RUNNING:
self.taker.aborted = True
self.taker_finished(False)
def err(self, request, message): def err(self, request, message):
""" Return errors in a standard format. """ Return errors in a standard format.
@ -370,7 +391,7 @@ class JMWalletDaemon(Service):
# are any. # are any.
# This will stop all supporting services and wipe # This will stop all supporting services and wipe
# state (so wallet, maker service and cookie/token): # state (so wallet, maker service and cookie/token):
self.stopService() self.stopSubServices()
self.services["wallet"] = WalletService(wallet) self.services["wallet"] = WalletService(wallet)
# restart callback needed, otherwise wallet creation will # restart callback needed, otherwise wallet creation will
@ -656,11 +677,12 @@ class JMWalletDaemon(Service):
# lock multiple times: # lock multiple times:
already_locked = True already_locked = True
else: else:
self.services["wallet"].stopService() # notice that here a wallet locking event shuts down
self.cookie = None # everything.
self.wss_factory.valid_token = None # TODO: changing this so a maker can run in the background
self.services["wallet"] = None # while locked, will require auto-detection of coinjoin
self.wallet_name = None # state on future unlock.
self.stopSubServices()
already_locked = False already_locked = False
return make_jmwalletd_response(request, walletname=walletname, return make_jmwalletd_response(request, walletname=walletname,
already_locked=already_locked) already_locked=already_locked)
@ -926,6 +948,9 @@ class JMWalletDaemon(Service):
raise InvalidRequestFormat() raise InvalidRequestFormat()
if not self.coinjoin_state == CJ_TAKER_RUNNING: if not self.coinjoin_state == CJ_TAKER_RUNNING:
raise ServiceNotStarted() raise ServiceNotStarted()
# prevent the next step, responding to AMP messages
# from jmdaemon backend, from continuing:
self.taker.aborted = True
self.taker_finished(False) self.taker_finished(False)
return make_jmwalletd_response(request, status=202) return make_jmwalletd_response(request, status=202)

Loading…
Cancel
Save