forked from lthn/blockchain
Merge branch 'multiassets' into recent_history
This commit is contained in:
commit
60a9274dcb
25 changed files with 701 additions and 235 deletions
|
|
@ -13,7 +13,7 @@ namespace currency
|
|||
{
|
||||
struct hard_forks_descriptor
|
||||
{
|
||||
constexpr static size_t m_total_count = 5;
|
||||
constexpr static size_t m_total_count = ZANO_HARDFORKS_TOTAL;
|
||||
std::array<uint64_t, m_total_count> m_height_the_hardfork_n_active_after;
|
||||
|
||||
hard_forks_descriptor()
|
||||
|
|
@ -81,6 +81,16 @@ namespace currency
|
|||
{
|
||||
return HF3_BLOCK_MINOR_VERSION;
|
||||
}
|
||||
|
||||
bool operator==(const hard_forks_descriptor& rhs) const
|
||||
{
|
||||
return m_height_the_hardfork_n_active_after == rhs.m_height_the_hardfork_n_active_after;
|
||||
}
|
||||
|
||||
bool operator!=(const hard_forks_descriptor& rhs) const
|
||||
{
|
||||
return ! operator==(rhs);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -94,10 +94,11 @@ bool transition_convert(const transaction_current_t& from, transaction_v1& to)
|
|||
{
|
||||
if (s.type() == typeid(NLSAG_sig))
|
||||
{
|
||||
to.signatures.push_back(boost::get<NLSAG_sig>(s).s); ;
|
||||
}else
|
||||
to.signatures.push_back(boost::get<NLSAG_sig>(s).s);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Unexpected type in signature_v");
|
||||
throw std::runtime_error(std::string("Unexpected type in tx.signatures during transition_convert: ") + s.type().name());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -266,6 +266,7 @@
|
|||
#define ZANO_HARDFORK_02 2
|
||||
#define ZANO_HARDFORK_03 3
|
||||
#define ZANO_HARDFORK_04_ZARCANUM 4
|
||||
#define ZANO_HARDFORKS_TOTAL 5
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2207,10 +2207,9 @@ namespace currency
|
|||
}
|
||||
|
||||
if (src_entr.is_native_coin())
|
||||
{
|
||||
native_coins_input_sum += src_entr.amount;
|
||||
}
|
||||
else
|
||||
|
||||
if (src_entr.is_zc())
|
||||
{
|
||||
// if at least one decoy output of a ZC input has a non-explicit asset id, then we can't say that all inputs are obviously native coins
|
||||
for(const tx_source_entry::output_entry& oe : in_context.outputs)
|
||||
|
|
@ -2224,6 +2223,10 @@ namespace currency
|
|||
}
|
||||
}
|
||||
|
||||
if (zc_inputs_count != 0 && tx.version <= TRANSACTION_VERSION_PRE_HF4)
|
||||
{
|
||||
LOG_PRINT_YELLOW("WARNING: tx v1 should not use ZC inputs", LOG_LEVEL_0);
|
||||
}
|
||||
|
||||
//
|
||||
// OUTs
|
||||
|
|
|
|||
|
|
@ -945,8 +945,8 @@ namespace currency
|
|||
return "(no transactions, the pool is empty)";
|
||||
// sort output by receive time
|
||||
txs.sort([](const std::pair<crypto::hash, tx_details>& lhs, const std::pair<crypto::hash, tx_details>& rhs) -> bool { return lhs.second.receive_time < rhs.second.receive_time; });
|
||||
ss << "# | transaction id | size | fee | ins | outs | outs money | live_time | max used block | last failed block | kept by a block?" << ENDL;
|
||||
// 1234 <f99fe6d4335fc0ddd69e6880a4d95e0f6ea398de0324a6837021a61c6a31cacd> 87157 0.10000111 2000 2000 112000.12345678 d0.h10.m16.s17 123456 <12345..> 123456 <12345..> YES
|
||||
ss << "# | transaction id | size | fee | ins | outs | outs money | live_time | max used block | last failed block | kept by a block?" << ENDL;
|
||||
// 1234 f99fe6d4335fc0ddd69e6880a4d95e0f6ea398de0324a6837021a61c6a31cacd 87157 0.10000111 2000 2000 112000.12345678 d0.h10.m16.s17 123456 <12345..> 123456 <12345..> YES
|
||||
size_t i = 0;
|
||||
for (auto& tx : txs)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit b45d5a82285a8804c859e9d3548fae693716cd6a
|
||||
Subproject commit 2750d12c11f6063e75f6370a4382db7f0784d624
|
||||
|
|
@ -2394,7 +2394,7 @@ int main(int argc, char* argv[])
|
|||
if (command_line::get_arg(vm, arg_generate_new_wallet).size() || command_line::get_arg(vm, arg_generate_new_auditable_wallet).size())
|
||||
return EXIT_FAILURE;
|
||||
|
||||
wal.m_use_assets_whitelisting(true);
|
||||
wal.set_use_assets_whitelisting(true);
|
||||
|
||||
if (!offline_mode)
|
||||
wal.refresh();
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@
|
|||
#define PROJECT_REVISION "0"
|
||||
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
|
||||
|
||||
#define PROJECT_VERSION_BUILD_NO 204
|
||||
#define PROJECT_VERSION_BUILD_NO 206
|
||||
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"
|
||||
|
|
|
|||
|
|
@ -96,9 +96,6 @@ gen_alias_tests::gen_alias_tests()
|
|||
REGISTER_CALLBACK_METHOD(gen_alias_tests, check_height_not_changed);
|
||||
REGISTER_CALLBACK_METHOD(gen_alias_tests, check_height_changed);
|
||||
REGISTER_CALLBACK_METHOD(gen_alias_tests, check_too_many_aliases_registration);
|
||||
|
||||
m_hardforks.set_hardfork_height(1, 0);
|
||||
m_hardforks.set_hardfork_height(2, 0);
|
||||
}
|
||||
|
||||
bool gen_alias_tests::generate(std::vector<test_event_entry>& events) const
|
||||
|
|
@ -107,7 +104,6 @@ bool gen_alias_tests::generate(std::vector<test_event_entry>& events) const
|
|||
GENERATE_ACCOUNT(miner_account); // event index
|
||||
m_accounts.push_back(miner_account);
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, preminer_account, test_core_time::get_time()); // 0
|
||||
set_hard_fork_heights_to_generator(generator);
|
||||
DO_CALLBACK(events, "configure_core"); // 1
|
||||
MAKE_ACCOUNT(events, first_acc); // 2
|
||||
MAKE_ACCOUNT(events, second_acc); // 3
|
||||
|
|
@ -874,6 +870,7 @@ bool gen_alias_reg_with_locked_money::generate(std::vector<test_event_entry>& ev
|
|||
GENERATE_ACCOUNT(alice);
|
||||
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts);
|
||||
DO_CALLBACK(events, "configure_core");
|
||||
|
||||
currency::block& prev_block = blk_0;
|
||||
|
||||
|
|
@ -1155,6 +1152,7 @@ bool gen_alias_tx_no_outs::generate(std::vector<test_event_entry>& events) const
|
|||
uint64_t ts = test_core_time::get_time();
|
||||
GENERATE_ACCOUNT(miner_acc);
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts);
|
||||
DO_CALLBACK(events, "configure_core");
|
||||
events.push_back(miner_acc);
|
||||
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2014-2018 Zano Project
|
||||
// Copyright (c) 2014-2023 Zano Project
|
||||
// Copyright (c) 2014-2018 The Louisdor Project
|
||||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
|
|
@ -46,7 +46,8 @@ namespace
|
|||
|
||||
#define BLOCK_VALIDATION_INIT_GENERATE() \
|
||||
GENERATE_ACCOUNT(miner_account); \
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, miner_account, 1338224400);
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, miner_account, 1338224400); \
|
||||
DO_CALLBACK(events, "configure_core");
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Tests
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2014-2018 Zano Project
|
||||
// Copyright (c) 2014-2023 Zano Project
|
||||
// Copyright (c) 2014-2018 The Louisdor Project
|
||||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
|
|
@ -8,16 +8,11 @@
|
|||
#include "chaingen.h"
|
||||
|
||||
template<size_t invalid_block_idx = 0>
|
||||
class gen_block_verification_base : public test_chain_unit_base
|
||||
class gen_block_verification_base : public test_chain_unit_enchanced
|
||||
{
|
||||
public:
|
||||
gen_block_verification_base()
|
||||
{
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[1] = 1440;
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[2] = 1800;
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[3] = 1801;
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[4] = 50000000000;
|
||||
|
||||
REGISTER_CALLBACK("check_block_purged", gen_block_verification_base<invalid_block_idx>::check_block_purged);
|
||||
}
|
||||
|
||||
|
|
@ -29,143 +24,131 @@ public:
|
|||
return !bvc.m_verification_failed;
|
||||
}
|
||||
|
||||
// currency::core_runtime_config get_runtime_info_for_core() const
|
||||
// {
|
||||
// currency::core_runtime_config res = test_chain_unit_base::get_runtime_info_for_core();
|
||||
//
|
||||
// }
|
||||
|
||||
bool check_block_purged(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
|
||||
CHECK_TEST_CONDITION(invalid_block_idx < ev_index);
|
||||
CHECK_EQ(0, c.get_pool_transactions_count());
|
||||
CHECK_EQ(invalid_block_idx, c.get_current_blockchain_size());
|
||||
size_t invalid_block_height = invalid_block_idx - 1; // it's bad idea to use invalid_block_idx for both event index and block height, consider redisign -- sowle
|
||||
CHECK_EQ(invalid_block_height, c.get_current_blockchain_size());
|
||||
|
||||
return true;
|
||||
}
|
||||
//mutable currency::hard_forks_descriptor m_hardforks;
|
||||
};
|
||||
|
||||
template<size_t expected_blockchain_height>
|
||||
struct gen_block_accepted_base : public test_chain_unit_base
|
||||
struct gen_block_accepted_base : public test_chain_unit_enchanced
|
||||
{
|
||||
gen_block_accepted_base()
|
||||
{
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[1] = 1440;
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[2] = 1800;
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[3] = 1801;
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[4] = 50000000000;
|
||||
REGISTER_CALLBACK("check_block_accepted", gen_block_accepted_base::check_block_accepted);
|
||||
}
|
||||
|
||||
bool check_block_accepted(currency::core& c, size_t /*ev_index*/, const std::vector<test_event_entry>& /*events*/)
|
||||
{
|
||||
|
||||
CHECK_EQ(0, c.get_pool_transactions_count());
|
||||
CHECK_EQ(expected_blockchain_height, c.get_current_blockchain_size());
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct gen_block_big_major_version : public gen_block_verification_base<1>
|
||||
struct gen_block_big_major_version : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_big_minor_version : public gen_block_accepted_base<2>
|
||||
struct gen_block_big_minor_version : public gen_block_accepted_base<2 /* <- expected blockchain height */>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_ts_not_checked : public gen_block_accepted_base<BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW>
|
||||
struct gen_block_ts_not_checked : public gen_block_accepted_base<BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW /* <- expected blockchain height */>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_ts_in_past : public gen_block_verification_base<BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW>
|
||||
struct gen_block_ts_in_past : public gen_block_verification_base<BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW + 1 /* <- invalid_block_idx */>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_ts_in_future : public gen_block_verification_base<1>
|
||||
struct gen_block_ts_in_future : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_invalid_prev_id : public gen_block_verification_base<1>
|
||||
struct gen_block_invalid_prev_id : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool check_block_verification_context(const currency::block_verification_context& bvc, size_t event_idx, const currency::block& /*blk*/);
|
||||
};
|
||||
|
||||
struct gen_block_invalid_nonce : public gen_block_verification_base<3>
|
||||
struct gen_block_invalid_nonce : public gen_block_verification_base<4>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_no_miner_tx : public gen_block_verification_base<1>
|
||||
struct gen_block_no_miner_tx : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_unlock_time_is_low : public gen_block_verification_base<1>
|
||||
struct gen_block_unlock_time_is_low : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_unlock_time_is_high : public gen_block_verification_base<1>
|
||||
struct gen_block_unlock_time_is_high : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_unlock_time_is_timestamp_in_past : public gen_block_verification_base<1>
|
||||
struct gen_block_unlock_time_is_timestamp_in_past : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_unlock_time_is_timestamp_in_future : public gen_block_verification_base<1>
|
||||
struct gen_block_unlock_time_is_timestamp_in_future : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_height_is_low : public gen_block_verification_base<1>
|
||||
struct gen_block_height_is_low : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_height_is_high : public gen_block_verification_base<1>
|
||||
struct gen_block_height_is_high : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_miner_tx_has_2_tx_gen_in : public gen_block_verification_base<1>
|
||||
struct gen_block_miner_tx_has_2_tx_gen_in : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_miner_tx_has_2_in : public gen_block_verification_base<CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1>
|
||||
struct gen_block_miner_tx_has_2_in : public gen_block_verification_base<CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_miner_tx_with_txin_to_key : public gen_block_verification_base<CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 2>
|
||||
struct gen_block_miner_tx_with_txin_to_key : public gen_block_verification_base<CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_miner_tx_out_is_small : public gen_block_verification_base<1>
|
||||
struct gen_block_miner_tx_out_is_small : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_miner_tx_out_is_big : public gen_block_verification_base<1>
|
||||
struct gen_block_miner_tx_out_is_big : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_miner_tx_has_no_out : public gen_block_verification_base<1>
|
||||
struct gen_block_miner_tx_has_no_out : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
|
@ -175,17 +158,17 @@ struct gen_block_miner_tx_has_out_to_alice : public gen_block_accepted_base<2>
|
|||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_has_invalid_tx : public gen_block_verification_base<1>
|
||||
struct gen_block_has_invalid_tx : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_is_too_big : public gen_block_verification_base<1>
|
||||
struct gen_block_is_too_big : public gen_block_verification_base<2>
|
||||
{
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
struct gen_block_wrong_version_agains_hardfork : public gen_block_verification_base<1>
|
||||
struct gen_block_wrong_version_agains_hardfork : public gen_block_verification_base<2>
|
||||
{
|
||||
public:
|
||||
gen_block_wrong_version_agains_hardfork();
|
||||
|
|
@ -193,8 +176,6 @@ public:
|
|||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct gen_block_invalid_binary_format : public test_chain_unit_base
|
||||
{
|
||||
gen_block_invalid_binary_format();
|
||||
|
|
@ -205,4 +186,4 @@ struct gen_block_invalid_binary_format : public test_chain_unit_base
|
|||
|
||||
private:
|
||||
size_t m_corrupt_blocks_begin_idx;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -965,6 +965,7 @@ bool test_generator::init_test_wallet(const currency::account_base& account, con
|
|||
crc.get_core_time = test_core_time::get_time;
|
||||
crc.pos_minimum_heigh = TESTS_POS_CONFIG_POS_MINIMUM_HEIGH;
|
||||
crc.min_coinstake_age = TESTS_POS_CONFIG_MIN_COINSTAKE_AGE;
|
||||
crc.hard_forks = m_hardforks;
|
||||
|
||||
std::shared_ptr<tools::wallet2> w(new tools::wallet2);
|
||||
w->set_core_runtime_config(crc);
|
||||
|
|
@ -1460,21 +1461,21 @@ bool fill_tx_sources_and_destinations(const std::vector<test_event_entry>& event
|
|||
|
||||
uint64_t inputs_amount = get_inputs_amount(sources);
|
||||
CHECK_AND_ASSERT_MES(inputs_amount >= amount + fee, false, "Pre-condition fail: inputs_amount is less than amount + fee");
|
||||
uint64_t cache_back = inputs_amount - (amount + fee);
|
||||
uint64_t change_amount = inputs_amount - (amount + fee);
|
||||
|
||||
if (b_multisig)
|
||||
{
|
||||
destinations.push_back(tx_destination_entry(amount, to));
|
||||
if (minimum_sigs != SIZE_MAX)
|
||||
destinations.back().minimum_sigs = minimum_sigs; // set custom minimum_sigs only if != SIZE_MAX, use default in tx_destination_entry::ctor() otherwise
|
||||
if (cache_back > 0)
|
||||
destinations.push_back(tx_destination_entry(cache_back, from.account_address));
|
||||
if (change_amount > 0)
|
||||
destinations.push_back(tx_destination_entry(change_amount, from.account_address));
|
||||
}
|
||||
else
|
||||
{
|
||||
tx_destination_entry change_dst = AUTO_VAL_INIT(change_dst);
|
||||
if (cache_back > 0)
|
||||
change_dst = tx_destination_entry(cache_back, from.account_address);
|
||||
if (change_amount > 0)
|
||||
change_dst = tx_destination_entry(change_amount, from.account_address);
|
||||
std::vector<tx_destination_entry> dsts(1, tx_destination_entry(amount, to.back()));
|
||||
uint64_t dust = 0;
|
||||
const test_gentime_settings& tgs = test_generator::get_test_gentime_settings();
|
||||
|
|
@ -1491,13 +1492,19 @@ bool fill_tx_sources_and_destinations(const std::vector<test_event_entry>& event
|
|||
break;
|
||||
case tests_random_split_strategy:
|
||||
{
|
||||
size_t outs_count = cache_back > 0 ? 2 : 1;
|
||||
size_t outs_count = change_amount > 0 ? 2 : 1;
|
||||
if (outs_count < tgs.rss_min_number_of_outputs)
|
||||
{
|
||||
// decompose both target and cache back amounts
|
||||
// decompose both target and change amounts
|
||||
// TODO: support tgs.tx_max_out_amount
|
||||
decompose_amount_randomly(amount, [&](uint64_t a){ destinations.emplace_back(a, to.back()); }, tgs.rss_min_number_of_outputs, tgs.rss_num_digits_to_keep);
|
||||
decompose_amount_randomly(cache_back, [&](uint64_t a){ destinations.emplace_back(a, from.account_address); }, tgs.rss_min_number_of_outputs, tgs.rss_num_digits_to_keep);
|
||||
decompose_amount_randomly(amount, [&](uint64_t a){ destinations.emplace_back(a, to.back()); }, tgs.rss_min_number_of_outputs, tgs.rss_num_digits_to_keep);
|
||||
decompose_amount_randomly(change_amount, [&](uint64_t a){ destinations.emplace_back(a, from.account_address); }, tgs.rss_min_number_of_outputs, tgs.rss_num_digits_to_keep);
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(change_amount > 0, false, "internal error: change_amount is zero");
|
||||
destinations = dsts;
|
||||
destinations.push_back(change_dst);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ VARIANT_TAG(binary_archive, core_hardforks_config, 0xd2);
|
|||
typedef boost::variant<currency::block, currency::transaction, currency::account_base, callback_entry, serialized_block, serialized_transaction, event_visitor_settings, event_special_block, event_core_time, core_hardforks_config> test_event_entry;
|
||||
typedef std::unordered_map<crypto::hash, const currency::transaction*> map_hash2tx_t;
|
||||
|
||||
enum test_tx_split_strategy { tests_void_split_strategy, tests_null_split_strategy, tests_digits_split_strategy, tests_random_split_strategy };
|
||||
enum test_tx_split_strategy { tests_default_split_strategy /*height-based, TODO*/, tests_void_split_strategy, tests_null_split_strategy, tests_digits_split_strategy, tests_random_split_strategy };
|
||||
struct test_gentime_settings
|
||||
{
|
||||
test_tx_split_strategy split_strategy = tests_digits_split_strategy;
|
||||
|
|
@ -255,11 +255,14 @@ public:
|
|||
void set_core_proxy(std::shared_ptr<tools::i_core_proxy>) { /* do nothing */ }
|
||||
uint64_t get_tx_version_from_events(const std::vector<test_event_entry> &events) const;
|
||||
|
||||
virtual void on_test_constructed() {} // called right after test class is constructed by the chaingen
|
||||
void on_test_generator_created(test_generator& generator) const; // tests can override this for special initialization
|
||||
|
||||
currency::core_runtime_config get_runtime_info_for_core() const; // tests can override this for special initialization
|
||||
|
||||
void set_hardforks_for_old_tests();
|
||||
currency::hard_forks_descriptor& get_hardforks() { return m_hardforks; }
|
||||
const currency::hard_forks_descriptor& get_hardforks() const { return m_hardforks; }
|
||||
|
||||
private:
|
||||
callbacks_map m_callbacks;
|
||||
|
|
|
|||
|
|
@ -310,8 +310,8 @@ inline bool put_alias_via_tx_to_list(const currency::hard_forks_descriptor& hf,
|
|||
uint64_t burnt_amount = 0;
|
||||
if (!check_native_coins_amount_burnt_in_outs(tx_set.back(), alias_reward, &burnt_amount))
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(false, false, "alias reward was not found, expected: " << print_money_brief(alias_reward)
|
||||
<< "; burnt: " << (tx_set.back().version <= TRANSACTION_VERSION_PRE_HF4 ? print_money_brief(burnt_amount) : "hidden") << "; tx: " << get_transaction_hash(tx_set.back()));
|
||||
CHECK_AND_ASSERT_MES(false, false, "alias reward was not found, expected: " << currency::print_money_brief(alias_reward)
|
||||
<< "; burnt: " << (tx_set.back().version <= TRANSACTION_VERSION_PRE_HF4 ? currency::print_money_brief(burnt_amount) : "hidden") << "; tx: " << get_transaction_hash(tx_set.back()));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ namespace
|
|||
test_generator::set_test_gentime_settings_default(); \
|
||||
std::vector<test_event_entry> events; \
|
||||
genclass g; \
|
||||
g.on_test_constructed(); \
|
||||
g.generate(events); \
|
||||
if (!tools::serialize_obj_to_file(events, filename)) \
|
||||
{ \
|
||||
|
|
@ -54,6 +55,95 @@ namespace
|
|||
return 1; \
|
||||
}
|
||||
|
||||
|
||||
std::vector<size_t> parse_hardfork_str_mask(std::string s /* intentionally passing by value */)
|
||||
{
|
||||
// "*" -> 0, 1, 2, ..., ZANO_HARDFORKS_TOTAL-1
|
||||
// "2-4,0" -> 2, 3, 4, 0
|
||||
// "1, 3-*" -> 1, 3, 4, ..., ZANO_HARDFORKS_TOTAL-1
|
||||
|
||||
std::vector<size_t> result;
|
||||
|
||||
auto error_result = []() -> std::vector<size_t> { return std::vector<size_t>(); };
|
||||
auto all_hardforks = []() -> std::vector<size_t> { std::vector<size_t> r; for(size_t i = 0; i < ZANO_HARDFORKS_TOTAL; ++i) r.push_back(i); return r; };
|
||||
|
||||
// remove all spaces
|
||||
s.erase(std::remove_if(s.begin(), s.end(), [](char c){ return std::isspace(static_cast<unsigned char>(c)); }), s.end());
|
||||
std::vector<std::string> ranges;
|
||||
boost::split(ranges, s, boost::is_any_of(","));
|
||||
for(auto& range : ranges)
|
||||
{
|
||||
std::vector<std::string> segments;
|
||||
boost::split(segments, range, boost::is_any_of("-"));
|
||||
if (segments.size() == 1)
|
||||
{
|
||||
if (segments.front() == "*")
|
||||
return all_hardforks();
|
||||
size_t hfid = SIZE_MAX;
|
||||
if (!epee::string_tools::string_to_num_fast(segments.front(), (int64_t&)hfid) || hfid == SIZE_MAX || hfid >= ZANO_HARDFORKS_TOTAL)
|
||||
return error_result();
|
||||
result.push_back(hfid);
|
||||
}
|
||||
else if (segments.size() == 2)
|
||||
{
|
||||
if (segments.front() == "*")
|
||||
return all_hardforks();
|
||||
|
||||
size_t hfid_a = SIZE_MAX;
|
||||
if (!epee::string_tools::string_to_num_fast(segments.front(), (int64_t&)hfid_a) || hfid_a == SIZE_MAX || hfid_a >= ZANO_HARDFORKS_TOTAL)
|
||||
return error_result();
|
||||
|
||||
size_t hfid_b = SIZE_MAX;
|
||||
if (segments.back() == "*")
|
||||
hfid_b = ZANO_HARDFORKS_TOTAL - 1;
|
||||
else
|
||||
{
|
||||
if (!epee::string_tools::string_to_num_fast(segments.back(), (int64_t&)hfid_b))
|
||||
hfid_b = SIZE_MAX;
|
||||
}
|
||||
if (hfid_b == SIZE_MAX || hfid_b >= ZANO_HARDFORKS_TOTAL || hfid_b < hfid_a)
|
||||
return error_result();
|
||||
for(size_t i = hfid_a; i <= hfid_b; ++i)
|
||||
result.push_back(i);
|
||||
if (segments.back() == "*")
|
||||
return result; // don't keep parsing if the last range was ?-*
|
||||
}
|
||||
else // i.e. segments.size() == 0 || segments.size() > 2
|
||||
return error_result();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool test_parse_hardfork_str_mask()
|
||||
{
|
||||
static_assert(ZANO_HARDFORKS_TOTAL >= 5, "this test was made in assumption that this condition holds");
|
||||
auto v_range = [](size_t a, size_t b) -> std::vector<size_t> { std::vector<size_t> r; for(size_t i = a; i <= b; ++i) r.push_back(i); return r; };
|
||||
auto v_concat = [](const std::vector<size_t>& a, const std::vector<size_t>& b) -> std::vector<size_t> { std::vector<size_t> r = a; r.insert(r.end(), b.begin(), b.end()); };
|
||||
const std::vector<size_t> res_empty;
|
||||
const std::vector<size_t> res_all_hf = v_range(0, ZANO_HARDFORKS_TOTAL - 1);
|
||||
std::string hf_total_num_str_m_1 = epee::string_tools::num_to_string_fast(ZANO_HARDFORKS_TOTAL - 1);
|
||||
std::string hf_total_num_str = epee::string_tools::num_to_string_fast(ZANO_HARDFORKS_TOTAL);
|
||||
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask("") == res_empty, false, "");
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask("*") == res_all_hf, false, "");
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask("1,2") == v_range(1, 2), false, "");
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask("0,*, 3") == res_all_hf, false, "");
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask("1-4") == v_range(1, 4), false, "");
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask("4-1") == res_empty, false, "");
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask("3-1,2") == res_empty, false, "");
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask("1,2-1") == res_empty, false, "");
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask("0, 2 - 2") == std::vector<size_t>({0, 2}), false, "");
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask("2-*") == v_range(2, ZANO_HARDFORKS_TOTAL - 1), false, "");
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask(" 2-*, 1") == v_range(2, ZANO_HARDFORKS_TOTAL - 1), false, "");
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask("2- *,3") == v_range(2, ZANO_HARDFORKS_TOTAL - 1), false, "");
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask("1,3,2") == std::vector<size_t>({1, 3, 2}), false, "");
|
||||
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask(hf_total_num_str_m_1) == std::vector<size_t>({ZANO_HARDFORKS_TOTAL - 1}), false, "");
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask(hf_total_num_str) == res_empty, false, "");
|
||||
CHECK_AND_ASSERT_MES(parse_hardfork_str_mask(std::string("2-") + hf_total_num_str) == res_empty, false, "");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool clean_data_directory()
|
||||
{
|
||||
std::string config_folder = command_line::get_arg(g_vm, command_line::arg_data_dir);
|
||||
|
|
@ -102,7 +192,7 @@ bool clean_data_directory()
|
|||
}
|
||||
|
||||
template<class genclass>
|
||||
bool generate_and_play(const char* const genclass_name)
|
||||
bool generate_and_play(const char* const genclass_name, size_t hardfork_id = SIZE_MAX)
|
||||
{
|
||||
std::vector<test_event_entry> events;
|
||||
bool generated = false;
|
||||
|
|
@ -117,11 +207,37 @@ bool generate_and_play(const char* const genclass_name)
|
|||
test_core_time::init();
|
||||
test_generator::set_test_gentime_settings_default();
|
||||
genclass g;
|
||||
|
||||
static const test_chain_unit_base tcub;
|
||||
bool has_non_default_hardforks = g.get_hardforks() != tcub.get_hardforks(); // compare with the defaults
|
||||
currency::hard_forks_descriptor hfd_local{};
|
||||
if (hardfork_id != SIZE_MAX)
|
||||
{
|
||||
static test_chain_unit_base tcub;
|
||||
if (has_non_default_hardforks) // compare with the defaults
|
||||
{
|
||||
LOG_ERROR(ENDL << "hardforks setting have been changed in ctor of " << genclass_name << " test" << ENDL << ENDL);
|
||||
return false;
|
||||
}
|
||||
g.get_hardforks().clear();
|
||||
g.get_hardforks().set_hardfork_height(hardfork_id, 1 /* <- height_the_hardfork_is_active_after */);
|
||||
}
|
||||
hfd_local = g.get_hardforks(); // save a copy for the safety checking at the end
|
||||
|
||||
g.on_test_constructed();
|
||||
|
||||
try
|
||||
{
|
||||
generated = g.generate(events);
|
||||
if (generated)
|
||||
{
|
||||
std::cout << concolor::normal << events.size() << " events generated successfully" << std::endl;
|
||||
if (has_non_default_hardforks || g.get_hardforks() != tcub.get_hardforks())
|
||||
{
|
||||
size_t configure_core_events_count = std::count_if(events.begin(), events.end(), [](auto& ev){ return ev.type() == typeid(callback_entry) && boost::get<callback_entry>(ev).callback_name == "configure_core"; });
|
||||
CHECK_AND_ASSERT_THROW_MES(configure_core_events_count != 0, "Test " << genclass_name << " has non-default hardfork settings and therefore must use 'configure_core' callback");
|
||||
}
|
||||
|
||||
std::cout << concolor::bright_white << std::string(100, '=') << std::endl <<
|
||||
"#TEST# >>>> " << genclass_name << " <<<< start replaying events" << std::endl <<
|
||||
std::string(100, '=') << concolor::normal << std::endl;
|
||||
|
|
@ -131,11 +247,18 @@ bool generate_and_play(const char* const genclass_name)
|
|||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
LOG_ERROR("got an exception during " << genclass_name << (generated ? " replaying: " : " generation: ") << ex.what());
|
||||
LOG_ERROR(">>>>> got an exception during " << genclass_name << (generated ? " replaying: " : " generation: ") << ex.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_ERROR("got an unknown exception during " << genclass_name << (generated ? " replaying" : " generation"));
|
||||
LOG_ERROR(">>>>> got an unknown exception during " << genclass_name << (generated ? " replaying" : " generation"));
|
||||
}
|
||||
|
||||
if (hardfork_id != SIZE_MAX && g.get_hardforks() != hfd_local)
|
||||
{
|
||||
// conflict detected: hardfork settings are either controlled by the test itself or by the chaingen
|
||||
LOG_ERROR("hardforks setting have been changed during generation or execution of test " << genclass_name);
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (result)
|
||||
|
|
@ -181,6 +304,7 @@ bool gen_and_play_intermitted_by_blockchain_saveload(const char* const genclass_
|
|||
test_core_time::init();
|
||||
test_generator::set_test_gentime_settings_default();
|
||||
genclass g;
|
||||
g.on_test_constructed();
|
||||
try
|
||||
{
|
||||
r = g.generate(events);
|
||||
|
|
@ -266,6 +390,7 @@ bool gen_and_play_intermitted_by_blockchain_saveload(const char* const genclass_
|
|||
{ \
|
||||
TIME_MEASURE_START_MS(t); \
|
||||
++tests_count; \
|
||||
++unique_tests_count; \
|
||||
if (!generate_and_play<genclass>(#genclass)) \
|
||||
{ \
|
||||
failed_tests.insert(#genclass); \
|
||||
|
|
@ -283,6 +408,7 @@ bool gen_and_play_intermitted_by_blockchain_saveload(const char* const genclass_
|
|||
const char* testname = #genclass " (BC saveload)"; \
|
||||
TIME_MEASURE_START_MS(t); \
|
||||
++tests_count; \
|
||||
++unique_tests_count; \
|
||||
if (!gen_and_play_intermitted_by_blockchain_saveload<genclass>(testname)) \
|
||||
{ \
|
||||
failed_tests.insert(testname); \
|
||||
|
|
@ -294,6 +420,32 @@ bool gen_and_play_intermitted_by_blockchain_saveload(const char* const genclass_
|
|||
tests_running_time.push_back(std::make_pair(testname, t)); \
|
||||
}
|
||||
|
||||
#define GENERATE_AND_PLAY_HF(genclass, hardfork_str_mask) \
|
||||
if((!postponed_tests.count(#genclass) && run_single_test.empty()) || (!run_single_test.empty() && std::string::npos != std::string(#genclass).find(run_single_test))) \
|
||||
{ \
|
||||
std::vector<size_t> hardforks = parse_hardfork_str_mask(hardfork_str_mask); \
|
||||
CHECK_AND_ASSERT_MES(!hardforks.empty(), false, "invalid hardforks mask: " << hardfork_str_mask); \
|
||||
for(size_t hfid : hardforks) \
|
||||
{ \
|
||||
std::string tns = std::string(#genclass) + " @ HF " + epee::string_tools::num_to_string_fast(hfid); \
|
||||
const char* testname = tns.c_str(); \
|
||||
TIME_MEASURE_START_MS(t); \
|
||||
++tests_count; \
|
||||
if (!generate_and_play<genclass>(testname, hfid)) \
|
||||
{ \
|
||||
failed_tests.insert(testname); \
|
||||
LOCAL_ASSERT(false); \
|
||||
if (stop_on_first_fail) \
|
||||
return 1; \
|
||||
} \
|
||||
TIME_MEASURE_FINISH_MS(t); \
|
||||
tests_running_time.push_back(std::make_pair(testname, t)); \
|
||||
} \
|
||||
++unique_tests_count; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
//#define GENERATE_AND_PLAY(genclass) GENERATE_AND_PLAY_INTERMITTED_BY_BLOCKCHAIN_SAVELOAD(genclass)
|
||||
|
||||
|
||||
|
|
@ -738,6 +890,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
size_t tests_count = 0;
|
||||
size_t unique_tests_count = 0;
|
||||
size_t serious_failures_count = 0;
|
||||
std::set<std::string> failed_tests;
|
||||
std::string tests_folder = command_line::get_arg(g_vm, arg_test_data_path);
|
||||
|
|
@ -774,6 +927,7 @@ int main(int argc, char* argv[])
|
|||
CALL_TEST("check_allowed_types_in_variant_container() test", check_allowed_types_in_variant_container_test);
|
||||
CALL_TEST("check_u8_str_case_funcs", check_u8_str_case_funcs);
|
||||
CALL_TEST("chec_u8_str_matching", chec_u8_str_matching);
|
||||
CALL_TEST("test_parse_hardfork_str_mask", test_parse_hardfork_str_mask);
|
||||
}
|
||||
|
||||
//CALL_TEST("check_hash_and_difficulty_monte_carlo_test", check_hash_and_difficulty_monte_carlo_test); // it's rather an experiment with unclean results than a solid test, for further research...
|
||||
|
|
@ -814,7 +968,7 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(multisig_and_unlock_time);
|
||||
GENERATE_AND_PLAY(multisig_and_coinbase);
|
||||
GENERATE_AND_PLAY(multisig_with_same_id_in_pool);
|
||||
GENERATE_AND_PLAY(multisig_and_checkpoints);
|
||||
GENERATE_AND_PLAY_HF(multisig_and_checkpoints, "0"); // TODO: fix for HF 1-3 (checkpoint hash check)
|
||||
GENERATE_AND_PLAY(multisig_and_checkpoints_bad_txs);
|
||||
GENERATE_AND_PLAY(multisig_and_altchains);
|
||||
GENERATE_AND_PLAY(multisig_out_make_and_spent_in_altchain);
|
||||
|
|
@ -874,7 +1028,7 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(gen_checkpoints_pos_validation_on_altchain);
|
||||
GENERATE_AND_PLAY(gen_checkpoints_and_invalid_tx_to_pool);
|
||||
GENERATE_AND_PLAY(gen_checkpoints_set_after_switching_to_altchain);
|
||||
GENERATE_AND_PLAY(gen_no_attchments_in_coinbase);
|
||||
GENERATE_AND_PLAY_HF(gen_no_attchments_in_coinbase, "3");
|
||||
GENERATE_AND_PLAY(gen_no_attchments_in_coinbase_gentime);
|
||||
|
||||
GENERATE_AND_PLAY(gen_alias_tests);
|
||||
|
|
@ -885,10 +1039,10 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(gen_alias_update_after_addr_changed);
|
||||
GENERATE_AND_PLAY(gen_alias_blocking_reg_by_invalid_tx);
|
||||
GENERATE_AND_PLAY(gen_alias_blocking_update_by_invalid_tx);
|
||||
GENERATE_AND_PLAY(gen_alias_reg_with_locked_money);
|
||||
GENERATE_AND_PLAY_HF(gen_alias_reg_with_locked_money, "*");
|
||||
GENERATE_AND_PLAY(gen_alias_too_small_reward);
|
||||
GENERATE_AND_PLAY(gen_alias_too_much_reward);
|
||||
GENERATE_AND_PLAY(gen_alias_tx_no_outs);
|
||||
GENERATE_AND_PLAY_HF(gen_alias_tx_no_outs, "*");
|
||||
GENERATE_AND_PLAY(gen_alias_switch_and_check_block_template);
|
||||
GENERATE_AND_PLAY(gen_alias_too_many_regs_in_block_template);
|
||||
GENERATE_AND_PLAY(gen_alias_update_for_free);
|
||||
|
|
@ -898,8 +1052,8 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(gen_wallet_refreshing_on_chain_switch);
|
||||
GENERATE_AND_PLAY(gen_wallet_refreshing_on_chain_switch_2);
|
||||
GENERATE_AND_PLAY(gen_wallet_unconfirmed_tx_from_tx_pool);
|
||||
GENERATE_AND_PLAY(gen_wallet_save_load_and_balance);
|
||||
GENERATE_AND_PLAY(gen_wallet_mine_pos_block);
|
||||
GENERATE_AND_PLAY_HF(gen_wallet_save_load_and_balance, "*");
|
||||
GENERATE_AND_PLAY_HF(gen_wallet_mine_pos_block, "3");
|
||||
GENERATE_AND_PLAY(gen_wallet_unconfirmed_outdated_tx);
|
||||
GENERATE_AND_PLAY(gen_wallet_unlock_by_block_and_by_time);
|
||||
GENERATE_AND_PLAY(gen_wallet_payment_id);
|
||||
|
|
@ -922,7 +1076,7 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(wallet_outputs_with_same_key_image);
|
||||
GENERATE_AND_PLAY(wallet_unconfirmed_tx_expiration);
|
||||
GENERATE_AND_PLAY(wallet_unconfimed_tx_balance);
|
||||
GENERATE_AND_PLAY(packing_outputs_on_pos_minting_wallet);
|
||||
GENERATE_AND_PLAY_HF(packing_outputs_on_pos_minting_wallet, "3");
|
||||
GENERATE_AND_PLAY(wallet_watch_only_and_chain_switch);
|
||||
|
||||
GENERATE_AND_PLAY(wallet_rpc_integrated_address);
|
||||
|
|
@ -985,30 +1139,30 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(random_outs_and_burnt_coins);
|
||||
|
||||
// Block verification tests
|
||||
GENERATE_AND_PLAY(gen_block_big_major_version);
|
||||
GENERATE_AND_PLAY(gen_block_big_minor_version);
|
||||
GENERATE_AND_PLAY(gen_block_ts_not_checked);
|
||||
GENERATE_AND_PLAY(gen_block_ts_in_past);
|
||||
GENERATE_AND_PLAY(gen_block_ts_in_future);
|
||||
//GENERATE_AND_PLAY(gen_block_invalid_prev_id); disabled becouse impossible to generate text chain with wrong prev_id - pow hash not works without chaining
|
||||
GENERATE_AND_PLAY(gen_block_invalid_nonce);
|
||||
GENERATE_AND_PLAY(gen_block_no_miner_tx);
|
||||
GENERATE_AND_PLAY(gen_block_unlock_time_is_low);
|
||||
GENERATE_AND_PLAY(gen_block_unlock_time_is_high);
|
||||
GENERATE_AND_PLAY(gen_block_unlock_time_is_timestamp_in_past);
|
||||
GENERATE_AND_PLAY(gen_block_unlock_time_is_timestamp_in_future);
|
||||
GENERATE_AND_PLAY(gen_block_height_is_low);
|
||||
GENERATE_AND_PLAY(gen_block_height_is_high);
|
||||
GENERATE_AND_PLAY(gen_block_miner_tx_has_2_tx_gen_in);
|
||||
GENERATE_AND_PLAY(gen_block_miner_tx_has_2_in);
|
||||
GENERATE_AND_PLAY(gen_block_miner_tx_with_txin_to_key);
|
||||
GENERATE_AND_PLAY(gen_block_miner_tx_out_is_small);
|
||||
GENERATE_AND_PLAY(gen_block_miner_tx_out_is_big);
|
||||
GENERATE_AND_PLAY(gen_block_miner_tx_has_no_out);
|
||||
GENERATE_AND_PLAY(gen_block_miner_tx_has_out_to_alice);
|
||||
GENERATE_AND_PLAY(gen_block_has_invalid_tx);
|
||||
GENERATE_AND_PLAY(gen_block_is_too_big);
|
||||
GENERATE_AND_PLAY(gen_block_wrong_version_agains_hardfork);
|
||||
GENERATE_AND_PLAY_HF(gen_block_big_major_version, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_big_minor_version, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_ts_not_checked, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_ts_in_past, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_ts_in_future, "0,3");
|
||||
//GENERATE_AND_PLAY(gen_block_invalid_prev_id); disabled because impossible to generate text chain with wrong prev_id - pow hash not works without chaining
|
||||
GENERATE_AND_PLAY_HF(gen_block_invalid_nonce, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_no_miner_tx, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_unlock_time_is_low, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_unlock_time_is_high, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_unlock_time_is_timestamp_in_past, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_unlock_time_is_timestamp_in_future, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_height_is_low, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_height_is_high, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_miner_tx_has_2_tx_gen_in, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_miner_tx_has_2_in, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_miner_tx_with_txin_to_key, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_miner_tx_out_is_small, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_miner_tx_out_is_big, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_miner_tx_has_no_out, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_miner_tx_has_out_to_alice, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_has_invalid_tx, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_is_too_big, "0,3");
|
||||
GENERATE_AND_PLAY_HF(gen_block_wrong_version_agains_hardfork, "0,3");
|
||||
//GENERATE_AND_PLAY(gen_block_invalid_binary_format); // Takes up to 3 hours, if CURRENCY_MINED_MONEY_UNLOCK_WINDOW == 500, up to 30 minutes, if CURRENCY_MINED_MONEY_UNLOCK_WINDOW == 10
|
||||
|
||||
|
||||
|
|
@ -1093,13 +1247,16 @@ int main(int argc, char* argv[])
|
|||
|
||||
GENERATE_AND_PLAY(zarcanum_basic_test);
|
||||
|
||||
GENERATE_AND_PLAY(multiassets_basic_test);
|
||||
GENERATE_AND_PLAY_HF(multiassets_basic_test, "4-*");
|
||||
GENERATE_AND_PLAY(ionic_swap_basic_test);
|
||||
GENERATE_AND_PLAY(zarcanum_test_n_inputs_validation);
|
||||
GENERATE_AND_PLAY(zarcanum_gen_time_balance);
|
||||
GENERATE_AND_PLAY(zarcanum_txs_with_big_shuffled_decoy_set_shuffled);
|
||||
GENERATE_AND_PLAY(zarcanum_pos_block_math);
|
||||
GENERATE_AND_PLAY(zarcanum_in_alt_chain);
|
||||
GENERATE_AND_PLAY(assets_and_explicit_native_coins_in_outs);
|
||||
GENERATE_AND_PLAY(zarcanum_block_with_txs);
|
||||
|
||||
|
||||
// GENERATE_AND_PLAY(gen_block_reward);
|
||||
// END OF TESTS */
|
||||
|
|
@ -1134,10 +1291,12 @@ int main(int argc, char* argv[])
|
|||
|
||||
std::cout << (serious_failures_count == 0 ? concolor::green : concolor::magenta);
|
||||
std::cout << "\nREPORT:\n";
|
||||
std::cout << " Test run: " << tests_count << std::endl;
|
||||
std::cout << " Failures: " << serious_failures_count << " (postponed failures: " << failed_postponed_tests_count << ")" << std::endl;
|
||||
std::cout << " Postponed: " << postponed_tests.size() << std::endl;
|
||||
std::cout << " Total time: " << total_time / 1000 << " s. (" << (tests_count > 0 ? total_time / tests_count : 0) << " ms per test in average)" << std::endl;
|
||||
std::cout << " Unique tests run: " << unique_tests_count << std::endl;
|
||||
std::cout << " Total tests run: " << tests_count << std::endl;
|
||||
|
||||
std::cout << " Failures: " << serious_failures_count << " (postponed failures: " << failed_postponed_tests_count << ")" << std::endl;
|
||||
std::cout << " Postponed: " << postponed_tests.size() << std::endl;
|
||||
std::cout << " Total time: " << total_time / 1000 << " s. (" << (tests_count > 0 ? total_time / tests_count : 0) << " ms per test in average)" << std::endl;
|
||||
if (!failed_tests.empty())
|
||||
{
|
||||
std::cout << "FAILED/POSTPONED TESTS:\n";
|
||||
|
|
|
|||
|
|
@ -669,11 +669,6 @@ bool gen_checkpoints_pos_validation_on_altchain::init_runtime_config(currency::c
|
|||
|
||||
gen_no_attchments_in_coinbase::gen_no_attchments_in_coinbase()
|
||||
{
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[1] = 1440;
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[2] = 1800;
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[3] = 1801;
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[4] = 50000000000;
|
||||
generator.set_hardforks(m_hardforks);
|
||||
// NOTE: This test is made deterministic to be able to correctly set up checkpoint.
|
||||
random_state_test_restorer::reset_random(); // random generator's state was previously stored, will be restore on dtor (see also m_random_state_test_restorer)
|
||||
|
||||
|
|
@ -692,6 +687,7 @@ bool gen_no_attchments_in_coinbase::generate(std::vector<test_event_entry>& even
|
|||
block blk_0 = AUTO_VAL_INIT(blk_0);
|
||||
generator.construct_genesis_block(blk_0, m_miner_acc, ts);
|
||||
events.push_back(blk_0);
|
||||
DO_CALLBACK(events, "configure_core");
|
||||
|
||||
DO_CALLBACK(events, "check_not_being_in_cp_zone");
|
||||
DO_CALLBACK(events, "init_config_set_cp");
|
||||
|
|
@ -708,7 +704,7 @@ bool gen_no_attchments_in_coinbase::init_config_set_cp(currency::core& c, size_t
|
|||
crc.pos_minimum_heigh = 1;
|
||||
c.get_blockchain_storage().set_core_runtime_config(crc);
|
||||
|
||||
m_checkpoints.add_checkpoint(12, "2a6e13df811eccce121c0de4dbdcc640de1d37c8459c2c8ea02af39717779836");
|
||||
m_checkpoints.add_checkpoint(12, "475331fb4a325e722ddbc2d087d32687a58392e5a9314001120de0f2ce7737f2");
|
||||
c.set_checkpoints(currency::checkpoints(m_checkpoints));
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#include "wallet_tests_basic.h"
|
||||
#include "random_helper.h"
|
||||
|
||||
struct hard_fork_2_base_test : virtual public test_chain_unit_enchanced
|
||||
struct hard_fork_2_base_test : public wallet_test
|
||||
{
|
||||
hard_fork_2_base_test(size_t hardfork_02_height);
|
||||
hard_fork_2_base_test(size_t hardfork_01_height, size_t hardfork_02_height);
|
||||
|
|
@ -18,14 +18,14 @@ struct hard_fork_2_base_test : virtual public test_chain_unit_enchanced
|
|||
size_t m_hardfork_03_height;
|
||||
};
|
||||
|
||||
struct hard_fork_2_tx_payer_in_wallet : public wallet_test, public hard_fork_2_base_test
|
||||
struct hard_fork_2_tx_payer_in_wallet : public hard_fork_2_base_test
|
||||
{
|
||||
hard_fork_2_tx_payer_in_wallet();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
};
|
||||
|
||||
struct hard_fork_2_tx_receiver_in_wallet : public wallet_test, public hard_fork_2_base_test
|
||||
struct hard_fork_2_tx_receiver_in_wallet : public hard_fork_2_base_test
|
||||
{
|
||||
hard_fork_2_tx_receiver_in_wallet();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
|
|
@ -34,21 +34,21 @@ struct hard_fork_2_tx_receiver_in_wallet : public wallet_test, public hard_fork_
|
|||
mutable uint64_t m_alice_start_balance;
|
||||
};
|
||||
|
||||
struct hard_fork_2_tx_extra_alias_entry_in_wallet : public wallet_test, public hard_fork_2_base_test
|
||||
struct hard_fork_2_tx_extra_alias_entry_in_wallet : public hard_fork_2_base_test
|
||||
{
|
||||
hard_fork_2_tx_extra_alias_entry_in_wallet();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
};
|
||||
|
||||
struct hard_fork_2_auditable_addresses_basics : public wallet_test, public hard_fork_2_base_test
|
||||
struct hard_fork_2_auditable_addresses_basics : public hard_fork_2_base_test
|
||||
{
|
||||
hard_fork_2_auditable_addresses_basics();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
};
|
||||
|
||||
struct hard_fork_2_no_new_structures_before_hf : public wallet_test, public hard_fork_2_base_test
|
||||
struct hard_fork_2_no_new_structures_before_hf : public hard_fork_2_base_test
|
||||
{
|
||||
using hard_fork_2_base_test::check_block_verification_context; // this is necessary for correct work of do_check_block_verification_context, consider rafactoring
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ struct hard_fork_2_no_new_structures_before_hf : public wallet_test, public hard
|
|||
};
|
||||
|
||||
template<bool before_hf_2>
|
||||
struct hard_fork_2_awo_wallets_basic_test : public wallet_test, public hard_fork_2_base_test
|
||||
struct hard_fork_2_awo_wallets_basic_test : public hard_fork_2_base_test
|
||||
{
|
||||
hard_fork_2_awo_wallets_basic_test();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
|
|
@ -66,7 +66,7 @@ struct hard_fork_2_awo_wallets_basic_test : public wallet_test, public hard_fork
|
|||
};
|
||||
|
||||
template<bool before_hf_2>
|
||||
struct hard_fork_2_alias_update_using_old_tx : public wallet_test, public hard_fork_2_base_test
|
||||
struct hard_fork_2_alias_update_using_old_tx : public hard_fork_2_base_test
|
||||
{
|
||||
hard_fork_2_alias_update_using_old_tx();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
|
|
@ -76,7 +76,7 @@ struct hard_fork_2_alias_update_using_old_tx : public wallet_test, public hard_f
|
|||
};
|
||||
|
||||
template<bool before_hf_2>
|
||||
struct hard_fork_2_incorrect_alias_update : public wallet_test, public hard_fork_2_base_test
|
||||
struct hard_fork_2_incorrect_alias_update : public hard_fork_2_base_test
|
||||
{
|
||||
hard_fork_2_incorrect_alias_update();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2014-2018 Zano Project
|
||||
// Copyright (c) 2014-2023 Zano Project
|
||||
// Copyright (c) 2014-2018 The Louisdor Project
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
|
@ -9,15 +9,14 @@
|
|||
|
||||
#include "random_helper.h"
|
||||
|
||||
#define AMOUNT_TO_TRANSFER_MULTIASSETS_BASIC (TESTS_DEFAULT_FEE)
|
||||
using namespace currency;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#define AMOUNT_TO_TRANSFER_MULTIASSETS_BASIC (TESTS_DEFAULT_FEE)
|
||||
#define AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC 500000000000000000
|
||||
|
||||
|
||||
|
||||
using namespace currency;
|
||||
uint64_t multiassets_basic_test::ts_starter = 0;
|
||||
//------------------------------------------------------------------------------
|
||||
multiassets_basic_test::multiassets_basic_test()
|
||||
{
|
||||
// TODO: remove the following line
|
||||
|
|
@ -25,10 +24,7 @@ multiassets_basic_test::multiassets_basic_test()
|
|||
LOG_PRINT_MAGENTA("STARTER TS: " << ts_starter, LOG_LEVEL_0);
|
||||
random_state_test_restorer::reset_random(ts_starter);
|
||||
|
||||
REGISTER_CALLBACK_METHOD(multiassets_basic_test, configure_core);
|
||||
REGISTER_CALLBACK_METHOD(multiassets_basic_test, c1);
|
||||
|
||||
m_hardforks.set_hardfork_height(ZANO_HARDFORK_04_ZARCANUM, 1);
|
||||
}
|
||||
|
||||
bool multiassets_basic_test::generate(std::vector<test_event_entry>& events) const
|
||||
|
|
@ -40,7 +36,6 @@ bool multiassets_basic_test::generate(std::vector<test_event_entry>& events) con
|
|||
uint64_t ts = 145000000;
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts);
|
||||
DO_CALLBACK(events, "configure_core"); // default configure_core callback will initialize core runtime config with m_hardforks
|
||||
set_hard_fork_heights_to_generator(generator);
|
||||
//TODO: Need to make sure REWIND_BLOCKS_N and other coretests codebase are capable of following hardfork4 rules
|
||||
//in this test hardfork4 moment moved to runtime section
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3);
|
||||
|
|
@ -141,5 +136,199 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v
|
|||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
assets_and_explicit_native_coins_in_outs::assets_and_explicit_native_coins_in_outs()
|
||||
{
|
||||
REGISTER_CALLBACK_METHOD(assets_and_explicit_native_coins_in_outs, c1_alice_cannot_deploy_asset);
|
||||
REGISTER_CALLBACK_METHOD(assets_and_explicit_native_coins_in_outs, c2_alice_deploys_asset);
|
||||
|
||||
m_hardforks.clear();
|
||||
m_hardforks.set_hardfork_height(ZANO_HARDFORK_04_ZARCANUM, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1);
|
||||
}
|
||||
|
||||
bool assets_and_explicit_native_coins_in_outs::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
/* Test idea:
|
||||
* 1) make sure an asset cannot be deployed if there's no ZC outputs available;
|
||||
* 2) make sure an asset emission transaction has hidden asset ids in all outputs;
|
||||
* 3) (NOT DONE YET) make sure tx with at least one input with at least one reference to non-explicit native asset id has non-explicit asset ids in outs (TODO: move to separate test)
|
||||
*/
|
||||
|
||||
bool r = false;
|
||||
|
||||
uint64_t ts = test_core_time::get_time();
|
||||
m_accounts.resize(TOTAL_ACCS_COUNT);
|
||||
account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts);
|
||||
account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts);
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts);
|
||||
DO_CALLBACK(events, "configure_core"); // necessary to set m_hardforks
|
||||
|
||||
// HF4 requires tests_random_split_strategy (for 2 outputs minimum)
|
||||
test_gentime_settings tgts = generator.get_test_gentime_settings();
|
||||
tgts.split_strategy = tests_random_split_strategy;
|
||||
generator.set_test_gentime_settings(tgts);
|
||||
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
DO_CALLBACK_PARAMS(events, "check_hardfork_inactive", static_cast<size_t>(ZANO_HARDFORK_04_ZARCANUM));
|
||||
|
||||
// tx_0: miner -> Alice
|
||||
// make tx_0 before HF4, so Alice will have only bare outs
|
||||
m_alice_initial_balance = MK_TEST_COINS(1000) + TESTS_DEFAULT_FEE;
|
||||
transaction tx_0{};
|
||||
std::vector<tx_source_entry> sources;
|
||||
std::vector<tx_destination_entry> destinations;
|
||||
r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc, alice_acc, m_alice_initial_balance, TESTS_DEFAULT_FEE, 0, sources, destinations, true /* spends */, false /* unlock time */);
|
||||
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
|
||||
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0);
|
||||
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
|
||||
|
||||
ADD_CUSTOM_EVENT(events, tx_0);
|
||||
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0);
|
||||
|
||||
// make sure HF4 has been activated
|
||||
DO_CALLBACK_PARAMS(events, "check_hardfork_active", static_cast<size_t>(ZANO_HARDFORK_04_ZARCANUM));
|
||||
|
||||
// rewind blocks
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_1r, blk_1, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
// check Alice's balance and make sure she cannot deploy an asset
|
||||
DO_CALLBACK(events, "c1_alice_cannot_deploy_asset");
|
||||
|
||||
// tx_1: Alice -> Alice (all coins) : this will convert two Alice's outputs to ZC outs (since we're at post-HF4 zone)
|
||||
MAKE_TX(events, tx_1, alice_acc, alice_acc, m_alice_initial_balance - TESTS_DEFAULT_FEE, blk_1r);
|
||||
CHECK_AND_ASSERT_MES(tx_1.vout.size() == 2, false, "unexpected tx_1.vout.size : " << tx_1.vout.size());
|
||||
|
||||
// make sure that all tx_1 outputs have explicit hative coin asset id
|
||||
for(auto& out : tx_1.vout)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(out.type() == typeid(tx_out_zarcanum), false, "invalid out type");
|
||||
const tx_out_zarcanum& out_zc = boost::get<tx_out_zarcanum>(out);
|
||||
CHECK_AND_ASSERT_MES(out_zc.blinded_asset_id == native_coin_asset_id_1div8, false, "tx_1 has non-explicit asset id in outputs");
|
||||
}
|
||||
|
||||
MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1r, miner_acc, tx_1);
|
||||
|
||||
// rewind blocks
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_2r, blk_2, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
// check Alice's balance and make sure she CAN deploy an asset now
|
||||
DO_CALLBACK(events, "c2_alice_deploys_asset");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool assets_and_explicit_native_coins_in_outs::c1_alice_cannot_deploy_asset(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, m_accounts[ALICE_ACC_IDX]);
|
||||
alice_wlt->refresh();
|
||||
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt, "Alice", m_alice_initial_balance, 0, m_alice_initial_balance, 0, 0), false, "");
|
||||
|
||||
asset_descriptor_base adb{};
|
||||
adb.total_max_supply = 10;
|
||||
adb.full_name = "it doesn't matter";
|
||||
adb.ticker = "really";
|
||||
adb.decimal_point = 12;
|
||||
|
||||
std::vector<tx_destination_entry> destinations;
|
||||
destinations.emplace_back(adb.total_max_supply, m_accounts[MINER_ACC_IDX].get_public_address(), null_pkey);
|
||||
|
||||
transaction asset_emission_tx{};
|
||||
crypto::public_key asset_id = null_pkey;
|
||||
bool r = false;
|
||||
try
|
||||
{
|
||||
alice_wlt->deploy_new_asset(adb, destinations, asset_emission_tx, asset_id);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
r = true;
|
||||
}
|
||||
|
||||
CHECK_AND_ASSERT_MES(r, false, "Alice successfully deployed an asset, which is unexpected (she has no ZC outs available)");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool assets_and_explicit_native_coins_in_outs::c2_alice_deploys_asset(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
bool r = false;
|
||||
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, m_accounts[ALICE_ACC_IDX]);
|
||||
alice_wlt->refresh();
|
||||
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt, "Alice", m_alice_initial_balance - TESTS_DEFAULT_FEE, 0, m_alice_initial_balance - TESTS_DEFAULT_FEE, 0, 0), false, "");
|
||||
|
||||
// make sure Alice has two UTXO now
|
||||
tools::wallet2::transfer_container transfers{};
|
||||
alice_wlt->get_transfers(transfers);
|
||||
size_t unspent_transfers = std::count_if(transfers.begin(), transfers.end(), [](const tools::wallet2::transfer_details& tr){ return !tr.is_spent(); });
|
||||
CHECK_AND_ASSERT_MES(unspent_transfers == 2, false, "unexpected number of Alice's unspent transfers: " << unspent_transfers);
|
||||
|
||||
asset_descriptor_base adb{};
|
||||
adb.total_max_supply = 100 * 1000000000000;
|
||||
adb.full_name = "very confidential asset";
|
||||
adb.ticker = "VCA";
|
||||
adb.decimal_point = 12;
|
||||
|
||||
std::vector<tx_destination_entry> destinations;
|
||||
destinations.emplace_back(adb.total_max_supply / 2, m_accounts[MINER_ACC_IDX].get_public_address(), null_pkey);
|
||||
destinations.emplace_back(adb.total_max_supply / 2, m_accounts[MINER_ACC_IDX].get_public_address(), null_pkey);
|
||||
|
||||
transaction asset_emission_tx{};
|
||||
crypto::public_key asset_id = null_pkey;
|
||||
|
||||
alice_wlt->deploy_new_asset(adb, destinations, asset_emission_tx, asset_id);
|
||||
|
||||
|
||||
// make sure the emission tx is correct
|
||||
CHECK_AND_ASSERT_MES(asset_emission_tx.vout.size() > 2, false, "Unexpected vout size: " << asset_emission_tx.vout.size());
|
||||
for(auto& out : asset_emission_tx.vout)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(out.type() == typeid(tx_out_zarcanum), false, "invalid out type");
|
||||
const tx_out_zarcanum& out_zc = boost::get<tx_out_zarcanum>(out);
|
||||
// as soon as this is the asset emmiting transaction, no output has an obvious asset id
|
||||
// make sure it is so
|
||||
CHECK_AND_ASSERT_MES(out_zc.blinded_asset_id != native_coin_asset_id_1div8, false, "One of outputs has explicit native asset id, which is unexpected");
|
||||
}
|
||||
|
||||
// get this tx confirmed
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
// check Alice balance, make sure all native coins are unlocked
|
||||
alice_wlt->refresh();
|
||||
uint64_t alice_balance = m_alice_initial_balance - TESTS_DEFAULT_FEE * 2;
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt, "Alice", alice_balance, 0, alice_balance, 0, 0), false, "");
|
||||
|
||||
// now Alice only has UTXO with non explicit asset id
|
||||
// Transfer all of them back to miner and check asset ids of outputs
|
||||
transaction tx_2{};
|
||||
alice_wlt->transfer(alice_balance - TESTS_DEFAULT_FEE, m_accounts[MINER_ACC_IDX].get_public_address(), tx_2, native_coin_asset_id);
|
||||
|
||||
CHECK_AND_ASSERT_MES(tx_2.vout.size() == 2, false, "unexpected tx_2.vout.size : " << tx_2.vout.size());
|
||||
for(auto& out : tx_2.vout)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(out.type() == typeid(tx_out_zarcanum), false, "invalid out type");
|
||||
const tx_out_zarcanum& out_zc = boost::get<tx_out_zarcanum>(out);
|
||||
CHECK_AND_ASSERT_MES(out_zc.blinded_asset_id != native_coin_asset_id_1div8, false, "One of outputs has explicit native asset id, which is unexpected");
|
||||
}
|
||||
|
||||
// finally, get this tx confirmed
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2014-2018 Zano Project
|
||||
// Copyright (c) 2014-2023 Zano Project
|
||||
// Copyright (c) 2014-2018 The Louisdor Project
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
|
@ -16,3 +16,13 @@ struct multiassets_basic_test : public wallet_test
|
|||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
};
|
||||
|
||||
struct assets_and_explicit_native_coins_in_outs : public wallet_test
|
||||
{
|
||||
assets_and_explicit_native_coins_in_outs();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool c1_alice_cannot_deploy_asset(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
bool c2_alice_deploys_asset(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
|
||||
mutable uint64_t m_alice_initial_balance = 0;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1632,10 +1632,6 @@ multisig_and_checkpoints::multisig_and_checkpoints()
|
|||
{
|
||||
// NOTE: This test is made deterministic to be able to correctly set up checkpoint.
|
||||
random_state_test_restorer::reset_random(); // random generator's state was previously stored, will be restore on dtor (see also m_random_state_test_restorer)
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[1] = 1440;
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[2] = 1800;
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[3] = 1801;
|
||||
m_hardforks.m_height_the_hardfork_n_active_after[4] = 50000000000;
|
||||
REGISTER_CALLBACK_METHOD(multisig_and_checkpoints, set_cp);
|
||||
}
|
||||
|
||||
|
|
@ -1681,6 +1677,7 @@ bool multisig_and_checkpoints::generate(std::vector<test_event_entry>& events) c
|
|||
std::vector<tx_destination_entry> destinations;
|
||||
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, preminer_acc, ts);
|
||||
DO_CALLBACK(events, "configure_core");
|
||||
// set checkpoint
|
||||
DO_CALLBACK(events, "set_cp");
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 2);
|
||||
|
|
|
|||
|
|
@ -432,7 +432,7 @@ bool gen_wallet_unconfirmed_tx_from_tx_pool::generate(std::vector<test_event_ent
|
|||
gen_wallet_save_load_and_balance::gen_wallet_save_load_and_balance()
|
||||
{
|
||||
REGISTER_CALLBACK_METHOD(gen_wallet_save_load_and_balance, c1_check_balance_and_store);
|
||||
REGISTER_CALLBACK_METHOD(gen_wallet_save_load_and_balance, c2_load_refresh_check_balance);
|
||||
REGISTER_CALLBACK_METHOD(gen_wallet_save_load_and_balance, c2);
|
||||
REGISTER_CALLBACK_METHOD(gen_wallet_save_load_and_balance, c3_load_refresh_check_balance);
|
||||
}
|
||||
|
||||
|
|
@ -451,6 +451,8 @@ bool gen_wallet_save_load_and_balance::generate(std::vector<test_event_entry>& e
|
|||
generator.construct_genesis_block(blk_0, miner_acc, test_core_time::get_time());
|
||||
events.push_back(blk_0);
|
||||
|
||||
DO_CALLBACK(events, "configure_core");
|
||||
|
||||
// create gen-time test wallets for accounts
|
||||
CREATE_TEST_WALLET(miner_wlt, miner_acc, blk_0);
|
||||
CREATE_TEST_WALLET(alice_wlt, alice_acc, blk_0);
|
||||
|
|
@ -473,7 +475,7 @@ bool gen_wallet_save_load_and_balance::generate(std::vector<test_event_entry>& e
|
|||
// put the transaction into a block
|
||||
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0);
|
||||
|
||||
// 0 10 11 21 22 <- blockchain height (assuming CURRENCY_MINED_MONEY_UNLOCK_WINDOW == 10)
|
||||
// 0 10 11 21 23 <- blockchain height (assuming CURRENCY_MINED_MONEY_UNLOCK_WINDOW == 10)
|
||||
// (0 )... (0r)- (1 )... (1r)- <- main chain
|
||||
// tx_0 <- txs
|
||||
// \- (2 )...........(2r) <- alt chain
|
||||
|
|
@ -487,12 +489,12 @@ bool gen_wallet_save_load_and_balance::generate(std::vector<test_event_entry>& e
|
|||
if (!check_balance_via_wallet(*alice_wlt.get(), "alice", MK_TEST_COINS(2000), 0, MK_TEST_COINS(2000), 0, 0))
|
||||
return false;
|
||||
|
||||
// load wallet from file and re-chech the balance
|
||||
DO_CALLBACK(events, "c2_load_refresh_check_balance");
|
||||
// load wallet from file, re-chech the balance, store, load again, re-reck again, make tx, make block, check balance, store wallet
|
||||
DO_CALLBACK(events, "c2");
|
||||
|
||||
// switch the chain, reload and re-check the wallet
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_2r, blk_0r, miner_acc, WALLET_DEFAULT_TX_SPENDABLE_AGE + 2);
|
||||
REFRESH_TEST_WALLET_AT_GEN_TIME(events, alice_wlt, blk_2r, WALLET_DEFAULT_TX_SPENDABLE_AGE + 2);
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_2r, blk_0r, miner_acc, WALLET_DEFAULT_TX_SPENDABLE_AGE + 3);
|
||||
REFRESH_TEST_WALLET_AT_GEN_TIME(events, alice_wlt, blk_2r, WALLET_DEFAULT_TX_SPENDABLE_AGE + 3);
|
||||
alice_wlt->scan_tx_pool(has_aliases);
|
||||
if (!check_balance_via_wallet(*alice_wlt.get(), "alice", MK_TEST_COINS(2000), 0, 0, MK_TEST_COINS(2000), 0)) // tx_0 moved to the pool, so its money in "awaiting_in" bucket
|
||||
return false;
|
||||
|
|
@ -513,7 +515,7 @@ bool gen_wallet_save_load_and_balance::c1_check_balance_and_store(currency::core
|
|||
bool has_alias;
|
||||
alice_wlt->scan_tx_pool(has_alias);
|
||||
|
||||
check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", MK_TEST_COINS(2000), 0, 0, MK_TEST_COINS(2000), 0);
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", MK_TEST_COINS(2000), 0, 0, MK_TEST_COINS(2000), 0), false, "");
|
||||
|
||||
alice_wlt->reset_password(g_wallet_password);
|
||||
alice_wlt->store(g_wallet_filename);
|
||||
|
|
@ -521,11 +523,12 @@ bool gen_wallet_save_load_and_balance::c1_check_balance_and_store(currency::core
|
|||
return true;
|
||||
}
|
||||
|
||||
bool gen_wallet_save_load_and_balance::c2_load_refresh_check_balance(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
bool gen_wallet_save_load_and_balance::c2(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
std::shared_ptr<tools::wallet2> alice_wlt(new tools::wallet2);
|
||||
alice_wlt->load(g_wallet_filename, g_wallet_password);
|
||||
alice_wlt->set_core_proxy(m_core_proxy);
|
||||
alice_wlt->set_core_runtime_config(c.get_blockchain_storage().get_core_runtime_config());
|
||||
|
||||
size_t blocks_fetched = 0;
|
||||
bool received_money;
|
||||
|
|
@ -533,7 +536,25 @@ bool gen_wallet_save_load_and_balance::c2_load_refresh_check_balance(currency::c
|
|||
alice_wlt->refresh(blocks_fetched, received_money, atomic_false);
|
||||
CHECK_AND_ASSERT_MES(blocks_fetched == WALLET_DEFAULT_TX_SPENDABLE_AGE + 1, false, "Incorrect numbers of blocks fetched");
|
||||
|
||||
check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", MK_TEST_COINS(2000), 0, MK_TEST_COINS(2000), 0, 0);
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", MK_TEST_COINS(2000), 0, MK_TEST_COINS(2000), 0, 0), false, "");
|
||||
alice_wlt->store(g_wallet_filename);
|
||||
|
||||
////// save - load ////////
|
||||
|
||||
alice_wlt.reset(new tools::wallet2);
|
||||
alice_wlt->load(g_wallet_filename, g_wallet_password);
|
||||
alice_wlt->set_core_proxy(m_core_proxy);
|
||||
alice_wlt->set_core_runtime_config(c.get_blockchain_storage().get_core_runtime_config());
|
||||
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", MK_TEST_COINS(2000), 0, MK_TEST_COINS(2000), 0, 0), false, "");
|
||||
|
||||
alice_wlt->transfer(MK_TEST_COINS(1000) - TESTS_DEFAULT_FEE, m_accounts[MINER_ACC_IDX].get_public_address());
|
||||
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", MK_TEST_COINS(1000), 0, 0, 0, MK_TEST_COINS(1000) - TESTS_DEFAULT_FEE), false, "");
|
||||
|
||||
bool r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Tx pool is not empty: " << c.get_pool_transactions_count());
|
||||
|
||||
alice_wlt->store(g_wallet_filename);
|
||||
|
||||
|
|
@ -545,17 +566,18 @@ bool gen_wallet_save_load_and_balance::c3_load_refresh_check_balance(currency::c
|
|||
std::shared_ptr<tools::wallet2> alice_wlt(new tools::wallet2);
|
||||
alice_wlt->load(g_wallet_filename, g_wallet_password);
|
||||
alice_wlt->set_core_proxy(m_core_proxy);
|
||||
alice_wlt->set_core_runtime_config(c.get_blockchain_storage().get_core_runtime_config());
|
||||
|
||||
size_t blocks_fetched = 0;
|
||||
bool received_money;
|
||||
std::atomic<bool> atomic_false = ATOMIC_VAR_INIT(false);
|
||||
alice_wlt->refresh(blocks_fetched, received_money, atomic_false);
|
||||
CHECK_AND_ASSERT_MES(blocks_fetched == WALLET_DEFAULT_TX_SPENDABLE_AGE + 2, false, "Incorrect numbers of blocks fetched");
|
||||
CHECK_AND_ASSERT_MES(blocks_fetched == WALLET_DEFAULT_TX_SPENDABLE_AGE + 3, false, "Incorrect numbers of blocks fetched");
|
||||
|
||||
bool has_alias;
|
||||
alice_wlt->scan_tx_pool(has_alias);
|
||||
|
||||
check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", MK_TEST_COINS(2000), 0, 0, MK_TEST_COINS(2000), 0);
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", MK_TEST_COINS(3000), 0, 0, MK_TEST_COINS(2000), MK_TEST_COINS(1000) - TESTS_DEFAULT_FEE), false, "");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -565,7 +587,6 @@ bool gen_wallet_save_load_and_balance::c3_load_refresh_check_balance(currency::c
|
|||
gen_wallet_mine_pos_block::gen_wallet_mine_pos_block()
|
||||
{
|
||||
REGISTER_CALLBACK_METHOD(gen_wallet_mine_pos_block, c1);
|
||||
REGISTER_CALLBACK_METHOD(gen_wallet_mine_pos_block, set_core_config);
|
||||
}
|
||||
|
||||
bool gen_wallet_mine_pos_block::generate(std::vector<test_event_entry>& events) const
|
||||
|
|
@ -585,7 +606,7 @@ bool gen_wallet_mine_pos_block::generate(std::vector<test_event_entry>& events)
|
|||
generator.construct_genesis_block(blk_0, miner_acc, test_core_time::get_time());
|
||||
events.push_back(blk_0);
|
||||
|
||||
DO_CALLBACK(events, "set_core_config");
|
||||
DO_CALLBACK(events, "configure_core");
|
||||
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
|
|
@ -598,15 +619,6 @@ bool gen_wallet_mine_pos_block::generate(std::vector<test_event_entry>& events)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool gen_wallet_mine_pos_block::set_core_config(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
core_runtime_config crc = c.get_blockchain_storage().get_core_runtime_config();
|
||||
crc.pos_minimum_heigh = TESTS_POS_CONFIG_POS_MINIMUM_HEIGH;
|
||||
crc.min_coinstake_age = TESTS_POS_CONFIG_MIN_COINSTAKE_AGE;
|
||||
c.get_blockchain_storage().set_core_runtime_config(crc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gen_wallet_mine_pos_block::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX);
|
||||
|
|
@ -616,7 +628,7 @@ bool gen_wallet_mine_pos_block::c1(currency::core& c, size_t ev_index, const std
|
|||
alice_wlt->refresh(blocks_fetched, received_money, atomic_false);
|
||||
CHECK_AND_ASSERT_MES(blocks_fetched == CURRENCY_MINED_MONEY_UNLOCK_WINDOW + WALLET_DEFAULT_TX_SPENDABLE_AGE + 1, false, "Incorrect numbers of blocks fetched");
|
||||
|
||||
check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", MK_TEST_COINS(2000), 0, MK_TEST_COINS(2000), 0, 0);
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", MK_TEST_COINS(2000), 0, MK_TEST_COINS(2000), 0, 0), false, "");
|
||||
|
||||
alice_wlt->try_mint_pos();
|
||||
|
||||
|
|
@ -628,7 +640,7 @@ bool gen_wallet_mine_pos_block::c1(currency::core& c, size_t ev_index, const std
|
|||
bool r = c.get_blockchain_storage().get_top_block(top_block);
|
||||
CHECK_AND_ASSERT_MES(r && is_pos_block(top_block), false, "get_top_block failed or smth goes wrong");
|
||||
uint64_t top_block_reward = get_outs_money_amount(top_block.miner_tx);
|
||||
check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", uint64_max, MK_TEST_COINS(2000) + top_block_reward, 0, 0, 0);
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", top_block_reward, top_block_reward - MK_TEST_COINS(2000), 0, 0, 0), false, "");
|
||||
|
||||
alice_wlt->reset_password(g_wallet_password);
|
||||
alice_wlt->store(g_wallet_filename);
|
||||
|
|
@ -3339,8 +3351,8 @@ bool wallet_unconfimed_tx_balance::c1(currency::core& c, size_t ev_index, const
|
|||
packing_outputs_on_pos_minting_wallet::packing_outputs_on_pos_minting_wallet()
|
||||
{
|
||||
REGISTER_CALLBACK_METHOD(packing_outputs_on_pos_minting_wallet, c1);
|
||||
REGISTER_CALLBACK_METHOD(packing_outputs_on_pos_minting_wallet, set_core_config);
|
||||
}
|
||||
|
||||
bool packing_outputs_on_pos_minting_wallet::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
|
||||
|
|
@ -3358,9 +3370,19 @@ bool packing_outputs_on_pos_minting_wallet::generate(std::vector<test_event_entr
|
|||
generator.construct_genesis_block(blk_0, miner_acc, test_core_time::get_time());
|
||||
events.push_back(blk_0);
|
||||
|
||||
DO_CALLBACK(events, "set_core_config");
|
||||
DO_CALLBACK(events, "configure_core");
|
||||
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW+5);
|
||||
CREATE_TEST_WALLET(miner_wlt, miner_acc, blk_0);
|
||||
REFRESH_TEST_WALLET_AT_GEN_TIME(events, miner_wlt, blk_0, 0);
|
||||
uint64_t unlocked, awaiting_in, awaiting_out, mined;
|
||||
m_premine_amount = miner_wlt->balance(unlocked, awaiting_in, awaiting_out, mined);
|
||||
|
||||
size_t n_blocks = CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5;
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, n_blocks);
|
||||
m_mined_amount = n_blocks * COIN;
|
||||
|
||||
REFRESH_TEST_WALLET_AT_GEN_TIME(events, miner_wlt, blk_0r, n_blocks);
|
||||
CHECK_TEST_WALLET_BALANCE_AT_GEN_TIME(miner_wlt, m_premine_amount + m_mined_amount);
|
||||
|
||||
//MAKE_TX_FEE(events, tx_0, miner_acc, alice_acc, MK_TEST_COINS(2000), TESTS_DEFAULT_FEE, blk_0r);
|
||||
//MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0);
|
||||
|
|
@ -3371,15 +3393,6 @@ bool packing_outputs_on_pos_minting_wallet::generate(std::vector<test_event_entr
|
|||
return true;
|
||||
}
|
||||
|
||||
bool packing_outputs_on_pos_minting_wallet::set_core_config(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
core_runtime_config crc = c.get_blockchain_storage().get_core_runtime_config();
|
||||
crc.pos_minimum_heigh = TESTS_POS_CONFIG_POS_MINIMUM_HEIGH;
|
||||
crc.min_coinstake_age = TESTS_POS_CONFIG_MIN_COINSTAKE_AGE;
|
||||
c.get_blockchain_storage().set_core_runtime_config(crc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool packing_outputs_on_pos_minting_wallet::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
std::shared_ptr<tools::wallet2> miner_wlt = init_playtime_test_wallet(events, c, MINER_ACC_IDX);
|
||||
|
|
@ -3390,7 +3403,7 @@ bool packing_outputs_on_pos_minting_wallet::c1(currency::core& c, size_t ev_inde
|
|||
CHECK_AND_ASSERT_MES(blocks_fetched == CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5, false, "Incorrect numbers of blocks fetched");
|
||||
|
||||
miner_wlt->set_pos_mint_packing_size(4);
|
||||
check_balance_via_wallet(*miner_wlt.get(), "miner_wlt", MK_TEST_COINS(2000), 0, MK_TEST_COINS(2000), 0, 0);
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*miner_wlt.get(), "miner_wlt", m_premine_amount + m_mined_amount, uint64_max, uint64_max, 0, 0), false, "");
|
||||
|
||||
miner_wlt->try_mint_pos();
|
||||
|
||||
|
|
@ -3402,7 +3415,7 @@ bool packing_outputs_on_pos_minting_wallet::c1(currency::core& c, size_t ev_inde
|
|||
bool r = c.get_blockchain_storage().get_top_block(top_block);
|
||||
CHECK_AND_ASSERT_MES(r && is_pos_block(top_block), false, "get_top_block failed or smth goes wrong");
|
||||
uint64_t top_block_reward = get_outs_money_amount(top_block.miner_tx);
|
||||
check_balance_via_wallet(*miner_wlt.get(), "miner_wlt", uint64_max, MK_TEST_COINS(2000) + top_block_reward, 0, 0, 0);
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*miner_wlt.get(), "miner_wlt", m_premine_amount + m_mined_amount + COIN), false, "");
|
||||
|
||||
miner_wlt->reset_password(g_wallet_password);
|
||||
miner_wlt->store(g_wallet_filename);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ struct gen_wallet_save_load_and_balance : public wallet_test
|
|||
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool c1_check_balance_and_store(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
bool c2_load_refresh_check_balance(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
bool c2(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
bool c3_load_refresh_check_balance(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
};
|
||||
|
||||
|
|
@ -44,7 +44,6 @@ struct gen_wallet_mine_pos_block : public wallet_test
|
|||
gen_wallet_mine_pos_block();
|
||||
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool set_core_config(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
bool c2(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
|
|
@ -256,8 +255,10 @@ struct packing_outputs_on_pos_minting_wallet : public wallet_test
|
|||
{
|
||||
packing_outputs_on_pos_minting_wallet();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool set_core_config(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
|
||||
mutable uint64_t m_premine_amount = 0;
|
||||
mutable uint64_t m_mined_amount = 0;
|
||||
};
|
||||
|
||||
struct wallet_sending_to_integrated_address : public wallet_test
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ struct wallet_test : virtual public test_chain_unit_enchanced
|
|||
bool check_balance_via_build_wallets(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
bool check_balance(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
|
||||
void on_test_constructed() override { on_test_generator_created(this->generator); }
|
||||
|
||||
static std::string get_test_account_name_by_id(size_t acc_id);
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@
|
|||
#include "pos_block_builder.h"
|
||||
|
||||
|
||||
#define AMOUNT_TO_TRANSFER_ZARCANUM_BASIC (TESTS_DEFAULT_FEE*10)
|
||||
|
||||
using namespace currency;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
@ -56,6 +54,48 @@ bool invalidate_zarcanum_sig(size_t n, zarcanum_sig& sig)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool make_next_pos_block(test_generator& generator, std::vector<test_event_entry>& events, const block& prev_block, const account_base& stake_acc,
|
||||
uint64_t amount_to_find, size_t nmix, const std::vector<transaction>& transactions, block& result)
|
||||
{
|
||||
bool r = false;
|
||||
std::vector<tx_source_entry> sources;
|
||||
|
||||
size_t height = get_block_height(prev_block) + 1;
|
||||
crypto::hash prev_id = get_block_hash(prev_block);
|
||||
r = fill_tx_sources(sources, events, prev_block, stake_acc.get_keys(), amount_to_find, nmix, true, true, false);
|
||||
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed");
|
||||
CHECK_AND_ASSERT_MES(shuffle_source_entries(sources), false, "");
|
||||
auto it = std::max_element(sources.begin(), sources.end(), [&](const tx_source_entry& lhs, const tx_source_entry& rhs){ return lhs.amount < rhs.amount; });
|
||||
const tx_source_entry& se = *it;
|
||||
const tx_source_entry::output_entry& oe = se.outputs[se.real_output];
|
||||
|
||||
crypto::key_image stake_output_key_image {};
|
||||
currency::keypair ephemeral_keys {};
|
||||
r = generate_key_image_helper(stake_acc.get_keys(), se.real_out_tx_key, se.real_output_in_tx_index, ephemeral_keys, stake_output_key_image);
|
||||
CHECK_AND_ASSERT_MES(r, false, "generate_key_image_helper failed");
|
||||
uint64_t stake_output_gindex = boost::get<uint64_t>(oe.out_reference);
|
||||
|
||||
currency::wide_difficulty_type pos_diff{};
|
||||
crypto::hash last_pow_block_hash{}, last_pos_block_kernel_hash{};
|
||||
r = generator.get_params_for_next_pos_block(prev_id, pos_diff, last_pow_block_hash, last_pos_block_kernel_hash);
|
||||
CHECK_AND_ASSERT_MES(r, false, "get_params_for_next_pos_block failed");
|
||||
|
||||
pos_block_builder pb;
|
||||
pb.step1_init_header(generator.get_hardforks(), height, prev_id);
|
||||
pb.step2_set_txs(transactions);
|
||||
|
||||
pb.step3a(pos_diff, last_pow_block_hash, last_pos_block_kernel_hash);
|
||||
|
||||
pb.step3b(se.amount, stake_output_key_image, se.real_out_tx_key, se.real_output_in_tx_index, se.real_out_amount_blinding_mask, stake_acc.get_keys().view_secret_key,
|
||||
stake_output_gindex, prev_block.timestamp, POS_SCAN_WINDOW, POS_SCAN_STEP);
|
||||
|
||||
pb.step4_generate_coinbase_tx(generator.get_timestamps_median(prev_id), generator.get_already_generated_coins(prev_block), stake_acc.get_public_address());
|
||||
|
||||
pb.step5_sign(se, stake_acc.get_keys());
|
||||
result = pb.m_block;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
|
@ -110,7 +150,7 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect
|
|||
CHECK_AND_FORCE_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool");
|
||||
|
||||
//create transfer from pre-zarcanum inputs to post-zarcanum inputs
|
||||
uint64_t transfer_amount = AMOUNT_TO_TRANSFER_ZARCANUM_BASIC + TESTS_DEFAULT_FEE;
|
||||
uint64_t transfer_amount = TESTS_DEFAULT_FEE*10 + TESTS_DEFAULT_FEE;
|
||||
const size_t batches_to_Alice_count = 4;
|
||||
for(size_t i = 0; i < batches_to_Alice_count; ++i)
|
||||
{
|
||||
|
|
@ -131,7 +171,7 @@ bool zarcanum_basic_test::c1(currency::core& c, size_t ev_index, const std::vect
|
|||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt, "Alice", transfer_amount * batches_to_Alice_count, UINT64_MAX, transfer_amount * batches_to_Alice_count), false, "");
|
||||
|
||||
//create transfer from post-zarcanum inputs to post-zarcanum inputs with mixins
|
||||
uint64_t transfer_amount2 = AMOUNT_TO_TRANSFER_ZARCANUM_BASIC;
|
||||
uint64_t transfer_amount2 = TESTS_DEFAULT_FEE*10;
|
||||
size_t nmix = 10;
|
||||
alice_wlt->transfer(transfer_amount2, nmix, m_accounts[BOB_ACC_IDX].get_public_address());
|
||||
LOG_PRINT_MAGENTA("Zarcanum-2-zarcanum transaction sent from Alice to Bob " << print_money_brief(transfer_amount2), LOG_LEVEL_0);
|
||||
|
|
@ -380,48 +420,6 @@ zarcanum_pos_block_math::zarcanum_pos_block_math()
|
|||
m_hardforks.set_hardfork_height(ZANO_HARDFORK_04_ZARCANUM, 0);
|
||||
}
|
||||
|
||||
bool make_next_pos_block(test_generator& generator, std::vector<test_event_entry>& events, const block& prev_block, const account_base& stake_acc,
|
||||
uint64_t amount_to_find, size_t nmix, block& result)
|
||||
{
|
||||
bool r = false;
|
||||
std::vector<tx_source_entry> sources;
|
||||
|
||||
size_t height = get_block_height(prev_block) + 1;
|
||||
crypto::hash prev_id = get_block_hash(prev_block);
|
||||
r = fill_tx_sources(sources, events, prev_block, stake_acc.get_keys(), amount_to_find, nmix, true, true, false);
|
||||
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed");
|
||||
CHECK_AND_ASSERT_MES(shuffle_source_entries(sources), false, "");
|
||||
auto it = std::max_element(sources.begin(), sources.end(), [&](const tx_source_entry& lhs, const tx_source_entry& rhs){ return lhs.amount < rhs.amount; });
|
||||
const tx_source_entry& se = *it;
|
||||
const tx_source_entry::output_entry& oe = se.outputs[se.real_output];
|
||||
|
||||
crypto::key_image stake_output_key_image {};
|
||||
currency::keypair ephemeral_keys {};
|
||||
r = generate_key_image_helper(stake_acc.get_keys(), se.real_out_tx_key, se.real_output_in_tx_index, ephemeral_keys, stake_output_key_image);
|
||||
CHECK_AND_ASSERT_MES(r, false, "generate_key_image_helper failed");
|
||||
uint64_t stake_output_gindex = boost::get<uint64_t>(oe.out_reference);
|
||||
|
||||
currency::wide_difficulty_type pos_diff{};
|
||||
crypto::hash last_pow_block_hash{}, last_pos_block_kernel_hash{};
|
||||
r = generator.get_params_for_next_pos_block(prev_id, pos_diff, last_pow_block_hash, last_pos_block_kernel_hash);
|
||||
CHECK_AND_ASSERT_MES(r, false, "get_params_for_next_pos_block failed");
|
||||
|
||||
pos_block_builder pb;
|
||||
pb.step1_init_header(generator.get_hardforks(), height, prev_id);
|
||||
pb.step2_set_txs(std::vector<transaction>());
|
||||
|
||||
pb.step3a(pos_diff, last_pow_block_hash, last_pos_block_kernel_hash);
|
||||
|
||||
pb.step3b(se.amount, stake_output_key_image, se.real_out_tx_key, se.real_output_in_tx_index, se.real_out_amount_blinding_mask, stake_acc.get_keys().view_secret_key,
|
||||
stake_output_gindex, prev_block.timestamp, POS_SCAN_WINDOW, POS_SCAN_STEP);
|
||||
|
||||
pb.step4_generate_coinbase_tx(generator.get_timestamps_median(prev_id), generator.get_already_generated_coins(prev_block), stake_acc.get_public_address());
|
||||
|
||||
pb.step5_sign(se, stake_acc.get_keys());
|
||||
result = pb.m_block;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool zarcanum_pos_block_math::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
bool r = false;
|
||||
|
|
@ -439,7 +437,7 @@ bool zarcanum_pos_block_math::generate(std::vector<test_event_entry>& events) co
|
|||
for(size_t i = 1; ; ++i)
|
||||
{
|
||||
block blk_1_pos_bad;
|
||||
CHECK_AND_ASSERT_MES(make_next_pos_block(generator, events, blk_1r, miner_acc, COIN, 10, blk_1_pos_bad), false, "");
|
||||
CHECK_AND_ASSERT_MES(make_next_pos_block(generator, events, blk_1r, miner_acc, COIN, 10, std::vector<transaction>(), blk_1_pos_bad), false, "");
|
||||
LOG_PRINT_CYAN("i = " << i, LOG_LEVEL_0);
|
||||
if (!invalidate_zarcanum_sig(i, boost::get<zarcanum_sig>(blk_1_pos_bad.miner_tx.signatures[0])))
|
||||
break;
|
||||
|
|
@ -734,3 +732,90 @@ bool zarcanum_in_alt_chain::c1(currency::core& c, size_t ev_index, const std::ve
|
|||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
zarcanum_block_with_txs::zarcanum_block_with_txs()
|
||||
{
|
||||
REGISTER_CALLBACK_METHOD(zarcanum_block_with_txs, c1);
|
||||
m_hardforks.set_hardfork_height(ZANO_HARDFORK_03, 0);
|
||||
m_hardforks.set_hardfork_height(ZANO_HARDFORK_04_ZARCANUM, 23);
|
||||
}
|
||||
|
||||
bool zarcanum_block_with_txs::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
// Test idea: make sure Zarcanum PoS block can have txs and the sum of fees is correctly added to the block reward
|
||||
|
||||
bool r = false;
|
||||
|
||||
uint64_t ts = test_core_time::get_time();
|
||||
m_accounts.resize(TOTAL_ACCS_COUNT);
|
||||
account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts);
|
||||
account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts);
|
||||
account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc.generate(); bob_acc.set_createtime(ts);
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts);
|
||||
DO_CALLBACK(events, "configure_core"); // necessary to set m_hardforks
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
//
|
||||
// before HF4
|
||||
//
|
||||
DO_CALLBACK_PARAMS(events, "check_hardfork_active", static_cast<size_t>(ZANO_HARDFORK_03));
|
||||
DO_CALLBACK_PARAMS(events, "check_hardfork_inactive", static_cast<size_t>(ZANO_HARDFORK_04_ZARCANUM));
|
||||
|
||||
// transfer few coins to Alice (one UTXO)
|
||||
m_alice_balance = MK_TEST_COINS(100);
|
||||
MAKE_TX(events, tx_0, miner_acc, alice_acc, m_alice_balance, blk_0r);
|
||||
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0);
|
||||
|
||||
// rewind blocks and make sure Alice has received the coins
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_1r, blk_1, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
DO_CALLBACK_PARAMS(events, "check_balance", params_check_balance(ALICE_ACC_IDX, m_alice_balance, m_alice_balance, 0, 0, 0));
|
||||
|
||||
// then miner sends few coins to Bob via a tx with a big fee amount
|
||||
std::list<currency::account_base> alice_stake_sources({ alice_acc });
|
||||
uint64_t fee = MK_TEST_COINS(123);
|
||||
MAKE_TX_FEE(events, tx_1, miner_acc, bob_acc, MK_TEST_COINS(1000), fee, blk_1r);
|
||||
|
||||
// and Alice mines a PoS block with this tx -- so Alice is expected to receive the fee
|
||||
MAKE_NEXT_POS_BLOCK_TX1(events, blk_2, blk_1r, alice_acc, alice_stake_sources, tx_1);
|
||||
|
||||
// make sure Alice received both block reward and the fee
|
||||
uint64_t mined_amount = COIN + fee;
|
||||
DO_CALLBACK_PARAMS(events, "check_balance", params_check_balance(ALICE_ACC_IDX, m_alice_balance + mined_amount, 0, mined_amount, 0, 0));
|
||||
m_alice_balance += mined_amount;
|
||||
|
||||
//
|
||||
// after HF4
|
||||
//
|
||||
MAKE_NEXT_BLOCK(events, blk_3, blk_2, miner_acc);
|
||||
DO_CALLBACK_PARAMS(events, "check_hardfork_active", static_cast<size_t>(ZANO_HARDFORK_04_ZARCANUM));
|
||||
|
||||
MAKE_TX(events, tx_2, miner_acc, alice_acc, MK_TEST_COINS(200), blk_3);
|
||||
MAKE_NEXT_BLOCK_TX1(events, blk_4, blk_3, miner_acc, tx_2);
|
||||
m_alice_balance += MK_TEST_COINS(200);
|
||||
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_4r, blk_4, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
DO_CALLBACK_PARAMS(events, "check_balance", params_check_balance(ALICE_ACC_IDX, m_alice_balance, m_alice_balance, mined_amount, 0, 0));
|
||||
|
||||
// then miner sends few coins to Bob via a tx with a big fee amount
|
||||
fee = MK_TEST_COINS(456);
|
||||
MAKE_TX_FEE(events, tx_3, miner_acc, bob_acc, MK_TEST_COINS(1000), fee, blk_4r);
|
||||
|
||||
// and Alice mines a PoS block with this tx -- so Alice is expected to receive the fee
|
||||
MAKE_NEXT_POS_BLOCK_TX1(events, blk_5, blk_4r, alice_acc, alice_stake_sources, tx_3);
|
||||
|
||||
// make sure Alice received both block reward and the fee
|
||||
uint64_t mined_amount_2 = COIN + fee;
|
||||
DO_CALLBACK_PARAMS(events, "check_balance", params_check_balance(ALICE_ACC_IDX, m_alice_balance + mined_amount_2, 0, mined_amount + mined_amount_2, 0, 0));
|
||||
m_alice_balance += mined_amount_2;
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool zarcanum_block_with_txs::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,3 +44,12 @@ struct zarcanum_in_alt_chain : public wallet_test
|
|||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
};
|
||||
|
||||
struct zarcanum_block_with_txs : public wallet_test
|
||||
{
|
||||
zarcanum_block_with_txs();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
|
||||
mutable uint64_t m_alice_balance = 0;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue