Browse Source

Make comments in main an init doxygen compatible

Fix typos where appropriate
Update license/copyright
tags/v0.15.1
Michael Ford 6 years ago
parent
commit
c5b390b6b9
4 changed files with 189 additions and 160 deletions
  1. 5
    5
      src/init.cpp
  2. 3
    3
      src/init.h
  3. 82
    67
      src/main.cpp
  4. 99
    85
      src/main.h

+ 5
- 5
src/init.cpp View File

@@ -1,6 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
@@ -60,7 +60,7 @@ bool fFeeEstimatesInitialized = false;
#define MIN_CORE_FILEDESCRIPTORS 150
#endif

// Used to pass flags to the Bind() function
/** Used to pass flags to the Bind() function */
enum BindFlags {
BF_NONE = 0,
BF_EXPLICIT = (1U << 0),
@@ -175,9 +175,9 @@ void Shutdown()
LogPrintf("%s: done\n", __func__);
}

//
// Signal handlers are very limited in what they are allowed to do, so:
//
/**
* Signal handlers are very limited in what they are allowed to do, so:
*/
void HandleSIGTERM(int)
{
fRequestShutdown = true;

+ 3
- 3
src/init.h View File

@@ -1,6 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2013 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_INIT_H
@@ -22,7 +22,7 @@ bool ShutdownRequested();
void Shutdown();
bool AppInit2(boost::thread_group& threadGroup);

/* The help message mode determines what help message to show */
/** The help message mode determines what help message to show */
enum HelpMessageMode {
HMM_BITCOIND,
HMM_BITCOIN_QT

+ 82
- 67
src/main.cpp View File

@@ -1,6 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "main.h"
@@ -33,9 +33,9 @@ using namespace std;
# error "Bitcoin cannot be compiled without assertions."
#endif

//
// Global state
//
/**
* Global state
*/

CCriticalSection cs_main;

@@ -66,7 +66,7 @@ map<uint256, COrphanTx> mapOrphanTransactions;
map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
void EraseOrphansFor(NodeId peer);

// Constant stuff for coinbase transactions we create:
/** Constant stuff for coinbase transactions we create: */
CScript COINBASE_FLAGS;

const string strMessageMagic = "Bitcoin Signed Message:\n";
@@ -97,44 +97,49 @@ namespace {

CBlockIndex *pindexBestInvalid;

// The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS or better that are at least
// as good as our current tip. Entries may be failed, though.
/**
* The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS or better that are at least
* as good as our current tip. Entries may be failed, though.
*/
set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
// Number of nodes with fSyncStarted.
/** Number of nodes with fSyncStarted. */
int nSyncStarted = 0;
// All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions.
/** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions. */
multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;

CCriticalSection cs_LastBlockFile;
std::vector<CBlockFileInfo> vinfoBlockFile;
int nLastBlockFile = 0;

// Every received block is assigned a unique and increasing identifier, so we
// know which one to give priority in case of a fork.
/**
* Every received block is assigned a unique and increasing identifier, so we
* know which one to give priority in case of a fork.
*/
CCriticalSection cs_nBlockSequenceId;
// Blocks loaded from disk are assigned id 0, so start the counter at 1.
/** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
uint32_t nBlockSequenceId = 1;

// Sources of received blocks, to be able to send them reject messages or ban
// them, if processing happens afterwards. Protected by cs_main.
/**
* Sources of received blocks, to be able to send them reject messages or ban
* them, if processing happens afterwards. Protected by cs_main.
*/
map<uint256, NodeId> mapBlockSource;

// Blocks that are in flight, and that are in the queue to be downloaded.
// Protected by cs_main.
/** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */
struct QueuedBlock {
uint256 hash;
CBlockIndex *pindex; // Optional.
int64_t nTime; // Time of "getdata" request in microseconds.
CBlockIndex *pindex; //! Optional.
int64_t nTime; //! Time of "getdata" request in microseconds.
};
map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;

// Number of preferrable block download peers.
/** Number of preferable block download peers. */
int nPreferredDownload = 0;

// Dirty block index entries.
/** Dirty block index entries. */
set<CBlockIndex*> setDirtyBlockIndex;

// Dirty block file entries.
/** Dirty block file entries. */
set<int> setDirtyFileInfo;
} // anon namespace

@@ -148,19 +153,19 @@ namespace {
namespace {

struct CMainSignals {
// Notifies listeners of updated transaction data (transaction, and optionally the block it is found in.
/** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */
boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction;
// Notifies listeners of an erased transaction (currently disabled, requires transaction replacement).
/** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */
boost::signals2::signal<void (const uint256 &)> EraseTransaction;
// Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible).
/** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
boost::signals2::signal<void (const uint256 &)> UpdatedTransaction;
// Notifies listeners of a new active block chain.
/** Notifies listeners of a new active block chain. */
boost::signals2::signal<void (const CBlockLocator &)> SetBestChain;
// Notifies listeners about an inventory item being seen on the network.
/** Notifies listeners about an inventory item being seen on the network. */
boost::signals2::signal<void (const uint256 &)> Inventory;
// Tells listeners to broadcast their data.
/** Tells listeners to broadcast their data. */
boost::signals2::signal<void ()> Broadcast;
// Notifies listeners of a block validation result
/** Notifies listeners of a block validation result */
boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
} g_signals;

@@ -213,32 +218,34 @@ struct CBlockReject {
uint256 hashBlock;
};

// Maintain validation-specific state about nodes, protected by cs_main, instead
// by CNode's own locks. This simplifies asynchronous operation, where
// processing of incoming data is done after the ProcessMessage call returns,
// and we're no longer holding the node's locks.
/**
* Maintain validation-specific state about nodes, protected by cs_main, instead
* by CNode's own locks. This simplifies asynchronous operation, where
* processing of incoming data is done after the ProcessMessage call returns,
* and we're no longer holding the node's locks.
*/
struct CNodeState {
// Accumulated misbehaviour score for this peer.
//! Accumulated misbehaviour score for this peer.
int nMisbehavior;
// Whether this peer should be disconnected and banned (unless whitelisted).
//! Whether this peer should be disconnected and banned (unless whitelisted).
bool fShouldBan;
// String name of this peer (debugging/logging purposes).
//! String name of this peer (debugging/logging purposes).
std::string name;
// List of asynchronously-determined block rejections to notify this peer about.
//! List of asynchronously-determined block rejections to notify this peer about.
std::vector<CBlockReject> rejects;
// The best known block we know this peer has announced.
//! The best known block we know this peer has announced.
CBlockIndex *pindexBestKnownBlock;
// The hash of the last unknown block this peer has announced.
//! The hash of the last unknown block this peer has announced.
uint256 hashLastUnknownBlock;
// The last full block we both have.
//! The last full block we both have.
CBlockIndex *pindexLastCommonBlock;
// Whether we've started headers synchronization with this peer.
//! Whether we've started headers synchronization with this peer.
bool fSyncStarted;
// Since when we're stalling block download progress (in microseconds), or 0.
//! Since when we're stalling block download progress (in microseconds), or 0.
int64_t nStallingSince;
list<QueuedBlock> vBlocksInFlight;
int nBlocksInFlight;
// Whether we consider this a preferred download peer.
//! Whether we consider this a preferred download peer.
bool fPreferredDownload;

CNodeState() {
@@ -254,7 +261,7 @@ struct CNodeState {
}
};

// Map maintaining per-node state. Requires cs_main.
/** Map maintaining per-node state. Requires cs_main. */
map<NodeId, CNodeState> mapNodeState;

// Requires cs_main.
@@ -708,15 +715,15 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
return true;
}

//
// Check transaction inputs to mitigate two
// potential denial-of-service attacks:
//
// 1. scriptSigs with extra data stuffed into them,
// not consumed by scriptPubKey (or P2SH script)
// 2. P2SH scripts with a crazy number of expensive
// CHECKSIG/CHECKMULTISIG operations
//
/**
* Check transaction inputs to mitigate two
* potential denial-of-service attacks:
*
* 1. scriptSigs with extra data stuffed into them,
* not consumed by scriptPubKey (or P2SH script)
* 2. P2SH scripts with a crazy number of expensive
* CHECKSIG/CHECKMULTISIG operations
*/
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{
if (tx.IsCoinBase())
@@ -1054,7 +1061,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
return true;
}

// Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock
/** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
{
CBlockIndex *pindexSlow = NULL;
@@ -1818,7 +1825,7 @@ void FlushStateToDisk() {
FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
}

// Update chainActive and related internal data structures.
/** Update chainActive and related internal data structures. */
void static UpdateTip(CBlockIndex *pindexNew) {
chainActive.SetTip(pindexNew);

@@ -1857,7 +1864,7 @@ void static UpdateTip(CBlockIndex *pindexNew) {
}
}

// Disconnect chainActive's tip.
/** Disconnect chainActive's tip. */
bool static DisconnectTip(CValidationState &state) {
CBlockIndex *pindexDelete = chainActive.Tip();
assert(pindexDelete);
@@ -1904,8 +1911,10 @@ static int64_t nTimeFlush = 0;
static int64_t nTimeChainState = 0;
static int64_t nTimePostConnect = 0;

// Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
// corresponding to pindexNew, to bypass loading it again from disk.
/**
* Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
* corresponding to pindexNew, to bypass loading it again from disk.
*/
bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
assert(pindexNew->pprev == chainActive.Tip());
mempool.check(pcoinsTip);
@@ -1965,8 +1974,10 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
return true;
}

// Return the tip of the chain with the most work in it, that isn't
// known to be invalid (it's however far from certain to be valid).
/**
* Return the tip of the chain with the most work in it, that isn't
* known to be invalid (it's however far from certain to be valid).
*/
static CBlockIndex* FindMostWorkChain() {
do {
CBlockIndex *pindexNew = NULL;
@@ -2007,7 +2018,7 @@ static CBlockIndex* FindMostWorkChain() {
} while(true);
}

// Delete all entries in setBlockIndexCandidates that are worse than the current tip.
/** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */
static void PruneBlockIndexCandidates() {
// Note that we can't delete the current block itself, as we may need to return to it later in case a
// reorganization to a better block fails.
@@ -2019,8 +2030,10 @@ static void PruneBlockIndexCandidates() {
assert(!setBlockIndexCandidates.empty());
}

// Try to make some progress towards making pindexMostWork the active block.
// pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
/**
* Try to make some progress towards making pindexMostWork the active block.
* pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
*/
static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
AssertLockHeld(cs_main);
bool fInvalidFound = false;
@@ -2085,9 +2098,11 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
return true;
}

// Make the best chain active, in multiple steps. The result is either failure
// or an activated best chain. pblock is either NULL or a pointer to a block
// that is already loaded (to avoid loading it again from disk).
/**
* Make the best chain active, in multiple steps. The result is either failure
* or an activated best chain. pblock is either NULL or a pointer to a block
* that is already loaded (to avoid loading it again from disk).
*/
bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
CBlockIndex *pindexNewTip = NULL;
CBlockIndex *pindexMostWork = NULL;
@@ -2236,7 +2251,7 @@ CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
return pindexNew;
}

// Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS).
/** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
{
pindexNew->nTx = block.vtx.size();
@@ -2745,7 +2760,7 @@ uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::ve
} else {
// calculate left hash
uint256 left = CalcHash(height-1, pos*2, vTxid), right;
// calculate right hash if not beyong the end of the array - copy left hash otherwise1
// calculate right hash if not beyond the end of the array - copy left hash otherwise1
if (pos*2+1 < CalcTreeWidth(height-1))
right = CalcHash(height-1, pos*2+1, vTxid);
else

+ 99
- 85
src/main.h View File

@@ -1,6 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_MAIN_H
@@ -60,7 +60,7 @@ static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 50000;
static const unsigned int MAX_STANDARD_TX_SIZE = 100000;
/** The maximum allowed number of signature check operations in a block (network rule) */
static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
/** Maxiumum number of signature check operations in an IsStandard() P2SH script */
/** Maximum number of signature check operations in an IsStandard() P2SH script */
static const unsigned int MAX_P2SH_SIGOPS = 15;
/** The maximum number of sigops we're willing to relay/mine in a single tx */
static const unsigned int MAX_TX_SIGOPS = MAX_BLOCK_SIGOPS/5;
@@ -97,7 +97,7 @@ static const unsigned int BLOCK_DOWNLOAD_WINDOW = 1024;
/** Time to wait (in seconds) between writing blockchain state to disk. */
static const unsigned int DATABASE_WRITE_INTERVAL = 3600;

/** "reject" message codes **/
/** "reject" message codes */
static const unsigned char REJECT_MALFORMED = 0x01;
static const unsigned char REJECT_INVALID = 0x10;
static const unsigned char REJECT_OBSOLETE = 0x11;
@@ -131,10 +131,10 @@ extern bool fIsBareMultisigStd;
extern unsigned int nCoinCacheSize;
extern CFeeRate minRelayTxFee;

// Best header we've seen so far (used for getheaders queries' starting points).
/** Best header we've seen so far (used for getheaders queries' starting points). */
extern CBlockIndex *pindexBestHeader;

// Minimum disk space required - used in CheckDiskSpace()
/** Minimum disk space required - used in CheckDiskSpace() */
static const uint64_t nMinDiskSpace = 52428800;

/** Register a wallet to receive updates from core */
@@ -151,15 +151,17 @@ void RegisterNodeSignals(CNodeSignals& nodeSignals);
/** Unregister a network node */
void UnregisterNodeSignals(CNodeSignals& nodeSignals);

/** Process an incoming block. This only returns after the best known valid
block is made active. Note that it does not, however, guarantee that the
specific block passed to it has been checked for validity!
@param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state iff pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface - this will have its BlockChecked method called whenever *any* block completes validation.
@param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid.
@param[in] pblock The block we want to process.
@param[out] dbp If pblock is stored to disk (or already there), this will be set to its location.
@return True if state.IsValid()
*/
/**
* Process an incoming block. This only returns after the best known valid
* block is made active. Note that it does not, however, guarantee that the
* specific block passed to it has been checked for validity!
*
* @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface - this will have its BlockChecked method called whenever *any* block completes validation.
* @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid.
* @param[in] pblock The block we want to process.
* @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location.
* @return True if state.IsValid()
*/
bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp = NULL);
/** Check whether enough disk space is available for an incoming block */
bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
@@ -245,54 +247,59 @@ struct CDiskTxPos : public CDiskBlockPos

CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree);

//
// Check transaction inputs, and make sure any
// pay-to-script-hash transactions are evaluating IsStandard scripts
//
// Why bother? To avoid denial-of-service attacks; an attacker
// can submit a standard HASH... OP_EQUAL transaction,
// which will get accepted into blocks. The redemption
// script can be anything; an attacker could use a very
// expensive-to-check-upon-redemption script like:
// DUP CHECKSIG DROP ... repeated 100 times... OP_1
//
/**
* Check transaction inputs, and make sure any
* pay-to-script-hash transactions are evaluating IsStandard scripts
*
* Why bother? To avoid denial-of-service attacks; an attacker
* can submit a standard HASH... OP_EQUAL transaction,
* which will get accepted into blocks. The redemption
* script can be anything; an attacker could use a very
* expensive-to-check-upon-redemption script like:
* DUP CHECKSIG DROP ... repeated 100 times... OP_1
*/

/** 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
*/
/**
* 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
*/
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs);

/** 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
*/
/**
* 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
*/
unsigned int GetLegacySigOpCount(const CTransaction& tx);

/** 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
/**
* 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
*/
unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& mapInputs);


