Use Equihash for Proof-of-Work

The main and test networks are configured to use parameters that are currently
low-memory but usable with the basic solver; they will be increased once the
solver is optimised. The regtest network is configured to have extremely low
memory usage for speed.

Note that Bitcoin's double-hasher is used for the difficulty check. This does
not match the paper, but is simpler than changing the block header
serialization. Single hashing is kept for the EquiHash solver because there is
no requirement on execution time there, only on memory usage.
This commit is contained in:
Jack Grigg
2016-02-28 20:19:07 +00:00
parent 020bed6021
commit fdda3c5085
13 changed files with 200 additions and 70 deletions

View File

@@ -112,12 +112,12 @@ uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMer
std::string CBlock::ToString() const
{
std::stringstream s;
s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%s, vtx=%u)\n",
GetHash().ToString(),
nVersion,
hashPrevBlock.ToString(),
hashMerkleRoot.ToString(),
nTime, nBits, nNonce,
nTime, nBits, nNonce.ToString(),
vtx.size());
for (unsigned int i = 0; i < vtx.size(); i++)
{

View File

@@ -27,7 +27,8 @@ public:
uint256 hashMerkleRoot;
uint32_t nTime;
uint32_t nBits;
uint32_t nNonce;
uint256 nNonce;
std::vector<uint32_t> nSolution;
CBlockHeader()
{
@@ -45,6 +46,7 @@ public:
READWRITE(nTime);
READWRITE(nBits);
READWRITE(nNonce);
READWRITE(nSolution);
}
void SetNull()
@@ -54,7 +56,8 @@ public:
hashMerkleRoot.SetNull();
nTime = 0;
nBits = 0;
nNonce = 0;
nNonce = uint256();
nSolution.clear();
}
bool IsNull() const
@@ -115,6 +118,7 @@ public:
block.nTime = nTime;
block.nBits = nBits;
block.nNonce = nNonce;
block.nSolution = nSolution;
return block;
}
@@ -130,6 +134,33 @@ public:
};
/**
* Custom serializer for CBlockHeader that omits the nonce and solution, for use
* as input to Equihash.
*/
class CEquihashInput : private CBlockHeader
{
public:
CEquihashInput(const CBlockHeader &header)
{
CBlockHeader::SetNull();
*((CBlockHeader*)this) = header;
}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(this->nVersion);
nVersion = this->nVersion;
READWRITE(hashPrevBlock);
READWRITE(hashMerkleRoot);
READWRITE(nTime);
READWRITE(nBits);
}
};
/** 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.