From 3ad9a6186fb7cad0eb6bc1aa2a0292012e7ababb Mon Sep 17 00:00:00 2001 From: mfrankovi Date: Wed, 12 Jun 2024 10:27:54 +0200 Subject: [PATCH 1/2] chore: gas estimation cache --- .../include/transaction/transaction_manager.hpp | 5 +++++ .../consensus/src/transaction/transaction_manager.cpp | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/libraries/core_libs/consensus/include/transaction/transaction_manager.hpp b/libraries/core_libs/consensus/include/transaction/transaction_manager.hpp index 0d5f272f5d..ae24fb61a3 100644 --- a/libraries/core_libs/consensus/include/transaction/transaction_manager.hpp +++ b/libraries/core_libs/consensus/include/transaction/transaction_manager.hpp @@ -234,12 +234,17 @@ class TransactionManager : public std::enable_shared_from_this> nonfinalized_transactions_in_dag_; std::unordered_map> recently_finalized_transactions_; std::unordered_map> recently_finalized_transactions_per_period_; uint64_t trx_count_ = 0; + const uint64_t kGasEstimationCacheSize = 1000; + mutable ExpirationCacheMap> gas_estimation_cache_; + const uint64_t kDagBlockGasLimit; const uint64_t kEstimateGasLimit = 200000; const uint64_t kRecentlyFinalizedTransactionsMax = 50000; diff --git a/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp b/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp index 2ea8ef629a..69bdb144c8 100644 --- a/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp +++ b/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp @@ -14,6 +14,7 @@ TransactionManager::TransactionManager(FullNodeConfig const &conf, std::shared_p : kConf(conf), transactions_pool_(final_chain, kConf.transactions_pool_size), kDagBlockGasLimit(kConf.genesis.dag.gas_limit), + gas_estimation_cache_(kGasEstimationCacheSize, kGasEstimationCacheSize / 10), db_(std::move(db)), final_chain_(std::move(final_chain)) { LOG_OBJECTS_CREATE("TRXMGR"); @@ -28,6 +29,13 @@ uint64_t TransactionManager::estimateTransactionGas(std::shared_ptr if (trx->getGas() <= kEstimateGasLimit) { return trx->getGas(); } + + std::unique_lock transactions_lock(gas_estimations_mutex_); + + auto estimation = gas_estimation_cache_.get(trx->getHash()); + if (estimation.second && estimation.first.first == *proposal_period) { + return estimation.first.second; + } const auto &result = final_chain_->call( state_api::EVMTransaction{ trx->getSender(), @@ -43,6 +51,8 @@ uint64_t TransactionManager::estimateTransactionGas(std::shared_ptr if (!result.code_err.empty() || !result.consensus_err.empty()) { return 0; } + + gas_estimation_cache_.insert(trx->getHash(), {*proposal_period, result.gas_used}); return result.gas_used; } From 2d18657eab81860aa8d16275fe58ad01d70e7322 Mon Sep 17 00:00:00 2001 From: Matus Kysel Date: Wed, 12 Jun 2024 15:07:37 +0200 Subject: [PATCH 2/2] feat: gas estimation cache with cond variables --- libraries/common/include/common/util.hpp | 2 +- .../transaction/transaction_manager.hpp | 5 ++-- .../src/transaction/transaction_manager.cpp | 27 ++++++++++++++++--- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/libraries/common/include/common/util.hpp b/libraries/common/include/common/util.hpp index 737d84d317..ea46ee5d18 100644 --- a/libraries/common/include/common/util.hpp +++ b/libraries/common/include/common/util.hpp @@ -365,7 +365,7 @@ class ExpirationCacheMap { bool insert(Key const &key, Value const &value) { { std::shared_lock lock(mtx_); - if (cache_.count(key)) { + if (cache_.contains(key)) { return false; } } diff --git a/libraries/core_libs/consensus/include/transaction/transaction_manager.hpp b/libraries/core_libs/consensus/include/transaction/transaction_manager.hpp index ae24fb61a3..1f74aad5dd 100644 --- a/libraries/core_libs/consensus/include/transaction/transaction_manager.hpp +++ b/libraries/core_libs/consensus/include/transaction/transaction_manager.hpp @@ -234,8 +234,8 @@ class TransactionManager : public std::enable_shared_from_this> nonfinalized_transactions_in_dag_; std::unordered_map> recently_finalized_transactions_; @@ -244,6 +244,7 @@ class TransactionManager : public std::enable_shared_from_this> gas_estimation_cache_; + mutable std::unordered_map> gas_estimation_condition_vars_; const uint64_t kDagBlockGasLimit; const uint64_t kEstimateGasLimit = 200000; diff --git a/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp b/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp index 69bdb144c8..b7cc03ec7c 100644 --- a/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp +++ b/libraries/core_libs/consensus/src/transaction/transaction_manager.cpp @@ -30,12 +30,26 @@ uint64_t TransactionManager::estimateTransactionGas(std::shared_ptr return trx->getGas(); } + const auto trx_hash = trx->getHash(); std::unique_lock transactions_lock(gas_estimations_mutex_); - auto estimation = gas_estimation_cache_.get(trx->getHash()); - if (estimation.second && estimation.first.first == *proposal_period) { - return estimation.first.second; + const auto [estimation, exist] = gas_estimation_cache_.get(trx_hash); + + if (!exist) { + gas_estimation_cache_.insert(trx_hash, {*proposal_period, -1}); + gas_estimation_condition_vars_[trx_hash] = std::make_shared(); + } else { + if (estimation.first == *proposal_period && estimation.second != -1) { + return estimation.second; + } + auto cond_var = gas_estimation_condition_vars_[trx_hash]; + cond_var->wait(transactions_lock, []{ return true; }); + gas_estimation_condition_vars_.erase(trx_hash); + return gas_estimation_cache_.get(trx_hash).first.second; } + + transactions_lock.unlock(); + const auto &result = final_chain_->call( state_api::EVMTransaction{ trx->getSender(), @@ -48,11 +62,16 @@ uint64_t TransactionManager::estimateTransactionGas(std::shared_ptr }, proposal_period); + transactions_lock.lock(); + if (!result.code_err.empty() || !result.consensus_err.empty()) { + gas_estimation_cache_.insert(trx_hash, {*proposal_period, 0}); + gas_estimation_condition_vars_[trx_hash]->notify_all(); return 0; } - gas_estimation_cache_.insert(trx->getHash(), {*proposal_period, result.gas_used}); + gas_estimation_cache_.insert(trx_hash, {*proposal_period, result.gas_used}); + gas_estimation_condition_vars_[trx_hash]->notify_all(); return result.gas_used; }