Electroneum
block_validation.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 "chaingen.h"
33 #include "block_validation.h"
34 
35 using namespace epee;
36 using namespace cryptonote;
37 
38 namespace
39 {
40  bool lift_up_difficulty(std::vector<test_event_entry>& events, std::vector<uint64_t>& timestamps,
41  std::vector<difficulty_type>& cummulative_difficulties, test_generator& generator,
42  size_t new_block_count, const block &blk_last, const account_base& miner_account)
43  {
44  difficulty_type commulative_diffic = cummulative_difficulties.empty() ? 0 : cummulative_difficulties.back();
45  block blk_prev = blk_last;
46  for (size_t i = 0; i < new_block_count; ++i)
47  {
48  block blk_next;
49  difficulty_type diffic = next_difficulty(timestamps, cummulative_difficulties,DIFFICULTY_TARGET);
50  if (!generator.construct_block_manually(blk_next, blk_prev, miner_account,
52  return false;
53 
54  commulative_diffic += diffic;
55  if (timestamps.size() == DIFFICULTY_WINDOW)
56  {
57  timestamps.erase(timestamps.begin());
58  cummulative_difficulties.erase(cummulative_difficulties.begin());
59  }
60  timestamps.push_back(blk_next.timestamp);
61  cummulative_difficulties.push_back(commulative_diffic);
62 
63  events.push_back(blk_next);
64  blk_prev = blk_next;
65  }
66 
67  return true;
68  }
69 }
70 
71 #define BLOCK_VALIDATION_INIT_GENERATE() \
72  GENERATE_ACCOUNT(miner_account); \
73  MAKE_GENESIS_BLOCK(events, blk_0, miner_account, 1338224400);
74 
75 //----------------------------------------------------------------------------------------------------------------------
76 // Tests
77 
78 bool gen_block_big_major_version::generate(std::vector<test_event_entry>& events) const
79 {
81 
82  block blk_1;
83  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_major_ver, 255);
84  events.push_back(blk_1);
85 
86  DO_CALLBACK(events, "check_block_purged");
87 
88  return true;
89 }
90 
91 bool gen_block_big_minor_version::generate(std::vector<test_event_entry>& events) const
92 {
94 
95  block blk_1;
96  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_minor_ver, 0, 255);
97  events.push_back(blk_1);
98 
99  DO_CALLBACK(events, "check_block_accepted");
100 
101  return true;
102 }
103 
104 bool gen_block_ts_not_checked::generate(std::vector<test_event_entry>& events) const
105 {
107  REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_account, BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW - 2);
108 
109  block blk_1;
110  generator.construct_block_manually(blk_1, blk_0r, miner_account, test_generator::bf_timestamp, 0, 0, blk_0.timestamp - 60 * 60);
111  events.push_back(blk_1);
112 
113  DO_CALLBACK(events, "check_block_accepted");
114 
115  return true;
116 }
117 
118 bool gen_block_ts_in_past::generate(std::vector<test_event_entry>& events) const
119 {
121  REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_account, BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW - 1);
122 
123  uint64_t ts_below_median = boost::get<block>(events[BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW / 2 - 1]).timestamp;
124  block blk_1;
125  generator.construct_block_manually(blk_1, blk_0r, miner_account, test_generator::bf_timestamp, 0, 0, ts_below_median);
126  events.push_back(blk_1);
127 
128  DO_CALLBACK(events, "check_block_purged");
129 
130  return true;
131 }
132 
133 bool gen_block_ts_in_future::generate(std::vector<test_event_entry>& events) const
134 {
136 
137  block blk_1;
138  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_timestamp, 0, 0, time(NULL) + 60*60 + CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT);
139  events.push_back(blk_1);
140 
141  DO_CALLBACK(events, "check_block_purged");
142 
143  return true;
144 }
145 
146 bool gen_block_invalid_prev_id::generate(std::vector<test_event_entry>& events) const
147 {
149 
150  block blk_1;
151  crypto::hash prev_id = get_block_hash(blk_0);
152  reinterpret_cast<char &>(prev_id) ^= 1;
153  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_prev_id, 0, 0, 0, prev_id);
154  events.push_back(blk_1);
155 
156  DO_CALLBACK(events, "check_block_purged");
157 
158  return true;
159 }
160 
162 {
163  if (1 == event_idx)
165  else
167 }
168 
169 bool gen_block_invalid_nonce::generate(std::vector<test_event_entry>& events) const
170 {
172 
173  std::vector<uint64_t> timestamps;
174  std::vector<difficulty_type> commulative_difficulties;
175  if (!lift_up_difficulty(events, timestamps, commulative_difficulties, generator, 2, blk_0, miner_account))
176  return false;
177 
178  // Create invalid nonce
179  difficulty_type diffic = next_difficulty(timestamps, commulative_difficulties,DIFFICULTY_TARGET);
180  assert(1 < diffic);
181  const block& blk_last = boost::get<block>(events.back());
182  uint64_t timestamp = blk_last.timestamp;
183  block blk_3;
184  do
185  {
186  ++timestamp;
187  blk_3.miner_tx.set_null();
188  if (!generator.construct_block_manually(blk_3, blk_last, miner_account,
190  return false;
191  }
192  while (0 == blk_3.nonce);
193  --blk_3.nonce;
194  events.push_back(blk_3);
195 
196  return true;
197 }
198 
199 bool gen_block_no_miner_tx::generate(std::vector<test_event_entry>& events) const
200 {
202 
203  transaction miner_tx;
204  miner_tx.set_null();
205 
206  block blk_1;
207  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
208  events.push_back(blk_1);
209 
210  DO_CALLBACK(events, "check_block_purged");
211 
212  return true;
213 }
214 
215 bool gen_block_unlock_time_is_low::generate(std::vector<test_event_entry>& events) const
216 {
218 
219  MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
220  --miner_tx.unlock_time;
221 
222  block blk_1;
223  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
224  events.push_back(blk_1);
225 
226  DO_CALLBACK(events, "check_block_purged");
227 
228  return true;
229 }
230 
231 bool gen_block_unlock_time_is_high::generate(std::vector<test_event_entry>& events) const
232 {
234 
235  MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
236  ++miner_tx.unlock_time;
237 
238  block blk_1;
239  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
240  events.push_back(blk_1);
241 
242  DO_CALLBACK(events, "check_block_purged");
243 
244  return true;
245 }
246 
247 bool gen_block_unlock_time_is_timestamp_in_past::generate(std::vector<test_event_entry>& events) const
248 {
250 
251  MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
252  miner_tx.unlock_time = blk_0.timestamp - 10 * 60;
253 
254  block blk_1;
255  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
256  events.push_back(blk_1);
257 
258  DO_CALLBACK(events, "check_block_purged");
259 
260  return true;
261 }
262 
263 bool gen_block_unlock_time_is_timestamp_in_future::generate(std::vector<test_event_entry>& events) const
264 {
266 
267  MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
268  miner_tx.unlock_time = blk_0.timestamp + 3 * CRYPTONOTE_MINED_ETN_UNLOCK_WINDOW * DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN_V6;
269 
270  block blk_1;
271  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
272  events.push_back(blk_1);
273 
274  DO_CALLBACK(events, "check_block_purged");
275 
276  return true;
277 }
278 
279 bool gen_block_height_is_low::generate(std::vector<test_event_entry>& events) const
280 {
282 
283  MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
284  boost::get<txin_gen>(miner_tx.vin[0]).height--;
285 
286  block blk_1;
287  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
288  events.push_back(blk_1);
289 
290  DO_CALLBACK(events, "check_block_purged");
291 
292  return true;
293 }
294 
295 bool gen_block_height_is_high::generate(std::vector<test_event_entry>& events) const
296 {
298 
299  MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
300  boost::get<txin_gen>(miner_tx.vin[0]).height++;
301 
302  block blk_1;
303  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
304  events.push_back(blk_1);
305 
306  DO_CALLBACK(events, "check_block_purged");
307 
308  return true;
309 }
310 
311 bool gen_block_miner_tx_has_2_tx_gen_in::generate(std::vector<test_event_entry>& events) const
312 {
314 
315  MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
316 
317  txin_gen in;
318  in.height = get_block_height(blk_0) + 1;
319  miner_tx.vin.push_back(in);
320 
321  block blk_1;
322  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
323  events.push_back(blk_1);
324 
325  DO_CALLBACK(events, "check_block_purged");
326 
327  return true;
328 }
329 
330 bool gen_block_miner_tx_has_2_in::generate(std::vector<test_event_entry>& events) const
331 {
333  REWIND_BLOCKS(events, blk_0r, blk_0, miner_account);
334 
335  GENERATE_ACCOUNT(alice);
336 
337  tx_source_entry se;
338  se.amount = blk_0.miner_tx.vout[0].amount;
339  se.push_output(0, boost::get<txout_to_key>(blk_0.miner_tx.vout[0].target).key, se.amount);
340  se.real_output = 0;
341  se.rct = false;
342  se.real_out_tx_key = get_tx_pub_key_from_extra(blk_0.miner_tx);
344  std::vector<tx_source_entry> sources;
345  sources.push_back(se);
346 
348  de.addr = miner_account.get_keys().m_account_address;
349  de.amount = se.amount;
350  std::vector<tx_destination_entry> destinations;
351  destinations.push_back(de);
352 
353  transaction tmp_tx;
354  if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tmp_tx, 0))
355  return false;
356 
357  MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
358  miner_tx.vin.push_back(tmp_tx.vin[0]);
359 
360  block blk_1;
361  generator.construct_block_manually(blk_1, blk_0r, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
362  events.push_back(blk_1);
363 
364  DO_CALLBACK(events, "check_block_purged");
365 
366  return true;
367 }
368 
369 bool gen_block_miner_tx_with_txin_to_key::generate(std::vector<test_event_entry>& events) const
370 {
372 
373  // This block has only one output
374  block blk_1;
375  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_none);
376  events.push_back(blk_1);
377 
378  REWIND_BLOCKS(events, blk_1r, blk_1, miner_account);
379 
380  tx_source_entry se;
381  se.amount = blk_1.miner_tx.vout[0].amount;
382  se.push_output(0, boost::get<txout_to_key>(blk_1.miner_tx.vout[0].target).key, se.amount);
383  se.real_output = 0;
384  se.rct = false;
387  std::vector<tx_source_entry> sources;
388  sources.push_back(se);
389 
391  de.addr = miner_account.get_keys().m_account_address;
392  de.amount = se.amount;
393  std::vector<tx_destination_entry> destinations;
394  destinations.push_back(de);
395 
396  transaction tmp_tx;
397  if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tmp_tx, 0))
398  return false;
399 
400  MAKE_MINER_TX_MANUALLY(miner_tx, blk_1);
401  miner_tx.vin[0] = tmp_tx.vin[0];
402 
403  block blk_2;
404  generator.construct_block_manually(blk_2, blk_1r, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
405  events.push_back(blk_2);
406 
407  DO_CALLBACK(events, "check_block_purged");
408 
409  return true;
410 }
411 
412 bool gen_block_miner_tx_out_is_small::generate(std::vector<test_event_entry>& events) const
413 {
415 
416  MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
417  miner_tx.vout[0].amount /= 2;
418 
419  block blk_1;
420  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
421  events.push_back(blk_1);
422 
423  DO_CALLBACK(events, "check_block_purged");
424 
425  return true;
426 }
427 
428 bool gen_block_miner_tx_out_is_big::generate(std::vector<test_event_entry>& events) const
429 {
431 
432  MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
433  miner_tx.vout[0].amount *= 2;
434 
435  block blk_1;
436  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
437  events.push_back(blk_1);
438 
439  DO_CALLBACK(events, "check_block_purged");
440 
441  return true;
442 }
443 
444 bool gen_block_miner_tx_has_no_out::generate(std::vector<test_event_entry>& events) const
445 {
447 
448  MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
449  miner_tx.vout.clear();
450 
451  block blk_1;
452  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
453  events.push_back(blk_1);
454 
455  DO_CALLBACK(events, "check_block_purged");
456 
457  return true;
458 }
459 
460 bool gen_block_miner_tx_has_out_to_alice::generate(std::vector<test_event_entry>& events) const
461 {
463 
464  GENERATE_ACCOUNT(alice);
465 
466  keypair txkey;
467  MAKE_MINER_TX_AND_KEY_MANUALLY(miner_tx, blk_0, &txkey);
468 
469  crypto::key_derivation derivation;
470  crypto::public_key out_eph_public_key;
471  crypto::generate_key_derivation(alice.get_keys().m_account_address.m_view_public_key, txkey.sec, derivation);
472  crypto::derive_public_key(derivation, 1, alice.get_keys().m_account_address.m_spend_public_key, out_eph_public_key);
473 
474  tx_out out_to_alice;
475  out_to_alice.amount = miner_tx.vout[0].amount / 2;
476  miner_tx.vout[0].amount -= out_to_alice.amount;
477  out_to_alice.target = txout_to_key(out_eph_public_key);
478  miner_tx.vout.push_back(out_to_alice);
479 
480  block blk_1;
481  generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx);
482  events.push_back(blk_1);
483 
484  DO_CALLBACK(events, "check_block_accepted");
485 
486  return true;
487 }
488 
489 bool gen_block_has_invalid_tx::generate(std::vector<test_event_entry>& events) const
490 {
492 
493  std::vector<crypto::hash> tx_hashes;
494  tx_hashes.push_back(crypto::hash());
495 
496  block blk_1;
497  generator.construct_block_manually_tx(blk_1, blk_0, miner_account, tx_hashes, 0);
498  events.push_back(blk_1);
499 
500  DO_CALLBACK(events, "check_block_purged");
501 
502  return true;
503 }
504 
505 bool gen_block_is_too_big::generate(std::vector<test_event_entry>& events) const
506 {
508 
509  // Creating a huge miner_tx, it will have a lot of outs
510  MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
511  static const size_t tx_out_count = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 / 2;
512  uint64_t amount = get_outs_etn_amount(miner_tx);
513  uint64_t portion = amount / tx_out_count;
514  uint64_t remainder = amount % tx_out_count;
515  txout_target_v target = miner_tx.vout[0].target;
516  miner_tx.vout.clear();
517  for (size_t i = 0; i < tx_out_count; ++i)
518  {
519  tx_out o;
520  o.amount = portion;
521  o.target = target;
522  miner_tx.vout.push_back(o);
523  }
524  if (0 < remainder)
525  {
526  tx_out o;
527  o.amount = remainder;
528  o.target = target;
529  miner_tx.vout.push_back(o);
530  }
531 
532  // Block reward will be incorrect, as it must be reduced if cumulative block size is very big,
533  // but in this test it doesn't matter
534  block blk_1;
535  if (!generator.construct_block_manually(blk_1, blk_0, miner_account, test_generator::bf_miner_tx, 0, 0, 0, crypto::hash(), 0, miner_tx))
536  return false;
537 
538  events.push_back(blk_1);
539 
540  DO_CALLBACK(events, "check_block_purged");
541 
542  return true;
543 }
544 
546  : m_corrupt_blocks_begin_idx(0)
547 {
550 }
551 
552 bool gen_block_invalid_binary_format::generate(std::vector<test_event_entry>& events) const
553 {
555 
556  std::vector<uint64_t> timestamps;
557  std::vector<difficulty_type> cummulative_difficulties;
558  difficulty_type cummulative_diff = 1;
559 
560  // Unlock blk_0 outputs
561  block blk_last = blk_0;
563  for (size_t i = 0; i < CRYPTONOTE_MINED_ETN_UNLOCK_WINDOW; ++i)
564  {
565  MAKE_NEXT_BLOCK(events, blk_curr, blk_last, miner_account);
566  timestamps.push_back(blk_curr.timestamp);
567  cummulative_difficulties.push_back(++cummulative_diff);
568  blk_last = blk_curr;
569  }
570 
571  // Lifting up takes a while
572  difficulty_type diffic;
573  do
574  {
575  blk_last = boost::get<block>(events.back());
576  diffic = next_difficulty(timestamps, cummulative_difficulties,DIFFICULTY_TARGET);
577  if (!lift_up_difficulty(events, timestamps, cummulative_difficulties, generator, 1, blk_last, miner_account))
578  return false;
579  std::cout << "Block #" << events.size() << ", difficulty: " << diffic << std::endl;
580  }
581  while (diffic < 1500);
582 
583  blk_last = boost::get<block>(events.back());
584  MAKE_TX(events, tx_0, miner_account, miner_account, MK_COINS(30), boost::get<block>(events[1]));
585  DO_CALLBACK(events, "corrupt_blocks_boundary");
586 
587  block blk_test;
588  std::vector<crypto::hash> tx_hashes;
589  tx_hashes.push_back(get_transaction_hash(tx_0));
590  size_t txs_weight = get_transaction_weight(tx_0);
591  diffic = next_difficulty(timestamps, cummulative_difficulties,DIFFICULTY_TARGET);
592  if (!generator.construct_block_manually(blk_test, blk_last, miner_account,
594  crypto::hash(), diffic, transaction(), tx_hashes, txs_weight))
595  return false;
596 
597  blobdata blob = t_serializable_object_to_blob(blk_test);
598  for (size_t i = 0; i < blob.size(); ++i)
599  {
600  for (size_t bit_idx = 0; bit_idx < sizeof(blobdata::value_type) * 8; ++bit_idx)
601  {
602  serialized_block sr_block(blob);
603  blobdata::value_type& ch = sr_block.data[i];
604  ch ^= 1 << bit_idx;
605 
606  events.push_back(sr_block);
607  }
608  }
609 
610  DO_CALLBACK(events, "check_all_blocks_purged");
611 
612  return true;
613 }
614 
616  size_t event_idx, const cryptonote::block& blk)
617 {
618  if (0 == m_corrupt_blocks_begin_idx || event_idx < m_corrupt_blocks_begin_idx)
619  {
620  return bvc.m_added_to_main_chain;
621  }
622  else
623  {
626  }
627 }
628 
629 bool gen_block_invalid_binary_format::corrupt_blocks_boundary(cryptonote::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
630 {
631  m_corrupt_blocks_begin_idx = ev_index + 1;
632  return true;
633 }
634 
635 bool gen_block_invalid_binary_format::check_all_blocks_purged(cryptonote::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
636 {
637  DEFINE_TESTS_ERROR_CONTEXT("gen_block_invalid_binary_format::check_all_blocks_purged");
638 
640  CHECK_EQ(m_corrupt_blocks_begin_idx - 2, c.get_current_blockchain_height());
641 
642  return true;
643 }
bool generate(std::vector< test_event_entry > &events) const
#define CRYPTONOTE_MINED_ETN_UNLOCK_WINDOW
bool corrupt_blocks_boundary(cryptonote::core &c, size_t ev_index, const std::vector< test_event_entry > &events)
bool generate(std::vector< test_event_entry > &events) const
bool generate(std::vector< test_event_entry > &events) const
crypto::public_key real_out_tx_key
crypto::secret_key sec
bool generate(std::vector< test_event_entry > &events) const
difficulty_type next_difficulty(std::vector< uint64_t > timestamps, std::vector< difficulty_type > cumulative_difficulties, size_t target_seconds, uint8_t version)
Definition: difficulty.cpp:210
uint64_t get_outs_etn_amount(const transaction &tx)
bool check_all_blocks_purged(cryptonote::core &c, size_t ev_index, const std::vector< test_event_entry > &events)
POD_CLASS key_derivation
Definition: crypto.h:98
uint64_t height
Definition: blockchain.cpp:91
cryptonote::blobdata data
Definition: chaingen.h:92
bool construct_tx(const account_keys &sender_account_keys, std::vector< tx_source_entry > &sources, const std::vector< tx_destination_entry > &destinations, const boost::optional< cryptonote::account_public_address > &change_addr, const std::vector< uint8_t > &extra, transaction &tx, uint64_t unlock_time)
#define REWIND_BLOCKS_N(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, COUNT)
Definition: chaingen.h:889
bool generate(std::vector< test_event_entry > &events) const
bool generate(std::vector< test_event_entry > &events) const
boost::variant< txout_to_script, txout_to_scripthash, txout_to_key, txout_to_key_public > txout_target_v
#define MAKE_NEXT_BLOCK(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC)
Definition: chaingen.h:839
bool check_block_verification_context(const cryptonote::block_verification_context &bvc, size_t event_idx, const cryptonote::block &)
bool generate(std::vector< test_event_entry > &events) const
bool rct
uint64_t get_transaction_weight(const transaction &tx, size_t blob_size)
uint64_t amount
#define DIFFICULTY_WINDOW
bool generate_key_derivation(const public_key &key1, const secret_key &key2, key_derivation &derivation)
Definition: crypto.h:272
size_t real_output
bool generate(std::vector< test_event_entry > &events) const
const account_keys & get_keys() const
Definition: account.cpp:264
#define MAKE_MINER_TX_AND_KEY_MANUALLY(TX, BLK, KEY)
Definition: chaingen.h:943
Holds cryptonote related classes and helpers.
Definition: ban.cpp:40
bool generate(std::vector< test_event_entry > &events) const
time_t time
Definition: blockchain.cpp:93
uint64_t get_current_blockchain_height() const
get the current height of the blockchain
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)
Definition: chaingen.cpp:221
bool generate(std::vector< test_event_entry > &events) const
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:263
bool generate(std::vector< test_event_entry > &events) const
handles core cryptonote functionality
#define REGISTER_CALLBACK(CB_NAME, CLBACK)
Definition: chaingen.h:827
bool generate(std::vector< test_event_entry > &events) const
unsigned __int64 uint64_t
Definition: stdint.h:136
#define BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW
#define CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT
bool t_serializable_object_to_blob(const t_object &to, blobdata &b_blob)
bool generate(std::vector< test_event_entry > &events) const
crypto::public_key get_tx_pub_key_from_extra(const std::vector< uint8_t > &tx_extra, size_t pk_index)
uint64_t amount
#define MAKE_MINER_TX_MANUALLY(TX, BLK)
Definition: chaingen.h:949
bool generate(std::vector< test_event_entry > &events) const
POD_CLASS public_key
Definition: crypto.h:76
void push_output(uint64_t idx, const crypto::public_key &k, uint64_t amount)
bool generate(std::vector< test_event_entry > &events) const
size_t get_pool_transactions_count() const
get the total number of transactions in the pool
bool generate(std::vector< test_event_entry > &events) const
account_public_address addr
std::string blobdata
Definition: blobdatatype.h:39
account_public_address m_account_address
Definition: account.h:43
bool generate(std::vector< test_event_entry > &events) const
#define REWIND_BLOCKS(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC)
Definition: chaingen.h:890
boost::multiprecision::uint128_t difficulty_type
Definition: difficulty.h:43
bool generate(std::vector< test_event_entry > &events) const
txout_target_v target
bool generate(std::vector< test_event_entry > &events) const
size_t real_output_in_tx_index
bool derive_public_key(const key_derivation &derivation, std::size_t output_index, const public_key &base, public_key &derived_key)
Definition: crypto.h:275
#define DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN_V6
crypto::hash get_transaction_hash(const transaction &t)
bool generate(std::vector< test_event_entry > &events) const
#define MAKE_TX(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, HEAD)
Definition: chaingen.h:903
#define DIFFICULTY_TARGET
bool generate(std::vector< test_event_entry > &events) const
crypto::hash get_block_hash(uint64_t height)
POD_CLASS hash
Definition: hash.h:50
#define BLOCK_VALIDATION_INIT_GENERATE()
#define MK_COINS(amount)
Definition: chaingen.h:1060
#define CHECK_EQ(v1, v2)
Definition: chaingen.h:1058
#define GENERATE_ACCOUNT(account)
Definition: chaingen.h:801
bool generate(std::vector< test_event_entry > &events) const
#define DEFINE_TESTS_ERROR_CONTEXT(text)
Definition: chaingen.h:1056
#define DO_CALLBACK(VEC_EVENTS, CB_NAME)
Definition: chaingen.h:820
uint64_t get_block_height(const block &b)
#define CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1
bool generate(std::vector< test_event_entry > &events) const
bool generate(std::vector< test_event_entry > &events) const
bool check_block_verification_context(const cryptonote::block_verification_context &bvc, size_t event_idx, const cryptonote::block &)