#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.h"
+#include <algorithm>
+#include <limits>
#include <list>
#include <map>
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 = 2000000000 * COIN;
+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
// Maximum number of script-checking threads allowed
static const int MAX_SCRIPTCHECK_THREADS = 16;
-#ifdef USE_UPNP
-static const int fHaveUPnP = true;
-#else
-static const int fHaveUPnP = false;
-#endif
-
static const uint256 hashGenesisBlock("0x00000a060336cbb72fe969666d337b87198b1add2abaa59cca226820b32933a4");
static const uint256 hashGenesisBlockTestNet("0x000c763e402f2436da9ed36c7286f62c3f6e5dbafce9ff289bd43d7459327eb");
-inline int64_t PastDrift(int64_t nTime) { return nTime - 2 * 60 * 60; } // up to 2 hours from the past
-inline int64_t FutureDrift(int64_t nTime) { return nTime + 2 * 60 * 60; } // up to 2 hours from the future
+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 unsigned int nTransactionsUpdated;
extern uint64_t nLastBlockTx;
extern uint64_t nLastBlockSize;
-extern int64_t nLastCoinStakeSearchInterval;
+extern uint32_t nLastCoinStakeSearchInterval;
extern const std::string strMessageMagic;
extern int64_t nTimeBestReceived;
extern CCriticalSection cs_setpwalletRegistered;
extern int64_t nTransactionFee;
extern int64_t nMinimumInputValue;
extern bool fUseFastIndex;
-extern unsigned int nDerivationMethodIndex;
extern int nScriptCheckThreads;
+extern const uint256 entropyStore[38];
// Minimum disk space required - used in CheckDiskSpace()
static const uint64_t nMinDiskSpace = 52428800;
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);
// Run an instance of the script checking thread
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
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, unsigned int nTime, bool bCoinYearOnly=false);
+int64_t GetProofOfWorkReward(unsigned int nBits);
+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 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);
-
-
-
-bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
-
/** Position on disk for a particular transaction. */
class 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)
{
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()); }
};
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)
{
{
GMF_BLOCK,
GMF_RELAY,
- GMF_SEND,
+ GMF_SEND
};
typedef std::map<uint256, std::pair<CTxIndex, CTransaction> > MapPrevTx;
nBlockTime = GetAdjustedTime();
if ((int64_t)nLockTime < ((int64_t)nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
return true;
- BOOST_FOREACH(const CTxIn& txin, vin)
+ for (const CTxIn& txin : vin)
if (!txin.IsFinal())
return false;
return true;
/** 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
int64_t GetValueOut() const
{
int64_t nValueOut = 0;
- BOOST_FOREACH(const CTxOut& txout, vout)
+ for (const CTxOut& txout : vout)
{
nValueOut += txout.nValue;
if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
try {
filein >> *this;
}
- catch (std::exception &e) {
- (void)e;
+ catch (const std::exception&) {
return error("%s() : deserialize or I/O error", BOOST_CURRENT_FUNCTION);
}
};
-
-
-
/** 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
uint256 GetHash() const
{
- return scrypt_blockhash(CVOIDBEGIN(nVersion));
+ return scrypt_blockhash((const uint8_t*)&nVersion);
}
int64_t GetBlockTime() const
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()) & 1ULL);
+ 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=%" PRId64 "\n", hashSig.Get64());
- return (unsigned int)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
int64_t GetMaxTransactionTime() const
{
int64_t maxTransactionTime = 0;
- BOOST_FOREACH(const CTransaction& tx, vtx)
+ for (const CTransaction& tx : vtx)
maxTransactionTime = std::max(maxTransactionTime, (int64_t)tx.nTime);
return maxTransactionTime;
}
uint256 BuildMerkleTree() const
{
vMerkleTree.clear();
- BOOST_FOREACH(const CTransaction& tx, vtx)
+ for (const CTransaction& tx : vtx)
vMerkleTree.push_back(tx.GetHash());
int j = 0;
for (int nSize = (int)vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
{
if (nIndex == -1)
return 0;
- BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
+ for (const uint256& otherside : vMerkleBranch)
{
if (nIndex & 1)
hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
try {
filein >> *this;
}
- catch (std::exception &e) {
- (void)e;
+ catch (const std::exception&) {
return error("%s() : deserialize or I/O error", BOOST_CURRENT_FUNCTION);
}
bool CheckBlock(bool fCheckPOW=true, bool fCheckMerkleRoot=true, bool fCheckSig=true) const;
bool AcceptBlock();
bool GetCoinAge(uint64_t& nCoinAge) const; // ppcoin: calculate total coin age spent in block
- bool SignBlock(CWallet& keystore);
- bool CheckBlockSignature(bool fProofOfStake) const;
+ bool CheckBlockSignature() const;
private:
bool SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew);
{
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_t nStakeModifier; // hash modifier for proof-of-stake
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" PRIx64 ", nStakeModifierChecksum=%08x, hashProofOfStake=%s, prevoutStake=(%s), nStakeTime=%d merkle=%s, hashBlock=%s)",
- pprev, pnext, nFile, nBlockPos, nHeight,
+ (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(),
uint256 GetBlockHash() const
{
- if (fUseFastIndex && (nTime < GetAdjustedTime() - 24 * 60 * 60) && blockHash != 0)
+ if (fUseFastIndex && (nTime < GetAdjustedTime() - nOneDay) && blockHash != 0)
return blockHash;
CBlock block;
// Retrace how far back it was in the sender's branch
int nDistance = 0;
int nStep = 1;
- BOOST_FOREACH(const uint256& hash, vHave)
+ for (const uint256& hash : vHave)
{
std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
if (mi != mapBlockIndex.end())
CBlockIndex* GetBlockIndex()
{
// Find the first block the caller has in the main chain
- BOOST_FOREACH(const uint256& hash, vHave)
+ for (const uint256& hash : vHave)
{
std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
if (mi != mapBlockIndex.end())
uint256 GetBlockHash()
{
// Find the first block the caller has in the main chain
- BOOST_FOREACH(const uint256& hash, vHave)
+ for (const uint256& hash : vHave)
{
std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
if (mi != mapBlockIndex.end())