1
0
Fork 0
forked from lthn/blockchain

wallet truncating fixed all core tests

This commit is contained in:
cryptozoidberg 2024-09-08 22:42:31 +04:00
parent 9c2e2bb0f8
commit 1eeb9a4a81
No known key found for this signature in database
GPG key ID: 2E10CC61CAC8F36D
7 changed files with 66 additions and 18 deletions

View file

@ -842,7 +842,7 @@ namespace tools
{
const currency::txout_htlc& hltc = out_get_htlc(out_v);
//mark this as spent
td.m_flags |= WALLET_TRANSFER_DETAIL_FLAG_SPENT;
td.m_flags |= WALLET_TRANSFER_DETAIL_FLAG_SPENT|WALLET_TRANSFER_DETAIL_CONCISE_MODE_PRESERVE;
//create entry for htlc input
htlc_expiration_trigger het = AUTO_VAL_INIT(het);
het.is_wallet_owns_redeem = (out_key == hltc.pkey_redeem) ? true : false;
@ -2028,10 +2028,27 @@ 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, full_reset_needed);
try
{
handle_pulled_blocks(blocks_added, stop, res, full_reset_needed);
}
catch (const tools::error::wallet_error_resync_needed& /*v*/)
{
full_reset_needed = true;
m_full_resync_requested_at_h = get_blockchain_current_size() - blocks_added;
}
if (full_reset_needed)
{
//back up m_unconfirmed_txs
//back up std::unordered_map<crypto::hash, crypto::secret_key> m_tx_keys;
unconfirmed_txs_container tmp_unconfirmed = m_unconfirmed_txs;
tx_secrete_keys_container tmp_secrete_keys = m_tx_keys;
crypto::hash genesis = m_chain.get_genesis();
reset_all();
m_chain.set_genesis(genesis);
m_unconfirmed_txs = tmp_unconfirmed;
m_tx_keys = tmp_secrete_keys;
}
}
@ -2120,8 +2137,9 @@ 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)
if (m_concise_mode && m_chain.get_blockchain_current_size() - (last_matched_index) > m_wallet_concise_mode_max_reorg_blocks)
{
m_full_resync_requested_at_h = m_chain.get_blockchain_current_size() - (last_matched_index + 1);
wallet_reset_needed = true;
return;
}
@ -2858,6 +2876,7 @@ namespace tools
{
load_whitelisted_tokens_if_not_loaded();
bool had_full_reset = false;
received_money = false;
blocks_fetched = 0;
size_t added_blocks = 0;
@ -2882,6 +2901,8 @@ namespace tools
return;
}
reset_count++;
m_height_of_start_sync = 0;
had_full_reset = true;
continue;
}
blocks_fetched += added_blocks;
@ -2919,7 +2940,12 @@ namespace tools
handle_expiration_list(tx_expiration_ts_median);
handle_contract_expirations(tx_expiration_ts_median);
m_found_free_amounts.clear();
trim_wallet();
truncate_wallet();
}
if (had_full_reset)
{
blocks_fetched = get_blockchain_current_size() - m_full_resync_requested_at_h;
m_full_resync_requested_at_h = 0;
}
@ -3792,28 +3818,28 @@ namespace tools
return true;
}
//----------------------------------------------------------------------------------------------------
bool wallet2::trim_wallet()
bool wallet2::truncate_wallet()
{
if (m_concise_mode)
{
std::list<size_t> items_to_remove;
for (auto& tr : m_transfers)
{
if (tr.second.is_spent())
if (tr.second.is_spent() && tr.second.m_spent_height != 0 && !(tr.second.m_flags & WALLET_TRANSFER_DETAIL_CONCISE_MODE_PRESERVE) )
{
if (m_concise_mode && tr.second.m_spent_height + m_wallet_concise_mode_max_reorg_blocks < m_chain.get_top_block_height())
if (tr.second.m_spent_height + m_wallet_concise_mode_max_reorg_blocks < m_chain.get_top_block_height())
{
items_to_remove.push_back(tr.first);
}
}
}
return trim_transfers_and_history(items_to_remove);
return truncate_transfers_and_history(items_to_remove);
}
return true;
}
//----------------------------------------------------------------------------------------------------
bool wallet2::trim_transfers_and_history(const std::list<size_t>& items_to_remove)
bool wallet2::truncate_transfers_and_history(const std::list<size_t>& items_to_remove)
{
//delete from m_transfers
for (auto item : items_to_remove)
@ -6070,6 +6096,10 @@ namespace tools
{
for (auto htlc_entry : m_active_htlcs_txid)
{
//auto it = m_transfers.find(htlc_entry.second);
//if (it == m_transfers.end())
// continue;
//const transfer_details& td = it->second;
const transfer_details& td = m_transfers.at(htlc_entry.second);
if (only_redeem_txs && !(td.m_flags & WALLET_TRANSFER_DETAIL_FLAG_HTLC_REDEEM))
{

View file

@ -136,9 +136,9 @@ namespace tools
std::unordered_map<crypto::key_image, size_t> m_key_images;
std::vector<wallet_public::wallet_transfer_info> m_transfer_history;
std::unordered_map<crypto::hash, currency::transaction> m_unconfirmed_in_transfers;
std::unordered_map<crypto::hash, tools::wallet_public::wallet_transfer_info> m_unconfirmed_txs;
unconfirmed_txs_container m_unconfirmed_txs;
std::unordered_set<crypto::hash> m_unconfirmed_multisig_transfers;
std::unordered_map<crypto::hash, crypto::secret_key> m_tx_keys;
tx_secrete_keys_container m_tx_keys;
std::unordered_map<crypto::public_key, wallet_own_asset_context> m_own_asset_descriptors;
std::unordered_map<crypto::public_key, currency::asset_descriptor_base> m_custom_assets; //assets that manually added by user
mutable std::unordered_map<crypto::public_key, currency::asset_descriptor_base> m_whitelisted_assets; //assets that whitelisted
@ -577,8 +577,8 @@ namespace tools
currency::transaction &escrow_template_tx);
bool check_connection();
bool trim_transfers_and_history(const std::list<size_t>& items_to_remove);
bool trim_wallet();
bool truncate_transfers_and_history(const std::list<size_t>& items_to_remove);
bool truncate_wallet();
// PoS mining
void do_pos_mining_prepare_entry(mining_context& cxt, const transfer_details& td);
@ -976,7 +976,7 @@ private:
std::atomic<bool> 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 = 5;//WALLET_CONCISE_MODE_MAX_REORG_BLOCKS;
uint64_t m_full_resync_requested_at_h = 0;
//this needed to access wallets state in coretests, for creating abnormal blocks and tranmsactions
friend class test_generator;
@ -1089,7 +1089,13 @@ namespace tools
if (tr_index != UINT64_MAX)
{
transfer_details& td = m_transfers.at(tr_index);
auto it_tr = m_transfers.find(tr_index);
if (it_tr == m_transfers.end())
{
throw tools::error::wallet_error_resync_needed();
}
transfer_details& td = it_tr->second;
ptc.total_balance_change[td.get_asset_id()] -= td.amount();
if (td.is_native_coin())
{

View file

@ -52,6 +52,7 @@
#define WALLET_TRANSFER_DETAIL_FLAG_MINED_TRANSFER uint32_t(1 << 3)
#define WALLET_TRANSFER_DETAIL_FLAG_COLD_SIG_RESERVATION uint32_t(1 << 4) // transfer is reserved for cold-signing (unsigned tx was created and passed for signing)
#define WALLET_TRANSFER_DETAIL_FLAG_HTLC_REDEEM uint32_t(1 << 5) // for htlc keeps info if this htlc belong as redeem or as refund
#define WALLET_TRANSFER_DETAIL_CONCISE_MODE_PRESERVE uint32_t(1 << 6) // do not truncate this output with CONCISE mode
@ -516,6 +517,8 @@ namespace tools
typedef std::map<uint64_t, std::set<size_t> > free_amounts_cache_type;
typedef std::unordered_map<crypto::public_key, free_amounts_cache_type> free_assets_amounts_cache_type;
typedef std::unordered_map<std::pair<uint64_t, uint64_t>, uint64_t> amount_gindex_to_transfer_id_container; // maps [amount; gindex] -> tid
typedef std::unordered_map<crypto::hash, crypto::secret_key> tx_secrete_keys_container;
typedef std::unordered_map<crypto::hash, tools::wallet_public::wallet_transfer_info> unconfirmed_txs_container;
}// namespace tools

View file

@ -321,6 +321,10 @@ namespace tools
const currency::transaction m_tx;
};
//----------------------------------------------------------------------------------------------------
struct wallet_error_resync_needed
{
};
struct tx_parse_error : public refresh_error
{
explicit tx_parse_error(std::string&& loc, const currency::blobdata& tx_blob)

View file

@ -317,7 +317,8 @@ bool escrow_altchain_meta_impl::c1(currency::core& c, size_t ev_index, const std
alice_wlt->scan_tx_pool(stub);
size_t blocks_fetched = 0;
alice_wlt->refresh(blocks_fetched);
CHECK_AND_ASSERT_MES(blocks_fetched == se.expected_blocks, false, "Alice got " << blocks_fetched << " after refresh, but " << se.expected_blocks << " is expected");
//fetched blocks disabled since resync might happened on different situation and number of blocks_fetched might be unexpected
//CHECK_AND_ASSERT_MES(blocks_fetched == se.expected_blocks, false, "Alice got " << blocks_fetched << " after refresh, but " << se.expected_blocks << " is expected");
LOG_PRINT_GREEN("Alice's transfers:" << ENDL << alice_wlt->dump_trunsfers(), LOG_LEVEL_1);
if (se.a_balance != UINT64_MAX)
{
@ -335,7 +336,8 @@ bool escrow_altchain_meta_impl::c1(currency::core& c, size_t ev_index, const std
bob_wlt->scan_tx_pool(stub);
blocks_fetched = 0;
bob_wlt->refresh(blocks_fetched);
CHECK_AND_ASSERT_MES(blocks_fetched == se.expected_blocks, false, "Bob got " << blocks_fetched << " after refresh, but " << se.expected_blocks << " is expected");
//fetched blocks disabled since resync might happened on different situation and number of blocks_fetched might be unexpected
//CHECK_AND_ASSERT_MES(blocks_fetched == se.expected_blocks, false, "Bob got " << blocks_fetched << " after refresh, but " << se.expected_blocks << " is expected");
LOG_PRINT_GREEN("Bob's transfers:" << ENDL << bob_wlt->dump_trunsfers(), LOG_LEVEL_1);
if (se.b_balance != UINT64_MAX)
{

View file

@ -89,7 +89,7 @@ bool wallet_test_core_proxy::call_COMMAND_RPC_GET_BLOCKS_FAST(const currency::CO
rsp.current_height = m_blocks.size();
rsp.status = API_RETURN_CODE_OK;
if (!m_first_call)
if (!m_first_call && rsp.start_height != 0 /*second condition needed for re-sync in concise_mode*/)
{
m_first_call = true;
return true; // respond with empty blocks on second call to gracefully stop wallet refreshing

View file

@ -1490,6 +1490,9 @@ bool gen_wallet_decrypted_attachments::generate(std::vector<test_event_entry>& e
REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
CREATE_TEST_WALLET(alice_wlt, alice_acc, blk_0);
//disable concise because this test count on on_transfer callbacks and resync cause firing on_transfer() for previous transactions
alice_wlt->set_concise_mode(false);
REFRESH_TEST_WALLET_AT_GEN_TIME(events, alice_wlt, blk_0r, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
// these attachments will be used across all the transactions in this test