Skip to content

Commit

Permalink
Move GetCoinAge methods to pos.cpp to make them context insensitive.
Browse files Browse the repository at this point in the history
Note: LogPrint call in SignatureHash (interpreter.cpp) should probably be migrated elsewhere to catch/log the out-of-range event
Note: Project should compile again now - tested successfully under MacOS.
  • Loading branch information
akyo8 committed Mar 3, 2021
1 parent 198c6fb commit 5fd8d57
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 59 deletions.
83 changes: 68 additions & 15 deletions src/pos.cpp
Expand Up @@ -436,14 +436,71 @@ bool CheckStakeKernelHash(unsigned int nBits, CBlockIndex* pindexPrev, unsigned
return true;
}

// ppcoin: total coin age spent in transaction, in the unit of coin-days.
// Only those coins meeting minimum age requirement counts. As those
// transactions not in main chain are not currently indexed so we
// might not find out about their coin age. Older transactions are
// guaranteed to be in main chain by sync-checkpoint. This rule is
// introduced to help nodes establish a consistent view of the coin
// age (trust score) of competing branches.
bool GetCoinAge(uint64_t& nCoinAge, CTransactionRef tx)
{
arith_uint512 bnCentSecond = 0; // coin age in the unit of cent-seconds
nCoinAge = 0;

if (tx->IsCoinBase())
return true;

//BOOST_FOREACH(const CTxIn& txin, vin)
for (const CTxIn& txin : tx->vin) {
// First try finding the previous transaction in database
CTransactionRef txPrev;
uint256 hashPrevBlock = uint256();

/*
if (!GetTransaction(txin.prevout.hash, txPrev, Params().GetConsensus(), hashPrevBlock, true))
return error("CheckProofOfStake() : INFO: read txPrev failed"); // previous transaction not in main chain, may occur during initial download
*/

// get input tx and block ref containing for block including input tx
if (!GetTransaction(txin.prevout.hash, txPrev, Params().GetConsensus(), hashPrevBlock, true))
continue; // previous transaction not in main chain

if (tx->nTime < txPrev->nTime)
return false; // Transaction timestamp violation

// Read block header
CBlockIndex* pblockindex = mapBlockIndex[hashPrevBlock];
CBlock blockPrev;
CDiskBlockPos blockPos = pblockindex->GetBlockPos();

if (!ReadBlockFromDisk(blockPrev, blockPos, Params().GetConsensus()))
return error("CheckProofOfStake() : read block failed");

if (blockPrev.GetBlockTime() + Params().GetConsensus().nStakeMinAge > tx->nTime)
continue; // only count coins meeting min age requirement

int64_t nValueIn = txPrev->vout[txin.prevout.n].nValue;
bnCentSecond += arith_uint512(nValueIn) * (tx->nTime - txPrev->nTime) / CENT;

//if (gArgs.GetArg("-printcoinage", false))
// printf("coin age nValueIn=%ld nTimeDiff=%d bnCentSecond=%s\n", nValueIn, nTime - txPrev.nTime, bnCentSecond.ToString().c_str());
}

arith_uint512 bnCoinDay = bnCentSecond * CENT / COIN / (24 * 60 * 60);
if (gArgs.GetArg("-printcoinage", false))
printf("coin age bnCoinDay=%s\n", bnCoinDay.ToString().c_str());
nCoinAge = bnCoinDay.GetLow64();
return true;
}

