From 57300491781af47bdb58d9c8f9a82252564d35c6 Mon Sep 17 00:00:00 2001
From: moneromooo-monero <moneromooo-monero@users.noreply.github.com>
Date: Wed, 21 Mar 2018 14:29:49 +0000
Subject: [PATCH] wallet: catch exceptions dealing with ringdb and warn

---
 src/simplewallet/simplewallet.cpp |  3 ++
 src/wallet/wallet2.cpp            | 63 +++++++++++++++++++++----------
 src/wallet/wallet2.h              |  2 +-
 3 files changed, 48 insertions(+), 20 deletions(-)

diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 97dadb126..4e06c4692 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -3101,6 +3101,9 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
   if (!m_trusted_daemon)
     message_writer() << (boost::format(tr("Warning: using an untrusted daemon at %s, privacy will be lessened")) % m_wallet->get_daemon_address()).str();
 
+  if (m_wallet->get_ring_database().empty())
+    fail_msg_writer() << tr("Failed to initialize ring database: privacy enhancing features will be inactive");
+
   m_wallet->callback(this);
 
   return true;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 4b7e6dd93..0f3201fdf 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -5467,29 +5467,43 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
   }
 }
 
-void wallet2::set_ring_database(const std::string &filename)
+bool wallet2::set_ring_database(const std::string &filename)
 {
   m_ring_database = filename;
   MINFO("ringdb path set to " << filename);
   m_ringdb.reset();
-  cryptonote::block b;
-  generate_genesis(b);
   if (!m_ring_database.empty())
-    m_ringdb.reset(new tools::ringdb(m_ring_database, epee::string_tools::pod_to_hex(get_block_hash(b))));
+  {
+    try
+    {
+      cryptonote::block b;
+      generate_genesis(b);
+      m_ringdb.reset(new tools::ringdb(m_ring_database, epee::string_tools::pod_to_hex(get_block_hash(b))));
+    }
+    catch (const std::exception &e)
+    {
+      MERROR("Failed to initialize ringdb: " << e.what());
+      m_ring_database = "";
+      return false;
+    }
+  }
+  return true;
 }
 
 bool wallet2::add_rings(const crypto::chacha_key &key, const cryptonote::transaction_prefix &tx)
 {
   if (!m_ringdb)
     return true;
-  return m_ringdb->add_rings(key, tx);
+  try { return m_ringdb->add_rings(key, tx); }
+  catch (const std::exception &e) { return false; }
 }
 
 bool wallet2::add_rings(const cryptonote::transaction_prefix &tx)
 {
   crypto::chacha_key key;
   generate_chacha_key_from_secret_keys(key);
-  return add_rings(key, tx);
+  try { return add_rings(key, tx); }
+  catch (const std::exception &e) { return false; }
 }
 
 bool wallet2::remove_rings(const cryptonote::transaction_prefix &tx)
@@ -5498,14 +5512,16 @@ bool wallet2::remove_rings(const cryptonote::transaction_prefix &tx)
     return true;
   crypto::chacha_key key;
   generate_chacha_key_from_secret_keys(key);
-  return m_ringdb->remove_rings(key, tx);
+  try { return m_ringdb->remove_rings(key, tx); }
+  catch (const std::exception &e) { return false; }
 }
 
 bool wallet2::get_ring(const crypto::chacha_key &key, const crypto::key_image &key_image, std::vector<uint64_t> &outs)
 {
   if (!m_ringdb)
     return true;
-  return m_ringdb->get_ring(key, key_image, outs);
+  try { return m_ringdb->get_ring(key, key_image, outs); }
+  catch (const std::exception &e) { return false; }
 }
 
 bool wallet2::get_rings(const crypto::hash &txid, std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> &outs)
@@ -5536,7 +5552,8 @@ bool wallet2::get_ring(const crypto::key_image &key_image, std::vector<uint64_t>
   crypto::chacha_key key;
   generate_chacha_key_from_secret_keys(key);
 
-  return get_ring(key, key_image, outs);
+  try { return get_ring(key, key_image, outs); }
+  catch (const std::exception &e) { return false; }
 }
 
 bool wallet2::set_ring(const crypto::key_image &key_image, const std::vector<uint64_t> &outs, bool relative)
@@ -5547,7 +5564,8 @@ bool wallet2::set_ring(const crypto::key_image &key_image, const std::vector<uin
   crypto::chacha_key key;
   generate_chacha_key_from_secret_keys(key);
 
-  return m_ringdb->set_ring(key, key_image, outs, relative);
+  try { return m_ringdb->set_ring(key, key_image, outs, relative); }
+  catch (const std::exception &e) { return false; }
 }
 
 bool wallet2::find_and_save_rings(bool force)
@@ -5615,33 +5633,40 @@ bool wallet2::blackball_output(const crypto::public_key &output)
 {
   if (!m_ringdb)
     return true;
-  return m_ringdb->blackball(output);
+  try { return m_ringdb->blackball(output); }
+  catch (const std::exception &e) { return false; }
 }
 
 bool wallet2::set_blackballed_outputs(const std::vector<crypto::public_key> &outputs, bool add)
 {
   if (!m_ringdb)
     return true;
-  bool ret = true;
-  if (!add)
-    ret &= m_ringdb->clear_blackballs();
-  for (const auto &output: outputs)
-    ret &= m_ringdb->blackball(output);
-  return ret;
+  try
+  {
+    bool ret = true;
+    if (!add)
+      ret &= m_ringdb->clear_blackballs();
+    for (const auto &output: outputs)
+      ret &= m_ringdb->blackball(output);
+    return ret;
+  }
+  catch (const std::exception &e) { return false; }
 }
 
 bool wallet2::unblackball_output(const crypto::public_key &output)
 {
   if (!m_ringdb)
     return true;
-  return m_ringdb->unblackball(output);
+  try { return m_ringdb->unblackball(output); }
+  catch (const std::exception &e) { return false; }
 }
 
 bool wallet2::is_output_blackballed(const crypto::public_key &output) const
 {
   if (!m_ringdb)
     return true;
-  return m_ringdb->blackballed(output);
+  try { return m_ringdb->blackballed(output); }
+  catch (const std::exception &e) { return false; }
 }
 
 bool wallet2::tx_add_fake_output(std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, uint64_t global_index, const crypto::public_key& output_public_key, const rct::key& mask, uint64_t real_index, bool unlocked) const
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index abc7bb538..ca8bee965 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -1061,7 +1061,7 @@ namespace tools
       return epee::net_utils::invoke_http_json_rpc(uri, method_name, req, res, m_http_client, timeout, http_method, req_id);
     }
 
-    void set_ring_database(const std::string &filename);
+    bool set_ring_database(const std::string &filename);
     const std::string get_ring_database() const { return m_ring_database; }
     bool get_ring(const crypto::key_image &key_image, std::vector<uint64_t> &outs);
     bool get_rings(const crypto::hash &txid, std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> &outs);