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

          Line data    Source code
       1             : // Copyright (c) 2014-2025 The Dash Core developers
       2             : // Distributed under the MIT/X11 software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #ifndef BITCOIN_GOVERNANCE_SUPERBLOCK_H
       6             : #define BITCOIN_GOVERNANCE_SUPERBLOCK_H
       7             : 
       8             : #include <consensus/amount.h>
       9             : #include <governance/object.h>
      10             : #include <script/script.h>
      11             : #include <script/standard.h>
      12             : #include <sync.h>
      13             : #include <uint256.h>
      14             : 
      15             : #include <atomic>
      16             : #include <map>
      17             : #include <memory>
      18             : #include <string>
      19             : #include <vector>
      20             : 
      21             : class CChain;
      22             : class CDeterministicMNList;
      23             : class CTransaction;
      24             : class CTxOut;
      25             : 
      26             : CAmount ParsePaymentAmount(const std::string& strAmount);
      27             : 
      28             : /**
      29             :  * Governance Object Payment
      30             :  */
      31             : class CGovernancePayment
      32             : {
      33             : private:
      34             :     bool fValid;
      35             : 
      36             : public:
      37             :     CScript script;
      38             :     CAmount nAmount;
      39             :     uint256 proposalHash;
      40             : 
      41        1000 :     CGovernancePayment() :
      42         500 :         fValid(false),
      43         500 :         script(),
      44         500 :         nAmount(0),
      45         500 :         proposalHash(0)
      46         500 :     {
      47        1000 :     }
      48             : 
      49             :     CGovernancePayment(const CTxDestination& destIn, CAmount nAmountIn, const uint256& proposalHash);
      50             : 
      51         954 :     bool IsValid() const { return fValid; }
      52             : };
      53             : 
      54             : 
      55             : /**
      56             : *  Trigger : Superblock
      57             : *
      58             : *   - Create payments on the network
      59             : *
      60             : *   object structure:
      61             : *   {
      62             : *       "governance_object_id" : last_id,
      63             : *       "type" : govtypes.trigger,
      64             : *       "subtype" : "superblock",
      65             : *       "superblock_name" : superblock_name,
      66             : *       "start_epoch" : start_epoch,
      67             : *       "payment_addresses" : "addr1|addr2|addr3",
      68             : *       "payment_amounts"   : "amount1|amount2|amount3"
      69             : *   }
      70             : */
      71             : class CSuperblock : public CGovernanceObject
      72             : {
      73             : private:
      74             :     uint256 nGovObjHash;
      75             : 
      76             :     int nBlockHeight;
      77             :     SeenObjectStatus nStatus;
      78             :     std::vector<CGovernancePayment> vecPayments;
      79             : 
      80             :     void ParsePaymentSchedule(const std::string& strPaymentAddresses, const std::string& strPaymentAmounts, const std::string& strProposalHashes);
      81             : 
      82             : public:
      83             :     CSuperblock();
      84             :     CSuperblock(int nBlockHeight, std::vector<CGovernancePayment> vecPayments);
      85             :     explicit CSuperblock(const CGovernanceObject& obj, uint256& nHash);
      86             : 
      87             :     static bool IsValidBlockHeight(int nBlockHeight);
      88             :     static void GetNearestSuperblocksHeights(int nBlockHeight, int& nLastSuperblockRet, int& nNextSuperblockRet);
      89             :     static CAmount GetPaymentsLimit(const CChain& active_chain, int nBlockHeight);
      90             : 
      91       10080 :     SeenObjectStatus GetStatus() const { return nStatus; }
      92         188 :     void SetStatus(SeenObjectStatus nStatusIn) { nStatus = nStatusIn; }
      93             : 
      94             :     std::string GetHexStrData() const;
      95             : 
      96             :     // TELL THE ENGINE WE EXECUTED THIS EVENT
      97          98 :     void SetExecuted() { nStatus = SeenObjectStatus::Executed; }
      98             : 
      99        5770 :     int GetBlockHeight() const
     100             :     {
     101        5770 :         return nBlockHeight;
     102             :     }
     103             : 
     104        3836 :     uint256 GetGovernanceObjHash() const { return nGovObjHash; }
     105             : 
     106         285 :     int CountPayments() const { return (int)vecPayments.size(); }
     107             :     bool GetPayment(int nPaymentIndex, CGovernancePayment& paymentRet);
     108             :     CAmount GetPaymentsTotalAmount();
     109             : 
     110             :     bool IsValid(const CChain& active_chain, const CTransaction& txNew, int nBlockHeight, CAmount blockReward, bool is_v24);
     111             :     bool IsExpired(int heightToTest) const;
     112             : 
     113             :     std::vector<uint256> GetProposalHashes() const;
     114             : };
     115             : 
     116             : using CSuperblock_sptr = std::shared_ptr<CSuperblock>;
     117             : 
     118             : namespace governance {
     119             : 
     120             : /**
     121             :  * Owns the set of active superblock triggers. Trigger lifecycle is fully
     122             :  * owned here; CGovernanceManager pushes new TRIGGER objects in via
     123             :  * AddTrigger() and notifies us via RemoveTrigger() when it erases the
     124             :  * underlying object from its store. Each entry holds a strong reference
     125             :  * to the underlying CGovernanceObject so we never look it up by hash.
     126             :  *
     127             :  * Lifetime: typically owned by CChainstateHelper, which outlives the
     128             :  * paired CGovernanceManager. The govman drives m_loaded via SetLoaded()
     129             :  * from LoadCache() and Clear()s us in its destructor, so IsValid() and
     130             :  * the trigger map track the live govman's state.
     131             :  */
     132        3063 : class SuperblockManager
     133             : {
     134             : public:
     135      341959 :     bool IsValid() const { return m_loaded; }
     136        2831 :     void SetLoaded(bool loaded) { m_loaded = loaded; }
     137             : 
     138             :     /** Register a TRIGGER governance object. Returns true if the resulting
     139             :      *  trigger is live (not already height-expired). */
     140             :     bool AddTrigger(std::shared_ptr<CGovernanceObject> obj, int cachedHeight) EXCLUSIVE_LOCKS_REQUIRED(!cs_sb);
     141             : 
     142             :     /** Single-direction notification from CGovernanceManager when it erases
     143             :      *  a TRIGGER object from its store. */
     144             :     void RemoveTrigger(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(!cs_sb);
     145             : 
     146             :     /** Prune triggers that are invalid or height-expired. Calls
     147             :      *  PrepareDeletion() on the underlying object so CGovernanceManager
     148             :      *  picks it up on its own sweep. */
     149             :     void Clean(int cachedHeight) EXCLUSIVE_LOCKS_REQUIRED(!cs_sb);
     150             : 
     151             :     void Clear() EXCLUSIVE_LOCKS_REQUIRED(!cs_sb);
     152             : 
     153             :     std::vector<CSuperblock_sptr> GetActiveTriggers() const EXCLUSIVE_LOCKS_REQUIRED(!cs_sb);
     154             : 
     155             :     bool GetBestSuperblock(const CDeterministicMNList& tip_mn_list, CSuperblock_sptr& sbRet, int nBlockHeight) const
     156             :         EXCLUSIVE_LOCKS_REQUIRED(!cs_sb);
     157             : 
     158             :     bool IsSuperblockTriggered(const CDeterministicMNList& tip_mn_list, int nBlockHeight) EXCLUSIVE_LOCKS_REQUIRED(!cs_sb);
     159             : 
     160             :     bool IsValidSuperblock(const CChain& active_chain, const CDeterministicMNList& tip_mn_list, const CTransaction& txNew,
     161             :                            int nBlockHeight, CAmount blockReward, bool is_v24) const EXCLUSIVE_LOCKS_REQUIRED(!cs_sb);
     162             : 
     163             :     bool GetSuperblockPayments(const CDeterministicMNList& tip_mn_list, int nBlockHeight,
     164             :                                std::vector<CTxOut>& voutSuperblockRet) const EXCLUSIVE_LOCKS_REQUIRED(!cs_sb);
     165             : 
     166             :     void ExecuteBestSuperblock(const CDeterministicMNList& tip_mn_list, int nBlockHeight) EXCLUSIVE_LOCKS_REQUIRED(!cs_sb);
     167             : 
     168             : private:
     169             :     struct TriggerEntry {
     170             :         CSuperblock_sptr sb;
     171             :         std::shared_ptr<CGovernanceObject> obj;
     172             :     };
     173             : 
     174             :     bool GetBestSuperblockInternal(const CDeterministicMNList& tip_mn_list, CSuperblock_sptr& sbRet,
     175             :                                    int nBlockHeight) const EXCLUSIVE_LOCKS_REQUIRED(cs_sb);
     176             : 
     177             :     mutable Mutex cs_sb;
     178        3063 :     std::atomic<bool> m_loaded{false};
     179             :     std::map<uint256, TriggerEntry> m_triggers GUARDED_BY(cs_sb);
     180             : };
     181             : 
     182             : } // namespace governance
     183             : 
     184             : #endif // BITCOIN_GOVERNANCE_SUPERBLOCK_H

Generated by: LCOV version 1.16