LCOV - code coverage report
Current view: top level - src/evo - creditpool.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 10 10 100.0 %
Date: 2026-06-25 07:23:43 Functions: 24 24 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2023-2025 The Dash Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #ifndef BITCOIN_EVO_CREDITPOOL_H
       6             : #define BITCOIN_EVO_CREDITPOOL_H
       7             : 
       8             : #include <consensus/amount.h>
       9             : #include <saltedhasher.h>
      10             : #include <serialize.h>
      11             : #include <sync.h>
      12             : #include <threadsafety.h>
      13             : #include <tinyformat.h>
      14             : #include <unordered_lru_cache.h>
      15             : #include <util/ranges_set.h>
      16             : 
      17             : #include <evo/assetlocktx.h>
      18             : 
      19             : #include <gsl/pointers.h>
      20             : 
      21             : #include <optional>
      22             : #include <unordered_set>
      23             : 
      24             : class BlockValidationState;
      25             : class CBlock;
      26             : class CBlockIndex;
      27             : class ChainstateManager;
      28             : class CEvoDB;
      29             : class TxValidationState;
      30             : namespace Consensus {
      31             : struct Params;
      32             : } // namespace Consensus
      33             : namespace llmq {
      34             : class CQuorumManager;
      35             : } // namespace llmq
      36             : 
      37      399460 : struct CCreditPool {
      38      399460 :     CAmount locked{0};
      39             : 
      40             :     // needs for logic of limits of unlocks
      41      399460 :     CAmount currentLimit{0};
      42      399460 :     CAmount latelyUnlocked{0};
      43      399460 :     CRangesSet indexes{};
      44             : 
      45             :     std::string ToString() const;
      46             : 
      47         315 :     SERIALIZE_METHODS(CCreditPool, obj)
      48             :     {
      49         105 :         READWRITE(
      50             :             obj.locked,
      51             :             obj.currentLimit,
      52             :             obj.latelyUnlocked,
      53             :             obj.indexes
      54             :         );
      55         105 :     }
      56             : };
      57             : 
      58             : /**
      59             :  * The class CCreditPoolDiff has 2 purposes:
      60             :  *  - it helps to determine which transaction can be included in new mined block
      61             :  *  within current limits for Asset Unlock transactions and filter duplicated indexes
      62             :  *  - to validate Asset Unlock transaction in mined block. The standalone checks of tx
      63             :  *  such as CheckSpecialTx is not able to do so because at that moment there is no full
      64             :  *  information about Credit Pool limits.
      65             :  *
      66             :  * CCreditPoolDiff temporary stores new values `lockedAmount` and `indexes` while
      67             :  * limits should stay same and depends only on the previous block.
      68             :  */
      69             : class CCreditPoolDiff {
      70             : public:
      71             :     const CCreditPool pool;
      72             : private:
      73             :     std::unordered_set<uint64_t> newIndexes;
      74             : 
      75             :     CAmount sessionLocked{0};
      76             :     CAmount sessionUnlocked{0};
      77             :     CAmount platformReward{0};
      78             : 
      79             : public:
      80             :     explicit CCreditPoolDiff(CCreditPool starter, const CBlockIndex *pindexPrev,
      81             :                              const Consensus::Params& consensusParams,
      82             :                              const CAmount blockSubsidy);
      83             : 
      84             :     /**
      85             :      * This function should be called for each Asset Lock/Unlock tx
      86             :      * to change amount of credit pool
      87             :      * @return true if transaction can be included in this block
      88             :      */
      89             :     bool ProcessLockUnlockTransaction(const CTransaction& tx, TxValidationState& state);
      90             : 
      91             :     /**
      92             :      * this function returns total amount of credits for the next block
      93             :      */
      94      135371 :     CAmount GetTotalLocked() const {
      95      135371 :         return pool.locked + sessionLocked - sessionUnlocked + platformReward;
      96             :     }
      97             : 
      98             :     std::string ToString() const {
      99             :         return strprintf("CCreditPoolDiff(sessionLocked=%lld, sessionUnlocked=%lld, platforomReward=%lld, newIndexes=%lld, pool=%s)", sessionLocked, sessionUnlocked, platformReward, newIndexes.size(), pool.ToString());
     100             :     }
     101             : 
     102             : private:
     103             :     bool Lock(const CTransaction& tx, TxValidationState& state);
     104             :     bool Unlock(const CTransaction& tx, TxValidationState& state);
     105             : };
     106             : 
     107             : class CCreditPoolManager
     108             : {
     109             : private:
     110             :     static constexpr size_t CreditPoolCacheSize = 1000;
     111             :     Mutex cache_mutex;
     112             :     Uint256LruHashMap<CCreditPool> creditPoolCache GUARDED_BY(cache_mutex){CreditPoolCacheSize};
     113             : 
     114             :     CEvoDB& evoDb;
     115             :     const ChainstateManager& m_chainman;
     116             : 
     117             :     static constexpr int DISK_SNAPSHOT_PERIOD = 576; // once per day
     118             : 
     119             : public:
     120             :     static constexpr CAmount LimitAmountLow = 100 * COIN;
     121             :     static constexpr CAmount LimitAmountHigh = 1000 * COIN;
     122             :     static constexpr CAmount LimitAmountV22 = 2000 * COIN;
     123             :     static constexpr CAmount LimitAmountV24 = 4000 * COIN;
     124             : 
     125             :     CCreditPoolManager() = delete;
     126             :     CCreditPoolManager(const CCreditPoolManager&) = delete;
     127             :     CCreditPoolManager& operator=(const CCreditPoolManager&) = delete;
     128             :     explicit CCreditPoolManager(CEvoDB& _evoDb, const ChainstateManager& chainman);
     129             :     ~CCreditPoolManager();
     130             : 
     131             :     /**
     132             :       * @return CCreditPool with data or with empty depends on activation V19 at that block
     133             :       * In case if block is invalid the function GetCreditPool throws an exception
     134             :       * it can happen if there limits of withdrawal (unlock) exceed
     135             :       */
     136             :     CCreditPool GetCreditPool(const CBlockIndex* block) EXCLUSIVE_LOCKS_REQUIRED(!cache_mutex);
     137             : 
     138             : private:
     139             :     std::optional<CCreditPool> GetFromCache(const CBlockIndex& block_index) EXCLUSIVE_LOCKS_REQUIRED(!cache_mutex);
     140             :     void AddToCache(const uint256& block_hash, int height, const CCreditPool& pool) EXCLUSIVE_LOCKS_REQUIRED(!cache_mutex);
     141             : 
     142             :     CCreditPool ConstructCreditPool(const gsl::not_null<const CBlockIndex*> block_index, CCreditPool prev)
     143             :         EXCLUSIVE_LOCKS_REQUIRED(!cache_mutex);
     144             : };
     145             : 
     146             : std::optional<CCreditPoolDiff> GetCreditPoolDiffForBlock(CCreditPoolManager& cpoolman,
     147             :                                                          const CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams,
     148             :                                                          const CAmount blockSubsidy, BlockValidationState& state);
     149             : 
     150             : #endif // BITCOIN_EVO_CREDITPOOL_H

Generated by: LCOV version 1.16