Electroneum
rct.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 "ringct/rctSigs.h"
33 #include "chaingen.h"
34 #include "rct.h"
35 #include "device/device.hpp"
36 
37 using namespace epee;
38 using namespace crypto;
39 using namespace cryptonote;
40 
41 //----------------------------------------------------------------------------------------------------------------------
42 // Tests
43 
44 bool gen_rct_tx_validation_base::generate_with(std::vector<test_event_entry>& events,
45  const int *out_idx, int mixin, uint64_t amount_paid, bool valid,
46  const std::function<void(std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations)> &pre_tx,
47  const std::function<void(transaction &tx)> &post_tx) const
48 {
49  uint64_t ts_start = 1338224400;
50 
51  GENERATE_ACCOUNT(miner_account);
52  MAKE_GENESIS_BLOCK(events, blk_0, miner_account, ts_start);
53 
54  // create 4 miner accounts, and have them mine the next 4 blocks
55  cryptonote::account_base miner_accounts[4];
56  const cryptonote::block *prev_block = &blk_0;
58  for (size_t n = 0; n < 4; ++n) {
59  miner_accounts[n].generate();
60  CHECK_AND_ASSERT_MES(generator.construct_block_manually(blocks[n], *prev_block, miner_accounts[n],
62  2, 2, prev_block->timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
63  crypto::hash(), 0, transaction(), std::vector<crypto::hash>(), 0, 0, 2),
64  false, "Failed to generate block");
65  events.push_back(blocks[n]);
66  prev_block = blocks + n;
67  LOG_PRINT_L0("Initial miner tx " << n << ": " << obj_to_json_str(blocks[n].miner_tx));
68  }
69 
70  // rewind
71  cryptonote::block blk_r, blk_last;
72  {
73  blk_last = blocks[3];
74  for (size_t i = 0; i < CRYPTONOTE_MINED_ETN_UNLOCK_WINDOW; ++i)
75  {
77  CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk, blk_last, miner_account,
79  2, 2, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
80  crypto::hash(), 0, transaction(), std::vector<crypto::hash>(), 0, 0, 2),
81  false, "Failed to generate block");
82  events.push_back(blk);
83  blk_last = blk;
84  }
85  blk_r = blk_last;
86  }
87 
88  // create 4 txes from these miners in another block, to generate some rct outputs
89  transaction rct_txes[4];
90  rct::key rct_tx_masks[16];
91  cryptonote::block blk_txes[4];
92  for (size_t n = 0; n < 4; ++n)
93  {
94  std::vector<crypto::hash> starting_rct_tx_hashes;
95  std::vector<tx_source_entry> sources;
96 
97  sources.resize(1);
98  tx_source_entry& src = sources.back();
99 
100  const size_t index_in_tx = 5;
101  src.amount = 30000000000000;
102  for (int m = 0; m < 4; ++m) {
103  src.push_output(m, boost::get<txout_to_key>(blocks[m].miner_tx.vout[index_in_tx].target).key, src.amount);
104  }
106  src.real_output = n;
107  src.real_output_in_tx_index = index_in_tx;
108  src.mask = rct::identity();
109  src.rct = false;
110 
111  //fill outputs entry
113  td.addr = miner_accounts[n].get_keys().m_account_address;
114  td.amount = 7390000000000;
115  std::vector<tx_destination_entry> destinations;
116  destinations.push_back(td);
117  destinations.push_back(td);
118  destinations.push_back(td);
119  destinations.push_back(td); // 30 -> 7.39 * 4
120 
121  crypto::secret_key tx_key;
122  std::vector<crypto::secret_key> additional_tx_keys;
123  std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
124  subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0};
125  bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes[n], 0, tx_key, additional_tx_keys, true);
126  CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
127  events.push_back(rct_txes[n]);
128  starting_rct_tx_hashes.push_back(get_transaction_hash(rct_txes[n]));
129 
130  for (size_t o = 0; o < 4; ++o)
131  {
132  crypto::key_derivation derivation;
133  bool r = crypto::generate_key_derivation(destinations[o].addr.m_view_public_key, tx_key, derivation);
134  CHECK_AND_ASSERT_MES(r, false, "Failed to generate key derivation");
135  crypto::secret_key amount_key;
136  crypto::derivation_to_scalar(derivation, o, amount_key);
137  const uint8_t type = rct_txes[n].rct_signatures.type;
138  if (type == rct::RCTTypeSimple || type == rct::RCTTypeBulletproof || type == rct::RCTTypeBulletproof2)
139  rct::decodeRctSimple(rct_txes[n].rct_signatures, rct::sk2rct(amount_key), o, rct_tx_masks[o+n*4], hw::get_device("default"));
140  else
141  rct::decodeRct(rct_txes[n].rct_signatures, rct::sk2rct(amount_key), o, rct_tx_masks[o+n*4], hw::get_device("default"));
142  }
143 
144  CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk_txes[n], blk_last, miner_account,
146  4, 4, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
147  crypto::hash(), 0, transaction(), starting_rct_tx_hashes, 0, 6, 4),
148  false, "Failed to generate block");
149  events.push_back(blk_txes[n]);
150  blk_last = blk_txes[n];
151  }
152 
153  // rewind
154  {
155  for (size_t i = 0; i < CRYPTONOTE_MINED_ETN_UNLOCK_WINDOW; ++i)
156  {
157  cryptonote::block blk;
158  CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk, blk_last, miner_account,
160  4, 4, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
161  crypto::hash(), 0, transaction(), std::vector<crypto::hash>(), 0, 6, 4),
162  false, "Failed to generate block");
163  events.push_back(blk);
164  blk_last = blk;
165  }
166  blk_r = blk_last;
167  }
168 
169  // create a tx from the requested ouputs
170  std::vector<tx_source_entry> sources;
171  size_t global_rct_idx = 6; // skip first coinbase (6 outputs)
172  size_t rct_idx = 0;
173  size_t pre_rct_idx = 0;
174  for (size_t out_idx_idx = 0; out_idx[out_idx_idx] >= 0; ++out_idx_idx) {
175  sources.resize(sources.size()+1);
176  tx_source_entry& src = sources.back();
177 
178  src.real_output = 0;
179  if (out_idx[out_idx_idx]) {
180  // rct
181  src.amount = 7390000000000;
182  src.real_out_tx_key = get_tx_pub_key_from_extra(rct_txes[rct_idx/4]);
183  src.real_output_in_tx_index = rct_idx&3;
184  src.mask = rct_tx_masks[rct_idx];
185  src.rct = true;
186  for (int m = 0; m <= mixin; ++m) {
187  rct::ctkey ctkey;
188  ctkey.dest = rct::pk2rct(boost::get<txout_to_key>(rct_txes[rct_idx/4].vout[rct_idx&3].target).key);
189  ctkey.mask = rct_txes[rct_idx/4].rct_signatures.outPk[rct_idx&3].mask;
190  src.outputs.push_back(std::make_pair(global_rct_idx, ctkey));
191  ++rct_idx;
192  ++global_rct_idx;
193  if (global_rct_idx % 10 == 0)
194  global_rct_idx += 6; // skip the coinbase
195  }
196  }
197  else
198  {
199  // pre rct
200  src.amount = 5000000000000;
201  src.real_out_tx_key = cryptonote::get_tx_pub_key_from_extra(blocks[pre_rct_idx].miner_tx);
202  src.real_output_in_tx_index = 4;
203  src.mask = rct::identity();
204  src.rct = false;
205  for (int m = 0; m <= mixin; ++m) {
206  src.push_output(m, boost::get<txout_to_key>(blocks[pre_rct_idx].miner_tx.vout[4].target).key, src.amount);
207  ++pre_rct_idx;
208  }
209  }
210  }
211 
212  //fill outputs entry
214  td.addr = miner_account.get_keys().m_account_address;
215  td.amount = amount_paid;
216  std::vector<tx_destination_entry> destinations;
217  destinations.push_back(td);
218 
219  if (pre_tx)
220  pre_tx(sources, destinations);
221 
222  transaction tx;
223  crypto::secret_key tx_key;
224  std::vector<crypto::secret_key> additional_tx_keys;
225  std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
226  subaddresses[miner_accounts[0].get_keys().m_account_address.m_spend_public_key] = {0,0};
227  bool r = construct_tx_and_get_tx_key(miner_accounts[0].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_keys, true);
228  CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
229 
230  if (post_tx)
231  post_tx(tx);
232 
233  if (!valid)
234  DO_CALLBACK(events, "mark_invalid_tx");
235  events.push_back(tx);
236  LOG_PRINT_L0("Test tx: " << obj_to_json_str(tx));
237 
238  return true;
239 }
240 
241 bool gen_rct_tx_valid_from_pre_rct::generate(std::vector<test_event_entry>& events) const
242 {
243  const int mixin = 2;
244  const int out_idx[] = {0, -1};
245  const uint64_t amount_paid = 10000;
246  return generate_with(events, out_idx, mixin, amount_paid, true, NULL, NULL);
247 }
248 
249 bool gen_rct_tx_valid_from_rct::generate(std::vector<test_event_entry>& events) const
250 {
251  const int mixin = 2;
252  const int out_idx[] = {1, -1};
253  const uint64_t amount_paid = 10000;
254  return generate_with(events, out_idx, mixin, amount_paid, true, NULL, NULL);
255 }
256 
257 bool gen_rct_tx_valid_from_mixed::generate(std::vector<test_event_entry>& events) const
258 {
259  const int mixin = 2;
260  const int out_idx[] = {1, 0, -1};
261  const uint64_t amount_paid = 10000;
262  return generate_with(events, out_idx, mixin, amount_paid, true, NULL, NULL);
263 }
264 
265 bool gen_rct_tx_pre_rct_bad_real_dest::generate(std::vector<test_event_entry>& events) const
266 {
267  const int mixin = 2;
268  const int out_idx[] = {0, -1};
269  const uint64_t amount_paid = 10000;
270  bool tx_creation_succeeded = false;
271  // in the case, the tx will fail to create, due to mismatched sk/pk
272  bool ret = generate_with(events, out_idx, mixin, amount_paid, false,
273  [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {rct::key sk; rct::skpkGen(sk, sources[0].outputs[0].second.dest);},
274  [&tx_creation_succeeded](const transaction &tx){tx_creation_succeeded=true;});
275  return !ret && !tx_creation_succeeded;
276 }
277 
278 bool gen_rct_tx_pre_rct_bad_real_mask::generate(std::vector<test_event_entry>& events) const
279 {
280  const int mixin = 2;
281  const int out_idx[] = {0, -1};
282  const uint64_t amount_paid = 10000;
283  return generate_with(events, out_idx, mixin, amount_paid, false,
284  [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {sources[0].outputs[0].second.mask = rct::zeroCommit(99999);},
285  NULL);
286 }
287 
288 bool gen_rct_tx_pre_rct_bad_fake_dest::generate(std::vector<test_event_entry>& events) const
289 {
290  const int mixin = 2;
291  const int out_idx[] = {0, -1};
292  const uint64_t amount_paid = 10000;
293  return generate_with(events, out_idx, mixin, amount_paid, false,
294  [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {rct::key sk; rct::skpkGen(sk, sources[0].outputs[1].second.dest);},
295  NULL);
296 }
297 
298 bool gen_rct_tx_pre_rct_bad_fake_mask::generate(std::vector<test_event_entry>& events) const
299 {
300  const int mixin = 2;
301  const int out_idx[] = {0, -1};
302  const uint64_t amount_paid = 10000;
303  return generate_with(events, out_idx, mixin, amount_paid, false,
304  [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {sources[0].outputs[1].second.mask = rct::zeroCommit(99999);},
305  NULL);
306 }
307 
308 bool gen_rct_tx_rct_bad_real_dest::generate(std::vector<test_event_entry>& events) const
309 {
310  const int mixin = 2;
311  const int out_idx[] = {1, -1};
312  const uint64_t amount_paid = 10000;
313  bool tx_creation_succeeded = false;
314  // in the case, the tx will fail to create, due to mismatched sk/pk
315  bool ret = generate_with(events, out_idx, mixin, amount_paid, false,
316  [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {rct::key sk; rct::skpkGen(sk, sources[0].outputs[0].second.dest);},
317  [&tx_creation_succeeded](const transaction &tx){tx_creation_succeeded=true;});
318  return !ret && !tx_creation_succeeded;
319 }
320 
321 bool gen_rct_tx_rct_bad_real_mask::generate(std::vector<test_event_entry>& events) const
322 {
323  const int mixin = 2;
324  const int out_idx[] = {1, -1};
325  const uint64_t amount_paid = 10000;
326  return generate_with(events, out_idx, mixin, amount_paid, false,
327  [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {sources[0].outputs[0].second.mask = rct::zeroCommit(99999);},
328  NULL);
329 }
330 
331 bool gen_rct_tx_rct_bad_fake_dest::generate(std::vector<test_event_entry>& events) const
332 {
333  const int mixin = 2;
334  const int out_idx[] = {1, -1};
335  const uint64_t amount_paid = 10000;
336  return generate_with(events, out_idx, mixin, amount_paid, false,
337  [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {rct::key sk; rct::skpkGen(sk, sources[0].outputs[1].second.dest);},
338  NULL);
339 }
340 
341 bool gen_rct_tx_rct_bad_fake_mask::generate(std::vector<test_event_entry>& events) const
342 {
343  const int mixin = 2;
344  const int out_idx[] = {1, -1};
345  const uint64_t amount_paid = 10000;
346  return generate_with(events, out_idx, mixin, amount_paid, false,
347  [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {sources[0].outputs[1].second.mask = rct::zeroCommit(99999);},
348  NULL);
349 }
350 
351 bool gen_rct_tx_rct_spend_with_zero_commit::generate(std::vector<test_event_entry>& events) const
352 {
353  const int mixin = 2;
354  const int out_idx[] = {1, -1};
355  const uint64_t amount_paid = 10000;
356  return generate_with(events, out_idx, mixin, amount_paid, false,
357  [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {sources[0].outputs[0].second.mask = rct::zeroCommit(sources[0].amount); sources[0].mask = rct::identity();},
358  [](transaction &tx){boost::get<txin_to_key>(tx.vin[0]).amount = 0;});
359 }
360 
361 bool gen_rct_tx_pre_rct_zero_vin_amount::generate(std::vector<test_event_entry>& events) const
362 {
363  const int mixin = 2;
364  const int out_idx[] = {0, -1};
365  const uint64_t amount_paid = 10000;
366  return generate_with(events, out_idx, mixin, amount_paid, false,
367  NULL, [](transaction &tx) {boost::get<txin_to_key>(tx.vin[0]).amount = 0;});
368 }
369 
370 bool gen_rct_tx_rct_non_zero_vin_amount::generate(std::vector<test_event_entry>& events) const
371 {
372  const int mixin = 2;
373  const int out_idx[] = {1, -1};
374  const uint64_t amount_paid = 10000;
375  return generate_with(events, out_idx, mixin, amount_paid, false,
376  NULL, [](transaction &tx) {boost::get<txin_to_key>(tx.vin[0]).amount = 5000000000000;}); // one that we know exists
377 }
378 
379 bool gen_rct_tx_non_zero_vout_amount::generate(std::vector<test_event_entry>& events) const
380 {
381  const int mixin = 2;
382  const int out_idx[] = {1, -1};
383  const uint64_t amount_paid = 10000;
384  return generate_with(events, out_idx, mixin, amount_paid, false,
385  NULL, [](transaction &tx) {tx.vout[0].amount = 5000000000000;}); // one that we know exists
386 }
387 
388 bool gen_rct_tx_pre_rct_duplicate_key_image::generate(std::vector<test_event_entry>& events) const
389 {
390  const int mixin = 2;
391  const int out_idx[] = {0, -1};
392  const uint64_t amount_paid = 10000;
393  return generate_with(events, out_idx, mixin, amount_paid, false,
394  NULL, [&events](transaction &tx) {boost::get<txin_to_key>(tx.vin[0]).k_image = boost::get<txin_to_key>(boost::get<transaction>(events[67]).vin[0]).k_image;});
395 }
396 
397 bool gen_rct_tx_rct_duplicate_key_image::generate(std::vector<test_event_entry>& events) const
398 {
399  const int mixin = 2;
400  const int out_idx[] = {1, -1};
401  const uint64_t amount_paid = 10000;
402  return generate_with(events, out_idx, mixin, amount_paid, false,
403  NULL, [&events](transaction &tx) {boost::get<txin_to_key>(tx.vin[0]).k_image = boost::get<txin_to_key>(boost::get<transaction>(events[67]).vin[0]).k_image;});
404 }
405 
406 bool gen_rct_tx_pre_rct_wrong_key_image::generate(std::vector<test_event_entry>& events) const
407 {
408  const int mixin = 2;
409  const int out_idx[] = {0, -1};
410  const uint64_t amount_paid = 10000;
411  // some random key image from the electroneum blockchain, so we get something that is a valid key image
412  static const uint8_t k_image[33] = "\x49\x3b\x56\x16\x54\x76\xa8\x75\xb7\xf4\xa8\x51\xf5\x55\xd3\x44\xe7\x3e\xea\x73\xee\xc1\x06\x7c\x7d\xb6\x57\x28\x46\x85\xe1\x07";
413  return generate_with(events, out_idx, mixin, amount_paid, false,
414  NULL, [](transaction &tx) {memcpy(&boost::get<txin_to_key>(tx.vin[0]).k_image, k_image, 32);});
415 }
416 
417 bool gen_rct_tx_rct_wrong_key_image::generate(std::vector<test_event_entry>& events) const
418 {
419  const int mixin = 2;
420  const int out_idx[] = {1, -1};
421  const uint64_t amount_paid = 10000;
422  // some random key image from the electroneum blockchain, so we get something that is a valid key image
423  static const uint8_t k_image[33] = "\x49\x3b\x56\x16\x54\x76\xa8\x75\xb7\xf4\xa8\x51\xf5\x55\xd3\x44\xe7\x3e\xea\x73\xee\xc1\x06\x7c\x7d\xb6\x57\x28\x46\x85\xe1\x07";
424  return generate_with(events, out_idx, mixin, amount_paid, false,
425  NULL, [](transaction &tx) {memcpy(&boost::get<txin_to_key>(tx.vin[0]).k_image, k_image, 32);});
426 }
427 
428 bool gen_rct_tx_pre_rct_wrong_fee::generate(std::vector<test_event_entry>& events) const
429 {
430  const int mixin = 2;
431  const int out_idx[] = {0, -1};
432  const uint64_t amount_paid = 10000;
433  return generate_with(events, out_idx, mixin, amount_paid, false,
434  NULL, [](transaction &tx) {tx.rct_signatures.txnFee++;});
435 }
436 
437 bool gen_rct_tx_rct_wrong_fee::generate(std::vector<test_event_entry>& events) const
438 {
439  const int mixin = 2;
440  const int out_idx[] = {1, -1};
441  const uint64_t amount_paid = 10000;
442  return generate_with(events, out_idx, mixin, amount_paid, false,
443  NULL, [](transaction &tx) {tx.rct_signatures.txnFee++;});
444 }
445 
446 bool gen_rct_tx_pre_rct_increase_vin_and_fee::generate(std::vector<test_event_entry>& events) const
447 {
448  const int mixin = 2;
449  const int out_idx[] = {0, -1};
450  const uint64_t amount_paid = 10000;
451  return generate_with(events, out_idx, mixin, amount_paid, false,
452  NULL, [](transaction &tx) {boost::get<txin_to_key>(tx.vin[0]).amount++;tx.rct_signatures.txnFee++;});
453 }
454 
455 bool gen_rct_tx_pre_rct_remove_vin::generate(std::vector<test_event_entry>& events) const
456 {
457  const int mixin = 2;
458  const int out_idx[] = {0, -1};
459  const uint64_t amount_paid = 10000;
460  return generate_with(events, out_idx, mixin, amount_paid, false,
461  NULL, [](transaction &tx) {tx.vin.pop_back();});
462 }
463 
464 bool gen_rct_tx_rct_remove_vin::generate(std::vector<test_event_entry>& events) const
465 {
466  const int mixin = 2;
467  const int out_idx[] = {1, -1};
468  const uint64_t amount_paid = 10000;
469  return generate_with(events, out_idx, mixin, amount_paid, false,
470  NULL, [](transaction &tx) {tx.vin.pop_back();});
471 }
472 
473 bool gen_rct_tx_pre_rct_add_vout::generate(std::vector<test_event_entry>& events) const
474 {
475  const int mixin = 2;
476  const int out_idx[] = {0, -1};
477  const uint64_t amount_paid = 10000;
478  return generate_with(events, out_idx, mixin, amount_paid, false,
479  NULL, [](transaction &tx) {tx.vout.push_back(tx.vout.back());});
480 }
481 
482 bool gen_rct_tx_rct_add_vout::generate(std::vector<test_event_entry>& events) const
483 {
484  const int mixin = 2;
485  const int out_idx[] = {1, -1};
486  const uint64_t amount_paid = 10000;
487  return generate_with(events, out_idx, mixin, amount_paid, false,
488  NULL, [](transaction &tx) {tx.vout.push_back(tx.vout.back());});
489 }
490 
491 bool gen_rct_tx_pre_rct_altered_extra::generate(std::vector<test_event_entry>& events) const
492 {
493  const int mixin = 2;
494  const int out_idx[] = {0, -1};
495  const uint64_t amount_paid = 10000;
496  bool failed = false;
497  return generate_with(events, out_idx, mixin, amount_paid, false,
498  NULL, [&failed](transaction &tx) {std::string extra_nonce; crypto::hash pid = crypto::null_hash; set_payment_id_to_tx_extra_nonce(extra_nonce, pid); if (!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce)) failed = true; }) && !failed;
499 }
500 
501 bool gen_rct_tx_rct_altered_extra::generate(std::vector<test_event_entry>& events) const
502 {
503  const int mixin = 2;
504  const int out_idx[] = {1, -1};
505  const uint64_t amount_paid = 10000;
506  bool failed = false;
507  return generate_with(events, out_idx, mixin, amount_paid, false,
508  NULL, [&failed](transaction &tx) {std::string extra_nonce; crypto::hash pid = crypto::null_hash; set_payment_id_to_tx_extra_nonce(extra_nonce, pid); if (!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce)) failed = true; }) && !failed;
509 }
510 
#define CRYPTONOTE_MINED_ETN_UNLOCK_WINDOW
void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res)
Definition: crypto.h:279
etn_amount txnFee
Definition: rctTypes.h:248
crypto::public_key real_out_tx_key
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:417
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:428
::std::string string
Definition: gtest-port.h:1097
POD_CLASS key_derivation
Definition: crypto.h:98
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:321
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:308
#define CHECK_AND_ASSERT_MES(expr, fail_ret_val, message)
Definition: misc_log_ex.h:181
const char * key
Definition: hmac_keccak.cpp:39
#define LOG_PRINT_L0(x)
Definition: misc_log_ex.h:99
crypto namespace.
Definition: crypto.cpp:58
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:379
bool rct
unsigned char uint8_t
Definition: stdint.h:124
crypto::secret_key generate(const crypto::secret_key &recovery_key=crypto::secret_key(), bool recover=false, bool two_random=false)
Definition: account.cpp:158
uint64_t amount
key dest
Definition: rctTypes.h:97
uint8_t type
Definition: rctTypes.h:241
etn_amount decodeRct(const rctSig &rv, const key &sk, unsigned int i, key &mask, hw::device &hwdev)
Definition: rctSigs.cpp:1150
bool generate_key_derivation(const public_key &key1, const secret_key &key2, key_derivation &derivation)
Definition: crypto.h:272
size_t real_output
std::vector< uint8_t > extra
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:278
const account_keys & get_keys() const
Definition: account.cpp:264
Holds cryptonote related classes and helpers.
Definition: ban.cpp:40
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:298
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:241
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:265
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:388
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:331
device & get_device(const std::string &device_descriptor)
Definition: device.cpp:95
#define MAKE_GENESIS_BLOCK(VEC_EVENTS, BLK_NAME, MINER_ACC, TS)
Definition: chaingen.h:833
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:361
std::string obj_to_json_str(T &obj)
unsigned __int64 uint64_t
Definition: stdint.h:136
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:341
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:351
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:288
bool generate_with(std::vector< test_event_entry > &events, const int *out_idx, int mixin, uint64_t amount_paid, bool valid, const std::function< void(std::vector< cryptonote::tx_source_entry > &sources, std::vector< cryptonote::tx_destination_entry > &destinations)> &pre_tx, const std::function< void(cryptonote::transaction &tx)> &post_tx) const
Definition: rct.cpp:44
crypto::public_key get_tx_pub_key_from_extra(const std::vector< uint8_t > &tx_extra, size_t pk_index)
uint64_t amount
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:473
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:501
void push_output(uint64_t idx, const crypto::public_key &k, uint64_t amount)
account_public_address addr
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:464
account_public_address m_account_address
Definition: account.h:43
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:482
key identity()
Definition: rctOps.h:73
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:446
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:437
void * memcpy(void *a, const void *b, size_t c)
size_t real_output_in_tx_index
ctkeyV outPk
Definition: rctTypes.h:247
crypto::hash get_transaction_hash(const transaction &t)
void skpkGen(key &sk, key &pk)
Definition: rctOps.cpp:284
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:249
bool add_extra_nonce_to_tx_extra(std::vector< uint8_t > &tx_extra, const blobdata &extra_nonce)
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:370
key mask
Definition: rctTypes.h:98
std::vector< output_entry > outputs
key zeroCommit(etn_amount amount)
Definition: rctOps.cpp:322
POD_CLASS hash
Definition: hash.h:50
#define DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:257
void set_payment_id_to_tx_extra_nonce(blobdata &extra_nonce, const crypto::hash &payment_id)
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:455
#define GENERATE_ACCOUNT(account)
Definition: chaingen.h:801
bool construct_tx_and_get_tx_key(const account_keys &sender_account_keys, const std::unordered_map< crypto::public_key, subaddress_index > &subaddresses, std::vector< tx_source_entry > &sources, 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, crypto::secret_key &tx_key, std::vector< crypto::secret_key > &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, rct::multisig_out *msout, const uint32_t account_major_offset, const cryptonote::network_type nettype)
#define DO_CALLBACK(VEC_EVENTS, CB_NAME)
Definition: chaingen.h:820
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:406
etn_amount decodeRctSimple(const rctSig &rv, const key &sk, unsigned int i, key &mask, hw::device &hwdev)
Definition: rctSigs.cpp:1180
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:397
bool generate(std::vector< test_event_entry > &events) const
Definition: rct.cpp:491
rct::key mask