// 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.
/**
* 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(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks,
unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks = NULL);

// Apply the effects of this transaction on the UTXO set represented by view
/** Apply the effects of this transaction on the UTXO set represented by view */
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight);

// Context-independent validity checks
/** Context-independent validity checks */
bool CheckTransaction(const CTransaction& tx, CValidationState& state);

/** Check for standard transaction types
@return True if all outputs (scriptPubKeys) use only standard transaction forms
*/
* @return True if all outputs (scriptPubKeys) use only standard transaction forms
*/
bool IsStandardTx(const CTransaction& tx, std::string& reason);

bool IsFinalTx(const CTransaction &tx, int nBlockHeight = 0, int64_t nBlockTime = 0);
@@ -315,8 +322,10 @@ public:
};


/** Closure representing one script verification
* Note that this stores references to the spending transaction */
/**
* Closure representing one script verification
* Note that this stores references to the spending transaction
*/
class CScriptCheck
{
private:
@@ -345,7 +354,7 @@ public:

/** Data structure that represents a partial merkle tree.
*
* It respresents a subset of the txid's of a known block, in a way that
* It represents a subset of the txid's of a known block, in a way that
* allows recovery of the list of txid's and the merkle root, in an
* authenticated way.
*
@@ -380,36 +389,38 @@ public:
class CPartialMerkleTree
{
protected:
// the total number of transactions in the block
/** the total number of transactions in the block */
unsigned int nTransactions;

// node-is-parent-of-matched-txid bits
/** node-is-parent-of-matched-txid bits */
std::vector<bool> vBits;

// txids and internal hashes
/** txids and internal hashes */
std::vector<uint256> vHash;

// flag set when encountering invalid data
/** flag set when encountering invalid data */
bool fBad;

// helper function to efficiently calculate the number of nodes at given height in the merkle tree
/** helper function to efficiently calculate the number of nodes at given height in the merkle tree */
unsigned int CalcTreeWidth(int height) {
return (nTransactions+(1 << height)-1) >> height;
}

// calculate the hash of a node in the merkle tree (at leaf level: the txid's themself)
/** calculate the hash of a node in the merkle tree (at leaf level: the txid's themselves) */
uint256 CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid);

