1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2013 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.
6 #ifndef BITCOIN_PRIMITIVES_BLOCK_H
7 #define BITCOIN_PRIMITIVES_BLOCK_H
9 #include "primitives/transaction.h"
10 #include "serialize.h"
12 #include "arith_uint256.h"
14 /** Nodes collect new transactions into a block, hash them into a hash tree,
15 * and scan through nonce values to make the block's hash satisfy proof-of-work
16 * requirements. When they solve the proof-of-work, they broadcast the block
17 * to everyone and the block is added to the block chain. The first transaction
18 * in the block is a special one that creates a new coin owned by the creator
25 static const size_t HEADER_SIZE=4+32+32+32+4+4+32; // excluding Equihash solution
26 static const int32_t CURRENT_VERSION=4;
27 static uint256 (CBlockHeader::*hashFunction)() const;
28 static void SetHashAlgo();
31 uint256 hashPrevBlock;
32 uint256 hashMerkleRoot;
37 std::vector<unsigned char> nSolution;
44 ADD_SERIALIZE_METHODS;
46 template <typename Stream, typename Operation>
47 inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
48 READWRITE(this->nVersion);
49 nVersion = this->nVersion;
50 READWRITE(hashPrevBlock);
51 READWRITE(hashMerkleRoot);
52 READWRITE(hashReserved);
61 nVersion = CBlockHeader::CURRENT_VERSION;
62 hashPrevBlock.SetNull();
63 hashMerkleRoot.SetNull();
64 hashReserved.SetNull();
76 uint256 GetHash() const
78 return (this->*hashFunction)();
81 uint256 GetSHA256DHash() const;
82 static void SetSHA256DHash();
84 uint256 GetVerusHash() const;
85 static void SetVerusHash();
87 uint256 GetVerusHashPortable() const;
88 static void SetVerusHashPortable();
90 uint256 GetVerusMiningHash() const;
92 int64_t GetBlockTime() const
94 return (int64_t)nTime;
97 int32_t GetVerusPOSTarget() const
101 for (const unsigned char *p = nNonce.begin() + 3; p >= nNonce.begin(); p--)
109 bool IsVerusPOSBlock() const
111 arith_uint256 arNonce = UintToArith256(nNonce);
112 arith_uint256 tmpNonce = ((arNonce << 128) >> 128);
113 CVerusHashPortableWriter hashWriter = CVerusHashPortableWriter(SER_GETHASH, PROTOCOL_VERSION);
114 hashWriter << ArithToUint256(tmpNonce);
115 return (nNonce == ArithToUint256(UintToArith256(hashWriter.GetHash()) << 128 | tmpNonce));
118 void SetVerusPOSTarget(int32_t nBits)
120 CVerusHashPortableWriter hashWriter = CVerusHashPortableWriter(SER_GETHASH, PROTOCOL_VERSION);
122 arith_uint256 tmpNonce;
124 arith_uint256 arNonce = UintToArith256(nNonce);
125 arNonce = ((arNonce >> 32) << 32) | nBits;
127 tmpNonce = ((arNonce << 128) >> 128);
128 hashWriter << ArithToUint256(tmpNonce);
130 nNonce = ArithToUint256(UintToArith256(hashWriter.GetHash()) << 128 | tmpNonce);
134 // this class is used to address the type mismatch that existed between nodes, where block headers
135 // were being serialized by senders as CBlock and deserialized as CBlockHeader + an assumed extra
136 // compact value. although it was working, I made this because it did break, and makes the connection
137 // between CBlock and CBlockHeader more brittle.
138 // by using this intentionally specified class instead, we remove an instability in the code that could break
139 // due to unrelated changes, but stay compatible with the old method.
140 class CNetworkBlockHeader : public CBlockHeader
143 std::vector<CTransaction> compatVec;
145 CNetworkBlockHeader() : CBlockHeader()
150 CNetworkBlockHeader(const CBlockHeader &header)
153 *((CBlockHeader*)this) = header;
156 ADD_SERIALIZE_METHODS;
158 template <typename Stream, typename Operation>
159 inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
160 READWRITE(*(CBlockHeader*)this);
161 READWRITE(compatVec);
166 CBlockHeader::SetNull();
171 class CBlock : public CBlockHeader
175 std::vector<CTransaction> vtx;
178 mutable std::vector<uint256> vMerkleTree;
185 CBlock(const CBlockHeader &header)
188 *((CBlockHeader*)this) = header;
191 ADD_SERIALIZE_METHODS;
193 template <typename Stream, typename Operation>
194 inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
195 READWRITE(*(CBlockHeader*)this);
201 CBlockHeader::SetNull();
206 CBlockHeader GetBlockHeader() const
209 block.nVersion = nVersion;
210 block.hashPrevBlock = hashPrevBlock;
211 block.hashMerkleRoot = hashMerkleRoot;
212 block.hashReserved = hashReserved;
215 block.nNonce = nNonce;
216 block.nSolution = nSolution;
220 // Build the in-memory merkle tree for this block and return the merkle root.
221 // If non-NULL, *mutated is set to whether mutation was detected in the merkle
222 // tree (a duplication of transactions in the block leading to an identical
224 uint256 BuildMerkleTree(bool* mutated = NULL) const;
226 std::vector<uint256> GetMerkleBranch(int nIndex) const;
227 static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex);
228 std::string ToString() const;
233 * Custom serializer for CBlockHeader that omits the nonce and solution, for use
234 * as input to Equihash.
236 class CEquihashInput : private CBlockHeader
239 CEquihashInput(const CBlockHeader &header)
241 CBlockHeader::SetNull();
242 *((CBlockHeader*)this) = header;
245 ADD_SERIALIZE_METHODS;
247 template <typename Stream, typename Operation>
248 inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
249 READWRITE(this->nVersion);
250 nVersion = this->nVersion;
251 READWRITE(hashPrevBlock);
252 READWRITE(hashMerkleRoot);
253 READWRITE(hashReserved);
260 /** Describes a place in the block chain to another node such that if the
261 * other node doesn't have the same branch, it can find a recent common trunk.
262 * The further back it is, the further before the fork it may be.
266 std::vector<uint256> vHave;
270 CBlockLocator(const std::vector<uint256>& vHaveIn)
275 ADD_SERIALIZE_METHODS;
277 template <typename Stream, typename Operation>
278 inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
279 if (!(nType & SER_GETHASH))
291 return vHave.empty();
294 friend bool operator==(const CBlockLocator& a, const CBlockLocator& b) {
295 return (a.vHave == b.vHave);
299 #endif // BITCOIN_PRIMITIVES_BLOCK_H