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
This commit is contained in:
parent
90294f09ae
commit
056c996703
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "wallet_tools.h"
|
||||
#include <random>
|
||||
#include <boost/assign.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace epee;
|
||||
|
@ -31,10 +32,17 @@ 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)
|
||||
{
|
||||
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;
|
||||
|
@ -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)
|
||||
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(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)
|
||||
{
|
||||
|
|
|
@ -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*);
|
||||
|
|
Loading…
Reference in New Issue