Monero
chaingen.h
Go to the documentation of this file.
1 // Copyright (c) 2014-2022, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29 // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
30 
31 #pragma once
32 
33 #include <functional>
34 #include <vector>
35 #include <iostream>
36 #include <stdint.h>
37 
38 #include <boost/program_options.hpp>
39 #include <boost/optional.hpp>
40 #include <boost/serialization/vector.hpp>
41 #include <boost/serialization/variant.hpp>
42 #include <boost/serialization/optional.hpp>
43 #include <boost/serialization/unordered_map.hpp>
44 #include <boost/functional/hash.hpp>
45 
46 #include "include_base_utils.h"
48 #include "common/command_line.h"
49 #include "common/threadpool.h"
50 
58 #include "misc_language.h"
59 
60 #undef MONERO_DEFAULT_LOG_CATEGORY
61 #define MONERO_DEFAULT_LOG_CATEGORY "tests.core"
62 
63 
64 
66 {
71 
72 private:
73  friend class boost::serialization::access;
74 
75  template<class Archive>
76  void serialize(Archive & ar, const unsigned int /*version*/)
77  {
78  ar & callback_name;
79  }
80 };
81 
82 template<typename T>
84 {
86 
88  : data(a_data)
89  {
90  }
91 
94  FIELD(data)
96 
97 private:
98  friend class boost::serialization::access;
99 
100  template<class Archive>
101  void serialize(Archive & ar, const unsigned int /*version*/)
102  {
103  ar & data;
104  }
105 };
106 
109 
111 {
112  int mask;
113 
114  enum settings
115  {
118  set_local_relay = 1 << 2,
119  set_txs_stem = 1 << 3
120  };
121 
122  event_visitor_settings(int a_mask = 0)
123  : mask(a_mask)
124  {
125  }
126 
127 private:
129 
130  template<class Archive>
131  void serialize(Archive & ar, const unsigned int /*version*/)
132  {
133  ar & mask;
134  }
135 };
136 
137 typedef std::vector<std::pair<uint8_t, uint64_t>> v_hardforks_t;
139 {
140  boost::optional<v_hardforks_t> hard_forks;
141 
142  event_replay_settings() = default;
143 
144 private:
146 
147  template<class Archive>
148  void serialize(Archive & ar, const unsigned int /*version*/)
149  {
150  ar & hard_forks;
151  }
152 };
153 
154 
161 
162 typedef boost::variant<cryptonote::block, cryptonote::transaction, std::vector<cryptonote::transaction>, cryptonote::account_base, callback_entry, serialized_block, serialized_transaction, event_visitor_settings, event_replay_settings> test_event_entry;
163 typedef std::unordered_map<crypto::hash, const cryptonote::transaction*> map_hash2tx_t;
164 
166 {
167 public:
168  typedef boost::function<bool (cryptonote::core& c, size_t ev_index, const std::vector<test_event_entry> &events)> verify_callback;
169  typedef std::map<std::string, verify_callback> callbacks_map;
170 
171  void register_callback(const std::string& cb_name, verify_callback cb);
172  bool verify(const std::string& cb_name, cryptonote::core& c, size_t ev_index, const std::vector<test_event_entry> &events);
173  bool check_block_verification_context(const cryptonote::block_verification_context& bvc, size_t event_idx, const cryptonote::block& /*blk*/);
174  bool check_tx_verification_context(const cryptonote::tx_verification_context& tvc, bool /*tx_added*/, size_t /*event_index*/, const cryptonote::transaction& /*tx*/);
175  bool check_tx_verification_context_array(const std::vector<cryptonote::tx_verification_context>& tvcs, size_t /*tx_added*/, size_t /*event_index*/, const std::vector<cryptonote::transaction>& /*txs*/);
176 
177 private:
179 };
180 
181 
183 {
184 public:
185  struct block_info
186  {
188  : prev_id()
190  , block_weight(0)
191  {
192  }
193 
194  block_info(crypto::hash a_prev_id, uint64_t an_already_generated_coins, size_t a_block_weight)
195  : prev_id(a_prev_id)
196  , already_generated_coins(an_already_generated_coins)
197  , block_weight(a_block_weight)
198  {
199  }
200 
203  size_t block_weight;
204 
205  private:
207 
208  template<class Archive>
209  void serialize(Archive & ar, const unsigned int /*version*/)
210  {
211  ar & prev_id;
213  ar & block_weight;
214  }
215  };
216 
218  {
219  bf_none = 0,
220  bf_major_ver = 1 << 0,
221  bf_minor_ver = 1 << 1,
222  bf_timestamp = 1 << 2,
223  bf_prev_id = 1 << 3,
224  bf_miner_tx = 1 << 4,
225  bf_tx_hashes = 1 << 5,
226  bf_diffic = 1 << 6,
227  bf_max_outs = 1 << 7,
228  bf_hf_version= 1 << 8,
229  bf_tx_fees = 1 << 9
230  };
231 
232  test_generator(): m_events(nullptr) {}
234  void get_block_chain(std::vector<block_info>& blockchain, const crypto::hash& head, size_t n) const;
235  void get_last_n_block_weights(std::vector<size_t>& block_weights, const crypto::hash& head, size_t n) const;
238 
239  void add_block(const cryptonote::block& blk, size_t tsx_size, std::vector<size_t>& block_weights, uint64_t already_generated_coins, uint64_t block_reward,
240  uint8_t hf_version = 1);
241  bool construct_block(cryptonote::block& blk, uint64_t height, const crypto::hash& prev_id,
242  const cryptonote::account_base& miner_acc, uint64_t timestamp, uint64_t already_generated_coins,
243  std::vector<size_t>& block_weights, const std::list<cryptonote::transaction>& tx_list,
244  const boost::optional<uint8_t>& hf_ver = boost::none);
245  bool construct_block(cryptonote::block& blk, const cryptonote::account_base& miner_acc, uint64_t timestamp);
246  bool construct_block(cryptonote::block& blk, const cryptonote::block& blk_prev, const cryptonote::account_base& miner_acc,
247  const std::list<cryptonote::transaction>& tx_list = std::list<cryptonote::transaction>(),
248  const boost::optional<uint8_t>& hf_ver = boost::none);
249 
250  bool construct_block_manually(cryptonote::block& blk, const cryptonote::block& prev_block,
251  const cryptonote::account_base& miner_acc, int actual_params = bf_none, uint8_t major_ver = 0,
252  uint8_t minor_ver = 0, uint64_t timestamp = 0, const crypto::hash& prev_id = crypto::hash(),
253  const cryptonote::difficulty_type& diffic = 1, const cryptonote::transaction& miner_tx = cryptonote::transaction(),
254  const std::vector<crypto::hash>& tx_hashes = std::vector<crypto::hash>(), size_t txs_sizes = 0, size_t max_outs = 999,
255  uint8_t hf_version = 1, uint64_t fees = 0);
257  const cryptonote::account_base& miner_acc, const std::vector<crypto::hash>& tx_hashes, size_t txs_size);
258  void fill_nonce(cryptonote::block& blk, const cryptonote::difficulty_type& diffic, uint64_t height);
259  void set_events(const std::vector<test_event_entry> * events) { m_events = events; }
260  void set_network_type(const cryptonote::network_type nettype) { m_nettype = nettype; }
261 
262 private:
263  std::unordered_map<crypto::hash, block_info> m_blocks_info;
264  const std::vector<test_event_entry> * m_events;
266 
268 
269  template<class Archive>
270  void serialize(Archive & ar, const unsigned int /*version*/)
271  {
272  ar & m_blocks_info;
273  }
274 };
275 
276 template<typename T>
278 {
279  std::ostringstream ss;
280  char buff[10];
281 
282  ss << "[";
283  for(int i = 0; i < 32; i++)
284  {
285  snprintf(buff, 10, "0x%02x", ((uint8_t)buff32[i] & 0xff));
286  ss << buff;
287  if (i < 31)
288  ss << ",";
289  }
290  ss << "]";
291  return ss.str();
292 }
293 
294 struct output_index {
297  size_t blk_height; // block height
298  size_t tx_no; // index of transaction in block
299  size_t out_no; // index of out in transaction
300  size_t idx;
303  bool spent;
304  bool rct;
308 
309  output_index(const cryptonote::txout_target_v &_out, uint64_t _a, size_t _h, size_t tno, size_t ono, const cryptonote::block *_pb, const cryptonote::transaction *_pt)
310  : out(_out), amount(_a), blk_height(_h), tx_no(tno), out_no(ono), idx(0), unlock_time(0),
311  is_coin_base(false), spent(false), rct(false), p_blk(_pb), p_tx(_pt)
312  {
313 
314  }
315 
317  : out(other.out), amount(other.amount), blk_height(other.blk_height), tx_no(other.tx_no), rct(other.rct),
318  out_no(other.out_no), idx(other.idx), unlock_time(other.unlock_time), is_coin_base(other.is_coin_base),
319  spent(other.spent), comm(other.comm), p_blk(other.p_blk), p_tx(other.p_tx) { }
320 
321  void set_rct(bool arct) {
322  rct = arct;
323  if (rct && p_tx->rct_signatures.outPk.size() > out_no)
325  else
327  }
328 
330  return comm;
331  }
332 
333  const std::string toString() const {
334  std::stringstream ss;
335 
336  ss << "output_index{blk_height=" << blk_height
337  << " tx_no=" << tx_no
338  << " out_no=" << out_no
339  << " amount=" << amount
340  << " idx=" << idx
341  << " unlock_time=" << unlock_time
342  << " spent=" << spent
343  << " is_coin_base=" << is_coin_base
344  << " rct=" << rct
345  << " comm=" << dump_keys(comm.bytes)
346  << "}";
347 
348  return ss.str();
349  }
350 
352  {
353  new(this) output_index(other);
354  return *this;
355  }
356 };
357 
358 typedef std::tuple<uint64_t, crypto::public_key, rct::key> get_outs_entry;
359 typedef std::pair<crypto::hash, size_t> output_hasher;
360 typedef boost::hash<output_hasher> output_hasher_hasher;
361 typedef std::map<uint64_t, std::vector<size_t> > map_output_t;
362 typedef std::map<uint64_t, std::vector<output_index> > map_output_idx_t;
363 typedef std::unordered_map<crypto::hash, cryptonote::block> map_block_t;
364 typedef std::unordered_map<output_hasher, output_index, output_hasher_hasher> map_txid_output_t;
365 typedef std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses_t;
366 typedef std::pair<uint64_t, size_t> outloc_t;
367 
368 typedef boost::variant<cryptonote::account_public_address, cryptonote::account_keys, cryptonote::account_base, cryptonote::tx_destination_entry> var_addr_t;
369 typedef struct {
374 
375 // Daemon functionality
377 {
378 public:
380  map_txid_output_t m_map_outs; // mapping (txid, out) -> output_index
382 
383  block_tracker() = default;
385  map_txid_output_t::iterator find_out(const crypto::hash &txid, size_t out);
386  map_txid_output_t::iterator find_out(const output_hasher &id);
387  void process(const std::vector<cryptonote::block>& blockchain, const map_hash2tx_t& mtx);
388  void process(const std::vector<const cryptonote::block*>& blockchain, const map_hash2tx_t& mtx);
389  void process(const cryptonote::block* blk, const cryptonote::transaction * tx, size_t i);
390  void global_indices(const cryptonote::transaction *tx, std::vector<uint64_t> &indices);
391  void get_fake_outs(size_t num_outs, uint64_t amount, uint64_t global_index, uint64_t cur_height, std::vector<get_outs_entry> &outs);
392 
394  void dump_data(const std::string & fname);
395 
396 private:
398 
399  template<class Archive>
400  void serialize(Archive & ar, const unsigned int /*version*/)
401  {
402  ar & m_outs;
403  ar & m_map_outs;
404  ar & m_blocks;
405  }
406 };
407 
414 
415 inline cryptonote::difficulty_type get_test_difficulty(const boost::optional<uint8_t>& hf_ver=boost::none) {return !hf_ver || hf_ver.get() <= 1 ? 1 : 2;}
416 inline uint64_t current_difficulty_window(const boost::optional<uint8_t>& hf_ver=boost::none){ return !hf_ver || hf_ver.get() <= 1 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2; }
417 
418 cryptonote::tx_destination_entry build_dst(const var_addr_t& to, bool is_subaddr=false, uint64_t amount=0);
419 std::vector<cryptonote::tx_destination_entry> build_dsts(const var_addr_t& to1, bool sub1=false, uint64_t am1=0);
420 std::vector<cryptonote::tx_destination_entry> build_dsts(std::initializer_list<dest_wrapper_t> inps);
421 uint64_t sum_amount(const std::vector<cryptonote::tx_destination_entry>& destinations);
422 uint64_t sum_amount(const std::vector<cryptonote::tx_source_entry>& sources);
423 
424 bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins,
426  uint64_t fee, uint8_t hf_version = 1,
427  cryptonote::keypair* p_txkey = nullptr);
428 
429 bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote::transaction& tx,
430  const cryptonote::block& blk_head, const cryptonote::account_base& from, const var_addr_t& to, uint64_t amount,
431  uint64_t fee, size_t nmix, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0);
432 
433 bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote::transaction& tx, const cryptonote::block& blk_head,
434  const cryptonote::account_base& from, std::vector<cryptonote::tx_destination_entry> destinations,
435  uint64_t fee, size_t nmix, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0);
436 
438  std::vector<cryptonote::tx_source_entry> &sources,
439  uint64_t fee, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0);
440 
441 bool construct_tx_to_key(cryptonote::transaction& tx, const cryptonote::account_base& from, const std::vector<cryptonote::tx_destination_entry>& destinations,
442  std::vector<cryptonote::tx_source_entry> &sources,
443  uint64_t fee, bool rct, rct::RangeProofType range_proof_type, int bp_version = 0);
444 
445 cryptonote::transaction construct_tx_with_fee(std::vector<test_event_entry>& events, const cryptonote::block& blk_head,
446  const cryptonote::account_base& acc_from, const var_addr_t& to,
447  uint64_t amount, uint64_t fee);
448 
449 bool construct_tx_rct(const cryptonote::account_keys& sender_account_keys,
450  std::vector<cryptonote::tx_source_entry>& sources,
451  const std::vector<cryptonote::tx_destination_entry>& destinations,
452  const boost::optional<cryptonote::account_public_address>& change_addr,
453  std::vector<uint8_t> extra, cryptonote::transaction& tx,
454  bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0);
455 
456 
457 uint64_t num_blocks(const std::vector<test_event_entry>& events);
458 cryptonote::block get_head_block(const std::vector<test_event_entry>& events);
459 
460 void get_confirmed_txs(const std::vector<cryptonote::block>& blockchain, const map_hash2tx_t& mtx, map_hash2tx_t& confirmed_txs);
461 bool trim_block_chain(std::vector<cryptonote::block>& blockchain, const crypto::hash& tail);
462 bool trim_block_chain(std::vector<const cryptonote::block*>& blockchain, const crypto::hash& tail);
463 bool find_block_chain(const std::vector<test_event_entry>& events, std::vector<cryptonote::block>& blockchain, map_hash2tx_t& mtx, const crypto::hash& head);
464 bool find_block_chain(const std::vector<test_event_entry>& events, std::vector<const cryptonote::block*>& blockchain, map_hash2tx_t& mtx, const crypto::hash& head);
465 
467  uint64_t amount, uint64_t fee,
468  const std::vector<cryptonote::tx_source_entry> &sources,
469  std::vector<cryptonote::tx_destination_entry>& destinations, bool always_change=false);
470 
471 void fill_tx_destinations(const var_addr_t& from, const std::vector<cryptonote::tx_destination_entry>& dests,
472  uint64_t fee,
473  const std::vector<cryptonote::tx_source_entry> &sources,
474  std::vector<cryptonote::tx_destination_entry>& destinations,
475  bool always_change);
476 
478  uint64_t amount, uint64_t fee,
479  const std::vector<cryptonote::tx_source_entry> &sources,
480  std::vector<cryptonote::tx_destination_entry>& destinations,
481  std::vector<cryptonote::tx_destination_entry>& destinations_pure,
482  bool always_change=false);
483 
484 
485 void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& events, const cryptonote::block& blk_head,
487  uint64_t amount, uint64_t fee, size_t nmix,
488  std::vector<cryptonote::tx_source_entry>& sources,
489  std::vector<cryptonote::tx_destination_entry>& destinations);
490 
491 void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& events, const cryptonote::block& blk_head,
492  const cryptonote::account_base& from, const cryptonote::account_base& to,
493  uint64_t amount, uint64_t fee, size_t nmix,
494  std::vector<cryptonote::tx_source_entry>& sources,
495  std::vector<cryptonote::tx_destination_entry>& destinations);
496 
497 uint64_t get_balance(const cryptonote::account_base& addr, const std::vector<cryptonote::block>& blockchain, const map_hash2tx_t& mtx);
498 
499 bool extract_hard_forks(const std::vector<test_event_entry>& events, v_hardforks_t& hard_forks);
500 bool extract_hard_forks_from_blocks(const std::vector<test_event_entry>& events, v_hardforks_t& hard_forks);
501 
502 /************************************************************************/
503 /* */
504 /************************************************************************/
505 template<class t_test_class>
506 struct push_core_event_visitor: public boost::static_visitor<bool>
507 {
508 private:
510  const std::vector<test_event_entry>& m_events;
511  t_test_class& m_validator;
512  size_t m_ev_index;
513 
515 
516 public:
517  push_core_event_visitor(cryptonote::core& c, const std::vector<test_event_entry>& events, t_test_class& validator)
518  : m_c(c)
519  , m_events(events)
520  , m_validator(validator)
521  , m_ev_index(0)
523  {
524  }
525 
526  void event_index(size_t ev_index)
527  {
528  m_ev_index = ev_index;
529  }
530 
531  bool operator()(const event_replay_settings& settings)
532  {
533  log_event("event_replay_settings");
534  return true;
535  }
536 
537  bool operator()(const event_visitor_settings& settings)
538  {
539  log_event("event_visitor_settings");
540 
542  {
544  }
545  else if (settings.mask & event_visitor_settings::set_local_relay)
546  {
548  }
550  {
552  }
553  else if (settings.mask & event_visitor_settings::set_txs_stem)
554  {
556  }
557  else
558  {
560  }
561 
562  return true;
563  }
564 
566  {
567  log_event("cryptonote::transaction");
568 
570  size_t pool_size = m_c.get_pool_transactions_count();
572  bool tx_added = pool_size + 1 == m_c.get_pool_transactions_count();
573  bool r = m_validator.check_tx_verification_context(tvc, tx_added, m_ev_index, tx);
574  CHECK_AND_NO_ASSERT_MES(r, false, "tx verification context check failed");
575  return true;
576  }
577 
578  bool operator()(const std::vector<cryptonote::transaction>& txs) const
579  {
580  log_event("cryptonote::transaction");
581 
582  std::vector<cryptonote::blobdata> tx_blobs;
583  std::vector<cryptonote::tx_verification_context> tvcs;
585  for (const auto &tx: txs)
586  {
587  tx_blobs.emplace_back(t_serializable_object_to_blob(tx));
588  tvcs.push_back(tvc0);
589  }
590  size_t pool_size = m_c.get_pool_transactions_count();
591  for (size_t i = 0; i < tx_blobs.size(); ++i)
592  m_c.handle_incoming_tx(tx_blobs[i], tvcs[i], m_tx_relay, false);
593  size_t tx_added = m_c.get_pool_transactions_count() - pool_size;
594  bool r = m_validator.check_tx_verification_context_array(tvcs, tx_added, m_ev_index, txs);
595  CHECK_AND_NO_ASSERT_MES(r, false, "tx verification context check failed");
596  return true;
597  }
598 
599  bool operator()(const cryptonote::block& b) const
600  {
601  log_event("cryptonote::block");
602 
605  std::vector<cryptonote::block> pblocks;
607  bce.pruned = false;
608  bce.block = bd;
609  bce.txs = {};
610  if (m_c.prepare_handle_incoming_blocks(std::vector<cryptonote::block_complete_entry>(1, bce), pblocks))
611  {
612  m_c.handle_incoming_block(bd, &b, bvc);
614  }
615  else
616  bvc.m_verifivation_failed = true;
617  bool r = m_validator.check_block_verification_context(bvc, m_ev_index, b);
618  CHECK_AND_NO_ASSERT_MES(r, false, "block verification context check failed");
619  return r;
620  }
621 
622  bool operator()(const callback_entry& cb) const
623  {
624  log_event(std::string("callback_entry ") + cb.callback_name);
625  return m_validator.verify(cb.callback_name, m_c, m_ev_index, m_events);
626  }
627 
628  bool operator()(const cryptonote::account_base& ab) const
629  {
630  log_event("cryptonote::account_base");
631  return true;
632  }
633 
634  bool operator()(const serialized_block& sr_block) const
635  {
636  log_event("serialized_block");
637 
639  std::vector<cryptonote::block> pblocks;
641  bce.pruned = false;
642  bce.block = sr_block.data;
643  bce.txs = {};
644  if (m_c.prepare_handle_incoming_blocks(std::vector<cryptonote::block_complete_entry>(1, bce), pblocks))
645  {
646  m_c.handle_incoming_block(sr_block.data, NULL, bvc);
648  }
649  else
650  bvc.m_verifivation_failed = true;
651 
652  cryptonote::block blk;
653  binary_archive<false> ba{epee::strspan<std::uint8_t>(sr_block.data)};
655  if (!ba.good())
656  {
657  blk = cryptonote::block();
658  }
659  bool r = m_validator.check_block_verification_context(bvc, m_ev_index, blk);
660  CHECK_AND_NO_ASSERT_MES(r, false, "block verification context check failed");
661  return true;
662  }
663 
664  bool operator()(const serialized_transaction& sr_tx) const
665  {
666  log_event("serialized_transaction");
667 
669  size_t pool_size = m_c.get_pool_transactions_count();
670  m_c.handle_incoming_tx(sr_tx.data, tvc, m_tx_relay, false);
671  bool tx_added = pool_size + 1 == m_c.get_pool_transactions_count();
672 
674  binary_archive<false> ba{epee::strspan<std::uint8_t>(sr_tx.data)};
676  if (!ba.good())
677  {
679  }
680 
681  bool r = m_validator.check_tx_verification_context(tvc, tx_added, m_ev_index, tx);
682  CHECK_AND_NO_ASSERT_MES(r, false, "transaction verification context check failed");
683  return true;
684  }
685 
686 private:
687  void log_event(const std::string& event_type) const
688  {
689  MGINFO_YELLOW("=== EVENT # " << m_ev_index << ": " << event_type);
690  }
691 };
692 //--------------------------------------------------------------------------
693 template<class t_test_class>
694 inline bool replay_events_through_core(cryptonote::core& cr, const std::vector<test_event_entry>& events, t_test_class& validator)
695 {
696  return replay_events_through_core_plain(cr, events, validator, true);
697 }
698 //--------------------------------------------------------------------------
699 template<class t_test_class>
700 inline bool replay_events_through_core_plain(cryptonote::core& cr, const std::vector<test_event_entry>& events, t_test_class& validator, bool reinit=true)
701 {
702  TRY_ENTRY();
703 
704  //init core here
705  if (reinit) {
706  CHECK_AND_ASSERT_MES(typeid(cryptonote::block) == events[0].type(), false,
707  "First event must be genesis block creation");
708  cr.set_genesis_block(boost::get<cryptonote::block>(events[0]));
709  }
710 
711  bool r = true;
712  push_core_event_visitor<t_test_class> visitor(cr, events, validator);
713  for(size_t i = 1; i < events.size() && r; ++i)
714  {
715  visitor.event_index(i);
716  r = boost::apply_visitor(visitor, events[i]);
717  }
718 
719  return r;
720 
721  CATCH_ENTRY_L0("replay_events_through_core", false);
722 }
723 //--------------------------------------------------------------------------
724 template<typename t_test_class>
726  const std::pair<uint8_t, uint64_t> hard_forks[2];
728  hard_forks, 0
729  };
730  get_test_options():hard_forks{std::make_pair((uint8_t)1, (uint64_t)0), std::make_pair((uint8_t)0, (uint64_t)0)}{}
731 };
732 //--------------------------------------------------------------------------
733 template<class t_test_class>
734 inline bool do_replay_events_get_core(std::vector<test_event_entry>& events, cryptonote::core *core)
735 {
736  boost::program_options::options_description desc("Allowed options");
738  boost::program_options::variables_map vm;
740  {
741  boost::program_options::store(boost::program_options::basic_parsed_options<char>(&desc), vm);
742  boost::program_options::notify(vm);
743  return true;
744  });
745  if (!r)
746  return false;
747 
748  auto & c = *core;
749 
750  // FIXME: make sure that vm has arg_testnet_on set to true or false if
751  // this test needs for it to be so.
753 
754  // Hardforks can be specified in events.
755  v_hardforks_t hardforks;
756  cryptonote::test_options test_options_tmp{nullptr, 0};
757  const cryptonote::test_options * test_options_ = &gto.test_options;
758  if (extract_hard_forks(events, hardforks)){
759  hardforks.push_back(std::make_pair((uint8_t)0, (uint64_t)0)); // terminator
760  test_options_tmp.hard_forks = hardforks.data();
761  test_options_ = &test_options_tmp;
762  }
763 
764  if (!c.init(vm, test_options_))
765  {
766  MERROR("Failed to init core");
767  return false;
768  }
769  c.get_blockchain_storage().get_db().set_batch_transactions(true);
770 
771  // start with a clean pool
772  std::vector<crypto::hash> pool_txs;
773  if (!c.get_pool_transaction_hashes(pool_txs))
774  {
775  MERROR("Failed to flush txpool");
776  return false;
777  }
778  c.get_blockchain_storage().flush_txes_from_pool(pool_txs);
779 
780  t_test_class validator;
781  bool ret = replay_events_through_core<t_test_class>(c, events, validator);
783 // c.deinit();
784  return ret;
785 }
786 //--------------------------------------------------------------------------
787 template<class t_test_class>
788 inline bool replay_events_through_core_validate(std::vector<test_event_entry>& events, cryptonote::core & c)
789 {
790  std::vector<crypto::hash> pool_txs;
791  if (!c.get_pool_transaction_hashes(pool_txs))
792  {
793  MERROR("Failed to flush txpool");
794  return false;
795  }
796  c.get_blockchain_storage().flush_txes_from_pool(pool_txs);
797 
798  t_test_class validator;
799  return replay_events_through_core_plain<t_test_class>(c, events, validator, false);
800 }
801 //--------------------------------------------------------------------------
802 template<class t_test_class>
803 inline bool do_replay_events(std::vector<test_event_entry>& events)
804 {
805  cryptonote::core core(nullptr);
806  bool ret = do_replay_events_get_core<t_test_class>(events, &core);
807  core.deinit();
808  return ret;
809 }
810 //--------------------------------------------------------------------------
811 template<class t_test_class>
812 inline bool do_replay_file(const std::string& filename)
813 {
814  std::vector<test_event_entry> events;
815  if (!tools::unserialize_obj_from_file(events, filename))
816  {
817  MERROR("Failed to deserialize data from file: ");
818  return false;
819  }
820  return do_replay_events<t_test_class>(events);
821 }
822 
823 //--------------------------------------------------------------------------
824 #define DEFAULT_HARDFORKS(HARDFORKS) do { \
825  HARDFORKS.push_back(std::make_pair((uint8_t)1, (uint64_t)0)); \
826 } while(0)
827 
828 #define ADD_HARDFORK(HARDFORKS, FORK, HEIGHT) HARDFORKS.push_back(std::make_pair((uint8_t)FORK, (uint64_t)HEIGHT))
829 
830 #define GENERATE_ACCOUNT(account) \
831  cryptonote::account_base account; \
832  account.generate();
833 
834 #define GENERATE_MULTISIG_ACCOUNT(account, threshold, total) \
835  CHECK_AND_ASSERT_MES(threshold >= 2 && threshold <= total, false, "Invalid multisig scheme"); \
836  std::vector<cryptonote::account_base> account(total); \
837  do \
838  { \
839  for (size_t msidx = 0; msidx < total; ++msidx) \
840  account[msidx].generate(); \
841  CHECK_AND_ASSERT_MES(make_multisig_accounts(account, threshold), false, "Failed to make multisig accounts."); \
842  } while(0)
843 
844 #define MAKE_ACCOUNT(VEC_EVENTS, account) \
845  cryptonote::account_base account; \
846  account.generate(); \
847  VEC_EVENTS.push_back(account);
848 
849 #define DO_CALLBACK(VEC_EVENTS, CB_NAME) \
850 { \
851  callback_entry CALLBACK_ENTRY; \
852  CALLBACK_ENTRY.callback_name = CB_NAME; \
853  VEC_EVENTS.push_back(CALLBACK_ENTRY); \
854 }
855 
856 #define REGISTER_CALLBACK(CB_NAME, CLBACK) \
857  register_callback(CB_NAME, std::bind(&CLBACK, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
858 
859 #define REGISTER_CALLBACK_METHOD(CLASS, METHOD) \
860  register_callback(#METHOD, std::bind(&CLASS::METHOD, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
861 
862 #define MAKE_GENESIS_BLOCK(VEC_EVENTS, BLK_NAME, MINER_ACC, TS) \
863  test_generator generator; \
864  cryptonote::block BLK_NAME; \
865  generator.construct_block(BLK_NAME, MINER_ACC, TS); \
866  VEC_EVENTS.push_back(BLK_NAME);
867 
868 #define MAKE_NEXT_BLOCK(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC) \
869  cryptonote::block BLK_NAME; \
870  generator.construct_block(BLK_NAME, PREV_BLOCK, MINER_ACC); \
871  VEC_EVENTS.push_back(BLK_NAME);
872 
873 #define MAKE_NEXT_BLOCK_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, HF) \
874  cryptonote::block BLK_NAME; \
875  generator.construct_block(BLK_NAME, PREV_BLOCK, MINER_ACC, std::list<cryptonote::transaction>(), HF); \
876  VEC_EVENTS.push_back(BLK_NAME);
877 
878 #define MAKE_NEXT_BLOCK_TX1(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, TX1) \
879  cryptonote::block BLK_NAME; \
880  { \
881  std::list<cryptonote::transaction> tx_list; \
882  tx_list.push_back(TX1); \
883  generator.construct_block(BLK_NAME, PREV_BLOCK, MINER_ACC, tx_list); \
884  } \
885  VEC_EVENTS.push_back(BLK_NAME);
886 
887 #define MAKE_NEXT_BLOCK_TX1_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, TX1, HF) \
888  cryptonote::block BLK_NAME; \
889  { \
890  std::list<cryptonote::transaction> tx_list; \
891  tx_list.push_back(TX1); \
892  generator.construct_block(BLK_NAME, PREV_BLOCK, MINER_ACC, tx_list, HF); \
893  } \
894  VEC_EVENTS.push_back(BLK_NAME);
895 
896 #define MAKE_NEXT_BLOCK_TX_LIST(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, TXLIST) \
897  cryptonote::block BLK_NAME; \
898  generator.construct_block(BLK_NAME, PREV_BLOCK, MINER_ACC, TXLIST); \
899  VEC_EVENTS.push_back(BLK_NAME);
900 
901 #define MAKE_NEXT_BLOCK_TX_LIST_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, TXLIST, HF) \
902  cryptonote::block BLK_NAME; \
903  generator.construct_block(BLK_NAME, PREV_BLOCK, MINER_ACC, TXLIST, HF); \
904  VEC_EVENTS.push_back(BLK_NAME);
905 
906 #define REWIND_BLOCKS_N_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, COUNT, HF) \
907  cryptonote::block BLK_NAME; \
908  { \
909  cryptonote::block blk_last = PREV_BLOCK; \
910  for (size_t i = 0; i < COUNT; ++i) \
911  { \
912  MAKE_NEXT_BLOCK_HF(VEC_EVENTS, blk, blk_last, MINER_ACC, HF); \
913  blk_last = blk; \
914  } \
915  BLK_NAME = blk_last; \
916  }
917 
918 #define REWIND_BLOCKS_N(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, COUNT) REWIND_BLOCKS_N_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, COUNT, boost::none)
919 #define REWIND_BLOCKS(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC) REWIND_BLOCKS_N(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW)
920 #define REWIND_BLOCKS_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, HF) REWIND_BLOCKS_N_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, HF)
921 
922 #define MAKE_TX_MIX(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \
923  cryptonote::transaction TX_NAME; \
924  construct_tx_to_key(VEC_EVENTS, TX_NAME, HEAD, FROM, TO, AMOUNT, TESTS_DEFAULT_FEE, NMIX); \
925  VEC_EVENTS.push_back(TX_NAME);
926 
927 #define MAKE_TX_MIX_RCT(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \
928  cryptonote::transaction TX_NAME; \
929  construct_tx_to_key(VEC_EVENTS, TX_NAME, HEAD, FROM, TO, AMOUNT, TESTS_DEFAULT_FEE, NMIX, true, rct::RangeProofPaddedBulletproof); \
930  VEC_EVENTS.push_back(TX_NAME);
931 
932 #define MAKE_TX(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, HEAD) MAKE_TX_MIX(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, 0, HEAD)
933 
934 #define MAKE_TX_MIX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \
935  { \
936  cryptonote::transaction t; \
937  construct_tx_to_key(VEC_EVENTS, t, HEAD, FROM, TO, AMOUNT, TESTS_DEFAULT_FEE, NMIX); \
938  SET_NAME.push_back(t); \
939  VEC_EVENTS.push_back(t); \
940  }
941 
942 #define MAKE_TX_MIX_LIST_RCT(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \
943  MAKE_TX_MIX_LIST_RCT_EX(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD, rct::RangeProofPaddedBulletproof, 1)
944 #define MAKE_TX_MIX_LIST_RCT_EX(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD, RCT_TYPE, BP_VER) \
945  { \
946  cryptonote::transaction t; \
947  construct_tx_to_key(VEC_EVENTS, t, HEAD, FROM, TO, AMOUNT, TESTS_DEFAULT_FEE, NMIX, true, RCT_TYPE, BP_VER); \
948  SET_NAME.push_back(t); \
949  VEC_EVENTS.push_back(t); \
950  }
951 
952 #define MAKE_TX_MIX_DEST_LIST_RCT(VEC_EVENTS, SET_NAME, FROM, TO, NMIX, HEAD) \
953  MAKE_TX_MIX_DEST_LIST_RCT_EX(VEC_EVENTS, SET_NAME, FROM, TO, NMIX, HEAD, rct::RangeProofPaddedBulletproof, 1)
954 #define MAKE_TX_MIX_DEST_LIST_RCT_EX(VEC_EVENTS, SET_NAME, FROM, TO, NMIX, HEAD, RCT_TYPE, BP_VER) \
955  { \
956  cryptonote::transaction t; \
957  construct_tx_to_key(VEC_EVENTS, t, HEAD, FROM, TO, TESTS_DEFAULT_FEE, NMIX, true, RCT_TYPE, BP_VER); \
958  SET_NAME.push_back(t); \
959  VEC_EVENTS.push_back(t); \
960  }
961 
962 #define MAKE_TX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, HEAD) MAKE_TX_MIX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, 0, HEAD)
963 
964 #define MAKE_TX_LIST_START(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, HEAD) \
965  std::list<cryptonote::transaction> SET_NAME; \
966  MAKE_TX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, HEAD);
967 
968 #define MAKE_TX_LIST_START_RCT(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \
969  std::list<cryptonote::transaction> SET_NAME; \
970  MAKE_TX_MIX_LIST_RCT(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD);
971 
972 #define MAKE_MINER_TX_AND_KEY_AT_HF_MANUALLY(TX, BLK, HF_VERSION, KEY) \
973  transaction TX; \
974  if (!construct_miner_tx_manually(get_block_height(BLK) + 1, generator.get_already_generated_coins(BLK), \
975  miner_account.get_keys().m_account_address, TX, 0, HF_VERSION, KEY)) \
976  return false;
977 
978 #define MAKE_MINER_TX_AND_KEY_MANUALLY(TX, BLK, KEY) MAKE_MINER_TX_AND_KEY_AT_HF_MANUALLY(TX, BLK, 1, KEY)
979 
980 #define MAKE_MINER_TX_MANUALLY(TX, BLK) MAKE_MINER_TX_AND_KEY_MANUALLY(TX, BLK, 0)
981 
982 #define SET_EVENT_VISITOR_SETT(VEC_EVENTS, SETT) VEC_EVENTS.push_back(event_visitor_settings(SETT));
983 
984 #define GENERATE(filename, genclass) \
985  { \
986  std::vector<test_event_entry> events; \
987  genclass g; \
988  g.generate(events); \
989  if (!tools::serialize_obj_to_file(events, filename)) \
990  { \
991  MERROR("Failed to serialize data to file: " << filename); \
992  throw std::runtime_error("Failed to serialize data to file"); \
993  } \
994  }
995 
996 
997 #define PLAY(filename, genclass) \
998  if(!do_replay_file<genclass>(filename)) \
999  { \
1000  MERROR("Failed to pass test : " << #genclass); \
1001  return 1; \
1002  }
1003 
1004 #define CATCH_REPLAY(genclass) \
1005  catch (const std::exception& ex) \
1006  { \
1007  MERROR(#genclass << " generation failed: what=" << ex.what()); \
1008  } \
1009  catch (...) \
1010  { \
1011  MERROR(#genclass << " generation failed: generic exception"); \
1012  }
1013 
1014 #define REPLAY_CORE(genclass) \
1015  if (generated && do_replay_events< genclass >(events)) \
1016  { \
1017  MGINFO_GREEN("#TEST# Succeeded " << #genclass); \
1018  } \
1019  else \
1020  { \
1021  MERROR("#TEST# Failed " << #genclass); \
1022  failed_tests.push_back(#genclass); \
1023  }
1024 
1025 #define REPLAY_WITH_CORE(genclass, CORE) \
1026  if (generated && replay_events_through_core_validate< genclass >(events, CORE)) \
1027  { \
1028  MGINFO_GREEN("#TEST# Succeeded " << #genclass); \
1029  } \
1030  else \
1031  { \
1032  MERROR("#TEST# Failed " << #genclass); \
1033  failed_tests.push_back(#genclass); \
1034  }
1035 
1036 #define CATCH_GENERATE_REPLAY(genclass) \
1037  CATCH_REPLAY(genclass); \
1038  REPLAY_CORE(genclass);
1039 
1040 #define CATCH_GENERATE_REPLAY_CORE(genclass, CORE) \
1041  CATCH_REPLAY(genclass); \
1042  REPLAY_WITH_CORE(genclass, CORE);
1043 
1044 #define GENERATE_AND_PLAY(genclass) \
1045  if (list_tests) \
1046  std::cout << #genclass << std::endl; \
1047  else if (filter.empty() || boost::regex_match(std::string(#genclass), match, boost::regex(filter))) \
1048  { \
1049  std::vector<test_event_entry> events; \
1050  ++tests_count; \
1051  bool generated = false; \
1052  try \
1053  { \
1054  genclass g; \
1055  generated = g.generate(events); \
1056  } \
1057  CATCH_GENERATE_REPLAY(genclass); \
1058  }
1059 
1060 #define GENERATE_AND_PLAY_INSTANCE(genclass, ins, CORE) \
1061  if (filter.empty() || boost::regex_match(std::string(#genclass), match, boost::regex(filter))) \
1062  { \
1063  std::vector<test_event_entry> events; \
1064  ++tests_count; \
1065  bool generated = false; \
1066  try \
1067  { \
1068  generated = ins.generate(events); \
1069  } \
1070  CATCH_GENERATE_REPLAY_CORE(genclass, CORE); \
1071  }
1072 
1073 #define CALL_TEST(test_name, function) \
1074  { \
1075  if(!function()) \
1076  { \
1077  MERROR("#TEST# Failed " << test_name); \
1078  return 1; \
1079  } \
1080  else \
1081  { \
1082  MGINFO_GREEN("#TEST# Succeeded " << test_name); \
1083  } \
1084  }
1085 
1086 #define QUOTEME(x) #x
1087 #define DEFINE_TESTS_ERROR_CONTEXT(text) const char* perr_context = text; (void) perr_context;
1088 #define CHECK_TEST_CONDITION(cond) CHECK_AND_ASSERT_MES(cond, false, "[" << perr_context << "] failed: \"" << QUOTEME(cond) << "\"")
1089 #define CHECK_EQ(v1, v2) CHECK_AND_ASSERT_MES(v1 == v2, false, "[" << perr_context << "] failed: \"" << QUOTEME(v1) << " == " << QUOTEME(v2) << "\", " << v1 << " != " << v2)
1090 #define CHECK_NOT_EQ(v1, v2) CHECK_AND_ASSERT_MES(!(v1 == v2), false, "[" << perr_context << "] failed: \"" << QUOTEME(v1) << " != " << QUOTEME(v2) << "\", " << v1 << " == " << v2)
1091 #define MK_COINS(amount) (UINT64_C(amount) * COIN)
1092 #define TESTS_DEFAULT_FEE ((uint64_t)20000000000) // 2 * pow(10, 10)
friend class boost::serialization::access
Definition: chaingen.h:145
void set_events(const std::vector< test_event_entry > *events)
Definition: chaingen.h:259
std::map< uint64_t, std::vector< output_index > > map_output_idx_t
Definition: chaingen.h:362
Definition: binary_utils.h:36
crypto::hash prev_id
Definition: chaingen.h:201
block_tracker()=default
Definition: chaingen.h:369
bool operator()(const cryptonote::account_base &ab) const
Definition: chaingen.h:628
size_t tx_no
Definition: chaingen.h:298
std::vector< cryptonote::tx_destination_entry > build_dsts(const var_addr_t &to1, bool sub1=false, uint64_t am1=0)
Definition: chaingen.cpp:958
test_generator()
Definition: chaingen.h:232
bool find_block_chain(const std::vector< test_event_entry > &events, std::vector< cryptonote::block > &blockchain, map_hash2tx_t &mtx, const crypto::hash &head)
Definition: chaingen.cpp:1248
const uint32_t T[512]
Definition: groestl_tables.h:36
size_t idx
Definition: chaingen.h:300
void serialize(Archive &ar, const unsigned int)
Definition: chaingen.h:76
test_generator(const test_generator &other)
Definition: chaingen.h:233
void global_indices(const cryptonote::transaction *tx, std::vector< uint64_t > &indices)
Definition: chaingen.cpp:686
bool deinit()
performs safe shutdown steps for core and core components
Definition: cryptonote_core.cpp:738
const char * inp
Definition: hmac_keccak.cpp:41
cryptonote::relay_method m_tx_relay
Definition: chaingen.h:514
push_core_event_visitor(cryptonote::core &c, const std::vector< test_event_entry > &events, t_test_class &validator)
Definition: chaingen.h:517
bool check_tx_verification_context(const cryptonote::tx_verification_context &tvc, bool, size_t, const cryptonote::transaction &)
Definition: chaingen.cpp:1334
bool check_block_verification_context(const cryptonote::block_verification_context &bvc, size_t event_idx, const cryptonote::block &)
Definition: chaingen.cpp:1329
Definition: chaingen.h:225
size_t get_pool_transactions_count(bool include_sensitive_txes=false) const
get the total number of transactions in the pool
Definition: cryptonote_core.cpp:1473
void add_block(const cryptonote::block &blk, size_t tsx_size, std::vector< size_t > &block_weights, uint64_t already_generated_coins, uint64_t block_reward, uint8_t hf_version=1)
Definition: chaingen.cpp:229
binary_archive< false > ar
Definition: cold-outputs.cpp:54
Definition: portable_binary_archive.hpp:29
bool extract_hard_forks(const std::vector< test_event_entry > &events, v_hardforks_t &hard_forks)
Definition: chaingen.cpp:1117
uint64_t current_difficulty_window(const boost::optional< uint8_t > &hf_ver=boost::none)
Definition: chaingen.h:416
uint64_t sum_amount(const std::vector< cryptonote::tx_destination_entry > &destinations)
Definition: chaingen.cpp:852
Definition: chaingen.h:138
bool construct_block_manually(cryptonote::block &blk, const cryptonote::block &prev_block, const cryptonote::account_base &miner_acc, int actual_params=bf_none, uint8_t major_ver=0, uint8_t minor_ver=0, uint64_t timestamp=0, const crypto::hash &prev_id=crypto::hash(), const cryptonote::difficulty_type &diffic=1, const cryptonote::transaction &miner_tx=cryptonote::transaction(), const std::vector< crypto::hash > &tx_hashes=std::vector< crypto::hash >(), size_t txs_sizes=0, size_t max_outs=999, uint8_t hf_version=1, uint64_t fees=0)
Definition: chaingen.cpp:341
int i
Definition: pymoduletest.py:23
void serialize(Archive &ar, const unsigned int)
Definition: chaingen.h:131
std::string callback_name
Definition: chaingen.h:67
std::pair< uint64_t, size_t > outloc_t
Definition: chaingen.h:366
std::unordered_map< crypto::hash, block_info > m_blocks_info
Definition: chaingen.h:263
Definition: cryptonote_basic.h:538
boost::optional< v_hardforks_t > hard_forks
Definition: chaingen.h:140
event_replay_settings()=default
key commit(xmr_amount amount, const key &mask)
Definition: rctOps.cpp:336
Definition: cryptonote_protocol_defs.h:132
Definition: chaingen.h:219
::std::string string
Definition: gtest-port.h:1097
Definition: chaingen.h:226
Definition: chaingen.h:118
std::map< std::string, verify_callback > callbacks_map
Definition: chaingen.h:169
Received/sent over network using Dandelion++ fluff.
bool is_coin_base
Definition: chaingen.h:302
Definition: cryptonote_basic.h:474
bool operator()(const std::vector< cryptonote::transaction > &txs) const
Definition: chaingen.h:578
void serialize(Archive &ar, const unsigned int)
Definition: chaingen.h:148
bool operator()(const callback_entry &cb) const
Definition: chaingen.h:622
boost::variant< txout_to_script, txout_to_scripthash, txout_to_key, txout_to_tagged_key > txout_target_v
Definition: cryptonote_basic.h:154
Definition: blockchain.py:1
map_output_idx_t m_outs
Definition: chaingen.h:379
std::unordered_map< crypto::public_key, cryptonote::subaddress_index > subaddresses_t
Definition: chaingen.h:365
const cryptonote::txout_target_v out
Definition: chaingen.h:295
cryptonote::blobdata data
Definition: chaingen.h:92
Definition: chaingen.h:119
bool operator()(const cryptonote::transaction &tx) const
Definition: chaingen.h:565
uint64_t amount
Definition: chaingen.h:372
Definition: chaingen.h:185
Definition: chaingen.h:222
void set_network_type(const cryptonote::network_type nettype)
Definition: chaingen.h:260
std::map< uint64_t, std::vector< size_t > > map_output_t
Definition: chaingen.h:361
void event_index(size_t ev_index)
Definition: chaingen.h:526
#define DIFFICULTY_TARGET_V1
Definition: cryptonote_config.h:81
Received in block, takes precedence over others.
settings
Definition: chaingen.h:114
int type
Definition: superscalar.cpp:50
friend class boost::serialization::access
Definition: chaingen.h:206
bool do_replay_events(std::vector< test_event_entry > &events)
Definition: chaingen.h:803
Definition: bulletproofs.cc:63
void get_fake_outs(size_t num_outs, uint64_t amount, uint64_t global_index, uint64_t cur_height, std::vector< get_outs_entry > &outs)
Definition: chaingen.cpp:698
int mask
Definition: chaingen.h:112
Definition: chaingen.h:65
bool operator()(const serialized_block &sr_block) const
Definition: chaingen.h:634
boost::function< bool(cryptonote::core &c, size_t ev_index, const std::vector< test_event_entry > &events)> verify_callback
Definition: chaingen.h:168
#define DIFFICULTY_TARGET_V2
Definition: cryptonote_config.h:80
Definition: verification_context.h:65
boost::variant< cryptonote::account_public_address, cryptonote::account_keys, cryptonote::account_base, cryptonote::tx_destination_entry > var_addr_t
Definition: chaingen.h:368
unsigned char uint8_t
Definition: stdint.h:124
boost::variant< cryptonote::block, cryptonote::transaction, std::vector< cryptonote::transaction >, cryptonote::account_base, callback_entry, serialized_block, serialized_transaction, event_visitor_settings, event_replay_settings > test_event_entry
Definition: chaingen.h:162
Definition: chaingen.h:376
bool check_tx_verification_context_array(const std::vector< cryptonote::tx_verification_context > &tvcs, size_t, size_t, const std::vector< cryptonote::transaction > &)
Definition: chaingen.cpp:1339
std::unordered_map< crypto::hash, cryptonote::block > map_block_t
Definition: chaingen.h:363
const std::vector< test_event_entry > * m_events
Definition: chaingen.h:264
uint64_t amount
Definition: chaingen.h:296
bool prepare_handle_incoming_blocks(const std::vector< block_complete_entry > &blocks_entry, std::vector< block > &blocks)
performs some preprocessing on a group of incoming blocks to speed up verification ...
Definition: cryptonote_core.cpp:1346
void fill_tx_sources_and_destinations(const std::vector< test_event_entry > &events, const cryptonote::block &blk_head, const cryptonote::account_base &from, const cryptonote::account_public_address &to, uint64_t amount, uint64_t fee, size_t nmix, std::vector< cryptonote::tx_source_entry > &sources, std::vector< cryptonote::tx_destination_entry > &destinations)
Definition: chaingen.cpp:927
desc
Definition: pymoduletest.py:79
map_txid_output_t::iterator find_out(const crypto::hash &txid, size_t out)
Definition: chaingen.cpp:613
bool operator()(const cryptonote::block &b) const
Definition: chaingen.h:599
size_t block_weight
Definition: chaingen.h:203
#define END_SERIALIZE()
self-explanatory
Definition: serialization.h:150
serialized_object()
Definition: chaingen.h:85
Definition: chaingen.h:221
size_t m_ev_index
Definition: chaingen.h:512
bool is_subaddr
Definition: chaingen.h:371
void recycle()
Definition: threadpool.cpp:68
bool trim_block_chain(std::vector< cryptonote::block > &blockchain, const crypto::hash &tail)
Definition: chaingen.cpp:1180
bool construct_tx_to_key(const std::vector< test_event_entry > &events, cryptonote::transaction &tx, const cryptonote::block &blk_head, const cryptonote::account_base &from, const var_addr_t &to, uint64_t amount, uint64_t fee, size_t nmix, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version=0)
Definition: chaingen.cpp:1023
Holds cryptonote related classes and helpers.
Definition: blockchain_db.cpp:44
binary_archive< false > ba
Definition: bulletproof.cpp:40
Definition: verification_context.h:40
bool do_replay_file(const std::string &filename)
Definition: chaingen.h:812
rct::key comm
Definition: chaingen.h:305
std::vector< tx_blob_entry > txs
Definition: cryptonote_protocol_defs.h:137
Definition: chaingen.h:220
bool pruned
Definition: cryptonote_protocol_defs.h:134
bool spent
Definition: chaingen.h:303
bool cleanup_handle_incoming_blocks(bool force_sync=false)
incoming blocks post-processing, cleanup, and disk sync
Definition: cryptonote_core.cpp:1358
void set_rct(bool arct)
Definition: chaingen.h:321
Definition: chaingen.h:506
uint64_t unlock_time
Definition: chaingen.h:301
std::unordered_map< output_hasher, output_index, output_hasher_hasher > map_txid_output_t
Definition: chaingen.h:364
std::unordered_map< crypto::hash, const cryptonote::transaction * > map_hash2tx_t
Definition: chaingen.h:163
Definition: binary_archive.h:93
bool unserialize_obj_from_file(t_object &obj, const std::string &file_path)
Definition: boost_serialization_helper.h:97
Definition: chaingen.h:294
bool handle_error_helper(const boost::program_options::options_description &desc, F parser)
Definition: command_line.h:236
cryptonote::transaction construct_tx_with_fee(std::vector< test_event_entry > &events, const cryptonote::block &blk_head, const cryptonote::account_base &acc_from, const var_addr_t &to, uint64_t amount, uint64_t fee)
Definition: chaingen.cpp:1082
const std::pair< uint8_t, uint64_t > hard_forks[2]
Definition: chaingen.h:726
cryptonote::network_type m_nettype
Definition: chaingen.h:265
rct::rctSig rct_signatures
Definition: cryptonote_basic.h:214
bool construct_block_manually_tx(cryptonote::block &blk, const cryptonote::block &prev_block, const cryptonote::account_base &miner_acc, const std::vector< crypto::hash > &tx_hashes, size_t txs_size)
Definition: chaingen.cpp:386
Definition: chaingen.h:182
VARIANT_TAG(binary_archive, callback_entry, 0xcb)
const cryptonote::transaction * p_tx
Definition: chaingen.h:307
output_index & operator=(const output_index &other)
Definition: chaingen.h:351
Definition: chaingen.h:223
Definition: account.h:73
void serialize(Archive &a, unsigned_tx_set &x, const boost::serialization::version_type ver)
Definition: serialization.cpp:898
Definition: chaingen.h:110
handles core cryptonote functionality
Definition: cryptonote_core.h:86
Definition: rctTypes.h:79
cryptonote::block get_head_block(const std::vector< test_event_entry > &events)
Definition: chaingen.cpp:1234
map_block_t m_blocks
Definition: chaingen.h:381
unsigned __int64 uint64_t
Definition: stdint.h:136
void serialize(Archive &ar, const unsigned int)
Definition: chaingen.h:270
#define BEGIN_SERIALIZE_OBJECT()
begins the environment of the DSL for described the serialization of an object
Definition: serialization.h:131
bool t_serializable_object_to_blob(const t_object &to, blobdata &b_blob)
Definition: cryptonote_format_utils.h:165
block_info(crypto::hash a_prev_id, uint64_t an_already_generated_coins, size_t a_block_weight)
Definition: chaingen.h:194
output_index(const cryptonote::txout_target_v &_out, uint64_t _a, size_t _h, size_t tno, size_t ono, const cryptonote::block *_pb, const cryptonote::transaction *_pt)
Definition: chaingen.h:309
static void init_options(boost::program_options::options_description &desc)
adds command line options to the given options set
Definition: cryptonote_core.cpp:312
Definition: chaingen.h:229
const var_addr_t addr
Definition: chaingen.h:370
Definition: rctTypes.h:307
blobdata block
Definition: cryptonote_protocol_defs.h:135
friend class boost::serialization::access
Definition: chaingen.h:128
#define false
Definition: stdbool.h:37
uint64_t already_generated_coins
Definition: chaingen.h:202
bool operator()(const serialized_transaction &sr_tx) const
Definition: chaingen.h:664
Definition: chaingen.h:227
friend class boost::serialization::access
Definition: chaingen.h:397
cryptonote::account_public_address get_address(const var_addr_t &inp)
Definition: chaingen.cpp:817
Definition: account.h:40
cryptonote::core & m_c
Definition: chaingen.h:509
bool operator()(const event_replay_settings &settings)
Definition: chaingen.h:531
void serialize(Archive &ar, const unsigned int)
Definition: chaingen.h:400
block_fields
Definition: chaingen.h:217
bool set_genesis_block(const block &b)
clears the blockchain and starts a new one
Definition: cryptonote_core.cpp:727
Definition: cryptonote_core.h:61
map_txid_output_t m_map_outs
Definition: chaingen.h:380
const cryptonote::block * p_blk
Definition: chaingen.h:306
const std::string toString() const
Definition: chaingen.h:333
bool handle_incoming_block(const blobdata &block_blob, const block *b, block_verification_context &bvc, bool update_miner_blocktemplate=true)
handles an incoming block as part of a batch
Definition: cryptonote_core.cpp:1370
block_info()
Definition: chaingen.h:187
Definition: chaingen.h:228
r
Definition: testupnpigd.py:61
std::tuple< uint64_t, crypto::public_key, rct::key > get_outs_entry
Definition: chaingen.h:358
void register_callback(const std::string &cb_name, verify_callback cb)
Definition: chaingen.cpp:1314
std::string blobdata
Definition: blobdatatype.h:39
Definition: chaingen.h:725
serialized_object(const cryptonote::blobdata &a_data)
Definition: chaingen.h:87
Definition: block_weight.py:1
size_t out_no
Definition: chaingen.h:299
bool rct
Definition: chaingen.h:304
network_type
Definition: cryptonote_config.h:301
randomx_vm * vm
Definition: tests.cpp:20
Definition: cryptonote_basic.h:511
Received/send over network using Dandelion++ stem.
unsigned char bytes[32]
Definition: rctTypes.h:87
key identity()
Definition: rctOps.h:73
const std::vector< test_event_entry > & m_events
Definition: chaingen.h:510
bool construct_tx_rct(const cryptonote::account_keys &sender_account_keys, std::vector< cryptonote::tx_source_entry > &sources, const std::vector< cryptonote::tx_destination_entry > &destinations, const boost::optional< cryptonote::account_public_address > &change_addr, std::vector< uint8_t > extra, cryptonote::transaction &tx, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version=0)
std::pair< crypto::hash, size_t > output_hasher
Definition: chaingen.h:359
boost::multiprecision::uint128_t difficulty_type
Definition: difficulty.h:41
void log_event(const std::string &event_type) const
Definition: chaingen.h:687
bool extract_hard_forks_from_blocks(const std::vector< test_event_entry > &events, v_hardforks_t &hard_forks)
Definition: chaingen.cpp:1135
bool construct_block(cryptonote::block &blk, uint64_t height, const crypto::hash &prev_id, const cryptonote::account_base &miner_acc, uint64_t timestamp, uint64_t already_generated_coins, std::vector< size_t > &block_weights, const std::list< cryptonote::transaction > &tx_list, const boost::optional< uint8_t > &hf_ver=boost::none)
event_visitor_settings(int a_mask=0)
Definition: chaingen.h:122
bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins, const cryptonote::account_public_address &miner_address, cryptonote::transaction &tx, uint64_t fee, uint8_t hf_version=1, cryptonote::keypair *p_txkey=nullptr)
Definition: chaingen.cpp:975
bool verify(const std::string &cb_name, cryptonote::core &c, size_t ev_index, const std::vector< test_event_entry > &events)
Definition: chaingen.cpp:1318
uint64_t get_already_generated_coins(const crypto::hash &blk_id) const
Definition: chaingen.cpp:213
bool replay_events_through_core(cryptonote::core &cr, const std::vector< test_event_entry > &events, t_test_class &validator)
Definition: chaingen.h:694
Definition: chaingen.h:224
std::string dump_data(const cryptonote::transaction &tx)
Definition: chaingen.cpp:769
cryptonote::transaction tx
Definition: transaction.cpp:40
void process(const std::vector< cryptonote::block > &blockchain, const map_hash2tx_t &mtx)
Definition: chaingen.cpp:623
void get_confirmed_txs(const std::vector< cryptonote::block > &blockchain, const map_hash2tx_t &mtx, map_hash2tx_t &confirmed_txs)
Definition: chaingen.cpp:1160
t_test_class & m_validator
Definition: chaingen.h:511
get_test_options()
Definition: chaingen.h:730
#define AUTO_VAL_INIT(v)
Definition: misc_language.h:36
const cryptonote::test_options test_options
Definition: chaingen.h:727
Definition: cryptonote_tx_utils.h:74
bool replay_events_through_core_validate(std::vector< test_event_entry > &events, cryptonote::core &c)
Definition: chaingen.h:788
serialized_object< cryptonote::transaction > serialized_transaction
Definition: chaingen.h:108
Received via RPC with do_not_relay set.
Received via RPC; trying to send over i2p/tor, etc.
void fill_nonce(cryptonote::block &blk, const cryptonote::difficulty_type &diffic, uint64_t height)
Definition: chaingen.cpp:393
boost::hash< output_hasher > output_hasher_hasher
Definition: chaingen.h:360
static boost::multiprecision::uint128_t fees
Definition: blockchain_stats.cpp:58
output_index(const output_index &other)
Definition: chaingen.h:316
static threadpool & getInstanceForCompute()
Definition: threadpool.h:46
relay_method
Methods tracking how a tx was received and relayed.
Definition: enums.h:36
POD_CLASS hash
Definition: hash.h:49
uint64_t num_blocks(const std::vector< test_event_entry > &events)
Definition: chaingen.cpp:1220
void serialize(Archive &ar, const unsigned int)
Definition: chaingen.h:101
friend class boost::serialization::access
Definition: chaingen.h:267
cryptonote::difficulty_type get_test_difficulty(const boost::optional< uint8_t > &hf_ver=boost::none)
Definition: chaingen.h:415
cryptonote::tx_destination_entry build_dst(const var_addr_t &to, bool is_subaddr=false, uint64_t amount=0)
Definition: chaingen.cpp:949
Definition: chaingen.h:165
bool operator()(const event_visitor_settings &settings)
Definition: chaingen.h:537
bool handle_incoming_tx(const blobdata &tx_blob, tx_verification_context &tvc, relay_method tx_relay, bool relayed)
handles an incoming transaction
Definition: cryptonote_core.cpp:772
void serialize(Archive &ar, const unsigned int)
Definition: chaingen.h:209
RangeProofType
Definition: rctTypes.h:307
size_t blk_height
Definition: chaingen.h:297
bool m_verifivation_failed
Definition: verification_context.h:68
std::string dump_keys(T *buff32)
Definition: chaingen.h:277
#define FIELD(f)
tags the field with the variable name and then serializes it
Definition: serialization.h:169
serialized_object< cryptonote::block > serialized_block
Definition: chaingen.h:107
std::string dump_data()
Definition: chaingen.cpp:736
const std::pair< uint8_t, uint64_t > * hard_forks
Definition: cryptonote_core.h:62
Definition: binary_archive.h:89
block_tracker(const block_tracker &bt)
Definition: chaingen.h:384
Definition: chaingen.h:83
#define const
Definition: ipfrdr.c:80
Definition: cryptonote_basic.h:204
ctkeyV outPk
Definition: rctTypes.h:325
bool good() const noexcept
Definition: binary_archive.h:99
void get_last_n_block_weights(std::vector< size_t > &block_weights, const crypto::hash &head, size_t n) const
Definition: chaingen.cpp:203
uint64_t get_balance(const cryptonote::account_base &addr, const std::vector< cryptonote::block > &blockchain, const map_hash2tx_t &mtx)
Definition: chaingen.cpp:1091
bool replay_events_through_core_plain(cryptonote::core &cr, const std::vector< test_event_entry > &events, t_test_class &validator, bool reinit=true)
Definition: chaingen.h:700
c
Definition: pymoduletest.py:79
void get_block_chain(std::vector< block_info > &blockchain, const crypto::hash &head, size_t n) const
Definition: chaingen.cpp:185
std::vector< std::pair< uint8_t, uint64_t > > v_hardforks_t
Definition: chaingen.h:137
cryptonote::block b
Definition: block.cpp:40
void fill_tx_destinations(const var_addr_t &from, const cryptonote::account_public_address &to, uint64_t amount, uint64_t fee, const std::vector< cryptonote::tx_source_entry > &sources, std::vector< cryptonote::tx_destination_entry > &destinations, bool always_change=false)
Definition: chaingen.cpp:918
bool do_replay_events_get_core(std::vector< test_event_entry > &events, cryptonote::core *core)
Definition: chaingen.h:734
callbacks_map m_callbacks
Definition: chaingen.h:178
rct::key commitment() const
Definition: chaingen.h:329