Rework the way PF API request validity is checked against the ledger.

This commit is contained in:
JoelKatz
2013-04-30 15:35:28 -07:00
parent dac85af5e3
commit 297f68f371
3 changed files with 49 additions and 10 deletions

View File

@@ -2,6 +2,8 @@
#include "NetworkOPs.h"
#include "RPCErr.h"
#include "Ledger.h"
#include "Application.h"
boost::recursive_mutex PFRequest::sLock;
std::set<PFRequest::wptr> PFRequest::sRequests;
@@ -15,11 +17,43 @@ PFRequest::PFRequest(const boost::shared_ptr<InfoSub>& subscriber) :
bool PFRequest::isValid()
{
boost::recursive_mutex::scoped_lock sl(mLock);
bValid = raSrcAccount.isSet() && raDstAccount.isSet() && saDstAmount.isPositive();
return bValid;
}
Json::Value PFRequest::doCreate(const Json::Value& value)
bool PFRequest::isValid(Ledger::ref lrLedger)
{
boost::recursive_mutex::scoped_lock sl(mLock);
bValid = raSrcAccount.isSet() && raDstAccount.isSet() && saDstAmount.isPositive();
if (bValid)
{
AccountState::pointer asSrc = theApp->getOPs().getAccountState(lrLedger, raSrcAccount);
if (!asSrc)
{ // no source account
bValid = false;
jvStatus = rpcError(rpcSRC_ACT_NOT_FOUND);
}
else
{
AccountState::pointer asDst = theApp->getOPs().getAccountState(lrLedger, raDstAccount);
if (!asDst)
{ // no destination account
if(!saDstAmount.isNative())
{ // only XRP can be send to a non-existent account
bValid = false;
jvStatus = rpcError(rpcACT_NOT_FOUND);
}
else if (saDstAmount < STAmount(lrLedger->getReserve(0)))
{ // payment must meet reserve
bValid = false;
jvStatus = rpcError(rpcDST_AMT_MALFORMED);
}
}
}
}
return bValid;
}
Json::Value PFRequest::doCreate(Ledger::ref lrLedger, const Json::Value& value)
{
Json::Value status;
bool mValid;
@@ -28,7 +62,7 @@ Json::Value PFRequest::doCreate(const Json::Value& value)
boost::recursive_mutex::scoped_lock sl(mLock);
parseJson(value, true);
status = jvStatus;
mValid = isValid();
mValid = isValid(lrLedger);
}
if (mValid)
@@ -75,7 +109,7 @@ int PFRequest::parseJson(const Json::Value& jvParams, bool complete)
if (jvParams.isMember("destination_amount"))
{
if (!saDstAmount.bSetJson(jvParams["destination_amount"]) ||
(saDstAmount.getCurrency().isZero() != saDstAmount.getIssuer().isZero()) ||
(saDstAmount.getCurrency().isZero() && saDstAmount.getIssuer().isNonZero()) ||
(saDstAmount.getCurrency() == CURRENCY_BAD))
{
jvStatus = rpcError(rpcDST_AMT_MALFORMED);
@@ -106,12 +140,16 @@ int PFRequest::parseJson(const Json::Value& jvParams, bool complete)
jvStatus = rpcError(rpcSRC_CUR_MALFORMED);
return PFR_PJ_INVALID;
}
if (jvCur.isMember("issuer"))
if (jvCur.isMember("issuer") && !STAmount::issuerFromString(uIss, jvCur["issuer"].asString()))
{
// parse issuer WRITEME
jvStatus = rpcError(rpcSRC_ISR_MALFORMED);
}
// sanity check WRITEME
// insert in set WRIEME
if (uCur.isZero() && uIss.isNonZero())
{
jvStatus = rpcError(rpcSRC_CUR_MALFORMED);
return PFR_PJ_INVALID;
}
sciSourceCurrencies.insert(currIssuer_t(uCur, uIss));
}
}

View File

@@ -61,10 +61,11 @@ public:
PFRequest(const boost::shared_ptr<InfoSub>& subscriber);
bool isValid(const boost::shared_ptr<Ledger>&);
bool isValid();
Json::Value getStatus();
Json::Value doCreate(const Json::Value&);
Json::Value doCreate(const boost::shared_ptr<Ledger>&, const Json::Value&);
Json::Value doClose(const Json::Value&);
Json::Value doStatus(const Json::Value&);

View File

@@ -1177,7 +1177,7 @@ Json::Value RPCHandler::doPathFind(Json::Value jvRequest, int& cost, ScopedLock&
{
mInfoSub->clearPFRequest();
PFRequest::pointer request = boost::make_shared<PFRequest>(mInfoSub);
Json::Value result = request->doCreate(jvRequest);
Json::Value result = request->doCreate(mNetOps->getCurrentLedger(), jvRequest);
if (request->isValid())
mInfoSub->setPFRequest(request);
return result;