// recursive function that traverses tree nodes, storing the data as bits and hashes
/** recursive function that traverses tree nodes, storing the data as bits and hashes */
void TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch);

// recursive function that traverses tree nodes, consuming the bits and hashes produced by TraverseAndBuild.
// it returns the hash of the respective node.
/**
* recursive function that traverses tree nodes, consuming the bits and hashes produced by TraverseAndBuild.
* it returns the hash of the respective node.
*/
uint256 TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch);

public:

// serialization implementation
/** serialization implementation */
ADD_SERIALIZE_METHODS;

template <typename Stream, typename Operation>
@@ -432,13 +443,15 @@ public:
}
}

// Construct a partial merkle tree from a list of transaction id's, and a mask that selects a subset of them
/** Construct a partial merkle tree from a list of transaction id's, and a mask that selects a subset of them */
CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch);

CPartialMerkleTree();

// extract the matching txid's represented by this partial merkle tree.
// returns the merkle root, or 0 in case of failure
/**
* extract the matching txid's represented by this partial merkle tree.
* returns the merkle root, or 0 in case of failure
*/
uint256 ExtractMatches(std::vector<uint256> &vMatch);
};

@@ -458,22 +471,21 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex);
* of problems. Note that in any case, coins may be modified. */
bool DisconnectBlock(CBlock& block, 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
/** Apply the effects of this block (with given index) on the UTXO set represented by coins */
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false);

