LCOV - code coverage report
Current view: top level - src - stakeinput.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 35 42 83.3 %
Date: 2025-02-23 09:33:43 Functions: 7 7 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2017-2022 The PIVX Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or https://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #include "stakeinput.h"
       6             : 
       7             : #include "chain.h"
       8             : #include "txdb.h"
       9             : #include "validation.h"
      10             : 
      11        6764 : static bool HasStakeMinAgeOrDepth(int nHeight, uint32_t nTime, const CBlockIndex* pindex)
      12             : {
      13        6764 :     const Consensus::Params& consensus = Params().GetConsensus();
      14        6764 :     if (consensus.NetworkUpgradeActive(nHeight + 1, Consensus::UPGRADE_ZC_PUBLIC) &&
      15        5074 :             !consensus.HasStakeMinAgeOrDepth(nHeight, nTime, pindex->nHeight, pindex->nTime)) {
      16           0 :         return error("%s : min age violation - height=%d - time=%d, nHeightBlockFrom=%d, nTimeBlockFrom=%d",
      17           0 :                      __func__, nHeight, nTime, pindex->nHeight, pindex->nTime);
      18             :     }
      19             :     return true;
      20             : }
      21             : 
      22        6764 : CPivStake* CPivStake::NewPivStake(const CTxIn& txin, int nHeight, uint32_t nTime)
      23             : {
      24        6764 :     if (txin.IsZerocoinSpend()) {
      25           0 :         error("%s: unable to initialize CPivStake from zerocoin spend", __func__);
      26           0 :         return nullptr;
      27             :     }
      28             : 
      29             :     // Look for the stake input in the coins cache first
      30        6764 :     const Coin& coin = pcoinsTip->AccessCoin(txin.prevout);
      31        6764 :     if (!coin.IsSpent()) {
      32       13424 :         const CBlockIndex* pindexFrom = mapBlockIndex.at(chainActive[coin.nHeight]->GetBlockHash());
      33             :         // Check that the stake has the required depth/age
      34        6712 :         if (!HasStakeMinAgeOrDepth(nHeight, nTime, pindexFrom)) {
      35             :             return nullptr;
      36             :         }
      37             :         // All good
      38        6712 :         return new CPivStake(coin.out, txin.prevout, pindexFrom);
      39             :     }
      40             : 
      41             :     // Otherwise find the previous transaction in database
      42          52 :     uint256 hashBlock;
      43        6764 :     CTransactionRef txPrev;
      44          52 :     if (!GetTransaction(txin.prevout.hash, txPrev, hashBlock, true)) {
      45           0 :         error("%s : INFO: read txPrev failed, tx id prev: %s", __func__, txin.prevout.hash.GetHex());
      46           0 :         return nullptr;
      47             :     }
      48          52 :     const CBlockIndex* pindexFrom = nullptr;
      49          52 :     if (mapBlockIndex.count(hashBlock)) {
      50          52 :         CBlockIndex* pindex = mapBlockIndex.at(hashBlock);
      51         104 :         if (chainActive.Contains(pindex)) pindexFrom = pindex;
      52             :     }
      53             :     // Check that the input is in the active chain
      54          52 :     if (!pindexFrom) {
      55           0 :         error("%s : Failed to find the block index for stake origin", __func__);
      56             :         return nullptr;
      57             :     }
      58             :     // Check that the stake has the required depth/age
      59          52 :     if (!HasStakeMinAgeOrDepth(nHeight, nTime, pindexFrom)) {
      60             :         return nullptr;
      61             :     }
      62             :     // All good
      63          52 :     return new CPivStake(txPrev->vout[txin.prevout.n], txin.prevout, pindexFrom);
      64             : }
      65             : 
      66        8639 : bool CPivStake::GetTxOutFrom(CTxOut& out) const
      67             : {
      68        8639 :     out = outputFrom;
      69        8639 :     return true;
      70             : }
      71             : 
      72        1919 : CTxIn CPivStake::GetTxIn() const
      73             : {
      74        3838 :     return CTxIn(outpointFrom.hash, outpointFrom.n);
      75             : }
      76             : 
      77       21409 : CAmount CPivStake::GetValue() const
      78             : {
      79       21409 :     return outputFrom.nValue;
      80             : }
      81             : 
      82       19490 : CDataStream CPivStake::GetUniqueness() const
      83             : {
      84             :     //The unique identifier for a PIV stake is the outpoint
      85       19490 :     CDataStream ss(SER_NETWORK, 0);
      86       19490 :     ss << outpointFrom.n << outpointFrom.hash;
      87       19490 :     return ss;
      88             : }
      89             : 
      90             : //The block that the UTXO was added to the chain
      91       19734 : const CBlockIndex* CPivStake::GetIndexFrom() const
      92             : {
      93             :     // Sanity check, pindexFrom is set on the constructor.
      94       19734 :     if (!pindexFrom) throw std::runtime_error("CPivStake: uninitialized pindexFrom");
      95       19734 :     return pindexFrom;
      96             : }
      97             : 

Generated by: LCOV version 1.14