#ifndef BITCOIN_MAIN_H
#define BITCOIN_MAIN_H
+#include <algorithm>
+
+#include "timestamps.h"
#include "bignum.h"
#include "sync.h"
#include "net.h"
#include "script.h"
-#include "scrypt_mine.h"
+#include "scrypt.h"
+#include <limits>
#include <list>
+#include <map>
class CWallet;
class CBlock;
class CRequestTracker;
class CNode;
+//
+// Global state
+//
+
static const unsigned int MAX_BLOCK_SIZE = 1000000;
static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
static const unsigned int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100;
static const unsigned int MAX_INV_SZ = 50000;
-static const int64 MIN_TX_FEE = CENT;
-static const int64 MIN_RELAY_TX_FEE = CENT;
-static const int64 MAX_MONEY = 2000000000 * COIN;
-static const int64 MAX_MINT_PROOF_OF_WORK = 100 * COIN;
-static const int64 MAX_MINT_PROOF_OF_STAKE = 1 * COIN;
-static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE;
-
-static const unsigned int ENTROPY_SWITCH_TIME = 1362791041; // Sat, 09 Mar 2013 01:04:01 GMT
-static const unsigned int STAKE_SWITCH_TIME = 1371686400; // Thu, 20 Jun 2013 00:00:00 GMT
-static const unsigned int TARGETS_SWITCH_TIME = 1374278400; // Sat, 20 Jul 2013 00:00:00 GMT
-static const unsigned int CHAINCHECKS_SWITCH_TIME = 1379635200; // Fri, 20 Sep 2013 00:00:00 GMT
-static const unsigned int STAKECURVE_SWITCH_TIME = 1382227200; // Sun, 20 Oct 2013 00:00:00 GMT
-static const unsigned int STAKEWEIGHT_SWITCH_TIME = 1388534400; // Wed, 01 Jan 2014 00:00:00 GMT
-
-
-inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
+
+static const int64_t MIN_TX_FEE = CENT/10;
+static const int64_t MIN_RELAY_TX_FEE = CENT/50;
+
+static const int64_t MAX_MONEY = std::numeric_limits<int64_t>::max();
+static const int64_t MAX_MINT_PROOF_OF_WORK = 100 * COIN;
+static const int64_t MAX_MINT_PROOF_OF_STAKE = 1 * COIN;
+static const int64_t MIN_TXOUT_AMOUNT = CENT/100;
+
+
+inline bool MoneyRange(int64_t nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
// Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp.
static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
-
-#ifdef USE_UPNP
-static const int fHaveUPnP = true;
-#else
-static const int fHaveUPnP = false;
-#endif
+// Maximum number of script-checking threads allowed
+static const int MAX_SCRIPTCHECK_THREADS = 16;
static const uint256 hashGenesisBlock("0x00000a060336cbb72fe969666d337b87198b1add2abaa59cca226820b32933a4");
static const uint256 hashGenesisBlockTestNet("0x000c763e402f2436da9ed36c7286f62c3f6e5dbafce9ff289bd43d7459327eb");
-static const int64 nMaxClockDrift = 2 * 60 * 60; // two hours
+inline int64_t PastDrift(int64_t nTime) { return nTime - 2 * nOneHour; } // up to 2 hours from the past
+inline int64_t FutureDrift(int64_t nTime) { return nTime + 2 * nOneHour; } // up to 2 hours from the future
extern CScript COINBASE_FLAGS;
-
-
extern CCriticalSection cs_main;
extern std::map<uint256, CBlockIndex*> mapBlockIndex;
extern std::set<std::pair<COutPoint, unsigned int> > setStakeSeen;
extern CBlockIndex* pindexGenesisBlock;
-extern unsigned int nStakeMinAge;
extern unsigned int nNodeLifespan;
+extern unsigned int nStakeMinAge;
extern int nCoinbaseMaturity;
extern int nBestHeight;
extern uint256 nBestChainTrust;
extern uint256 hashBestChain;
extern CBlockIndex* pindexBest;
extern unsigned int nTransactionsUpdated;
-extern uint64 nLastBlockTx;
-extern uint64 nLastBlockSize;
-extern int64 nLastCoinStakeSearchInterval;
+extern uint64_t nLastBlockTx;
+extern uint64_t nLastBlockSize;
+extern uint32_t nLastCoinStakeSearchInterval;
extern const std::string strMessageMagic;
-extern int64 nTimeBestReceived;
+extern int64_t nTimeBestReceived;
extern CCriticalSection cs_setpwalletRegistered;
extern std::set<CWallet*> setpwalletRegistered;
extern unsigned char pchMessageStart[4];
extern std::map<uint256, CBlock*> mapOrphanBlocks;
// Settings
-extern int64 nTransactionFee;
-extern bool fStakeUsePooledKeys;
+extern int64_t nTransactionFee;
+extern int64_t nMinimumInputValue;
+extern bool fUseFastIndex;
+extern int nScriptCheckThreads;
+extern const uint256 entropyStore[38];
// Minimum disk space required - used in CheckDiskSpace()
-static const uint64 nMinDiskSpace = 52428800;
-
+static const uint64_t nMinDiskSpace = 52428800;
class CReserveKey;
class CTxDB;
class CTxIndex;
+class CScriptCheck;
void RegisterWallet(CWallet* pwalletIn);
void UnregisterWallet(CWallet* pwalletIn);
void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false, bool fConnect = true);
bool ProcessBlock(CNode* pfrom, CBlock* pblock);
-bool CheckDiskSpace(uint64 nAdditionalBytes=0);
+bool CheckDiskSpace(uint64_t nAdditionalBytes=0);
FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
FILE* AppendBlockFile(unsigned int& nFileRet);
+
+void UnloadBlockIndex();
bool LoadBlockIndex(bool fAllowNew=true);
void PrintBlockTree();
CBlockIndex* FindBlockByHeight(int nHeight);
bool ProcessMessages(CNode* pfrom);
-bool SendMessages(CNode* pto, bool fSendTrickle);
+bool SendMessages(CNode* pto);
bool LoadExternalBlockFile(FILE* fileIn);
-CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake=false);
-void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
-void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
-bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
-bool CheckStake(CBlock* pblock, CWallet& wallet);
+
+// Run an instance of the script checking thread
+void ThreadScriptCheck(void* parg);
+// Stop the script checking threads
+void ThreadScriptCheckQuit();
+
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
-int64 GetProofOfWorkReward(unsigned int nBits);
-int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, bool bCoinYearOnly=false);
-unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
-unsigned int ComputeMinStake(unsigned int nBase, int64 nTime, unsigned int nBlockTime);
+unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake);
+int64_t GetProofOfWorkReward(unsigned int nBits, int64_t nFees=0);
+int64_t GetProofOfStakeReward(int64_t nCoinAge, unsigned int nBits, int64_t nTime, bool bCoinYearOnly=false);
+unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime);
+unsigned int ComputeMinStake(unsigned int nBase, int64_t nTime, unsigned int nBlockTime);
int GetNumBlocksOfPeers();
bool IsInitialBlockDownload();
std::string GetWarnings(std::string strFor);
bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock);
uint256 WantedByOrphan(const CBlock* pblockOrphan);
const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfStake);
-void StakeMiner(CWallet *pwallet);
-void ResendWalletTransactions();
-
-
+void ResendWalletTransactions(bool fForceResend=false);
+bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType);
class CDiskTxPos
{
public:
- unsigned int nFile;
- unsigned int nBlockPos;
- unsigned int nTxPos;
+ uint32_t nFile;
+ uint32_t nBlockPos;
+ uint32_t nTxPos;
CDiskTxPos()
{
}
IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
- void SetNull() { nFile = (unsigned int) -1; nBlockPos = 0; nTxPos = 0; }
- bool IsNull() const { return (nFile == (unsigned int) -1); }
+ void SetNull() { nFile = std::numeric_limits<uint32_t>::max(); nBlockPos = 0; nTxPos = 0; }
+ bool IsNull() const { return (nFile == std::numeric_limits<uint32_t>::max()); }
friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
{
{
public:
CTransaction* ptx;
- unsigned int n;
+ uint32_t n;
CInPoint() { SetNull(); }
CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
- void SetNull() { ptx = NULL; n = (unsigned int) -1; }
- bool IsNull() const { return (ptx == NULL && n == (unsigned int) -1); }
+ void SetNull() { ptx = NULL; n = std::numeric_limits<uint32_t>::max(); }
+ bool IsNull() const { return (ptx == NULL && n == std::numeric_limits<uint32_t>::max()); }
};
{
public:
uint256 hash;
- unsigned int n;
+ uint32_t n;
COutPoint() { SetNull(); }
COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
- void SetNull() { hash = 0; n = (unsigned int) -1; }
- bool IsNull() const { return (hash == 0 && n == (unsigned int) -1); }
+ void SetNull() { hash = 0; n = std::numeric_limits<uint32_t>::max(); }
+ bool IsNull() const { return (hash == 0 && n == std::numeric_limits<uint32_t>::max()); }
friend bool operator<(const COutPoint& a, const COutPoint& b)
{
public:
COutPoint prevout;
CScript scriptSig;
- unsigned int nSequence;
+ uint32_t nSequence;
CTxIn()
{
class CTxOut
{
public:
- int64 nValue;
+ int64_t nValue;
CScript scriptPubKey;
CTxOut()
SetNull();
}
- CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
+ CTxOut(int64_t nValueIn, CScript scriptPubKeyIn)
{
nValue = nValueIn;
scriptPubKey = scriptPubKeyIn;
{
GMF_BLOCK,
GMF_RELAY,
- GMF_SEND,
+ GMF_SEND
};
typedef std::map<uint256, std::pair<CTxIndex, CTransaction> > MapPrevTx;
public:
static const int CURRENT_VERSION=1;
int nVersion;
- unsigned int nTime;
+ uint32_t nTime;
std::vector<CTxIn> vin;
std::vector<CTxOut> vout;
- unsigned int nLockTime;
+ uint32_t nLockTime;
// Denial-of-service detection:
mutable int nDoS;
void SetNull()
{
nVersion = CTransaction::CURRENT_VERSION;
- nTime = GetAdjustedTime();
+ nTime = (uint32_t) GetAdjustedTime();
vin.clear();
vout.clear();
nLockTime = 0;
return SerializeHash(*this);
}
- bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
+ bool IsFinal(int nBlockHeight=0, int64_t nBlockTime=0) const
{
// Time based nLockTime implemented in 0.1.6
if (nLockTime == 0)
nBlockHeight = nBestHeight;
if (nBlockTime == 0)
nBlockTime = GetAdjustedTime();
- if ((int64)nLockTime < ((int64)nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
+ if ((int64_t)nLockTime < ((int64_t)nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
return true;
BOOST_FOREACH(const CTxIn& txin, vin)
if (!txin.IsFinal())
/** Check for standard transaction types
@return True if all outputs (scriptPubKeys) use only standard transaction forms
*/
- bool IsStandard() const;
+ bool IsStandard(std::string& strReason) const;
+ bool IsStandard() const
+ {
+ std::string strReason;
+ return IsStandard(strReason);
+ }
/** Check for standard transaction types
@param[in] mapInputs Map of previous transactions that have outputs we're spending
/** Amount of bitcoins spent by this transaction.
@return sum of all outputs (note: does not include fees)
*/
- int64 GetValueOut() const
+ int64_t GetValueOut() const
{
- int64 nValueOut = 0;
+ int64_t nValueOut = 0;
BOOST_FOREACH(const CTxOut& txout, vout)
{
nValueOut += txout.nValue;
@return Sum of value of all inputs (scriptSigs)
@see CTransaction::FetchInputs
*/
- int64 GetValueIn(const MapPrevTx& mapInputs) const;
+ int64_t GetValueIn(const MapPrevTx& mapInputs) const;
static bool AllowFree(double dPriority)
{
return dPriority > COIN * 144 / 250;
}
- int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=false, enum GetMinFee_mode mode=GMF_BLOCK) const;
+ int64_t GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=false, enum GetMinFee_mode mode=GMF_BLOCK, unsigned int nBytes = 0) const;
bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
{
try {
filein >> *this;
}
- catch (std::exception &e) {
- return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__);
+ catch (const std::exception&) {
+ return error("%s() : deserialize or I/O error", BOOST_CURRENT_FUNCTION);
}
// Return file pointer
{
std::string str;
str += IsCoinBase()? "Coinbase" : (IsCoinStake()? "Coinstake" : "CTransaction");
- str += strprintf("(hash=%s, nTime=%d, ver=%d, vin.size=%"PRIszu", vout.size=%"PRIszu", nLockTime=%d)\n",
+ str += strprintf("(hash=%s, nTime=%d, ver=%d, vin.size=%" PRIszu ", vout.size=%" PRIszu ", nLockTime=%d)\n",
GetHash().ToString().substr(0,10).c_str(),
nTime,
nVersion,
@param[in] pindexBlock
@param[in] fBlock true if called from ConnectBlock
@param[in] fMiner true if called from CreateNewBlock
- @param[in] fStrictPayToScriptHash true if fully validating p2sh transactions
+ @param[in] fScriptChecks enable scripts validation?
+ @param[in] flags STRICT_FLAGS script validation flags
+ @param[in] pvChecks NULL If pvChecks is not NULL, script checks are pushed onto it instead of being performed inline.
@return Returns true if all checks succeed
*/
- bool ConnectInputs(CTxDB& txdb, MapPrevTx inputs,
- std::map<uint256, CTxIndex>& mapTestPool, const CDiskTxPos& posThisTx,
- const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash=true);
+ bool ConnectInputs(CTxDB& txdb, MapPrevTx inputs, std::map<uint256, CTxIndex>& mapTestPool, const CDiskTxPos& posThisTx, const CBlockIndex* pindexBlock,
+ bool fBlock, bool fMiner, bool fScriptChecks=true,
+ unsigned int flags=STRICT_FLAGS, std::vector<CScriptCheck> *pvChecks = NULL);
bool ClientConnectInputs();
bool CheckTransaction() const;
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
- bool GetCoinAge(CTxDB& txdb, uint64& nCoinAge) const; // ppcoin: get transaction coin age
+ bool GetCoinAge(CTxDB& txdb, uint64_t& nCoinAge) const; // ppcoin: get transaction coin age
protected:
const CTxOut& GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const;
};
+/** Closure representing one script verification
+ * Note that this stores references to the spending transaction */
+class CScriptCheck
+{
+private:
+ CScript scriptPubKey;
+ const CTransaction *ptxTo;
+ unsigned int nIn;
+ unsigned int nFlags;
+ int nHashType;
+
+public:
+ CScriptCheck() {}
+ CScriptCheck(const CTransaction& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, int nHashTypeIn) :
+ scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey),
+ ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), nHashType(nHashTypeIn) { }
+
+ bool operator()() const;
+
+ void swap(CScriptCheck &check) {
+ scriptPubKey.swap(check.scriptPubKey);
+ std::swap(ptxTo, check.ptxTo);
+ std::swap(nIn, check.nIn);
+ std::swap(nFlags, check.nFlags);
+ std::swap(nHashType, check.nHashType);
+ }
+};
public:
uint256 hashBlock;
std::vector<uint256> vMerkleBranch;
- int nIndex;
+ int32_t nIndex;
// memory only
mutable bool fMerkleVerified;
};
-
-
-
/** Nodes collect new transactions into a block, hash them into a hash tree,
* and scan through nonce values to make the block's hash satisfy proof-of-work
* requirements. When they solve the proof-of-work, they broadcast the block
public:
// header
static const int CURRENT_VERSION=6;
- int nVersion;
+ int32_t nVersion;
uint256 hashPrevBlock;
uint256 hashMerkleRoot;
- unsigned int nTime;
- unsigned int nBits;
- unsigned int nNonce;
+ uint32_t nTime;
+ uint32_t nBits;
+ uint32_t nNonce;
// network and disk
std::vector<CTransaction> vtx;
uint256 GetHash() const
{
- return scrypt_blockhash(CVOIDBEGIN(nVersion));
+ return scrypt_blockhash((const uint8_t*)&nVersion);
}
- int64 GetBlockTime() const
+ int64_t GetBlockTime() const
{
- return (int64)nTime;
+ return (int64_t)nTime;
}
void UpdateTime(const CBlockIndex* pindexPrev);
// ppcoin: entropy bit for stake modifier if chosen by modifier
- unsigned int GetStakeEntropyBit(unsigned int nTime) const
+ unsigned int GetStakeEntropyBit(unsigned int nHeight) const
{
// Protocol switch to support p2pool at novacoin block #9689
- if (nTime >= ENTROPY_SWITCH_TIME || fTestNet)
+ if (nHeight >= 9689 || fTestNet)
{
// Take last bit of block hash as entropy bit
- unsigned int nEntropyBit = ((GetHash().Get64()) & 1llu);
+ unsigned int nEntropyBit = (GetHash().Get64()) & (uint64_t)1;
if (fDebug && GetBoolArg("-printstakemodifier"))
printf("GetStakeEntropyBit: nTime=%u hashBlock=%s nEntropyBit=%u\n", nTime, GetHash().ToString().c_str(), nEntropyBit);
return nEntropyBit;
}
- // Before novacoin block #9689 - old protocol
- uint160 hashSig = Hash160(vchBlockSig);
- if (fDebug && GetBoolArg("-printstakemodifier"))
- printf("GetStakeEntropyBit: hashSig=%s", hashSig.ToString().c_str());
- hashSig >>= 159; // take the first bit of the hash
+
+ // Before novacoin block #9689 - get from pregenerated table
+ int nBitNum = nHeight & 0xFF;
+ int nItemNum = nHeight / 0xFF;
+
+ unsigned int nEntropyBit = (unsigned int) ((entropyStore[nItemNum] & (uint256(1) << nBitNum)) >> nBitNum).Get64();
if (fDebug && GetBoolArg("-printstakemodifier"))
- printf(" entropybit=%"PRI64d"\n", hashSig.Get64());
- return hashSig.Get64();
+ printf("GetStakeEntropyBit: from pregenerated table, nHeight=%d nEntropyBit=%u\n", nHeight, nEntropyBit);
+ return nEntropyBit;
}
// ppcoin: two types of block: proof-of-work or proof-of-stake
}
// ppcoin: get max transaction timestamp
- int64 GetMaxTransactionTime() const
+ int64_t GetMaxTransactionTime() const
{
- int64 maxTransactionTime = 0;
+ int64_t maxTransactionTime = 0;
BOOST_FOREACH(const CTransaction& tx, vtx)
- maxTransactionTime = std::max(maxTransactionTime, (int64)tx.nTime);
+ maxTransactionTime = std::max(maxTransactionTime, (int64_t)tx.nTime);
return maxTransactionTime;
}
BOOST_FOREACH(const CTransaction& tx, vtx)
vMerkleTree.push_back(tx.GetHash());
int j = 0;
- for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
+ for (int nSize = (int)vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
{
for (int i = 0; i < nSize; i += 2)
{
BuildMerkleTree();
std::vector<uint256> vMerkleBranch;
int j = 0;
- for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
+ for (int nSize = (int)vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
{
int i = std::min(nIndex^1, nSize-1);
vMerkleBranch.push_back(vMerkleTree[j+i]);
try {
filein >> *this;
}
- catch (std::exception &e) {
- return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__);
+ catch (const std::exception&) {
+ return error("%s() : deserialize or I/O error", BOOST_CURRENT_FUNCTION);
}
// Check the header
void print() const
{
- printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%"PRIszu", vchBlockSig=%s)\n",
+ printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%" PRIszu ", vchBlockSig=%s)\n",
GetHash().ToString().c_str(),
nVersion,
hashPrevBlock.ToString().c_str(),
bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
bool CheckBlock(bool fCheckPOW=true, bool fCheckMerkleRoot=true, bool fCheckSig=true) const;
bool AcceptBlock();
- bool GetCoinAge(uint64& nCoinAge) const; // ppcoin: calculate total coin age spent in block
- bool SignBlock(const CKeyStore& keystore);
- bool CheckBlockSignature(bool fProofOfStake) const;
+ bool GetCoinAge(uint64_t& nCoinAge) const; // ppcoin: calculate total coin age spent in block
+ bool CheckBlockSignature() const;
private:
bool SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew);
const uint256* phashBlock;
CBlockIndex* pprev;
CBlockIndex* pnext;
- unsigned int nFile;
- unsigned int nBlockPos;
+ uint32_t nFile;
+ uint32_t nBlockPos;
uint256 nChainTrust; // ppcoin: trust score of block chain
- int nHeight;
+ int32_t nHeight;
- int64 nMint;
- int64 nMoneySupply;
+ int64_t nMint;
+ int64_t nMoneySupply;
- unsigned int nFlags; // ppcoin: block index flags
+ uint32_t nFlags; // ppcoin: block index flags
enum
{
BLOCK_PROOF_OF_STAKE = (1 << 0), // is proof-of-stake block
BLOCK_STAKE_ENTROPY = (1 << 1), // entropy bit for stake modifier
- BLOCK_STAKE_MODIFIER = (1 << 2), // regenerated stake modifier
+ BLOCK_STAKE_MODIFIER = (1 << 2) // regenerated stake modifier
};
- uint64 nStakeModifier; // hash modifier for proof-of-stake
- unsigned int nStakeModifierChecksum; // checksum of index; in-memeory only
+ uint64_t nStakeModifier; // hash modifier for proof-of-stake
+ uint32_t nStakeModifierChecksum; // checksum of index; in-memeory only
// proof-of-stake specific fields
COutPoint prevoutStake;
- unsigned int nStakeTime;
+ uint32_t nStakeTime;
uint256 hashProofOfStake;
// block header
- int nVersion;
- uint256 hashMerkleRoot;
- unsigned int nTime;
- unsigned int nBits;
- unsigned int nNonce;
+ int32_t nVersion;
+ uint256 hashMerkleRoot;
+ uint32_t nTime;
+ uint32_t nBits;
+ uint32_t nNonce;
CBlockIndex()
{
return *phashBlock;
}
- int64 GetBlockTime() const
+ int64_t GetBlockTime() const
{
- return (int64)nTime;
+ return (int64_t)nTime;
}
uint256 GetBlockTrust() const;
enum { nMedianTimeSpan=11 };
- int64 GetMedianTimePast() const
+ int64_t GetMedianTimePast() const
{
- int64 pmedian[nMedianTimeSpan];
- int64* pbegin = &pmedian[nMedianTimeSpan];
- int64* pend = &pmedian[nMedianTimeSpan];
+ int64_t pmedian[nMedianTimeSpan];
+ int64_t* pbegin = &pmedian[nMedianTimeSpan];
+ int64_t* pend = &pmedian[nMedianTimeSpan];
const CBlockIndex* pindex = this;
for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
return pbegin[(pend - pbegin)/2];
}
- int64 GetMedianTime() const
+ int64_t GetMedianTime() const
{
const CBlockIndex* pindex = this;
for (int i = 0; i < nMedianTimeSpan/2; i++)
bool GeneratedStakeModifier() const
{
- return (nFlags & BLOCK_STAKE_MODIFIER);
+ return (nFlags & BLOCK_STAKE_MODIFIER) != 0;
}
- void SetStakeModifier(uint64 nModifier, bool fGeneratedStakeModifier)
+ void SetStakeModifier(uint64_t nModifier, bool fGeneratedStakeModifier)
{
nStakeModifier = nModifier;
if (fGeneratedStakeModifier)
std::string ToString() const
{
- return strprintf("CBlockIndex(nprev=%p, pnext=%p, nFile=%u, nBlockPos=%-6d nHeight=%d, nMint=%s, nMoneySupply=%s, nFlags=(%s)(%d)(%s), nStakeModifier=%016"PRI64x", nStakeModifierChecksum=%08x, hashProofOfStake=%s, prevoutStake=(%s), nStakeTime=%d merkle=%s, hashBlock=%s)",
- pprev, pnext, nFile, nBlockPos, nHeight,
+ return strprintf("CBlockIndex(nprev=%p, pnext=%p, nFile=%u, nBlockPos=%-6d nHeight=%d, nMint=%s, nMoneySupply=%s, nFlags=(%s)(%d)(%s), nStakeModifier=%016" PRIx64 ", nStakeModifierChecksum=%08x, hashProofOfStake=%s, prevoutStake=(%s), nStakeTime=%d merkle=%s, hashBlock=%s)",
+ (const void*)pprev, (const void*)pnext, nFile, nBlockPos, nHeight,
FormatMoney(nMint).c_str(), FormatMoney(nMoneySupply).c_str(),
GeneratedStakeModifier() ? "MOD" : "-", GetStakeEntropyBit(), IsProofOfStake()? "PoS" : "PoW",
- nStakeModifier, nStakeModifierChecksum,
+ nStakeModifier, nStakeModifierChecksum,
hashProofOfStake.ToString().c_str(),
prevoutStake.ToString().c_str(), nStakeTime,
hashMerkleRoot.ToString().c_str(),
/** Used to marshal pointers into hashes for db storage. */
class CDiskBlockIndex : public CBlockIndex
{
+private:
+ uint256 blockHash;
+
public:
uint256 hashPrev;
uint256 hashNext;
{
hashPrev = 0;
hashNext = 0;
+ blockHash = 0;
}
explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
READWRITE(nTime);
READWRITE(nBits);
READWRITE(nNonce);
+ READWRITE(blockHash);
)
uint256 GetBlockHash() const
{
+ if (fUseFastIndex && (nTime < GetAdjustedTime() - nOneDay) && blockHash != 0)
+ return blockHash;
+
CBlock block;
block.nVersion = nVersion;
block.hashPrevBlock = hashPrev;
block.nTime = nTime;
block.nBits = nBits;
block.nNonce = nNonce;
- return block.GetHash();
- }
+ const_cast<CDiskBlockIndex*>(this)->blockHash = block.GetHash();
+
+ return blockHash;
+ }
std::string ToString() const
{
void clear();
void queryHashes(std::vector<uint256>& vtxid);
- unsigned long size()
+ size_t size()
{
LOCK(cs);
return mapTx.size();