From 31a59785b0b3f678ea29fcfb63902f051c4e7ce0 Mon Sep 17 00:00:00 2001 From: mydesktop Date: Sun, 25 May 2014 20:25:37 -0400 Subject: temporary fix for block reward dos --- src/cryptonote_core/tx_pool.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'src/cryptonote_core/tx_pool.cpp') diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 24e5752ad..37f4632a9 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -355,13 +355,35 @@ namespace cryptonote total_size = 0; fee = 0; - size_t max_total_size = 2 * median_size - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; + size_t max_total_size = 2 * median_size - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; // Max block size std::unordered_set k_images; BOOST_FOREACH(transactions_container::value_type& tx, m_transactions) { + // Can not exceed maximum block size if (max_total_size < total_size + tx.second.blob_size) continue; + // Check to see if the minimum fee is included + if (tx.second.fee < DEFAULT_FEE) + continue; + + // Skip transactions that are too large + // TODO: Correct upper_transactions_size_limit + // such that it is based on median block size; + // We need to make a similar patch for + // wallet2.h + uint64_t upper_transaction_size_limit = ((CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; + if (tx.second.blob_size > upper_transaction_size_limit) + continue; + + // If we've exceeded the penalty free size, + // stop including more tx + if (total_size > median_size) + continue; + + // Skip transactions that are not ready to be + // included into the blockchain or that are + // missing key images if (!is_transaction_ready_to_go(tx.second) || have_key_images(k_images, tx.second.tx)) continue; -- cgit v1.2.3 From f545fd8ff04d66667c10c7668c0529c578e29db0 Mon Sep 17 00:00:00 2001 From: mydesktop Date: Mon, 26 May 2014 19:51:22 -0400 Subject: maximum block size 130% of median --- src/cryptonote_core/tx_pool.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src/cryptonote_core/tx_pool.cpp') diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 37f4632a9..a95002dc8 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -357,13 +357,18 @@ namespace cryptonote size_t max_total_size = 2 * median_size - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; // Max block size std::unordered_set k_images; + + // Tx size limit as in wallet2.h + uint64_t upper_transaction_size_limit = ((CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; + BOOST_FOREACH(transactions_container::value_type& tx, m_transactions) { // Can not exceed maximum block size if (max_total_size < total_size + tx.second.blob_size) continue; - // Check to see if the minimum fee is included + // Check to see if the minimum fee is included; + // exclude tx missing minimum fee if (tx.second.fee < DEFAULT_FEE) continue; @@ -372,14 +377,20 @@ namespace cryptonote // such that it is based on median block size; // We need to make a similar patch for // wallet2.h - uint64_t upper_transaction_size_limit = ((CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; if (tx.second.blob_size > upper_transaction_size_limit) continue; + // If adding this tx will make the block size + // greater than 130% of the median, reject the + // tx; this will keep down largely punitive tx + // from being included + if ( (total_size + tx.second.blob_size) > ((130 * median_size) / 100) ) + continue; + // If we've exceeded the penalty free size, // stop including more tx if (total_size > median_size) - continue; + break; // Skip transactions that are not ready to be // included into the blockchain or that are -- cgit v1.2.3 From 328a52a5438435666ba3564afe73e866aae2b5c9 Mon Sep 17 00:00:00 2001 From: mydesktop Date: Mon, 26 May 2014 20:57:50 -0400 Subject: dynamic tx size scaling for tx mempool --- src/cryptonote_core/tx_pool.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/cryptonote_core/tx_pool.cpp') diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index a95002dc8..5eb99db40 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -361,6 +361,17 @@ namespace cryptonote // Tx size limit as in wallet2.h uint64_t upper_transaction_size_limit = ((CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; + // Calculate size limit based on median too; useful + // for when we actually fix wallet2.h's maximum + // allowable tx size + // + // Can be removed when wallet2.h calculates max + // tx size based on the median too; just use + // upper_transaction_size_limit_median in all cases + uint64_t upper_transaction_size_limit_median = ((median_size * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; + if (upper_transaction_size_limit_median > upper_transaction_size_limit) + upper_transaction_size_limit = upper_transaction_size_limit_median; + BOOST_FOREACH(transactions_container::value_type& tx, m_transactions) { // Can not exceed maximum block size -- cgit v1.2.3 From 976152994135592bb37db3d8bee6189238c1c071 Mon Sep 17 00:00:00 2001 From: mydesktop Date: Tue, 27 May 2014 16:45:50 -0400 Subject: fix typing mismatch --- src/cryptonote_core/tx_pool.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/cryptonote_core/tx_pool.cpp') diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 5eb99db40..294cfc254 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -350,6 +350,10 @@ namespace cryptonote //--------------------------------------------------------------------------------- bool tx_memory_pool::fill_block_template(block &bl, size_t median_size, uint64_t already_generated_coins, size_t &total_size, uint64_t &fee) { + // Warning: This function takes already_generated_ + // coins as an argument and appears to do nothing + // with it. + CRITICAL_REGION_LOCAL(m_transactions_lock); total_size = 0; @@ -359,7 +363,10 @@ namespace cryptonote std::unordered_set k_images; // Tx size limit as in wallet2.h - uint64_t upper_transaction_size_limit = ((CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; + // tx_pool.cpp uses uint64_t for tx sizes, whereas + // wallet2.h uses uint64_t; just use size_t here + // for now + size_t upper_transaction_size_limit = ((CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; // Calculate size limit based on median too; useful // for when we actually fix wallet2.h's maximum @@ -368,7 +375,7 @@ namespace cryptonote // Can be removed when wallet2.h calculates max // tx size based on the median too; just use // upper_transaction_size_limit_median in all cases - uint64_t upper_transaction_size_limit_median = ((median_size * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; + size_t upper_transaction_size_limit_median = ((median_size * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; if (upper_transaction_size_limit_median > upper_transaction_size_limit) upper_transaction_size_limit = upper_transaction_size_limit_median; -- cgit v1.2.3 From 2475ec877fbd7e9d46bf94b3f847cbad062b64db Mon Sep 17 00:00:00 2001 From: monero-project Date: Wed, 28 May 2014 13:19:24 -0400 Subject: typo in tx_pool.cpp --- src/cryptonote_core/tx_pool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/cryptonote_core/tx_pool.cpp') diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 294cfc254..4c4c6aea1 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -363,7 +363,7 @@ namespace cryptonote std::unordered_set k_images; // Tx size limit as in wallet2.h - // tx_pool.cpp uses uint64_t for tx sizes, whereas + // tx_pool.cpp uses size_t for tx sizes, whereas // wallet2.h uses uint64_t; just use size_t here // for now size_t upper_transaction_size_limit = ((CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; -- cgit v1.2.3 From 3bc16dc0e6bd38fbec51a054e640bacdb17a9a82 Mon Sep 17 00:00:00 2001 From: fluffypony Date: Sun, 15 Jun 2014 09:48:13 +0200 Subject: proper tx_pool handling from CryptoZoidberg / BBR --- src/cryptonote_config.h | 2 ++ src/cryptonote_core/cryptonote_core.cpp | 1 + src/cryptonote_core/tx_pool.cpp | 26 ++++++++++++++++++++++++++ src/cryptonote_core/tx_pool.h | 8 +++++++- 4 files changed, 36 insertions(+), 1 deletion(-) (limited to 'src/cryptonote_core/tx_pool.cpp') diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index a992a9db0..295f59e51 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -51,6 +51,8 @@ #define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT 200 //by default, blocks count in blocks downloading #define CRYPTONOTE_PROTOCOL_HOP_RELAX_COUNT 3 //value of hop, after which we use only announce of new block +#define CRYPTONOTE_MEMPOOL_TX_LIVETIME 86400 //seconds, one day +#define CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME 604800 //seconds, one week #define P2P_DEFAULT_PORT 18080 #define RPC_DEFAULT_PORT 18081 diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 50cbfd267..2609fc13e 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -526,6 +526,7 @@ namespace cryptonote m_store_blockchain_interval.do_call(boost::bind(&blockchain_storage::store_blockchain, &m_blockchain_storage)); m_miner.on_idle(); + m_mempool.on_idle(); return true; } //----------------------------------------------------------------------------------------------- diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 4c4c6aea1..ce1bc1ad2 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -83,6 +83,7 @@ namespace cryptonote txd_p.first->second.max_used_block_id = null_hash; txd_p.first->second.max_used_block_height = 0; txd_p.first->second.kept_by_block = kept_by_block; + txd_p.first->second.receive_time = time(nullptr); tvc.m_verifivation_impossible = true; tvc.m_added_to_pool = true; }else @@ -104,6 +105,7 @@ namespace cryptonote txd_p.first->second.max_used_block_height = max_used_block_height; txd_p.first->second.last_failed_height = 0; txd_p.first->second.last_failed_id = null_hash; + txd_p.first->second.receive_time = time(nullptr); tvc.m_added_to_pool = true; if(txd_p.first->second.fee > 0) @@ -178,6 +180,30 @@ namespace cryptonote return true; } //--------------------------------------------------------------------------------- + void tx_memory_pool::on_idle() + { + m_remove_stuck_tx_interval.do_call([this](){return remove_stuck_transactions();}); + } + //--------------------------------------------------------------------------------- + //proper tx_pool handling courtesy of CryptoZoidberg and Boolberry + bool tx_memory_pool::remove_stuck_transactions() + { + CRITICAL_REGION_LOCAL(m_transactions_lock); + for(auto it = m_transactions.begin(); it!= m_transactions.end();) + { + uint64_t tx_age = time(nullptr) - it->second.receive_time; + + if((tx_age > CRYPTONOTE_MEMPOOL_TX_LIVETIME && !it->second.kept_by_block) || + (tx_age > CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME && it->second.kept_by_block) ) + { + LOG_PRINT_L0("Tx " << it->first << " removed from tx pool due to outdated, age: " << tx_age ); + m_transactions.erase(it++); + }else + ++it; + } + return true; + } + //--------------------------------------------------------------------------------- size_t tx_memory_pool::get_transactions_count() { CRITICAL_REGION_LOCAL(m_transactions_lock); diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h index 26d273aa7..649af41a3 100644 --- a/src/cryptonote_core/tx_pool.h +++ b/src/cryptonote_core/tx_pool.h @@ -13,6 +13,7 @@ #include "string_tools.h" #include "syncobj.h" +#include "math_helper.h" #include "cryptonote_basic_impl.h" #include "verification_context.h" #include "crypto/hash.h" @@ -40,6 +41,7 @@ namespace cryptonote bool on_blockchain_inc(uint64_t new_block_height, const crypto::hash& top_block_id); bool on_blockchain_dec(uint64_t new_block_height, const crypto::hash& top_block_id); + void on_idle(); void lock(); void unlock(); @@ -59,7 +61,7 @@ namespace cryptonote /*bool flush_pool(const std::strig& folder); bool inflate_pool(const std::strig& folder);*/ -#define CURRENT_MEMPOOL_ARCHIVE_VER 7 +#define CURRENT_MEMPOOL_ARCHIVE_VER 8 template void serialize(archive_t & a, const unsigned int version) @@ -82,9 +84,11 @@ namespace cryptonote // uint64_t last_failed_height; crypto::hash last_failed_id; + time_t receive_time; }; private: + bool remove_stuck_transactions(); bool is_transaction_ready_to_go(tx_details& txd); typedef std::unordered_map transactions_container; typedef std::unordered_map > key_images_container; @@ -92,6 +96,7 @@ namespace cryptonote epee::critical_section m_transactions_lock; transactions_container m_transactions; key_images_container m_spent_key_images; + epee::math_helper::once_a_time_seconds<30> m_remove_stuck_tx_interval; //transactions_container m_alternative_transactions; @@ -159,6 +164,7 @@ namespace boost ar & td.max_used_block_id; ar & td.last_failed_height; ar & td.last_failed_id; + ar & td.receive_time; } } -- cgit v1.2.3