X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fmain.h;h=95da601ec3bc4b835e6713f8d752cb251581a34f;hb=acdbd44af1807b5114e6edd480680395478a2f38;hp=8b57cd458429cb3f369ffbccf85d7575b0a92d23;hpb=af1b5b2c9471be320ee44b6ec030434e0626571d;p=novacoin.git diff --git a/src/main.h b/src/main.h index 8b57cd4..95da601 100644 --- a/src/main.h +++ b/src/main.h @@ -5,14 +5,17 @@ #ifndef BITCOIN_MAIN_H #define BITCOIN_MAIN_H +#include + +#include "timestamps.h" #include "bignum.h" #include "sync.h" #include "net.h" #include "script.h" #include "scrypt.h" -#include "zerocoin/Zerocoin.h" #include +#include class CWallet; class CBlock; @@ -26,29 +29,29 @@ class CInv; 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 MIN_TX_FEE = CENT/10; +static const int64 MIN_RELAY_TX_FEE = CENT/50; + 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 - +static const int64 MIN_TXOUT_AMOUNT = CENT/100; inline bool MoneyRange(int64 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; @@ -58,16 +61,17 @@ static const int fHaveUPnP = false; static const uint256 hashGenesisBlock("0x00000a060336cbb72fe969666d337b87198b1add2abaa59cca226820b32933a4"); static const uint256 hashGenesisBlockTestNet("0x000c763e402f2436da9ed36c7286f62c3f6e5dbafce9ff289bd43d7459327eb"); -static const int64 nMaxClockDrift = 2 * 60 * 60; // two hours -extern libzerocoin::Params* ZCParams; +inline int64 PastDrift(int64 nTime) { return nTime - 2 * 60 * 60; } // up to 2 hours from the past +inline int64 FutureDrift(int64 nTime) { return nTime + 2 * 60 * 60; } // up to 2 hours from the future + extern CScript COINBASE_FLAGS; extern CCriticalSection cs_main; extern std::map mapBlockIndex; extern std::set > 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; @@ -87,8 +91,10 @@ extern std::map mapOrphanBlocks; // Settings extern int64 nTransactionFee; -extern bool fStakeUsePooledKeys; +extern int64 nMinimumInputValue; +extern bool fUseFastIndex; extern unsigned int nDerivationMethodIndex; +extern int nScriptCheckThreads; // Minimum disk space required - used in CheckDiskSpace() static const uint64 nMinDiskSpace = 52428800; @@ -96,6 +102,7 @@ static const uint64 nMinDiskSpace = 52428800; class CReserveKey; class CTxDB; class CTxIndex; +class CScriptCheck; void RegisterWallet(CWallet* pwalletIn); void UnregisterWallet(CWallet* pwalletIn); @@ -111,9 +118,14 @@ bool ProcessMessages(CNode* pfrom); bool SendMessages(CNode* pto, bool fSendTrickle); bool LoadExternalBlockFile(FILE* fileIn); +// 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); unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake); -int64 GetProofOfWorkReward(unsigned int nBits); +int64 GetProofOfWorkReward(unsigned int nBits, int64 nFees=0); 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); @@ -126,8 +138,7 @@ const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfSta void StakeMiner(CWallet *pwallet); void ResendWalletTransactions(); - - +bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType); @@ -531,7 +542,7 @@ public: bool IsCoinStake() const { // ppcoin: the coin stake transaction is marked with the first output empty - return (vin.size() > 0 && (!vin[0].prevout.IsNull()) && vout.size() >= 2 && vout[0].IsEmpty() && !vout[1].IsEmpty()); + return (vin.size() > 0 && (!vin[0].prevout.IsNull()) && vout.size() >= 2 && vout[0].IsEmpty()); } /** Check for standard transaction types @@ -592,7 +603,7 @@ public: return dPriority > COIN * 144 / 250; } - int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=false, enum GetMinFee_mode mode=GMF_BLOCK) const; + int64 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) { @@ -608,7 +619,7 @@ public: filein >> *this; } catch (std::exception &e) { - return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__); + return error("%s() : deserialize or I/O error", BOOST_CURRENT_FUNCTION); } // Return file pointer @@ -693,12 +704,14 @@ public: @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& mapTestPool, const CDiskTxPos& posThisTx, - const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash=true); + bool ConnectInputs(CTxDB& txdb, MapPrevTx inputs, std::map& mapTestPool, const CDiskTxPos& posThisTx, const CBlockIndex* pindexBlock, + bool fBlock, bool fMiner, bool fScriptChecks=true, + unsigned int flags=STRICT_FLAGS, std::vector *pvChecks = NULL); bool ClientConnectInputs(); bool CheckTransaction() const; bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL); @@ -708,6 +721,33 @@ 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); + } +}; @@ -923,7 +963,8 @@ public: if (nTime >= ENTROPY_SWITCH_TIME || fTestNet) { // Take last bit of block hash as entropy bit - unsigned int nEntropyBit = ((GetHash().Get64()) & 1llu); + unsigned int nEntropyBit = ((GetHash().Get64()) & 1ULL); + //unsigned int nEntropyBit = 1; if (fDebug && GetBoolArg("-printstakemodifier")) printf("GetStakeEntropyBit: nTime=%u hashBlock=%s nEntropyBit=%u\n", nTime, GetHash().ToString().c_str(), nEntropyBit); return nEntropyBit; @@ -1056,7 +1097,7 @@ public: filein >> *this; } catch (std::exception &e) { - return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__); + return error("%s() : deserialize or I/O error", BOOST_CURRENT_FUNCTION); } // Check the header @@ -1098,7 +1139,7 @@ public: 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 SignBlock(CWallet& keystore); bool CheckBlockSignature(bool fProofOfStake) const; private: @@ -1348,6 +1389,9 @@ public: /** Used to marshal pointers into hashes for db storage. */ class CDiskBlockIndex : public CBlockIndex { +private: + uint256 blockHash; + public: uint256 hashPrev; uint256 hashNext; @@ -1356,6 +1400,7 @@ public: { hashPrev = 0; hashNext = 0; + blockHash = 0; } explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) @@ -1397,10 +1442,14 @@ public: READWRITE(nTime); READWRITE(nBits); READWRITE(nNonce); + READWRITE(blockHash); ) uint256 GetBlockHash() const { + if (fUseFastIndex && (nTime < GetAdjustedTime() - 24 * 60 * 60) && blockHash != 0) + return blockHash; + CBlock block; block.nVersion = nVersion; block.hashPrevBlock = hashPrev; @@ -1408,9 +1457,11 @@ public: block.nTime = nTime; block.nBits = nBits; block.nNonce = nNonce; - return block.GetHash(); - } + const_cast(this)->blockHash = block.GetHash(); + + return blockHash; + } std::string ToString() const {