aboutsummaryrefslogtreecommitdiff
path: root/src/rpc/bootstrap_daemon.h
blob: 1e4477123fc7eb2ecd226a08fec0a06fdb716140 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#pragma  once

#include <functional>
#include <map>
#include <utility>

#include <boost/optional/optional.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/utility/string_ref.hpp>

#include "net/http.h"
#include "storages/http_abstract_invoke.h"

#include "bootstrap_node_selector.h"

namespace cryptonote
{

  class bootstrap_daemon
  {
  public:
    bootstrap_daemon(
      std::function<std::map<std::string, bool>()> get_public_nodes,
      bool rpc_payment_enabled,
      const std::string &proxy);
    bootstrap_daemon(
      const std::string &address,
      boost::optional<epee::net_utils::http::login> credentials,
      bool rpc_payment_enabled,
      const std::string &proxy);

    std::string address() const noexcept;
    boost::optional<std::pair<uint64_t, uint64_t>> get_height();
    bool handle_result(bool success, const std::string &status);

    template <class t_request, class t_response>
    bool invoke_http_json(const boost::string_ref uri, const t_request &out_struct, t_response &result_struct)
    {
      if (!switch_server_if_needed())
      {
        return false;
      }

      const bool result = epee::net_utils::invoke_http_json(uri, out_struct, result_struct, m_http_client);
      return handle_result(result, result_struct.status);
    }

    template <class t_request, class t_response>
    bool invoke_http_bin(const boost::string_ref uri, const t_request &out_struct, t_response &result_struct)
    {
      if (!switch_server_if_needed())
      {
        return false;
      }

      const bool result = epee::net_utils::invoke_http_bin(uri, out_struct, result_struct, m_http_client);
      return handle_result(result, result_struct.status);
    }

    template <class t_request, class t_response>
    bool invoke_http_json_rpc(const boost::string_ref command_name, const t_request &out_struct, t_response &result_struct)
    {
      if (!switch_server_if_needed())
      {
        return false;
      }

      const bool result = epee::net_utils::invoke_http_json_rpc(
        "/json_rpc",
        std::string(command_name.begin(), command_name.end()),
        out_struct,
        result_struct,
        m_http_client);
      return handle_result(result, result_struct.status);
    }

    void set_proxy(const std::string &address);

  private:
    bool set_server(const std::string &address, const boost::optional<epee::net_utils::http::login> &credentials = boost::none);
    bool switch_server_if_needed();

  private:
    net::http::client m_http_client;
    const bool m_rpc_payment_enabled;
    const std::unique_ptr<bootstrap_node::selector> m_selector;
    boost::mutex m_selector_mutex;
  };

}