]> Git Repo - VerusCoin.git/blob - src/primitives/block.h
Merge branch 'master' into dave-dev
[VerusCoin.git] / src / primitives / block.h
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.
5
6 #ifndef BITCOIN_PRIMITIVES_BLOCK_H
7 #define BITCOIN_PRIMITIVES_BLOCK_H
8
9 #include "primitives/transaction.h"
10 #include "serialize.h"
11 #include "uint256.h"
12 #include "arith_uint256.h"
13
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
19  * of the block.
20  */
21 class CBlockHeader
22 {
23 public:
24     // header
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();
29
30     int32_t nVersion;
31     uint256 hashPrevBlock;
32     uint256 hashMerkleRoot;
33     uint256 hashReserved;
34     uint32_t nTime;
35     uint32_t nBits;
36     uint256 nNonce;
37     std::vector<unsigned char> nSolution;
38
39     CBlockHeader()
40     {
41         SetNull();
42     }
43
44     ADD_SERIALIZE_METHODS;
45
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);
53         READWRITE(nTime);
54         READWRITE(nBits);
55         READWRITE(nNonce);
56         READWRITE(nSolution);
57     }
58
59     void SetNull()
60     {
61         nVersion = CBlockHeader::CURRENT_VERSION;
62         hashPrevBlock.SetNull();
63         hashMerkleRoot.SetNull();
64         hashReserved.SetNull();
65         nTime = 0;
66         nBits = 0;
67         nNonce = uint256();
68         nSolution.clear();
69     }
70
71     bool IsNull() const
72     {
73         return (nBits == 0);
74     }
75
76     uint256 GetHash() const
77     {
78         return (this->*hashFunction)();
79     }
80
81     uint256 GetSHA256DHash() const;
82     static void SetSHA256DHash();
83
84     uint256 GetVerusHash() const;
85     static void SetVerusHash();
86
87     uint256 GetVerusHashPortable() const;
88     static void SetVerusHashPortable();
89
90     uint256 GetVerusMiningHash() const;
91
92     int64_t GetBlockTime() const
93     {
94         return (int64_t)nTime;
95     }
96
97     int32_t GetVerusPOSTarget() const
98     {
99         uint32_t nBits = 0;
100
101         for (const unsigned char *p = nNonce.begin() + 3; p >= nNonce.begin(); p--)
102         {
103             nBits <<= 8;
104             nBits += *p;
105         }
106         return nBits;
107     }
108
109     bool IsVerusPOSBlock() const
110     {
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));
116     }
117
118     void SetVerusPOSTarget(int32_t nBits)
119     {
120         CVerusHashPortableWriter hashWriter = CVerusHashPortableWriter(SER_GETHASH, PROTOCOL_VERSION);
121         uint256 hash;
122         arith_uint256 tmpNonce;
123
124         arith_uint256 arNonce = UintToArith256(nNonce);
125         arNonce = ((arNonce >> 32) << 32) | nBits;
126
127         tmpNonce = ((arNonce << 128) >> 128);
128         hashWriter << ArithToUint256(tmpNonce);
129
130         nNonce = ArithToUint256(UintToArith256(hashWriter.GetHash()) << 128 | tmpNonce);
131     }
132 };
133
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
141 {
142     public:
143         std::vector<CTransaction> compatVec;
144
145     CNetworkBlockHeader() : CBlockHeader()
146     {
147         SetNull();
148     }
149
150     CNetworkBlockHeader(const CBlockHeader &header)
151     {
152         SetNull();
153         *((CBlockHeader*)this) = header;
154     }
155
156     ADD_SERIALIZE_METHODS;
157
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);
162     }
163
164     void SetNull()
165     {
166         CBlockHeader::SetNull();
167         compatVec.clear();    
168     }
169 };
170
171 class CBlock : public CBlockHeader
172 {
173 public:
174     // network and disk
175     std::vector<CTransaction> vtx;
176
177     // memory only
178     mutable std::vector<uint256> vMerkleTree;
179
180     CBlock()
181     {
182         SetNull();
183     }
184
185     CBlock(const CBlockHeader &header)
186     {
187         SetNull();
188         *((CBlockHeader*)this) = header;
189     }
190
191     ADD_SERIALIZE_METHODS;
192
193     template <typename Stream, typename Operation>
194     inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
195         READWRITE(*(CBlockHeader*)this);
196         READWRITE(vtx);
197     }
198
199     void SetNull()
200     {
201         CBlockHeader::SetNull();
202         vtx.clear();
203         vMerkleTree.clear();
204     }
205
206     CBlockHeader GetBlockHeader() const
207     {
208         CBlockHeader block;
209         block.nVersion       = nVersion;
210         block.hashPrevBlock  = hashPrevBlock;
211         block.hashMerkleRoot = hashMerkleRoot;
212         block.hashReserved   = hashReserved;
213         block.nTime          = nTime;
214         block.nBits          = nBits;
215         block.nNonce         = nNonce;
216         block.nSolution      = nSolution;
217         return block;
218     }
219
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
223     // merkle root).
224     uint256 BuildMerkleTree(bool* mutated = NULL) const;
225
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;
229 };
230
231
232 /**
233  * Custom serializer for CBlockHeader that omits the nonce and solution, for use
234  * as input to Equihash.
235  */
236 class CEquihashInput : private CBlockHeader
237 {
238 public:
239     CEquihashInput(const CBlockHeader &header)
240     {
241         CBlockHeader::SetNull();
242         *((CBlockHeader*)this) = header;
243     }
244
245     ADD_SERIALIZE_METHODS;
246
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);
254         READWRITE(nTime);
255         READWRITE(nBits);
256     }
257 };
258
259
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.
263  */
264 struct CBlockLocator
265 {
266     std::vector<uint256> vHave;
267
268     CBlockLocator() {}
269
270     CBlockLocator(const std::vector<uint256>& vHaveIn)
271     {
272         vHave = vHaveIn;
273     }
274
275     ADD_SERIALIZE_METHODS;
276
277     template <typename Stream, typename Operation>
278     inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
279         if (!(nType & SER_GETHASH))
280             READWRITE(nVersion);
281         READWRITE(vHave);
282     }
283
284     void SetNull()
285     {
286         vHave.clear();
287     }
288
289     bool IsNull() const
290     {
291         return vHave.empty();
292     }
293
294     friend bool operator==(const CBlockLocator& a, const CBlockLocator& b) {
295         return (a.vHave == b.vHave);
296     }
297 };
298
299 #endif // BITCOIN_PRIMITIVES_BLOCK_H
This page took 0.043868 seconds and 4 git commands to generate.