Start coding proof of work logic.

This commit is contained in:
JoelKatz
2012-11-10 22:19:03 -08:00
parent bf9263fa58
commit 3613c45962
2 changed files with 132 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
#include "ProofOfWork.h"
#include <string>
#include <openssl/rand.h>
#include "Serializer.h"
const uint256 ProofOfWork::sMinTarget("00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
const int ProofOfWork::sMaxIterations(1 << 23);
bool ProofOfWork::isValid() const
{
return ((mIterations <= sMaxIterations) && (mTarget >= sMinTarget));
}
uint64 ProofOfWork::getDifficulty(const uint256& target, int iterations)
{ // calculate the approximate number of hashes required to solve this proof of work
if ((iterations > sMaxIterations) || (target < sMinTarget));
throw std::runtime_error("invalid proof of work target/iteration");
// more iterations means more hashes per iteration but also a larger final hash
uint64 difficulty = iterations * (iterations / 4 + 1);
// Multiply the number of hashes needed by 16 for each leading zero in the hex difficulty
const unsigned char *ptr = target.begin();
while (*ptr == 0)
{
difficulty *= 16;
ptr++;
}
// If the first digit after a zero isn't an F, multiply
difficulty *= (16 - *ptr);
return difficulty;
}
uint256 ProofOfWork::solve(int maxIterations) const
{
if (!isValid())
throw std::runtime_error("invalid proof of work target/iteration");
uint256 nonce;
RAND_bytes(nonce.begin(), nonce.size());
Serializer s1, s2;
std::vector<unsigned char> buf;
buf.reserve((256 / 8) * mIterations);
while (maxIterations > 8)
{
s1.add256(mChallenge);
s1.add256(nonce);
// uint256 base = s1.getSHA512Half();
for (int i = 0; i < mIterations; ++i)
{
// WRITEME
}
s1.erase();
nonce++;
}
return uint256();
}

View File

@@ -0,0 +1,66 @@
#ifndef PROOF_OF_WORK__H
#define PROOF_OF_WORK__H
#include <string>
#include <boost/thread/mutex.hpp>
#include <boost/bimap.hpp>
#include <boost/bimap/set_of.hpp>
#include <boost/bimap/multiset_of.hpp>
#include "uint256.h"
class ProofOfWork
{
protected:
std::string mToken;
uint256 mChallenge;
uint256 mTarget;
int mIterations;
static const uint256 sMinTarget;
static const int sMaxIterations;
public:
ProofOfWork(const std::string& token, int iterations, const uint256& challenge, const uint256& target) :
mToken(token), mChallenge(challenge), mTarget(target), mIterations(iterations)
{ ; }
bool isValid() const;
uint256 solve(int maxIterations) const;
bool checkSolution(const uint256& solution) const;
// approximate number of hashes needed to solve
static uint64 getDifficulty(const uint256& target, int iterations);
uint64 getDifficulty() const { return getDifficulty(mTarget, mIterations); }
};
class ProofOfWorkGenerator
{
public:
typedef boost::bimap< boost::bimaps::multiset_of<time_t>, boost::bimaps::set_of<uint256> > powMap_t;
typedef powMap_t::value_type powMap_vt;
protected:
uint256 mSecret;
int mIterations;
uint256 mTarget;
time_t mLastDifficultyChange;
powMap_t mSolvedChallenges;
boost::mutex mLock;
public:
ProofOfWorkGenerator(const uint256& secret);
ProofOfWork getProof();
bool checkProof(const std::string& token, const uint256& solution);
void loadHigh();
void loadLow();
uint64 getDifficulty() { return ProofOfWork::getDifficulty(mTarget, mIterations); }
};
#endif