wallet2: fix task lifetime during parsed block processing

This commit is contained in:
selsta
2026-07-22 21:56:40 +02:00
parent d23e971ae6
commit 2cec172f9d
+12 -10
View File
@@ -3248,7 +3248,6 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect
THROW_WALLET_EXCEPTION_IF(!m_blockchain.is_in_bounds(start_height), error::out_of_hashchain_bounds_error); THROW_WALLET_EXCEPTION_IF(!m_blockchain.is_in_bounds(start_height), error::out_of_hashchain_bounds_error);
tools::threadpool& tpool = tools::threadpool::getInstanceForCompute(); tools::threadpool& tpool = tools::threadpool::getInstanceForCompute();
tools::threadpool::waiter waiter(tpool);
size_t num_txes = 0; size_t num_txes = 0;
std::vector<tx_cache_data> tx_cache_data; std::vector<tx_cache_data> tx_cache_data;
@@ -3258,6 +3257,7 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect
size_t txidx = 0; size_t txidx = 0;
crypto::hash prev_block_id; crypto::hash prev_block_id;
bool has_prev_block = m_blockchain.is_in_bounds(start_height - 1); bool has_prev_block = m_blockchain.is_in_bounds(start_height - 1);
tools::threadpool::waiter cache_waiter(tpool);
if (has_prev_block) { if (has_prev_block) {
prev_block_id = m_blockchain[start_height - 1]; prev_block_id = m_blockchain[start_height - 1];
} }
@@ -3280,16 +3280,16 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect
continue; continue;
} }
if (m_refresh_type != RefreshNoCoinbase) if (m_refresh_type != RefreshNoCoinbase)
tpool.submit(&waiter, [&, i, txidx](){ cache_tx_data(parsed_blocks[i].block.miner_tx, get_transaction_hash(parsed_blocks[i].block.miner_tx), tx_cache_data[txidx]); }); tpool.submit(&cache_waiter, [&, i, txidx](){ cache_tx_data(parsed_blocks[i].block.miner_tx, get_transaction_hash(parsed_blocks[i].block.miner_tx), tx_cache_data[txidx]); });
++txidx; ++txidx;
for (size_t idx = 0; idx < parsed_blocks[i].txes.size(); ++idx) for (size_t idx = 0; idx < parsed_blocks[i].txes.size(); ++idx)
{ {
tpool.submit(&waiter, [&, i, idx, txidx](){ cache_tx_data(parsed_blocks[i].txes[idx], parsed_blocks[i].block.tx_hashes[idx], tx_cache_data[txidx]); }); tpool.submit(&cache_waiter, [&, i, idx, txidx](){ cache_tx_data(parsed_blocks[i].txes[idx], parsed_blocks[i].block.tx_hashes[idx], tx_cache_data[txidx]); });
++txidx; ++txidx;
} }
} }
THROW_WALLET_EXCEPTION_IF(txidx != num_txes, error::wallet_internal_error, "txidx does not match tx_cache_data size"); THROW_WALLET_EXCEPTION_IF(txidx != num_txes, error::wallet_internal_error, "txidx does not match tx_cache_data size");
THROW_WALLET_EXCEPTION_IF(!waiter.wait(), error::wallet_internal_error, "Exception in thread pool"); THROW_WALLET_EXCEPTION_IF(!cache_waiter.wait(), error::wallet_internal_error, "Exception in thread pool");
hw::device &hwdev = m_account.get_device(); hw::device &hwdev = m_account.get_device();
hw::reset_mode rst(hwdev); hw::reset_mode rst(hwdev);
@@ -3305,11 +3305,12 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect
} }
}; };
tools::threadpool::waiter derivation_waiter(tpool);
for (size_t i = 0; i < tx_cache_data.size(); ++i) for (size_t i = 0; i < tx_cache_data.size(); ++i)
{ {
if (tx_cache_data[i].empty()) if (tx_cache_data[i].empty())
continue; continue;
tpool.submit(&waiter, [&gender, &tx_cache_data, i]() { tpool.submit(&derivation_waiter, [&gender, &tx_cache_data, i]() {
auto &slot = tx_cache_data[i]; auto &slot = tx_cache_data[i];
for (auto &iod: slot.primary) for (auto &iod: slot.primary)
gender(iod); gender(iod);
@@ -3317,7 +3318,7 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect
gender(iod); gender(iod);
}, true); }, true);
} }
THROW_WALLET_EXCEPTION_IF(!waiter.wait(), error::wallet_internal_error, "Exception in thread pool"); THROW_WALLET_EXCEPTION_IF(!derivation_waiter.wait(), error::wallet_internal_error, "Exception in thread pool");
auto geniod = [&](const cryptonote::transaction &tx, size_t n_vouts, size_t txidx) { auto geniod = [&](const cryptonote::transaction &tx, size_t n_vouts, size_t txidx) {
for (size_t k = 0; k < n_vouts; ++k) for (size_t k = 0; k < n_vouts; ++k)
@@ -3349,6 +3350,7 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect
std::vector<geniod_params> geniods; std::vector<geniod_params> geniods;
geniods.reserve(num_txes); geniods.reserve(num_txes);
tools::threadpool::waiter output_waiter(tpool);
txidx = 0; txidx = 0;
uint8_t hf_version_view_tags = get_view_tag_fork(); uint8_t hf_version_view_tags = get_view_tag_fork();
for (size_t i = 0; i < blocks.size(); ++i) for (size_t i = 0; i < blocks.size(); ++i)
@@ -3369,7 +3371,7 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect
if (parsed_blocks[i].block.major_version >= hf_version_view_tags) if (parsed_blocks[i].block.major_version >= hf_version_view_tags)
geniods.push_back(geniod_params{ tx, n_vouts, txidx }); geniods.push_back(geniod_params{ tx, n_vouts, txidx });
else else
tpool.submit(&waiter, [&, n_vouts, txidx](){ geniod(tx, n_vouts, txidx); }, true); tpool.submit(&output_waiter, [&, n_vouts, txidx](){ geniod(tx, n_vouts, txidx); }, true);
} }
} }
++txidx; ++txidx;
@@ -3379,7 +3381,7 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect
if (parsed_blocks[i].block.major_version >= hf_version_view_tags) if (parsed_blocks[i].block.major_version >= hf_version_view_tags)
geniods.push_back(geniod_params{ parsed_blocks[i].txes[j], parsed_blocks[i].txes[j].vout.size(), txidx }); geniods.push_back(geniod_params{ parsed_blocks[i].txes[j], parsed_blocks[i].txes[j].vout.size(), txidx });
else else
tpool.submit(&waiter, [&, i, j, txidx](){ geniod(parsed_blocks[i].txes[j], parsed_blocks[i].txes[j].vout.size(), txidx); }, true); tpool.submit(&output_waiter, [&, i, j, txidx](){ geniod(parsed_blocks[i].txes[j], parsed_blocks[i].txes[j].vout.size(), txidx); }, true);
++txidx; ++txidx;
} }
} }
@@ -3398,7 +3400,7 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect
{ {
size_t batch_end = std::min(batch_start + GENIOD_BATCH_SIZE, geniods.size()); size_t batch_end = std::min(batch_start + GENIOD_BATCH_SIZE, geniods.size());
THROW_WALLET_EXCEPTION_IF(batch_end < batch_start, error::wallet_internal_error, "Thread batch end overflow"); THROW_WALLET_EXCEPTION_IF(batch_end < batch_start, error::wallet_internal_error, "Thread batch end overflow");
tpool.submit(&waiter, [&geniods, &geniod, batch_start, batch_end]() { tpool.submit(&output_waiter, [&geniods, &geniod, batch_start, batch_end]() {
for (size_t i = batch_start; i < batch_end; ++i) for (size_t i = batch_start; i < batch_end; ++i)
{ {
const geniod_params &gp = geniods[i]; const geniod_params &gp = geniods[i];
@@ -3410,7 +3412,7 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect
} }
THROW_WALLET_EXCEPTION_IF(num_batch_txes != geniods.size(), error::wallet_internal_error, "txes batched for thread pool did not reach expected value"); THROW_WALLET_EXCEPTION_IF(num_batch_txes != geniods.size(), error::wallet_internal_error, "txes batched for thread pool did not reach expected value");
} }
THROW_WALLET_EXCEPTION_IF(!waiter.wait(), error::wallet_internal_error, "Exception in thread pool"); THROW_WALLET_EXCEPTION_IF(!output_waiter.wait(), error::wallet_internal_error, "Exception in thread pool");
hwdev.set_mode(hw::device::NONE); hwdev.set_mode(hw::device::NONE);