Electroneum
Toggle main menu visibility
Loading...
Searching...
No Matches
daemon.cpp
Go to the documentation of this file.
1
// Copyrights(c) 2017-2021, The Electroneum Project
2
// Copyrights(c) 2014-2019, The Monero Project
3
//
4
// All rights reserved.
5
//
6
// Redistribution and use in source and binary forms, with or without modification, are
7
// permitted provided that the following conditions are met:
8
//
9
// 1. Redistributions of source code must retain the above copyright notice, this list of
10
// conditions and the following disclaimer.
11
//
12
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
13
// of conditions and the following disclaimer in the documentation and/or other
14
// materials provided with the distribution.
15
//
16
// 3. Neither the name of the copyright holder nor the names of its contributors may be
17
// used to endorse or promote products derived from this software without specific
18
// prior written permission.
19
//
20
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
//
30
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
31
32
#include <memory>
33
#include <stdexcept>
34
#include <boost/algorithm/string/split.hpp>
35
#include "
misc_log_ex.h
"
36
#include "daemon/daemon.h"
37
#include "
rpc/daemon_handler.h
"
38
#include "
rpc/zmq_server.h
"
39
40
#include "
common/password.h
"
41
#include "
common/util.h
"
42
#include "
daemon/core.h
"
43
#include "
daemon/p2p.h
"
44
#include "
daemon/protocol.h
"
45
#include "
daemon/rpc.h
"
46
#include "
daemon/command_server.h
"
47
#include "
daemon/command_server.h
"
48
#include "
daemon/command_line_args.h
"
49
#include "
net/net_ssl.h
"
50
#include "
version.h
"
51
52
using namespace
epee
;
53
54
#include <functional>
55
56
#undef ELECTRONEUM_DEFAULT_LOG_CATEGORY
57
#define ELECTRONEUM_DEFAULT_LOG_CATEGORY "daemon"
58
59
namespace
daemonize
{
60
61
struct
t_internals
{
62
private
:
63
t_protocol
protocol;
64
public
:
65
t_core
core
;
66
t_p2p
p2p
;
67
std::vector<std::unique_ptr<t_rpc>>
rpcs
;
68
69
t_internals
(
70
boost::program_options::variables_map
const
& vm
71
)
72
:
core
{vm}
73
, protocol{vm,
core
,
command_line
::get_arg(vm,
cryptonote
::arg_offline)}
74
,
p2p
{vm, protocol}
75
{
76
// Handle circular dependencies
77
protocol.set_p2p_endpoint(
p2p
.get());
78
core
.set_protocol(protocol.get());
79
80
const
auto
restricted =
command_line::get_arg
(vm,
cryptonote::core_rpc_server::arg_restricted_rpc
);
81
const
auto
main_rpc_port =
command_line::get_arg
(vm,
cryptonote::core_rpc_server::arg_rpc_bind_port
);
82
rpcs
.emplace_back(
new
t_rpc
{vm, core, p2p, restricted, main_rpc_port,
"core"
});
83
84
auto
restricted_rpc_port_arg =
cryptonote::core_rpc_server::arg_rpc_restricted_bind_port
;
85
if
(!
command_line::is_arg_defaulted
(vm, restricted_rpc_port_arg))
86
{
87
auto restricted_rpc_port = command_line::get_arg(vm, restricted_rpc_port_arg);
88
rpcs.emplace_back(new t_rpc{vm, core, p2p, true, restricted_rpc_port,
"restricted"
});
89
}
90
}
91
};
92
93
void
t_daemon::init_options
(boost::program_options::options_description & option_spec)
94
{
95
t_core::init_options
(option_spec);
96
t_p2p::init_options
(option_spec);
97
t_rpc::init_options
(option_spec);
98
}
99
100
t_daemon::t_daemon
(
101
boost::program_options::variables_map
const
& vm,
102
uint16_t
public_rpc_port
103
)
104
: mp_internals{new
t_internals
{vm}},
105
public_rpc_port(public_rpc_port)
106
{
107
zmq_rpc_bind_port =
command_line::get_arg
(vm,
daemon_args::arg_zmq_rpc_bind_port
);
108
zmq_rpc_bind_address =
command_line::get_arg
(vm,
daemon_args::arg_zmq_rpc_bind_ip
);
109
zmq_rpc_disabled =
command_line::get_arg
(vm,
daemon_args::arg_zmq_rpc_disabled
);
110
}
111
112
t_daemon::~t_daemon
() =
default
;
113
114
// MSVC is brain-dead and can't default this...
115
t_daemon::t_daemon
(
t_daemon
&& other)
116
{
117
if
(
this
!= &other)
118
{
119
mp_internals = std::move(other.mp_internals);
120
other.mp_internals.reset(
nullptr
);
121
public_rpc_port = other.public_rpc_port;
122
}
123
}
124
125
// or this
126
t_daemon
&
t_daemon::operator=
(
t_daemon
&& other)
127
{
128
if
(
this
!= &other)
129
{
130
mp_internals = std::move(other.mp_internals);
131
other.mp_internals.reset(
nullptr
);
132
public_rpc_port = other.public_rpc_port;
133
}
134
return
*
this
;
135
}
136
137
bool
t_daemon::run
(
bool
interactive)
138
{
139
if
(
nullptr
== mp_internals)
140
{
141
throw
std::runtime_error{
"Can't run stopped daemon"
};
142
}
143
144
std::atomic<bool>
stop
(
false
), shutdown(
false
);
145
boost::thread stop_thread = boost::thread([&
stop
, &shutdown,
this
] {
146
while
(!
stop
)
147
epee::misc_utils::sleep_no_w
(100);
148
if
(shutdown)
149
this->stop_p2p();
150
});
151
epee::misc_utils::auto_scope_leave_caller
scope_exit_handler =
epee::misc_utils::create_scope_leave_handler
([&](){
152
stop
=
true
;
153
stop_thread.join();
154
});
155
tools::signal_handler::install
([&
stop
, &shutdown](
int
){
stop
= shutdown =
true
; });
156
157
try
158
{
159
if
(!mp_internals->core.run())
160
return
false
;
161
162
for
(
auto
& rpc: mp_internals->rpcs)
163
rpc->run();
164
165
std::unique_ptr<daemonize::t_command_server> rpc_commands;
166
if
(interactive && mp_internals->rpcs.size())
167
{
168
// The first three variables are not used when the fourth is false
169
rpc_commands.reset(
new
daemonize::t_command_server
(0, 0, boost::none,
epee::net_utils::ssl_support_t::e_ssl_support_disabled
,
false
, mp_internals->rpcs.front()->get_server()));
170
rpc_commands->start_handling(std::bind(&daemonize::t_daemon::stop_p2p,
this
));
171
}
172
173
cryptonote::rpc::DaemonHandler
rpc_daemon_handler(mp_internals->core.get(), mp_internals->p2p.get());
174
cryptonote::rpc::ZmqServer
zmq_server(rpc_daemon_handler);
175
176
if
(!zmq_rpc_disabled)
177
{
178
if
(!zmq_server.
addTCPSocket
(zmq_rpc_bind_address, zmq_rpc_bind_port))
179
{
180
LOG_ERROR
(std::string(
"Failed to add TCP Socket ("
) + zmq_rpc_bind_address
181
+
":"
+ zmq_rpc_bind_port +
") to ZMQ RPC Server"
);
182
183
if
(rpc_commands)
184
rpc_commands->stop_handling();
185
186
for
(
auto
& rpc : mp_internals->rpcs)
187
rpc->stop();
188
189
return
false
;
190
}
191
192
MINFO
(
"Starting ZMQ server..."
);
193
zmq_server.
run
();
194
195
MINFO
(std::string(
"ZMQ server started at "
) + zmq_rpc_bind_address
196
+
":"
+ zmq_rpc_bind_port +
"."
);
197
}
198
else
199
MINFO
(
"ZMQ server disabled"
);
200
201
if
(public_rpc_port > 0)
202
{
203
MGINFO
(
"Public RPC port "
<< public_rpc_port <<
" will be advertised to other peers over P2P"
);
204
mp_internals->p2p.get().set_rpc_port(public_rpc_port);
205
}
206
207
mp_internals->p2p.run();
// blocks until p2p goes down
208
209
if
(rpc_commands)
210
rpc_commands->stop_handling();
211
212
if
(!zmq_rpc_disabled)
213
zmq_server.
stop
();
214
215
for
(
auto
& rpc : mp_internals->rpcs)
216
rpc->stop();
217
MGINFO
(
"Node stopped."
);
218
return
true
;
219
}
220
catch
(std::exception
const
& ex)
221
{
222
MFATAL
(
"Uncaught exception! "
<< ex.what());
223
return
false
;
224
}
225
catch
(...)
226
{
227
MFATAL
(
"Uncaught exception!"
);
228
return
false
;
229
}
230
}
231
232
void
t_daemon::stop
()
233
{
234
if
(
nullptr
== mp_internals)
235
{
236
throw
std::runtime_error{
"Can't stop stopped daemon"
};
237
}
238
mp_internals->p2p.stop();
239
for
(
auto
& rpc : mp_internals->rpcs)
240
rpc->stop();
241
242
mp_internals.reset(
nullptr
);
// Ensure resources are cleaned up before we return
243
}
244
245
void
t_daemon::stop_p2p()
246
{
247
if
(
nullptr
== mp_internals)
248
{
249
throw
std::runtime_error{
"Can't send stop signal to a stopped daemon"
};
250
}
251
mp_internals->p2p.get().send_stop_signal();
252
}
253
254
}
// namespace daemonize
cryptonote::core_rpc_server::arg_rpc_bind_port
static const command_line::arg_descriptor< std::string, false, true, 2 > arg_rpc_bind_port
Definition
core_rpc_server.h:63
cryptonote::core_rpc_server::arg_rpc_restricted_bind_port
static const command_line::arg_descriptor< std::string > arg_rpc_restricted_bind_port
Definition
core_rpc_server.h:64
cryptonote::core_rpc_server::arg_restricted_rpc
static const command_line::arg_descriptor< bool > arg_restricted_rpc
Definition
core_rpc_server.h:65
cryptonote::rpc::DaemonHandler
Definition
daemon_handler.h:50
cryptonote::rpc::ZmqServer
Definition
zmq_server.h:46
cryptonote::rpc::ZmqServer::run
void run()
Definition
zmq_server.cpp:149
cryptonote::rpc::ZmqServer::stop
void stop()
Definition
zmq_server.cpp:154
cryptonote::rpc::ZmqServer::addTCPSocket
bool addTCPSocket(boost::string_ref address, boost::string_ref port)
Definition
zmq_server.cpp:103
daemonize::t_command_server
Definition
command_server.h:51
daemonize::t_core
Definition
core.h:44
daemonize::t_core::init_options
static void init_options(boost::program_options::options_description &option_spec)
Definition
core.h:46
daemonize::t_daemon::stop
void stop()
Definition
daemon.cpp:232
daemonize::t_daemon::~t_daemon
~t_daemon()
daemonize::t_daemon::init_options
static void init_options(boost::program_options::options_description &option_spec)
Definition
daemon.cpp:93
daemonize::t_daemon::operator=
t_daemon & operator=(t_daemon &&other)
Definition
daemon.cpp:126
daemonize::t_daemon::t_daemon
t_daemon(boost::program_options::variables_map const &vm, uint16_t public_rpc_port=0)
Definition
daemon.cpp:100
daemonize::t_p2p
Definition
p2p.h:45
daemonize::t_p2p::init_options
static void init_options(boost::program_options::options_description &option_spec)
Definition
p2p.h:50
daemonize::t_protocol
Definition
protocol.h:41
daemonize::t_rpc
Definition
rpc.h:43
daemonize::t_rpc::init_options
static void init_options(boost::program_options::options_description &option_spec)
Definition
rpc.h:45
t_daemon::run
bool run()
Definition
wallet_rpc_server.cpp:4299
t_daemon::t_daemon
t_daemon(boost::program_options::variables_map const &_vm)
Definition
wallet_rpc_server.cpp:4293
tools::signal_handler::install
static bool install(T t)
installs a signal handler
Definition
util.h:164
command_line_args.h
command_server.h
core.h
daemon_handler.h
misc_log_ex.h
MFATAL
#define MFATAL(x)
Definition
misc_log_ex.h:72
LOG_ERROR
#define LOG_ERROR(x)
Definition
misc_log_ex.h:98
MGINFO
#define MGINFO(x)
Definition
misc_log_ex.h:80
MINFO
#define MINFO(x)
Definition
misc_log_ex.h:75
command_line
Definition
command_line.cpp:39
command_line::is_arg_defaulted
bool is_arg_defaulted(const boost::program_options::variables_map &vm, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg)
Definition
command_line.h:265
command_line::get_arg
T get_arg(const boost::program_options::variables_map &vm, const arg_descriptor< T, false, true > &arg)
Definition
command_line.h:271
cryptonote
Holds cryptonote related classes and helpers.
Definition
ban.cpp:40
daemon_args::arg_zmq_rpc_disabled
const command_line::arg_descriptor< bool > arg_zmq_rpc_disabled
Definition
command_line_args.h:126
daemon_args::arg_zmq_rpc_bind_port
const command_line::arg_descriptor< std::string, false, true, 2 > arg_zmq_rpc_bind_port
Definition
command_line_args.h:112
daemon_args::arg_zmq_rpc_bind_ip
const command_line::arg_descriptor< std::string > arg_zmq_rpc_bind_ip
Definition
command_line_args.h:106
daemonize
Definition
command_parser_executor.cpp:38
epee::misc_utils::auto_scope_leave_caller
boost::shared_ptr< call_befor_die_base > auto_scope_leave_caller
Definition
misc_language.h:139
epee::misc_utils::sleep_no_w
bool sleep_no_w(long ms)
Definition
misc_language.h:100
epee::misc_utils::create_scope_leave_handler
auto_scope_leave_caller create_scope_leave_handler(t_scope_leave_handler f)
Definition
misc_language.h:156
epee::net_utils::ssl_support_t::e_ssl_support_disabled
@ e_ssl_support_disabled
Definition
net_ssl.h:47
epee
Definition
ado_db_helper.h:67
net_ssl.h
p2p.h
password.h
protocol.h
rpc.h
util.h
uint16_t
unsigned short uint16_t
Definition
stdint.h:125
daemonize::t_internals
Definition
daemon.cpp:61
daemonize::t_internals::t_internals
t_internals(boost::program_options::variables_map const &vm)
Definition
daemon.cpp:69
daemonize::t_internals::rpcs
std::vector< std::unique_ptr< t_rpc > > rpcs
Definition
daemon.cpp:67
daemonize::t_internals::core
t_core core
Definition
daemon.cpp:65
daemonize::t_internals::p2p
t_p2p p2p
Definition
daemon.cpp:66
version.h
zmq_server.h
src
daemon
daemon.cpp
Generated on
for Electroneum by
1.17.0