1
0
Fork 0
forked from lthn/blockchain

tx pool: remove stuck txs with key image conflicts from pool once conflicted tx has enough confirmations in the blockchain (closes #52)

This commit is contained in:
sowle 2019-10-17 14:07:32 +03:00
parent 87a294e58b
commit 2ba3f5afac
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC

View file

@ -32,6 +32,8 @@ DISABLE_VS_WARNINGS(4244 4345 4503) //'boost::foreach_detail_::or_' : decorated
#define TRANSACTION_POOL_OPTIONS_ID_STORAGE_MAJOR_COMPATIBILITY_VERSION 92 // DON'T CHANGE THIS, if you need to resync db! Change TRANSACTION_POOL_MAJOR_COMPATIBILITY_VERSION instead!
#define TRANSACTION_POOL_MAJOR_COMPATIBILITY_VERSION BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION + 1
#define CONFLICT_KEY_IMAGE_SPENT_DEPTH_TO_REMOVE_TX_FROM_POOL 50 // if there's a conflict in key images between tx in the pool and in the blockchain this much depth in required to remove correspongin tx from pool
#undef LOG_DEFAULT_CHANNEL
#define LOG_DEFAULT_CHANNEL "tx_pool"
ENABLE_CHANNEL_BY_DEFAULT("tx_pool");
@ -427,18 +429,41 @@ namespace currency
int64_t tx_age = get_core_time() - tx_entry.receive_time;
if ((tx_age > CURRENCY_MEMPOOL_TX_LIVETIME ))
{
LOG_PRINT_L0("Tx " << h << " removed from tx pool, reason: outdated, age: " << tx_age);
LOG_PRINT_L0("tx " << h << " is about to be removed from tx pool, reason: outdated, age: " << tx_age << " = " << misc_utils::get_time_interval_string(tx_age));
to_delete.push_back(tx_to_delete_entry(h, tx_entry.tx, tx_entry.kept_by_block));
}
// expiration time check - remove expired
if (is_tx_expired(tx_entry.tx, tx_expiration_ts_median) )
{
LOG_PRINT_L0("Tx " << h << " removed from tx pool, reason: expired, expiration time: " << get_tx_expiration_time(tx_entry.tx) << ", blockchain median: " << tx_expiration_ts_median);
LOG_PRINT_L0("tx " << h << " is about to be removed from tx pool, reason: expired, expiration time: " << get_tx_expiration_time(tx_entry.tx) << ", blockchain median: " << tx_expiration_ts_median);
to_delete.push_back(tx_to_delete_entry(h, tx_entry.tx, tx_entry.kept_by_block));
}
// if a tx has at least one key image already used in blockchain (deep enough) -- remove such tx, as it cannot be added to any block
// although it will be removed by the age check above, we consider desireable
// to remove it from the pool faster in order to unblock related key images used in the same tx
uint64_t should_be_spent_before_height = m_blockchain.get_current_blockchain_size() - 1;
if (should_be_spent_before_height > CONFLICT_KEY_IMAGE_SPENT_DEPTH_TO_REMOVE_TX_FROM_POOL)
{
should_be_spent_before_height -= CONFLICT_KEY_IMAGE_SPENT_DEPTH_TO_REMOVE_TX_FROM_POOL;
for (auto& in : tx_entry.tx.vin)
{
if (in.type() == typeid(txin_to_key))
{
// if at least one key image is spent deep enought -- remove such tx
const crypto::key_image& ki = boost::get<txin_to_key>(in).k_image;
if (m_blockchain.have_tx_keyimg_as_spent(ki, should_be_spent_before_height))
{
LOG_PRINT_L0("tx " << h << " is about to be removed from tx pool, reason: ki was spent in the blockchain before height " << should_be_spent_before_height << ", tx age: " << misc_utils::get_time_interval_string(tx_age));
to_delete.push_back(tx_to_delete_entry(h, tx_entry.tx, tx_entry.kept_by_block));
return true;
}
}
}
}
return true;
});