aboutsummaryrefslogtreecommitdiff
path: root/src/main.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.h')
-rw-r--r--src/main.h169
1 files changed, 95 insertions, 74 deletions
diff --git a/src/main.h b/src/main.h
index 996b727b6..fc8d45992 100644
--- a/src/main.h
+++ b/src/main.h
@@ -1,48 +1,39 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 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.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_MAIN_H
#define BITCOIN_MAIN_H
#include "bignum.h"
+#include "sync.h"
#include "net.h"
-#include "key.h"
#include "script.h"
-#include "db.h"
#include <list>
+class CWallet;
class CBlock;
class CBlockIndex;
-class CWalletTx;
-class CWallet;
class CKeyItem;
class CReserveKey;
-class CWalletDB;
class CAddress;
class CInv;
class CRequestTracker;
class CNode;
-static const int CLIENT_VERSION = 60006;
-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 int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100;
-static const int64 COIN = 100000000;
-static const int64 CENT = 1000000;
+static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
+static const unsigned int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100;
static const int64 MIN_TX_FEE = 50000;
static const int64 MIN_RELAY_TX_FEE = 10000;
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
+static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
#ifdef USE_UPNP
static const int fHaveUPnP = true;
#else
@@ -66,7 +57,6 @@ extern CBigNum bnBestChainWork;
extern CBigNum bnBestInvalidWork;
extern uint256 hashBestChain;
extern CBlockIndex* pindexBest;
-extern uint64 nPooledTx;
extern unsigned int nTransactionsUpdated;
extern uint64 nLastBlockTx;
extern uint64 nLastBlockSize;
@@ -76,12 +66,13 @@ extern int64 nHPSTimerStart;
extern int64 nTimeBestReceived;
extern CCriticalSection cs_setpwalletRegistered;
extern std::set<CWallet*> setpwalletRegistered;
+extern unsigned char pchMessageStart[4];
// Settings
extern int64 nTransactionFee;
-
-
+// Minimum disk space required - used in CheckDiskSpace()
+static const uint64 nMinDiskSpace = 52428800;
class CReserveKey;
@@ -90,6 +81,7 @@ class CTxIndex;
void RegisterWallet(CWallet* pwalletIn);
void UnregisterWallet(CWallet* pwalletIn);
+void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false);
bool ProcessBlock(CNode* pfrom, CBlock* pblock);
bool CheckDiskSpace(uint64 nAdditionalBytes=0);
FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
@@ -98,6 +90,7 @@ bool LoadBlockIndex(bool fAllowNew=true);
void PrintBlockTree();
bool ProcessMessages(CNode* pfrom);
bool SendMessages(CNode* pto, bool fSendTrickle);
+bool LoadExternalBlockFile(FILE* fileIn);
void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
CBlock* CreateNewBlock(CReserveKey& reservekey);
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
@@ -108,7 +101,7 @@ unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
int GetNumBlocksOfPeers();
bool IsInitialBlockDownload();
std::string GetWarnings(std::string strFor);
-
+bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock);
@@ -143,8 +136,8 @@ public:
}
IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
- void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; }
- bool IsNull() const { return (nFile == -1); }
+ void SetNull() { nFile = (unsigned int) -1; nBlockPos = 0; nTxPos = 0; }
+ bool IsNull() const { return (nFile == (unsigned int) -1); }
friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
{
@@ -161,7 +154,7 @@ public:
std::string ToString() const
{
if (IsNull())
- return strprintf("null");
+ return "null";
else
return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos);
}
@@ -183,8 +176,8 @@ public:
CInPoint() { SetNull(); }
CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
- void SetNull() { ptx = NULL; n = -1; }
- bool IsNull() const { return (ptx == NULL && n == -1); }
+ void SetNull() { ptx = NULL; n = (unsigned int) -1; }
+ bool IsNull() const { return (ptx == NULL && n == (unsigned int) -1); }
};
@@ -199,8 +192,8 @@ public:
COutPoint() { SetNull(); }
COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
- void SetNull() { hash = 0; n = -1; }
- bool IsNull() const { return (hash == 0 && n == -1); }
+ void SetNull() { hash = 0; n = (unsigned int) -1; }
+ bool IsNull() const { return (hash == 0 && n == (unsigned int) -1); }
friend bool operator<(const COutPoint& a, const COutPoint& b)
{
@@ -288,7 +281,7 @@ public:
std::string ToString() const
{
std::string str;
- str += strprintf("CTxIn(");
+ str += "CTxIn(";
str += prevout.ToString();
if (prevout.IsNull())
str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
@@ -393,6 +386,7 @@ typedef std::map<uint256, std::pair<CTxIndex, CTransaction> > MapPrevTx;
class CTransaction
{
public:
+ static const int CURRENT_VERSION=1;
int nVersion;
std::vector<CTxIn> vin;
std::vector<CTxOut> vout;
@@ -418,7 +412,7 @@ public:
void SetNull()
{
- nVersion = 1;
+ nVersion = CTransaction::CURRENT_VERSION;
vin.clear();
vout.clear();
nLockTime = 0;
@@ -444,7 +438,7 @@ public:
nBlockHeight = nBestHeight;
if (nBlockTime == 0)
nBlockTime = GetAdjustedTime();
- if ((int64)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
+ if ((int64)nLockTime < ((int64)nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
return true;
BOOST_FOREACH(const CTxIn& txin, vin)
if (!txin.IsFinal())
@@ -456,13 +450,13 @@ public:
{
if (vin.size() != old.vin.size())
return false;
- for (int i = 0; i < vin.size(); i++)
+ for (unsigned int i = 0; i < vin.size(); i++)
if (vin[i].prevout != old.vin[i].prevout)
return false;
bool fNewer = false;
unsigned int nLowest = std::numeric_limits<unsigned int>::max();
- for (int i = 0; i < vin.size(); i++)
+ for (unsigned int i = 0; i < vin.size(); i++)
{
if (vin[i].nSequence != old.vin[i].nSequence)
{
@@ -502,7 +496,7 @@ public:
@return number of sigops this transaction's outputs will produce when spent
@see CTransaction::FetchInputs
*/
- int GetLegacySigOpCount() const;
+ unsigned int GetLegacySigOpCount() const;
/** Count ECDSA signature operations in pay-to-script-hash inputs.
@@ -510,7 +504,7 @@ public:
@return maximum number of sigops required to validate this transaction's inputs
@see CTransaction::FetchInputs
*/
- int GetP2SHSigOpCount(const MapPrevTx& mapInputs) const;
+ unsigned int GetP2SHSigOpCount(const MapPrevTx& mapInputs) const;
/** Amount of bitcoins spent by this transaction.
@return sum of all outputs (note: does not include fees)
@@ -549,7 +543,7 @@ public:
// Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE
int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
- unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
+ unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
unsigned int nNewBlockSize = nBlockSize + nBytes;
int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
@@ -572,9 +566,11 @@ public:
// To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01
if (nMinFee < nBaseFee)
+ {
BOOST_FOREACH(const CTxOut& txout, vout)
if (txout.nValue < CENT)
nMinFee = nBaseFee;
+ }
// Raise the price as the block approaches full
if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
@@ -592,14 +588,20 @@ public:
bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
{
- CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
+ CAutoFile filein = CAutoFile(OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb"), SER_DISK, CLIENT_VERSION);
if (!filein)
return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
// Read transaction
if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
return error("CTransaction::ReadFromDisk() : fseek failed");
- filein >> *this;
+
+ try {
+ filein >> *this;
+ }
+ catch (std::exception &e) {
+ return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__);
+ }
// Return file pointer
if (pfileRet)
@@ -634,9 +636,9 @@ public:
vin.size(),
vout.size(),
nLockTime);
- for (int i = 0; i < vin.size(); i++)
+ for (unsigned int i = 0; i < vin.size(); i++)
str += " " + vin[i].ToString() + "\n";
- for (int i = 0; i < vout.size(); i++)
+ for (unsigned int i = 0; i < vout.size(); i++)
str += " " + vout[i].ToString() + "\n";
return str;
}
@@ -683,13 +685,9 @@ public:
bool ClientConnectInputs();
bool CheckTransaction() const;
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
- bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL);
protected:
const CTxOut& GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const;
- bool AddToMemoryPoolUnchecked();
-public:
- bool RemoveFromMemoryPool();
};
@@ -705,7 +703,7 @@ public:
int nIndex;
// memory only
- mutable char fMerkleVerified;
+ mutable bool fMerkleVerified;
CMerkleTx()
@@ -820,6 +818,7 @@ class CBlock
{
public:
// header
+ static const int CURRENT_VERSION=1;
int nVersion;
uint256 hashPrevBlock;
uint256 hashMerkleRoot;
@@ -861,7 +860,7 @@ public:
void SetNull()
{
- nVersion = 1;
+ nVersion = CBlock::CURRENT_VERSION;
hashPrevBlock = 0;
hashMerkleRoot = 0;
nTime = 0;
@@ -944,7 +943,7 @@ public:
bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
{
// Open history file to append
- CAutoFile fileout = AppendBlockFile(nFileRet);
+ CAutoFile fileout = CAutoFile(AppendBlockFile(nFileRet), SER_DISK, CLIENT_VERSION);
if (!fileout)
return error("CBlock::WriteToDisk() : AppendBlockFile failed");
@@ -953,21 +952,16 @@ public:
fileout << FLATDATA(pchMessageStart) << nSize;
// Write block
- nBlockPosRet = ftell(fileout);
- if (nBlockPosRet == -1)
+ long fileOutPos = ftell(fileout);
+ if (fileOutPos < 0)
return error("CBlock::WriteToDisk() : ftell failed");
+ nBlockPosRet = fileOutPos;
fileout << *this;
// Flush stdio buffers and commit to disk before returning
fflush(fileout);
if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
- {
-#ifdef WIN32
- _commit(_fileno(fileout));
-#else
- fsync(fileno(fileout));
-#endif
- }
+ FileCommit(fileout);
return true;
}
@@ -977,14 +971,19 @@ public:
SetNull();
// Open history file to read
- CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
+ CAutoFile filein = CAutoFile(OpenBlockFile(nFile, nBlockPos, "rb"), SER_DISK, CLIENT_VERSION);
if (!filein)
return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
if (!fReadTransactions)
filein.nType |= SER_BLOCKHEADERONLY;
// Read block
- filein >> *this;
+ try {
+ filein >> *this;
+ }
+ catch (std::exception &e) {
+ return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__);
+ }
// Check the header
if (!CheckProofOfWork(GetHash(), nBits))
@@ -1004,13 +1003,13 @@ public:
hashMerkleRoot.ToString().substr(0,10).c_str(),
nTime, nBits, nNonce,
vtx.size());
- for (int i = 0; i < vtx.size(); i++)
+ for (unsigned int i = 0; i < vtx.size(); i++)
{
printf(" ");
vtx[i].print();
}
printf(" vMerkleTree: ");
- for (int i = 0; i < vMerkleTree.size(); i++)
+ for (unsigned int i = 0; i < vMerkleTree.size(); i++)
printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
printf("\n");
}
@@ -1135,21 +1134,6 @@ public:
return CheckProofOfWork(GetBlockHash(), nBits);
}
- bool EraseBlockFromDisk()
- {
- // Open history file
- CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
- if (!fileout)
- return false;
-
- // Overwrite with empty null block
- CBlock block;
- block.SetNull();
- fileout << block;
-
- return true;
- }
-
enum { nMedianTimeSpan=11 };
int64 GetMedianTimePast() const
@@ -1598,12 +1582,49 @@ public:
return error("CAlert::CheckSignature() : verify signature failed");
// Now unserialize the data
- CDataStream sMsg(vchMsg);
+ CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION);
sMsg >> *(CUnsignedAlert*)this;
return true;
}
bool ProcessAlert();
+
+ /*
+ * Get copy of (active) alert object by hash. Returns a null alert if it is not found.
+ */
+ static CAlert getAlertByHash(const uint256 &hash);
};
+class CTxMemPool
+{
+public:
+ mutable CCriticalSection cs;
+ std::map<uint256, CTransaction> mapTx;
+ std::map<COutPoint, CInPoint> mapNextTx;
+
+ bool accept(CTxDB& txdb, CTransaction &tx,
+ bool fCheckInputs, bool* pfMissingInputs);
+ bool addUnchecked(const uint256& hash, CTransaction &tx);
+ bool remove(CTransaction &tx);
+ void queryHashes(std::vector<uint256>& vtxid);
+
+ unsigned long size()
+ {
+ LOCK(cs);
+ return mapTx.size();
+ }
+
+ bool exists(uint256 hash)
+ {
+ return (mapTx.count(hash) != 0);
+ }
+
+ CTransaction& lookup(uint256 hash)
+ {
+ return mapTx[hash];
+ }
+};
+
+extern CTxMemPool mempool;
+
#endif