Wallet2: fix optimize-coinbase for p2pool payouts

RefreshOptimizeCoinbase was an optimization to speed up scanning of coinbase transactions before RingCT (tx version 2) where they split miner reward into multiple denominations, all to the same wallet.

When RingCT was introduced, all coinbase transactions became 1 output only, so this optimization does nothing now.

With p2pool, this optimization will skip scanning p2pool payouts because they use more than 1 output in coinbase transaction.

Fix it by applying this optimization only to pre-RingCT transactions (version < 2).
This commit is contained in:
SChernykh 2021-08-26 11:50:15 +02:00
parent 2d3ce2d64a
commit e52802baef

View File

@ -1938,7 +1938,7 @@ void wallet2::cache_tx_data(const cryptonote::transaction& tx, const crypto::has
const bool is_miner = tx.vin.size() == 1 && tx.vin[0].type() == typeid(cryptonote::txin_gen); const bool is_miner = tx.vin.size() == 1 && tx.vin[0].type() == typeid(cryptonote::txin_gen);
if (!is_miner || m_refresh_type != RefreshType::RefreshNoCoinbase) if (!is_miner || m_refresh_type != RefreshType::RefreshNoCoinbase)
{ {
const size_t rec_size = is_miner && m_refresh_type == RefreshType::RefreshOptimizeCoinbase ? 1 : tx.vout.size(); const size_t rec_size = (is_miner && m_refresh_type == RefreshType::RefreshOptimizeCoinbase && tx.version < 2) ? 1 : tx.vout.size();
if (!tx.vout.empty()) if (!tx.vout.empty())
{ {
// if tx.vout is not empty, we loop through all tx pubkeys // if tx.vout is not empty, we loop through all tx pubkeys
@ -2087,7 +2087,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
{ {
// assume coinbase isn't for us // assume coinbase isn't for us
} }
else if (miner_tx && m_refresh_type == RefreshOptimizeCoinbase) else if (miner_tx && m_refresh_type == RefreshOptimizeCoinbase && tx.version < 2)
{ {
check_acc_out_precomp_once(tx.vout[0], derivation, additional_derivations, 0, is_out_data_ptr, tx_scan_info[0], output_found[0]); check_acc_out_precomp_once(tx.vout[0], derivation, additional_derivations, 0, is_out_data_ptr, tx_scan_info[0], output_found[0]);
THROW_WALLET_EXCEPTION_IF(tx_scan_info[0].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys()); THROW_WALLET_EXCEPTION_IF(tx_scan_info[0].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
@ -2858,8 +2858,9 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector<cry
if (m_refresh_type != RefreshType::RefreshNoCoinbase) if (m_refresh_type != RefreshType::RefreshNoCoinbase)
{ {
THROW_WALLET_EXCEPTION_IF(txidx >= tx_cache_data.size(), error::wallet_internal_error, "txidx out of range"); THROW_WALLET_EXCEPTION_IF(txidx >= tx_cache_data.size(), error::wallet_internal_error, "txidx out of range");
const size_t n_vouts = m_refresh_type == RefreshType::RefreshOptimizeCoinbase ? 1 : parsed_blocks[i].block.miner_tx.vout.size(); const cryptonote::transaction& tx = parsed_blocks[i].block.miner_tx;
tpool.submit(&waiter, [&, i, n_vouts, txidx](){ geniod(parsed_blocks[i].block.miner_tx, n_vouts, txidx); }, true); const size_t n_vouts = (m_refresh_type == RefreshType::RefreshOptimizeCoinbase && tx.version < 2) ? 1 : tx.vout.size();
tpool.submit(&waiter, [&, i, n_vouts, txidx](){ geniod(tx, n_vouts, txidx); }, true);
} }
++txidx; ++txidx;
for (size_t j = 0; j < parsed_blocks[i].txes.size(); ++j) for (size_t j = 0; j < parsed_blocks[i].txes.size(); ++j)