More PoW work.

This commit is contained in:
JoelKatz
2012-11-19 01:06:23 -08:00
parent 366b477052
commit 645f7022c4
2 changed files with 107 additions and 9 deletions

View File

@@ -18,7 +18,10 @@ const int ProofOfWork::sMaxIterations(1 << 23);
bool ProofOfWork::isValid() const
{
return ((mIterations <= sMaxIterations) && (mTarget >= sMinTarget));
if ((mIterations <= sMaxIterations) && (mTarget >= sMinTarget))
return true;
cLog(lsWARNING) << "Invalid PoW: " << mIterations << ", " << mTarget;
return false;
}
uint64 ProofOfWork::getDifficulty(const uint256& target, int iterations)
@@ -33,7 +36,7 @@ uint64 ProofOfWork::getDifficulty(const uint256& target, int iterations)
}
// more iterations means more hashes per iteration but also a larger final hash
uint64 difficulty = iterations + (iterations / 4);
uint64 difficulty = iterations + (iterations / 8);
// Multiply the number of hashes needed by 256 for each leading zero byte in the difficulty
const unsigned char *ptr = target.begin();
@@ -70,7 +73,7 @@ uint256 ProofOfWork::solve(int maxIterations) const
while (maxIterations > 0)
{
buf1[1] = nonce;
buf1[2] = uint256();
buf1[2].zero();
for (int i = (mIterations - 1); i >= 0; --i)
{
buf1[2] = getSHA512Half(buf1);
@@ -149,7 +152,7 @@ POWResult ProofOfWorkGenerator::checkProof(const std::string& token, const uint2
if (fields[4] != Serializer::getSHA512Half(v).GetHex())
{
cLog(lsDEBUG) << "PoW " << token << " has a bad token";
return powBADTOKEN;
return powCORRUPT;
}
uint256 challenge, target;
@@ -178,6 +181,7 @@ POWResult ProofOfWorkGenerator::checkProof(const std::string& token, const uint2
{
boost::mutex::scoped_lock sl(mLock);
// if (...) return powTOOEASY;
if (!mSolvedChallenges.insert(powMap_vt(now, challenge)).second)
{
cLog(lsDEBUG) << "PoW " << token << " has been reused";
@@ -188,6 +192,77 @@ POWResult ProofOfWorkGenerator::checkProof(const std::string& token, const uint2
return powOK;
}
void ProofOfWorkGenerator::sweep()
{
time_t expire = time(NULL) - mValidTime;
boost::mutex::scoped_lock sl(mLock);
do
{
powMap_t::left_map::iterator it = mSolvedChallenges.left.begin();
if (it == mSolvedChallenges.left.end())
return;
if (it->first >= expire)
return;
mSolvedChallenges.left.erase(it);
} while(1);
}
struct PowEntry
{
const char *target;
int iterations;
};
PowEntry PowEntries[32] =
{
// FIXME: These targets are too low and iteration counts too low
// These get too difficulty before they become sufficently RAM intensive
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 256 }, // Hashes:5242880 KB=8
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 512 }, // Hashes:5242880 KB=16
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 512 }, // Hashes:10485760 KB=16
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 1024 }, // Hashes:10485760 KB=32
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 1024 }, // Hashes:20971520 KB=32
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 2048 }, // Hashes:20971520 KB=64
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 2048 }, // Hashes:41943040 KB=64
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 4096 }, // Hashes:41943040 KB=128
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 4096 }, // Hashes:83886080 KB=128
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 8192 }, // Hashes:83886080 KB=256
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 8192 }, // Hashes:167772160 KB=256
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16384 }, // Hashes:167772160 KB=512
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 32768 }, // Hashes:335544320 MB=1
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 32768 }, // Hashes:671088640 MB=1
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 65536 }, // Hashes:671088640 MB=2
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 65536 }, // Hashes:1342177280 MB=2
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 131072 }, // Hashes:1342177280 MB=4
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 131072 }, // Hashes:2684354560 MB=4
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 262144 }, // Hashes:2684354560 MB=8
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 524288 }, // Hashes:5368709120 MB=16
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 524288 }, // Hashes:10737418240 MB=16
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 1048576 }, // Hashes:10737418240 MB=32
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 1048576 }, // Hashes:21474836480 MB=32
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 2097152 }, // Hashes:21474836480 MB=64
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 2097152 }, // Hashes:42949672960 MB=64
{ "00007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 524288 }, // Hashes:85899345920 MB=16
{ "00003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 524288 }, // Hashes:171798691840 MB=16
{ "00007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 1048576 }, // Hashes:171798691840 MB=32
{ "00003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 1048576 }, // Hashes:343597383680 MB=32
{ "00007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 2097152 }, // Hashes:343597383680 MB=64
{ "00003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 2097152 }, // Hashes:687194767360 MB=64
};
void ProofOfWorkGenerator::setDifficulty(int i)
{
assert((i >= 0) && (i <= 31));
time_t now = time(NULL);
boost::mutex::scoped_lock sl(mLock);
mPowEntry = i;
mIterations = PowEntries[i].iterations;
mTarget.SetHex(PowEntries[i].target);
mLastDifficultyChange = now;
}
BOOST_AUTO_TEST_SUITE(ProofOfWork_suite)
BOOST_AUTO_TEST_CASE( ProofOfWork_test )
@@ -209,6 +284,27 @@ BOOST_AUTO_TEST_CASE( ProofOfWork_test )
cLog(lsDEBUG) << "A reused nonce error is expected";
if (gen.checkProof(pow.getToken(), solution) != powREUSED)
BOOST_FAIL("Reuse solution not detected");
#ifdef SOLVE_POWS
for (int i = 0; i < 12; ++i)
{
gen.setDifficulty(i);
ProofOfWork pow = gen.getProof();
cLog(lsINFO) << "Level: " << i << ", Estimated difficulty: " << pow.getDifficulty();
uint256 solution = pow.solve(131072);
if (solution.isZero())
cLog(lsINFO) << "Giving up";
else
{
cLog(lsINFO) << "Solution found";
if (gen.checkProof(pow.getToken(), solution) != powOK)
{
cLog(lsFATAL) << "Solution fails";
}
}
#endif
}
}
BOOST_AUTO_TEST_SUITE_END()

View File

@@ -13,11 +13,11 @@
enum POWResult
{
powOK = 0,
powREUSED = 1,
powBADNONCE = 2,
powBADTOKEN = 3,
powEXPIRED = 4,
powCORRUPT = 5,
powREUSED = 1, // already submitted
powBADNONCE = 2, // you didn't solve it
powEXPIRED = 3, // time is up
powCORRUPT = 4,
powTOOEASY = 5, // the difficulty increased too much while you solved it
};
class ProofOfWork
@@ -62,6 +62,7 @@ protected:
uint256 mTarget;
time_t mLastDifficultyChange;
int mValidTime;
int mPowEntry;
powMap_t mSolvedChallenges;
boost::mutex mLock;
@@ -72,6 +73,7 @@ public:
ProofOfWork getProof();
POWResult checkProof(const std::string& token, const uint256& solution);
uint64 getDifficulty() { return ProofOfWork::getDifficulty(mTarget, mIterations); }
void setDifficulty(int i);
void loadHigh();
void loadLow();