// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2011 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_MAIN_H
#include "net.h"
#include "key.h"
#include "script.h"
+#include "db.h"
#include <list>
-class COutPoint;
-class CInPoint;
-class CDiskTxPos;
-class CCoinBase;
-class CTxIn;
-class CTxOut;
-class CTransaction;
class CBlock;
class CBlockIndex;
class CWalletTx;
class CWallet;
class CKeyItem;
+class CReserveKey;
+class CWalletDB;
-class CMessageHeader;
class CAddress;
class CInv;
class CRequestTracker;
class CNode;
class CBlockIndex;
+static const int CLIENT_VERSION = 59900;
+static const bool VERSION_IS_BETA = true;
+extern const std::string CLIENT_NAME;
+
static const unsigned int MAX_BLOCK_SIZE = 1000000;
static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
static const int64 MAX_MONEY = 21000000 * COIN;
inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
static const int COINBASE_MATURITY = 100;
+// Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp.
+static const int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
#ifdef USE_UPNP
static const int fHaveUPnP = true;
#else
extern CCriticalSection cs_main;
extern std::map<uint256, CBlockIndex*> mapBlockIndex;
extern uint256 hashGenesisBlock;
-extern CBigNum bnProofOfWorkLimit;
extern CBlockIndex* pindexGenesisBlock;
extern int nBestHeight;
extern CBigNum bnBestChainWork;
extern CBigNum bnBestInvalidWork;
extern uint256 hashBestChain;
extern CBlockIndex* pindexBest;
-extern std::set<int64> setKeyPool;
-extern CCriticalSection cs_setKeyPool;
extern unsigned int nTransactionsUpdated;
extern double dHashesPerSec;
extern int64 nHPSTimerStart;
extern int64 nTimeBestReceived;
-extern std::map<std::string, std::string> mapAddressBook;
-extern CCriticalSection cs_mapAddressBook;
-
+extern CCriticalSection cs_setpwalletRegistered;
+extern std::set<CWallet*> setpwalletRegistered;
// Settings
extern int fGenerateBitcoins;
extern int64 nTransactionFee;
-extern CAddress addrIncoming;
extern int fLimitProcessors;
extern int nLimitProcessors;
extern int fMinimizeToTray;
class CTxDB;
class CTxIndex;
+void RegisterWallet(CWallet* pwalletIn);
+void UnregisterWallet(CWallet* pwalletIn);
+bool ProcessBlock(CNode* pfrom, CBlock* pblock);
bool CheckDiskSpace(uint64 nAdditionalBytes=0);
FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
FILE* AppendBlockFile(unsigned int& nFileRet);
bool LoadBlockIndex(bool fAllowNew=true);
void PrintBlockTree();
bool ProcessMessages(CNode* pfrom);
-bool ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vRecv);
bool SendMessages(CNode* pto, bool fSendTrickle);
-void GenerateBitcoins(bool fGenerate);
-void ThreadBitcoinMiner(void* parg);
+void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
CBlock* CreateNewBlock(CReserveKey& reservekey);
-void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce, int64& nPrevTime);
+void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
-bool CheckWork(CBlock* pblock, CReserveKey& reservekey);
-void BitcoinMiner();
+bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
+unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
+int GetNumBlocksOfPeers();
bool IsInitialBlockDownload();
std::string GetWarnings(std::string strFor);
+bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
+
+template<typename T>
+bool WriteSetting(const std::string& strKey, const T& value)
+{
+ bool fOk = false;
+ BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
+ {
+ std::string strWalletFile;
+ if (!GetWalletFile(pwallet, strWalletFile))
+ continue;
+ fOk |= CWalletDB(strWalletFile).WriteSetting(strKey, value);
+ }
+ return fOk;
+}
+
+
class CDiskTxPos
{
public:
CTxIn()
{
- nSequence = UINT_MAX;
+ nSequence = std::numeric_limits<unsigned int>::max();
}
- explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
+ explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max())
{
prevout = prevoutIn;
scriptSig = scriptSigIn;
nSequence = nSequenceIn;
}
- CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
+ CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max())
{
prevout = COutPoint(hashPrevTx, nOut);
scriptSig = scriptSigIn;
bool IsFinal() const
{
- return (nSequence == UINT_MAX);
+ return (nSequence == std::numeric_limits<unsigned int>::max());
}
friend bool operator==(const CTxIn& a, const CTxIn& b)
str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
else
str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
- if (nSequence != UINT_MAX)
+ if (nSequence != std::numeric_limits<unsigned int>::max())
str += strprintf(", nSequence=%u", nSequence);
str += ")";
return str;
{
printf("%s\n", ToString().c_str());
}
-
- bool IsMine() const;
- int64 GetDebit() const;
};
return SerializeHash(*this);
}
- bool IsMine() const
- {
- return ::IsMine(scriptPubKey);
- }
-
- int64 GetCredit() const
- {
- if (!MoneyRange(nValue))
- throw std::runtime_error("CTxOut::GetCredit() : value out of range");
- return (IsMine() ? nValue : 0);
- }
-
- bool IsChange() const
- {
- // On a debit transaction, a txout that's mine but isn't in the address book is change
- std::vector<unsigned char> vchPubKey;
- if (ExtractPubKey(scriptPubKey, true, vchPubKey))
- CRITICAL_BLOCK(cs_mapAddressBook)
- if (!mapAddressBook.count(PubKeyToAddress(vchPubKey)))
- return true;
- return false;
- }
-
- int64 GetChange() const
- {
- if (!MoneyRange(nValue))
- throw std::runtime_error("CTxOut::GetChange() : value out of range");
- return (IsChange() ? nValue : 0);
- }
-
friend bool operator==(const CTxOut& a, const CTxOut& b)
{
return (a.nValue == b.nValue &&
std::vector<CTxOut> vout;
unsigned int nLockTime;
+ // Denial-of-service detection:
+ mutable int nDoS;
+ bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
CTransaction()
{
vin.clear();
vout.clear();
nLockTime = 0;
+ nDoS = 0; // Denial-of-service prevention
}
bool IsNull() const
nBlockHeight = nBestHeight;
if (nBlockTime == 0)
nBlockTime = GetAdjustedTime();
- if ((int64)nLockTime < (nLockTime < 500000000 ? (int64)nBlockHeight : nBlockTime))
+ if ((int64)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
return true;
BOOST_FOREACH(const CTxIn& txin, vin)
if (!txin.IsFinal())
return false;
bool fNewer = false;
- unsigned int nLowest = UINT_MAX;
+ unsigned int nLowest = std::numeric_limits<unsigned int>::max();
for (int i = 0; i < vin.size(); i++)
{
if (vin[i].nSequence != old.vin[i].nSequence)
return true;
}
- bool IsMine() const
- {
- BOOST_FOREACH(const CTxOut& txout, vout)
- if (txout.IsMine())
- return true;
- return false;
- }
-
- bool IsFromMe() const
- {
- return (GetDebit() > 0);
- }
-
- int64 GetDebit() const
- {
- int64 nDebit = 0;
- BOOST_FOREACH(const CTxIn& txin, vin)
- {
- nDebit += txin.GetDebit();
- if (!MoneyRange(nDebit))
- throw std::runtime_error("CTransaction::GetDebit() : value out of range");
- }
- return nDebit;
- }
-
- int64 GetCredit() const
- {
- int64 nCredit = 0;
- BOOST_FOREACH(const CTxOut& txout, vout)
- {
- nCredit += txout.GetCredit();
- if (!MoneyRange(nCredit))
- throw std::runtime_error("CTransaction::GetCredit() : value out of range");
- }
- return nCredit;
- }
-
- int64 GetChange() const
- {
- if (IsCoinBase())
- return 0;
- int64 nChange = 0;
- BOOST_FOREACH(const CTxOut& txout, vout)
- {
- nChange += txout.GetChange();
- if (!MoneyRange(nChange))
- throw std::runtime_error("CTransaction::GetChange() : value out of range");
- }
- return nChange;
- }
-
int64 GetValueOut() const
{
int64 nValueOut = 0;
int SetMerkleBranch(const CBlock* pblock=NULL);
- int GetDepthInMainChain(int& nHeightRet) const;
- int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
+ int GetDepthInMainChain(CBlockIndex* &pindexRet) const;
+ int GetDepthInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
int GetBlocksToMaturity() const;
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
return !(a == b);
}
int GetDepthInMainChain() const;
+
};
// memory only
mutable std::vector<uint256> vMerkleTree;
+ // Denial-of-service detection:
+ mutable int nDoS;
+ bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
CBlock()
{
nNonce = 0;
vtx.clear();
vMerkleTree.clear();
+ nDoS = 0;
}
bool IsNull() const
fflush(fileout);
if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
{
-#ifdef __WXMSW__
+#ifdef WIN32
_commit(_fileno(fileout));
#else
fsync(fileno(fileout));
Set((*mi).second);
}
+ CBlockLocator(const std::vector<uint256>& vHaveIn)
+ {
+ vHave = vHaveIn;
+ }
+
IMPLEMENT_SERIALIZE
(
if (!(nType & SER_GETHASH))
bool AppliesTo(int nVersion, std::string strSubVerIn) const
{
+ // TODO: rework for client-version-embedded-in-strSubVer ?
return (IsInEffect() &&
nMinVer <= nVersion && nVersion <= nMaxVer &&
(setSubVer.empty() || setSubVer.count(strSubVerIn)));
bool AppliesToMe() const
{
- return AppliesTo(VERSION, ::pszSubVer);
+ return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<std::string>()));
}
bool RelayTo(CNode* pnode) const
bool ProcessAlert();
};
-
-
-
-
-
-
-
-
-
-extern std::map<uint256, CTransaction> mapTransactions;
-extern std::map<std::vector<unsigned char>, CPrivKey> mapKeys;
-extern std::map<uint160, std::vector<unsigned char> > mapPubKeys;
-extern CCriticalSection cs_mapKeys;
-
#endif