Skip to content

Commit

Permalink
feat: gas estimation cache with cond variables
Browse files Browse the repository at this point in the history
  • Loading branch information
MatusKysel committed Jun 12, 2024
1 parent 3ad9a61 commit 2d18657
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 7 deletions.
2 changes: 1 addition & 1 deletion libraries/common/include/common/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ class TransactionManager : public std::enable_shared_from_this<TransactionManage
// Transactions can be in one of three states:
// 1. In transactions pool; 2. In non-finalized Dag block 3. Executed
mutable std::shared_mutex transactions_mutex_;
mutable std::shared_mutex gas_estimations_mutex_;
mutable std::mutex gas_estimations_mutex_;

TransactionQueue transactions_pool_;
std::unordered_map<trx_hash_t, std::shared_ptr<Transaction>> nonfinalized_transactions_in_dag_;
std::unordered_map<trx_hash_t, std::shared_ptr<Transaction>> recently_finalized_transactions_;
Expand All @@ -244,6 +244,7 @@ class TransactionManager : public std::enable_shared_from_this<TransactionManage

const uint64_t kGasEstimationCacheSize = 1000;
mutable ExpirationCacheMap<trx_hash_t, std::pair<PbftPeriod, uint64_t>> gas_estimation_cache_;
mutable std::unordered_map<trx_hash_t, std::shared_ptr<std::condition_variable>> gas_estimation_condition_vars_;

const uint64_t kDagBlockGasLimit;
const uint64_t kEstimateGasLimit = 200000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,26 @@ uint64_t TransactionManager::estimateTransactionGas(std::shared_ptr<Transaction>
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<std::condition_variable>();
} 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(),
Expand All @@ -48,11 +62,16 @@ uint64_t TransactionManager::estimateTransactionGas(std::shared_ptr<Transaction>
},
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;
}

Expand Down

0 comments on commit 2d18657

Please sign in to comment.