]> Git Repo - VerusCoin.git/blobdiff - src/primitives/block.h
Incorporate all Zcash updates through 2.0.7-3 in addition to PBaaS, reserves, etc.
[VerusCoin.git] / src / primitives / block.h
index 874ffc7085c9a4f25ffdf11a7d48e32a4c12694c..009c4e0f9c3e7afd3cd1cf0b078af6054abbd44f 100644 (file)
@@ -1,16 +1,24 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
 // Copyright (c) 2009-2013 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or https://www.opensource.org/licenses/mit-license.php .
 
 #ifndef BITCOIN_PRIMITIVES_BLOCK_H
 #define BITCOIN_PRIMITIVES_BLOCK_H
 
-#include "primitives/transaction.h"
 #include "primitives/nonce.h"
+#include "primitives/transaction.h"
 #include "serialize.h"
 #include "uint256.h"
 #include "arith_uint256.h"
+#include "primitives/solutiondata.h"
+
+// does not check for height / sapling upgrade, etc. this should not be used to get block proofs
+// on a pre-VerusPoP chain
+arith_uint256 GetCompactPower(const uint256 &nNonce, uint32_t nBits, int32_t version=CPOSNonce::VERUS_V2);
+class CMMRPowerNode;
+class CMerkleBranch;
+class CBlockHeader;
 
 /** 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
@@ -23,15 +31,17 @@ class CBlockHeader
 {
 public:
     // header
-    static const size_t HEADER_SIZE=4+32+32+32+4+4+32; // excluding Equihash solution
-    static const int32_t CURRENT_VERSION=4;
+    static const size_t HEADER_SIZE = 4+32+32+32+4+4+32;  // excluding Equihash solution
+    static const int32_t CURRENT_VERSION = CPOSNonce::VERUS_V1;
+    static const int32_t CURRENT_VERSION_MASK = 0x0000ffff; // for compatibility
+    static const int32_t VERUS_V2 = CPOSNonce::VERUS_V2;
+
     static uint256 (CBlockHeader::*hashFunction)() const;
-    static void SetHashAlgo();
 
     int32_t nVersion;
     uint256 hashPrevBlock;
     uint256 hashMerkleRoot;
-    uint256 hashReserved;
+    uint256 hashFinalSaplingRoot;
     uint32_t nTime;
     uint32_t nBits;
     CPOSNonce nNonce;
@@ -45,12 +55,11 @@ public:
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
-    inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+    inline void SerializationOp(Stream& s, Operation ser_action) {
         READWRITE(this->nVersion);
-        nVersion = this->nVersion;
         READWRITE(hashPrevBlock);
         READWRITE(hashMerkleRoot);
-        READWRITE(hashReserved);
+        READWRITE(hashFinalSaplingRoot);
         READWRITE(nTime);
         READWRITE(nBits);
         READWRITE(nNonce);
@@ -62,7 +71,7 @@ public:
         nVersion = CBlockHeader::CURRENT_VERSION;
         hashPrevBlock.SetNull();
         hashMerkleRoot.SetNull();
-        hashReserved.SetNull();
+        hashFinalSaplingRoot.SetNull();
         nTime = 0;
         nBits = 0;
         nNonce = uint256();
@@ -74,21 +83,164 @@ public:
         return (nBits == 0);
     }
 
+    // returns 0 if not PBaaS, 1 if PBaaS PoW, -1 if PBaaS PoS
+    int32_t IsPBaaS()
+    {
+        if (nVersion == VERUS_V2)
+        {
+            return CVerusSolutionVector(nSolution).IsPBaaS();
+        }
+        return 0;
+    }
+
+    // return a vector of bytes that contains the internal data for this solution vector
+    void GetExtraData(std::vector<unsigned char> &dataVec)
+    {
+        CVerusSolutionVector(nSolution).GetExtraData(dataVec);
+    }
+
+    // set the extra data with a pointer to bytes and length
+    bool SetExtraData(const unsigned char *pbegin, uint32_t len)
+    {
+        return CVerusSolutionVector(nSolution).SetExtraData(pbegin, len);
+    }
+
+    void ResizeExtraData(uint32_t newSize)
+    {
+        CVerusSolutionVector(nSolution).ResizeExtraData(newSize);
+    }
+
+    uint32_t ExtraDataLen()
+    {
+        return CVerusSolutionVector(nSolution).ExtraDataLen();
+    }
+
+    // returns -1 on failure, upon failure, pbbh is undefined and likely corrupted
+    int32_t GetPBaaSHeader(CPBaaSBlockHeader &pbh, const uint160 &cID) const;
+
+    // returns false on failure to read data
+    bool GetPBaaSHeader(CPBaaSBlockHeader &pbh, uint32_t idx) const
+    {
+        // search in the solution for this header index and return it if found
+        CPBaaSSolutionDescriptor descr = CConstVerusSolutionVector::GetDescriptor(nSolution);
+        int pbType;
+        if (nVersion == VERUS_V2 && CConstVerusSolutionVector::IsPBaaS(nSolution) != 0 && idx < descr.numPBaaSHeaders)
+        {
+            pbh = *(CConstVerusSolutionVector::GetFirstPBaaSHeader(nSolution) + idx);
+            return true;
+        }
+        return false;
+    }
+
+    // returns false on failure to read data
+    int32_t NumPBaaSHeaders() const
+    {
+        // search in the solution for this header index and return it if found
+        CPBaaSSolutionDescriptor descr = CConstVerusSolutionVector::GetDescriptor(nSolution);
+        return descr.numPBaaSHeaders;
+    }
+
+    // this can save a new header into an empty space or update an existing header
+    bool SavePBaaSHeader(CPBaaSBlockHeader &pbh, uint32_t idx)
+    {
+        CPBaaSBlockHeader pbbh = CPBaaSBlockHeader();
+        int ix;
+
+        CVerusSolutionVector sv = CVerusSolutionVector(nSolution);
+
+        if (sv.IsPBaaS() && !pbh.IsNull() && idx < sv.GetNumPBaaSHeaders() && (((ix = GetPBaaSHeader(pbbh, pbh.chainID)) == -1) || ix == idx))
+        {
+            sv.SetPBaaSHeader(pbh, idx);
+            return true;
+        }
+        return false;
+    }
+
+    bool UpdatePBaaSHeader(const CPBaaSBlockHeader &pbh)
+    {
+        CPBaaSBlockHeader pbbh = CPBaaSBlockHeader();
+        uint32_t idx;
+
+        // what we are updating, must be present
+        if (!pbh.IsNull() && (idx = GetPBaaSHeader(pbbh, pbh.chainID)) != -1)
+        {
+            CVerusSolutionVector(nSolution).SetPBaaSHeader(pbh, idx);
+            return true;
+        }
+        return false;
+    }
+
+    void DeletePBaaSHeader(uint32_t idx)
+    {
+        CVerusSolutionVector sv = CVerusSolutionVector(nSolution);
+        CPBaaSSolutionDescriptor descr = sv.Descriptor();
+        if (idx < descr.numPBaaSHeaders)
+        {
+            CPBaaSBlockHeader pbh;
+            // if we weren't last, move the one that was last to our prior space
+            if (idx < (descr.numPBaaSHeaders - 1))
+            {
+                sv.GetPBaaSHeader(pbh, descr.numPBaaSHeaders - 1);
+            }
+            sv.SetPBaaSHeader(pbh, idx);
+            
+            descr.numPBaaSHeaders--;
+            sv.SetDescriptor(descr);
+        }
+    }
+
+    // returns the index of the new header if added, otherwise, -1
+    int32_t AddPBaaSHeader(const CPBaaSBlockHeader &pbh);
+
+    // add the parts of this block header that can be represented by a PBaaS header to the solution
+    int32_t AddPBaaSHeader(uint256 hashPrevMMRRoot, const uint160 &cID)
+    {
+
+        CPBaaSBlockHeader pbbh = CPBaaSBlockHeader(cID, CPBaaSPreHeader(*this), hashPrevMMRRoot);
+        return AddPBaaSHeader(pbbh);
+    }
+
+    bool AddUpdatePBaaSHeader(uint256 mmvRoot);
+    bool AddUpdatePBaaSHeader(const CPBaaSBlockHeader &pbh);
+
+    // clears everything except version, time, and solution, which are shared across all merge mined blocks
+    void ClearNonCanonicalData()
+    {
+        hashPrevBlock = uint256();
+        hashMerkleRoot = uint256();
+        hashFinalSaplingRoot = uint256();
+        nBits = 0;
+        nNonce = uint256();
+    }
+
+    // this confirms that the current header's data matches what would be expected from its preheader hash in the
+    // solution
+    bool CheckNonCanonicalData() const;
+    bool CheckNonCanonicalData(uint160 &cID) const;
+
     uint256 GetHash() const
     {
         return (this->*hashFunction)();
     }
 
+    // return a node from this block header, including hash of merkle root and block hash as well as compact chain power, to put into an MMR
+    CMMRPowerNode GetMMRNode() const;
+    void AddMerkleProofBridge(CMerkleBranch &branch) const;
+    void AddBlockProofBridge(CMerkleBranch &branch) const;
+    uint256 GetPrevMMRRoot() const;
+
     uint256 GetSHA256DHash() const;
     static void SetSHA256DHash();
 
     uint256 GetVerusHash() const;
     static void SetVerusHash();
 
-    bool GetRawVerusPOSHash(uint256 &value, int32_t nHeight) const;
-    uint256 GetVerusEntropyHash(int32_t nHeight) const;
-
     uint256 GetVerusV2Hash() const;
+    static void SetVerusV2Hash();
+
+    bool GetRawVerusPOSHash(uint256 &ret, int32_t nHeight) const;
+    bool GetVerusPOSHash(arith_uint256 &ret, int32_t nHeight, CAmount value) const; // value is amount of stake tx
+    uint256 GetVerusEntropyHash(int32_t nHeight) const;
 
     int64_t GetBlockTime() const
     {
@@ -109,25 +261,66 @@ public:
 
     bool IsVerusPOSBlock() const
     {
-        return nNonce.IsPOSNonce();
+        return nNonce.IsPOSNonce(nVersion) && GetVerusPOSTarget() != 0;
     }
 
     void SetVerusPOSTarget(uint32_t nBits)
     {
-        CVerusHashWriter hashWriter = CVerusHashWriter(SER_GETHASH, PROTOCOL_VERSION);
+        if (nVersion == VERUS_V2)
+        {
+            CVerusHashV2Writer hashWriter = CVerusHashV2Writer(SER_GETHASH, PROTOCOL_VERSION);
 
-        arith_uint256 arNonce = UintToArith256(nNonce);
+            arith_uint256 arNonce = UintToArith256(nNonce);
 
-        // printf("before svpt: %s\n", ArithToUint256(arNonce).GetHex().c_str());
+            // printf("before svpt: %s\n", ArithToUint256(arNonce).GetHex().c_str());
 
-        arNonce = (arNonce & CPOSNonce::entropyMask) | nBits;
+            arNonce = (arNonce & CPOSNonce::entropyMask) | nBits;
 
-        // printf("after clear: %s\n", ArithToUint256(arNonce).GetHex().c_str());
+            // printf("after clear: %s\n", ArithToUint256(arNonce).GetHex().c_str());
 
-        hashWriter << ArithToUint256(arNonce);
-        nNonce = CPOSNonce(ArithToUint256(UintToArith256(hashWriter.GetHash()) << 128 | arNonce));
+            hashWriter << ArithToUint256(arNonce);
+            nNonce = CPOSNonce(ArithToUint256(UintToArith256(hashWriter.GetHash()) << 128 | arNonce));
 
-        // printf(" after svpt: %s\n", nNonce.GetHex().c_str());
+            // printf(" after svpt: %s\n", nNonce.GetHex().c_str());
+        }
+        else
+        {
+            CVerusHashWriter hashWriter = CVerusHashWriter(SER_GETHASH, PROTOCOL_VERSION);
+
+            arith_uint256 arNonce = UintToArith256(nNonce);
+
+            // printf("before svpt: %s\n", ArithToUint256(arNonce).GetHex().c_str());
+
+            arNonce = (arNonce & CPOSNonce::entropyMask) | nBits;
+
+            // printf("after clear: %s\n", ArithToUint256(arNonce).GetHex().c_str());
+
+            hashWriter << ArithToUint256(arNonce);
+            nNonce = CPOSNonce(ArithToUint256(UintToArith256(hashWriter.GetHash()) << 128 | arNonce));
+
+            // printf(" after svpt: %s\n", nNonce.GetHex().c_str());
+        }
+    }
+
+    bool SetVersionByHeight(uint32_t height)
+    {
+        CVerusSolutionVector vsv = CVerusSolutionVector(nSolution);
+        if (vsv.SetVersionByHeight(height) && vsv.Version() > 0)
+        {
+            nVersion = VERUS_V2;
+        }
+    }
+
+    static uint32_t GetVersionByHeight(uint32_t height)
+    {
+        if (CVerusSolutionVector::GetVersionByHeight(height) > 0)
+        {
+            return VERUS_V2;
+        }
+        else
+        {
+            return CURRENT_VERSION;
+        }
     }
 };
 
@@ -156,7 +349,7 @@ class CNetworkBlockHeader : public CBlockHeader
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
-    inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+    inline void SerializationOp(Stream& s, Operation ser_action) {
         READWRITE(*(CBlockHeader*)this);
         READWRITE(compatVec);
     }
@@ -191,7 +384,7 @@ public:
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
-    inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+    inline void SerializationOp(Stream& s, Operation ser_action) {
         READWRITE(*(CBlockHeader*)this);
         READWRITE(vtx);
     }
@@ -209,7 +402,7 @@ public:
         block.nVersion       = nVersion;
         block.hashPrevBlock  = hashPrevBlock;
         block.hashMerkleRoot = hashMerkleRoot;
-        block.hashReserved   = hashReserved;
+        block.hashFinalSaplingRoot   = hashFinalSaplingRoot;
         block.nTime          = nTime;
         block.nBits          = nBits;
         block.nNonce         = nNonce;
@@ -251,12 +444,11 @@ public:
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
-    inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+    inline void SerializationOp(Stream& s, Operation ser_action) {
         READWRITE(this->nVersion);
-        nVersion = this->nVersion;
         READWRITE(hashPrevBlock);
         READWRITE(hashMerkleRoot);
-        READWRITE(hashReserved);
+        READWRITE(hashFinalSaplingRoot);
         READWRITE(nTime);
         READWRITE(nBits);
     }
@@ -281,8 +473,9 @@ struct CBlockLocator
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
-    inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
-        if (!(nType & SER_GETHASH))
+    inline void SerializationOp(Stream& s, Operation ser_action) {
+        int nVersion = s.GetVersion();
+        if (!(s.GetType() & SER_GETHASH))
             READWRITE(nVersion);
         READWRITE(vHave);
     }
This page took 0.034078 seconds and 4 git commands to generate.