diff options
Diffstat (limited to 'src/primitives')
| -rw-r--r-- | src/primitives/block.cpp | 20 | ||||
| -rw-r--r-- | src/primitives/block.h | 59 | ||||
| -rw-r--r-- | src/primitives/pureheader.cpp | 29 | ||||
| -rw-r--r-- | src/primitives/pureheader.h | 157 |
4 files changed, 222 insertions, 43 deletions
diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index c61dc5fb5..f272347a3 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -6,21 +6,21 @@ #include <primitives/block.h> #include <hash.h> -#include <crypto/scrypt.h> #include <tinyformat.h> #include <utilstrencodings.h> #include <crypto/common.h> -uint256 CBlockHeader::GetHash() const +void CBlockHeader::SetAuxpow (std::unique_ptr<CAuxPow> apow) { - return SerializeHash(*this); -} - -uint256 CBlockHeader::GetPoWHash() const -{ - uint256 thash; - scrypt_1024_1_1_256(BEGIN(nVersion), BEGIN(thash)); - return thash; + if (apow != nullptr) + { + auxpow.reset(apow.release()); + SetAuxpowFlag(true); + } else + { + auxpow.reset(); + SetAuxpowFlag(false); + } } std::string CBlock::ToString() const diff --git a/src/primitives/block.h b/src/primitives/block.h index 9bc06ad6b..1c3243bb3 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -6,10 +6,14 @@ #ifndef BITCOIN_PRIMITIVES_BLOCK_H #define BITCOIN_PRIMITIVES_BLOCK_H +#include <auxpow.h> #include <primitives/transaction.h> +#include <primitives/pureheader.h> #include <serialize.h> #include <uint256.h> +#include <memory> + /** Nodes collect new transactions into a block, hash them into a hash tree, * and scan through nonce values to make the block's hash satisfy proof-of-work * requirements. When they solve the proof-of-work, they broadcast the block @@ -17,16 +21,12 @@ * in the block is a special one that creates a new coin owned by the creator * of the block. */ -class CBlockHeader +class CBlockHeader : public CPureBlockHeader { public: - // header - int32_t nVersion; - uint256 hashPrevBlock; - uint256 hashMerkleRoot; - uint32_t nTime; - uint32_t nBits; - uint32_t nNonce; + + // auxpow (if this is a merge-minded block) + std::shared_ptr<CAuxPow> auxpow; CBlockHeader() { @@ -37,37 +37,29 @@ public: template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(this->nVersion); - READWRITE(hashPrevBlock); - READWRITE(hashMerkleRoot); - READWRITE(nTime); - READWRITE(nBits); - READWRITE(nNonce); + READWRITE(*(CPureBlockHeader*)this); + + if (this->IsAuxpow()) + { + if (ser_action.ForRead()) + auxpow = std::make_shared<CAuxPow>(); + assert(auxpow != nullptr); + READWRITE(*auxpow); + } else if (ser_action.ForRead()) + auxpow.reset(); } void SetNull() { - nVersion = 0; - hashPrevBlock.SetNull(); - hashMerkleRoot.SetNull(); - nTime = 0; - nBits = 0; - nNonce = 0; - } - - bool IsNull() const - { - return (nBits == 0); + CPureBlockHeader::SetNull(); + auxpow.reset(); } - uint256 GetHash() const; - - uint256 GetPoWHash() const; - - int64_t GetBlockTime() const - { - return (int64_t)nTime; - } + /** + * Set the block's auxpow (or unset it). This takes care of updating + * the version accordingly. + */ + void SetAuxpow (std::unique_ptr<CAuxPow> apow); }; @@ -115,6 +107,7 @@ public: block.nTime = nTime; block.nBits = nBits; block.nNonce = nNonce; + block.auxpow = auxpow; return block; } diff --git a/src/primitives/pureheader.cpp b/src/primitives/pureheader.cpp new file mode 100644 index 000000000..2dc33d738 --- /dev/null +++ b/src/primitives/pureheader.cpp @@ -0,0 +1,29 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "primitives/pureheader.h" + +#include "crypto/scrypt.h" +#include "hash.h" +#include "utilstrencodings.h" + +void CPureBlockHeader::SetBaseVersion(int32_t nBaseVersion, int32_t nChainId) +{ + assert(nBaseVersion >= 1 && nBaseVersion < VERSION_AUXPOW); + assert(!IsAuxpow()); + nVersion = nBaseVersion | (nChainId * VERSION_CHAIN_START); +} + +uint256 CPureBlockHeader::GetHash() const +{ + return SerializeHash(*this); +} + +uint256 CPureBlockHeader::GetPoWHash() const +{ + uint256 thash; + scrypt_1024_1_1_256(BEGIN(nVersion), BEGIN(thash)); + return thash; +} diff --git a/src/primitives/pureheader.h b/src/primitives/pureheader.h new file mode 100644 index 000000000..34373bbb7 --- /dev/null +++ b/src/primitives/pureheader.h @@ -0,0 +1,157 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2013 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_PRIMITIVES_PUREHEADER_H +#define BITCOIN_PRIMITIVES_PUREHEADER_H + +#include "serialize.h" +#include "uint256.h" + +/** + * A block header without auxpow information. This "intermediate step" + * in constructing the full header is useful, because it breaks the cyclic + * dependency between auxpow (referencing a parent block header) and + * the block header (referencing an auxpow). The parent block header + * does not have auxpow itself, so it is a pure header. + */ +class CPureBlockHeader +{ +public: + + /* Modifiers to the version. */ + static const int32_t VERSION_AUXPOW = (1 << 8); + + /** Bits above are reserved for the auxpow chain ID. */ + static const int32_t VERSION_CHAIN_START = (1 << 16); + + // header + int32_t nVersion; + uint256 hashPrevBlock; + uint256 hashMerkleRoot; + uint32_t nTime; + uint32_t nBits; + uint32_t nNonce; + + CPureBlockHeader() + { + SetNull(); + } + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(this->nVersion); + READWRITE(hashPrevBlock); + READWRITE(hashMerkleRoot); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); + } + + void SetNull() + { + nVersion = 0; + hashPrevBlock.SetNull(); + hashMerkleRoot.SetNull(); + nTime = 0; + nBits = 0; + nNonce = 0; + } + + bool IsNull() const + { + return (nBits == 0); + } + + uint256 GetHash() const; + uint256 GetPoWHash() const; + + int64_t GetBlockTime() const + { + return (int64_t)nTime; + } + + /* Below are methods to interpret the version with respect to + auxpow data and chain ID. This used to be in the CBlockVersion + class, but was moved here when we switched back to nVersion being + a pure int member as preparation to undoing the "abuse" and + allowing BIP9 to work. */ + + /** + * Extract the base version (without modifiers and chain ID). + * @return The base version./ + */ + inline int32_t GetBaseVersion() const + { + return GetBaseVersion(nVersion); + } + static inline int32_t GetBaseVersion(int32_t ver) + { + return ver % VERSION_AUXPOW; + } + + /** + * Set the base version (apart from chain ID and auxpow flag) to + * the one given. This should only be called when auxpow is not yet + * set, to initialise a block! + * @param nBaseVersion The base version. + * @param nChainId The auxpow chain ID. + */ + void SetBaseVersion(int32_t nBaseVersion, int32_t nChainId); + + /** + * Extract the chain ID. + * @return The chain ID encoded in the version. + */ + inline int32_t GetChainId() const + { + return nVersion >> 16; + } + + /** + * Set the chain ID. This is used for the test suite. + * @param ch The chain ID to set. + */ + inline void SetChainId(int32_t chainId) + { + nVersion %= VERSION_CHAIN_START; + nVersion |= chainId * VERSION_CHAIN_START; + } + + /** + * Check if the auxpow flag is set in the version. + * @return True iff this block version is marked as auxpow. + */ + inline bool IsAuxpow() const + { + return nVersion & VERSION_AUXPOW; + } + + /** + * Set the auxpow flag. This is used for testing. + * @param auxpow Whether to mark auxpow as true. + */ + inline void SetAuxpowFlag(bool auxpow) + { + if (auxpow) + nVersion |= VERSION_AUXPOW; + else + nVersion &= ~VERSION_AUXPOW; + } + + /** + * Check whether this is a "legacy" block without chain ID. + * @return True iff it is. + */ + inline bool IsLegacy() const + { + return nVersion == 1 + // Dogecoin: We have a random v2 block with no AuxPoW, treat as legacy + || (nVersion == 2 && GetChainId() == 0); + } +}; + +#endif // BITCOIN_PRIMITIVES_PUREHEADER_H |