Changeset View
Changeset View
Standalone View
Standalone View
src/chain.h
Show First 20 Lines • Show All 182 Lines • ▼ Show 20 Lines | enum BlockStatusEnum : uint32_t { | ||||
/** | /** | ||||
* All validity bits. | * All validity bits. | ||||
*/ | */ | ||||
BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | | BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | | ||||
BLOCK_VALID_TRANSACTIONS | BLOCK_VALID_CHAIN | | BLOCK_VALID_TRANSACTIONS | BLOCK_VALID_CHAIN | | ||||
BLOCK_VALID_SCRIPTS, | BLOCK_VALID_SCRIPTS, | ||||
// Just a helper | |||||
BLOCK_HAVE_NOTHING = 0, | |||||
// Full block available in blk*.dat | // Full block available in blk*.dat | ||||
BLOCK_HAVE_DATA = 8, | BLOCK_HAVE_DATA = 8, | ||||
// Undo data available in rev*.dat | // Undo data available in rev*.dat | ||||
BLOCK_HAVE_UNDO = 16, | BLOCK_HAVE_UNDO = 16, | ||||
BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO, | BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO, | ||||
// The block is invalid. | // The block is invalid. | ||||
BLOCK_FAILED_VALID = 32, | BLOCK_FAILED_VALID = 32, | ||||
// The block has an invalid parent. | // The block has an invalid parent. | ||||
BLOCK_FAILED_CHILD = 64, | BLOCK_FAILED_CHILD = 64, | ||||
BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD, | BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD, | ||||
}; | }; | ||||
struct BlockStatus { | |||||
private: | |||||
uint32_t status; | |||||
explicit BlockStatus(uint32_t nStatusIn) : status(nStatusIn) {} | |||||
public: | |||||
explicit BlockStatus() : status(BLOCK_VALID_UNKNOWN) {} | |||||
BlockValidity getValidity() const { | |||||
return BlockValidity(status & BLOCK_VALID_MASK); | |||||
} | |||||
BlockStatus withValidity(BlockValidity validity) const { | |||||
return BlockStatus((status & ~BLOCK_VALID_MASK) | uint32_t(validity)); | |||||
} | |||||
bool hasData() const { return status & BLOCK_HAVE_DATA; } | |||||
BlockStatus withData(bool hasData = true) const { | |||||
return BlockStatus((status & ~BLOCK_HAVE_DATA) | | |||||
(hasData ? BLOCK_HAVE_DATA : BLOCK_HAVE_NOTHING)); | |||||
} | |||||
bool hasUndo() const { return status & BLOCK_HAVE_UNDO; } | |||||
BlockStatus withUndo(bool hasUndo = true) const { | |||||
return BlockStatus((status & ~BLOCK_HAVE_UNDO) | | |||||
(hasUndo ? BLOCK_HAVE_UNDO : BLOCK_HAVE_NOTHING)); | |||||
} | |||||
/** | |||||
* Check whether this block index entry is valid up to the passed validity | |||||
* level. | |||||
*/ | |||||
bool isValid(enum BlockValidity nUpTo = BlockValidity::TRANSACTIONS) const { | |||||
if (status & BLOCK_FAILED_MASK) { | |||||
return false; | |||||
} | |||||
return getValidity() >= nUpTo; | |||||
} | |||||
// To transition from this and the plain old intereger. | |||||
// TODO: delete. | |||||
uint32_t operator&(uint32_t rhs) const { return status & rhs; } | |||||
uint32_t operator|(uint32_t rhs) const { return status | rhs; } | |||||
BlockStatus &operator&=(uint32_t rhs) { | |||||
this->status &= rhs; | |||||
return *this; | |||||
} | |||||
BlockStatus &operator|=(uint32_t rhs) { | |||||
this->status |= rhs; | |||||
return *this; | |||||
} | |||||
operator bool() const { return status != 0; } | |||||
operator uint32_t() const { return status; } | |||||
ADD_SERIALIZE_METHODS; | |||||
template <typename Stream, typename Operation> | |||||
inline void SerializationOp(Stream &s, Operation ser_action) { | |||||
READWRITE(VARINT(status)); | |||||
} | |||||
}; | |||||
/** | /** | ||||
* The block chain is a tree shaped structure starting with the genesis block at | * The block chain is a tree shaped structure starting with the genesis block at | ||||
* the root, with each block potentially having multiple candidates to be the | * the root, with each block potentially having multiple candidates to be the | ||||
* next block. A blockindex may have multiple pprev pointing to it, but at most | * next block. A blockindex may have multiple pprev pointing to it, but at most | ||||
* one of them can be part of the currently active branch. | * one of them can be part of the currently active branch. | ||||
*/ | */ | ||||
class CBlockIndex { | class CBlockIndex { | ||||
public: | public: | ||||
Show All 31 Lines | public: | ||||
//! (memory only) Number of transactions in the chain up to and including | //! (memory only) Number of transactions in the chain up to and including | ||||
//! this block. | //! this block. | ||||
//! This value will be non-zero only if and only if transactions for this | //! This value will be non-zero only if and only if transactions for this | ||||
//! block and all its parents are available. Change to 64-bit type when | //! block and all its parents are available. Change to 64-bit type when | ||||
//! necessary; won't happen before 2030 | //! necessary; won't happen before 2030 | ||||
unsigned int nChainTx; | unsigned int nChainTx; | ||||
//! Verification status of this block. See enum BlockStatus | //! Verification status of this block. See enum BlockStatus | ||||
uint32_t nStatus; | BlockStatus nStatus; | ||||
//! block header | //! block header | ||||
int32_t nVersion; | int32_t nVersion; | ||||
uint256 hashMerkleRoot; | uint256 hashMerkleRoot; | ||||
uint32_t nTime; | uint32_t nTime; | ||||
uint32_t nBits; | uint32_t nBits; | ||||
uint32_t nNonce; | uint32_t nNonce; | ||||
Show All 13 Lines | void SetNull() { | ||||
pskip = nullptr; | pskip = nullptr; | ||||
nHeight = 0; | nHeight = 0; | ||||
nFile = 0; | nFile = 0; | ||||
nDataPos = 0; | nDataPos = 0; | ||||
nUndoPos = 0; | nUndoPos = 0; | ||||
nChainWork = arith_uint256(); | nChainWork = arith_uint256(); | ||||
nTx = 0; | nTx = 0; | ||||
nChainTx = 0; | nChainTx = 0; | ||||
nStatus = 0; | nStatus = BlockStatus(); | ||||
nSequenceId = 0; | nSequenceId = 0; | ||||
nTimeMax = 0; | nTimeMax = 0; | ||||
nVersion = 0; | nVersion = 0; | ||||
hashMerkleRoot = uint256(); | hashMerkleRoot = uint256(); | ||||
nTime = 0; | nTime = 0; | ||||
nTimeReceived = 0; | nTimeReceived = 0; | ||||
nBits = 0; | nBits = 0; | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | std::string ToString() const { | ||||
return strprintf( | return strprintf( | ||||
"CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)", pprev, | "CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)", pprev, | ||||
nHeight, hashMerkleRoot.ToString(), GetBlockHash().ToString()); | nHeight, hashMerkleRoot.ToString(), GetBlockHash().ToString()); | ||||
} | } | ||||
//! Check whether this block index entry is valid up to the passed validity | //! Check whether this block index entry is valid up to the passed validity | ||||
//! level. | //! level. | ||||
bool IsValid(enum BlockValidity nUpTo = BlockValidity::TRANSACTIONS) const { | bool IsValid(enum BlockValidity nUpTo = BlockValidity::TRANSACTIONS) const { | ||||
// Only validity flags allowed. | return nStatus.isValid(nUpTo); | ||||
if (nStatus & BLOCK_FAILED_MASK) { | |||||
return false; | |||||
} | |||||
return BlockValidity(nStatus & BLOCK_VALID_MASK) >= nUpTo; | |||||
} | } | ||||
//! Raise the validity level of this block index entry. | //! Raise the validity level of this block index entry. | ||||
//! Returns true if the validity was changed. | //! Returns true if the validity was changed. | ||||
bool RaiseValidity(enum BlockValidity nUpTo) { | bool RaiseValidity(enum BlockValidity nUpTo) { | ||||
// Only validity flags allowed. | // Only validity flags allowed. | ||||
if (nStatus & BLOCK_FAILED_MASK) { | if (nStatus & BLOCK_FAILED_MASK) { | ||||
return false; | return false; | ||||
} | } | ||||
if (BlockValidity(nStatus & BLOCK_VALID_MASK) >= nUpTo) { | if (BlockValidity(nStatus & BLOCK_VALID_MASK) >= nUpTo) { | ||||
return false; | return false; | ||||
} | } | ||||
nStatus = (nStatus & ~BLOCK_VALID_MASK) | uint32_t(nUpTo); | nStatus = nStatus.withValidity(nUpTo); | ||||
return true; | return true; | ||||
} | } | ||||
//! Build the skiplist pointer for this entry. | //! Build the skiplist pointer for this entry. | ||||
void BuildSkip(); | void BuildSkip(); | ||||
//! Efficiently find an ancestor of this block. | //! Efficiently find an ancestor of this block. | ||||
CBlockIndex *GetAncestor(int height); | CBlockIndex *GetAncestor(int height); | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | public: | ||||
template <typename Stream, typename Operation> | template <typename Stream, typename Operation> | ||||
inline void SerializationOp(Stream &s, Operation ser_action) { | inline void SerializationOp(Stream &s, Operation ser_action) { | ||||
int nVersion = s.GetVersion(); | int nVersion = s.GetVersion(); | ||||
if (!(s.GetType() & SER_GETHASH)) { | if (!(s.GetType() & SER_GETHASH)) { | ||||
READWRITE(VARINT(nVersion)); | READWRITE(VARINT(nVersion)); | ||||
} | } | ||||
READWRITE(VARINT(nHeight)); | READWRITE(VARINT(nHeight)); | ||||
READWRITE(VARINT(nStatus)); | READWRITE(nStatus); | ||||
READWRITE(VARINT(nTx)); | READWRITE(VARINT(nTx)); | ||||
if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO)) { | if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO)) { | ||||
READWRITE(VARINT(nFile)); | READWRITE(VARINT(nFile)); | ||||
} | } | ||||
if (nStatus & BLOCK_HAVE_DATA) { | if (nStatus & BLOCK_HAVE_DATA) { | ||||
READWRITE(VARINT(nDataPos)); | READWRITE(VARINT(nDataPos)); | ||||
} | } | ||||
if (nStatus & BLOCK_HAVE_UNDO) { | if (nStatus & BLOCK_HAVE_UNDO) { | ||||
▲ Show 20 Lines • Show All 116 Lines • Show Last 20 Lines |