From 71ef04d9e6277cd2c6af0ef0a6577a10c699b677 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 26 Nov 2021 16:06:44 +0300 Subject: [PATCH 01/14] checkpoints: get_checkpoint_before_height() added with unit tests (+ unit tests for is_in_checkpoint_zone()) --- src/currency_core/checkpoints.cpp | 27 ++++++++++++++-- src/currency_core/checkpoints.h | 2 ++ tests/unit_tests/check_points_test.cpp | 45 ++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/currency_core/checkpoints.cpp b/src/currency_core/checkpoints.cpp index 2d997691..3dacc47e 100644 --- a/src/currency_core/checkpoints.cpp +++ b/src/currency_core/checkpoints.cpp @@ -36,11 +36,11 @@ namespace currency if(height > blockchain_last_block_height) return false; - auto it = m_points.lower_bound(height); + auto it = m_points.lower_bound(height); // if found, it->first >= height if(it == m_points.end()) return false; if(it->first <= blockchain_last_block_height) - return true; + return true; // this is the case only if height <= it->first <= blockchain_last_block_height else return false; } @@ -68,4 +68,27 @@ namespace currency return false; } } + //--------------------------------------------------------------------------- + uint64_t checkpoints::get_checkpoint_before_height(uint64_t height) const + { + // returns height of the leftmost CP with height that is LESS than the given height + // ex: + // If there are two CP at 11 and 15: + // get_checkpoint_before_height(10) = 0 + // get_checkpoint_before_height(11) = 0 + // get_checkpoint_before_height(12) = 11 + // get_checkpoint_before_height(13) = 11 + // get_checkpoint_before_height(14) = 11 + // get_checkpoint_before_height(15) = 11 + // get_checkpoint_before_height(16) = 15 + + uint64_t top_cp = get_top_checkpoint_height(); + if (height > top_cp) + return top_cp; + + auto it = m_points.lower_bound(height); // if found, it->first >= height + if (it == m_points.end() || --it == m_points.end()) + return 0; + return it->first; + } } diff --git a/src/currency_core/checkpoints.h b/src/currency_core/checkpoints.h index a845e6eb..76675e67 100644 --- a/src/currency_core/checkpoints.h +++ b/src/currency_core/checkpoints.h @@ -20,6 +20,8 @@ namespace currency bool is_height_passed_zone(uint64_t height, uint64_t blockchain_last_block_height) const; bool check_block(uint64_t height, const crypto::hash& h) const; uint64_t get_top_checkpoint_height() const; + + uint64_t get_checkpoint_before_height(uint64_t height) const; private: std::map m_points; }; diff --git a/tests/unit_tests/check_points_test.cpp b/tests/unit_tests/check_points_test.cpp index 543e2ac6..0c9e5c26 100644 --- a/tests/unit_tests/check_points_test.cpp +++ b/tests/unit_tests/check_points_test.cpp @@ -39,3 +39,48 @@ TEST(checkpoints_test, test_checkpoints_for_alternative) r = cp.is_height_passed_zone(11, 12); ASSERT_FALSE(r); } + +TEST(checkpoints_test, get_checkpoint_before_height) +{ + currency::checkpoints cp; + cp.add_checkpoint(11, "0000000000000000000000000000000000000000000000000000000000000000"); + cp.add_checkpoint(15, "0000000000000000000000000000000000000000000000000000000000000000"); + cp.add_checkpoint(21, "0000000000000000000000000000000000000000000000000000000000000000"); + + for(uint64_t h = 0; h < 11; ++h) + ASSERT_TRUE(cp.get_checkpoint_before_height(h) == 0); + + ASSERT_TRUE(cp.get_checkpoint_before_height(11) == 0); + + ASSERT_TRUE(cp.get_checkpoint_before_height(12) == 11); + ASSERT_TRUE(cp.get_checkpoint_before_height(13) == 11); + ASSERT_TRUE(cp.get_checkpoint_before_height(14) == 11); + ASSERT_TRUE(cp.get_checkpoint_before_height(15) == 11); + + ASSERT_TRUE(cp.get_checkpoint_before_height(16) == 15); + ASSERT_TRUE(cp.get_checkpoint_before_height(17) == 15); + ASSERT_TRUE(cp.get_checkpoint_before_height(18) == 15); + ASSERT_TRUE(cp.get_checkpoint_before_height(19) == 15); + ASSERT_TRUE(cp.get_checkpoint_before_height(20) == 15); + ASSERT_TRUE(cp.get_checkpoint_before_height(21) == 15); + + ASSERT_TRUE(cp.get_checkpoint_before_height(22) == 21); + + for(uint64_t h = 22; h < 100; ++h) + ASSERT_TRUE(cp.get_checkpoint_before_height(h) == 21); +} + + +TEST(checkpoints_test, is_in_checkpoint_zone) +{ + currency::checkpoints cp; + cp.add_checkpoint(11, "0000000000000000000000000000000000000000000000000000000000000000"); + cp.add_checkpoint(15, "0000000000000000000000000000000000000000000000000000000000000000"); + cp.add_checkpoint(21, "0000000000000000000000000000000000000000000000000000000000000000"); + + for (uint64_t h = 0; h < 22; ++h) + ASSERT_TRUE(cp.is_in_checkpoint_zone(h)); + + for (uint64_t h = 22; h < 100; ++h) + ASSERT_FALSE(cp.is_in_checkpoint_zone(h)); +} From f86459935a4c98eeb938ef97a26951831f34651a Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 26 Nov 2021 16:08:43 +0300 Subject: [PATCH 02/14] coretests fixed after moving to json format of gui config --- tests/core_tests/chaingen_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index b50044b6..763b1a94 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -57,7 +57,7 @@ bool clean_data_directory() { std::string config_folder = command_line::get_arg(g_vm, command_line::arg_data_dir); - static const std::set files = { CURRENCY_POOLDATA_FOLDERNAME_OLD, CURRENCY_BLOCKCHAINDATA_FOLDERNAME_OLD, P2P_NET_DATA_FILENAME, MINER_CONFIG_FILENAME, GUI_SECURE_CONFIG_FILENAME, GUI_CONFIG_FILENAME, GUI_INTERNAL_CONFIG }; + static const std::set files = { CURRENCY_POOLDATA_FOLDERNAME_OLD, CURRENCY_BLOCKCHAINDATA_FOLDERNAME_OLD, P2P_NET_DATA_FILENAME, MINER_CONFIG_FILENAME, GUI_SECURE_CONFIG_FILENAME, GUI_CONFIG_FILENAME, GUI_INTERNAL_CONFIG2 }; static const std::set prefixes = { CURRENCY_POOLDATA_FOLDERNAME_PREFIX, CURRENCY_BLOCKCHAINDATA_FOLDERNAME_PREFIX }; std::vector entries_to_remove; From 5c15ef7bcc1e9fd1e88212cac6382c312f9fc612 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 26 Nov 2021 16:10:30 +0300 Subject: [PATCH 03/14] coretests: checkpoints_test improved to support multiple CPs, gen_checkpoints_set_after_switching_to_altchain test added --- tests/core_tests/chaingen_main.cpp | 1 + tests/core_tests/checkpoints_tests.cpp | 82 +++++++++++++++++++++++++- tests/core_tests/checkpoints_tests.h | 10 ++++ 3 files changed, 90 insertions(+), 3 deletions(-) diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 763b1a94..2dc1eef6 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -814,6 +814,7 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY(gen_checkpoints_reorganize); 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(gen_no_attchments_in_coinbase_gentime); diff --git a/tests/core_tests/checkpoints_tests.cpp b/tests/core_tests/checkpoints_tests.cpp index da68a5fd..d1ec860a 100644 --- a/tests/core_tests/checkpoints_tests.cpp +++ b/tests/core_tests/checkpoints_tests.cpp @@ -36,13 +36,18 @@ bool checkpoints_test::set_checkpoint(currency::core& c, size_t ev_index, const { if (pcp.hash != null_hash && pcp.hash != get_block_hash(b)) continue; - currency::checkpoints cp; - cp.add_checkpoint(currency::get_block_height(b), epee::string_tools::pod_to_hex(currency::get_block_hash(b))); - c.set_checkpoints(std::move(cp)); + m_local_checkpoints.add_checkpoint(pcp.height, epee::string_tools::pod_to_hex(currency::get_block_hash(b))); + c.set_checkpoints(currency::checkpoints(m_local_checkpoints)); + LOG_PRINT_YELLOW("CHECKPOINT set at height " << pcp.height, LOG_LEVEL_0); + + //for(uint64_t h = 0; h <= pcp.height + 1; ++h) + // LOG_PRINT_MAGENTA("%% " << h << " : " << m_local_checkpoints.get_checkpoint_before_height(h), LOG_LEVEL_0); return true; } } + LOG_ERROR("set_checkpoint failed trying to set checkpoint at height " << pcp.height); + return false; } @@ -895,3 +900,74 @@ bool gen_checkpoints_and_invalid_tx_to_pool::c1(currency::core& c, size_t ev_ind return true; } +//------------------------------------------------------------------------------ + +gen_checkpoints_set_after_switching_to_altchain::gen_checkpoints_set_after_switching_to_altchain() +{ + REGISTER_CALLBACK_METHOD(gen_checkpoints_set_after_switching_to_altchain, prune_blockchain); +} + +bool gen_checkpoints_set_after_switching_to_altchain::generate(std::vector& events) const +{ + // Test idea: make sure + + // 0 ... N N+1 N+2 N+3 N+4 N+5 N+6 <- height (N = CURRENCY_MINED_MONEY_UNLOCK_WINDOW) + // tx1 + // (0 )- (0r)- (1 )- (2a)- (3a)- <- alt chain + // \ + // \- (2 )- <- main chain + + bool r = false; + GENERATE_ACCOUNT(miner_acc); + GENERATE_ACCOUNT(alice_acc); + MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, test_core_time::get_time()); + + REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + + DO_CALLBACK(events, "check_not_being_in_cp_zone"); + + MAKE_NEXT_BLOCK(events, blk_1, blk_0r, miner_acc); + MAKE_TX(events, tx1, miner_acc, alice_acc, MK_TEST_COINS(1), blk_1); + MAKE_NEXT_BLOCK_TX1(events, blk_2a, blk_1, miner_acc, tx1); + MAKE_NEXT_BLOCK(events, blk_3a, blk_2a, miner_acc); + + DO_CALLBACK(events, "check_not_being_in_cp_zone"); + + // 0 ... N N+1 N+2 N+3 N+4 N+5 N+6 <- height (N = CURRENCY_MINED_MONEY_UNLOCK_WINDOW) + // +-----------> CP <- checkpoint + // tx1 | + // (0 )- (0r)- (1 )- (2a)- (3a)- <- alt chain + // \ | <- when CP set up + // \- (2 )- (3 )- (4 )- (5 )- (6 )- <- main chain + + DO_CALLBACK_PARAMS(events, "set_checkpoint", params_checkpoint(CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5)); + DO_CALLBACK(events, "prune_blockchain"); + + MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner_acc); + MAKE_NEXT_BLOCK(events, blk_3, blk_2, miner_acc); + MAKE_NEXT_BLOCK(events, blk_4, blk_3, miner_acc); + MAKE_NEXT_BLOCK(events, blk_5, blk_4, miner_acc); // <-- CHECKPOINT + MAKE_NEXT_BLOCK(events, blk_6, blk_5, miner_acc); + + return true; +} + +bool gen_checkpoints_set_after_switching_to_altchain::prune_blockchain(currency::core& c, size_t ev_index, const std::vector& events) +{ + bool r = false; + uint64_t height = 0; + uint64_t transactions_pruned = 0, signatures_pruned = 0, attachments_pruned = 0; + + c.get_blockchain_storage().prune_ring_signatures_and_attachments_if_need(); + + /*for (uint64_t height = 1, size = c.get_current_blockchain_size(); height < size; ++height) + { + r = c.get_blockchain_storage().prune_ring_signatures_and_attachments(height, transactions_pruned, signatures_pruned, attachments_pruned); + CHECK_AND_ASSERT_MES(r, false, "prune_ring_signatures_and_attachments failed for height " << height); + } + + // make sure only one tx was pruned (namely, tx1) + CHECK_AND_ASSERT_MES(transactions_pruned == 1, false, "incorrect number of pruned txs: " << transactions_pruned); + */ + return true; +} diff --git a/tests/core_tests/checkpoints_tests.h b/tests/core_tests/checkpoints_tests.h index 67f84a12..01ff5f68 100644 --- a/tests/core_tests/checkpoints_tests.h +++ b/tests/core_tests/checkpoints_tests.h @@ -23,6 +23,9 @@ protected: uint64_t height; crypto::hash hash; }; + +private: + currency::checkpoints m_local_checkpoints; }; struct gen_checkpoints_attachments_basic : public checkpoints_test @@ -109,3 +112,10 @@ struct gen_checkpoints_and_invalid_tx_to_pool : public checkpoints_test bool generate(std::vector& events) const; bool c1(currency::core& c, size_t ev_index, const std::vector& events); }; + +struct gen_checkpoints_set_after_switching_to_altchain : public checkpoints_test +{ + gen_checkpoints_set_after_switching_to_altchain(); + bool generate(std::vector& events) const; + bool prune_blockchain(currency::core& c, size_t ev_index, const std::vector& events); +}; From 0b1b2d5bdf5f0f556d8a507c8e8f23ef1750f272 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 26 Nov 2021 16:23:41 +0300 Subject: [PATCH 04/14] coretests: trying not to mess with blockchainstorage too much --- tests/core_tests/checkpoints_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core_tests/checkpoints_tests.cpp b/tests/core_tests/checkpoints_tests.cpp index d1ec860a..33698163 100644 --- a/tests/core_tests/checkpoints_tests.cpp +++ b/tests/core_tests/checkpoints_tests.cpp @@ -958,7 +958,7 @@ bool gen_checkpoints_set_after_switching_to_altchain::prune_blockchain(currency: uint64_t height = 0; uint64_t transactions_pruned = 0, signatures_pruned = 0, attachments_pruned = 0; - c.get_blockchain_storage().prune_ring_signatures_and_attachments_if_need(); + //c.get_blockchain_storage().prune_ring_signatures_and_attachments_if_need(); /*for (uint64_t height = 1, size = c.get_current_blockchain_size(); height < size; ++height) { From ba912973cf21e221f6fdd1615c41b5513282ed93 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 26 Nov 2021 17:23:50 +0300 Subject: [PATCH 05/14] bcs: minor fixes --- src/currency_core/blockchain_storage.cpp | 8 +++++--- src/currency_core/blockchain_storage.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 54813472..3335c94c 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -578,13 +578,13 @@ bool blockchain_storage::set_checkpoints(checkpoints&& chk_pts) catch (const std::exception& ex) { m_db.abort_transaction(); - LOG_ERROR("UNKNOWN EXCEPTION WHILE ADDINIG NEW BLOCK: " << ex.what()); + LOG_ERROR("UNKNOWN EXCEPTION WHILE SETTING CHECKPOINTS: " << ex.what()); return false; } catch (...) { m_db.abort_transaction(); - LOG_ERROR("UNKNOWN EXCEPTION WHILE ADDINIG NEW BLOCK."); + LOG_ERROR("UNKNOWN EXCEPTION WHILE SETTING CHECKPOINTS."); return false; } @@ -1036,7 +1036,9 @@ void blockchain_storage::purge_alt_block_txs_hashs(const block& b) //------------------------------------------------------------------ void blockchain_storage::do_erase_altblock(alt_chain_container::iterator it) { - purge_altblock_keyimages_from_big_heap(it->second.bl, get_block_hash(it->second.bl)); + crypto::hash id = get_block_hash(it->second.bl); + LOG_PRINT_L1("erasing alt block " << print16(id) << " @ " << get_block_height(it->second.bl)); + purge_altblock_keyimages_from_big_heap(it->second.bl, id); purge_alt_block_txs_hashs(it->second.bl); m_alternative_chains.erase(it); } diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index 7cb02c41..cad2ca91 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -396,7 +396,7 @@ namespace currency else { CHECK_AND_ASSERT_MES(*block_ind_ptr < m_db_blocks.size(), false, "Internal error: bl_id=" << string_tools::pod_to_hex(bl_id) - << " have index record with offset=" << *block_ind_ptr << ", bigger then m_blocks.size()=" << m_db_blocks.size()); + << " have index record with offset=" << *block_ind_ptr << ", bigger then m_db_blocks.size()=" << m_db_blocks.size()); blocks.push_back(m_db_blocks[*block_ind_ptr]->bl); } } From de15869c27b7a28e0eedd20a0c9699e008260f68 Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 27 Nov 2021 03:30:05 +0300 Subject: [PATCH 06/14] coretests: gen_checkpoints_set_after_switching_to_altchain fixed to fail if no fix present --- tests/core_tests/checkpoints_tests.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/core_tests/checkpoints_tests.cpp b/tests/core_tests/checkpoints_tests.cpp index 33698163..ab06f8aa 100644 --- a/tests/core_tests/checkpoints_tests.cpp +++ b/tests/core_tests/checkpoints_tests.cpp @@ -945,10 +945,17 @@ bool gen_checkpoints_set_after_switching_to_altchain::generate(std::vector Date: Sat, 27 Nov 2021 05:26:36 +0300 Subject: [PATCH 07/14] blockchain_storage::prune_ring_signatures_and_attachments_if_need() fixed (it could prune txs in cases when chain switching was still possible) --- src/currency_core/blockchain_storage.cpp | 26 +++++++++++------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 3335c94c..b247c050 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -626,22 +626,20 @@ bool blockchain_storage::prune_ring_signatures_and_attachments_if_need() { CRITICAL_REGION_LOCAL(m_read_lock); - if (m_db_blocks.size() > 1 && m_checkpoints.get_top_checkpoint_height() && m_checkpoints.get_top_checkpoint_height() > m_db_current_pruned_rs_height) - { - uint64_t pruning_last_height = std::min(m_db_blocks.size() - 1, m_checkpoints.get_top_checkpoint_height()); - if (pruning_last_height > m_db_current_pruned_rs_height) + uint64_t top_block_height = get_top_block_height(); + uint64_t pruning_end_height = m_checkpoints.get_checkpoint_before_height(top_block_height); + if (pruning_end_height > m_db_current_pruned_rs_height) + { + LOG_PRINT_CYAN("Starting pruning ring signatues and attachments from height " << m_db_current_pruned_rs_height + 1 << " to height " << pruning_end_height + << " (" << pruning_end_height - m_db_current_pruned_rs_height << " blocks)", LOG_LEVEL_0); + uint64_t tx_count = 0, sig_count = 0, attach_count = 0; + for(uint64_t height = m_db_current_pruned_rs_height + 1; height <= pruning_end_height; height++) { - LOG_PRINT_CYAN("Starting pruning ring signatues and attachments from height " << m_db_current_pruned_rs_height + 1 << " to height " << pruning_last_height - << " (" << pruning_last_height - m_db_current_pruned_rs_height << " blocks)", LOG_LEVEL_0); - uint64_t tx_count = 0, sig_count = 0, attach_count = 0; - for(uint64_t height = m_db_current_pruned_rs_height + 1; height <= pruning_last_height; height++) - { - bool res = prune_ring_signatures_and_attachments(height, tx_count, sig_count, attach_count); - CHECK_AND_ASSERT_MES(res, false, "failed to prune_ring_signatures_and_attachments for height = " << height); - } - m_db_current_pruned_rs_height = pruning_last_height; - LOG_PRINT_CYAN("Transaction pruning finished: " << sig_count << " signatures and " << attach_count << " attachments released in " << tx_count << " transactions.", LOG_LEVEL_0); + bool res = prune_ring_signatures_and_attachments(height, tx_count, sig_count, attach_count); + CHECK_AND_ASSERT_MES(res, false, "failed to prune_ring_signatures_and_attachments for height = " << height); } + m_db_current_pruned_rs_height = pruning_end_height; + LOG_PRINT_CYAN("Transaction pruning finished: " << sig_count << " signatures and " << attach_count << " attachments released in " << tx_count << " transactions.", LOG_LEVEL_0); } return true; } From 03a828228c12e14729bba1e487b3078951812bc1 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 29 Nov 2021 04:50:30 +0300 Subject: [PATCH 08/14] coretests: 1) gen_checkpoints_prun_txs_after_blockchain_load fixed to reflect new rules on tx pruning; 2) final touches to gen_checkpoints_set_after_switching_to_altchain --- tests/core_tests/checkpoints_tests.cpp | 45 ++++++++++---------------- tests/core_tests/checkpoints_tests.h | 1 - 2 files changed, 17 insertions(+), 29 deletions(-) diff --git a/tests/core_tests/checkpoints_tests.cpp b/tests/core_tests/checkpoints_tests.cpp index ab06f8aa..254a05e6 100644 --- a/tests/core_tests/checkpoints_tests.cpp +++ b/tests/core_tests/checkpoints_tests.cpp @@ -400,8 +400,13 @@ bool gen_checkpoints_prun_txs_after_blockchain_load::generate(std::vector attach; + attach.push_back(tx_comment{"jokes are funny"}); + + // tx pool won't accept the tx, because it cannot be verified in CP zone + // set kept_by_block flag, so tx_0 be accepted + events.push_back(event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, true)); + MAKE_TX_ATTACH(events, tx_0, miner_acc, alice, MK_TEST_COINS(1), blk_0r, attach); events.push_back(event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, false)); MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0); @@ -412,11 +417,12 @@ bool gen_checkpoints_prun_txs_after_blockchain_load::generate(std::vector& events) const { - // Test idea: make sure + // Test outline: + // 0) no checkpoints are set; + // 1) core is in a subchain, that will become alternative; + // 2) checkpoint is set (in the furute), transaction pruning is executed; + // 3) core continues to sync, chain switching occurs + // Make sure that chain switching is still possible after pruning. // 0 ... N N+1 N+2 N+3 N+4 N+5 N+6 <- height (N = CURRENCY_MINED_MONEY_UNLOCK_WINDOW) // tx1 @@ -941,7 +951,6 @@ bool gen_checkpoints_set_after_switching_to_altchain::generate(std::vector& events) -{ - bool r = false; - uint64_t height = 0; - uint64_t transactions_pruned = 0, signatures_pruned = 0, attachments_pruned = 0; - - //c.get_blockchain_storage().prune_ring_signatures_and_attachments_if_need(); - - /*for (uint64_t height = 1, size = c.get_current_blockchain_size(); height < size; ++height) - { - r = c.get_blockchain_storage().prune_ring_signatures_and_attachments(height, transactions_pruned, signatures_pruned, attachments_pruned); - CHECK_AND_ASSERT_MES(r, false, "prune_ring_signatures_and_attachments failed for height " << height); - } - - // make sure only one tx was pruned (namely, tx1) - CHECK_AND_ASSERT_MES(transactions_pruned == 1, false, "incorrect number of pruned txs: " << transactions_pruned); - */ - return true; -} diff --git a/tests/core_tests/checkpoints_tests.h b/tests/core_tests/checkpoints_tests.h index 01ff5f68..672d9b42 100644 --- a/tests/core_tests/checkpoints_tests.h +++ b/tests/core_tests/checkpoints_tests.h @@ -117,5 +117,4 @@ struct gen_checkpoints_set_after_switching_to_altchain : public checkpoints_test { gen_checkpoints_set_after_switching_to_altchain(); bool generate(std::vector& events) const; - bool prune_blockchain(currency::core& c, size_t ev_index, const std::vector& events); }; From 5f0b5f8f55c4330103a409a78cd68a8a9bd648c3 Mon Sep 17 00:00:00 2001 From: sowle Date: Mon, 29 Nov 2021 23:46:33 +0300 Subject: [PATCH 09/14] unittests: checkpoints_test.get_checkpoint_before_height_1 and checkpoints_test.get_checkpoint_before_height_2 tests added --- tests/unit_tests/check_points_test.cpp | 47 +++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/tests/unit_tests/check_points_test.cpp b/tests/unit_tests/check_points_test.cpp index 0c9e5c26..ab2372c1 100644 --- a/tests/unit_tests/check_points_test.cpp +++ b/tests/unit_tests/check_points_test.cpp @@ -40,14 +40,53 @@ TEST(checkpoints_test, test_checkpoints_for_alternative) ASSERT_FALSE(r); } -TEST(checkpoints_test, get_checkpoint_before_height) + +TEST(checkpoints_test, get_checkpoint_before_height_1) +{ + currency::checkpoints cp; + cp.add_checkpoint(15, "0000000000000000000000000000000000000000000000000000000000000000"); + + for (uint64_t h = 0; h <= 15; ++h) + ASSERT_TRUE(cp.get_checkpoint_before_height(h) == 0); + + ASSERT_TRUE(cp.get_checkpoint_before_height(16) == 15); + + for (uint64_t h = 17; h < 100; ++h) + ASSERT_TRUE(cp.get_checkpoint_before_height(h) == 15); +} + + +TEST(checkpoints_test, get_checkpoint_before_height_2) +{ + currency::checkpoints cp; + cp.add_checkpoint(11, "0000000000000000000000000000000000000000000000000000000000000000"); + cp.add_checkpoint(15, "0000000000000000000000000000000000000000000000000000000000000000"); + + for (uint64_t h = 0; h < 11; ++h) + ASSERT_TRUE(cp.get_checkpoint_before_height(h) == 0); + + ASSERT_TRUE(cp.get_checkpoint_before_height(11) == 0); + + ASSERT_TRUE(cp.get_checkpoint_before_height(12) == 11); + ASSERT_TRUE(cp.get_checkpoint_before_height(13) == 11); + ASSERT_TRUE(cp.get_checkpoint_before_height(14) == 11); + ASSERT_TRUE(cp.get_checkpoint_before_height(15) == 11); + + ASSERT_TRUE(cp.get_checkpoint_before_height(16) == 15); + + for (uint64_t h = 17; h < 100; ++h) + ASSERT_TRUE(cp.get_checkpoint_before_height(h) == 15); +} + + +TEST(checkpoints_test, get_checkpoint_before_height_3) { currency::checkpoints cp; cp.add_checkpoint(11, "0000000000000000000000000000000000000000000000000000000000000000"); cp.add_checkpoint(15, "0000000000000000000000000000000000000000000000000000000000000000"); cp.add_checkpoint(21, "0000000000000000000000000000000000000000000000000000000000000000"); - for(uint64_t h = 0; h < 11; ++h) + for (uint64_t h = 0; h < 11; ++h) ASSERT_TRUE(cp.get_checkpoint_before_height(h) == 0); ASSERT_TRUE(cp.get_checkpoint_before_height(11) == 0); @@ -63,10 +102,10 @@ TEST(checkpoints_test, get_checkpoint_before_height) ASSERT_TRUE(cp.get_checkpoint_before_height(19) == 15); ASSERT_TRUE(cp.get_checkpoint_before_height(20) == 15); ASSERT_TRUE(cp.get_checkpoint_before_height(21) == 15); - + ASSERT_TRUE(cp.get_checkpoint_before_height(22) == 21); - for(uint64_t h = 22; h < 100; ++h) + for (uint64_t h = 22; h < 100; ++h) ASSERT_TRUE(cp.get_checkpoint_before_height(h) == 21); } From e99d4ad8e24602c3c30f57215cdbb83d7b934eef Mon Sep 17 00:00:00 2001 From: sowle Date: Tue, 30 Nov 2021 00:20:51 +0300 Subject: [PATCH 10/14] get_checkpoint_before_height() fixed (rare case in gcc when CPs < 3) --- src/currency_core/checkpoints.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/currency_core/checkpoints.cpp b/src/currency_core/checkpoints.cpp index 3dacc47e..bbce9815 100644 --- a/src/currency_core/checkpoints.cpp +++ b/src/currency_core/checkpoints.cpp @@ -87,8 +87,8 @@ namespace currency return top_cp; auto it = m_points.lower_bound(height); // if found, it->first >= height - if (it == m_points.end() || --it == m_points.end()) + if (it == m_points.end() || it == m_points.begin()) return 0; - return it->first; + return (--it)->first; } } From 0ad4ab6c52a3146c8a5a3d22136ff34d6a3f4d6c Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 1 Dec 2021 05:19:11 +0300 Subject: [PATCH 11/14] coretests: wallet_spend_form_auditable_and_track test added --- tests/core_tests/chaingen_main.cpp | 3 ++ tests/core_tests/wallet_tests.cpp | 82 ++++++++++++++++++++++++++++++ tests/core_tests/wallet_tests.h | 9 ++++ 3 files changed, 94 insertions(+) diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 2dc1eef6..3e9cbc80 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -743,6 +743,9 @@ int main(int argc, char* argv[]) #undef MARK_TEST_AS_POSTPONED + + // TODO // GENERATE_AND_PLAY(wallet_spend_form_auditable_and_track); + GENERATE_AND_PLAY(pos_minting_tx_packing); GENERATE_AND_PLAY(multisig_wallet_test); diff --git a/tests/core_tests/wallet_tests.cpp b/tests/core_tests/wallet_tests.cpp index ab62563f..f4f2e027 100644 --- a/tests/core_tests/wallet_tests.cpp +++ b/tests/core_tests/wallet_tests.cpp @@ -3553,5 +3553,87 @@ bool wallet_watch_only_and_chain_switch::c1(currency::core& c, size_t ev_index, CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt, MK_TEST_COINS(7), false, UINT64_MAX, 0, 0, MK_TEST_COINS(7), 0), false, ""); + return true; +} + +//------------------------------------------------------------------------------ + +wallet_spend_form_auditable_and_track::wallet_spend_form_auditable_and_track() +{ + REGISTER_CALLBACK_METHOD(wallet_spend_form_auditable_and_track, c1); +} + +bool wallet_spend_form_auditable_and_track::generate(std::vector& events) const +{ + bool r = false; + + m_accounts.resize(TOTAL_ACCS_COUNT); + account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); + account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(true); // Alice has auditable wallet + account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc = alice_acc; bob_acc.make_account_watch_only(); // Bob has Alice's tracking wallet + + MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, test_core_time::get_time()); + REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); + + MAKE_TX(events, tx_1, miner_acc, alice_acc, MK_TEST_COINS(5), blk_0r); + + MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_1); + REWIND_BLOCKS_N(events, blk_1r, blk_1, miner_acc, WALLET_DEFAULT_TX_SPENDABLE_AGE); + + std::vector attachments; + tx_comment comment_attachment = AUTO_VAL_INIT(comment_attachment); + m_comment = "Jokes are funny!"; + comment_attachment.comment = m_comment; + attachments.push_back(comment_attachment); + MAKE_TX_ATTACH(events, tx_2, alice_acc, miner_acc, MK_TEST_COINS(1), blk_1r, attachments); + + MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1r, miner_acc, tx_2); + + DO_CALLBACK(events, "c1"); + + return true; +} + +bool wallet_spend_form_auditable_and_track::c1(currency::core& c, size_t ev_index, const std::vector& events) +{ + bool r = false; + std::shared_ptr miner_wlt = init_playtime_test_wallet(events, c, MINER_ACC_IDX); + std::shared_ptr alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX); + std::shared_ptr bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX); + + // make sure Alice's wallet is autibale and not watch-only + CHECK_AND_ASSERT_MES(!alice_wlt->is_watch_only() && alice_wlt->is_auditable(), false, "incorrect type of Alice's wallet"); + // make sure Bob's wallet is a tracking wallet + CHECK_AND_ASSERT_MES(bob_wlt->is_watch_only() && bob_wlt->is_auditable(), false, "incorrect type of Bob's wallet"); + + const account_public_address& bob_addr = bob_wlt->get_account().get_public_address(); + const account_public_address& alice_addr = alice_wlt->get_account().get_public_address(); + + // make sure their addresses are linked indeed + CHECK_AND_ASSERT_MES(bob_addr.view_public_key == alice_addr.view_public_key && bob_addr.spend_public_key == alice_addr.spend_public_key, false, + "Bob's tracking wallet address is not linked with Alice's one"); + + CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count()); + + bob_wlt->refresh(); + + // check the balances + CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt, MK_TEST_COINS(3), false, UINT64_MAX, 0, 0, 0, 0), false, ""); + CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt, MK_TEST_COINS(3), false, UINT64_MAX, 0, 0, 0, 0), false, ""); + + r = false; + bool r_comment = false; + bob_wlt->enumerate_transfers_history([&](const tools::wallet_public::wallet_transfer_info& wti) { + if (wti.amount == MK_TEST_COINS(5)) + { + r_comment = (wti.comment == m_comment); + if (!r_comment) + return false; // stop + } + return true; // continue + }, true); + CHECK_AND_ASSERT_MES(r, false, "cannot get comment from tx"); + CHECK_AND_ASSERT_MES(r_comment, false, "wrong comment got from tx"); + return true; } diff --git a/tests/core_tests/wallet_tests.h b/tests/core_tests/wallet_tests.h index 17c83bcd..eb54960b 100644 --- a/tests/core_tests/wallet_tests.h +++ b/tests/core_tests/wallet_tests.h @@ -276,3 +276,12 @@ struct wallet_watch_only_and_chain_switch : public wallet_test mutable crypto::hash m_split_point_block_id; mutable uint64_t m_split_point_block_height; }; + +struct wallet_spend_form_auditable_and_track : public wallet_test +{ + wallet_spend_form_auditable_and_track(); + bool generate(std::vector& events) const; + bool c1(currency::core& c, size_t ev_index, const std::vector& events); + + mutable std::string m_comment; +}; From 708fb4c40bea0db2d5fd354882c6ddc4b60ce83e Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 1 Dec 2021 12:29:28 +0300 Subject: [PATCH 12/14] bcs: minor improvements --- src/currency_core/blockchain_storage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index b247c050..6bb47719 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -594,7 +594,7 @@ bool blockchain_storage::prune_ring_signatures_and_attachments(uint64_t height, { CRITICAL_REGION_LOCAL(m_read_lock); - CHECK_AND_ASSERT_MES(height < m_db_blocks.size(), false, "prune_ring_signatures called with wrong parameter: " << height << ", m_blocks.size() " << m_db_blocks.size()); + CHECK_AND_ASSERT_MES(height < m_db_blocks.size(), false, "prune_ring_signatures called with wrong parameter: " << height << ", m_blocks.size() = " << m_db_blocks.size()); auto vptr = m_db_blocks[height]; CHECK_AND_ASSERT_MES(vptr.get(), false, "Failed to get block on height"); @@ -631,7 +631,7 @@ bool blockchain_storage::prune_ring_signatures_and_attachments_if_need() if (pruning_end_height > m_db_current_pruned_rs_height) { LOG_PRINT_CYAN("Starting pruning ring signatues and attachments from height " << m_db_current_pruned_rs_height + 1 << " to height " << pruning_end_height - << " (" << pruning_end_height - m_db_current_pruned_rs_height << " blocks)", LOG_LEVEL_0); + << " (" << pruning_end_height - m_db_current_pruned_rs_height << " blocks), top block height is " << top_block_height, LOG_LEVEL_0); uint64_t tx_count = 0, sig_count = 0, attach_count = 0; for(uint64_t height = m_db_current_pruned_rs_height + 1; height <= pruning_end_height; height++) { From ba35377d45dbadbbdcf5ca6cdeecc755f2dbb6c5 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 2 Dec 2021 16:45:25 +0100 Subject: [PATCH 13/14] fixed #313 --- src/gui/qt-daemon/application/mainwindow.cpp | 34 ++++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/qt-daemon/application/mainwindow.cpp index acdaef1c..083c2afd 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/qt-daemon/application/mainwindow.cpp @@ -548,15 +548,29 @@ void MainWindow::restore_pos(bool consider_showed) } else { - - QPoint pos; - QSize sz; - pos.setX(m_config.m_window_position.first); - pos.setY(m_config.m_window_position.second); - sz.setHeight(m_config.m_window_size.first); - sz.setWidth(m_config.m_window_size.second); - this->move(pos); - this->resize(sz); + QPoint point = QApplication::desktop()->screenGeometry().bottomRight(); + if (m_config.m_window_position.first + m_config.m_window_size.second > point.x() || + m_config.m_window_position.second + m_config.m_window_size.first > point.y() + ) + { + QSize sz = AUTO_VAL_INIT(sz); + sz.setHeight(770); + sz.setWidth(1200); + this->resize(sz); + store_window_pos(); + //reset position(screen changed or other reason) + } + else + { + QPoint pos = AUTO_VAL_INIT(pos); + QSize sz = AUTO_VAL_INIT(sz); + pos.setX(m_config.m_window_position.first); + pos.setY(m_config.m_window_position.second); + sz.setHeight(m_config.m_window_size.first); + sz.setWidth(m_config.m_window_size.second); + this->move(pos); + this->resize(sz); + } } if (consider_showed) @@ -645,7 +659,7 @@ bool MainWindow::show_inital() { m_config = AUTO_VAL_INIT(m_config); this->show(); - QSize sz; + QSize sz = AUTO_VAL_INIT(sz); sz.setHeight(770); sz.setWidth(1200); this->resize(sz); From 0b1c09154724ad6129bab8e6adefe02203ac58d8 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 2 Dec 2021 16:47:03 +0100 Subject: [PATCH 14/14] pulled zano_ui to latest commit again --- src/gui/qt-daemon/layout | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qt-daemon/layout b/src/gui/qt-daemon/layout index 6299e301..20f9219e 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 6299e3014aea2f1c5055405f37f0e9de4afc60dd +Subproject commit 20f9219e5f782e019983680791a59b79701e0081