From 063eebbd434d25fc7880edfd31d33d602b9ff306 Mon Sep 17 00:00:00 2001
From: xiphon <xiphon@protonmail.com>
Date: Wed, 21 Aug 2019 13:04:20 +0000
Subject: [PATCH] daemon: implement 'set_bootstrap_daemon' command

---
 src/daemon/command_parser_executor.cpp | 14 ++++++++++
 src/daemon/command_parser_executor.h   |  2 ++
 src/daemon/command_server.cpp          |  7 +++++
 src/daemon/rpc_command_executor.cpp    | 36 ++++++++++++++++++++++++++
 src/daemon/rpc_command_executor.h      |  5 ++++
 5 files changed, 64 insertions(+)

diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp
index 924447701..c1e46d00a 100644
--- a/src/daemon/command_parser_executor.cpp
+++ b/src/daemon/command_parser_executor.cpp
@@ -813,4 +813,18 @@ bool t_command_parser_executor::check_blockchain_pruning(const std::vector<std::
   return m_executor.check_blockchain_pruning();
 }
 
+bool t_command_parser_executor::set_bootstrap_daemon(const std::vector<std::string>& args)
+{
+  const size_t args_count = args.size();
+  if (args_count < 1 || args_count > 3)
+  {
+    return false;
+  }
+
+  return m_executor.set_bootstrap_daemon(
+    args[0] != "none" ? args[0] : std::string(),
+    args_count > 1 ? args[1] : std::string(),
+    args_count > 2 ? args[2] : std::string());
+}
+
 } // namespace daemonize
diff --git a/src/daemon/command_parser_executor.h b/src/daemon/command_parser_executor.h
index d39bc1c9b..25587dea8 100644
--- a/src/daemon/command_parser_executor.h
+++ b/src/daemon/command_parser_executor.h
@@ -150,6 +150,8 @@ public:
   bool check_blockchain_pruning(const std::vector<std::string>& args);
 
   bool print_net_stats(const std::vector<std::string>& args);
+
+  bool set_bootstrap_daemon(const std::vector<std::string>& args);
 };
 
 } // namespace daemonize
diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp
index aecdda52c..757e072a4 100644
--- a/src/daemon/command_server.cpp
+++ b/src/daemon/command_server.cpp
@@ -310,6 +310,13 @@ t_command_server::t_command_server(
     , std::bind(&t_command_parser_executor::check_blockchain_pruning, &m_parser, p::_1)
     , "Check the blockchain pruning."
     );
+    m_command_lookup.set_handler(
+      "set_bootstrap_daemon"
+    , std::bind(&t_command_parser_executor::set_bootstrap_daemon, &m_parser, p::_1)
+    , "set_bootstrap_daemon (auto | none | host[:port] [username] [password])"
+    , "URL of a 'bootstrap' remote daemon that the connected wallets can use while this daemon is still not fully synced.\n"
+      "Use 'auto' to enable automatic public nodes discovering and bootstrap daemon switching"
+    );
 }
 
 bool t_command_server::process_command_str(const std::string& cmd)
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index 4d3debed6..ed6f5c65e 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -2320,4 +2320,40 @@ bool t_rpc_command_executor::check_blockchain_pruning()
     return true;
 }
 
+bool t_rpc_command_executor::set_bootstrap_daemon(
+  const std::string &address,
+  const std::string &username,
+  const std::string &password)
+{
+    cryptonote::COMMAND_RPC_SET_BOOTSTRAP_DAEMON::request req;
+    cryptonote::COMMAND_RPC_SET_BOOTSTRAP_DAEMON::response res;
+    const std::string fail_message = "Unsuccessful";
+
+    req.address = address;
+    req.username = username;
+    req.password = password;
+
+    if (m_is_rpc)
+    {
+        if (!m_rpc_client->rpc_request(req, res, "/set_bootstrap_daemon", fail_message))
+        {
+            return true;
+        }
+    }
+    else
+    {
+        if (!m_rpc_server->on_set_bootstrap_daemon(req, res) || res.status != CORE_RPC_STATUS_OK)
+        {
+            tools::fail_msg_writer() << make_error(fail_message, res.status);
+            return true;
+        }
+    }
+
+    tools::success_msg_writer()
+      << "Successfully set bootstrap daemon address to "
+      << (!req.address.empty() ? req.address : "none");
+
+    return true;
+}
+
 }// namespace daemonize
diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h
index f3ed48319..c474e0a0f 100644
--- a/src/daemon/rpc_command_executor.h
+++ b/src/daemon/rpc_command_executor.h
@@ -162,6 +162,11 @@ public:
   bool check_blockchain_pruning();
 
   bool print_net_stats();
+
+  bool set_bootstrap_daemon(
+    const std::string &address,
+    const std::string &username,
+    const std::string &password);
 };
 
 } // namespace daemonize