From a8e0a4ab24095a65e0d4e01ad27c4388f6f764b5 Mon Sep 17 00:00:00 2001 From: Adam Gibson Date: Sun, 20 Mar 2022 17:31:18 +0000 Subject: [PATCH] Make commitmentlist be in datadir by default. Prior to this commit, the file commitmentlist, which stores commitments (podle) for makers to let them blacklist/prevent reuse was stored in the local directory for the script, which allowed remote running of jmdaemon but was very unhelpful for any situation where multiple bots are running at once, e.g. in testing or using multiple wallets against the same codebase. This could result in incorrect rejection of coinjoins. After this commit, by default, the commitmentlist file is stored in datadir/cmtdata/commitmentlist, so it will be local to any custom data directory as would be the case for running multiple wallets on the same machine. A user can set the POLICY variable commitment_list_location to "." to revert to the previous behaviour. --- jmbase/jmbase/commands.py | 3 ++- jmbase/test/test_commands.py | 7 ++++--- jmclient/jmclient/client_protocol.py | 6 ++++-- jmclient/jmclient/configure.py | 13 +++++++++++++ jmclient/test/test_client_protocol.py | 4 ++-- jmdaemon/jmdaemon/daemon_protocol.py | 11 +++++++++-- jmdaemon/test/test_daemon_protocol.py | 5 +++-- 7 files changed, 37 insertions(+), 12 deletions(-) diff --git a/jmbase/jmbase/commands.py b/jmbase/jmbase/commands.py index a937b7ce9..498b96ee0 100644 --- a/jmbase/jmbase/commands.py +++ b/jmbase/jmbase/commands.py @@ -34,7 +34,8 @@ class JMInit(JMCommand): (b'irc_configs', JsonEncodable()), (b'minmakers', Integer()), (b'maker_timeout_sec', Integer()), - (b'dust_threshold', Integer())] + (b'dust_threshold', Integer()), + (b'blacklist_location', Unicode())] errors = {DaemonNotReady: b'daemon is not ready'} class JMStartMC(JMCommand): diff --git a/jmbase/test/test_commands.py b/jmbase/test/test_commands.py index 3971670ee..c6e4100b6 100644 --- a/jmbase/test/test_commands.py +++ b/jmbase/test/test_commands.py @@ -44,9 +44,9 @@ class JMTestServerProtocol(JMBaseProtocol): @JMInit.responder def on_JM_INIT(self, bcsource, network, irc_configs, minmakers, - maker_timeout_sec, dust_threshold): + maker_timeout_sec, dust_threshold, blacklist_location): show_receipt("JMINIT", bcsource, network, irc_configs, minmakers, - maker_timeout_sec, dust_threshold) + maker_timeout_sec, dust_threshold, blacklist_location) d = self.callRemote(JMInitProto, nick_hash_length=1, nick_max_encoded=2, @@ -140,7 +140,8 @@ def clientStart(self): irc_configs=['dummy', 'irc', 'config'], minmakers=7, maker_timeout_sec=8, - dust_threshold=1500) + dust_threshold=1500, + blacklist_location=".") self.defaultCallbacks(d) @JMInitProto.responder diff --git a/jmclient/jmclient/client_protocol.py b/jmclient/jmclient/client_protocol.py index 4ecb4bf7d..68ea865ac 100644 --- a/jmclient/jmclient/client_protocol.py +++ b/jmclient/jmclient/client_protocol.py @@ -445,7 +445,8 @@ def clientStart(self): irc_configs=irc_configs, minmakers=minmakers, maker_timeout_sec=maker_timeout_sec, - dust_threshold=jm_single().DUST_THRESHOLD) + dust_threshold=jm_single().DUST_THRESHOLD, + blacklist_location=jm_single().commitment_list_location) self.defaultCallbacks(d) @commands.JMFidelityBondProofRequest.responder @@ -616,7 +617,8 @@ def clientStart(self): irc_configs=irc_configs, minmakers=minmakers, maker_timeout_sec=maker_timeout_sec, - dust_threshold=jm_single().DUST_THRESHOLD) + dust_threshold=jm_single().DUST_THRESHOLD, + blacklist_location=jm_single().commitment_list_location) self.defaultCallbacks(d) def stallMonitor(self, schedule_index): diff --git a/jmclient/jmclient/configure.py b/jmclient/jmclient/configure.py index dc8849da9..adeb77178 100644 --- a/jmclient/jmclient/configure.py +++ b/jmclient/jmclient/configure.py @@ -383,6 +383,12 @@ def jm_single(): # and those you want to use in future), relative to the scripts directory. commit_file_location = cmtdata/commitments.json +# Location of the file used by makers to keep track of used/blacklisted +# commitments. For remote daemon, set to `.` to have it stored locally +# (but note that *all* bots using the same code installation share it, +# in this case, which can be bad in testing). +commitment_list_location = cmtdata/commitmentlist + ############################## # END OF ANTI-SNOOPING SETTINGS ############################## @@ -727,6 +733,13 @@ def load_program_config(config_path="", bs=None, plugin_services=[]): set_commitment_file(os.path.join(config_path, global_singleton.commit_file_location)) + if global_singleton.config.get("POLICY", "commitment_list_location") == ".": + # Exceptional case as explained in comment in joinmarket.cfg: + global_singleton.commitment_list_location = "." + else: + global_singleton.commitment_list_location = os.path.join(config_path, + global_singleton.config.get("POLICY", "commitment_list_location")) + for p in plugin_services: # for now, at this config level, the only significance # of a "plugin" is that it keeps its own separate log. diff --git a/jmclient/test/test_client_protocol.py b/jmclient/test/test_client_protocol.py index f77f446b3..d60adcbff 100644 --- a/jmclient/test/test_client_protocol.py +++ b/jmclient/test/test_client_protocol.py @@ -168,9 +168,9 @@ class JMTestServerProtocol(JMBaseProtocol): @JMInit.responder def on_JM_INIT(self, bcsource, network, irc_configs, minmakers, - maker_timeout_sec, dust_threshold): + maker_timeout_sec, dust_threshold, blacklist_location): show_receipt("JMINIT", bcsource, network, irc_configs, minmakers, - maker_timeout_sec, dust_threshold) + maker_timeout_sec, dust_threshold, blacklist_location) d = self.callRemote(JMInitProto, nick_hash_length=1, nick_max_encoded=2, diff --git a/jmdaemon/jmdaemon/daemon_protocol.py b/jmdaemon/jmdaemon/daemon_protocol.py index 60b1294c0..b20a55107 100644 --- a/jmdaemon/jmdaemon/daemon_protocol.py +++ b/jmdaemon/jmdaemon/daemon_protocol.py @@ -66,6 +66,12 @@ def func_wrapper(inst, *args, **kwargs): return None return func_wrapper +# the location of the file +blacklist_location = None +def set_blacklist_location(location): + global blacklist_location + blacklist_location = location + def check_utxo_blacklist(commitment, persist=False): """Compare a given commitment with the persisted blacklist log file, which is hardcoded to this directory and name 'commitmentlist' (no @@ -75,7 +81,7 @@ def check_utxo_blacklist(commitment, persist=False): If flagged, persist the usage of this commitment to the above file. """ #TODO format error checking? - fname = "commitmentlist" + fname = blacklist_location if os.path.isfile(fname): with open(fname, "rb") as f: blacklisted_commitments = [x.decode('ascii').strip() for x in f.readlines()] @@ -498,7 +504,7 @@ def defaultCallbacks(self, d): @JMInit.responder def on_JM_INIT(self, bcsource, network, irc_configs, minmakers, - maker_timeout_sec, dust_threshold): + maker_timeout_sec, dust_threshold, blacklist_location): """Reads in required configuration from client for a new session; feeds back joinmarket messaging protocol constants (required for nick creation). @@ -507,6 +513,7 @@ def on_JM_INIT(self, bcsource, network, irc_configs, minmakers, """ self.maker_timeout_sec = maker_timeout_sec self.minmakers = minmakers + set_blacklist_location(blacklist_location) self.dust_threshold = int(dust_threshold) #(bitcoin) network only referenced in channel name construction self.network = network diff --git a/jmdaemon/test/test_daemon_protocol.py b/jmdaemon/test/test_daemon_protocol.py index 002e517e4..71beba734 100644 --- a/jmdaemon/test/test_daemon_protocol.py +++ b/jmdaemon/test/test_daemon_protocol.py @@ -66,7 +66,8 @@ def clientStart(self): irc_configs=irc, minmakers=2, maker_timeout_sec=3, - dust_threshold=27300) + dust_threshold=27300, + blacklist_location=".") self.defaultCallbacks(d) @JMInitProto.responder @@ -212,7 +213,7 @@ def on_JM_REQUEST_OFFERS(self): @JMInit.responder def on_JM_INIT(self, bcsource, network, irc_configs, minmakers, - maker_timeout_sec, dust_threshold): + maker_timeout_sec, dust_threshold, blacklist_location): self.maker_timeout_sec = maker_timeout_sec self.dust_threshold = int(dust_threshold) self.minmakers = minmakers