From 5985c5afe8051ef9933212e62293ece3634a5024 Mon Sep 17 00:00:00 2001
From: moneromooo-monero <moneromooo-monero@users.noreply.github.com>
Date: Mon, 2 Dec 2019 18:51:28 +0000
Subject: [PATCH] rpc: add bad-blocks to flush_cache RPC

Flushes m_invalid_blocks in Blockchain.
---
 src/cryptonote_core/blockchain.cpp      |  7 +++++++
 src/cryptonote_core/blockchain.h        |  5 +++++
 src/cryptonote_core/cryptonote_core.cpp |  4 ++++
 src/cryptonote_core/cryptonote_core.h   |  5 +++++
 src/daemon/command_parser_executor.cpp  | 20 +++++++++++++++++---
 src/daemon/command_server.cpp           |  2 +-
 src/daemon/rpc_command_executor.cpp     |  3 ++-
 src/daemon/rpc_command_executor.h       |  2 +-
 src/rpc/core_rpc_server.cpp             |  2 ++
 src/rpc/core_rpc_server_commands_defs.h |  4 +++-
 10 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index d22158dfc..733ac5bcd 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -2534,6 +2534,13 @@ bool Blockchain::add_block_as_invalid(const block_extended_info& bei, const cryp
   return true;
 }
 //------------------------------------------------------------------
+void Blockchain::flush_invalid_blocks()
+{
+  LOG_PRINT_L3("Blockchain::" << __func__);
+  CRITICAL_REGION_LOCAL(m_blockchain_lock);
+  m_invalid_blocks.clear();
+}
+//------------------------------------------------------------------
 bool Blockchain::have_block(const crypto::hash& id) const
 {
   LOG_PRINT_L3("Blockchain::" << __func__);
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index 6467031c2..915c48f80 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -1016,6 +1016,11 @@ namespace cryptonote
      */
     bool has_block_weights(uint64_t height, uint64_t nblocks) const;
 
+    /**
+     * @brief flush the invalid blocks set
+     */
+    void flush_invalid_blocks();
+
 #ifndef IN_UNIT_TESTS
   private:
 #endif
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 02620996e..c4ef8b460 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -1921,6 +1921,10 @@ namespace cryptonote
     bad_semantics_txes_lock.unlock();
   }
   //-----------------------------------------------------------------------------------------------
+  void core::flush_invalid_blocks()
+  {
+    m_blockchain_storage.flush_invalid_blocks();
+  }
   bool core::update_blockchain_pruning()
   {
     return m_blockchain_storage.update_blockchain_pruning();
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index f69ac3509..4d86a0fcf 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -844,6 +844,11 @@ namespace cryptonote
       */
      void flush_bad_txs_cache();
 
+     /**
+      * @brief flushes the invalid block cache
+      */
+     void flush_invalid_blocks();
+
    private:
 
      /**
diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp
index b827221f6..8f06b1f01 100644
--- a/src/daemon/command_parser_executor.cpp
+++ b/src/daemon/command_parser_executor.cpp
@@ -846,13 +846,27 @@ bool t_command_parser_executor::set_bootstrap_daemon(const std::vector<std::stri
 
 bool t_command_parser_executor::flush_cache(const std::vector<std::string>& args)
 {
+  bool bad_txs = false, bad_blocks = false;
+  std::string arg;
+
   if (args.empty())
     goto show_list;
-  if (args[0] == "bad-txs")
-    return m_executor.flush_cache(true);
+
+  for (size_t i = 0; i < args.size(); ++i)
+  {
+    arg = args[i];
+    if (arg == "bad-txs")
+      bad_txs = true;
+    else if (arg == "bad-blocks")
+      bad_blocks = true;
+    else
+      goto show_list;
+  }
+  return m_executor.flush_cache(bad_txs, bad_blocks);
 
 show_list:
-  std::cout << "Cache type needed: bad-txs" << std::endl;
+  std::cout << "Invalid cache type: " << arg << std::endl;
+  std::cout << "Cache types: bad-txs bad-blocks" << std::endl;
   return true;
 }
 
diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp
index 8ec690631..7fae77c30 100644
--- a/src/daemon/command_server.cpp
+++ b/src/daemon/command_server.cpp
@@ -325,7 +325,7 @@ t_command_server::t_command_server(
     m_command_lookup.set_handler(
       "flush_cache"
     , std::bind(&t_command_parser_executor::flush_cache, &m_parser, p::_1)
-    , "flush_cache bad-txs"
+    , "flush_cache [bad-txs] [bad-blocks]"
     , "Flush the specified cache(s)."
     );
 }
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index ed614a89b..0fae9b99e 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -2373,7 +2373,7 @@ bool t_rpc_command_executor::set_bootstrap_daemon(
     return true;
 }
 
-bool t_rpc_command_executor::flush_cache(bool bad_txs)
+bool t_rpc_command_executor::flush_cache(bool bad_txs, bool bad_blocks)
 {
     cryptonote::COMMAND_RPC_FLUSH_CACHE::request req;
     cryptonote::COMMAND_RPC_FLUSH_CACHE::response res;
@@ -2381,6 +2381,7 @@ bool t_rpc_command_executor::flush_cache(bool bad_txs)
     epee::json_rpc::error error_resp;
 
     req.bad_txs = bad_txs;
+    req.bad_blocks = bad_blocks;
 
     if (m_is_rpc)
     {
diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h
index e8b12cb9b..6276d124d 100644
--- a/src/daemon/rpc_command_executor.h
+++ b/src/daemon/rpc_command_executor.h
@@ -170,7 +170,7 @@ public:
 
   bool rpc_payments();
 
-  bool flush_cache(bool bad_txs);
+  bool flush_cache(bool bad_txs, bool invalid_blocks);
 };
 
 } // namespace daemonize
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 9117b5b3a..2438b3045 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -3004,6 +3004,8 @@ namespace cryptonote
     RPC_TRACKER(flush_cache);
     if (req.bad_txs)
       m_core.flush_bad_txs_cache();
+    if (req.bad_blocks)
+      m_core.flush_invalid_blocks();
     res.status = CORE_RPC_STATUS_OK;
     return true;
   }
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 855ea854c..c3ee866bb 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -88,7 +88,7 @@ namespace cryptonote
 // advance which version they will stop working with
 // Don't go over 32767 for any of these
 #define CORE_RPC_VERSION_MAJOR 3
-#define CORE_RPC_VERSION_MINOR 0
+#define CORE_RPC_VERSION_MINOR 1
 #define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
 #define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
 
@@ -2559,9 +2559,11 @@ namespace cryptonote
     struct request_t
     {
       bool bad_txs;
+      bool bad_blocks;
 
       BEGIN_KV_SERIALIZE_MAP()
         KV_SERIALIZE_OPT(bad_txs, false)
+        KV_SERIALIZE_OPT(bad_blocks, false)
       END_KV_SERIALIZE_MAP()
     };
     typedef epee::misc_utils::struct_init<request_t> request;