Electroneum
core_proxy.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 // node.cpp : Defines the entry point for the console application.
33 //
34 
35 
36 #include "include_base_utils.h"
37 #include "version.h"
38 #include <iostream>
39 #include <sstream>
40 
41 #include <boost/program_options.hpp>
42 
43 #include "common/command_line.h"
44 #include "console_handler.h"
45 #include "p2p/net_node.h"
46 #include "p2p/net_node.inl"
47 //#include "cryptonote_core/cryptonote_core.h"
49 #include "cryptonote_protocol/cryptonote_protocol_handler.inl"
50 #include "core_proxy.h"
51 #include "version.h"
52 
53 #if defined(WIN32)
54 #include <crtdbg.h>
55 #endif
56 
57 namespace po = boost::program_options;
58 using namespace std;
59 using namespace epee;
60 using namespace cryptonote;
61 using namespace crypto;
62 
63 
65 
66 int main(int argc, char* argv[])
67 {
68 
69 #ifdef WIN32
70  _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
71 #endif
72 
73  TRY_ENTRY();
74 
77 
78  //set up logging options
79  mlog_configure(mlog_get_default_log_path("core_proxy.log"), true);
81 
82 
83  po::options_description desc("Allowed options");
86 
87  po::variables_map vm;
88  bool r = command_line::handle_error_helper(desc, [&]()
89  {
90  po::store(po::parse_command_line(argc, argv, desc), vm);
91  po::notify(vm);
92  return true;
93  });
94  if (!r)
95  return 1;
96 
97  MGINFO("Module folder: " << argv[0]);
98  MGINFO("Node starting ...");
99 
100 
101  //create objects and link them
102  tests::proxy_core pr_core;
105  cprotocol
106  };
107  cprotocol.set_p2p_endpoint(&p2psrv);
108  //pr_core.set_cryptonote_protocol(&cprotocol);
109  //daemon_cmmands_handler dch(p2psrv);
110 
111  //initialize objects
112 
113  MGINFO("Initializing p2p server...");
114  bool res = p2psrv.init(vm);
115  CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize p2p server.");
116  MGINFO("P2p server initialized OK");
117 
118  MGINFO("Initializing cryptonote protocol...");
119  res = cprotocol.init(vm);
120  CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize cryptonote protocol.");
121  MGINFO("Cryptonote protocol initialized OK");
122 
123  //initialize core here
124  MGINFO("Initializing proxy core...");
125  res = pr_core.init(vm);
126  CHECK_AND_ASSERT_MES(res, 1, "Failed to initialize core");
127  MGINFO("Core initialized OK");
128 
129  MGINFO("Starting p2p net loop...");
130  p2psrv.run();
131  MGINFO("p2p net loop stopped");
132 
133  //deinitialize components
134  MGINFO("Deinitializing core...");
135  pr_core.deinit();
136  MGINFO("Deinitializing cryptonote_protocol...");
137  cprotocol.deinit();
138  MGINFO("Deinitializing p2p...");
139  p2psrv.deinit();
140 
141 
142  //pr_core.set_cryptonote_protocol(NULL);
143  cprotocol.set_p2p_endpoint(NULL);
144 
145 
146  MGINFO("Node stopped.");
147  return 0;
148 
149  CATCH_ENTRY_L0("main", 1);
150 }
151 
152 /*
153 string tx2str(const cryptonote::transaction& tx, const cryptonote::hash256& tx_hash, const cryptonote::hash256& tx_prefix_hash, const cryptonote::blobdata& blob) {
154  stringstream ss;
155 
156  ss << "{" << endl;
157  ss << "\tversion:" << tx.version << endl;
158  ss << "\tunlock_time:" << tx.unlock_time << endl;
159  ss << "\t"
160 
161  return ss.str();
162 }*/
163 
164 bool tests::proxy_core::handle_incoming_tx(const cryptonote::blobdata& tx_blob, cryptonote::tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) {
165  if (!keeped_by_block)
166  return true;
167 
168  crypto::hash tx_hash = null_hash;
169  crypto::hash tx_prefix_hash = null_hash;
170  transaction tx;
171 
172  if (!parse_and_validate_tx_from_blob(tx_blob, tx, tx_hash, tx_prefix_hash)) {
173  cerr << "WRONG TRANSACTION BLOB, Failed to parse, rejected" << endl;
174  return false;
175  }
176 
177  cout << "TX " << endl << endl;
178  cout << tx_hash << endl;
179  cout << tx_prefix_hash << endl;
180  cout << tx_blob.size() << endl;
181  //cout << string_tools::buff_to_hex_nodelimer(tx_blob) << endl << endl;
182  cout << obj_to_json_str(tx) << endl;
183  cout << endl << "ENDTX" << endl;
184 
185  return true;
186 }
187 
188 bool tests::proxy_core::handle_incoming_txs(const std::vector<blobdata>& tx_blobs, std::vector<tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
189 {
190  tvc.resize(tx_blobs.size());
191  size_t i = 0;
192  for (const auto &tx_blob: tx_blobs)
193  {
194  if (!handle_incoming_tx(tx_blob, tvc[i], keeped_by_block, relayed, do_not_relay))
195  return false;
196  ++i;
197  }
198  return true;
199 }
200 
201 bool tests::proxy_core::handle_incoming_block(const cryptonote::blobdata& block_blob, const cryptonote::block *block_, cryptonote::block_verification_context& bvc, bool update_miner_blocktemplate) {
202  block b = AUTO_VAL_INIT(b);
203 
204  if(!parse_and_validate_block_from_blob(block_blob, b)) {
205  cerr << "Failed to parse and validate new block" << endl;
206  return false;
207  }
208 
209  crypto::hash h;
210  crypto::hash lh;
211  cout << "BLOCK" << endl << endl;
212  cout << (h = get_block_hash(b)) << endl;
213  cout << (lh = get_block_longhash(b, 0)) << endl;
214  cout << get_transaction_hash(b.miner_tx) << endl;
215  cout << ::get_object_blobsize(b.miner_tx) << endl;
216  //cout << string_tools::buff_to_hex_nodelimer(block_blob) << endl;
217  cout << obj_to_json_str(b) << endl;
218 
219  cout << endl << "ENDBLOCK" << endl << endl;
220 
221  if (!add_block(h, lh, b, block_blob))
222  return false;
223 
224  return true;
225 }
226 
227 bool tests::proxy_core::get_short_chain_history(std::list<crypto::hash>& ids) {
228  build_short_history(ids, m_lastblk);
229  return true;
230 }
231 
233  height = 0;
234  top_id = get_block_hash(m_genesis);
235 }
236 
237 bool tests::proxy_core::init(const boost::program_options::variables_map& /*vm*/) {
239  crypto::hash h = get_block_hash(m_genesis);
240  add_block(h, get_block_longhash(m_genesis, 0), m_genesis, block_to_blob(m_genesis));
241  return true;
242 }
243 
245  if (m_hash2blkidx.end() == m_hash2blkidx.find(id))
246  return false;
247  return true;
248 }
249 
250 void tests::proxy_core::build_short_history(std::list<crypto::hash> &m_history, const crypto::hash &m_start) {
251  m_history.push_front(get_block_hash(m_genesis));
252  /*std::unordered_map<crypto::hash, tests::block_index>::const_iterator cit = m_hash2blkidx.find(m_lastblk);
253 
254  do {
255  m_history.push_front(cit->first);
256 
257  size_t n = 1 << m_history.size();
258  while (m_hash2blkidx.end() != cit && crypto::null_hash != cit->second.blk.prev_id && n > 0) {
259  n--;
260  cit = m_hash2blkidx.find(cit->second.blk.prev_id);
261  }
262  } while (m_hash2blkidx.end() != cit && get_block_hash(cit->second.blk) != cit->first);*/
263 }
264 
265 bool tests::proxy_core::add_block(const crypto::hash &_id, const crypto::hash &_longhash, const cryptonote::block &_blk, const cryptonote::blobdata &_blob) {
266  size_t height = 0;
267 
268  if (crypto::null_hash != _blk.prev_id) {
269  std::unordered_map<crypto::hash, tests::block_index>::const_iterator cit = m_hash2blkidx.find(_blk.prev_id);
270  if (m_hash2blkidx.end() == cit) {
271  cerr << "ERROR: can't find previous block with id \"" << _blk.prev_id << "\"" << endl;
272  return false;
273  }
274 
275  height = cit->second.height + 1;
276  }
277 
278  m_known_block_list.push_back(_id);
279 
280  block_index bi(height, _id, _longhash, _blk, _blob, txes);
281  m_hash2blkidx.insert(std::make_pair(_id, bi));
282  txes.clear();
283  m_lastblk = _id;
284 
285  return true;
286 }
const char * res
Definition: hmac_keccak.cpp:41
void init_options(boost::program_options::options_description &hidden_options, boost::program_options::options_description &normal_options)
void get_blockchain_top(uint64_t &height, crypto::hash &top_id)
Definition: core_proxy.cpp:232
bool set_module_name_and_folder(const std::string &path_to_process_)
Definition: string_tools.h:249
void set_p2p_endpoint(nodetool::i_p2p_endpoint< connection_context > *p2p)
#define CHECK_AND_ASSERT_MES(expr, fail_ret_val, message)
Definition: misc_log_ex.h:181
size_t get_object_blobsize(const t_object &o)
bool get_short_chain_history(std::list< crypto::hash > &ids)
Definition: core_proxy.cpp:227
std::string mlog_get_default_log_path(const char *default_filename)
Definition: mlog.cpp:72
uint64_t height
Definition: blockchain.cpp:91
void mlog_configure(const std::string &filename_base, bool console, const std::size_t max_log_file_size=MAX_LOG_FILE_SIZE, const std::size_t max_log_files=MAX_LOG_FILES)
Definition: mlog.cpp:148
crypto namespace.
Definition: crypto.cpp:58
STL namespace.
#define MGINFO(x)
Definition: misc_log_ex.h:80
bool on_startup()
Definition: util.cpp:778
bool init(const boost::program_options::variables_map &vm)
Holds cryptonote related classes and helpers.
Definition: ban.cpp:40
bool get_block_longhash(const block &b, crypto::hash &res, uint64_t height)
bool handle_incoming_tx(const cryptonote::blobdata &tx_blob, cryptonote::tx_verification_context &tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
Definition: core_proxy.cpp:164
bool generate_genesis_block(block &bl, std::string const &genesis_tx, uint32_t nonce)
bool handle_error_helper(const boost::program_options::options_description &desc, F parser)
Definition: command_line.h:237
#define TRY_ENTRY()
Definition: misc_log_ex.h:151
bool have_block(const crypto::hash &id)
Definition: core_proxy.cpp:244
std::string const GENESIS_TX
std::string obj_to_json_str(T &obj)
unsigned __int64 uint64_t
Definition: stdint.h:136
const command_line::arg_descriptor< std::string, false, true, 2 > arg_data_dir
BOOST_CLASS_VERSION(nodetool::node_server< cryptonote::t_cryptonote_protocol_handler< tests::proxy_core > >, 1)
bool parse_and_validate_tx_from_blob(const blobdata &tx_blob, transaction &tx)
This is the orginal cryptonote protocol network-events handler, modified by us.
void add_arg(boost::program_options::options_description &description, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg, bool unique=true)
Definition: command_line.h:188
bool handle_incoming_block(const cryptonote::blobdata &block_blob, const cryptonote::block *block, cryptonote::block_verification_context &bvc, bool update_miner_blocktemplate=true)
Definition: core_proxy.cpp:201
std::string blobdata
Definition: blobdatatype.h:39
crypto::hash get_transaction_hash(const transaction &t)
boost::program_options::basic_parsed_options< charT > parse_command_line(int argc, const charT *const argv[], const boost::program_options::options_description &desc, bool allow_unregistered=false)
Definition: command_line.h:224
uint32_t const GENESIS_NONCE
#define AUTO_VAL_INIT(v)
Definition: misc_language.h:53
bool init(const boost::program_options::variables_map &vm)
Definition: core_proxy.cpp:237
crypto::hash get_block_hash(uint64_t height)
POD_CLASS hash
Definition: hash.h:50
bool handle_incoming_txs(const std::vector< cryptonote::blobdata > &tx_blobs, std::vector< cryptonote::tx_verification_context > &tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
Definition: core_proxy.cpp:188
blobdata block_to_blob(const block &b)
#define CATCH_ENTRY_L0(lacation, return_val)
Definition: misc_log_ex.h:165
void mlog_set_log_level(int level)
Definition: mlog.cpp:282
int main(int argc, char *argv[])
Definition: core_proxy.cpp:66
bool parse_and_validate_block_from_blob(const blobdata &b_blob, block &b, crypto::hash *block_hash)