aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDusan Klinec <dusan.klinec@gmail.com>2023-09-29 19:11:20 +0200
committerDusan Klinec <dusan.klinec@gmail.com>2023-09-29 19:11:20 +0200
commit056c9967036175e78b7ac1758d9a2943a9283bfc (patch)
tree97f729ef3ab44dc917f9a4975691ab3748503f64
parentMerge pull request #8976 (diff)
downloadmonero-056c9967036175e78b7ac1758d9a2943a9283bfc.tar.xz
fix chaingen tests
- fix tx create from sources, input locking. Originally, creating a synthetic transactions with chaingen could create a transaction with outputs that are still locked in the current block, thus failing chain validation by the daemon. Simple unlock check was added. Some buggy tests were fixed as well as new unlock-checking version of tx creation rejected those, fixes are simple - mostly using correct block after a rewind to construct a transaction
-rw-r--r--tests/core_tests/block_reward.cpp10
-rw-r--r--tests/core_tests/block_validation.cpp2
-rw-r--r--tests/core_tests/chain_split_1.cpp6
-rw-r--r--tests/core_tests/chain_switch_1.cpp24
-rw-r--r--tests/core_tests/chaingen.cpp59
-rw-r--r--tests/core_tests/chaingen.h44
-rw-r--r--tests/core_tests/chaingen001.cpp12
-rw-r--r--tests/core_tests/double_spend.h2
-rw-r--r--tests/core_tests/double_spend.inl14
-rw-r--r--tests/core_tests/integer_overflow.cpp4
-rw-r--r--tests/core_tests/ring_signature_1.cpp36
-rw-r--r--tests/core_tests/tx_pool.cpp14
-rw-r--r--tests/core_tests/tx_validation.cpp42
-rw-r--r--tests/core_tests/wallet_tools.cpp51
-rw-r--r--tests/core_tests/wallet_tools.h6
15 files changed, 191 insertions, 135 deletions
diff --git a/tests/core_tests/block_reward.cpp b/tests/core_tests/block_reward.cpp
index bd2fc2a9b..7f75aea5b 100644
--- a/tests/core_tests/block_reward.cpp
+++ b/tests/core_tests/block_reward.cpp
@@ -172,21 +172,21 @@ bool gen_block_reward::generate(std::vector<test_event_entry>& events) const
return false;
// Test: fee increases block reward
- transaction tx_0(construct_tx_with_fee(events, blk_5, miner_account, bob_account, MK_COINS(1), 3 * TESTS_DEFAULT_FEE));
+ transaction tx_0(construct_tx_with_fee(events, blk_5r, miner_account, bob_account, MK_COINS(1), 3 * TESTS_DEFAULT_FEE));
MAKE_NEXT_BLOCK_TX1(events, blk_6, blk_5r, miner_account, tx_0);
DO_CALLBACK(events, "mark_checked_block");
// Test: fee from all block transactions increase block reward
std::list<transaction> txs_0;
- txs_0.push_back(construct_tx_with_fee(events, blk_5, miner_account, bob_account, MK_COINS(1), 5 * TESTS_DEFAULT_FEE));
- txs_0.push_back(construct_tx_with_fee(events, blk_5, miner_account, bob_account, MK_COINS(1), 7 * TESTS_DEFAULT_FEE));
+ txs_0.push_back(construct_tx_with_fee(events, blk_5r, miner_account, bob_account, MK_COINS(1), 5 * TESTS_DEFAULT_FEE));
+ txs_0.push_back(construct_tx_with_fee(events, blk_5r, miner_account, bob_account, MK_COINS(1), 7 * TESTS_DEFAULT_FEE));
MAKE_NEXT_BLOCK_TX_LIST(events, blk_7, blk_6, miner_account, txs_0);
DO_CALLBACK(events, "mark_checked_block");
// Test: block reward == transactions fee
{
- transaction tx_1 = construct_tx_with_fee(events, blk_5, miner_account, bob_account, MK_COINS(1), 11 * TESTS_DEFAULT_FEE);
- transaction tx_2 = construct_tx_with_fee(events, blk_5, miner_account, bob_account, MK_COINS(1), 13 * TESTS_DEFAULT_FEE);
+ transaction tx_1 = construct_tx_with_fee(events, blk_5r, miner_account, bob_account, MK_COINS(1), 11 * TESTS_DEFAULT_FEE);
+ transaction tx_2 = construct_tx_with_fee(events, blk_5r, miner_account, bob_account, MK_COINS(1), 13 * TESTS_DEFAULT_FEE);
size_t txs_1_weight = get_transaction_weight(tx_1) + get_transaction_weight(tx_2);
uint64_t txs_fee = get_tx_fee(tx_1) + get_tx_fee(tx_2);
diff --git a/tests/core_tests/block_validation.cpp b/tests/core_tests/block_validation.cpp
index 37f19d94b..071d2198e 100644
--- a/tests/core_tests/block_validation.cpp
+++ b/tests/core_tests/block_validation.cpp
@@ -580,7 +580,7 @@ bool gen_block_invalid_binary_format::generate(std::vector<test_event_entry>& ev
while (diffic < 1500);
blk_last = boost::get<block>(events.back());
- MAKE_TX(events, tx_0, miner_account, miner_account, MK_COINS(30), boost::get<block>(events[1]));
+ MAKE_TX(events, tx_0, miner_account, miner_account, MK_COINS(30), blk_last);
DO_CALLBACK(events, "corrupt_blocks_boundary");
block blk_test;
diff --git a/tests/core_tests/chain_split_1.cpp b/tests/core_tests/chain_split_1.cpp
index 8f49b1af8..cffabb9c1 100644
--- a/tests/core_tests/chain_split_1.cpp
+++ b/tests/core_tests/chain_split_1.cpp
@@ -114,9 +114,9 @@ bool gen_simple_chain_split_1::generate(std::vector<test_event_entry> &events) c
REWIND_BLOCKS(events, blk_23r, blk_23, first_miner_account); // 30...N1
GENERATE_ACCOUNT(alice);
- MAKE_TX(events, tx_0, first_miner_account, alice, MK_COINS(10), blk_23); // N1+1
- MAKE_TX(events, tx_1, first_miner_account, alice, MK_COINS(20), blk_23); // N1+2
- MAKE_TX(events, tx_2, first_miner_account, alice, MK_COINS(30), blk_23); // N1+3
+ MAKE_TX(events, tx_0, first_miner_account, alice, MK_COINS(10), blk_23r); // N1+1
+ MAKE_TX(events, tx_1, first_miner_account, alice, MK_COINS(20), blk_23r); // N1+2
+ MAKE_TX(events, tx_2, first_miner_account, alice, MK_COINS(30), blk_23r); // N1+3
DO_CALLBACK(events, "check_mempool_1"); // N1+4
MAKE_NEXT_BLOCK_TX1(events, blk_24, blk_23r, first_miner_account, tx_0); // N1+5
DO_CALLBACK(events, "check_mempool_2"); // N1+6
diff --git a/tests/core_tests/chain_switch_1.cpp b/tests/core_tests/chain_switch_1.cpp
index 8271ab783..2d9cdcbd8 100644
--- a/tests/core_tests/chain_switch_1.cpp
+++ b/tests/core_tests/chain_switch_1.cpp
@@ -72,37 +72,37 @@ bool gen_chain_switch_1::generate(std::vector<test_event_entry>& events) const
MAKE_ACCOUNT(events, recipient_account_3); // 3
MAKE_ACCOUNT(events, recipient_account_4); // 4
REWIND_BLOCKS(events, blk_0r, blk_0, miner_account) // <N blocks>
- MAKE_TX(events, tx_00, miner_account, recipient_account_1, MK_COINS(5), blk_0); // 5 + N
+ MAKE_TX(events, tx_00, miner_account, recipient_account_1, MK_COINS(5), blk_0r); // 5 + N
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_account, tx_00); // 6 + N
MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner_account); // 7 + N
REWIND_BLOCKS(events, blk_2r, blk_2, miner_account) // <N blocks>
// Transactions to test account balances after switch
- MAKE_TX_LIST_START(events, txs_blk_3, miner_account, recipient_account_2, MK_COINS(7), blk_2); // 8 + 2N
- MAKE_TX_LIST_START(events, txs_blk_4, miner_account, recipient_account_3, MK_COINS(11), blk_2); // 9 + 2N
- MAKE_TX_LIST_START(events, txs_blk_5, miner_account, recipient_account_4, MK_COINS(13), blk_2); // 10 + 2N
+ MAKE_TX_LIST_START(events, txs_blk_3, miner_account, recipient_account_2, MK_COINS(7), blk_2r); // 8 + 2N
+ MAKE_TX_LIST_START(events, txs_blk_4, miner_account, recipient_account_3, MK_COINS(11), blk_2r); // 9 + 2N
+ MAKE_TX_LIST_START(events, txs_blk_5, miner_account, recipient_account_4, MK_COINS(13), blk_2r); // 10 + 2N
std::list<transaction> txs_blk_6;
txs_blk_6.push_back(txs_blk_4.front());
// Transactions, that has different order in alt block chains
- MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_1, MK_COINS(1), blk_2); // 11 + 2N
+ MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_1, MK_COINS(1), blk_2r); // 11 + 2N
txs_blk_5.push_back(txs_blk_3.back());
- MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_1, MK_COINS(2), blk_2); // 12 + 2N
+ MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_1, MK_COINS(2), blk_2r); // 12 + 2N
txs_blk_6.push_back(txs_blk_3.back());
- MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_2, MK_COINS(1), blk_2); // 13 + 2N
+ MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_2, MK_COINS(1), blk_2r); // 13 + 2N
txs_blk_5.push_back(txs_blk_3.back());
- MAKE_TX_LIST(events, txs_blk_4, miner_account, recipient_account_2, MK_COINS(2), blk_2); // 14 + 2N
+ MAKE_TX_LIST(events, txs_blk_4, miner_account, recipient_account_2, MK_COINS(2), blk_2r); // 14 + 2N
txs_blk_5.push_back(txs_blk_4.back());
- MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_3, MK_COINS(1), blk_2); // 15 + 2N
+ MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_3, MK_COINS(1), blk_2r); // 15 + 2N
txs_blk_6.push_back(txs_blk_3.back());
- MAKE_TX_LIST(events, txs_blk_4, miner_account, recipient_account_3, MK_COINS(2), blk_2); // 16 + 2N
+ MAKE_TX_LIST(events, txs_blk_4, miner_account, recipient_account_3, MK_COINS(2), blk_2r); // 16 + 2N
txs_blk_5.push_back(txs_blk_4.back());
- MAKE_TX_LIST(events, txs_blk_4, miner_account, recipient_account_4, MK_COINS(1), blk_2); // 17 + 2N
+ MAKE_TX_LIST(events, txs_blk_4, miner_account, recipient_account_4, MK_COINS(1), blk_2r); // 17 + 2N
txs_blk_5.push_back(txs_blk_4.back());
- MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_4, MK_COINS(2), blk_2); // 18 + 2N
+ MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_4, MK_COINS(2), blk_2r); // 18 + 2N
txs_blk_6.push_back(txs_blk_3.back());
MAKE_NEXT_BLOCK_TX_LIST(events, blk_3, blk_2r, miner_account, txs_blk_3); // 19 + 2N
diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp
index b66aa7924..9aa0de8e5 100644
--- a/tests/core_tests/chaingen.cpp
+++ b/tests/core_tests/chaingen.cpp
@@ -504,7 +504,7 @@ bool init_spent_output_indices(map_output_idx_t& outs, map_output_t& outs_mine,
return true;
}
-bool fill_output_entries(std::vector<output_index>& out_indices, size_t sender_out, size_t nmix, size_t& real_entry_idx, std::vector<tx_source_entry::output_entry>& output_entries)
+bool fill_output_entries(std::vector<output_index>& out_indices, size_t sender_out, size_t nmix, size_t& real_entry_idx, std::vector<tx_source_entry::output_entry>& output_entries, uint64_t cur_height, const boost::optional<fnc_accept_output_t>& fnc_accept = boost::none)
{
if (out_indices.size() <= nmix)
return false;
@@ -516,6 +516,10 @@ bool fill_output_entries(std::vector<output_index>& out_indices, size_t sender_o
const output_index& oi = out_indices[i];
if (oi.spent)
continue;
+ if (oi.unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER && oi.unlock_time > cur_height + 1)
+ continue;
+ if (fnc_accept && !(fnc_accept.get())({.oi=oi, .cur_height=cur_height}))
+ continue;
bool append = false;
if (i == sender_out)
@@ -542,7 +546,8 @@ bool fill_output_entries(std::vector<output_index>& out_indices, size_t sender_o
}
bool fill_tx_sources(std::vector<tx_source_entry>& sources, const std::vector<test_event_entry>& events,
- const block& blk_head, const cryptonote::account_base& from, uint64_t amount, size_t nmix)
+ const block& blk_head, const cryptonote::account_base& from, uint64_t amount, size_t nmix,
+ bool check_unlock_time, const boost::optional<fnc_accept_output_t>& fnc_accept)
{
map_output_idx_t outs;
map_output_t outs_mine;
@@ -559,6 +564,7 @@ bool fill_tx_sources(std::vector<tx_source_entry>& sources, const std::vector<te
return false;
// Iterate in reverse is more efficiency
+ uint64_t head_height = check_unlock_time ? get_block_height(blk_head) : std::numeric_limits<uint64_t>::max() - 1;
uint64_t sources_amount = 0;
bool sources_found = false;
BOOST_REVERSE_FOREACH(const map_output_t::value_type o, outs_mine)
@@ -571,13 +577,17 @@ bool fill_tx_sources(std::vector<tx_source_entry>& sources, const std::vector<te
continue;
if (oi.rct)
continue;
+ if (oi.unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER && oi.unlock_time > head_height + 1)
+ continue;
+ if (fnc_accept && !(fnc_accept.get())({.oi=oi, .cur_height=head_height}))
+ continue;
cryptonote::tx_source_entry ts;
ts.amount = oi.amount;
ts.real_output_in_tx_index = oi.out_no;
ts.real_out_tx_key = get_tx_pub_key_from_extra(*oi.p_tx); // incoming tx public key
size_t realOutput;
- if (!fill_output_entries(outs[o.first], sender_out, nmix, realOutput, ts.outputs))
+ if (!fill_output_entries(outs[o.first], sender_out, nmix, realOutput, ts.outputs, head_height, fnc_accept))
continue;
ts.real_output = realOutput;
@@ -692,7 +702,7 @@ void block_tracker::global_indices(const cryptonote::transaction *tx, std::vecto
}
}
-void block_tracker::get_fake_outs(size_t num_outs, uint64_t amount, uint64_t global_index, uint64_t cur_height, std::vector<get_outs_entry> &outs){
+void block_tracker::get_fake_outs(size_t num_outs, uint64_t amount, uint64_t global_index, uint64_t cur_height, std::vector<get_outs_entry> &outs, const boost::optional<fnc_accept_output_t>& fnc_accept){
auto & vct = m_outs[amount];
const size_t n_outs = vct.size();
CHECK_AND_ASSERT_THROW_MES(n_outs > 0, "n_outs is 0");
@@ -717,15 +727,16 @@ void block_tracker::get_fake_outs(size_t num_outs, uint64_t amount, uint64_t glo
continue;
if (oi.out.type() != typeid(cryptonote::txout_to_key))
continue;
- if (oi.unlock_time > cur_height)
+ if (oi.unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER && oi.unlock_time > cur_height + 1)
continue;
if (used.find(oi_idx) != used.end())
continue;
+ if (fnc_accept && !(fnc_accept.get())({.oi=oi, .cur_height=cur_height}))
+ continue;
rct::key comm = oi.commitment();
auto out = boost::get<txout_to_key>(oi.out);
- auto item = std::make_tuple(oi.idx, out.key, comm);
- outs.push_back(item);
+ outs.emplace_back(oi.idx, out.key, comm);
used.insert(oi_idx);
}
}
@@ -924,13 +935,14 @@ void fill_tx_destinations(const var_addr_t& from, const cryptonote::account_publ
void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& events, const 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<tx_source_entry>& sources,
- std::vector<tx_destination_entry>& destinations)
+ std::vector<tx_destination_entry>& destinations, bool check_unlock_time,
+ const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept)
{
sources.clear();
destinations.clear();
- if (!fill_tx_sources(sources, events, blk_head, from, amount + fee, nmix))
- throw std::runtime_error("couldn't fill transaction sources");
+ if (!fill_tx_sources(sources, events, blk_head, from, amount + fee, nmix, check_unlock_time, fnc_tx_in_accept))
+ throw tx_construct_tx_fill_error();
fill_tx_destinations(from, to, amount, fee, sources, destinations, false);
}
@@ -938,9 +950,10 @@ void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& event
void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& events, const block& blk_head,
const cryptonote::account_base& from, const cryptonote::account_base& to,
uint64_t amount, uint64_t fee, size_t nmix, std::vector<tx_source_entry>& sources,
- std::vector<tx_destination_entry>& destinations)
+ std::vector<tx_destination_entry>& destinations, bool check_unlock_time,
+ const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept)
{
- fill_tx_sources_and_destinations(events, blk_head, from, to.get_keys().m_account_address, amount, fee, nmix, sources, destinations);
+ fill_tx_sources_and_destinations(events, blk_head, from, to.get_keys().m_account_address, amount, fee, nmix, sources, destinations, check_unlock_time, fnc_tx_in_accept);
}
cryptonote::tx_destination_entry build_dst(const var_addr_t& to, bool is_subaddr, uint64_t amount)
@@ -952,10 +965,14 @@ cryptonote::tx_destination_entry build_dst(const var_addr_t& to, bool is_subaddr
return de;
}
-std::vector<cryptonote::tx_destination_entry> build_dsts(const var_addr_t& to1, bool sub1, uint64_t am1)
+std::vector<cryptonote::tx_destination_entry> build_dsts(const var_addr_t& to1, bool sub1, uint64_t am1, size_t repeat)
{
std::vector<cryptonote::tx_destination_entry> res;
- res.push_back(build_dst(to1, sub1, am1));
+ res.reserve(repeat);
+ for(size_t i = 0; i < repeat; ++i)
+ {
+ res.emplace_back(build_dst(to1, sub1, am1));
+ }
return res;
}
@@ -1019,25 +1036,27 @@ bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins
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, rct::RangeProofType range_proof_type, int bp_version)
+ uint64_t fee, size_t nmix, bool rct, rct::RangeProofType range_proof_type, int bp_version,
+ bool check_unlock_time, const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept)
{
vector<tx_source_entry> sources;
vector<tx_destination_entry> destinations;
- fill_tx_sources_and_destinations(events, blk_head, from, get_address(to), amount, fee, nmix, sources, destinations);
+ fill_tx_sources_and_destinations(events, blk_head, from, get_address(to), amount, fee, nmix, sources, destinations, check_unlock_time, fnc_tx_in_accept);
return construct_tx_rct(from.get_keys(), sources, destinations, from.get_keys().m_account_address, std::vector<uint8_t>(), tx, 0, rct, range_proof_type, bp_version);
}
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, std::vector<cryptonote::tx_destination_entry> destinations,
- uint64_t fee, size_t nmix, bool rct, rct::RangeProofType range_proof_type, int bp_version)
+ const cryptonote::account_base& from, const std::vector<cryptonote::tx_destination_entry>& destinations,
+ uint64_t fee, size_t nmix, bool rct, rct::RangeProofType range_proof_type, int bp_version,
+ bool check_unlock_time, const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept)
{
vector<tx_source_entry> sources;
vector<tx_destination_entry> destinations_all;
uint64_t amount = sum_amount(destinations);
- if (!fill_tx_sources(sources, events, blk_head, from, amount + fee, nmix))
- throw std::runtime_error("couldn't fill transaction sources");
+ if (!fill_tx_sources(sources, events, blk_head, from, amount + fee, nmix, check_unlock_time, fnc_tx_in_accept))
+ throw tx_construct_tx_fill_error();
fill_tx_destinations(from, destinations, fee, sources, destinations_all, false);
diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h
index 31580502d..4d990f439 100644
--- a/tests/core_tests/chaingen.h
+++ b/tests/core_tests/chaingen.h
@@ -372,6 +372,13 @@ typedef struct {
uint64_t amount;
} dest_wrapper_t;
+typedef struct {
+ const output_index &oi;
+ uint64_t cur_height;
+} fnc_accept_output_crate_t;
+
+typedef std::function<bool(const fnc_accept_output_crate_t &info)> fnc_accept_output_t;
+
// Daemon functionality
class block_tracker
{
@@ -388,7 +395,7 @@ public:
void process(const std::vector<const cryptonote::block*>& blockchain, const map_hash2tx_t& mtx);
void process(const cryptonote::block* blk, const cryptonote::transaction * tx, size_t i);
void global_indices(const cryptonote::transaction *tx, std::vector<uint64_t> &indices);
- 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);
+ 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, const boost::optional<fnc_accept_output_t>& fnc_accept = boost::none);
std::string dump_data();
void dump_data(const std::string & fname);
@@ -405,6 +412,19 @@ private:
}
};
+class tx_construct_error : public std::runtime_error
+{
+public:
+ tx_construct_error(const char *s) : runtime_error(s) { }
+};
+
+class tx_construct_tx_fill_error : public tx_construct_error
+{
+public:
+ tx_construct_tx_fill_error() : tx_construct_error("Couldn't fill transaction sources") { }
+ tx_construct_tx_fill_error(const char *s) : tx_construct_error(s) { }
+};
+
std::string dump_data(const cryptonote::transaction &tx);
cryptonote::account_public_address get_address(const var_addr_t& inp);
cryptonote::account_public_address get_address(const cryptonote::account_public_address& inp);
@@ -416,7 +436,7 @@ inline cryptonote::difficulty_type get_test_difficulty(const boost::optional<uin
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; }
cryptonote::tx_destination_entry build_dst(const var_addr_t& to, bool is_subaddr=false, uint64_t amount=0);
-std::vector<cryptonote::tx_destination_entry> build_dsts(const var_addr_t& to1, bool sub1=false, uint64_t am1=0);
+std::vector<cryptonote::tx_destination_entry> build_dsts(const var_addr_t& to1, bool sub1=false, uint64_t am1=0, size_t repeat=1);
std::vector<cryptonote::tx_destination_entry> build_dsts(std::initializer_list<dest_wrapper_t> inps);
uint64_t sum_amount(const std::vector<cryptonote::tx_destination_entry>& destinations);
uint64_t sum_amount(const std::vector<cryptonote::tx_source_entry>& sources);
@@ -428,11 +448,13 @@ bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins
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);
+ uint64_t fee, size_t nmix, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0,
+ bool check_unlock_time = true, const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept = boost::none);
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, std::vector<cryptonote::tx_destination_entry> destinations,
- uint64_t fee, size_t nmix, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0);
+ const cryptonote::account_base& from, const std::vector<cryptonote::tx_destination_entry>& destinations,
+ uint64_t fee, size_t nmix, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0,
+ bool check_unlock_time = true, const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept = boost::none);
bool construct_tx_to_key(cryptonote::transaction& tx, const cryptonote::account_base& from, const var_addr_t& to, uint64_t amount,
std::vector<cryptonote::tx_source_entry> &sources,
@@ -463,6 +485,10 @@ bool trim_block_chain(std::vector<const cryptonote::block*>& blockchain, const c
bool find_block_chain(const std::vector<test_event_entry>& events, std::vector<cryptonote::block>& blockchain, map_hash2tx_t& mtx, const crypto::hash& head);
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);
+bool fill_tx_sources(std::vector<cryptonote::tx_source_entry>& sources, const std::vector<test_event_entry>& events,
+ const cryptonote::block& blk_head, const cryptonote::account_base& from, uint64_t amount, size_t nmix,
+ bool check_unlock_time = true, const boost::optional<fnc_accept_output_t>& fnc_accept = boost::none);
+
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,
@@ -486,13 +512,17 @@ void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& event
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);
+ std::vector<cryptonote::tx_destination_entry>& destinations,
+ bool check_unlock_time = true,
+ const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept = boost::none);
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_base& to,
uint64_t amount, uint64_t fee, size_t nmix,
std::vector<cryptonote::tx_source_entry>& sources,
- std::vector<cryptonote::tx_destination_entry>& destinations);
+ std::vector<cryptonote::tx_destination_entry>& destinations,
+ bool check_unlock_time = true,
+ const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept = boost::none);
uint64_t get_balance(const cryptonote::account_base& addr, const std::vector<cryptonote::block>& blockchain, const map_hash2tx_t& mtx);
diff --git a/tests/core_tests/chaingen001.cpp b/tests/core_tests/chaingen001.cpp
index 8738585e0..1dde16ff5 100644
--- a/tests/core_tests/chaingen001.cpp
+++ b/tests/core_tests/chaingen001.cpp
@@ -120,18 +120,18 @@ bool gen_simple_chain_001::generate(std::vector<test_event_entry> &events)
std::cout << "BALANCE = " << get_balance(miner, chain, mtx) << std::endl;
REWIND_BLOCKS(events, blk_2r, blk_2, miner);
- MAKE_TX_LIST_START(events, txlist_0, miner, alice, MK_COINS(1), blk_2);
- MAKE_TX_LIST(events, txlist_0, miner, alice, MK_COINS(2), blk_2);
- MAKE_TX_LIST(events, txlist_0, miner, alice, MK_COINS(4), blk_2);
+ MAKE_TX_LIST_START(events, txlist_0, miner, alice, MK_COINS(1), blk_2r);
+ MAKE_TX_LIST(events, txlist_0, miner, alice, MK_COINS(2), blk_2r);
+ MAKE_TX_LIST(events, txlist_0, miner, alice, MK_COINS(4), blk_2r);
MAKE_NEXT_BLOCK_TX_LIST(events, blk_3, blk_2r, miner, txlist_0);
REWIND_BLOCKS(events, blk_3r, blk_3, miner);
- MAKE_TX(events, tx_1, miner, alice, MK_COINS(50), blk_3);
+ MAKE_TX(events, tx_1, miner, alice, MK_COINS(50), blk_3r);
MAKE_NEXT_BLOCK_TX1(events, blk_4, blk_3r, miner, tx_1);
REWIND_BLOCKS(events, blk_4r, blk_4, miner);
- MAKE_TX(events, tx_2, miner, alice, MK_COINS(50), blk_4);
+ MAKE_TX(events, tx_2, miner, alice, MK_COINS(50), blk_4r);
MAKE_NEXT_BLOCK_TX1(events, blk_5, blk_4r, miner, tx_2);
REWIND_BLOCKS(events, blk_5r, blk_5, miner);
- MAKE_TX(events, tx_3, miner, alice, MK_COINS(50), blk_5);
+ MAKE_TX(events, tx_3, miner, alice, MK_COINS(50), blk_5r);
MAKE_NEXT_BLOCK_TX1(events, blk_6, blk_5r, miner, tx_3);
DO_CALLBACK(events, "verify_callback_1");
diff --git a/tests/core_tests/double_spend.h b/tests/core_tests/double_spend.h
index b1f071f38..85c855bcf 100644
--- a/tests/core_tests/double_spend.h
+++ b/tests/core_tests/double_spend.h
@@ -144,7 +144,7 @@ public:
MAKE_ACCOUNT(events, bob_account); \
MAKE_ACCOUNT(events, alice_account); \
REWIND_BLOCKS(events, blk_0r, blk_0, miner_account); \
- MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0); \
+ MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0r); \
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_account, tx_0); \
REWIND_BLOCKS(events, blk_1r, blk_1, miner_account);
diff --git a/tests/core_tests/double_spend.inl b/tests/core_tests/double_spend.inl
index 4b60da3a3..b6e3726cc 100644
--- a/tests/core_tests/double_spend.inl
+++ b/tests/core_tests/double_spend.inl
@@ -126,20 +126,14 @@ bool gen_double_spend_in_tx<txs_keeped_by_block>::generate(std::vector<test_even
DO_CALLBACK(events, "mark_last_valid_block");
std::vector<cryptonote::tx_source_entry> sources;
- cryptonote::tx_source_entry se;
- se.amount = tx_0.vout[0].amount;
- se.push_output(0, boost::get<cryptonote::txout_to_key>(tx_0.vout[0].target).key, se.amount);
- se.real_output = 0;
- se.rct = false;
- se.real_out_tx_key = get_tx_pub_key_from_extra(tx_0);
- se.real_output_in_tx_index = 0;
- sources.push_back(se);
+ CHECK_AND_ASSERT_THROW_MES(fill_tx_sources(sources, events, blk_1r, bob_account, send_amount, 0), "Source find error");
+
// Double spend!
- sources.push_back(se);
+ sources.push_back(sources[0]);
cryptonote::tx_destination_entry de;
de.addr = alice_account.get_keys().m_account_address;
- de.amount = 2 * se.amount - TESTS_DEFAULT_FEE;
+ de.amount = 2 * send_amount - TESTS_DEFAULT_FEE;
std::vector<cryptonote::tx_destination_entry> destinations;
destinations.push_back(de);
diff --git a/tests/core_tests/integer_overflow.cpp b/tests/core_tests/integer_overflow.cpp
index 42ad0d26a..6ffc3786b 100644
--- a/tests/core_tests/integer_overflow.cpp
+++ b/tests/core_tests/integer_overflow.cpp
@@ -123,8 +123,8 @@ bool gen_uint_overflow_1::generate(std::vector<test_event_entry>& events) const
events.push_back(blk_2);
REWIND_BLOCKS(events, blk_2r, blk_2, miner_account);
- MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MONEY_SUPPLY, blk_2);
- MAKE_TX_LIST(events, txs_0, miner_account, bob_account, MONEY_SUPPLY, blk_2);
+ MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MONEY_SUPPLY, blk_2r);
+ MAKE_TX_LIST(events, txs_0, miner_account, bob_account, MONEY_SUPPLY, blk_2r);
MAKE_NEXT_BLOCK_TX_LIST(events, blk_3, blk_2r, miner_account, txs_0);
REWIND_BLOCKS(events, blk_3r, blk_3, miner_account);
diff --git a/tests/core_tests/ring_signature_1.cpp b/tests/core_tests/ring_signature_1.cpp
index f3f8109c3..218747f21 100644
--- a/tests/core_tests/ring_signature_1.cpp
+++ b/tests/core_tests/ring_signature_1.cpp
@@ -70,19 +70,19 @@ bool gen_ring_signature_1::generate(std::vector<test_event_entry>& events) const
MAKE_NEXT_BLOCK(events, blk_4, blk_3, miner_account); // 8
REWIND_BLOCKS(events, blk_5, blk_4, miner_account); // <N blocks>
REWIND_BLOCKS(events, blk_5r, blk_5, miner_account); // <N blocks>
- MAKE_TX_LIST_START(events, txs_blk_6, miner_account, bob_account, MK_COINS(1), blk_5); // 9 + 2N
- MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(11) + rnd_11, blk_5); // 10 + 2N
- MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(11) + rnd_11, blk_5); // 11 + 2N
- MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(20) + rnd_20, blk_5); // 12 + 2N
- MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(29) + rnd_29, blk_5); // 13 + 2N
- MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(29) + rnd_29, blk_5); // 14 + 2N
- MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(29) + rnd_29, blk_5); // 15 + 2N
- MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5); // 16 + 2N
- MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5); // 17 + 2N
- MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5); // 18 + 2N
- MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5); // 19 + 2N
- MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(20) + rnd_20, blk_5); // 20 + 2N
- MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_2, MK_COINS(20) + rnd_20, blk_5); // 21 + 2N
+ MAKE_TX_LIST_START(events, txs_blk_6, miner_account, bob_account, MK_COINS(1), blk_5r); // 9 + 2N
+ MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(11) + rnd_11, blk_5r); // 10 + 2N
+ MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(11) + rnd_11, blk_5r); // 11 + 2N
+ MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(20) + rnd_20, blk_5r); // 12 + 2N
+ MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(29) + rnd_29, blk_5r); // 13 + 2N
+ MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(29) + rnd_29, blk_5r); // 14 + 2N
+ MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(29) + rnd_29, blk_5r); // 15 + 2N
+ MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5r); // 16 + 2N
+ MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5r); // 17 + 2N
+ MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5r); // 18 + 2N
+ MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5r); // 19 + 2N
+ MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(20) + rnd_20, blk_5r); // 20 + 2N
+ MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_2, MK_COINS(20) + rnd_20, blk_5r); // 21 + 2N
MAKE_NEXT_BLOCK_TX_LIST(events, blk_6, blk_5r, miner_account, txs_blk_6); // 22 + 2N
DO_CALLBACK(events, "check_balances_1"); // 23 + 2N
REWIND_BLOCKS(events, blk_6r, blk_6, miner_account); // <N blocks>
@@ -161,14 +161,14 @@ bool gen_ring_signature_2::generate(std::vector<test_event_entry>& events) const
MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner_account); // 4
MAKE_NEXT_BLOCK(events, blk_3, blk_2, miner_account); // 5
REWIND_BLOCKS(events, blk_3r, blk_3, miner_account); // <N blocks>
- MAKE_TX_LIST_START(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3); // 6 + N
- MAKE_TX_LIST(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3); // 7 + N
- MAKE_TX_LIST(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3); // 8 + N
- MAKE_TX_LIST(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3); // 9 + N
+ MAKE_TX_LIST_START(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3r); // 6 + N
+ MAKE_TX_LIST(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3r); // 7 + N
+ MAKE_TX_LIST(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3r); // 8 + N
+ MAKE_TX_LIST(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3r); // 9 + N
MAKE_NEXT_BLOCK_TX_LIST(events, blk_4, blk_3r, miner_account, txs_blk_4); // 10 + N
DO_CALLBACK(events, "check_balances_1"); // 11 + N
REWIND_BLOCKS(events, blk_4r, blk_4, miner_account); // <N blocks>
- MAKE_TX_MIX(events, tx_0, bob_account, alice_account, MK_COINS(52) - TESTS_DEFAULT_FEE, 3, blk_4); // 12 + 2N
+ MAKE_TX_MIX(events, tx_0, bob_account, alice_account, MK_COINS(52) - TESTS_DEFAULT_FEE, 3, blk_4r); // 12 + 2N
MAKE_NEXT_BLOCK_TX1(events, blk_5, blk_4r, miner_account, tx_0); // 13 + 2N
DO_CALLBACK(events, "check_balances_2"); // 14 + 2N
diff --git a/tests/core_tests/tx_pool.cpp b/tests/core_tests/tx_pool.cpp
index d3dc5d9bb..1b8480526 100644
--- a/tests/core_tests/tx_pool.cpp
+++ b/tests/core_tests/tx_pool.cpp
@@ -98,7 +98,7 @@ bool txpool_spend_key_public::generate(std::vector<test_event_entry>& events) co
INIT_MEMPOOL_TEST();
DO_CALLBACK(events, "check_txpool_spent_keys");
- MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0);
+ MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0r);
DO_CALLBACK(events, "increase_broadcasted_tx_count");
DO_CALLBACK(events, "increase_all_tx_count");
DO_CALLBACK(events, "check_txpool_spent_keys");
@@ -112,7 +112,7 @@ bool txpool_spend_key_all::generate(std::vector<test_event_entry>& events)
SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_do_not_relay);
DO_CALLBACK(events, "check_txpool_spent_keys");
- MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0);
+ MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0r);
DO_CALLBACK(events, "increase_all_tx_count");
DO_CALLBACK(events, "check_txpool_spent_keys");
@@ -502,7 +502,7 @@ bool txpool_double_spend_norelay::generate(std::vector<test_event_entry>& events
SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_do_not_relay);
DO_CALLBACK(events, "mark_no_new");
- MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0);
+ MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0r);
DO_CALLBACK(events, "increase_all_tx_count");
DO_CALLBACK(events, "check_txpool_spent_keys");
@@ -539,7 +539,7 @@ bool txpool_double_spend_local::generate(std::vector<test_event_entry>& events)
SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_local_relay);
DO_CALLBACK(events, "mark_no_new");
- MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0);
+ MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0r);
DO_CALLBACK(events, "increase_all_tx_count");
DO_CALLBACK(events, "check_txpool_spent_keys");
@@ -574,7 +574,7 @@ bool txpool_double_spend_keyimage::generate(std::vector<test_event_entry>& event
DO_CALLBACK(events, "mark_no_new");
const std::size_t tx_index1 = events.size();
- MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0);
+ MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0r);
SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_stem);
DO_CALLBACK(events, "increase_all_tx_count");
@@ -595,7 +595,7 @@ bool txpool_double_spend_keyimage::generate(std::vector<test_event_entry>& event
auto events_copy = events;
events_copy.erase(events_copy.begin() + tx_index1);
events_copy.erase(events_copy.begin() + tx_index2 - 1);
- MAKE_TX(events_copy, tx_temp, miner_account, bob_account, send_amount, blk_0);
+ MAKE_TX(events_copy, tx_temp, miner_account, bob_account, send_amount, blk_0r);
tx_1 = tx_temp;
}
@@ -616,7 +616,7 @@ bool txpool_stem_loop::generate(std::vector<test_event_entry>& events) const
SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_stem);
DO_CALLBACK(events, "mark_no_new");
- MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0);
+ MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0r);
DO_CALLBACK(events, "increase_all_tx_count");
DO_CALLBACK(events, "check_txpool_spent_keys");
diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp
index cfc8f089d..bc8622539 100644
--- a/tests/core_tests/tx_validation.cpp
+++ b/tests/core_tests/tx_validation.cpp
@@ -141,7 +141,7 @@ namespace
{
std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations;
- fill_tx_sources_and_destinations(events, blk_head, from, to, amount, TESTS_DEFAULT_FEE, 0, sources, destinations);
+ fill_tx_sources_and_destinations(events, blk_head, from, to, amount, TESTS_DEFAULT_FEE, 0, sources, destinations, false);
tx_builder builder;
builder.step1_init(1, unlock_time);
@@ -191,7 +191,7 @@ bool gen_tx_big_version::generate(std::vector<test_event_entry>& events) const
std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations;
- fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
+ fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder;
builder.step1_init(1 + 1, 0);
@@ -217,7 +217,7 @@ bool gen_tx_unlock_time::generate(std::vector<test_event_entry>& events) const
auto make_tx_with_unlock_time = [&](uint64_t unlock_time) -> transaction
{
- return make_simple_tx_with_unlock_time(events, blk_1, miner_account, miner_account, MK_COINS(1), unlock_time);
+ return make_simple_tx_with_unlock_time(events, blk_1r, miner_account, miner_account, MK_COINS(1), unlock_time);
};
std::list<transaction> txs_0;
@@ -266,7 +266,7 @@ bool gen_tx_input_is_not_txin_to_key::generate(std::vector<test_event_entry>& ev
{
std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations;
- fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
+ fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder;
builder.step1_init();
@@ -309,7 +309,7 @@ bool gen_tx_no_inputs_has_outputs::generate(std::vector<test_event_entry>& event
std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations;
- fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
+ fill_tx_destinations(miner_account, miner_account.get_keys().m_account_address, MK_COINS(1), TESTS_DEFAULT_FEE, sources, destinations, false);
tx_builder builder;
builder.step1_init();
@@ -331,7 +331,7 @@ bool gen_tx_has_inputs_no_outputs::generate(std::vector<test_event_entry>& event
std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations;
- fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
+ fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
destinations.clear();
tx_builder builder;
@@ -357,7 +357,7 @@ bool gen_tx_invalid_input_amount::generate(std::vector<test_event_entry>& events
std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations;
- fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
+ fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
sources.front().amount++;
tx_builder builder;
@@ -383,7 +383,7 @@ bool gen_tx_input_wo_key_offsets::generate(std::vector<test_event_entry>& events
std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations;
- fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
+ fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder;
builder.step1_init();
@@ -414,8 +414,8 @@ bool gen_tx_key_offest_points_to_foreign_key::generate(std::vector<test_event_en
REWIND_BLOCKS(events, blk_1r, blk_1, miner_account);
MAKE_ACCOUNT(events, alice_account);
MAKE_ACCOUNT(events, bob_account);
- MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MK_COINS(15) + 1, blk_1);
- MAKE_TX_LIST(events, txs_0, miner_account, alice_account, MK_COINS(15) + 1, blk_1);
+ MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MK_COINS(15) + 1, blk_1r);
+ MAKE_TX_LIST(events, txs_0, miner_account, alice_account, MK_COINS(15) + 1, blk_1r);
MAKE_NEXT_BLOCK_TX_LIST(events, blk_2, blk_1r, miner_account, txs_0);
std::vector<tx_source_entry> sources_bob;
@@ -451,7 +451,7 @@ bool gen_tx_sender_key_offest_not_exist::generate(std::vector<test_event_entry>&
std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations;
- fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
+ fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder;
builder.step1_init();
@@ -478,8 +478,8 @@ bool gen_tx_mixed_key_offest_not_exist::generate(std::vector<test_event_entry>&
REWIND_BLOCKS(events, blk_1r, blk_1, miner_account);
MAKE_ACCOUNT(events, alice_account);
MAKE_ACCOUNT(events, bob_account);
- MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1);
- MAKE_TX_LIST(events, txs_0, miner_account, alice_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1);
+ MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1r);
+ MAKE_TX_LIST(events, txs_0, miner_account, alice_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1r);
MAKE_NEXT_BLOCK_TX_LIST(events, blk_2, blk_1r, miner_account, txs_0);
std::vector<tx_source_entry> sources;
@@ -511,7 +511,7 @@ bool gen_tx_key_image_not_derive_from_tx_key::generate(std::vector<test_event_en
std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations;
- fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
+ fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder;
builder.step1_init();
@@ -547,7 +547,7 @@ bool gen_tx_key_image_is_invalid::generate(std::vector<test_event_entry>& events
std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations;
- fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
+ fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder;
builder.step1_init();
@@ -591,7 +591,7 @@ bool gen_tx_check_input_unlock_time::generate(std::vector<test_event_entry>& eve
std::list<transaction> txs_0;
auto make_tx_to_acc = [&](size_t acc_idx, uint64_t unlock_time)
{
- txs_0.push_back(make_simple_tx_with_unlock_time(events, blk_1, miner_account, accounts[acc_idx],
+ txs_0.push_back(make_simple_tx_with_unlock_time(events, blk_1r, miner_account, accounts[acc_idx],
MK_COINS(1) + TESTS_DEFAULT_FEE, unlock_time));
events.push_back(txs_0.back());
};
@@ -641,7 +641,7 @@ bool gen_tx_txout_to_key_has_invalid_key::generate(std::vector<test_event_entry>
std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations;
- fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
+ fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder;
builder.step1_init();
@@ -670,7 +670,7 @@ bool gen_tx_output_with_zero_amount::generate(std::vector<test_event_entry>& eve
std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations;
- fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
+ fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder;
builder.step1_init();
@@ -698,7 +698,7 @@ bool gen_tx_output_is_not_txout_to_key::generate(std::vector<test_event_entry>&
std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations;
- fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
+ fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder;
builder.step1_init();
@@ -740,8 +740,8 @@ bool gen_tx_signatures_are_invalid::generate(std::vector<test_event_entry>& even
REWIND_BLOCKS(events, blk_1r, blk_1, miner_account);
MAKE_ACCOUNT(events, alice_account);
MAKE_ACCOUNT(events, bob_account);
- MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1);
- MAKE_TX_LIST(events, txs_0, miner_account, alice_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1);
+ MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1r);
+ MAKE_TX_LIST(events, txs_0, miner_account, alice_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1r);
MAKE_NEXT_BLOCK_TX_LIST(events, blk_2, blk_1r, miner_account, txs_0);
MAKE_TX(events, tx_0, miner_account, miner_account, MK_COINS(60), blk_2);
diff --git a/tests/core_tests/wallet_tools.cpp b/tests/core_tests/wallet_tools.cpp
index a3b66e835..5378b0254 100644
--- a/tests/core_tests/wallet_tools.cpp
+++ b/tests/core_tests/wallet_tools.cpp
@@ -4,6 +4,7 @@
#include "wallet_tools.h"
#include <random>
+#include <boost/assign.hpp>
using namespace std;
using namespace epee;
@@ -31,11 +32,18 @@ void wallet_accessor_test::set_account(tools::wallet2 * wallet, cryptonote::acco
void wallet_accessor_test::process_parsed_blocks(tools::wallet2 * wallet, uint64_t start_height, const std::vector<cryptonote::block_complete_entry> &blocks, const std::vector<tools::wallet2::parsed_block> &parsed_blocks, uint64_t& blocks_added)
{
- wallet->process_parsed_blocks(start_height, blocks, parsed_blocks, blocks_added);
+ if (wallet != nullptr) {
+ wallet->process_parsed_blocks(start_height, blocks, parsed_blocks, blocks_added);
+ }
}
void wallet_tools::process_transactions(tools::wallet2 * wallet, const std::vector<test_event_entry>& events, const cryptonote::block& blk_head, block_tracker &bt, const boost::optional<crypto::hash>& blk_tail)
{
+ process_transactions(boost::assign::list_of(wallet), events, blk_head, bt, blk_tail);
+}
+
+void wallet_tools::process_transactions(const std::vector<tools::wallet2*>& wallets, const std::vector<test_event_entry>& events, const cryptonote::block& blk_head, block_tracker &bt, const boost::optional<crypto::hash>& blk_tail)
+{
map_hash2tx_t mtx;
std::vector<const cryptonote::block*> blockchain;
find_block_chain(events, blockchain, mtx, get_block_hash(blk_head));
@@ -44,10 +52,14 @@ void wallet_tools::process_transactions(tools::wallet2 * wallet, const std::vect
trim_block_chain(blockchain, blk_tail.get());
}
- process_transactions(wallet, blockchain, mtx, bt);
+ process_transactions(wallets, blockchain, mtx, bt);
+}
+
+void wallet_tools::process_transactions(tools::wallet2 * wallet, const std::vector<const cryptonote::block*>& blockchain, const map_hash2tx_t & mtx, block_tracker &bt){
+ process_transactions(boost::assign::list_of(wallet), blockchain, mtx, bt);
}
-void wallet_tools::process_transactions(tools::wallet2 * wallet, const std::vector<const cryptonote::block*>& blockchain, const map_hash2tx_t & mtx, block_tracker &bt)
+void wallet_tools::process_transactions(const std::vector<tools::wallet2*>& wallets, const std::vector<const cryptonote::block*>& blockchain, const map_hash2tx_t & mtx, block_tracker &bt)
{
uint64_t start_height=0, blocks_added=0;
std::vector<cryptonote::block_complete_entry> v_bche;
@@ -67,11 +79,12 @@ void wallet_tools::process_transactions(tools::wallet2 * wallet, const std::vect
wallet_tools::gen_block_data(bt, bl, mtx, v_bche.back(), v_parsed_block.back(), idx == 1 ? start_height : height);
}
- if (wallet)
+ for(auto wallet: wallets) {
wallet_accessor_test::process_parsed_blocks(wallet, start_height, v_bche, v_parsed_block, blocks_added);
+ }
}
-bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptonote::tx_source_entry>& sources, size_t mixin, const boost::optional<size_t>& num_utxo, const boost::optional<uint64_t>& min_amount, block_tracker &bt, std::vector<size_t> &selected, uint64_t cur_height, ssize_t offset, int step, const boost::optional<fnc_accept_tx_source_t>& fnc_accept)
+bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptonote::tx_source_entry>& sources, size_t mixin, const boost::optional<size_t>& num_utxo, const boost::optional<uint64_t>& min_amount, block_tracker &bt, std::vector<size_t> &selected, uint64_t cur_height, ssize_t offset, int step, const boost::optional<fnc_accept_tx_source_t>& fnc_accept, const boost::optional<fnc_accept_output_t>& fnc_in_accept)
{
CHECK_AND_ASSERT_THROW_MES(step != 0, "Step is zero");
sources.clear();
@@ -84,7 +97,7 @@ bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptono
size_t iters = 0;
uint64_t sum = 0;
size_t cur_utxo = 0;
- bool abort = false;
+ bool should_abort_search = false;
unsigned brk_cond = 0;
unsigned brk_thresh = num_utxo && min_amount ? 2 : (num_utxo || min_amount ? 1 : 0);
@@ -96,7 +109,7 @@ bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptono
brk_cond += 1; \
} while(0)
- for(ssize_t i = roffset; iters < ntrans && !abort; i += step, ++iters)
+ for(ssize_t i = roffset; iters < ntrans && !should_abort_search; i += step, ++iters)
{
EVAL_BRK_COND();
if (brk_cond >= brk_thresh)
@@ -106,7 +119,7 @@ bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptono
auto & td = transfers[i];
if (td.m_spent)
continue;
- if (td.m_block_height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW > cur_height)
+ if (td.m_tx.unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER && td.m_tx.unlock_time > cur_height + 1)
continue;
if (selected_idx.find((size_t)i) != selected_idx.end()){
MERROR("Should not happen (selected_idx not found): " << i);
@@ -119,18 +132,12 @@ bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptono
try {
cryptonote::tx_source_entry src;
- wallet_tools::gen_tx_src(mixin, cur_height, td, src, bt);
+ wallet_tools::gen_tx_src(mixin, cur_height, td, src, bt, fnc_in_accept);
// Acceptor function
- if (fnc_accept){
- tx_source_info_crate_t c_info{.td=&td, .src=&src, .selected_idx=&selected_idx, .selected_kis=&selected_kis,
- .ntrans=ntrans, .iters=iters, .sum=sum, .cur_utxo=cur_utxo};
-
- bool take_it = (fnc_accept.get())(c_info, abort);
- if (!take_it){
+ if (fnc_accept && !(fnc_accept.get())({.td=&td, .src=&src, .selected_idx=&selected_idx, .selected_kis=&selected_kis,
+ .ntrans=ntrans, .iters=iters, .sum=sum, .cur_utxo=cur_utxo}, should_abort_search))
continue;
- }
- }
MDEBUG("Selected " << i << " from tx: " << dump_keys(td.m_txid.data)
<< " ki: " << dump_keys(td.m_key_image.data)
@@ -154,18 +161,22 @@ bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptono
}
EVAL_BRK_COND();
- return brk_cond >= brk_thresh;
+ const auto res = brk_cond >= brk_thresh;
+ if (!res) {
+ MDEBUG("fill_tx_sources fails, brk_cond: " << brk_cond << ", brk_thresh: " << brk_thresh << ", utxos: " << cur_utxo << ", sum: " << sum);
+ }
+ return res;
#undef EVAL_BRK_COND
}
-void wallet_tools::gen_tx_src(size_t mixin, uint64_t cur_height, const tools::wallet2::transfer_details & td, cryptonote::tx_source_entry & src, block_tracker &bt)
+void wallet_tools::gen_tx_src(size_t mixin, uint64_t cur_height, const tools::wallet2::transfer_details & td, cryptonote::tx_source_entry & src, block_tracker &bt, const boost::optional<fnc_accept_output_t>& fnc_accept)
{
CHECK_AND_ASSERT_THROW_MES(mixin != 0, "mixin is zero");
src.amount = td.amount();
src.rct = td.is_rct();
std::vector<tools::wallet2::get_outs_entry> outs;
- bt.get_fake_outs(mixin, td.is_rct() ? 0 : td.amount(), td.m_global_output_index, cur_height, outs);
+ bt.get_fake_outs(mixin, td.is_rct() ? 0 : td.amount(), td.m_global_output_index, cur_height, outs, fnc_accept);
for (size_t n = 0; n < mixin; ++n)
{
diff --git a/tests/core_tests/wallet_tools.h b/tests/core_tests/wallet_tools.h
index 1fb8017bf..2201e11f4 100644
--- a/tests/core_tests/wallet_tools.h
+++ b/tests/core_tests/wallet_tools.h
@@ -68,12 +68,14 @@ public:
class wallet_tools
{
public:
- static void gen_tx_src(size_t mixin, uint64_t cur_height, const tools::wallet2::transfer_details & td, cryptonote::tx_source_entry & src, block_tracker &bt);
+ static void gen_tx_src(size_t mixin, uint64_t cur_height, const tools::wallet2::transfer_details & td, cryptonote::tx_source_entry & src, block_tracker &bt, const boost::optional<fnc_accept_output_t>& fnc_accept = boost::none);
static void gen_block_data(block_tracker &bt, const cryptonote::block *bl, const map_hash2tx_t & mtx, cryptonote::block_complete_entry &bche, tools::wallet2::parsed_block &parsed_block, uint64_t &height);
static void compute_subaddresses(std::unordered_map<crypto::public_key, cryptonote::subaddress_index> &subaddresses, cryptonote::account_base & creds, size_t account, size_t minors);
static void process_transactions(tools::wallet2 * wallet, const std::vector<test_event_entry>& events, const cryptonote::block& blk_head, block_tracker &bt, const boost::optional<crypto::hash>& blk_tail=boost::none);
+ static void process_transactions(const std::vector<tools::wallet2*>& wallets, const std::vector<test_event_entry>& events, const cryptonote::block& blk_head, block_tracker &bt, const boost::optional<crypto::hash>& blk_tail=boost::none);
static void process_transactions(tools::wallet2 * wallet, const std::vector<const cryptonote::block*>& blockchain, const map_hash2tx_t & mtx, block_tracker &bt);
- static bool fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptonote::tx_source_entry>& sources, size_t mixin, const boost::optional<size_t>& num_utxo, const boost::optional<uint64_t>& min_amount, block_tracker &bt, std::vector<size_t> &selected, uint64_t cur_height, ssize_t offset=0, int step=1, const boost::optional<fnc_accept_tx_source_t>& fnc_accept=boost::none);
+ static void process_transactions(const std::vector<tools::wallet2*>& wallets, const std::vector<const cryptonote::block*>& blockchain, const map_hash2tx_t & mtx, block_tracker &bt);
+ static bool fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptonote::tx_source_entry>& sources, size_t mixin, const boost::optional<size_t>& num_utxo, const boost::optional<uint64_t>& min_amount, block_tracker &bt, std::vector<size_t> &selected, uint64_t cur_height, ssize_t offset=0, int step=1, const boost::optional<fnc_accept_tx_source_t>& fnc_accept=boost::none, const boost::optional<fnc_accept_output_t>& fnc_in_accept = boost::none);
};
cryptonote::account_public_address get_address(const tools::wallet2*);