aboutsummaryrefslogtreecommitdiff
path: root/tests/core_tests/rct.cpp
diff options
context:
space:
mode:
authorRiccardo Spagni <ric@spagni.net>2016-08-28 22:41:11 +0200
committerRiccardo Spagni <ric@spagni.net>2016-08-28 22:41:12 +0200
commit8a5b766d17761f5fbdd3e30e638daa98a40a4c8a (patch)
treeea05e3f0fd47fd1d8728e64d081292d337825cb9 /tests/core_tests/rct.cpp
parenta569b264bc4d4ca1a07c2eadcc24b5ab75fd0c84 (diff)
parent887db9f93670da8c1eb28c9d53d6d4f055486e3b (diff)
downloadmonzero-core-8a5b766d17761f5fbdd3e30e638daa98a40a4c8a.tar.gz
monzero-core-8a5b766d17761f5fbdd3e30e638daa98a40a4c8a.tar.xz
monzero-core-8a5b766d17761f5fbdd3e30e638daa98a40a4c8a.zip
Merge pull request #961
887db9f blockchain: testnet heights for v3, v4, and v5 (moneromooo-monero) f24ab58 ringct: remove unused code (moneromooo-monero) b38452b ringct: pass structure by const ref, not value (moneromooo-monero) fd11271 ringct: use memcpy/memset instead of handwritten loop where appropriate (moneromooo-monero) 5d38206 ringct: remove spurious copies (moneromooo-monero) 16732a8 rct: faster Cryptonote/rct conversions (moneromooo-monero) fbd7c35 wallet: fix some "may be used uninitialized" warnings (moneromooo-monero) 4a41dd4 wallet: do not generate 0 change (moneromooo-monero) a0925e6 core: use full rct signatures if just one input (moneromooo-monero) 94fd881 rct: early out on failure on verRange (moneromooo-monero) 45349b6 wallet: do not ask for duplicate histograms (moneromooo-monero) b951bc8 wallet: transfer_selected_rct now also selects fake outs (moneromooo-monero) 4f887de increase minimum mixin to 4 on hard fork 5 (moneromooo-monero) 0815c72 core: allow v1 txes after HF 5 when sweeping unmixable outputs (moneromooo-monero) f782d45 tests: hard fork list must end with a 0 (moneromooo-monero) 074e602 ringct: use Cryptonote serialization to hash non prunable data (moneromooo-monero) c3b3260 New "Halfway RingCT" outputs for coinbase transactions (moneromooo-monero) 6f526cd rct: log why verification fails (moneromooo-monero) d4b8991 rct: serialize txnFee as varint (moneromooo-monero) d4b62a1 rct amount key modified as per luigi1111's recommendations (moneromooo-monero) 93f5c62 rct: rework v2 txes into prunable and non prunable data (moneromooo-monero) d93746b rct: rework the verification preparation process (moneromooo-monero) 3ab2ab3 rct: change the simple flag to a type (moneromooo-monero) c5be4b0 rct: avoid the need for the last II element (Shen Noether) a47ceee wallet: do not store signatures in the wallet cache (moneromooo-monero) 0263dd2 core: add some locking around pool use (moneromooo-monero) 2c9d951 wallet2: factor m_spent changes (moneromooo-monero) 1303cda wallet: always use new algorithm for RPC transfers (moneromooo-monero) b337aea rct: do not serialize senderPk - it is not used anymore (moneromooo-monero) e5a9a47 core_tests: fix a couple pre-rct tests using rct (moneromooo-monero) 230fca2 wallet: use the prefered rct case only when enough rct outs exist (moneromooo-monero) c27194a wallet: do not try to use rct txes a few blocks before the fork (moneromooo-monero) 1bf0698 tx_pool: log why a transaction was rejected for version checks (moneromooo-monero) 37bdf6e change fork settings to allow pre-rct txes for one more fork cycle (moneromooo-monero) cc85cc6 simplewallet: better check_tx_key feedback (moneromooo-monero) 9b70856 rct: make the amount key derivable by a third party with the tx key (moneromooo-monero) cf33e1a rct: do not serialize public keys in outPk (moneromooo-monero) 83ab315 wallet2_api: zero amounts are now allowed with rct (moneromooo-monero) 096ac06 wallet2_api: update on_money_{received,spent} prototypes for rct changes (moneromooo-monero) 3cb2ede rpc: send global indices along with blocks/transacions on refresh (moneromooo-monero) 414b424 core: always use the new simple rct variant (moneromooo-monero) ce5de8b tests: add tests for wallet output selection (moneromooo-monero) 84c82cd wallet: better tx input selection (moneromooo-monero) 1e21651 rct: use the already defined H where possible (moneromooo-monero) 07d353d wallet: handle 0 change properly (moneromooo-monero) e81a2b2 port get_tx_key/check_tx_key to rct (moneromooo-monero) e06faef tests: add basic tests for simple rct api (moneromooo-monero) a4d4d61 integrate simple rct api (moneromooo-monero) 1e8d37e serialization: add override for serializing bool (moneromooo-monero) dbb5f2d ringct: optimization/cleanup of hash functions (Shen Noether) 4fd01f2 ringct: "simple" ringct variant (Shen Noether) 37c895e wallet: rct specific output selection (moneromooo-monero) 1181c57 wallet: make sweep_all work with rct txes too (moneromooo-monero) c2ec6d3 mixable transactions must be rct for v3 (moneromooo-monero) 1017a75 wallet: factor transfer_rct code with transfer code (moneromooo-monero) f5465d8 Condition v2 txes on v3 hard fork (moneromooo-monero) 59a66e2 move the rct commitments to the output_amounts database (moneromooo-monero) 6d0e471 rct: add the tx prefix hash into the MLSAG (moneromooo-monero) 35dce5c ringct: fix size unit mismatch calling keccak (moneromooo-monero) 20e50ec ringct: do not serialize what can be reconstructed (moneromooo-monero) 106e3dc Add rct core tests (moneromooo-monero) ada5275 Use the supplied hard fork version in validate_miner_transaction (moneromooo-monero) acbe06d wallet: update spent status when an accepted tx disappears (moneromooo-monero) 089df4a wallet: reset output spent status on blockchain reorg (moneromooo-monero) 73d59f1 ringct: catch errors from ge_frombytes_vartime (moneromooo-monero) 161551e tests: test for ringct rctSig data sizes (moneromooo-monero) 359f469 ringct: add missing size check for ecdhInfo (moneromooo-monero) 229968e ringct: change asserts to return false for boolean functions (moneromooo-monero) dc4aad7 add rct to the protocol (moneromooo-monero) 211d1db db_lmdb: update reset for recent db changes (moneromooo-monero) dee42d6 ringct: add functions to commit to an amount (moneromooo-monero) cc7f449 make rct tx serialization work (moneromooo-monero) e70e8a6 crypto: error out where appropriate (moneromooo-monero) 54f7429 ringct: allow no outputs, and add tests for this and fees (moneromooo-monero) e99904a ringct: make fee optional (moneromooo-monero) f8c04ad ringct: txn fee stuff (Shen Noether) 66f9626 ringct: new {gen,decode}Rct APIs for convenience (moneromooo-monero) 789b2e2 ringct: add more convenience functions (moneromooo-monero) 9856443 core: link against libringct (moneromooo-monero) 4258dab core: new /getrandom_rctouts.bin binary RPC call (moneromooo-monero) c3a2e14 ringct: add convenience functions to bridge ringct and cryptonote (moneromooo-monero) eb56d0f blockchain_db: add functions for adding/removing/getting rct commitments (moneromooo-monero) 82072e7 ringct: restore verRange check in debug mode (moneromooo-monero) 63856ca ringct: add check for destinations/amount size being equal (moneromooo-monero) e816a09 ringct: fix off by 1 in mixin usage (moneromooo-monero) 09c5ea4 ringct: simplify random key generation (moneromooo-monero) 53cdf4d tests: new ringct test for checking H2 values (Shen Noether) 56f6549 ringct: cosmetic fixes (Shen Noether) 55ff136 ringct: changes to hashToPointSimple to calcualte H2 values (Shen Noether) 63733b1 ringct: compare keys with bitwise equality, not crypto ops (Shen Noether) 98f4c6f ringct: fix size argument to cn_fast_hash (Shen Noether) 720ac85 tests: zero inputs/outputs are in fact supposed to be accepted (moneromooo-monero) 84948ea ringct: add a test for prooveRange being non deterministic (moneromooo-monero) 09fb9f4 Fix sc_0 to skGen in ProveRange (Shen Noether) d37c1db ringct: add a few consts where appropriate (moneromooo-monero) 700248f tests: more ringct range proof tests (moneromooo-monero) d02f999 rct: add serialization machinery to rct types (moneromooo-monero) 0ff8305 serialization: declare do_serialize specializations before use (moneromooo-monero) 8b135e7 Added note on generating H2 (Shen Noether) 4d639d9 Fixed missing last index H2 (Shen Noether) 9e82b69 remove original Cryptonote blockchain_storage blockchain format (moneromooo-monero) 86b4426 ringct: lock access to the PRNG (moneromooo-monero) 4d7f073 ringct: add simple input validation (moneromooo-monero) 57779ab tests: add some more ringct building block tests (moneromooo-monero) b656001 ringct: add convenience operators to key (moneromooo-monero) 2d6303f tests: add Shen Noether's basic ringct tests (moneromooo-monero) 9b1afe5 ringct: import of Shen Noether's ring confidential transactions (moneromooo-monero)
Diffstat (limited to 'tests/core_tests/rct.cpp')
-rw-r--r--tests/core_tests/rct.cpp499
1 files changed, 499 insertions, 0 deletions
diff --git a/tests/core_tests/rct.cpp b/tests/core_tests/rct.cpp
new file mode 100644
index 000000000..c29854888
--- /dev/null
+++ b/tests/core_tests/rct.cpp
@@ -0,0 +1,499 @@
+// Copyright (c) 2014-2016, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#include "ringct/rctSigs.h"
+#include "chaingen.h"
+#include "chaingen_tests_list.h"
+
+using namespace epee;
+using namespace crypto;
+using namespace cryptonote;
+
+//----------------------------------------------------------------------------------------------------------------------
+// Tests
+
+bool gen_rct_tx_validation_base::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<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations)> &pre_tx,
+ const std::function<void(transaction &tx)> &post_tx) const
+{
+ uint64_t ts_start = 1338224400;
+
+ GENERATE_ACCOUNT(miner_account);
+ MAKE_GENESIS_BLOCK(events, blk_0, miner_account, ts_start);
+
+ // create 4 miner accounts, and have them mine the next 4 blocks
+ cryptonote::account_base miner_accounts[4];
+ const cryptonote::block *prev_block = &blk_0;
+ cryptonote::block blocks[4];
+ for (size_t n = 0; n < 4; ++n) {
+ miner_accounts[n].generate();
+ CHECK_AND_ASSERT_MES(generator.construct_block_manually(blocks[n], *prev_block, miner_accounts[n],
+ test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_hf_version,
+ 2, 2, prev_block->timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
+ crypto::hash(), 0, transaction(), std::vector<crypto::hash>(), 0, 0, 2),
+ false, "Failed to generate block");
+ events.push_back(blocks[n]);
+ prev_block = blocks + n;
+ LOG_PRINT_L0("Initial miner tx " << n << ": " << obj_to_json_str(blocks[n].miner_tx));
+ }
+
+ // rewind
+ cryptonote::block blk_r, blk_last;
+ {
+ blk_last = blocks[3];
+ for (size_t i = 0; i < CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW; ++i)
+ {
+ cryptonote::block blk;
+ CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk, blk_last, miner_account,
+ test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_hf_version,
+ 2, 2, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
+ crypto::hash(), 0, transaction(), std::vector<crypto::hash>(), 0, 0, 2),
+ false, "Failed to generate block");
+ events.push_back(blk);
+ blk_last = blk;
+ }
+ blk_r = blk_last;
+ }
+
+ // create 4 txes from these miners in another block, to generate some rct outputs
+ transaction rct_txes[4];
+ rct::key rct_tx_masks[16];
+ cryptonote::block blk_txes[4];
+ for (size_t n = 0; n < 4; ++n)
+ {
+ std::vector<crypto::hash> starting_rct_tx_hashes;
+ std::vector<tx_source_entry> sources;
+
+ sources.resize(1);
+ tx_source_entry& src = sources.back();
+
+ const size_t index_in_tx = 5;
+ src.amount = 30000000000000;
+ for (int m = 0; m < 4; ++m) {
+ src.push_output(m, boost::get<txout_to_key>(blocks[m].miner_tx.vout[index_in_tx].target).key, src.amount);
+ }
+ src.real_out_tx_key = cryptonote::get_tx_pub_key_from_extra(blocks[n].miner_tx);
+ src.real_output = n;
+ src.real_output_in_tx_index = index_in_tx;
+ src.mask = rct::identity();
+ src.rct = false;
+
+ //fill outputs entry
+ tx_destination_entry td;
+ td.addr = miner_accounts[n].get_keys().m_account_address;
+ td.amount = 7390000000000;
+ std::vector<tx_destination_entry> destinations;
+ destinations.push_back(td);
+ destinations.push_back(td);
+ destinations.push_back(td);
+ destinations.push_back(td); // 30 -> 7.39 * 4
+
+ crypto::secret_key tx_key;
+ bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), sources, destinations, std::vector<uint8_t>(), rct_txes[n], 0, tx_key, true);
+ CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
+ events.push_back(rct_txes[n]);
+ starting_rct_tx_hashes.push_back(get_transaction_hash(rct_txes[n]));
+
+ for (size_t o = 0; o < 4; ++o)
+ {
+ crypto::key_derivation derivation;
+ bool r = crypto::generate_key_derivation(destinations[o].addr.m_view_public_key, tx_key, derivation);
+ CHECK_AND_ASSERT_MES(r, false, "Failed to generate key derivation");
+ crypto::secret_key amount_key;
+ crypto::derivation_to_scalar(derivation, o, amount_key);
+ if (rct_txes[n].rct_signatures.type == rct::RCTTypeSimple)
+ rct::decodeRctSimple(rct_txes[n].rct_signatures, rct::sk2rct(amount_key), o, rct_tx_masks[o+n*4]);
+ else
+ rct::decodeRct(rct_txes[n].rct_signatures, rct::sk2rct(amount_key), o, rct_tx_masks[o+n*4]);
+ }
+
+ CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk_txes[n], blk_last, miner_account,
+ test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_tx_hashes | test_generator::bf_hf_version | test_generator::bf_max_outs,
+ 4, 4, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
+ crypto::hash(), 0, transaction(), starting_rct_tx_hashes, 0, 6, 4),
+ false, "Failed to generate block");
+ events.push_back(blk_txes[n]);
+ blk_last = blk_txes[n];
+ }
+
+ // rewind
+ {
+ for (size_t i = 0; i < CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW; ++i)
+ {
+ cryptonote::block blk;
+ CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk, blk_last, miner_account,
+ test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_hf_version | test_generator::bf_max_outs,
+ 4, 4, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
+ crypto::hash(), 0, transaction(), std::vector<crypto::hash>(), 0, 6, 4),
+ false, "Failed to generate block");
+ events.push_back(blk);
+ blk_last = blk;
+ }
+ blk_r = blk_last;
+ }
+
+ // create a tx from the requested ouputs
+ std::vector<tx_source_entry> sources;
+ size_t global_rct_idx = 6; // skip first coinbase (6 outputs)
+ size_t rct_idx = 0;
+ size_t pre_rct_idx = 0;
+ for (size_t out_idx_idx = 0; out_idx[out_idx_idx] >= 0; ++out_idx_idx) {
+ sources.resize(sources.size()+1);
+ tx_source_entry& src = sources.back();
+
+ src.real_output = 0;
+ if (out_idx[out_idx_idx]) {
+ // rct
+ src.amount = 7390000000000;
+ src.real_out_tx_key = get_tx_pub_key_from_extra(rct_txes[rct_idx/4]);
+ src.real_output_in_tx_index = rct_idx&3;
+ src.mask = rct_tx_masks[rct_idx];
+ src.rct = true;
+ for (int m = 0; m <= mixin; ++m) {
+ rct::ctkey ctkey;
+ ctkey.dest = rct::pk2rct(boost::get<txout_to_key>(rct_txes[rct_idx/4].vout[rct_idx&3].target).key);
+ ctkey.mask = rct_txes[rct_idx/4].rct_signatures.outPk[rct_idx&3].mask;
+ src.outputs.push_back(std::make_pair(global_rct_idx, ctkey));
+ ++rct_idx;
+ ++global_rct_idx;
+ if (global_rct_idx % 10 == 0)
+ global_rct_idx += 6; // skip the coinbase
+ }
+ }
+ else
+ {
+ // pre rct
+ src.amount = 5000000000000;
+ src.real_out_tx_key = cryptonote::get_tx_pub_key_from_extra(blocks[pre_rct_idx].miner_tx);
+ src.real_output_in_tx_index = 4;
+ src.mask = rct::identity();
+ src.rct = false;
+ for (int m = 0; m <= mixin; ++m) {
+ src.push_output(m, boost::get<txout_to_key>(blocks[pre_rct_idx].miner_tx.vout[4].target).key, src.amount);
+ ++pre_rct_idx;
+ }
+ }
+ }
+
+ //fill outputs entry
+ tx_destination_entry td;
+ td.addr = miner_account.get_keys().m_account_address;
+ td.amount = amount_paid;
+ std::vector<tx_destination_entry> destinations;
+ destinations.push_back(td);
+
+ if (pre_tx)
+ pre_tx(sources, destinations);
+
+ transaction tx;
+ crypto::secret_key tx_key;
+ bool r = construct_tx_and_get_tx_key(miner_accounts[0].get_keys(), sources, destinations, std::vector<uint8_t>(), tx, 0, tx_key, true);
+ CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
+
+ if (post_tx)
+ post_tx(tx);
+
+ if (!valid)
+ DO_CALLBACK(events, "mark_invalid_tx");
+ events.push_back(tx);
+ LOG_PRINT_L0("Test tx: " << obj_to_json_str(tx));
+
+ return true;
+}
+
+bool gen_rct_tx_valid_from_pre_rct::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, true, NULL, NULL);
+}
+
+bool gen_rct_tx_valid_from_rct::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, true, NULL, NULL);
+}
+
+bool gen_rct_tx_valid_from_mixed::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, 0, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, true, NULL, NULL);
+}
+
+bool gen_rct_tx_pre_rct_bad_real_dest::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ bool tx_creation_succeeded = false;
+ // in the case, the tx will fail to create, due to mismatched sk/pk
+ bool ret = generate_with(events, out_idx, mixin, amount_paid, false,
+ [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {rct::key sk; rct::skpkGen(sk, sources[0].outputs[0].second.dest);},
+ [&tx_creation_succeeded](const transaction &tx){tx_creation_succeeded=true;});
+ return !ret && !tx_creation_succeeded;
+}
+
+bool gen_rct_tx_pre_rct_bad_real_mask::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {sources[0].outputs[0].second.mask = rct::zeroCommit(99999);},
+ NULL);
+}
+
+bool gen_rct_tx_pre_rct_bad_fake_dest::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {rct::key sk; rct::skpkGen(sk, sources[0].outputs[1].second.dest);},
+ NULL);
+}
+
+bool gen_rct_tx_pre_rct_bad_fake_mask::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {sources[0].outputs[1].second.mask = rct::zeroCommit(99999);},
+ NULL);
+}
+
+bool gen_rct_tx_rct_bad_real_dest::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ bool tx_creation_succeeded = false;
+ // in the case, the tx will fail to create, due to mismatched sk/pk
+ bool ret = generate_with(events, out_idx, mixin, amount_paid, false,
+ [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {rct::key sk; rct::skpkGen(sk, sources[0].outputs[0].second.dest);},
+ [&tx_creation_succeeded](const transaction &tx){tx_creation_succeeded=true;});
+ return !ret && !tx_creation_succeeded;
+}
+
+bool gen_rct_tx_rct_bad_real_mask::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {sources[0].outputs[0].second.mask = rct::zeroCommit(99999);},
+ NULL);
+}
+
+bool gen_rct_tx_rct_bad_fake_dest::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {rct::key sk; rct::skpkGen(sk, sources[0].outputs[1].second.dest);},
+ NULL);
+}
+
+bool gen_rct_tx_rct_bad_fake_mask::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ [](std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations) {sources[0].outputs[1].second.mask = rct::zeroCommit(99999);},
+ NULL);
+}
+
+bool gen_rct_tx_rct_spend_with_zero_commit::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ [](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();},
+ [](transaction &tx){boost::get<txin_to_key>(tx.vin[0]).amount = 0;});
+}
+
+bool gen_rct_tx_pre_rct_zero_vin_amount::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ NULL, [](transaction &tx) {boost::get<txin_to_key>(tx.vin[0]).amount = 0;});
+}
+
+bool gen_rct_tx_rct_non_zero_vin_amount::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ NULL, [](transaction &tx) {boost::get<txin_to_key>(tx.vin[0]).amount = 5000000000000;}); // one that we know exists
+}
+
+bool gen_rct_tx_non_zero_vout_amount::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ NULL, [](transaction &tx) {tx.vout[0].amount = 5000000000000;}); // one that we know exists
+}
+
+bool gen_rct_tx_pre_rct_duplicate_key_image::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ 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;});
+}
+
+bool gen_rct_tx_rct_duplicate_key_image::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ 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;});
+}
+
+bool gen_rct_tx_pre_rct_wrong_key_image::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ // some random key image from the monero blockchain, so we get something that is a valid key image
+ 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";
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ NULL, [](transaction &tx) {memcpy(&boost::get<txin_to_key>(tx.vin[0]).k_image, k_image, 32);});
+}
+
+bool gen_rct_tx_rct_wrong_key_image::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ // some random key image from the monero blockchain, so we get something that is a valid key image
+ 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";
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ NULL, [](transaction &tx) {memcpy(&boost::get<txin_to_key>(tx.vin[0]).k_image, k_image, 32);});
+}
+
+bool gen_rct_tx_pre_rct_wrong_fee::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ NULL, [](transaction &tx) {tx.rct_signatures.txnFee++;});
+}
+
+bool gen_rct_tx_rct_wrong_fee::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ NULL, [](transaction &tx) {tx.rct_signatures.txnFee++;});
+}
+
+bool gen_rct_tx_pre_rct_increase_vin_and_fee::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ NULL, [](transaction &tx) {boost::get<txin_to_key>(tx.vin[0]).amount++;tx.rct_signatures.txnFee++;});
+}
+
+bool gen_rct_tx_pre_rct_remove_vin::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ NULL, [](transaction &tx) {tx.vin.pop_back();});
+}
+
+bool gen_rct_tx_rct_remove_vin::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ NULL, [](transaction &tx) {tx.vin.pop_back();});
+}
+
+bool gen_rct_tx_pre_rct_add_vout::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ NULL, [](transaction &tx) {tx.vout.push_back(tx.vout.back());});
+}
+
+bool gen_rct_tx_rct_add_vout::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ NULL, [](transaction &tx) {tx.vout.push_back(tx.vout.back());});
+}
+
+bool gen_rct_tx_pre_rct_altered_extra::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {0, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ NULL, [](transaction &tx) {std::string extra_nonce; crypto::hash pid = cryptonote::null_hash; set_payment_id_to_tx_extra_nonce(extra_nonce, pid); add_extra_nonce_to_tx_extra(tx.extra, extra_nonce);});
+}
+
+bool gen_rct_tx_rct_altered_extra::generate(std::vector<test_event_entry>& events) const
+{
+ const int mixin = 2;
+ const int out_idx[] = {1, -1};
+ const uint64_t amount_paid = 10000;
+ return generate_with(events, out_idx, mixin, amount_paid, false,
+ NULL, [](transaction &tx) {std::string extra_nonce; crypto::hash pid = cryptonote::null_hash; set_payment_id_to_tx_extra_nonce(extra_nonce, pid); add_extra_nonce_to_tx_extra(tx.extra, extra_nonce);});
+}
+