aboutsummaryrefslogtreecommitdiff
path: root/src/primitives
diff options
context:
space:
mode:
authorMax K <[email protected]>2019-07-14 19:35:30 +0200
committerGitHub <[email protected]>2019-07-14 19:35:30 +0200
commitcee13699a5676355487f8eb2d91985f63438eae4 (patch)
treecf12be6180f950a25ee2ee7f3f2126542835d6e3 /src/primitives
parentCorrect build and test net seed (diff)
parentHandle legacy v2 block at #66064 (diff)
downloaddiscoin-1.17-dev.tar.xz
discoin-1.17-dev.zip
Merge pull request #1546 from rnicoll/1.17-auxpow1.17-dev
1.17 AuxPoW support
Diffstat (limited to 'src/primitives')
-rw-r--r--src/primitives/block.cpp20
-rw-r--r--src/primitives/block.h59
-rw-r--r--src/primitives/pureheader.cpp29
-rw-r--r--src/primitives/pureheader.h157
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