#ifndef BITCOIN_MAIN_H
#define BITCOIN_MAIN_H
-#include <stdint.h>
-
#include "bignum.h"
#include "net.h"
#include "key.h"
class CInv;
class CRequestTracker;
class CNode;
-class CBlockIndex;
static const int CLIENT_VERSION = 59900;
static const bool VERSION_IS_BETA = true;
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_t COIN = 100000000;
-static const int64_t CENT = 1000000;
-static const int64_t MIN_TX_FEE = 50000;
-static const int64_t MIN_RELAY_TX_FEE = 10000;
-static const int64_t MAX_MONEY = 21000000 * COIN;
-inline bool MoneyRange(int64_t nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
+static const int64 COIN = 100000000;
+static const int64 CENT = 1000000;
+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
#endif
+// Put "/P2SH/" in the coinbase so everybody can tell when
+// a majority of miners support it
+static const char* pszP2SH = "/P2SH/";
+static const CScript COINBASE_FLAGS = CScript() << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH));
+
+
extern CBigNum bnBestInvalidWork;
extern uint256 hashBestChain;
extern CBlockIndex* pindexBest;
+extern uint64 nPooledTx;
extern unsigned int nTransactionsUpdated;
+extern uint64 nLastBlockTx;
+extern uint64 nLastBlockSize;
+extern const std::string strMessageMagic;
extern double dHashesPerSec;
-extern int64_t nHPSTimerStart;
-extern int64_t nTimeBestReceived;
+extern int64 nHPSTimerStart;
+extern int64 nTimeBestReceived;
extern CCriticalSection cs_setpwalletRegistered;
extern std::set<CWallet*> setpwalletRegistered;
// Settings
extern int fGenerateBitcoins;
-extern int64_t nTransactionFee;
+extern int64 nTransactionFee;
extern int fLimitProcessors;
extern int nLimitProcessors;
extern int fMinimizeToTray;
void RegisterWallet(CWallet* pwalletIn);
void UnregisterWallet(CWallet* pwalletIn);
bool ProcessBlock(CNode* pfrom, CBlock* pblock);
-bool CheckDiskSpace(uint64_t nAdditionalBytes=0);
+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 FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
-unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime);
+unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
int GetNumBlocksOfPeers();
bool IsInitialBlockDownload();
std::string GetWarnings(std::string strFor);
class CTxOut
{
public:
- int64_t nValue;
+ int64 nValue;
CScript scriptPubKey;
CTxOut()
SetNull();
}
- CTxOut(int64_t nValueIn, CScript scriptPubKeyIn)
+ CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
{
nValue = nValueIn;
scriptPubKey = scriptPubKeyIn;
GMF_SEND,
};
+typedef std::map<uint256, std::pair<CTxIndex, CTransaction> > MapPrevTx;
+
//
// The basic transaction that is broadcasted on the network and contained in
// blocks. A transaction can contain multiple inputs and outputs.
return SerializeHash(*this);
}
- bool IsFinal(int nBlockHeight=0, int64_t nBlockTime=0) const
+ bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
{
// Time based nLockTime implemented in 0.1.6
if (nLockTime == 0)
nBlockHeight = nBestHeight;
if (nBlockTime == 0)
nBlockTime = GetAdjustedTime();
- if ((int64_t)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
+ if ((int64)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
return true;
BOOST_FOREACH(const CTxIn& txin, vin)
if (!txin.IsFinal())
return (vin.size() == 1 && vin[0].prevout.IsNull());
}
+ /** Check for standard transaction types
+ @return True if all outputs (scriptPubKeys) use only standard transaction forms
+ */
bool IsStandard() const;
- bool AreInputsStandard(std::map<uint256, std::pair<CTxIndex, CTransaction> > mapInputs) const;
- int64_t GetValueOut() const
- {
- int64_t nValueOut = 0;
+ /** Check for standard transaction types
+ @param[in] mapInputs Map of previous transactions that have outputs we're spending
+ @return True if all inputs (scriptSigs) use only standard transaction forms
+ @see CTransaction::FetchInputs
+ */
+ bool AreInputsStandard(const MapPrevTx& mapInputs) const;
+
+ /** Count ECDSA signature operations the old-fashioned (pre-0.6) way
+ @return number of sigops this transaction's outputs will produce when spent
+ @see CTransaction::FetchInputs
+ */
+ int GetLegacySigOpCount() const;
+
+ /** Count ECDSA signature operations in pay-to-script-hash inputs.
+
+ @param[in] mapInputs Map of previous transactions that have outputs we're spending
+ @return maximum number of sigops required to validate this transaction's inputs
+ @see CTransaction::FetchInputs
+ */
+ int GetP2SHSigOpCount(const MapPrevTx& mapInputs) const;
+
+ /** Amount of bitcoins spent by this transaction.
+ @return sum of all outputs (note: does not include fees)
+ */
+ int64 GetValueOut() const
+ {
+ int64 nValueOut = 0;
BOOST_FOREACH(const CTxOut& txout, vout)
{
nValueOut += txout.nValue;
return nValueOut;
}
+ /** Amount of bitcoins coming in to this transaction
+ Note that lightweight clients may not know anything besides the hash of previous transactions,
+ so may not be able to calculate this.
+
+ @param[in] mapInputs Map of previous transactions that have outputs we're spending
+ @return Sum of value of all inputs (scriptSigs)
+ @see CTransaction::FetchInputs
+ */
+ int64 GetValueIn(const MapPrevTx& mapInputs) const;
+
static bool AllowFree(double dPriority)
{
// Large (in bytes) low-priority (new, small-coin) transactions
return dPriority > COIN * 144 / 250;
}
- int64_t GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, enum GetMinFee_mode mode=GMF_BLOCK) const
+ int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, enum GetMinFee_mode mode=GMF_BLOCK) const
{
// Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE
- int64_t nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
+ int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
unsigned int nNewBlockSize = nBlockSize + nBytes;
- int64_t nMinFee = (1 + (int64_t)nBytes / 1000) * nBaseFee;
+ int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
if (fAllowFree)
{
bool ReadFromDisk(COutPoint prevout);
bool DisconnectInputs(CTxDB& txdb);
- // Fetch from memory and/or disk. inputsRet keys are transaction hashes.
+ /** Fetch from memory and/or disk. inputsRet keys are transaction hashes.
+
+ @param[in] txdb Transaction database
+ @param[in] mapTestPool List of pending changes to the transaction index database
+ @param[in] fBlock True if being called to add a new best-block to the chain
+ @param[in] fMiner True if being called by CreateNewBlock
+ @param[out] inputsRet Pointers to this transaction's inputs
+ @param[out] fInvalid returns true if transaction is invalid
+ @return Returns true if all inputs are in txdb or mapTestPool
+ */
bool FetchInputs(CTxDB& txdb, const std::map<uint256, CTxIndex>& mapTestPool,
- bool fBlock, bool fMiner, std::map<uint256, std::pair<CTxIndex, CTransaction> >& inputsRet);
- bool ConnectInputs(std::map<uint256, std::pair<CTxIndex, CTransaction> > inputs,
- std::map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
- CBlockIndex* pindexBlock, int64_t& nFees, bool fBlock, bool fMiner, int& nSigOpsRet, int64_t nMinFee=0);
+ bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid);
+
+ /** Sanity check previous transactions, then, if all checks succeed,
+ mark them as spent by this transaction.
+
+ @param[in] inputs Previous transactions (from FetchInputs)
+ @param[out] mapTestPool Keeps track of inputs that need to be updated on disk
+ @param[in] posThisTx Position of this transaction on disk
+ @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
+ @return Returns true if all checks succeed
+ */
+ bool ConnectInputs(MapPrevTx inputs,
+ std::map<uint256, CTxIndex>& mapTestPool, const CDiskTxPos& posThisTx,
+ const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash=true);
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();
return Hash(BEGIN(nVersion), END(nNonce));
}
- int64_t GetBlockTime() const
+ int64 GetBlockTime() const
{
- return (int64_t)nTime;
+ return (int64)nTime;
}
return *phashBlock;
}
- int64_t GetBlockTime() const
+ int64 GetBlockTime() const
{
- return (int64_t)nTime;
+ return (int64)nTime;
}
CBigNum GetBlockWork() const
enum { nMedianTimeSpan=11 };
- int64_t GetMedianTimePast() const
+ int64 GetMedianTimePast() const
{
- int64_t pmedian[nMedianTimeSpan];
- int64_t* pbegin = &pmedian[nMedianTimeSpan];
- int64_t* pend = &pmedian[nMedianTimeSpan];
+ int64 pmedian[nMedianTimeSpan];
+ int64* pbegin = &pmedian[nMedianTimeSpan];
+ int64* pend = &pmedian[nMedianTimeSpan];
const CBlockIndex* pindex = this;
for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
return pbegin[(pend - pbegin)/2];
}
- int64_t GetMedianTime() const
+ int64 GetMedianTime() const
{
const CBlockIndex* pindex = this;
for (int i = 0; i < nMedianTimeSpan/2; i++)
{
public:
int nVersion;
- int64_t nRelayUntil; // when newer nodes stop relaying to newer nodes
- int64_t nExpiration;
+ int64 nRelayUntil; // when newer nodes stop relaying to newer nodes
+ int64 nExpiration;
int nID;
int nCancel;
std::set<int> setCancel;