diff options
Diffstat (limited to 'tests')
34 files changed, 335 insertions, 269 deletions
diff --git a/tests/block_weight/block_weight.cpp b/tests/block_weight/block_weight.cpp index 4b00fc63f..676d56006 100644 --- a/tests/block_weight/block_weight.cpp +++ b/tests/block_weight/block_weight.cpp @@ -138,7 +138,7 @@ static uint32_t lcg() static void test(test_t t, uint64_t blocks) { - PREFIX(10); + PREFIX(HF_VERSION_2021_SCALING); for (uint64_t h = 0; h < LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h) { @@ -177,8 +177,8 @@ static void test(test_t t, uint64_t blocks) } uint64_t ltw = bc->get_next_long_term_block_weight(w); cryptonote::block b; - b.major_version = 10; - b.minor_version = 10; + b.major_version = HF_VERSION_2021_SCALING; + b.minor_version = HF_VERSION_2021_SCALING; bc->get_db().add_block(std::make_pair(std::move(b), ""), w, ltw, bc->get_db().height(), bc->get_db().height(), {}); if (!bc->update_next_cumulative_weight_limit()) diff --git a/tests/block_weight/block_weight.py b/tests/block_weight/block_weight.py index 5ec09896d..cfd0900fb 100755 --- a/tests/block_weight/block_weight.py +++ b/tests/block_weight/block_weight.py @@ -18,14 +18,20 @@ ltembw = MEDIAN_THRESHOLD weights = [MEDIAN_THRESHOLD]*MEDIAN_WINDOW_SMALL # weights of recent blocks (B), with index -1 most recent lt_weights = [MEDIAN_THRESHOLD]*MEDIAN_WINDOW_BIG # long-term weights +# see contrib/epee/include/misc_language.h, get_mid +def get_mid(a, b): + return (a//2) + (b//2) + ((a - 2*(a//2)) + (b - 2*(b//2)))//2; + # Compute the median of a list def get_median(vec): - #temp = vec + if len(vec) == 1: + return vec[0] temp = sorted(vec) + n = len(temp) // 2 if len(temp) % 2 == 1: - return temp[len(temp)//2] + return temp[n] else: - return int((temp[len(temp)//2]+temp[len(temp)//2-1])//2) + return get_mid(temp[n-1], temp[n]) def LCG(): global lcg_seed @@ -46,7 +52,7 @@ def run(t, blocks): # determine the effective weight stmedian = get_median(weights[-MEDIAN_WINDOW_SMALL:]) - embw = min(max(MEDIAN_THRESHOLD,stmedian),int(MULTIPLIER_BIG*ltembw)) + embw = min(max(ltembw,stmedian),int(MULTIPLIER_BIG*ltembw)) # drop the lowest values weights = weights[1:] @@ -64,7 +70,7 @@ def run(t, blocks): else: sys.exit(1) weights.append(max_weight) - lt_weights.append(min(max_weight,int(ltembw + int(ltembw * 2 / 5)))) + lt_weights.append(min(max(max_weight, ltembw * 10 // 17),int(ltembw + int(ltembw * 7 / 10)))) #print "H %u, r %u, BW %u, EMBW %u, LTBW %u, LTEMBW %u, ltmedian %u" % (block, r, max_weight, embw, lt_weights[-1], ltembw, ltmedian) print("H %u, BW %u, EMBW %u, LTBW %u" % (block, max_weight, embw, lt_weights[-1])) diff --git a/tests/core_tests/block_validation.cpp b/tests/core_tests/block_validation.cpp index 071d2198e..fd5ab5a7f 100644 --- a/tests/core_tests/block_validation.cpp +++ b/tests/core_tests/block_validation.cpp @@ -350,7 +350,7 @@ bool gen_block_miner_tx_has_2_in::generate(std::vector<test_event_entry>& events destinations.push_back(de); transaction tmp_tx; - if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tmp_tx, 0)) + if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tmp_tx)) return false; MAKE_MINER_TX_MANUALLY(miner_tx, blk_0); @@ -393,7 +393,7 @@ bool gen_block_miner_tx_with_txin_to_key::generate(std::vector<test_event_entry> destinations.push_back(de); transaction tmp_tx; - if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tmp_tx, 0)) + if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tmp_tx)) return false; MAKE_MINER_TX_MANUALLY(miner_tx, blk_1); diff --git a/tests/core_tests/bulletproof_plus.cpp b/tests/core_tests/bulletproof_plus.cpp index ece03dd77..742670063 100644 --- a/tests/core_tests/bulletproof_plus.cpp +++ b/tests/core_tests/bulletproof_plus.cpp @@ -136,7 +136,7 @@ bool gen_bpp_tx_validation_base::generate_with(std::vector<test_event_entry>& ev std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses; subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0}; rct_txes.resize(rct_txes.size() + 1); - bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), 0, tx_key, additional_tx_keys, true, rct_config[n]); + bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), tx_key, additional_tx_keys, true, rct_config[n]); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); if (post_tx && !post_tx(rct_txes.back(), n)) diff --git a/tests/core_tests/bulletproofs.cpp b/tests/core_tests/bulletproofs.cpp index f875edf74..278bf46a2 100644 --- a/tests/core_tests/bulletproofs.cpp +++ b/tests/core_tests/bulletproofs.cpp @@ -136,7 +136,7 @@ bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& eve std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses; subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0}; rct_txes.resize(rct_txes.size() + 1); - bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), 0, tx_key, additional_tx_keys, true, rct_config[n]); + bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), tx_key, additional_tx_keys, true, rct_config[n]); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); if (post_tx && !post_tx(rct_txes.back(), n)) diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 9aa0de8e5..8b2c2a577 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -1043,7 +1043,7 @@ bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote vector<tx_destination_entry> destinations; fill_tx_sources_and_destinations(events, blk_head, from, get_address(to), amount, fee, nmix, sources, destinations, check_unlock_time, fnc_tx_in_accept); - return construct_tx_rct(from.get_keys(), sources, destinations, from.get_keys().m_account_address, std::vector<uint8_t>(), tx, 0, rct, range_proof_type, bp_version); + return construct_tx_rct(from.get_keys(), sources, destinations, from.get_keys().m_account_address, std::vector<uint8_t>(), tx, rct, range_proof_type, bp_version); } bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote::transaction& tx, const cryptonote::block& blk_head, @@ -1060,7 +1060,7 @@ bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote fill_tx_destinations(from, destinations, fee, sources, destinations_all, false); - return construct_tx_rct(from.get_keys(), sources, destinations_all, get_address(from), std::vector<uint8_t>(), tx, 0, rct, range_proof_type, bp_version); + return construct_tx_rct(from.get_keys(), sources, destinations_all, get_address(from), std::vector<uint8_t>(), tx, rct, range_proof_type, bp_version); } bool construct_tx_to_key(cryptonote::transaction& tx, @@ -1070,7 +1070,7 @@ bool construct_tx_to_key(cryptonote::transaction& tx, { vector<tx_destination_entry> destinations; fill_tx_destinations(from, get_address(to), amount, fee, sources, destinations, rct); - return construct_tx_rct(from.get_keys(), sources, destinations, get_address(from), std::vector<uint8_t>(), tx, 0, rct, range_proof_type, bp_version); + return construct_tx_rct(from.get_keys(), sources, destinations, get_address(from), std::vector<uint8_t>(), tx, rct, range_proof_type, bp_version); } bool construct_tx_to_key(cryptonote::transaction& tx, @@ -1081,10 +1081,10 @@ bool construct_tx_to_key(cryptonote::transaction& tx, { vector<tx_destination_entry> all_destinations; fill_tx_destinations(from, destinations, fee, sources, all_destinations, rct); - return construct_tx_rct(from.get_keys(), sources, all_destinations, get_address(from), std::vector<uint8_t>(), tx, 0, rct, range_proof_type, bp_version); + return construct_tx_rct(from.get_keys(), sources, all_destinations, get_address(from), std::vector<uint8_t>(), tx, rct, range_proof_type, bp_version); } -bool construct_tx_rct(const cryptonote::account_keys& sender_account_keys, std::vector<cryptonote::tx_source_entry>& sources, const std::vector<cryptonote::tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, std::vector<uint8_t> extra, cryptonote::transaction& tx, uint64_t unlock_time, bool rct, rct::RangeProofType range_proof_type, int bp_version) +bool construct_tx_rct(const cryptonote::account_keys& sender_account_keys, std::vector<cryptonote::tx_source_entry>& sources, const std::vector<cryptonote::tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, std::vector<uint8_t> extra, cryptonote::transaction& tx, bool rct, rct::RangeProofType range_proof_type, int bp_version) { std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses; subaddresses[sender_account_keys.m_account_address.m_spend_public_key] = {0, 0}; @@ -1092,7 +1092,7 @@ bool construct_tx_rct(const cryptonote::account_keys& sender_account_keys, std:: std::vector<crypto::secret_key> additional_tx_keys; std::vector<tx_destination_entry> destinations_copy = destinations; rct::RCTConfig rct_config = {range_proof_type, bp_version}; - return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config); + return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, tx_key, additional_tx_keys, rct, rct_config); } transaction construct_tx_with_fee(std::vector<test_event_entry>& events, const block& blk_head, diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index 41f7275d3..0a1eb232d 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -472,7 +472,7 @@ bool construct_tx_rct(const cryptonote::account_keys& sender_account_keys, std::vector<cryptonote::tx_source_entry>& sources, const std::vector<cryptonote::tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, - std::vector<uint8_t> extra, cryptonote::transaction& tx, uint64_t unlock_time, + std::vector<uint8_t> extra, cryptonote::transaction& tx, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0); diff --git a/tests/core_tests/double_spend.inl b/tests/core_tests/double_spend.inl index b6e3726cc..5ccf4de98 100644 --- a/tests/core_tests/double_spend.inl +++ b/tests/core_tests/double_spend.inl @@ -138,7 +138,7 @@ bool gen_double_spend_in_tx<txs_keeped_by_block>::generate(std::vector<test_even destinations.push_back(de); cryptonote::transaction tx_1; - if (!construct_tx(bob_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_1, 0)) + if (!construct_tx(bob_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_1)) return false; SET_EVENT_VISITOR_SETT(events, txs_keeped_by_block ? event_visitor_settings::set_txs_keeped_by_block : 0); diff --git a/tests/core_tests/integer_overflow.cpp b/tests/core_tests/integer_overflow.cpp index 6ffc3786b..2f48ec04a 100644 --- a/tests/core_tests/integer_overflow.cpp +++ b/tests/core_tests/integer_overflow.cpp @@ -174,7 +174,7 @@ bool gen_uint_overflow_2::generate(std::vector<test_event_entry>& events) const destinations.push_back(tx_destination_entry(sources.front().amount - MONEY_SUPPLY - MONEY_SUPPLY + 1 - TESTS_DEFAULT_FEE, bob_addr, false)); cryptonote::transaction tx_1; - if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_1, 0)) + if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_1)) return false; events.push_back(tx_1); @@ -200,7 +200,7 @@ bool gen_uint_overflow_2::generate(std::vector<test_event_entry>& events) const destinations.push_back(de); cryptonote::transaction tx_2; - if (!construct_tx(bob_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_2, 0)) + if (!construct_tx(bob_account.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_2)) return false; events.push_back(tx_2); diff --git a/tests/core_tests/multisig.cpp b/tests/core_tests/multisig.cpp index ed6fd68b5..e33803325 100644 --- a/tests/core_tests/multisig.cpp +++ b/tests/core_tests/multisig.cpp @@ -310,7 +310,7 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry crypto::secret_key multisig_tx_key_entropy; auto sources_copy = sources; multisig::signing::tx_builder_ringct_t tx_builder; - CHECK_AND_ASSERT_MES(tx_builder.init(miner_account[creator].get_keys(), {}, 0, 0, {0}, sources, destinations, {}, {rct::RangeProofPaddedBulletproof, 4}, true, false, tx_key, additional_tx_secret_keys, multisig_tx_key_entropy, tx), false, "error: multisig::signing::tx_builder_ringct_t::init"); + CHECK_AND_ASSERT_MES(tx_builder.init(miner_account[creator].get_keys(), {}, 0, {0}, sources, destinations, {}, {rct::RangeProofPaddedBulletproof, 4}, true, false, tx_key, additional_tx_secret_keys, multisig_tx_key_entropy, tx), false, "error: multisig::signing::tx_builder_ringct_t::init"); // work out the permutation done on sources std::vector<size_t> ins_order; @@ -399,7 +399,7 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry } tools::apply_permutation(ins_order, k); multisig::signing::tx_builder_ringct_t signer_tx_builder; - CHECK_AND_ASSERT_MES(signer_tx_builder.init(miner_account[signer].get_keys(), {}, 0, 0, {0}, sources, destinations, {}, {rct::RangeProofPaddedBulletproof, 4}, true, true, tx_key, additional_tx_secret_keys, multisig_tx_key_entropy, tx), false, "error: multisig::signing::tx_builder_ringct_t::init"); + CHECK_AND_ASSERT_MES(signer_tx_builder.init(miner_account[signer].get_keys(), {}, 0, {0}, sources, destinations, {}, {rct::RangeProofPaddedBulletproof, 4}, true, true, tx_key, additional_tx_secret_keys, multisig_tx_key_entropy, tx), false, "error: multisig::signing::tx_builder_ringct_t::init"); MDEBUG("signing with k size " << k.size()); for (size_t n = 0; n < multisig::signing::kAlphaComponents; ++n) diff --git a/tests/core_tests/rct.cpp b/tests/core_tests/rct.cpp index 3f2cfbea3..9ea7a8e3b 100644 --- a/tests/core_tests/rct.cpp +++ b/tests/core_tests/rct.cpp @@ -122,7 +122,7 @@ bool gen_rct_tx_validation_base::generate_with_full(std::vector<test_event_entry std::vector<crypto::secret_key> additional_tx_keys; std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses; subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0}; - bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes[n], 0, tx_key, additional_tx_keys, true); + bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes[n], tx_key, additional_tx_keys, true); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); events.push_back(rct_txes[n]); starting_rct_tx_hashes.push_back(get_transaction_hash(rct_txes[n])); @@ -229,7 +229,7 @@ bool gen_rct_tx_validation_base::generate_with_full(std::vector<test_event_entry std::vector<crypto::secret_key> additional_tx_keys; std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses; subaddresses[miner_accounts[0].get_keys().m_account_address.m_spend_public_key] = {0,0}; - bool r = construct_tx_and_get_tx_key(miner_accounts[0].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_keys, true, rct_config, use_view_tags); + bool r = construct_tx_and_get_tx_key(miner_accounts[0].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), tx, tx_key, additional_tx_keys, true, rct_config, use_view_tags); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); if (post_tx) diff --git a/tests/core_tests/rct2.cpp b/tests/core_tests/rct2.cpp index c8e0f6260..28e97b06d 100644 --- a/tests/core_tests/rct2.cpp +++ b/tests/core_tests/rct2.cpp @@ -136,7 +136,7 @@ bool gen_rct2_tx_validation_base::generate_with(std::vector<test_event_entry>& e std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses; subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0}; rct_txes.resize(rct_txes.size() + 1); - bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), 0, tx_key, additional_tx_keys, true, rct_config[n]); + bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), tx_key, additional_tx_keys, true, rct_config[n]); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); if (post_tx && !post_tx(rct_txes.back(), n)) diff --git a/tests/core_tests/transaction_tests.cpp b/tests/core_tests/transaction_tests.cpp index b5ecba9ae..c27e6b375 100644 --- a/tests/core_tests/transaction_tests.cpp +++ b/tests/core_tests/transaction_tests.cpp @@ -102,7 +102,7 @@ bool test_transaction_generation_and_ring_signature() destinations.push_back(td); transaction tx_rc1; - bool r = construct_tx(miner_acc2.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_rc1, 0); + bool r = construct_tx(miner_acc2.get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx_rc1); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); crypto::hash pref_hash = get_transaction_prefix_hash(tx_rc1); diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp index bc8622539..a46b2a06a 100644 --- a/tests/core_tests/tx_validation.cpp +++ b/tests/core_tests/tx_validation.cpp @@ -212,7 +212,7 @@ bool gen_tx_unlock_time::generate(std::vector<test_event_entry>& events) const GENERATE_ACCOUNT(miner_account); MAKE_GENESIS_BLOCK(events, blk_0, miner_account, ts_start); - REWIND_BLOCKS_N(events, blk_1, blk_0, miner_account, 10); + REWIND_BLOCKS_N(events, blk_1, blk_0, miner_account, 20); REWIND_BLOCKS(events, blk_1r, blk_1, miner_account); auto make_tx_with_unlock_time = [&](uint64_t unlock_time) -> transaction @@ -222,9 +222,34 @@ bool gen_tx_unlock_time::generate(std::vector<test_event_entry>& events) const std::list<transaction> txs_0; + // Let's make sure that non-zero unlock times fail with a normal relay method + SET_EVENT_VISITOR_SETT(events, 0); // set relay_method::fluff + txs_0.push_back(make_tx_with_unlock_time(0)); events.push_back(txs_0.back()); + DO_CALLBACK(events, "mark_invalid_tx"); + events.push_back(make_tx_with_unlock_time(get_block_height(blk_1r) - 1)); + + DO_CALLBACK(events, "mark_invalid_tx"); + events.push_back(make_tx_with_unlock_time(get_block_height(blk_1r))); + + DO_CALLBACK(events, "mark_invalid_tx"); + events.push_back(make_tx_with_unlock_time(get_block_height(blk_1r) + 1)); + + DO_CALLBACK(events, "mark_invalid_tx"); + events.push_back(make_tx_with_unlock_time(get_block_height(blk_1r) + 2)); + + DO_CALLBACK(events, "mark_invalid_tx"); + events.push_back(make_tx_with_unlock_time(ts_start - 1)); + + DO_CALLBACK(events, "mark_invalid_tx"); + events.push_back(make_tx_with_unlock_time(time(0) + 60 * 60)); + + // We want to try adding these transactions with non-zero unlock times to the pool, but relay + // rules enforce otherwise, so we set the relay method to block + SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_keeped_by_block); // set relay_method::block + txs_0.push_back(make_tx_with_unlock_time(get_block_height(blk_1r) - 1)); events.push_back(txs_0.back()); @@ -596,6 +621,7 @@ bool gen_tx_check_input_unlock_time::generate(std::vector<test_event_entry>& eve events.push_back(txs_0.back()); }; + SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_keeped_by_block); // set relay_method::block uint64_t blk_3_height = get_block_height(blk_1r) + 2; make_tx_to_acc(0, 0); make_tx_to_acc(1, blk_3_height - 1); @@ -604,6 +630,7 @@ bool gen_tx_check_input_unlock_time::generate(std::vector<test_event_entry>& eve make_tx_to_acc(4, time(0) - 1); make_tx_to_acc(5, time(0) + 60 * 60); MAKE_NEXT_BLOCK_TX_LIST(events, blk_2, blk_1r, miner_account, txs_0); + SET_EVENT_VISITOR_SETT(events, 0); // set relay_method::fluff std::list<transaction> txs_1; auto make_tx_from_acc = [&](size_t acc_idx, bool invalid) diff --git a/tests/core_tests/v2_tests.cpp b/tests/core_tests/v2_tests.cpp index f2d0121b6..9030f22ba 100644 --- a/tests/core_tests/v2_tests.cpp +++ b/tests/core_tests/v2_tests.cpp @@ -107,7 +107,7 @@ bool gen_v2_tx_validation_base::generate_with(std::vector<test_event_entry>& eve destinations.push_back(td); transaction tx; - bool r = construct_tx(miner_accounts[0].get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx, 0); + bool r = construct_tx(miner_accounts[0].get_keys(), sources, destinations, boost::none, std::vector<uint8_t>(), tx); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); if (!valid) DO_CALLBACK(events, "mark_invalid_tx"); diff --git a/tests/core_tests/wallet_tools.cpp b/tests/core_tests/wallet_tools.cpp index ee29fdad1..c81abbbaf 100644 --- a/tests/core_tests/wallet_tools.cpp +++ b/tests/core_tests/wallet_tools.cpp @@ -271,7 +271,7 @@ bool construct_tx_to_key(cryptonote::transaction& tx, { vector<tx_destination_entry> destinations; fill_tx_destinations(sender_wallet->get_account(), get_address(to), amount, fee, sources, destinations, rct); - return construct_tx_rct(sender_wallet, sources, destinations, get_address(sender_wallet), std::vector<uint8_t>(), tx, 0, rct, range_proof_type, bp_version); + return construct_tx_rct(sender_wallet, sources, destinations, get_address(sender_wallet), std::vector<uint8_t>(), tx, rct, range_proof_type, bp_version); } bool construct_tx_to_key(cryptonote::transaction& tx, @@ -282,15 +282,15 @@ bool construct_tx_to_key(cryptonote::transaction& tx, { vector<tx_destination_entry> all_destinations; fill_tx_destinations(sender_wallet->get_account(), destinations, fee, sources, all_destinations, rct); - return construct_tx_rct(sender_wallet, sources, all_destinations, get_address(sender_wallet), std::vector<uint8_t>(), tx, 0, rct, range_proof_type, bp_version); + return construct_tx_rct(sender_wallet, sources, all_destinations, get_address(sender_wallet), std::vector<uint8_t>(), tx, rct, range_proof_type, bp_version); } -bool construct_tx_rct(tools::wallet2 * sender_wallet, std::vector<cryptonote::tx_source_entry>& sources, const std::vector<cryptonote::tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, std::vector<uint8_t> extra, cryptonote::transaction& tx, uint64_t unlock_time, bool rct, rct::RangeProofType range_proof_type, int bp_version) +bool construct_tx_rct(tools::wallet2 * sender_wallet, std::vector<cryptonote::tx_source_entry>& sources, const std::vector<cryptonote::tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, std::vector<uint8_t> extra, cryptonote::transaction& tx, bool rct, rct::RangeProofType range_proof_type, int bp_version) { subaddresses_t & subaddresses = wallet_accessor_test::get_subaddresses(sender_wallet); crypto::secret_key tx_key; std::vector<crypto::secret_key> additional_tx_keys; std::vector<tx_destination_entry> destinations_copy = destinations; rct::RCTConfig rct_config = {range_proof_type, bp_version}; - return construct_tx_and_get_tx_key(sender_wallet->get_account().get_keys(), subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config); + return construct_tx_and_get_tx_key(sender_wallet->get_account().get_keys(), subaddresses, sources, destinations_copy, change_addr, extra, tx, tx_key, additional_tx_keys, rct, rct_config); } diff --git a/tests/core_tests/wallet_tools.h b/tests/core_tests/wallet_tools.h index 2201e11f4..94921e56e 100644 --- a/tests/core_tests/wallet_tools.h +++ b/tests/core_tests/wallet_tools.h @@ -53,6 +53,7 @@ class wallet_accessor_test { public: static void set_account(tools::wallet2 * wallet, cryptonote::account_base& account); + static void set_password(tools::wallet2 * wallet, const epee::wipeable_string & password) { wallet->setup_keys(password); } static tools::wallet2::transfer_container & get_transfers(tools::wallet2 * wallet) { return wallet->m_transfers; } static subaddresses_t & get_subaddresses(tools::wallet2 * wallet) { return wallet->m_subaddresses; } static void process_parsed_blocks(tools::wallet2 * wallet, uint64_t start_height, const std::vector<cryptonote::block_complete_entry> &blocks, const std::vector<tools::wallet2::parsed_block> &parsed_blocks, uint64_t& blocks_added); @@ -92,5 +93,5 @@ bool construct_tx_rct(tools::wallet2 * sender_wallet, std::vector<cryptonote::tx_source_entry>& sources, const std::vector<cryptonote::tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, - std::vector<uint8_t> extra, cryptonote::transaction& tx, uint64_t unlock_time, + std::vector<uint8_t> extra, cryptonote::transaction& tx, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0); diff --git a/tests/functional_tests/functional_tests_rpc.py b/tests/functional_tests/functional_tests_rpc.py index 7e4d49ffa..e483352a4 100755 --- a/tests/functional_tests/functional_tests_rpc.py +++ b/tests/functional_tests/functional_tests_rpc.py @@ -12,8 +12,8 @@ import os USAGE = 'usage: functional_tests_rpc.py <python> <srcdir> <builddir> [<tests-to-run> | all]' DEFAULT_TESTS = [ 'address_book', 'bans', 'blockchain', 'cold_signing', 'daemon_info', 'get_output_distribution', - 'integrated_address', 'k_anonymity', 'mining', 'multisig', 'p2p', 'proofs', 'rpc_payment', - 'sign_message', 'transfer', 'txpool', 'uri', 'validate_address', 'wallet' + 'http_digest_auth', 'integrated_address', 'k_anonymity', 'mining', 'multisig', 'p2p', 'proofs', + 'rpc_payment', 'sign_message', 'transfer', 'txpool', 'uri', 'validate_address', 'wallet' ] try: python = sys.argv[1] @@ -41,12 +41,12 @@ except: # a main offline monerod, does most of the tests # a restricted RPC monerod setup with RPC payment # two local online monerods connected to each other -N_MONERODS = 4 +N_MONERODS = 5 # 4 wallets connected to the main offline monerod # 1 wallet connected to the first local online monerod # 1 offline wallet -N_WALLETS = 6 +N_WALLETS = 7 WALLET_DIRECTORY = builddir + "/functional-tests-directory" FUNCTIONAL_TESTS_DIRECTORY = builddir + "/tests/functional_tests" @@ -58,15 +58,17 @@ monerod_extra = [ ["--rpc-payment-address", "44SKxxLQw929wRF6BA9paQ1EWFshNnKhXM3qz6Mo3JGDE2YG3xyzVutMStEicxbQGRfrYvAAYxH6Fe8rnD56EaNwUiqhcwR", "--rpc-payment-difficulty", str(DIFFICULTY), "--rpc-payment-credits", "5000", "--offline"], ["--add-exclusive-node", "127.0.0.1:18283"], ["--add-exclusive-node", "127.0.0.1:18282"], + ["--rpc-login", "md5_lover:Z1ON0101", "--offline"], ] -wallet_base = [builddir + "/bin/monero-wallet-rpc", "--wallet-dir", WALLET_DIRECTORY, "--rpc-bind-port", "wallet_port", "--disable-rpc-login", "--rpc-ssl", "disabled", "--daemon-ssl", "disabled", "--log-level", "1", "--allow-mismatched-daemon-version"] +wallet_base = [builddir + "/bin/monero-wallet-rpc", "--wallet-dir", WALLET_DIRECTORY, "--rpc-bind-port", "wallet_port", "--rpc-ssl", "disabled", "--daemon-ssl", "disabled", "--log-level", "1", "--allow-mismatched-daemon-version"] wallet_extra = [ - ["--daemon-port", "18180"], - ["--daemon-port", "18180"], - ["--daemon-port", "18180"], - ["--daemon-port", "18180"], - ["--daemon-port", "18182"], - ["--offline"], + ["--daemon-port", "18180", "--disable-rpc-login"], + ["--daemon-port", "18180", "--disable-rpc-login"], + ["--daemon-port", "18180", "--disable-rpc-login"], + ["--daemon-port", "18180", "--disable-rpc-login"], + ["--daemon-port", "18182", "--disable-rpc-login"], + ["--offline", "--disable-rpc-login"], + ["--daemon-port", "18184", "--daemon-login", "md5_lover:Z1ON0101", "--rpc-login", "kyle:reveille"], ] command_lines = [] diff --git a/tests/functional_tests/http_digest_auth.py b/tests/functional_tests/http_digest_auth.py new file mode 100644 index 000000000..7c22f9f30 --- /dev/null +++ b/tests/functional_tests/http_digest_auth.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2024, The Monero Project +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from framework.daemon import Daemon +from framework.wallet import Wallet + +import time + + +DAEMON_IDX = 4 +DAEMON_USER = "md5_lover" +DAEMON_PASS = "Z1ON0101" +WALLET_IDX = 6 +WALLET_USER = "kyle" +WALLET_PASS = "reveille" +WALLET_SEED = "velvet lymph giddy number token physics poetry unquoted nibs useful sabotage limits \ + benches lifestyle eden nitrogen anvil fewest avoid batch vials washing fences goat unquoted" + +class HttpDigestAuthTest(): + def run_test(self): + self.test_daemon_login_required() + self.test_wallet_login_required() + + self.make_daemon_conn() + self.create_wallet() + + self.mine_through_wallet() + + def test_daemon_login_required(self): + print('Attempting to connect to daemon loginless with RPC digest authentication required...') + bad_daemon = Daemon(idx = DAEMON_IDX) + try: + res = bad_daemon.get_height() + assert(False) + except: + pass + + def test_wallet_login_required(self): + print('Attempting to connect to wallet server loginless with RPC digest authentication required...') + bad_wallet = Wallet(idx = WALLET_IDX) + try: + res = bad_wallet.get_balance() + assert(False) + except: + pass + + def make_daemon_conn(self): + print('Connecting to daemon with RPC digest authentication required...') + self.daemon = Daemon(idx = DAEMON_IDX, username = DAEMON_USER, password = DAEMON_PASS) + res = self.daemon.get_height() + self.daemon.pop_blocks(res.height - 1) + self.daemon.flush_txpool() + + def create_wallet(self): + print('Connecting to wallet server with RPC digest authentication required...') + self.wallet = Wallet(idx = WALLET_IDX, username = WALLET_USER, password = WALLET_PASS) + # close the wallet if any, will throw if none is loaded + try: self.wallet.close_wallet() + except: pass + res = self.wallet.restore_deterministic_wallet(seed = WALLET_SEED) + + def mine_through_wallet(self): + print('Telling login-required daemon to start mining through login-required wallet server...') + start_height = self.daemon.get_height().height + self.wallet.start_mining(2) + + print("Waiting a few seconds for mining to occur...") + for tries in range(20): + time.sleep(1) + + stop_height = self.daemon.get_height().height + if stop_height > start_height: + break + + print('Telling login-required daemon to stop mining through login-required wallet server...') + self.wallet.stop_mining() + + num_blocks_mined = stop_height - start_height + assert num_blocks_mined > 0 + print('Mined {} blocks!'.format(num_blocks_mined)) + +if __name__ == '__main__': + HttpDigestAuthTest().run_test() diff --git a/tests/functional_tests/transactions_flow_test.cpp b/tests/functional_tests/transactions_flow_test.cpp index 8c4b27d24..a15348bca 100644 --- a/tests/functional_tests/transactions_flow_test.cpp +++ b/tests/functional_tests/transactions_flow_test.cpp @@ -85,7 +85,7 @@ bool do_send_money(tools::wallet2& w1, tools::wallet2& w2, size_t mix_in_factor, try { std::vector<tools::wallet2::pending_tx> ptx; - ptx = w1.create_transactions_2(dsts, mix_in_factor, 0, 0, std::vector<uint8_t>(), 0, {}); + ptx = w1.create_transactions_2(dsts, mix_in_factor, 0, std::vector<uint8_t>(), 0, {}); for (auto &p: ptx) w1.commit_tx(p); return true; diff --git a/tests/hash/main.cpp b/tests/hash/main.cpp index 23455f7f3..c1ad80c7c 100644 --- a/tests/hash/main.cpp +++ b/tests/hash/main.cpp @@ -43,7 +43,7 @@ #include "warnings.h" #include "crypto/hash.h" #include "crypto/variant2_int_sqrt.h" -#include "randomx/src/blake2/blake2.h" +#include "crypto/blake2b.h" #include "../io.h" using namespace std; diff --git a/tests/performance_tests/check_tx_signature.h b/tests/performance_tests/check_tx_signature.h index de979856a..2ae4a2613 100644 --- a/tests/performance_tests/check_tx_signature.h +++ b/tests/performance_tests/check_tx_signature.h @@ -72,7 +72,7 @@ public: std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses; subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0}; rct::RCTConfig rct_config{range_proof_type, bp_version}; - if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, rct_config)) + if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, tx_key, additional_tx_keys, rct, rct_config)) return false; get_transaction_prefix_hash(m_tx, m_tx_prefix_hash); @@ -136,7 +136,7 @@ public: m_txes.resize(a_num_txes + (extra_outs > 0 ? 1 : 0)); for (size_t n = 0; n < a_num_txes; ++n) { - if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes[n], 0, tx_key, additional_tx_keys, true, {rct::RangeProofPaddedBulletproof, 2})) + if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes[n], tx_key, additional_tx_keys, true, {rct::RangeProofPaddedBulletproof, 2})) return false; } @@ -147,7 +147,7 @@ public: for (size_t n = 1; n < extra_outs; ++n) destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false)); - if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes.back(), 0, tx_key, additional_tx_keys, true, {rct::RangeProofMultiOutputBulletproof, 2})) + if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes.back(), tx_key, additional_tx_keys, true, {rct::RangeProofMultiOutputBulletproof, 2})) return false; } diff --git a/tests/performance_tests/construct_tx.h b/tests/performance_tests/construct_tx.h index 4b3f061c4..14a603ca5 100644 --- a/tests/performance_tests/construct_tx.h +++ b/tests/performance_tests/construct_tx.h @@ -74,7 +74,7 @@ public: std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses; subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0}; rct::RCTConfig rct_config{range_proof_type, bp_version}; - return cryptonote::construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, m_destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, rct_config); + return cryptonote::construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, m_destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, tx_key, additional_tx_keys, rct, rct_config); } private: diff --git a/tests/performance_tests/ge_frombytes_vartime.h b/tests/performance_tests/ge_frombytes_vartime.h index d543ed720..d3d717195 100644 --- a/tests/performance_tests/ge_frombytes_vartime.h +++ b/tests/performance_tests/ge_frombytes_vartime.h @@ -57,7 +57,7 @@ public: std::vector<tx_destination_entry> destinations; destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false)); - if (!construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, boost::none, std::vector<uint8_t>(), m_tx, 0)) + if (!construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, boost::none, std::vector<uint8_t>(), m_tx)) return false; const cryptonote::txin_to_key& txin = boost::get<cryptonote::txin_to_key>(m_tx.vin[0]); diff --git a/tests/performance_tests/ge_tobytes.h b/tests/performance_tests/ge_tobytes.h index a3c6121b1..7adf1dcea 100644 --- a/tests/performance_tests/ge_tobytes.h +++ b/tests/performance_tests/ge_tobytes.h @@ -57,7 +57,7 @@ public: std::vector<tx_destination_entry> destinations; destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false)); - if (!construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, boost::none, std::vector<uint8_t>(), m_tx, 0)) + if (!construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, boost::none, std::vector<uint8_t>(), m_tx)) return false; const cryptonote::txin_to_key& txin = boost::get<cryptonote::txin_to_key>(m_tx.vin[0]); diff --git a/tests/performance_tests/performance_tests.h b/tests/performance_tests/performance_tests.h index 0f16ff8fc..68679a36c 100644 --- a/tests/performance_tests/performance_tests.h +++ b/tests/performance_tests/performance_tests.h @@ -249,7 +249,7 @@ bool run_test(const std::string &filter, ParamsT ¶ms_shuttle, const char* te double stddev = runner.get_stddev(); double npskew = runner.get_non_parametric_skew(); - std::vector<TimingsDatabase::instance> prev_instances = params.td.get(test_name); + const TimingsDatabase::instance* prev_instance = params.td.get_most_recent(test_name); params.td.add(test_name, {time(NULL), runner.get_size(), min, max, mean, med, stddev, npskew, quantiles}); std::cout << (params.verbose ? " time per call: " : " ") << time_per_call << " " << unit << "/call" << (params.verbose ? "\n" : ""); @@ -260,15 +260,14 @@ bool run_test(const std::string &filter, ParamsT ¶ms_shuttle, const char* te uint64_t p95s = quantiles[9] / scale; uint64_t stddevs = stddev / scale; std::string cmp; - if (!prev_instances.empty()) + if (prev_instance) { - const TimingsDatabase::instance &prev_instance = prev_instances.back(); - if (!runner.is_same_distribution(prev_instance.npoints, prev_instance.mean, prev_instance.stddev)) + if (!runner.is_same_distribution(prev_instance->npoints, prev_instance->mean, prev_instance->stddev)) { - double pc = fabs(100. * (prev_instance.mean - runner.get_mean()) / prev_instance.mean); - cmp = ", " + std::to_string(pc) + "% " + (mean > prev_instance.mean ? "slower" : "faster"); + double pc = fabs(100. * (prev_instance->mean - runner.get_mean()) / prev_instance->mean); + cmp = ", " + std::to_string(pc) + "% " + (mean > prev_instance->mean ? "slower" : "faster"); } - cmp += " -- " + std::to_string(prev_instance.mean); + cmp += " -- " + std::to_string(prev_instance->mean); } std::cout << " (min " << mins << " " << unit << ", 90th " << p95s << " " << unit << ", median " << meds << " " << unit << ", std dev " << stddevs << " " << unit << ")" << cmp; } diff --git a/tests/trezor/trezor_tests.cpp b/tests/trezor/trezor_tests.cpp index b21da95c0..0fcd10cef 100644 --- a/tests/trezor/trezor_tests.cpp +++ b/tests/trezor/trezor_tests.cpp @@ -2206,6 +2206,7 @@ bool gen_trezor_wallet_passphrase::generate(std::vector<test_event_entry>& event const auto wallet_path = (m_wallet_dir / "alice2").string(); const epee::wipeable_string& password = epee::wipeable_string("test-pass"); + wallet_accessor_test::set_password(m_wl_alice2.get(), password); m_wl_alice2->store_to(wallet_path, password); // Positive load diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index 212f834d2..567ca8b00 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -51,7 +51,6 @@ set(unit_tests_sources epee_serialization.cpp epee_utils.cpp expect.cpp - fee.cpp json_serialization.cpp get_xtype_from_string.cpp hashchain.cpp diff --git a/tests/unit_tests/crypto.cpp b/tests/unit_tests/crypto.cpp index 88ecb5853..9f79ed60e 100644 --- a/tests/unit_tests/crypto.cpp +++ b/tests/unit_tests/crypto.cpp @@ -112,6 +112,7 @@ TEST(Crypto, tree_branch) { crypto::hash inputs[6]; crypto::hash branch[8]; + crypto::hash branch_1[8 + 1]; crypto::hash root, root2; size_t depth; uint32_t path, path2; @@ -296,12 +297,16 @@ TEST(Crypto, tree_branch) ASSERT_FALSE(crypto::is_branch_in_tree(inputs[5].data, root.data, (const char(*)[32])branch, depth, path)); ASSERT_FALSE(crypto::is_branch_in_tree(crypto::null_hash.data, root.data, (const char(*)[32])branch, depth, path)); + // a version with an extra (dummy) hash + memcpy(branch_1, branch, sizeof(branch)); + branch_1[depth] = crypto::null_hash; + ASSERT_FALSE(crypto::is_branch_in_tree(inputs[4].data, root.data, (const char(*)[32])branch, depth - 1, path)); - ASSERT_FALSE(crypto::is_branch_in_tree(inputs[4].data, root.data, (const char(*)[32])branch, depth + 1, path)); + ASSERT_FALSE(crypto::is_branch_in_tree(inputs[4].data, root.data, (const char(*)[32])branch_1, depth + 1, path)); ASSERT_FALSE(crypto::is_branch_in_tree(inputs[4].data, root.data, (const char(*)[32])branch, depth, path ^ 1)); ASSERT_FALSE(crypto::is_branch_in_tree(inputs[4].data, root.data, (const char(*)[32])branch, depth, path ^ 2)); ASSERT_FALSE(crypto::is_branch_in_tree(inputs[4].data, root.data, (const char(*)[32])branch, depth, path ^ 3)); - ASSERT_FALSE(crypto::is_branch_in_tree(inputs[4].data, root.data, (const char(*)[32])(branch + 1), depth, path)); + ASSERT_FALSE(crypto::is_branch_in_tree(inputs[4].data, root.data, (const char(*)[32])(branch_1 + 1), depth, path)); // five, not found ASSERT_FALSE(crypto::tree_branch((const char(*)[32])inputs, 5, crypto::null_hash.data, (char(*)[32])branch, &depth, &path)); diff --git a/tests/unit_tests/fee.cpp b/tests/unit_tests/fee.cpp deleted file mode 100644 index 1df1a4f04..000000000 --- a/tests/unit_tests/fee.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) 2014-2023, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#include "gtest/gtest.h" - -#include "cryptonote_core/blockchain.h" - -using namespace cryptonote; - -namespace -{ - static uint64_t clamp_fee(uint64_t fee) - { - static uint64_t mask = 0; - if (mask == 0) - { - mask = 1; - for (size_t n = PER_KB_FEE_QUANTIZATION_DECIMALS; n < CRYPTONOTE_DISPLAY_DECIMAL_POINT; ++n) - mask *= 10; - } - return (fee + mask - 1) / mask * mask; - } - - //-------------------------------------------------------------------------------------------------------------------- - class fee : public ::testing::Test - { - }; - - // try with blocks ~ 1GB. Passing 2 GB will break on 32 bit systems - - TEST_F(fee, 10xmr) - { - // CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 and lower are clamped - ASSERT_EQ(Blockchain::get_dynamic_base_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2, 3), clamp_fee(2000000000)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 2, 3), clamp_fee(2000000000)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 100, 3), clamp_fee(2000000000)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(10000000000000, 1, 3), 2000000000); - - // higher is inverse proportional - ASSERT_EQ(Blockchain::get_dynamic_base_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 2, 3), clamp_fee(2000000000 / 2)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 10, 3), clamp_fee(2000000000 / 10)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 1000, 3), clamp_fee(2000000000 / 1000)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(10000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 20000ull, 3), clamp_fee(2000000000 / 20000)); - } - - TEST_F(fee, 1xmr) - { - // CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 and lower are clamped - ASSERT_EQ(Blockchain::get_dynamic_base_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2, 3), clamp_fee(200000000)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 2, 3), clamp_fee(200000000)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 100, 3), clamp_fee(200000000)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(1000000000000, 1, 3), 200000000); - - // higher is inverse proportional - ASSERT_EQ(Blockchain::get_dynamic_base_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 2, 3), clamp_fee(200000000 / 2)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 10, 3), clamp_fee(200000000 / 10)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 1000, 3), clamp_fee(200000000 / 1000)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(1000000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 20000ull, 3), clamp_fee(200000000 / 20000)); - } - - TEST_F(fee, dot3xmr) - { - // CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 and lower are clamped - ASSERT_EQ(Blockchain::get_dynamic_base_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2, 3), clamp_fee(60000000)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 2, 3), clamp_fee(60000000)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 / 100, 3), clamp_fee(60000000)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(300000000000, 1, 3), 60000000); - - // higher is inverse proportional - ASSERT_EQ(Blockchain::get_dynamic_base_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 2, 3), clamp_fee(60000000 / 2)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 10, 3), clamp_fee(60000000 / 10)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 1000, 3), clamp_fee(60000000 / 1000)); - ASSERT_EQ(Blockchain::get_dynamic_base_fee(300000000000, CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 20000ull, 3), clamp_fee(60000000 / 20000)); - } - - static bool is_more_or_less(double x, double y) - { - return fabs(y - x) < 0.001; - } - - static const double MAX_MULTIPLIER = 166.f; - - TEST_F(fee, double_at_full) - { - static const uint64_t block_rewards[] = { - 20000000000000ull, // 20 monero - 13000000000000ull, - 1000000000000ull, - 600000000000ull, // .6 monero, minimum reward per block at 2min - 300000000000ull, // .3 monero, minimum reward per block at 1min - }; - static const uint64_t median_block_weights[] = { - CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2, - CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 2, - CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 10, - CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 1000, - // with clamping, the formula does not hold for such large blocks and small fees - // CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 20000ull - }; - - for (uint64_t block_reward: block_rewards) - { - for (uint64_t median_block_weight: median_block_weights) - { - ASSERT_TRUE(is_more_or_less(Blockchain::get_dynamic_base_fee(block_reward, median_block_weight, 3) * (median_block_weight / 1024.) * MAX_MULTIPLIER / (double)block_reward, 1.992 * 1000 / 1024)); - } - } - } -} diff --git a/tests/unit_tests/json_serialization.cpp b/tests/unit_tests/json_serialization.cpp index aa46b68dc..9525d23ea 100644 --- a/tests/unit_tests/json_serialization.cpp +++ b/tests/unit_tests/json_serialization.cpp @@ -78,7 +78,7 @@ namespace test std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses; subaddresses[from.m_account_address.m_spend_public_key] = {0,0}; - if (!cryptonote::construct_tx_and_get_tx_key(from, subaddresses, actual_sources, to, boost::none, {}, tx, 0, tx_key, extra_keys, rct, { bulletproof ? rct::RangeProofBulletproof : rct::RangeProofBorromean, bulletproof ? 2 : 0 })) + if (!cryptonote::construct_tx_and_get_tx_key(from, subaddresses, actual_sources, to, boost::none, {}, tx, tx_key, extra_keys, rct, { bulletproof ? rct::RangeProofBulletproof : rct::RangeProofBorromean, bulletproof ? 2 : 0 })) throw std::runtime_error{"transaction construction error"}; return tx; diff --git a/tests/unit_tests/multisig.cpp b/tests/unit_tests/multisig.cpp index a79b81e84..c044591c1 100644 --- a/tests/unit_tests/multisig.cpp +++ b/tests/unit_tests/multisig.cpp @@ -159,12 +159,12 @@ static void check_results(const std::vector<std::string> &intermediate_infos, for (size_t i = 0; i < wallets.size(); ++i) { EXPECT_TRUE(!intermediate_infos[i].empty()); - bool ready; - uint32_t threshold, total; - EXPECT_TRUE(wallets[i].multisig(&ready, &threshold, &total)); - EXPECT_TRUE(ready); - EXPECT_TRUE(threshold == M); - EXPECT_TRUE(total == wallets.size()); + const multisig::multisig_account_status ms_status{wallets[i].get_multisig_status()}; + EXPECT_TRUE(ms_status.multisig_is_active); + EXPECT_TRUE(ms_status.kex_is_done); + EXPECT_TRUE(ms_status.is_ready); + EXPECT_TRUE(ms_status.threshold == M); + EXPECT_TRUE(ms_status.total == wallets.size()); wallets[i].decrypt_keys(""); @@ -226,10 +226,8 @@ static void make_wallets(const unsigned int M, const unsigned int N, const bool } // wallets should not be multisig yet - for (const auto &wallet: wallets) - { - ASSERT_FALSE(wallet.multisig()); - } + for (const auto& wallet: wallets) + ASSERT_FALSE(wallet.get_multisig_status().multisig_is_active); // make wallets multisig, get second round kex messages (if appropriate) std::vector<std::string> intermediate_infos(wallets.size()); @@ -242,16 +240,15 @@ static void make_wallets(const unsigned int M, const unsigned int N, const bool ++rounds_complete; // perform kex rounds until kex is complete - bool ready; - wallets[0].multisig(&ready); - while (!ready) + multisig::multisig_account_status ms_status{wallets[0].get_multisig_status()}; + while (!ms_status.is_ready) { if (force_update) intermediate_infos = exchange_round_force_update(wallets, intermediate_infos, rounds_complete + 1); else intermediate_infos = exchange_round(wallets, intermediate_infos); - wallets[0].multisig(&ready); + ms_status = wallets[0].get_multisig_status(); ++rounds_complete; } diff --git a/tests/unit_tests/scaling_2021.cpp b/tests/unit_tests/scaling_2021.cpp index d90f0f9e6..59e036d10 100644 --- a/tests/unit_tests/scaling_2021.cpp +++ b/tests/unit_tests/scaling_2021.cpp @@ -30,68 +30,26 @@ // - https://github.com/ArticMine/Monero-Documents/blob/master/MoneroScaling2021.pdf // - https://github.com/monero-project/research-lab/issues/70 -#define IN_UNIT_TESTS - #include "gtest/gtest.h" #include "cryptonote_core/blockchain.h" -#include "cryptonote_core/tx_pool.h" -#include "cryptonote_core/cryptonote_core.h" -#include "blockchain_db/testdb.h" - -namespace -{ - -class TestDB: public cryptonote::BaseTestDB -{ -public: - TestDB() { m_open = true; } -}; - -} - -#define PREFIX_WINDOW(hf_version,window) \ - struct get_test_options { \ - const std::pair<uint8_t, uint64_t> hard_forks[3]; \ - const cryptonote::test_options test_options = { \ - hard_forks, \ - window, \ - }; \ - get_test_options(): hard_forks{std::make_pair(1, (uint64_t)0), std::make_pair((uint8_t)hf_version, (uint64_t)1), std::make_pair((uint8_t)0, (uint64_t)0)} {} \ - } opts; \ - cryptonote::BlockchainAndPool bap; \ - cryptonote::Blockchain *blockchain = &bap.blockchain; \ - cryptonote::Blockchain *bc = blockchain; \ - bool r = blockchain->init(new TestDB(), cryptonote::FAKECHAIN, true, &opts.test_options, 0, NULL); \ - ASSERT_TRUE(r) - -#define PREFIX(hf_version) PREFIX_WINDOW(hf_version, TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW) TEST(fee_2021_scaling, relay_fee_cases_from_pdf) { - PREFIX_WINDOW(HF_VERSION_2021_SCALING, CRYPTONOTE_LONG_TERM_BLOCK_WEIGHT_WINDOW_SIZE); - - ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 300000, HF_VERSION_2021_SCALING-1), 8000); - ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 300000, HF_VERSION_2021_SCALING), 38000); - ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 1425000, HF_VERSION_2021_SCALING-1), 1684 /*1680*/); - ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 1425000, HF_VERSION_2021_SCALING), 1684 /*1680*/); - ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 1500000, HF_VERSION_2021_SCALING-1), 1600); - ASSERT_EQ(bc->get_dynamic_base_fee(1200000000000, 1500000, HF_VERSION_2021_SCALING), 1520); - - ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 300000, HF_VERSION_2021_SCALING-1), 4000); - ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 300000, HF_VERSION_2021_SCALING), 19000); - ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 1425000, HF_VERSION_2021_SCALING-1), 842 /*840*/); - ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 1425000, HF_VERSION_2021_SCALING), 842 /*840*/); - ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 1500000, HF_VERSION_2021_SCALING-1), 800); - ASSERT_EQ(bc->get_dynamic_base_fee(600000000000, 1500000, HF_VERSION_2021_SCALING), 760); + ASSERT_EQ(cryptonote::Blockchain::get_dynamic_base_fee(1200000000000, 300000), 38000); + ASSERT_EQ(cryptonote::Blockchain::get_dynamic_base_fee(1200000000000, 1425000), 1684 /*1680*/); + ASSERT_EQ(cryptonote::Blockchain::get_dynamic_base_fee(1200000000000, 1500000), 1520); + + ASSERT_EQ(cryptonote::Blockchain::get_dynamic_base_fee(600000000000, 300000), 19000); + ASSERT_EQ(cryptonote::Blockchain::get_dynamic_base_fee(600000000000, 1425000), 842 /*840*/); + ASSERT_EQ(cryptonote::Blockchain::get_dynamic_base_fee(600000000000, 1500000), 760); } TEST(fee_2021_scaling, wallet_fee_cases_from_pdf) { - PREFIX_WINDOW(HF_VERSION_2021_SCALING, CRYPTONOTE_LONG_TERM_BLOCK_WEIGHT_WINDOW_SIZE); std::vector<uint64_t> fees; fees.clear(); - bc->get_dynamic_base_fee_estimate_2021_scaling(10, 600000000000, 300000, 300000, fees); + cryptonote::Blockchain::get_dynamic_base_fee_estimate_2021_scaling(600000000000, 300000, 300000, fees); ASSERT_EQ(fees.size(), 4); ASSERT_EQ(fees[0], 20000); ASSERT_EQ(fees[1], 80000); @@ -99,7 +57,7 @@ TEST(fee_2021_scaling, wallet_fee_cases_from_pdf) ASSERT_EQ(fees[3], 4000000); fees.clear(); - bc->get_dynamic_base_fee_estimate_2021_scaling(10, 600000000000, 15000000, 300000, fees); + cryptonote::Blockchain::get_dynamic_base_fee_estimate_2021_scaling(600000000000, 15000000, 300000, fees); ASSERT_EQ(fees.size(), 4); ASSERT_EQ(fees[0], 20000); ASSERT_EQ(fees[1], 80000); @@ -107,7 +65,7 @@ TEST(fee_2021_scaling, wallet_fee_cases_from_pdf) ASSERT_EQ(fees[3], 1300000); fees.clear(); - bc->get_dynamic_base_fee_estimate_2021_scaling(10, 600000000000, 1425000, 1425000, fees); + cryptonote::Blockchain::get_dynamic_base_fee_estimate_2021_scaling(600000000000, 1425000, 1425000, fees); ASSERT_EQ(fees.size(), 4); ASSERT_EQ(fees[0], 890); ASSERT_EQ(fees[1], 3600); @@ -115,7 +73,7 @@ TEST(fee_2021_scaling, wallet_fee_cases_from_pdf) ASSERT_EQ(fees[3], 850000 /* 842000 */); fees.clear(); - bc->get_dynamic_base_fee_estimate_2021_scaling(10, 600000000000, 1500000, 1500000, fees); + cryptonote::Blockchain::get_dynamic_base_fee_estimate_2021_scaling(600000000000, 1500000, 1500000, fees); ASSERT_EQ(fees.size(), 4); ASSERT_EQ(fees[0], 800); ASSERT_EQ(fees[1], 3200); @@ -123,7 +81,7 @@ TEST(fee_2021_scaling, wallet_fee_cases_from_pdf) ASSERT_EQ(fees[3], 800000); fees.clear(); - bc->get_dynamic_base_fee_estimate_2021_scaling(10, 600000000000, 75000000, 1500000, fees); + cryptonote::Blockchain::get_dynamic_base_fee_estimate_2021_scaling(600000000000, 75000000, 1500000, fees); ASSERT_EQ(fees.size(), 4); ASSERT_EQ(fees[0], 800); ASSERT_EQ(fees[1], 3200); diff --git a/tests/unit_tests/serialization.cpp b/tests/unit_tests/serialization.cpp index ab81acefc..2af8012ed 100644 --- a/tests/unit_tests/serialization.cpp +++ b/tests/unit_tests/serialization.cpp @@ -51,11 +51,21 @@ using namespace std; using namespace crypto; +static_assert(!std::is_trivially_copyable<std::vector<unsigned char>>(), + "should fail to compile when applying blob serializer"); +static_assert(!std::is_trivially_copyable<std::string>(), + "should fail to compile when applying blob serializer"); + struct Struct { int32_t a; int32_t b; char blob[8]; + + bool operator==(const Struct &other) const + { + return a == other.a && b == other.b && 0 == memcmp(blob, other.blob, sizeof(blob)); + } }; template <class Archive> @@ -1207,3 +1217,90 @@ TEST(Serialization, adl_free_function) const std::string expected = "{\"custom_fieldname\": " + std::to_string(msg.size()) + '"' + epee::string_tools::buff_to_hex_nodelimer(msg) + "\"}"; EXPECT_EQ(expected, ss.str()); } + +using Tuple3 = std::tuple<uint16_t, std::string, uint64_t>; +using Tuple4 = std::tuple<int32_t, std::string, uint64_t, Struct>; + +TEST(Serialization, tuple_3_4_backwards_compatibility) +{ + std::string serialized; + + //////////////////////////////////////// + + Tuple3 t3{1876, "Hullabaloo", 1963}; + EXPECT_TRUE(::serialization::dump_binary(t3, serialized)); + + EXPECT_EQ("0354070a48756c6c6162616c6f6fab0f", + epee::string_tools::buff_to_hex_nodelimer(serialized)); + + Tuple3 t3_recovered; + EXPECT_TRUE(::serialization::parse_binary(serialized, t3_recovered)); + EXPECT_EQ(t3, t3_recovered); + + ///////////////////////////////////////// + + Tuple4 t4{1999, "Caneck Caneck", (uint64_t)-1, {20229, 242, {1, 1, 2, 3, 5, 8, 13, 21}}}; + EXPECT_TRUE(::serialization::dump_binary(t4, serialized)); + + EXPECT_EQ("04cf0700000d43616e65636b2043616e65636bffffffffffffffffff01054f0000f20000000101020305080d15", + epee::string_tools::buff_to_hex_nodelimer(serialized)); + + Tuple4 t4_recovered; + EXPECT_TRUE(::serialization::parse_binary(serialized, t4_recovered)); + EXPECT_EQ(t4, t4_recovered); +} + +struct Tupler +{ + std::tuple<> t0; + std::tuple<int8_t> t1; + std::tuple<uint8_t, int16_t> t2; + Tuple3 t3_backcompat; + Tuple3 t3_compact; + Tuple4 t4_backcompat; + Tuple4 t4_compact; + std::tuple<uint32_t, std::string, bool, int64_t, Struct> t5; + + BEGIN_SERIALIZE_OBJECT() + FIELD(t0) + FIELD(t1) + FIELD(t2) + FIELD(t3_backcompat) + TUPLE_COMPACT_FIELD(t3_compact) + FIELD(t4_backcompat) + TUPLE_COMPACT_FIELD(t4_compact) + TUPLE_COMPACT_FIELD(t5) + END_SERIALIZE() +}; + +bool operator==(const Tupler &a, const Tupler &b) +{ + return a.t0 == b.t0 && a.t1 == b.t1 && a.t2 == b.t2 && a.t3_backcompat == b.t3_backcompat && + a.t3_compact == b.t3_compact && a.t4_backcompat == b.t4_backcompat && a.t5 == b.t5; +} + +TEST(Serialization, tuple_many_tuples) +{ + Tupler tupler{ + {}, + {69}, + {42, 420}, + {1876, "Hullabaloo", 1963}, + {1876, "Hullabaloo", 1963}, + {1999, "Caneck Caneck", (uint64_t)-1, {20229, 242, {1, 1, 2, 3, 5, 8, 13, 21}}}, + {1999, "Caneck Caneck", (uint64_t)-1, {20229, 242, {1, 1, 2, 3, 5, 8, 13, 21}}}, + {72982, "He is now rising from affluence to poverty.", false, 256, + { + 13, 37, { 1, 1, 1, 2, 3, 7, 11, 26 } + } + } + }; + + std::string serialized; + EXPECT_TRUE(::serialization::dump_binary(tupler, serialized)); + + Tupler tupler_recovered; + EXPECT_TRUE(::serialization::parse_binary(serialized, tupler_recovered)); + + EXPECT_EQ(tupler, tupler_recovered); +} |