diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index 268cda5725..f28eb397f1 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -471,6 +471,17 @@ Json::Value RPCParser::parseAccountRaw(const Json::Value& jvParams, bool bPeer) return jvRequest; } +// proof_create [] +Json::Value RPCParser::parseProofCreate(const Json::Value& jvParams) +{ + Json::Value jvRequest; + + if (1 == jvParams.size()) + jvRequest["difficulty"] = jvParams[0u].asInt(); + + return jvRequest; +} + // ripple_path_find [] Json::Value RPCParser::parseRipplePathFind(const Json::Value& jvParams) { @@ -698,6 +709,7 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) { "peers", &RPCParser::parseAsIs, 0, 0 }, { "ping", &RPCParser::parseAsIs, 0, 0 }, // { "profile", &RPCParser::parseProfile, 1, 9 }, + { "proof_create", &RPCParser::parseProofCreate, 0, 1 }, { "random", &RPCParser::parseAsIs, 0, 0 }, { "ripple_path_find", &RPCParser::parseRipplePathFind, 1, 2 }, { "sign", &RPCParser::parseSignSubmit, 2, 2 }, diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index ac726afdf9..6fa8f27252 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -34,6 +34,7 @@ protected: #endif Json::Value parseLogLevel(const Json::Value& jvParams); Json::Value parseOwnerInfo(const Json::Value& jvParams); + Json::Value parseProofCreate(const Json::Value& jvParams); Json::Value parseRandom(const Json::Value& jvParams); Json::Value parseRipplePathFind(const Json::Value& jvParams); Json::Value parseSMS(const Json::Value& jvParams); diff --git a/src/cpp/ripple/ProofOfWork.cpp b/src/cpp/ripple/ProofOfWork.cpp index 7ec6a8ef91..2036a66f67 100644 --- a/src/cpp/ripple/ProofOfWork.cpp +++ b/src/cpp/ripple/ProofOfWork.cpp @@ -15,6 +15,7 @@ SETUP_LOG(); const uint256 ProofOfWork::sMinTarget("00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); const int ProofOfWork::sMaxIterations(1 << 23); +const int ProofOfWork::sMaxDifficulty(30); bool ProofOfWork::isValid() const { @@ -243,7 +244,7 @@ struct PowEntry int iterations; }; -PowEntry PowEntries[31] = +PowEntry PowEntries[ProofOfWork::sMaxDifficulty + 1] = { // target iterations hashes memory { "0CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 65536 }, // 1451874, 2 MB { "0CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 98304 }, // 2177811, 3 MB @@ -300,7 +301,7 @@ int ProofOfWorkGenerator::getPowEntry(const uint256& target, int iterations) void ProofOfWorkGenerator::setDifficulty(int i) { - assert((i >= 0) && (i <= 30)); + assert((i >= 0) && (i <= ProofOfWork::sMaxDifficulty)); time_t now = time(NULL); boost::mutex::scoped_lock sl(mLock); diff --git a/src/cpp/ripple/ProofOfWork.h b/src/cpp/ripple/ProofOfWork.h index 0e1409c05b..1133a4c29f 100644 --- a/src/cpp/ripple/ProofOfWork.h +++ b/src/cpp/ripple/ProofOfWork.h @@ -20,6 +20,7 @@ enum POWResult powTOOEASY = 5, // the difficulty increased too much while you solved it }; + class ProofOfWork { protected: @@ -33,6 +34,8 @@ protected: static const int sMaxIterations; public: + static const int sMaxDifficulty; + typedef boost::shared_ptr pointer; ProofOfWork(const std::string& token, int iterations, const uint256& challenge, const uint256& target) : @@ -81,6 +84,8 @@ public: void loadLow(); void sweep(void); + const uint256& getSecret() const { return mSecret; } + static int getPowEntry(const uint256& target, int iterations); }; diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index f3aa3aee94..cab60568c8 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -23,6 +23,7 @@ #include "InstanceCounter.h" #include "Offer.h" #include "PFRequest.h" +#include "ProofOfWork.h" SETUP_LOG(); @@ -877,6 +878,38 @@ Json::Value RPCHandler::doProfile(Json::Value jvRequest, int& cost, ScopedLock& return obj; } +// { +// difficulty: // optional, if set, a temporary generator is +// // instantiated and its secret included +// } +Json::Value RPCHandler::doProofCreate(Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +{ + // XXX: Add ability to create proof with arbitrary secret and time + + Json::Value jvResult(Json::objectValue); + + if (jvRequest.isMember("difficulty")) + { + if (!jvRequest["difficulty"].isIntegral()) + return rpcError(rpcINVALID_PARAMS); + + int iDifficulty = jvRequest["difficulty"].asInt(); + + if (iDifficulty < 0 || iDifficulty > ProofOfWork::sMaxDifficulty) + return rpcError(rpcINVALID_PARAMS); + + ProofOfWorkGenerator pgGen; + pgGen.setDifficulty(iDifficulty); + + jvResult["token"] = pgGen.getProof().getToken(); + jvResult["secret"] = pgGen.getSecret().GetHex(); + } else { + jvResult["token"] = theApp->getPowGen().getProof().getToken(); + } + + return jvResult; +} + // { // account: || // account_index: // optional, defaults to 0. @@ -3343,6 +3376,7 @@ Json::Value RPCHandler::doCommand(const Json::Value& jvRequest, int iRole, int & { "path_find", &RPCHandler::doPathFind, false, optCurrent }, { "ping", &RPCHandler::doPing, false, optNone }, // { "profile", &RPCHandler::doProfile, false, optCurrent }, + { "proof_create", &RPCHandler::doProofCreate, false, optNone }, { "random", &RPCHandler::doRandom, false, optNone }, { "ripple_path_find", &RPCHandler::doRipplePathFind, false, optCurrent }, { "sign", &RPCHandler::doSign, false, optCurrent }, diff --git a/src/cpp/ripple/RPCHandler.h b/src/cpp/ripple/RPCHandler.h index f5b73c39be..d90610f919 100644 --- a/src/cpp/ripple/RPCHandler.h +++ b/src/cpp/ripple/RPCHandler.h @@ -72,6 +72,7 @@ class RPCHandler Json::Value doPathFind(Json::Value params, int& cost, ScopedLock& mlh); 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 doRandom(Json::Value jvRequest, int& cost, ScopedLock& mlh); Json::Value doRipplePathFind(Json::Value jvRequest, int& cost, ScopedLock& mlh); Json::Value doServerInfo(Json::Value params, int& cost, ScopedLock& mlh); // for humans