// Context-independent validity checks
/** Context-independent validity checks */
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true);
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true);

// Context-dependent validity checks
/** Context-dependent validity checks */
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev);
bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev);

// Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held)
/** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */
bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex *pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true);

// Store block on disk
// if dbp is provided, the file is known to already reside on disk
/** Store block on disk. If dbp is provided, the file is known to already reside on disk */
bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex **pindex, CDiskBlockPos* dbp = NULL);
bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL);

@@ -482,13 +494,13 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
class CBlockFileInfo
{
public:
unsigned int nBlocks; // number of blocks stored in file
unsigned int nSize; // number of used bytes of block file
unsigned int nUndoSize; // number of used bytes in the undo file
unsigned int nHeightFirst; // lowest height of block in file
unsigned int nHeightLast; // highest height of block in file
uint64_t nTimeFirst; // earliest time of block in file
uint64_t nTimeLast; // latest time of block in file
unsigned int nBlocks; //! number of blocks stored in file
unsigned int nSize; //! number of used bytes of block file
unsigned int nUndoSize; //! number of used bytes in the undo file
unsigned int nHeightFirst; //! lowest height of block in file
unsigned int nHeightLast; //! highest height of block in file
uint64_t nTimeFirst; //! earliest time of block in file
uint64_t nTimeLast; //! latest time of block in file

ADD_SERIALIZE_METHODS;

@@ -519,7 +531,7 @@ public:

std::string ToString() const;

// update statistics (does not update nSize)
/** update statistics (does not update nSize) */
void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn) {
if (nBlocks==0 || nHeightFirst > nHeightIn)
nHeightFirst = nHeightIn;
@@ -537,9 +549,9 @@ public:
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_VALID, //! everything ok
MODE_INVALID, //! network rule violation (DoS value may be set)
MODE_ERROR, //! run-time error
} mode;
int nDoS;
std::string strRejectReason;
@@ -634,24 +646,26 @@ struct CBlockTemplate



/** Used to relay blocks as header + vector<merkle branch>
/**
* Used to relay blocks as header + vector<merkle branch>
* to filtered nodes.
*/
class CMerkleBlock
{
public:
// Public only for unit testing
/** Public only for unit testing */
CBlockHeader header;
CPartialMerkleTree txn;

public:
// Public only for unit testing and relay testing
// (not relayed)
/** Public only for unit testing and relay testing (not relayed) */
std::vector<std::pair<unsigned int, uint256> > vMatchedTxn;

// Create from a CBlock, filtering transactions according to filter
// Note that this will call IsRelevantAndUpdate on the filter for each transaction,
// thus the filter will likely be modified.
/**
* Create from a CBlock, filtering transactions according to filter
* Note that this will call IsRelevantAndUpdate on the filter for each transaction,
* thus the filter will likely be modified.
*/
CMerkleBlock(const CBlock& block, CBloomFilter& filter);

ADD_SERIALIZE_METHODS;

Loading…
Cancel
Save