aboutsummaryrefslogtreecommitdiff
path: root/src/main.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.h')
-rw-r--r--src/main.h112
1 files changed, 72 insertions, 40 deletions
diff --git a/src/main.h b/src/main.h
index d5f7093e42..c1af0c3706 100644
--- a/src/main.h
+++ b/src/main.h
@@ -28,6 +28,8 @@ struct CBlockIndexWorkComparator;
static const unsigned int MAX_BLOCK_SIZE = 1000000;
/** The maximum size for mined blocks */
static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
+/** The maximum size for transactions we're willing to relay/mine **/
+static const unsigned int MAX_STANDARD_TX_SIZE = MAX_BLOCK_SIZE_GEN/5;
/** The maximum allowed number of signature check operations in a block (network rule) */
static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
/** The maximum number of orphan transactions kept in memory */
@@ -106,15 +108,17 @@ static const uint64 nMinDiskSpace = 52428800;
class CReserveKey;
class CCoinsDB;
class CBlockTreeDB;
-class CDiskBlockPos;
+struct CDiskBlockPos;
class CCoins;
class CTxUndo;
class CCoinsView;
class CCoinsViewCache;
class CScriptCheck;
+class CValidationState;
struct CBlockTemplate;
+
/** Register a wallet to receive updates from core */
void RegisterWallet(CWallet* pwalletIn);
/** Unregister a wallet from core */
@@ -122,7 +126,7 @@ void UnregisterWallet(CWallet* pwalletIn);
/** Push an updated transaction to all registered wallets */
void SyncWithWallets(const uint256 &hash, const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false);
/** Process an incoming block */
-bool ProcessBlock(CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp = NULL);
+bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp = NULL);
/** Check whether enough disk space is available for an incoming block */
bool CheckDiskSpace(uint64 nAdditionalBytes = 0);
/** Open a block file (blk?????.dat) */
@@ -131,8 +135,12 @@ FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly = false);
FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false);
/** Import blocks from an external file */
bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp = NULL);
+/** Initialize a new block tree database + block data on disk */
+bool InitBlockIndex();
/** Load the block tree and coins database from disk */
bool LoadBlockIndex();
+/** Unload database information */
+void UnloadBlockIndex();
/** Verify consistency of the block and coin databases */
bool VerifyDB();
/** Print the loaded block tree */
@@ -172,13 +180,15 @@ std::string GetWarnings(std::string strFor);
/** Retrieve a transaction (from memory pool, or from disk, if possible) */
bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false);
/** Connect/disconnect blocks until pindexNew is the new tip of the active block chain */
-bool SetBestChain(CBlockIndex* pindexNew);
+bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew);
/** Find the best known block, and make it the tip of the block chain */
-bool ConnectBestBlock();
+bool ConnectBestBlock(CValidationState &state);
/** Create a new block index entry for a given block hash */
CBlockIndex * InsertBlockIndex(uint256 hash);
/** Verify a signature */
bool VerifySignature(const CCoins& txFrom, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType);
+/** Abort with a message */
+bool AbortNode(const std::string &msg);
@@ -454,7 +464,6 @@ public:
-
enum GetMinFee_mode
{
GMF_BLOCK,
@@ -474,10 +483,6 @@ public:
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()
{
SetNull();
@@ -498,7 +503,6 @@ public:
vin.clear();
vout.clear();
nLockTime = 0;
- nDoS = 0; // Denial-of-service prevention
}
bool IsNull() const
@@ -654,27 +658,24 @@ public:
}
- // Do all possible client-mode checks
- bool ClientCheckInputs() const;
-
// Check whether all prevouts of this transaction are present in the UTXO set represented by view
bool HaveInputs(CCoinsViewCache &view) const;
// Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts)
// This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it
// instead of being performed inline.
- bool CheckInputs(CCoinsViewCache &view, bool fScriptChecks = true,
+ bool CheckInputs(CValidationState &state, CCoinsViewCache &view, bool fScriptChecks = true,
unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC,
std::vector<CScriptCheck> *pvChecks = NULL) const;
// Apply the effects of this transaction on the UTXO set represented by view
- bool UpdateCoins(CCoinsViewCache &view, CTxUndo &txundo, int nHeight, const uint256 &txhash) const;
+ bool UpdateCoins(CValidationState &state, CCoinsViewCache &view, CTxUndo &txundo, int nHeight, const uint256 &txhash) const;
// Context-independent validity checks
- bool CheckTransaction() const;
+ bool CheckTransaction(CValidationState &state) const;
// Try to accept this transaction into the memory pool
- bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL);
+ bool AcceptToMemoryPool(CValidationState &state, bool fCheckInputs=true, bool fLimitFree = true, bool* pfMissingInputs=NULL);
protected:
static const CTxOut &GetOutputFor(const CTxIn& input, CCoinsViewCache& mapInputs);
@@ -814,22 +815,12 @@ public:
uint256 hashChecksum;
try {
filein >> *this;
+ filein >> hashChecksum;
}
catch (std::exception &e) {
return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__);
}
- // for compatibility with pre-release code that didn't write checksums to undo data
- // TODO: replace by a simply 'filein >> hashChecksum' in the above try block
- try {
- filein >> hashChecksum;
- } catch (std::exception &e) {
- hashChecksum = 0;
- }
- uint32_t hashInit = hashChecksum.Get64(0) & 0xFFFFFFFFUL;
- if (hashChecksum == 0 || memcmp(&hashInit, pchMessageStart, 4) == 0)
- return true;
-
// Verify checksum
CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
hasher << hashBlock;
@@ -1163,7 +1154,7 @@ public:
int GetDepthInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
int GetBlocksToMaturity() const;
- bool AcceptToMemoryPool(bool fCheckInputs=true);
+ bool AcceptToMemoryPool(bool fCheckInputs=true, bool fLimitFree=true);
};
@@ -1339,10 +1330,6 @@ public:
// 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()
{
SetNull();
@@ -1365,7 +1352,6 @@ public:
CBlockHeader::SetNull();
vtx.clear();
vMerkleTree.clear();
- nDoS = 0;
}
CBlockHeader GetBlockHeader() const
@@ -1513,23 +1499,23 @@ public:
* In case pfClean is provided, operation will try to be tolerant about errors, and *pfClean
* will be true if no problems were found. Otherwise, the return value will be false in case
* of problems. Note that in any case, coins may be modified. */
- bool DisconnectBlock(CBlockIndex *pindex, CCoinsViewCache &coins, bool *pfClean = NULL);
+ bool DisconnectBlock(CValidationState &state, CBlockIndex *pindex, CCoinsViewCache &coins, bool *pfClean = NULL);
// Apply the effects of this block (with given index) on the UTXO set represented by coins
- bool ConnectBlock(CBlockIndex *pindex, CCoinsViewCache &coins, bool fJustCheck=false);
+ bool ConnectBlock(CValidationState &state, CBlockIndex *pindex, CCoinsViewCache &coins, bool fJustCheck=false);
// Read a block from disk
bool ReadFromDisk(const CBlockIndex* pindex);
// Add this block to the block index, and if necessary, switch the active block chain to this
- bool AddToBlockIndex(const CDiskBlockPos &pos);
+ bool AddToBlockIndex(CValidationState &state, const CDiskBlockPos &pos);
// Context-independent validity checks
- bool CheckBlock(bool fCheckPOW=true, bool fCheckMerkleRoot=true) const;
+ bool CheckBlock(CValidationState &state, bool fCheckPOW=true, bool fCheckMerkleRoot=true) const;
// Store block on disk
// if dbp is provided, the file is known to already reside on disk
- bool AcceptBlock(CDiskBlockPos *dbp = NULL);
+ bool AcceptBlock(CValidationState &state, CDiskBlockPos *dbp = NULL);
};
@@ -1896,6 +1882,52 @@ public:
}
};
+/** Capture information about block/transaction validation */
+class CValidationState {
+private:
+ enum mode_state {
+ MODE_VALID, // everything ok
+ MODE_INVALID, // network rule violation (DoS value may be set)
+ MODE_ERROR, // run-time error
+ } mode;
+ int nDoS;
+public:
+ CValidationState() : mode(MODE_VALID), nDoS(0) {}
+ bool DoS(int level, bool ret = false) {
+ if (mode == MODE_ERROR)
+ return ret;
+ nDoS += level;
+ mode = MODE_INVALID;
+ return ret;
+ }
+ bool Invalid(bool ret = false) {
+ return DoS(0, ret);
+ }
+ bool Error() {
+ mode = MODE_ERROR;
+ return false;
+ }
+ bool Abort(const std::string &msg) {
+ AbortNode(msg);
+ return Error();
+ }
+ bool IsValid() {
+ return mode == MODE_VALID;
+ }
+ bool IsInvalid() {
+ return mode == MODE_INVALID;
+ }
+ bool IsError() {
+ return mode == MODE_ERROR;
+ }
+ bool IsInvalid(int &nDoSOut) {
+ if (IsInvalid()) {
+ nDoSOut = nDoS;
+ return true;
+ }
+ return false;
+ }
+};
@@ -2044,7 +2076,7 @@ public:
std::map<uint256, CTransaction> mapTx;
std::map<COutPoint, CInPoint> mapNextTx;
- bool accept(CTransaction &tx, bool fCheckInputs, bool* pfMissingInputs);
+ bool accept(CValidationState &state, CTransaction &tx, bool fCheckInputs, bool fLimitFree, bool* pfMissingInputs);
bool addUnchecked(const uint256& hash, CTransaction &tx);
bool remove(const CTransaction &tx, bool fRecursive = false);
bool removeConflicts(const CTransaction &tx);