// ppcoin: total coin age spent in block, in the unit of coin-days.
bool GetCoinAgeBlock(uint64_t& nCoinAge, CBlock block)
bool GetCoinAgeBlock(const CBlock& block, uint64_t& nCoinAge)
{
nCoinAge = 0;
for (const CTransactionRef& tx : block.vtx)
{
for (const CTransactionRef& tx : block.vtx) {
uint64_t nTxCoinAge;
if (GetCoinAge(nTxCoinAge, tx))
if (::GetCoinAgeTX(tx, nTxCoinAge))
nCoinAge += nTxCoinAge;
else
return false;
Expand All @@ -460,13 +517,13 @@ bool GetCoinAgeBlock(uint64_t& nCoinAge, CBlock block)
// ppcoin: total coin age spent in transaction, in the unit of coin-days.
// Only those coins meeting minimum age requirement counts. As those
// transactions not in main chain are not currently indexed so we
// might not find out about their coin age. Older transactions are
// might not find out about their coin age. Older transactions are
// guaranteed to be in main chain by sync-checkpoint. This rule is
// introduced to help nodes establish a consistent view of the coin
// age (trust score) of competing branches.
bool GetCoinAge(uint64_t& nCoinAge, CTransactionRef tx)
bool GetCoinAgeTX(const CTransactionRef& tx, uint64_t& nCoinAge)
{
arith_uint512 bnCentSecond = 0; // coin age in the unit of cent-seconds
arith_uint512 bnCentSecond = 0; // coin age in the unit of cent-seconds
nCoinAge = 0;

if (tx->IsCoinBase())
Expand All @@ -478,25 +535,20 @@ bool GetCoinAge(uint64_t& nCoinAge, CTransactionRef tx)
CTransactionRef txPrev;
uint256 hashPrevBlock = uint256();

/*
if (!GetTransaction(txin.prevout.hash, txPrev, Params().GetConsensus(), hashPrevBlock, true))
return error("CheckProofOfStake() : INFO: read txPrev failed"); // previous transaction not in main chain, may occur during initial download
*/

// get input tx and block ref containing for block including input tx
if (!GetTransaction(txin.prevout.hash, txPrev, Params().GetConsensus(), hashPrevBlock, true))
continue; // previous transaction not in main chain
continue; // previous transaction not in main chain

if (tx->nTime < txPrev->nTime)
return false; // Transaction timestamp violation
return false; // Transaction timestamp violation

// Read block header
CBlockIndex* pblockindex = mapBlockIndex[hashPrevBlock];
CBlock blockPrev;
CDiskBlockPos blockPos = pblockindex->GetBlockPos();

if (!ReadBlockFromDisk(blockPrev, blockPos, Params().GetConsensus()))
return error("CheckProofOfStake() : read block failed");
return false; // unable to read block of previous transaction

if (blockPrev.GetBlockTime() + Params().GetConsensus().nStakeMinAge > tx->nTime)
continue; // only count coins meeting min age requirement
Expand All @@ -515,6 +567,7 @@ bool GetCoinAge(uint64_t& nCoinAge, CTransactionRef tx)
return true;
}


// Check kernel hash target and coinstake signature
bool CheckProofOfStake(const CTransactionRef tx, unsigned int nBits, uint256& hashProofOfStake, std::vector<CScriptCheck> *pvChecks, bool fCHeckSignature)
{
Expand Down
4 changes: 3 additions & 1 deletion src/pos.h
Expand Up @@ -10,7 +10,7 @@
class CBlockHeader;
class CBlockIndex;
class uint256;

class CBlock;
class CScriptCheck;

// MODIFIER_INTERVAL: time to elapse before new modifier is computed
Expand All @@ -27,7 +27,9 @@ bool CheckStakeKernelHash(unsigned int nBits, CBlockIndex* pindexPrev, unsigned
// Check kernel hash target and coinstake signature
bool CheckProofOfStake(const CTransactionRef tx, unsigned int nBits, uint256& hashProofOfStake, std::vector<CScriptCheck>* pvChecks = nullptr, bool fCHeckSignature = true);
bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeModifier, bool& fGeneratedStakeModifier);
bool GetCoinAgeBlock(const CBlock& block, uint64_t& nCoinAge);

bool GetCoinAgeTX(const CTransactionRef& tx, uint64_t& nCoinAge);
bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierChecksum);

unsigned int GetStakeModifierChecksum(const CBlockIndex* pindex);
Expand Down
2 changes: 2 additions & 0 deletions src/pow.cpp
Expand Up @@ -14,6 +14,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
{
assert(pindexLast != nullptr);
unsigned int nProofOfWorkLimit = UintToArith256(params.nProofOfWorkLimit).GetCompact();
assert("GetNextWorkRequired deprecated for Cloak- use GetNextTargetRequired");

// Only change once per difficulty adjustment interval
if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)
Expand Down Expand Up @@ -50,6 +51,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF
{
if (params.fPowNoRetargeting)
return pindexLast->nBits;
assert("CalculateNextWorkRequired deprecated for Cloak- use GetNextTargetRequired");

// Limit adjustment step
int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
Expand Down
20 changes: 1 addition & 19 deletions src/primitives/block.cpp
Expand Up @@ -4,7 +4,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <primitives/block.h>

#include <pos.h>
#include <hash.h>
#include <tinyformat.h>

Expand All @@ -15,25 +15,7 @@ uint256 CBlockHeader::GetHash() const
//return SerializeHash(*this);
}

// ppcoin: total coin age spent in block, in the unit of coin-days.
bool CBlock::GetCoinAge(uint64_t& nCoinAge) const
{
nCoinAge = 0;
for (const CTransactionRef& tx : vtx) {
{
uint64_t nTxCoinAge;
if (tx->GetCoinAge(nTxCoinAge))
nCoinAge += nTxCoinAge;
else
return false;
}

if (nCoinAge == 0) // block coin age minimum 1 coin-day
nCoinAge = 1;
//if (fDebug && GetBoolArg("-printcoinage"))
// printf("block coin age total nCoinDays=%" PRI64d "\n", nCoinAge);
return true;
}

std::string CBlock::ToString() const
{
Expand Down
21 changes: 0 additions & 21 deletions src/primitives/transaction.cpp
Expand Up @@ -132,27 +132,6 @@ bool CTransaction::GetCoinAge(uint64_t& nCoinAge) const
return true;
}

// ppcoin: total coin age spent in block, in the unit of coin-days.
bool CBlock::GetCoinAge(uint64& nCoinAge) const
{
nCoinAge = 0;

CTxDB txdb("r");
BOOST_FOREACH (const CTransaction& tx, vtx) {
uint64 nTxCoinAge;
if (tx.GetCoinAge(txdb, nTxCoinAge))
nCoinAge += nTxCoinAge;
else
return false;
}

if (nCoinAge == 0) // block coin age minimum 1 coin-day
nCoinAge = 1;
if (fDebug && GetBoolArg("-printcoinage"))
printf("block coin age total nCoinDays=%" PRI64d "\n", nCoinAge);
return true;
}

CAmount CTransaction::GetValueOut() const
{
CAmount nValueOut = 0;
Expand Down
1 change: 0 additions & 1 deletion src/primitives/transaction.h
Expand Up @@ -78,7 +78,6 @@ class CTxIn
/* If this flag set, CTxIn::nSequence is NOT interpreted as a
* relative lock-time. */
static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1U << 31);
bool GetCoinAge(uint64_t& nCoinAge) const;

/* If CTxIn::nSequence encodes a relative lock-time and this flag
* is set, the relative lock-time has units of 512 seconds,
Expand Down
1 change: 0 additions & 1 deletion src/script/interpreter.cpp
Expand Up @@ -1651,7 +1651,6 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn
// Only lock-in the txout payee at same index as txin
unsigned int nOut = nIn;
if (nOut >= txTmp.vout.size()) {
LogPrintf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut);
return one;
}
txTmp.vout.resize(nOut + 1);
Expand Down
5 changes: 5 additions & 0 deletions src/timedata.cpp
Expand Up @@ -31,6 +31,11 @@ int64_t GetTimeOffset()
return nTimeOffset;
}

int64_t abs64(int64_t n)
{
return (n >= 0 ? n : -n);
}

int64_t GetAdjustedTime()
{
return GetTime() + GetTimeOffset();
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/wallet.cpp
Expand Up @@ -551,7 +551,7 @@ void CWallet::CreateCoinStake(unsigned int nBits, int64_t nSearchInterval, CTran

uint64_t nCoinAge;

if (!txNew->GetCoinAge(nCoinAge)) {
if (!GetCoinAgeTX(txNew, nCoinAge)) {
return;
}

Expand Down

0 comments on commit 5fd8d57

Please sign in to comment.