Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto 2 : // Copyright (c) 2009-2020 The Bitcoin Core developers 3 : // Distributed under the MIT software license, see the accompanying 4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 : 6 : #ifndef BITCOIN_PRIMITIVES_BLOCK_H 7 : #define BITCOIN_PRIMITIVES_BLOCK_H 8 : 9 : #include <list> 10 : #include <primitives/transaction.h> 11 : #include <serialize.h> 12 : #include <uint256.h> 13 : #include <cstddef> 14 : #include <type_traits> 15 : 16 : /** Nodes collect new transactions into a block, hash them into a hash tree, 17 : * and scan through nonce values to make the block's hash satisfy proof-of-work 18 : * requirements. When they solve the proof-of-work, they broadcast the block 19 : * to everyone and the block is added to the block chain. The first transaction 20 : * in the block is a special one that creates a new coin owned by the creator 21 : * of the block. 22 : */ 23 : class CBlockHeader 24 : { 25 : public: 26 : // header 27 : int32_t nVersion; 28 : uint256 hashPrevBlock; 29 : uint256 hashMerkleRoot; 30 : uint32_t nTime; 31 : uint32_t nBits; 32 : uint32_t nNonce; 33 : 34 3029885 : CBlockHeader() 35 640145 : { 36 2389740 : SetNull(); 37 3029885 : } 38 : 39 28806638 : SERIALIZE_METHODS(CBlockHeader, obj) { READWRITE(obj.nVersion, obj.hashPrevBlock, obj.hashMerkleRoot, obj.nTime, obj.nBits, obj.nNonce); } 40 : 41 4591451 : void SetNull() 42 : { 43 4591451 : nVersion = 0; 44 4591451 : hashPrevBlock.SetNull(); 45 4591451 : hashMerkleRoot.SetNull(); 46 4591451 : nTime = 0; 47 4591451 : nBits = 0; 48 4591451 : nNonce = 0; 49 4591451 : } 50 : 51 631647 : bool IsNull() const 52 : { 53 631647 : return (nBits == 0); 54 : } 55 : 56 : uint256 GetHash() const; 57 : 58 1501609 : int64_t GetBlockTime() const 59 : { 60 1501609 : return (int64_t)nTime; 61 : } 62 : }; 63 : 64 357972 : class CompressedHeaderBitField 65 : { 66 357972 : std::byte bit_field{0}; 67 : 68 : public: 69 : enum class Flag : std::underlying_type_t<std::byte> { 70 : VERSION_BIT_0 = (1 << 0), 71 : VERSION_BIT_1 = (1 << 1), 72 : VERSION_BIT_2 = (1 << 2), 73 : PREV_BLOCK_HASH = (1 << 3), 74 : TIMESTAMP = (1 << 4), 75 : NBITS = (1 << 5), 76 : }; 77 : 78 1352436 : inline bool IsCompressed(Flag flag) const 79 : { 80 1352436 : return (bit_field & to_byte(flag)) == to_byte(0); 81 : } 82 : 83 536175 : inline void MarkAsUncompressed(Flag flag) 84 : { 85 536175 : bit_field |= to_byte(flag); 86 536175 : } 87 : 88 277389 : inline void MarkAsCompressed(Flag flag) 89 : { 90 277389 : bit_field &= ~to_byte(flag); 91 277389 : } 92 : 93 450812 : inline bool IsVersionCompressed() const 94 : { 95 450812 : return GetVersionOffset() != 0; 96 : } 97 : 98 270309 : inline void SetVersionOffset(uint8_t version) 99 : { 100 270309 : bit_field &= ~VERSION_BIT_MASK; 101 270309 : bit_field |= to_byte(version) & VERSION_BIT_MASK; 102 270309 : } 103 : 104 542779 : inline uint8_t GetVersionOffset() const 105 : { 106 542779 : return to_uint8(bit_field & VERSION_BIT_MASK); 107 : } 108 : 109 : template <typename Stream> 110 178725 : void Serialize(Stream& s) const 111 : { 112 178725 : ::Serialize(s, to_uint8(bit_field)); 113 178725 : } 114 : 115 : template <typename Stream> 116 179247 : void Unserialize(Stream& s) 117 : { 118 : uint8_t new_bit_field_value; 119 179247 : ::Unserialize(s, new_bit_field_value); 120 179247 : bit_field = to_byte(new_bit_field_value); 121 179247 : } 122 : 123 : private: 124 721504 : static constexpr uint8_t to_uint8(const std::byte value) 125 : { 126 721504 : return std::to_integer<uint8_t>(value); 127 : } 128 : 129 1801992 : static constexpr std::byte to_byte(const uint8_t value) 130 : { 131 1801992 : return std::byte{value}; 132 : } 133 : 134 2166000 : static constexpr std::byte to_byte(const Flag flag) 135 : { 136 2166000 : return static_cast<std::byte>(flag); 137 : } 138 : 139 : static constexpr std::byte VERSION_BIT_MASK = static_cast<std::byte>(Flag::VERSION_BIT_0) | static_cast<std::byte>(Flag::VERSION_BIT_1) | static_cast<std::byte>(Flag::VERSION_BIT_2); 140 : }; 141 : 142 : struct CompressibleBlockHeader : CBlockHeader { 143 : CompressedHeaderBitField bit_field; 144 357972 : int16_t time_offset{0}; 145 : 146 537741 : CompressibleBlockHeader() = default; 147 : 148 357450 : explicit CompressibleBlockHeader(CBlockHeader&& block_header) 149 178725 : { 150 : static_assert(std::is_trivially_copyable_v<CBlockHeader>, "If CBlockHeader is not trivially copyable, please consider using std::move on the next line"); 151 178725 : *static_cast<CBlockHeader*>(this) = block_header; 152 : 153 : // When we create this from a block header, mark everything as uncompressed 154 178725 : bit_field.SetVersionOffset(0); 155 178725 : bit_field.MarkAsUncompressed(CompressedHeaderBitField::Flag::PREV_BLOCK_HASH); 156 178725 : bit_field.MarkAsUncompressed(CompressedHeaderBitField::Flag::TIMESTAMP); 157 178725 : bit_field.MarkAsUncompressed(CompressedHeaderBitField::Flag::NBITS); 158 357450 : } 159 : 160 1073916 : SERIALIZE_METHODS(CompressibleBlockHeader, obj) 161 : { 162 357972 : READWRITE(obj.bit_field); 163 357972 : if (!obj.bit_field.IsVersionCompressed()) { 164 174421 : READWRITE(obj.nVersion); 165 174421 : } 166 357972 : if (!obj.bit_field.IsCompressed(CompressedHeaderBitField::Flag::PREV_BLOCK_HASH)) { 167 172669 : READWRITE(obj.hashPrevBlock); 168 172669 : } 169 357972 : READWRITE(obj.hashMerkleRoot); 170 357972 : if (!obj.bit_field.IsCompressed(CompressedHeaderBitField::Flag::TIMESTAMP)) { 171 172669 : READWRITE(obj.nTime); 172 172669 : } else { 173 185303 : READWRITE(obj.time_offset); 174 : } 175 357972 : if (!obj.bit_field.IsCompressed(CompressedHeaderBitField::Flag::NBITS)) { 176 172669 : READWRITE(obj.nBits); 177 172669 : } 178 357972 : READWRITE(obj.nNonce); 179 357972 : } 180 : 181 : void Compress(const std::vector<CompressibleBlockHeader>& previous_blocks, std::list<int32_t>& last_unique_versions); 182 : 183 : void Uncompress(const std::vector<CBlockHeader>& previous_blocks, std::list<int32_t>& last_unique_versions); 184 : }; 185 : 186 : class CBlock : public CBlockHeader 187 : { 188 : public: 189 : // network and disk 190 : std::vector<CTransactionRef> vtx; 191 : 192 : // memory only 193 : mutable bool fChecked; 194 : 195 2301628 : CBlock() 196 1150814 : { 197 1150814 : SetNull(); 198 2301628 : } 199 : 200 481620 : CBlock(const CBlockHeader &header) 201 240810 : { 202 240810 : SetNull(); 203 240810 : *(static_cast<CBlockHeader*>(this)) = header; 204 481620 : } 205 : 206 7919980 : SERIALIZE_METHODS(CBlock, obj) 207 : { 208 2639998 : READWRITEAS(CBlockHeader, obj); 209 2639998 : READWRITE(obj.vtx); 210 2639998 : } 211 : 212 2104031 : void SetNull() 213 : { 214 2104031 : CBlockHeader::SetNull(); 215 2104031 : vtx.clear(); 216 2104031 : fChecked = false; 217 2104031 : } 218 : 219 123775 : CBlockHeader GetBlockHeader() const 220 : { 221 123775 : CBlockHeader block; 222 123775 : block.nVersion = nVersion; 223 123775 : block.hashPrevBlock = hashPrevBlock; 224 123775 : block.hashMerkleRoot = hashMerkleRoot; 225 123775 : block.nTime = nTime; 226 123775 : block.nBits = nBits; 227 123775 : block.nNonce = nNonce; 228 123775 : return block; 229 : } 230 : 231 : std::string ToString() const; 232 : }; 233 : 234 : 235 : /** Describes a place in the block chain to another node such that if the 236 : * other node doesn't have the same branch, it can find a recent common trunk. 237 : * The further back it is, the further before the fork it may be. 238 : */ 239 : struct CBlockLocator 240 : { 241 : std::vector<uint256> vHave; 242 : 243 36810 : CBlockLocator() {} 244 : 245 82178 : explicit CBlockLocator(const std::vector<uint256>& vHaveIn) : vHave(vHaveIn) {} 246 : 247 168744 : SERIALIZE_METHODS(CBlockLocator, obj) 248 : { 249 56248 : int nVersion = s.GetVersion(); 250 56248 : if (!(s.GetType() & SER_GETHASH)) 251 56248 : READWRITE(nVersion); 252 56248 : READWRITE(obj.vHave); 253 56248 : } 254 : 255 3400 : void SetNull() 256 : { 257 3400 : vHave.clear(); 258 3400 : } 259 : 260 22902 : bool IsNull() const 261 : { 262 22902 : return vHave.empty(); 263 : } 264 : }; 265 : 266 : #endif // BITCOIN_PRIMITIVES_BLOCK_H