diff --git a/src/cpp/ripple/Peer.cpp b/src/cpp/ripple/Peer.cpp index f7319f5d3..b35af8d0e 100644 --- a/src/cpp/ripple/Peer.cpp +++ b/src/cpp/ripple/Peer.cpp @@ -1146,7 +1146,27 @@ void Peer::recvProofWork(ripple::TMProofWork& packet) if (packet.has_target() && packet.has_challenge() && packet.has_iterations()) { // this is a challenge - // WRITEME + // WRITEME: Reject from inbound connections + + uint256 challenge, target; + if ((packet.challenge().size() != (256 / 8)) || (packet.target().size() != (256 / 8))) + { + punishPeer(PP_INVALID_REQUEST); + return; + } + memcpy(challenge.begin(), packet.challenge().data(), 256 / 8); + memcpy(target.begin(), packet.target().data(), 256 / 8); + ProofOfWork::pointer pow = boost::make_shared(packet.token(), packet.iterations(), + challenge, target); + if (!pow->isValid()) + { + punishPeer(PP_INVALID_REQUEST); + return; + } + + theApp->getJobQueue().addJob(jtPROOFWORK, + boost::bind(&Peer::doProofOfWork, _1, boost::weak_ptr(shared_from_this()), pow)); + return; } @@ -1587,6 +1607,33 @@ void Peer::punishPeer(PeerPunish) { } +void Peer::doProofOfWork(Job&, boost::weak_ptr peer, ProofOfWork::pointer pow) +{ + if (peer.expired()) + return; + + uint256 solution = pow->solve(); + if (solution.isZero()) + { + cLog(lsWARNING) << "Failed to solve proof of work"; + } + else + { + Peer::pointer pptr(peer.lock()); + if (pptr) + { + ripple::TMProofWork reply; + reply.set_token(pow->getToken()); + reply.set_response(solution.begin(), solution.size()); + pptr->sendPacket(boost::make_shared(reply, ripple::mtPROOFOFWORK)); + } + else + { + // WRITEME: Save solved proof of work for new connection + } + } +} + Json::Value Peer::getJson() { Json::Value ret(Json::objectValue); diff --git a/src/cpp/ripple/Peer.h b/src/cpp/ripple/Peer.h index c1883027f..df1dceee3 100644 --- a/src/cpp/ripple/Peer.h +++ b/src/cpp/ripple/Peer.h @@ -13,6 +13,8 @@ #include "Ledger.h" #include "Transaction.h" #include "InstanceCounter.h" +#include "JobQueue.h" +#include "ProofOfWork.h" enum PeerPunish { @@ -116,6 +118,8 @@ protected: void addLedger(const uint256& ledger); void addTxSet(const uint256& TxSet); + static void doProofOfWork(Job&, boost::weak_ptr, ProofOfWork::pointer); + public: //bool operator == (const Peer& other); diff --git a/src/cpp/ripple/ProofOfWork.h b/src/cpp/ripple/ProofOfWork.h index 7c77f8659..0e1409c05 100644 --- a/src/cpp/ripple/ProofOfWork.h +++ b/src/cpp/ripple/ProofOfWork.h @@ -33,13 +33,15 @@ protected: static const int sMaxIterations; public: + typedef boost::shared_ptr pointer; + 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; + uint256 solve(int maxIterations = 2 * sMaxIterations) const; bool checkSolution(const uint256& solution) const; const std::string& getToken() const { return mToken; }