diff --git a/src/Makefile.am b/src/Makefile.am --- a/src/Makefile.am +++ b/src/Makefile.am @@ -93,6 +93,7 @@ blockencodings.h \ blockfileinfo.h \ blockindexworkcomparator.h \ + blockstatus.h \ blockvalidity.h \ cashaddr.h \ cashaddrenc.h \ diff --git a/src/blockstatus.h b/src/blockstatus.h new file mode 100644 --- /dev/null +++ b/src/blockstatus.h @@ -0,0 +1,117 @@ +// Copyright (c) 2018 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_BLOCKSTATUS_H +#define BITCOIN_BLOCKSTATUS_H + +#include "blockvalidity.h" +#include "serialize.h" + +#include + +struct BlockStatus { +private: + uint32_t status; + + explicit BlockStatus(uint32_t nStatusIn) : status(nStatusIn) {} + + static const uint32_t VALIDITY_MASK = 0x07; + + // Full block available in blk*.dat + static const uint32_t HAS_DATA_FLAG = 0x08; + // Undo data available in rev*.dat + static const uint32_t HAS_UNDO_FLAG = 0x10; + + // The block is invalid. + static const uint32_t FAILED_FLAG = 0x20; + // The block has an invalid parent. + static const uint32_t FAILED_PARENT_FLAG = 0x40; + + // Mask used to check if the block failed. + static const uint32_t INVALID_MASK = FAILED_FLAG | FAILED_PARENT_FLAG; + + // The block is being parked for some reason. It will be reconsidered if its + // chains grows. + static const uint32_t PARKED_FLAG = 0x80; + // One of the block's parent is parked. + static const uint32_t PARKED_PARENT_FLAG = 0x100; + + // Mask used to check for parked blocks. + static const uint32_t PARKED_MASK = PARKED_FLAG | PARKED_PARENT_FLAG; + +public: + explicit BlockStatus() : status(0) {} + + BlockValidity getValidity() const { + return BlockValidity(status & VALIDITY_MASK); + } + + BlockStatus withValidity(BlockValidity validity) const { + return BlockStatus((status & ~VALIDITY_MASK) | uint32_t(validity)); + } + + bool hasData() const { return status & HAS_DATA_FLAG; } + BlockStatus withData(bool hasData = true) const { + return BlockStatus((status & ~HAS_DATA_FLAG) | + (hasData ? HAS_DATA_FLAG : 0)); + } + + bool hasUndo() const { return status & HAS_UNDO_FLAG; } + BlockStatus withUndo(bool hasUndo = true) const { + return BlockStatus((status & ~HAS_UNDO_FLAG) | + (hasUndo ? HAS_UNDO_FLAG : 0)); + } + + bool hasFailed() const { return status & FAILED_FLAG; } + BlockStatus withFailed(bool hasFailed = true) const { + return BlockStatus((status & ~FAILED_FLAG) | + (hasFailed ? FAILED_FLAG : 0)); + } + + bool hasFailedParent() const { return status & FAILED_PARENT_FLAG; } + BlockStatus withFailedParent(bool hasFailedParent = true) const { + return BlockStatus((status & ~FAILED_PARENT_FLAG) | + (hasFailedParent ? FAILED_PARENT_FLAG : 0)); + } + + bool isParked() const { return status & PARKED_FLAG; } + BlockStatus withParked(bool parked = true) const { + return BlockStatus((status & ~PARKED_FLAG) | + (parked ? PARKED_FLAG : 0)); + } + + bool hasParkedParent() const { return status & PARKED_PARENT_FLAG; } + BlockStatus withParkedParent(bool parkedParent = true) const { + return BlockStatus((status & ~PARKED_PARENT_FLAG) | + (parkedParent ? PARKED_PARENT_FLAG : 0)); + } + + /** + * Check whether this block index entry is valid up to the passed validity + * level. + */ + bool isValid(enum BlockValidity nUpTo = BlockValidity::TRANSACTIONS) const { + if (isInvalid()) { + return false; + } + + return getValidity() >= nUpTo; + } + + bool isInvalid() const { return status & INVALID_MASK; } + BlockStatus withClearedFailureFlags() const { + return BlockStatus(status & ~INVALID_MASK); + } + + bool isOnParkedChain() const { return status & PARKED_MASK; } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream &s, Operation ser_action) { + READWRITE(VARINT(status)); + } +}; + +#endif // BITCOIN_BLOCKSTATUS_H diff --git a/src/chain.h b/src/chain.h --- a/src/chain.h +++ b/src/chain.h @@ -7,6 +7,7 @@ #define BITCOIN_CHAIN_H #include "arith_uint256.h" +#include "blockstatus.h" #include "blockvalidity.h" #include "consensus/params.h" #include "diskblockpos.h" @@ -32,110 +33,6 @@ */ static const int64_t TIMESTAMP_WINDOW = MAX_FUTURE_BLOCK_TIME; -struct BlockStatus { -private: - uint32_t status; - - explicit BlockStatus(uint32_t nStatusIn) : status(nStatusIn) {} - - static const uint32_t VALIDITY_MASK = 0x07; - - // Full block available in blk*.dat - static const uint32_t HAS_DATA_FLAG = 0x08; - // Undo data available in rev*.dat - static const uint32_t HAS_UNDO_FLAG = 0x10; - - // The block is invalid. - static const uint32_t FAILED_FLAG = 0x20; - // The block has an invalid parent. - static const uint32_t FAILED_PARENT_FLAG = 0x40; - - // Mask used to check if the block failed. - static const uint32_t INVALID_MASK = FAILED_FLAG | FAILED_PARENT_FLAG; - - // The block is being parked for some reason. It will be reconsidered if its - // chains grows. - static const uint32_t PARKED_FLAG = 0x80; - // One of the block's parent is parked. - static const uint32_t PARKED_PARENT_FLAG = 0x100; - - // Mask used to check for parked blocks. - static const uint32_t PARKED_MASK = PARKED_FLAG | PARKED_PARENT_FLAG; - -public: - explicit BlockStatus() : status(0) {} - - BlockValidity getValidity() const { - return BlockValidity(status & VALIDITY_MASK); - } - - BlockStatus withValidity(BlockValidity validity) const { - return BlockStatus((status & ~VALIDITY_MASK) | uint32_t(validity)); - } - - bool hasData() const { return status & HAS_DATA_FLAG; } - BlockStatus withData(bool hasData = true) const { - return BlockStatus((status & ~HAS_DATA_FLAG) | - (hasData ? HAS_DATA_FLAG : 0)); - } - - bool hasUndo() const { return status & HAS_UNDO_FLAG; } - BlockStatus withUndo(bool hasUndo = true) const { - return BlockStatus((status & ~HAS_UNDO_FLAG) | - (hasUndo ? HAS_UNDO_FLAG : 0)); - } - - bool hasFailed() const { return status & FAILED_FLAG; } - BlockStatus withFailed(bool hasFailed = true) const { - return BlockStatus((status & ~FAILED_FLAG) | - (hasFailed ? FAILED_FLAG : 0)); - } - - bool hasFailedParent() const { return status & FAILED_PARENT_FLAG; } - BlockStatus withFailedParent(bool hasFailedParent = true) const { - return BlockStatus((status & ~FAILED_PARENT_FLAG) | - (hasFailedParent ? FAILED_PARENT_FLAG : 0)); - } - - bool isParked() const { return status & PARKED_FLAG; } - BlockStatus withParked(bool parked = true) const { - return BlockStatus((status & ~PARKED_FLAG) | - (parked ? PARKED_FLAG : 0)); - } - - bool hasParkedParent() const { return status & PARKED_PARENT_FLAG; } - BlockStatus withParkedParent(bool parkedParent = true) const { - return BlockStatus((status & ~PARKED_PARENT_FLAG) | - (parkedParent ? PARKED_PARENT_FLAG : 0)); - } - - /** - * Check whether this block index entry is valid up to the passed validity - * level. - */ - bool isValid(enum BlockValidity nUpTo = BlockValidity::TRANSACTIONS) const { - if (isInvalid()) { - return false; - } - - return getValidity() >= nUpTo; - } - - bool isInvalid() const { return status & INVALID_MASK; } - BlockStatus withClearedFailureFlags() const { - return BlockStatus(status & ~INVALID_MASK); - } - - bool isOnParkedChain() const { return status & PARKED_MASK; } - - ADD_SERIALIZE_METHODS; - - template - 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 root, with each block potentially having multiple candidates to be the diff --git a/src/test/blockstatus_tests.cpp b/src/test/blockstatus_tests.cpp --- a/src/test/blockstatus_tests.cpp +++ b/src/test/blockstatus_tests.cpp @@ -2,8 +2,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "blockstatus.h" #include "blockvalidity.h" -#include "chain.h" #include "test/test_bitcoin.h" #include