Merge pull request #9844

528664b1c cryptonote_protocol: fix handling of pruned blocks during sync (jeffro256)
This commit is contained in:
tobtoht 2025-03-24 02:50:17 +00:00
commit 2d20c4a9b7
No known key found for this signature in database
GPG Key ID: E45B10DD027D2472
2 changed files with 32 additions and 8 deletions

View File

@ -4260,7 +4260,7 @@ leave:
{
tx = std::move(extra_txs_it->second.first);
txblob = std::move(extra_txs_it->second.second);
tx_weight = get_transaction_weight(tx, txblob.size());
tx_weight = tx.pruned ? get_pruned_transaction_weight(tx) : get_transaction_weight(tx, txblob.size());
fee = get_tx_fee(tx);
pruned = tx.pruned;
extra_block_txs.txs_by_txid.erase(extra_txs_it);

View File

@ -81,6 +81,7 @@ namespace cryptonote
inline bool make_pool_supplement_from_block_entry(
const std::vector<cryptonote::tx_blob_entry>& tx_entries,
const CryptoHashContainer& blk_tx_hashes,
const bool allow_pruned,
cryptonote::pool_supplement& pool_supplement)
{
pool_supplement.nic_verified_hf_version = 0;
@ -91,7 +92,7 @@ namespace cryptonote
return false;
}
for (const auto& tx_entry: tx_entries)
for (const cryptonote::tx_blob_entry& tx_entry: tx_entries)
{
if (tx_entry.blob.size() > get_max_tx_size())
{
@ -99,17 +100,38 @@ namespace cryptonote
return false;
}
const bool is_pruned = tx_entry.prunable_hash != crypto::null_hash;
if (is_pruned && !allow_pruned)
{
MERROR("Pruned transaction not allowed here");
return false;
}
cryptonote::transaction tx;
crypto::hash tx_hash;
if (!cryptonote::parse_and_validate_tx_from_blob(tx_entry.blob, tx, tx_hash)
|| !blk_tx_hashes.count(tx_hash)
|| tx.pruned)
bool parse_success = false;
if (is_pruned)
{
MERROR("failed to parse and/or validate unpruned transaction as inside block: "
if ((parse_success = cryptonote::parse_and_validate_tx_base_from_blob(tx_entry.blob, tx)))
tx_hash = cryptonote::get_pruned_transaction_hash(tx, tx_entry.prunable_hash);
}
else
{
parse_success = cryptonote::parse_and_validate_tx_from_blob(tx_entry.blob, tx, tx_hash);
}
if (!parse_success)
{
MERROR("failed to parse and/or validate transaction: "
<< epee::string_tools::buff_to_hex_nodelimer(tx_entry.blob)
);
return false;
}
else if (!blk_tx_hashes.count(tx_hash))
{
MERROR("transaction " << tx_hash << " not in block");
return false;
}
pool_supplement.txs_by_txid.emplace(tx_hash, std::make_pair(std::move(tx), tx_entry.blob));
}
@ -146,7 +168,9 @@ namespace cryptonote
return false;
}
return make_pool_supplement_from_block_entry(blk_entry.txs, blk_tx_hashes, pool_supplement);
// We set `allow_pruned` equal to whether this block entry is pruned since the pruned flag
// should be checked anyways by the time we deserialize transactions
return make_pool_supplement_from_block_entry(blk_entry.txs, blk_tx_hashes, blk_entry.pruned, pool_supplement);
}
@ -624,7 +648,7 @@ namespace cryptonote
// can skip the mempool for faster block propagation. Later in the function, we will erase all
// transactions from the relayed block.
pool_supplement extra_block_txs;
if (!make_pool_supplement_from_block_entry(arg.b.txs, blk_txids_set, extra_block_txs))
if (!make_pool_supplement_from_block_entry(arg.b.txs, blk_txids_set, /*allow_pruned=*/false, extra_block_txs))
{
LOG_ERROR_CCONTEXT
(