|
|
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
|
|
|
// Copyright (c) 2009-2017 The Bitcoin Core developers
|
|
|
|
// Distributed under the MIT software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
|
|
|
#ifndef BITCOIN_PRIMITIVES_BLOCK_H
|
|
|
|
#define BITCOIN_PRIMITIVES_BLOCK_H
|
|
|
|
|
|
|
|
#include <primitives/transaction.h>
|
|
|
|
#include <serialize.h>
|
|
|
|
#include <uint256.h>
|
|
|
|
|
|
|
|
#include <cryptonote_basic/cryptonote_format_utils.h>
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This header is to store the proof-of-work of cryptonote mining.
|
|
|
|
* Kevacoin uses Cryptonight PoW and uses its existing infrastructure
|
|
|
|
* (mining pools and miners)
|
|
|
|
*/
|
|
|
|
class CryptoNoteHeader
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
uint8_t major_version;
|
|
|
|
uint8_t minor_version; // now used as a voting mechanism, rather than how this particular block is built
|
|
|
|
uint64_t timestamp;
|
|
|
|
uint256 prev_id;
|
|
|
|
uint32_t nonce;
|
|
|
|
uint256 merkle_root;
|
|
|
|
size_t nTxes; // Number of transactions.
|
|
|
|
|
|
|
|
CryptoNoteHeader()
|
|
|
|
{
|
|
|
|
SetNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetNull()
|
|
|
|
{
|
|
|
|
major_version = 0;
|
|
|
|
minor_version = 0;
|
|
|
|
prev_id.SetNull();
|
|
|
|
timestamp = 0;
|
|
|
|
nonce = 0;
|
|
|
|
merkle_root.SetNull();
|
|
|
|
nTxes = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsNull() const
|
|
|
|
{
|
|
|
|
return (timestamp == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// load
|
|
|
|
template <template <bool> class Archive>
|
|
|
|
bool do_serialize(Archive<false>& ar)
|
|
|
|
{
|
|
|
|
VARINT_FIELD(major_version)
|
|
|
|
VARINT_FIELD(minor_version)
|
|
|
|
VARINT_FIELD(timestamp)
|
|
|
|
crypto::hash prev_hash;
|
|
|
|
FIELD(prev_hash)
|
|
|
|
memcpy(prev_id.begin(), &prev_hash, prev_id.size());
|
|
|
|
FIELD(nonce)
|
|
|
|
crypto::hash merkle_hash;
|
|
|
|
FIELD(merkle_hash)
|
|
|
|
memcpy(merkle_root.begin(), &merkle_hash, merkle_root.size());
|
|
|
|
VARINT_FIELD(nTxes)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// store
|
|
|
|
template <template <bool> class Archive>
|
|
|
|
bool do_serialize(Archive<true>& ar)
|
|
|
|
{
|
|
|
|
VARINT_FIELD(major_version)
|
|
|
|
VARINT_FIELD(minor_version)
|
|
|
|
VARINT_FIELD(timestamp)
|
|
|
|
crypto::hash prev_hash;
|
|
|
|
memcpy(&prev_hash, prev_id.begin(), prev_id.size());
|
|
|
|
FIELD(prev_hash)
|
|
|
|
FIELD(nonce)
|
|
|
|
crypto::hash merkle_hash;
|
|
|
|
memcpy(&merkle_hash, merkle_root.begin(), merkle_root.size());
|
|
|
|
FIELD(merkle_hash)
|
|
|
|
VARINT_FIELD(nTxes)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action) {
|
|
|
|
if (ser_action.ForRead()) {
|
|
|
|
std::string blob;
|
|
|
|
READWRITE(blob);
|
|
|
|
std::stringstream ss;
|
|
|
|
ss << blob;
|
|
|
|
// load
|
|
|
|
binary_archive<false> ba(ss);
|
|
|
|
::serialization::serialize(ba, *this);
|
|
|
|
} else {
|
|
|
|
std::stringstream ss;
|
|
|
|
// store
|
|
|
|
binary_archive<true> ba(ss);
|
|
|
|
::serialization::serialize(ba, *this);
|
|
|
|
std::string blob = ss.str();
|
|
|
|
READWRITE(blob);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/** 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
|
|
|
|
* to everyone and the block is added to the block chain. The first transaction
|
|
|
|
* in the block is a special one that creates a new coin owned by the creator
|
|
|
|
* of the block.
|
|
|
|
*/
|
|
|
|
class CBlockHeader
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// header
|
|
|
|
int32_t nVersion;
|
|
|
|
uint256 hashPrevBlock;
|
|
|
|
uint256 hashMerkleRoot;
|
|
|
|
uint32_t nTime;
|
|
|
|
uint32_t nBits;
|
|
|
|
// nNonce is no longer used as nonce, as the nonce is now in cnHeader.
|
|
|
|
// Repurpose it for block height used in Cryptnight variant 4.
|
|
|
|
uint32_t nNonce;
|
|
|
|
|
|
|
|
// CryptoNote header for emulation or merged mining
|
|
|
|
CryptoNoteHeader cnHeader;
|
|
|
|
|
|
|
|
CBlockHeader()
|
|
|
|
{
|
|
|
|
SetNull();
|
|
|
|
cnHeader.SetNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
overhaul serialization code
The implementation of each class' serialization/deserialization is no longer
passed within a macro. The implementation now lies within a template of form:
template <typename T, typename Stream, typename Operation>
inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) {
size_t nSerSize = 0;
/* CODE */
return nSerSize;
}
In cases when codepath should depend on whether or not we are just deserializing
(old fGetSize, fWrite, fRead flags) an additional clause can be used:
bool fRead = boost::is_same<Operation, CSerActionUnserialize>();
The IMPLEMENT_SERIALIZE macro will now be a freestanding clause added within
class' body (similiar to Qt's Q_OBJECT) to implement GetSerializeSize,
Serialize and Unserialize. These are now wrappers around
the "SerializationOp" template.
10 years ago
|
|
|
|
|
|
|
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);
|
|
|
|
// Genesis block does not have cnHeader.
|
|
|
|
if (!hashPrevBlock.IsNull() && !legacyMode) {
|
|
|
|
READWRITE(cnHeader);
|
|
|
|
}
|
overhaul serialization code
The implementation of each class' serialization/deserialization is no longer
passed within a macro. The implementation now lies within a template of form:
template <typename T, typename Stream, typename Operation>
inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) {
size_t nSerSize = 0;
/* CODE */
return nSerSize;
}
In cases when codepath should depend on whether or not we are just deserializing
(old fGetSize, fWrite, fRead flags) an additional clause can be used:
bool fRead = boost::is_same<Operation, CSerActionUnserialize>();
The IMPLEMENT_SERIALIZE macro will now be a freestanding clause added within
class' body (similiar to Qt's Q_OBJECT) to implement GetSerializeSize,
Serialize and Unserialize. These are now wrappers around
the "SerializationOp" template.
10 years ago
|
|
|
}
|
|
|
|
|
|
|
|
void SetNull()
|
|
|
|
{
|
|
|
|
nVersion = 0;
|
|
|
|
hashPrevBlock.SetNull();
|
|
|
|
hashMerkleRoot.SetNull();
|
|
|
|
nTime = 0;
|
|
|
|
nBits = 0;
|
|
|
|
nNonce = 0;
|
|
|
|
legacyMode = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsNull() const
|
|
|
|
{
|
|
|
|
return (nBits == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint256 GetHash() const;
|
|
|
|
|
|
|
|
uint256 GetCryptonoteFastHash() const;
|
|
|
|
|
|
|
|
uint256 GetPoWHash() const;
|
|
|
|
|
|
|
|
int64_t GetBlockTime() const
|
|
|
|
{
|
|
|
|
return (int64_t)nTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetLegacy(bool legacy)
|
|
|
|
{
|
|
|
|
legacyMode = legacy;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isLegacy()
|
|
|
|
{
|
|
|
|
return legacyMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
// When legacyMode is true, cnHeader is not used.
|
|
|
|
// This is used for regtest.
|
|
|
|
bool legacyMode;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class CBlock : public CBlockHeader
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// network and disk
|
|
|
|
std::vector<CTransactionRef> vtx;
|
|
|
|
|
|
|
|
// memory only
|
|
|
|
mutable bool fChecked;
|
|
|
|
|
|
|
|
CBlock()
|
|
|
|
{
|
|
|
|
SetNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
CBlock(const CBlockHeader &header)
|
|
|
|
{
|
|
|
|
SetNull();
|
|
|
|
*((CBlockHeader*)this) = header;
|
|
|
|
}
|
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
overhaul serialization code
The implementation of each class' serialization/deserialization is no longer
passed within a macro. The implementation now lies within a template of form:
template <typename T, typename Stream, typename Operation>
inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) {
size_t nSerSize = 0;
/* CODE */
return nSerSize;
}
In cases when codepath should depend on whether or not we are just deserializing
(old fGetSize, fWrite, fRead flags) an additional clause can be used:
bool fRead = boost::is_same<Operation, CSerActionUnserialize>();
The IMPLEMENT_SERIALIZE macro will now be a freestanding clause added within
class' body (similiar to Qt's Q_OBJECT) to implement GetSerializeSize,
Serialize and Unserialize. These are now wrappers around
the "SerializationOp" template.
10 years ago
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action) {
|
|
|
|
READWRITE(*(CBlockHeader*)this);
|
|
|
|
READWRITE(vtx);
|
overhaul serialization code
The implementation of each class' serialization/deserialization is no longer
passed within a macro. The implementation now lies within a template of form:
template <typename T, typename Stream, typename Operation>
inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) {
size_t nSerSize = 0;
/* CODE */
return nSerSize;
}
In cases when codepath should depend on whether or not we are just deserializing
(old fGetSize, fWrite, fRead flags) an additional clause can be used:
bool fRead = boost::is_same<Operation, CSerActionUnserialize>();
The IMPLEMENT_SERIALIZE macro will now be a freestanding clause added within
class' body (similiar to Qt's Q_OBJECT) to implement GetSerializeSize,
Serialize and Unserialize. These are now wrappers around
the "SerializationOp" template.
10 years ago
|
|
|
}
|
|
|
|
|
|
|
|
void SetNull()
|
|
|
|
{
|
|
|
|
CBlockHeader::SetNull();
|
|
|
|
vtx.clear();
|
|
|
|
fChecked = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
CBlockHeader GetBlockHeader() const
|
|
|
|
{
|
|
|
|
CBlockHeader block;
|
|
|
|
block.nVersion = nVersion;
|
|
|
|
block.hashPrevBlock = hashPrevBlock;
|
|
|
|
block.hashMerkleRoot = hashMerkleRoot;
|
|
|
|
block.nTime = nTime;
|
|
|
|
block.nBits = nBits;
|
|
|
|
block.nNonce = nNonce;
|
|
|
|
block.SetLegacy(legacyMode);
|
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string ToString() const;
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Describes a place in the block chain to another node such that if the
|
|
|
|
* other node doesn't have the same branch, it can find a recent common trunk.
|
|
|
|
* The further back it is, the further before the fork it may be.
|
|
|
|
*/
|
|
|
|
struct CBlockLocator
|
|
|
|
{
|
|
|
|
std::vector<uint256> vHave;
|
|
|
|
|
|
|
|
CBlockLocator() {}
|
|
|
|
|
|
|
|
explicit CBlockLocator(const std::vector<uint256>& vHaveIn) : vHave(vHaveIn) {}
|
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
overhaul serialization code
The implementation of each class' serialization/deserialization is no longer
passed within a macro. The implementation now lies within a template of form:
template <typename T, typename Stream, typename Operation>
inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) {
size_t nSerSize = 0;
/* CODE */
return nSerSize;
}
In cases when codepath should depend on whether or not we are just deserializing
(old fGetSize, fWrite, fRead flags) an additional clause can be used:
bool fRead = boost::is_same<Operation, CSerActionUnserialize>();
The IMPLEMENT_SERIALIZE macro will now be a freestanding clause added within
class' body (similiar to Qt's Q_OBJECT) to implement GetSerializeSize,
Serialize and Unserialize. These are now wrappers around
the "SerializationOp" template.
10 years ago
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action) {
|
|
|
|
int nVersion = s.GetVersion();
|
|
|
|
if (!(s.GetType() & SER_GETHASH))
|
|
|
|
READWRITE(nVersion);
|
|
|
|
READWRITE(vHave);
|
overhaul serialization code
The implementation of each class' serialization/deserialization is no longer
passed within a macro. The implementation now lies within a template of form:
template <typename T, typename Stream, typename Operation>
inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) {
size_t nSerSize = 0;
/* CODE */
return nSerSize;
}
In cases when codepath should depend on whether or not we are just deserializing
(old fGetSize, fWrite, fRead flags) an additional clause can be used:
bool fRead = boost::is_same<Operation, CSerActionUnserialize>();
The IMPLEMENT_SERIALIZE macro will now be a freestanding clause added within
class' body (similiar to Qt's Q_OBJECT) to implement GetSerializeSize,
Serialize and Unserialize. These are now wrappers around
the "SerializationOp" template.
10 years ago
|
|
|
}
|
|
|
|
|
|
|
|
void SetNull()
|
|
|
|
{
|
|
|
|
vHave.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsNull() const
|
|
|
|
{
|
|
|
|
return vHave.empty();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // BITCOIN_PRIMITIVES_BLOCK_H
|