diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 9d842fdf..01521feb 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1201,7 +1201,7 @@ bool simple_wallet::show_staking_history(const std::vector& args) bool transfers_found = false; for (auto it = transfers.rbegin(); it != transfers.rend(); it++) { - const auto& td = *it; + const auto& td = it->second; if (timestamp && td.m_ptx_wallet_info->m_block_timestamp < timestamp) break; @@ -1263,8 +1263,9 @@ bool simple_wallet::show_incoming_transfers(const std::vector& args m_wallet->get_transfers(transfers); bool transfers_found = false; - for (const auto& td : transfers) + for (const auto& tr : transfers) { + const auto& td = tr.second; if (!filter || available != static_cast(td.m_flags&WALLET_TRANSFER_DETAIL_FLAG_SPENT)) { if (!transfers_found) @@ -1307,8 +1308,9 @@ bool simple_wallet::show_incoming_transfers_counts(const std::vector& stop) + void wallet2::pull_blocks(size_t& blocks_added, std::atomic& stop, bool& full_reset_needed) { blocks_added = 0; currency::COMMAND_RPC_GET_BLOCKS_DIRECT::request req = AUTO_VAL_INIT(req); @@ -2028,12 +2028,16 @@ namespace tools "wrong daemon response: m_start_height=" + std::to_string(res.start_height) + " not less than local blockchain size=" + std::to_string(get_blockchain_current_size())); - handle_pulled_blocks(blocks_added, stop, res); + handle_pulled_blocks(blocks_added, stop, res, full_reset_needed); + if (full_reset_needed) + { + reset_all(); + } } //---------------------------------------------------------------------------------------------------- void wallet2::handle_pulled_blocks(size_t& blocks_added, std::atomic& stop, - currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& res) + currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& res, bool& wallet_reset_needed) { size_t current_index = res.start_height; m_last_known_daemon_height = res.current_height; @@ -2116,6 +2120,11 @@ namespace tools } //TODO: take into account date of wallet creation //reorganize + if (m_concise_mode && m_chain.get_blockchain_current_size() - (last_matched_index+1) > m_wallet_concise_mode_max_reorg_blocks) + { + wallet_reset_needed = true; + return; + } detach_blockchain(last_matched_index + 1); process_new_blockchain_entry(bl, bl_entry, bl_id, height); ++blocks_added; @@ -2853,6 +2862,7 @@ namespace tools blocks_fetched = 0; size_t added_blocks = 0; size_t try_count = 0; + size_t reset_count = 0; crypto::hash last_tx_hash_id = m_transfers.size() ? get_transaction_hash((--m_transfers.end())->second.m_ptx_wallet_info->m_tx) : null_hash; m_height_of_start_sync = get_blockchain_current_size(); m_last_sync_percent = 0; @@ -2860,7 +2870,20 @@ namespace tools { try { - pull_blocks(added_blocks, stop); + bool full_reset_needed = false; + pull_blocks(added_blocks, stop, full_reset_needed); + if (full_reset_needed) + { + if (reset_count > 1) + { + WLT_LOG_L0("Intenral error: reset_count infinit loop catch"); + if (m_wcallback) + m_wcallback->on_message(tools::i_wallet2_callback::ms_red, "Internal error: reset_count infinite loop catch"); + return; + } + reset_count++; + continue; + } blocks_fetched += added_blocks; if (!added_blocks) break; @@ -3802,10 +3825,10 @@ namespace tools } //delete from recent_history - if (m_transfer_history.size() > WALLET_CONCISE_MODE_MAX_HISTORY_SIZE) - { - m_transfer_history.erase(m_transfer_history.begin(), m_transfer_history.end() - WALLET_CONCISE_MODE_MAX_HISTORY_SIZE); - } + //if (m_transfer_history.size() > WALLET_CONCISE_MODE_MAX_HISTORY_SIZE) + //{ + // m_transfer_history.erase(m_transfer_history.begin(), m_transfer_history.end() - WALLET_CONCISE_MODE_MAX_HISTORY_SIZE); + //} return true; } diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 58f119e9..f8922d54 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -151,8 +151,7 @@ namespace tools uint64_t m_last_pow_block_h = 0; std::list> m_rollback_events; std::list > m_last_zc_global_indexs; // , biggest height comes in front - - std::atomic m_concise_mode = false; //in this mode the wallet don't keep spent entries in m_transfers as well as m_recent_transfers longer then 100 entries + //variables that not being serialized std::atomic m_last_bc_timestamp = 0; @@ -253,7 +252,7 @@ namespace tools { return; } - a& m_concise_mode; + } }; @@ -754,6 +753,8 @@ namespace tools bool is_in_hardfork_zone(uint64_t hardfork_index) const; //performance inefficient call, suitable only for rare ocasions or super lazy developers bool proxy_to_daemon(const std::string& uri, const std::string& body, int& response_code, std::string& response_body); + void set_concise_mode(bool enabled) { m_concise_mode = enabled; } + void set_concise_mode_reorg_max_reorg_blocks(uint64_t max_blocks) { m_wallet_concise_mode_max_reorg_blocks = max_blocks; } construct_tx_param get_default_construct_tx_param(); @@ -788,7 +789,7 @@ private: bool on_idle(); void unserialize_block_complete_entry(const currency::COMMAND_RPC_GET_BLOCKS_FAST::response& serialized, currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& unserialized); - void pull_blocks(size_t& blocks_added, std::atomic& stop); + void pull_blocks(size_t& blocks_added, std::atomic& stop, bool& full_reset_needed); bool prepare_free_transfers_cache(uint64_t fake_outputs_count); bool select_transfers(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust, std::vector& selected_indicies); void add_transfers_to_transfers_cache(const std::vector& indexs); @@ -809,7 +810,7 @@ private: void add_to_last_zc_global_indexs(uint64_t h, uint64_t last_zc_output_index); uint64_t get_actual_zc_global_index(); void handle_pulled_blocks(size_t& blocks_added, std::atomic& stop, - currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& blocks); + currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& blocks, bool& full_reset_needed); std::string get_alias_for_address(const std::string& addr); std::vector get_aliases_for_address(const std::string& addr); bool is_connected_to_net(); @@ -972,8 +973,9 @@ private: std::string m_votes_config_path; tools::wallet_public::wallet_vote_config m_votes_config; + std::atomic m_concise_mode = true; //in this mode the wallet don't keep spent entries in m_transfers as well as m_recent_transfers longer then 100 entries uint64_t m_last_known_daemon_height = 0; - uint64_t m_wallet_concise_mode_max_reorg_blocks = WALLET_CONCISE_MODE_MAX_REORG_BLOCKS; + uint64_t m_wallet_concise_mode_max_reorg_blocks = 5;//WALLET_CONCISE_MODE_MAX_REORG_BLOCKS; //this needed to access wallets state in coretests, for creating abnormal blocks and tranmsactions diff --git a/tests/core_tests/atomic_tests.cpp b/tests/core_tests/atomic_tests.cpp index f04d984a..bff1c87a 100644 --- a/tests/core_tests/atomic_tests.cpp +++ b/tests/core_tests/atomic_tests.cpp @@ -52,7 +52,7 @@ bool atomic_base_test::generate(std::vector& events) const test_core_time::adjust(m_genesis_timestamp); - epee::debug::get_set_enable_assert(true, true); + //epee::debug::get_set_enable_assert(true, true); currency::account_base genesis_acc; genesis_acc.generate(); @@ -68,7 +68,7 @@ bool atomic_base_test::generate(std::vector& events) const REWIND_BLOCKS_N(events, blk_0r, blk_0, m_mining_accunt, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5); DO_CALLBACK(events, "c1"); - epee::debug::get_set_enable_assert(true, false); + //epee::debug::get_set_enable_assert(true, false); return true; } @@ -78,8 +78,8 @@ bool atomic_base_test::generate(std::vector& events) const bool atomic_simple_test::c1(currency::core& c, size_t ev_index, const std::vector& events) { - epee::debug::get_set_enable_assert(true, true); - misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([&](){epee::debug::get_set_enable_assert(true, false); }); + //epee::debug::get_set_enable_assert(true, true); + //misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([&](){epee::debug::get_set_enable_assert(true, false); }); /* diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index d31857a2..5aceba54 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -1293,6 +1293,7 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY_HF(asset_emission_and_unconfirmed_balance, "4-*"); GENERATE_AND_PLAY_HF(pos_fuse_test, "4-*"); + GENERATE_AND_PLAY_HF(wallet_reorganize_and_trim_test, "4-*"); diff --git a/tests/core_tests/cumulative_diificulty_adjustments_tests.cpp b/tests/core_tests/cumulative_diificulty_adjustments_tests.cpp index 35040e15..7e7c40b4 100644 --- a/tests/core_tests/cumulative_diificulty_adjustments_tests.cpp +++ b/tests/core_tests/cumulative_diificulty_adjustments_tests.cpp @@ -14,7 +14,7 @@ using namespace currency; cumulative_difficulty_adjustment_test::cumulative_difficulty_adjustment_test() { - epee::debug::get_set_enable_assert(true, true); + //epee::debug::get_set_enable_assert(true, true); REGISTER_CALLBACK_METHOD(cumulative_difficulty_adjustment_test, configure_core); REGISTER_CALLBACK_METHOD(cumulative_difficulty_adjustment_test, configure_check_height1); REGISTER_CALLBACK_METHOD(cumulative_difficulty_adjustment_test, memorize_main_chain); @@ -25,7 +25,7 @@ cumulative_difficulty_adjustment_test::cumulative_difficulty_adjustment_test() } cumulative_difficulty_adjustment_test::~cumulative_difficulty_adjustment_test() { - epee::debug::get_set_enable_assert(true, false); + //epee::debug::get_set_enable_assert(true, false); } #define FIRST_ALIAS_NAME "first" #define SECOND_ALIAS_NAME "second" diff --git a/tests/core_tests/escrow_wallet_tests.cpp b/tests/core_tests/escrow_wallet_tests.cpp index ea32cfd1..b511aaab 100644 --- a/tests/core_tests/escrow_wallet_tests.cpp +++ b/tests/core_tests/escrow_wallet_tests.cpp @@ -32,7 +32,7 @@ escrow_wallet_test::escrow_wallet_test() bool escrow_wallet_test::generate(std::vector& events) const { - epee::debug::get_set_enable_assert(true, true); + //epee::debug::get_set_enable_assert(true, true); currency::account_base genesis_acc; genesis_acc.generate(); @@ -47,7 +47,7 @@ bool escrow_wallet_test::generate(std::vector& events) const DO_CALLBACK(events, "c1"); - epee::debug::get_set_enable_assert(true, false); + //epee::debug::get_set_enable_assert(true, false); return true; } @@ -272,8 +272,8 @@ bool escrow_wallet_test::exec_test_with_cancel_release_type(currency::core& c, c bool escrow_wallet_test::c1(currency::core& c, size_t ev_index, const std::vector& events) { - epee::debug::get_set_enable_assert(true, true); - misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([&](){epee::debug::get_set_enable_assert(true, false); }); + //epee::debug::get_set_enable_assert(true, true); + //misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([&](){epee::debug::get_set_enable_assert(true, false); }); bool r = exec_test_with_cancel_release_type(c, events); if (!r) @@ -287,7 +287,7 @@ bool escrow_wallet_test::c1(currency::core& c, size_t ev_index, const std::vecto if (!r) return false; - epee::debug::get_set_enable_assert(true, false); + //epee::debug::get_set_enable_assert(true, false); return r; } diff --git a/tests/core_tests/isolate_auditable_and_proof.cpp b/tests/core_tests/isolate_auditable_and_proof.cpp index b363ba12..f676c8a1 100644 --- a/tests/core_tests/isolate_auditable_and_proof.cpp +++ b/tests/core_tests/isolate_auditable_and_proof.cpp @@ -32,7 +32,7 @@ bool isolate_auditable_and_proof::generate(std::vector& events test_core_time::adjust(m_genesis_timestamp); - epee::debug::get_set_enable_assert(true, true); + //epee::debug::get_set_enable_assert(true, true); currency::account_base genesis_acc; genesis_acc.generate(); @@ -47,7 +47,7 @@ bool isolate_auditable_and_proof::generate(std::vector& events REWIND_BLOCKS_N(events, blk_0r, blk_0, m_mining_accunt, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 15); DO_CALLBACK(events, "c1"); - epee::debug::get_set_enable_assert(true, false); + //epee::debug::get_set_enable_assert(true, false); return true; } @@ -61,8 +61,8 @@ bool isolate_auditable_and_proof::configure_core(currency::core& c, size_t ev_in bool isolate_auditable_and_proof::c1(currency::core& c, size_t ev_index, const std::vector& events) { - epee::debug::get_set_enable_assert(true, true); - misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([&](){epee::debug::get_set_enable_assert(true, false); }); + //epee::debug::get_set_enable_assert(true, true); + //misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([&](){epee::debug::get_set_enable_assert(true, false); }); LOG_PRINT_MAGENTA("Mining Address: " << currency::get_account_address_as_str(m_mining_accunt.get_public_address()), LOG_LEVEL_0); diff --git a/tests/core_tests/wallet_tests.cpp b/tests/core_tests/wallet_tests.cpp index cba1fadb..e6bc9f5b 100644 --- a/tests/core_tests/wallet_tests.cpp +++ b/tests/core_tests/wallet_tests.cpp @@ -3908,3 +3908,64 @@ bool block_template_blacklist_test::c1(currency::core& c, size_t ev_index, const return true; } + +wallet_reorganize_and_trim_test::wallet_reorganize_and_trim_test() +{ + REGISTER_CALLBACK_METHOD(wallet_reorganize_and_trim_test, c1); +} + + +bool wallet_reorganize_and_trim_test::generate(std::vector& events) const +{ + uint64_t ts = test_core_time::get_time(); + m_accounts.resize(1); + account_base preminer_acc; + preminer_acc.generate(); + preminer_acc.set_createtime(ts); + account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts); + MAKE_GENESIS_BLOCK(events, blk_0, preminer_acc, ts); + DO_CALLBACK(events, "configure_core"); + + MAKE_NEXT_BLOCK(events, blk_1, blk_0, preminer_acc); + + REWIND_BLOCKS_N_WITH_TIME(events, blk_1r, blk_1, miner_acc, 2 * CURRENCY_MINED_MONEY_UNLOCK_WINDOW - 1); + + DO_CALLBACK(events, "c1"); + return true; + +} +bool wallet_reorganize_and_trim_test::c1(currency::core& c, size_t ev_index, const std::vector& events) +{ + std::shared_ptr miner_wlt = init_playtime_test_wallet(events, c, MINER_ACC_IDX); + //mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, 2); +#define WALLET_REORGANIZE_AND_TRIM_TEST_REORG_SIZE 10 + miner_wlt->set_concise_mode(true); + miner_wlt->set_concise_mode_reorg_max_reorg_blocks(6); + + account_base acc; + acc.generate(); + std::shared_ptr alice = init_playtime_test_wallet(events, c, acc); + miner_wlt->refresh(); + miner_wlt->transfer(COIN, alice->get_account().get_public_address()); + mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, 2); + + mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, WALLET_REORGANIZE_AND_TRIM_TEST_REORG_SIZE); + uint64_t h1 = c.get_blockchain_storage().get_top_block_height(); + miner_wlt->refresh(); + uint64_t unlocked = 0; + uint64_t total = miner_wlt->balance(unlocked); + + c.get_blockchain_storage().truncate_blockchain(c.get_blockchain_storage().get_top_block_height() - (WALLET_REORGANIZE_AND_TRIM_TEST_REORG_SIZE-1)); + mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, 10); + uint64_t h2 = c.get_blockchain_storage().get_top_block_height(); + miner_wlt->refresh(); + uint64_t unlocked2 = 0; + uint64_t total2 = miner_wlt->balance(unlocked2); + if (unlocked2 != unlocked || total2 != total) + { + CHECK_AND_ASSERT_MES(false, false, "wallet concise mode check failed"); + } + return true; +} + + diff --git a/tests/core_tests/wallet_tests.h b/tests/core_tests/wallet_tests.h index cad3871e..ab7a109c 100644 --- a/tests/core_tests/wallet_tests.h +++ b/tests/core_tests/wallet_tests.h @@ -301,4 +301,11 @@ struct block_template_blacklist_test : public wallet_test block_template_blacklist_test(); bool generate(std::vector& events) const; bool c1(currency::core& c, size_t ev_index, const std::vector& events); +}; + +struct wallet_reorganize_and_trim_test : public wallet_test +{ + wallet_reorganize_and_trim_test(); + bool generate(std::vector& events) const; + bool c1(currency::core& c, size_t ev_index, const std::vector& events); }; \ No newline at end of file diff --git a/tests/functional_tests/core_concurrency_test.cpp b/tests/functional_tests/core_concurrency_test.cpp index c0b70781..3fcbc00c 100644 --- a/tests/functional_tests/core_concurrency_test.cpp +++ b/tests/functional_tests/core_concurrency_test.cpp @@ -450,7 +450,7 @@ namespace boost bool core_concurrency_test(boost::program_options::variables_map& vm, size_t wthreads, size_t rthreads, size_t blocks_count) { log_space::get_set_log_detalisation_level(true, LOG_LEVEL_0); - //epee::debug::get_set_enable_assert(true, false); + epee::debug::get_set_enable_assert(true, false); log_space::get_set_need_thread_id(true, true); cct_accounts_t accounts(s_wallets_total_count);