diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index 86e5f1537..4160dfea8 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -482,6 +482,16 @@ Json::Value RPCParser::parseProofCreate(const Json::Value& jvParams) return jvRequest; } +// proof_solve +Json::Value RPCParser::parseProofSolve(const Json::Value& jvParams) +{ + Json::Value jvRequest; + + jvRequest["token"] = jvParams[0u].asString(); + + return jvRequest; +} + // proof_verify Json::Value RPCParser::parseProofVerify(const Json::Value& jvParams) { @@ -721,6 +731,7 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) { "ping", &RPCParser::parseAsIs, 0, 0 }, // { "profile", &RPCParser::parseProfile, 1, 9 }, { "proof_create", &RPCParser::parseProofCreate, 0, 1 }, + { "proof_solve", &RPCParser::parseProofSolve, 1, 1 }, { "proof_verify", &RPCParser::parseProofVerify, 2, 2 }, { "random", &RPCParser::parseAsIs, 0, 0 }, { "ripple_path_find", &RPCParser::parseRipplePathFind, 1, 2 }, diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index a07ea4043..01920c19e 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -35,6 +35,7 @@ protected: Json::Value parseLogLevel(const Json::Value& jvParams); Json::Value parseOwnerInfo(const Json::Value& jvParams); Json::Value parseProofCreate(const Json::Value& jvParams); + Json::Value parseProofSolve(const Json::Value& jvParams); Json::Value parseProofVerify(const Json::Value& jvParams); Json::Value parseRandom(const Json::Value& jvParams); Json::Value parseRipplePathFind(const Json::Value& jvParams); diff --git a/src/cpp/ripple/ProofOfWork.cpp b/src/cpp/ripple/ProofOfWork.cpp index 16d0f3cf1..b38a23ab9 100644 --- a/src/cpp/ripple/ProofOfWork.cpp +++ b/src/cpp/ripple/ProofOfWork.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -48,6 +49,19 @@ const uint256 ProofOfWork::sMinTarget("00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF const int ProofOfWork::sMaxIterations(1 << 23); const int ProofOfWork::sMaxDifficulty(30); +ProofOfWork::ProofOfWork(const std::string& token) +{ + std::vector fields; + boost::split(fields, token, boost::algorithm::is_any_of("-")); + if (fields.size() != 5) + throw std::runtime_error("invalid token"); + + mToken = token; + mChallenge.SetHex(fields[0]); + mTarget.SetHex(fields[1]); + mIterations = lexical_cast_s(fields[2]); +} + bool ProofOfWork::isValid() const { if ((mIterations <= sMaxIterations) && (mTarget >= sMinTarget)) @@ -141,6 +155,14 @@ bool ProofOfWork::checkSolution(const uint256& solution) const return getSHA512Half(buf2) <= mTarget; } +bool ProofOfWork::validateToken(const std::string& strToken) +{ + static boost::regex reToken("[[:xdigit:]]{64}-[[:xdigit:]]{64}-[[:digit:]]+-[[:digit:]]+-[[:xdigit:]]{64}"); + boost::smatch smMatch; + + return boost::regex_match(strToken, smMatch, reToken); +} + ProofOfWorkGenerator::ProofOfWorkGenerator() : mValidTime(180) { setDifficulty(1); diff --git a/src/cpp/ripple/ProofOfWork.h b/src/cpp/ripple/ProofOfWork.h index f7e0f78ae..1e29ada1d 100644 --- a/src/cpp/ripple/ProofOfWork.h +++ b/src/cpp/ripple/ProofOfWork.h @@ -43,6 +43,8 @@ public: mToken(token), mChallenge(challenge), mTarget(target), mIterations(iterations) { ; } + ProofOfWork(const std::string& token); + bool isValid() const; uint256 solve(int maxIterations = 2 * sMaxIterations) const; @@ -54,6 +56,8 @@ public: // approximate number of hashes needed to solve static uint64 getDifficulty(const uint256& target, int iterations); uint64 getDifficulty() const { return getDifficulty(mTarget, mIterations); } + + static bool validateToken(const std::string& strToken); }; class ProofOfWorkGenerator diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 3d89ad89c..e39c85c3f 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -910,6 +910,29 @@ Json::Value RPCHandler::doProofCreate(Json::Value jvRequest, int& cost, ScopedLo return jvResult; } +// { +// token: +// } +Json::Value RPCHandler::doProofSolve(Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +{ + Json::Value jvResult; + + if (!jvRequest.isMember("token")) + return rpcError(rpcINVALID_PARAMS); + + std::string strToken = jvRequest["token"].asString(); + + if (!ProofOfWork::validateToken(strToken)) + return rpcError(rpcINVALID_PARAMS); + + ProofOfWork powProof(strToken); + uint256 uSolution = powProof.solve(); + + jvResult["solution"] = uSolution.GetHex(); + + return jvResult; +} + // { // token: @@ -3412,6 +3435,7 @@ Json::Value RPCHandler::doCommand(const Json::Value& jvRequest, int iRole, int & { "ping", &RPCHandler::doPing, false, optNone }, // { "profile", &RPCHandler::doProfile, false, optCurrent }, { "proof_create", &RPCHandler::doProofCreate, false, optNone }, + { "proof_solve", &RPCHandler::doProofSolve, true, optNone }, { "proof_verify", &RPCHandler::doProofVerify, true, optNone }, { "random", &RPCHandler::doRandom, false, optNone }, { "ripple_path_find", &RPCHandler::doRipplePathFind, false, optCurrent }, diff --git a/src/cpp/ripple/RPCHandler.h b/src/cpp/ripple/RPCHandler.h index 41ceed624..ba9c17151 100644 --- a/src/cpp/ripple/RPCHandler.h +++ b/src/cpp/ripple/RPCHandler.h @@ -73,6 +73,7 @@ class RPCHandler Json::Value doPing(Json::Value params, int& cost, ScopedLock& mlh); Json::Value doProfile(Json::Value params, int& cost, ScopedLock& mlh); Json::Value doProofCreate(Json::Value params, int& cost, ScopedLock& mlh); + Json::Value doProofSolve(Json::Value params, int& cost, ScopedLock& mlh); Json::Value doProofVerify(Json::Value params, int& cost, ScopedLock& mlh); Json::Value doRandom(Json::Value jvRequest, int& cost, ScopedLock& mlh); Json::Value doRipplePathFind(Json::Value jvRequest, int& cost, ScopedLock& mlh);