Cleanups to RPC code

This commit is contained in:
Tom Ritchford
2014-08-03 18:42:00 -04:00
committed by Nik Bougalis
parent 4c7fd18230
commit 22ca13bc78
35 changed files with 402 additions and 477 deletions

View File

@@ -2725,6 +2725,9 @@
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\rpc\handlers\Handlers.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\rpc\handlers\Internal.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\module\rpc\handlers\Ledger.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -2773,9 +2776,6 @@
<ClCompile Include="..\..\src\ripple\module\rpc\handlers\Print.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\module\rpc\handlers\Profile.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\module\rpc\handlers\ProofCreate.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -2921,6 +2921,8 @@
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\rpc\impl\TransactionSign.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\module\rpc\InternalHandler.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\module\rpc\Manager.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\module\rpc\Request.h">

View File

@@ -3888,6 +3888,9 @@
<ClInclude Include="..\..\src\ripple\module\rpc\handlers\Handlers.h">
<Filter>ripple\module\rpc\handlers</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\rpc\handlers\Internal.cpp">
<Filter>ripple\module\rpc\handlers</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\module\rpc\handlers\Ledger.cpp">
<Filter>ripple\module\rpc\handlers</Filter>
</ClCompile>
@@ -3936,9 +3939,6 @@
<ClCompile Include="..\..\src\ripple\module\rpc\handlers\Print.cpp">
<Filter>ripple\module\rpc\handlers</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\module\rpc\handlers\Profile.cpp">
<Filter>ripple\module\rpc\handlers</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\module\rpc\handlers\ProofCreate.cpp">
<Filter>ripple\module\rpc\handlers</Filter>
</ClCompile>
@@ -4095,6 +4095,9 @@
<ClInclude Include="..\..\src\ripple\module\rpc\impl\TransactionSign.h">
<Filter>ripple\module\rpc\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\module\rpc\InternalHandler.h">
<Filter>ripple\module\rpc</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\module\rpc\Manager.h">
<Filter>ripple\module\rpc</Filter>
</ClInclude>

View File

@@ -58,8 +58,8 @@ public:
{
m_context.reset (RippleSSLContext::createAuthenticated (
getConfig ().RPC_SSL_KEY,
getConfig ().RPC_SSL_CERT,
getConfig ().RPC_SSL_CHAIN));
getConfig ().RPC_SSL_CERT,
getConfig ().RPC_SSL_CHAIN));
}
}
@@ -74,7 +74,7 @@ public:
if (! getConfig ().getRpcIP().empty () &&
getConfig ().getRpcPort() != 0)
{
beast::IP::Endpoint ep (beast::IP::Endpoint::from_string (getConfig().getRpcIP()));
auto ep = beast::IP::Endpoint::from_string (getConfig().getRpcIP());
// VFALCO TODO IP address should not have an "unspecified" state
//if (! is_unspecified (ep))
@@ -143,18 +143,11 @@ public:
return;
}
#if 0
// Synchronous version that doesn't use job queue
Job job;
processSession (job, session);
#else
session.detach();
m_jobQueue.addJob (jtCLIENT, "RPC-Client", std::bind (
&RPCHTTPServerImp::processSession, this, std::placeholders::_1,
std::ref (session)));
#endif
}
void
@@ -174,15 +167,9 @@ public:
// Dispatched on the job queue
void processSession (Job& job, HTTP::Session& session)
{
#if 0
// Goes through the old code
session.write (m_deprecatedHandler.processRequest (
session.content(), session.remoteAddress().at_port(0)));
#else
auto const s (to_string(session.message().body));
session.write (processRequest (to_string(session.message().body),
session.remoteAddress().at_port(0)));
#endif
if (session.message().keep_alive())
{
@@ -219,7 +206,7 @@ public:
}
}
Config::Role const role (getConfig ().getAdminRole (jvRequest, remoteIPAddress));
auto const role = getConfig ().getAdminRole (jvRequest, remoteIPAddress);
Resource::Consumer usage;
@@ -233,34 +220,30 @@ public:
// Parse id now so errors from here on will have the id
//
// VFALCO NOTE Except that "id" isn't included in the following errors...
// VFALCO NOTE Except that "id" isn't included in the following errors.
//
Json::Value const id = jvRequest ["id"];
Json::Value const method = jvRequest ["method"];
if (method.isNull ())
{
return createResponse (400, "Null method");
}
else if (! method.isString ())
{
if (! method.isString ())
return createResponse (400, "method is not string");
}
std::string strMethod = method.asString ();
if (strMethod.empty())
return createResponse (400, "method is empty");
// Parse params
Json::Value params = jvRequest ["params"];
if (params.isNull ())
{
params = Json::Value (Json::arrayValue);
}
else if (!params.isArray ())
{
return HTTPReply (400, "params unparseable");
}
// VFALCO TODO Shouldn't we handle this earlier?
//
@@ -272,20 +255,19 @@ public:
return HTTPReply (403, "Forbidden");
}
std::string response;
RPCHandler rpcHandler (m_networkOPs);
Resource::Charge loadType = Resource::feeReferenceRPC;
m_journal.debug << "Query: " << strMethod << params;
RPCHandler rpcHandler (m_networkOPs);
Resource::Charge loadType = Resource::feeReferenceRPC;
Json::Value const result (rpcHandler.doRpcCommand (
strMethod, params, role, loadType));
m_journal.debug << "Reply: " << result;
usage.charge (loadType);
m_journal.debug << "Reply: " << result;
response = JSONRPCReply (result, Json::Value (), id);
@@ -314,9 +296,12 @@ RPCHTTPServer::RPCHTTPServer (Stoppable& parent)
//------------------------------------------------------------------------------
std::unique_ptr <RPCHTTPServer>
make_RPCHTTPServer (beast::Stoppable& parent, beast::Journal journal,
JobQueue& jobQueue, NetworkOPs& networkOPs,
Resource::Manager& resourceManager)
make_RPCHTTPServer (
beast::Stoppable& parent,
beast::Journal journal,
JobQueue& jobQueue,
NetworkOPs& networkOPs,
Resource::Manager& resourceManager)
{
return std::make_unique <RPCHTTPServerImp> (
parent, journal, jobQueue, networkOPs, resourceManager);

View File

@@ -0,0 +1,50 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_APP_RPC_INTERNAL_HANDLER
#define RIPPLE_APP_RPC_INTERNAL_HANDLER
namespace ripple {
namespace RPC {
/** To dynamically add custom or experimental RPC handlers, construct a new
* instance of InternalHandler with your own handler function. */
struct InternalHandler
{
typedef Json::Value (*handler_t) (const Json::Value&);
InternalHandler (const std::string& name, handler_t handler)
: name_ (name),
handler_ (handler)
{
nextHandler_ = InternalHandler::headHandler;
InternalHandler::headHandler = this;
}
InternalHandler* nextHandler_;
std::string name_;
handler_t handler_;
static InternalHandler* headHandler;
};
} // RPC
} // ripple
#endif

View File

@@ -34,7 +34,6 @@ public:
virtual ~Manager () = 0;
/** Add a handler for the specified JSON-RPC command. */
/** @{ */
template <class Handler>
void add (std::string const& method)
{
@@ -47,17 +46,16 @@ public:
}
virtual void add (std::string const& method, handler_type&& handler) = 0;
/** @} */
/** Dispatch the JSON-RPC request.
@return `true` If the command was found.
@return `true` if the command was found.
*/
virtual bool dispatch (Request& req) = 0;
};
std::unique_ptr <Manager> make_Manager (beast::Journal journal);
}
}
} // RPC
} // ripple
#endif

View File

@@ -32,52 +32,31 @@
namespace ripple {
// used by the RPCServer or WSDoor to carry out these RPC commands
class NetworkOPs;
class InfoSub;
class NetworkOPs;
class RPCHandler
{
public:
explicit RPCHandler (NetworkOPs& netOps);
RPCHandler (NetworkOPs& netOps, InfoSub::pointer infoSub);
explicit RPCHandler (
NetworkOPs& netOps, InfoSub::pointer infoSub = nullptr);
Json::Value doCommand (
Json::Value const& jvRequest, Config::Role role,
Json::Value const& request,
Config::Role role,
Resource::Charge& loadType);
Json::Value doRpcCommand (
std::string const& strCommand, Json::Value const& jvParams,
Config::Role iRole, Resource::Charge& loadType);
// Utilities
std::string const& command,
Json::Value const& params,
Config::Role role,
Resource::Charge& loadType);
private:
NetworkOPs* mNetOps;
InfoSub::pointer mInfoSub;
NetworkOPs& netOps_;
InfoSub::pointer infoSub_;
Config::Role mRole;
};
class RPCInternalHandler
{
public:
typedef Json::Value (*handler_t) (Json::Value const&);
public:
RPCInternalHandler (std::string const& name, handler_t handler);
static Json::Value runHandler (
std::string const& name, Json::Value const& params);
private:
// VFALCO TODO Replace with a singleton with a well defined interface and
// a lock free stack (if necessary).
//
static RPCInternalHandler* sHeadHandler;
RPCInternalHandler* mNextHandler;
std::string mName;
handler_t mHandler;
Config::Role role_ = Config::FORBID;
};
} // ripple

View File

@@ -29,14 +29,14 @@ class NetworkOPs;
class RPCServerHandler : public RPCServer::Handler
{
public:
explicit RPCServerHandler (NetworkOPs& networkOPs, Resource::Manager& resourceManager);
RPCServerHandler (NetworkOPs&, Resource::Manager&);
std::string createResponse (int statusCode, std::string const& description);
bool isAuthorized (std::map <std::string, std::string> const& headers);
std::string processRequest (std::string const& request,
beast::IP::Endpoint const& remoteIPAddress);
std::string processRequest (
std::string const& request,
beast::IP::Endpoint const& remoteIPAddress);
private:
NetworkOPs& m_networkOPs;

View File

@@ -23,18 +23,19 @@
#include <ripple/unity/json.h>
#include <ripple/unity/resource.h>
namespace ripple {
class Application; // forward declare
class Application;
namespace RPC {
struct Request
{
explicit Request (beast::Journal journal_,
std::string const& method_, Json::Value& params_,
Application& app_)
explicit Request (
beast::Journal journal_,
std::string const& method_,
Json::Value& params_,
Application& app_)
: journal (journal_)
, method (method_)
, params (params_)

View File

@@ -28,8 +28,7 @@ const int MAX_PATHFINDS_IN_PROGRESS = 2;
const int MAX_PATHFIND_JOB_COUNT = 50;
const int MAX_JOB_QUEUE_CLIENTS = 500;
const int MAX_VALIDATED_LEDGER_AGE = 120;
// TODO(tom): Shouldn't DEFAULT_AUTO_FILL_FEE_MULTIPLIER be floating point?
const int MAX_REQUEST_SIZE = 1000000;
} // RPC
} // ripple

View File

@@ -22,10 +22,13 @@ namespace ripple {
// {
// account: <indent>,
// account_index : <index> // optional
// strict: <bool> // true, only allow public keys and addresses. false, default.
// strict: <bool>
// if true, only allow public keys and addresses. false, default.
// ledger_hash : <ledger>
// ledger_index : <ledger_index>
// }
// TODO(tom): what is that "default"?
Json::Value doAccountInfo (RPC::Context& context)
{
auto& params = context.params_;

View File

@@ -85,22 +85,22 @@ Json::Value doAccountLines (RPC::Context& context)
if (!raPeer.isValid () ||
raPeer.getAccountID () == line->getAccountIDPeer ())
{
STAmount const& saBalance = line->getBalance ();
STAmount const& saLimit = line->getLimit ();
STAmount const& saLimitPeer = line->getLimitPeer ();
STAmount const& saBalance = line->getBalance ();
STAmount const& saLimit = line->getLimit ();
STAmount const& saLimitPeer = line->getLimitPeer ();
Json::Value& jPeer = jsonLines.append (Json::objectValue);
Json::Value& jPeer = jsonLines.append (Json::objectValue);
jPeer[jss::account] = to_string (line->getAccountIDPeer ());
jPeer[jss::account] = to_string (line->getAccountIDPeer ());
// Amount reported is positive if current account holds other
// account's IOUs.
//
// Amount reported is negative if other account holds current
// account's IOUs.
jPeer[jss::balance] = saBalance.getText ();
jPeer[jss::currency] = saBalance.getHumanCurrency ();
jPeer[jss::limit] = saLimit.getText ();
jPeer[jss::limit_peer] = saLimitPeer.getText ();
jPeer[jss::balance] = saBalance.getText ();
jPeer[jss::currency] = saBalance.getHumanCurrency ();
jPeer[jss::limit] = saLimit.getText ();
jPeer[jss::limit_peer] = saLimitPeer.getText ();
jPeer[jss::quality_in]
= static_cast<Json::UInt> (line->getQualityIn ());
jPeer[jss::quality_out]

View File

@@ -73,10 +73,11 @@ Json::Value doAccountOffers (RPC::Context& context)
return rpcError (rpcACT_NOT_FOUND);
Json::Value& jvsOffers = (result[jss::offers] = Json::arrayValue);
ledger->visitAccountItems (raAccount.getAccountID (),
std::bind (&offerAdder, std::ref (jvsOffers),
std::placeholders::_1));
auto adder = std::bind (
&offerAdder,
std::ref (jvsOffers),
std::placeholders::_1);
ledger->visitAccountItems (raAccount.getAccountID (), adder);
context.loadType_ = Resource::feeMediumBurdenRPC;
return result;

View File

@@ -53,7 +53,6 @@ Json::Value doPathFind (RPC::Context&);
Json::Value doPeers (RPC::Context&);
Json::Value doPing (RPC::Context&);
Json::Value doPrint (RPC::Context&);
Json::Value doProfile (RPC::Context&);
Json::Value doProofCreate (RPC::Context&);
Json::Value doProofSolve (RPC::Context&);
Json::Value doProofVerify (RPC::Context&);

View File

@@ -0,0 +1,53 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012-2014 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/module/rpc/InternalHandler.h>
namespace ripple {
RPC::InternalHandler* RPC::InternalHandler::headHandler = nullptr;
Json::Value doInternal (RPC::Context& context)
{
// Used for debug or special-purpose RPC commands
if (!context.params_.isMember ("internal_command"))
return rpcError (rpcINVALID_PARAMS);
auto name = context.params_["internal_command"].asString ();
auto params = context.params_["params"];
for (auto* h = RPC::InternalHandler::headHandler; h; )
{
if (name == h->name_)
{
WriteLog (lsWARNING, RPCHandler)
<< "Internal command " << name << ": " << params;
Json::Value ret = h->handler_ (params);
WriteLog (lsWARNING, RPCHandler)
<< "Internal command returns: " << ret;
return ret;
}
h = h->nextHandler_;
}
return rpcError (rpcBAD_SYNTAX);
}
} // ripple

View File

@@ -27,7 +27,7 @@ Json::Value doLedgerAccept (RPC::Context& context)
if (!getConfig ().RUN_STANDALONE)
{
jvResult["error"] = "notStandAlone";
jvResult["error"] = "notStandAlone";
}
else
{

View File

@@ -22,13 +22,11 @@ namespace ripple {
Json::Value doLedgerClosed (RPC::Context& context)
{
Json::Value jvResult;
uint256 uLedger = context.netOps_.getClosedLedgerHash ();
jvResult["ledger_index"] = context.netOps_.getLedgerID (uLedger);
jvResult["ledger_hash"] = to_string (uLedger);
//jvResult["ledger_time"] = uLedger.
Json::Value jvResult;
jvResult["ledger_index"] = context.netOps_.getLedgerID (uLedger);
jvResult["ledger_hash"] = to_string (uLedger);
return jvResult;
}

View File

@@ -23,9 +23,7 @@ namespace ripple {
Json::Value doLedgerCurrent (RPC::Context& context)
{
Json::Value jvResult;
jvResult["ledger_current_index"] = context.netOps_.getCurrentLedgerID ();
jvResult["ledger_current_index"] = context.netOps_.getCurrentLedgerID ();
return jvResult;
}

View File

@@ -24,12 +24,14 @@ namespace ripple {
// 'ident' : <indent>,
// 'account_index' : <index> // optional
// }
// XXX This would be better if it took the ledger.
Json::Value doOwnerInfo (RPC::Context& context)
{
auto lock = getApp().masterLock();
if (!context.params_.isMember ("account") && !context.params_.isMember ("ident"))
if (!context.params_.isMember ("account") &&
!context.params_.isMember ("ident"))
{
return RPC::missing_field_error ("account");
}
std::string strIdent = context.params_.isMember ("account")
? context.params_["account"].asString ()
@@ -38,25 +40,35 @@ Json::Value doOwnerInfo (RPC::Context& context)
int iIndex = context.params_.isMember ("account_index")
? context.params_["account_index"].asUInt () : 0;
RippleAddress raAccount;
Json::Value ret;
// Get info on account.
auto const& closedLedger = context.netOps_.getClosedLedger ();
Json::Value jAccepted = RPC::accountFromString (
context.netOps_.getClosedLedger (), raAccount, bIndex, strIdent, iIndex,
false, context.netOps_);
closedLedger,
raAccount,
bIndex,
strIdent,
iIndex,
false,
context.netOps_);
ret["accepted"] = jAccepted.empty ()
? context.netOps_.getOwnerInfo (
context.netOps_.getClosedLedger (), raAccount) : jAccepted;
ret["accepted"] = jAccepted.empty () ? context.netOps_.getOwnerInfo (
closedLedger, raAccount) : jAccepted;
auto const& currentLedger = context.netOps_.getCurrentLedger ();
Json::Value jCurrent = RPC::accountFromString (
context.netOps_.getCurrentLedger (), raAccount, bIndex, strIdent, iIndex,
false, context.netOps_);
currentLedger,
raAccount,
bIndex,
strIdent,
iIndex,
false,
context.netOps_);
ret["current"] = jCurrent.empty () ? context.netOps_.getOwnerInfo (
context.netOps_.getCurrentLedger (), raAccount) : jCurrent;
currentLedger, raAccount) : jCurrent;
return ret;
}

View File

@@ -29,7 +29,7 @@ Json::Value doPeers (RPC::Context& context)
{
auto lock = getApp().masterLock();
jvResult["peers"] = getApp().overlay ().json ();
jvResult["peers"] = getApp().overlay ().json ();
getApp().getUNL().addClusterStatus(jvResult);
}

View File

@@ -1,120 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012-2014 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace ripple {
// profile offers <pass_a> <account_a> <currency_offer_a> <account_b>
// <currency_offer_b> <count> [submit]
//
// profile 0:offers 1:pass_a 2:account_a 3:currency_offer_a 4:account_b
// 5:currency_offer_b 6:<count> 7:[submit]
//
// issuer is the offering account
//
// --> submit: 'submit|true|false': defaults to false
//
// Prior to running allow each to have a credit line of what they will be
// getting from the other account.
Json::Value doProfile (RPC::Context& context)
{
/* need to fix now that sharedOfferCreate is gone
int iArgs = context.params_.size();
RippleAddress naSeedA;
RippleAddress naAccountA;
Currency uCurrencyOfferA;
RippleAddress naSeedB;
RippleAddress naAccountB;
Currency uCurrencyOfferB;
uint32 iCount = 100;
bool bSubmit = false;
if (iArgs < 6 || "offers" != context.params_[0u].asString())
{
return rpcError(rpcINVALID_PARAMS);
}
if (!naSeedA.setSeedGeneric(context.params_[1u].asString())) // <pass_a>
return rpcError(rpcINVALID_PARAMS);
naAccountA.setAccountID(context.params_[2u].asString()); // <account_a>
if (!to_currency(uCurrencyOfferA, context.params_[3u].asString())) // <currency_offer_a>
return rpcError(rpcINVALID_PARAMS);
naAccountB.setAccountID(context.params_[4u].asString()); // <account_b>
if (!to_currency(uCurrencyOfferB, context.params_[5u].asString())) // <currency_offer_b>
return rpcError(rpcINVALID_PARAMS);
iCount = lexicalCast <uint32>(context.params_[6u].asString());
if (iArgs >= 8 && "false" != context.params_[7u].asString())
bSubmit = true;
boost::posix_time::ptime ptStart(boost::posix_time::microsec_clock::local_time());
for(unsigned int n=0; n<iCount; n++)
{
RippleAddress naMasterGeneratorA;
RippleAddress naAccountPublicA;
RippleAddress naAccountPrivateA;
AccountState::pointer asSrcA;
STAmount saSrcBalanceA;
Json::Value jvObjA = authorize(uint256(0), naSeedA, naAccountA, naAccountPublicA, naAccountPrivateA,
saSrcBalanceA, getConfig ().FEE_DEFAULT, asSrcA, naMasterGeneratorA);
if (!jvObjA.empty())
return jvObjA;
Transaction::pointer tpOfferA = Transaction::sharedOfferCreate(
naAccountPublicA, naAccountPrivateA,
naAccountA, // naSourceAccount,
asSrcA->getSeq(), // uSeq
getConfig ().FEE_DEFAULT,
0, // uSourceTag,
false, // bPassive
STAmount(uCurrencyOfferA, naAccountA.getAccountID(), 1), // saTakerPays
STAmount(uCurrencyOfferB, naAccountB.getAccountID(), 1+n), // saTakerGets
0); // uExpiration
if (bSubmit)
tpOfferA = context.netOps_.submitTransactionSync(tpOfferA); // FIXME: Don't use synch interface
}
boost::posix_time::ptime ptEnd(boost::posix_time::microsec_clock::local_time());
boost::posix_time::time_duration tdInterval = ptEnd-ptStart;
long lMicroseconds = tdInterval.total_microseconds();
int iTransactions = iCount;
float fRate = lMicroseconds ? iTransactions/(lMicroseconds/1000000.0) : 0.0;
Json::Value obj(Json::objectValue);
obj["transactions"] = iTransactions;
obj["submit"] = bSubmit;
obj["start"] = boost::posix_time::to_simple_string(ptStart);
obj["end"] = boost::posix_time::to_simple_string(ptEnd);
obj["interval"] = boost::posix_time::to_simple_string(tdInterval);
obj["rate_per_second"] = fRate;
*/
Json::Value obj (Json::objectValue);
return obj;
}
} // ripple

View File

@@ -55,12 +55,12 @@ Json::Value doProofCreate (RPC::Context& context)
if (context.params_.isMember ("secret"))
{
uint256 uSecret (context.params_["secret"].asString ());
uint256 uSecret (context.params_["secret"].asString ());
pgGen->setSecret (uSecret);
}
jvResult["token"] = pgGen->getProof ().getToken ();
jvResult["secret"] = to_string (pgGen->getSecret ());
jvResult["token"] = pgGen->getProof ().getToken ();
jvResult["secret"] = to_string (pgGen->getSecret ());
}
else
{

View File

@@ -39,7 +39,7 @@ Json::Value doProofVerify (RPC::Context& context)
if (!context.params_.isMember ("solution"))
return RPC::missing_field_error ("solution");
std::string strToken = context.params_["token"].asString ();
std::string strToken = context.params_["token"].asString ();
uint256 uSolution (context.params_["solution"].asString ());
PowResult prResult;
@@ -60,7 +60,7 @@ Json::Value doProofVerify (RPC::Context& context)
if (iDifficulty < 0 ||
iDifficulty > ProofOfWorkFactory::kMaxDifficulty)
{
return RPC::missing_field_error ("difficulty");
return RPC::invalid_field_error ("difficulty");
}
pgGen->setDifficulty (iDifficulty);
@@ -68,12 +68,12 @@ Json::Value doProofVerify (RPC::Context& context)
if (context.params_.isMember ("secret"))
{
uint256 uSecret (context.params_["secret"].asString ());
uint256 uSecret (context.params_["secret"].asString ());
pgGen->setSecret (uSecret);
}
prResult = pgGen->checkProof (strToken, uSolution);
jvResult["secret"] = to_string (pgGen->getSecret ());
prResult = pgGen->checkProof (strToken, uSolution);
jvResult["secret"] = to_string (pgGen->getSecret ());
}
else
{
@@ -87,9 +87,9 @@ Json::Value doProofVerify (RPC::Context& context)
ProofOfWork::calcResultInfo (prResult, sToken, sHuman);
jvResult["proof_result"] = sToken;
jvResult["proof_result_code"] = prResult;
jvResult["proof_result_message"] = sHuman;
jvResult["proof_result"] = sToken;
jvResult["proof_result_code"] = prResult;
jvResult["proof_result_message"] = sHuman;
return jvResult;
}

View File

@@ -26,10 +26,11 @@ namespace ripple {
// }
Json::Value doRandom (RPC::Context& context)
{
uint256 rand;
// TODO(tom): the try/catch is almost certainly redundant, we catch at the
// top level too.
try
{
uint256 rand;
RandomNumbers::getInstance ().fillBytes (rand.begin (), rand.size ());
Json::Value jvResult;

View File

@@ -30,8 +30,10 @@ namespace ripple {
Json::Value doTransactionEntry (RPC::Context& context)
{
Ledger::pointer lpLedger;
Json::Value jvResult
= RPC::lookupLedger (context.params_, lpLedger, context.netOps_);
Json::Value jvResult = RPC::lookupLedger (
context.params_,
lpLedger,
context.netOps_);
if (!lpLedger)
return jvResult;

View File

@@ -44,6 +44,7 @@ Json::Value doTx (RPC::Context& context)
return rpcError (rpcTXN_NOT_FOUND);
#ifdef READY_FOR_NEW_TX_FORMAT
// TODO(tom): what new format is this?
Json::Value ret;
ret[jss::transaction] = txn->getJson (0, binary);
#else
@@ -52,12 +53,9 @@ Json::Value doTx (RPC::Context& context)
if (txn->getLedger () != 0)
{
auto lgr = context.netOps_.getLedgerBySeq (txn->getLedger ());
if (lgr)
if (auto lgr = context.netOps_.getLedgerBySeq (txn->getLedger ()))
{
bool okay = false;
if (binary)
{
std::string meta;
@@ -71,7 +69,6 @@ Json::Value doTx (RPC::Context& context)
else
{
TransactionMetaSet::pointer set;
if (lgr->getTransactionMeta (txid, set))
{
okay = true;

View File

@@ -33,20 +33,18 @@ Json::Value doUnlAdd (RPC::Context& context)
std::string strComment = context.params_.isMember ("comment")
? context.params_["comment"].asString () : "";
RippleAddress raNodePublic;
RippleAddress raNodePublic;
if (raNodePublic.setNodePublic (strNode))
{
getApp().getUNL ().nodeAddPublic (
raNodePublic, UniqueNodeList::vsManual, strComment);
return "adding node by public key";
}
else
{
getApp().getUNL ().nodeAddDomain (
strNode, UniqueNodeList::vsManual, strComment);
return "adding node by domain";
}
}

View File

@@ -30,20 +30,17 @@ Json::Value doUnlDelete (RPC::Context& context)
if (!context.params_.isMember ("node"))
return rpcError (rpcINVALID_PARAMS);
std::string strNode = context.params_["node"].asString ();
RippleAddress raNodePublic;
auto strNode = context.params_["node"].asString ();
RippleAddress raNodePublic;
if (raNodePublic.setNodePublic (strNode))
{
getApp().getUNL ().nodeRemovePublic (raNodePublic);
return "removing node by public key";
}
else
{
getApp().getUNL ().nodeRemoveDomain (strNode);
return "removing node by domain";
}
}

View File

@@ -41,7 +41,6 @@ Json::Value doUnsubscribe (RPC::Context& context)
return rpcError (rpcNO_PERMISSION);
std::string strUrl = context.params_["url"].asString ();
ispSub = context.netOps_.findRpcSub (strUrl);
if (!ispSub)
@@ -70,7 +69,7 @@ Json::Value doUnsubscribe (RPC::Context& context)
context.netOps_.unsubTransactions (ispSub->getSeq ());
else if (streamName == "transactions_proposed"
|| streamName == "rt_transactions") // DEPRECATED
|| streamName == "rt_transactions") // DEPRECATED
context.netOps_.unsubRTTransactions (ispSub->getSeq ());
else
@@ -116,44 +115,40 @@ Json::Value doUnsubscribe (RPC::Context& context)
}
else
{
for (auto& jvSubRequest: context.params_["books"])
for (auto& jv: context.params_["books"])
{
if (!jvSubRequest.isObject ()
|| !jvSubRequest.isMember ("taker_pays")
|| !jvSubRequest.isMember ("taker_gets")
|| !jvSubRequest["taker_pays"].isObject ()
|| !jvSubRequest["taker_gets"].isObject ())
if (!jv.isObject ()
|| !jv.isMember ("taker_pays")
|| !jv.isMember ("taker_gets")
|| !jv["taker_pays"].isObject ()
|| !jv["taker_gets"].isObject ())
return rpcError (rpcINVALID_PARAMS);
Currency pay_currency;
Account pay_issuer;
Currency get_currency;
Account get_issuer;
bool bBoth = (jvSubRequest.isMember ("both") &&
jvSubRequest["both"].asBool ())
|| (jvSubRequest.isMember ("both_sides") &&
jvSubRequest["both_sides"].asBool ()); // DEPRECATED
bool bBoth = (jv.isMember ("both") && jv["both"].asBool ()) ||
(jv.isMember ("both_sides") && jv["both_sides"].asBool ());
// both_sides is deprecated.
Json::Value taker_pays = jvSubRequest["taker_pays"];
Json::Value taker_gets = jvSubRequest["taker_gets"];
Json::Value taker_pays = jv["taker_pays"];
Json::Value taker_gets = jv["taker_gets"];
Book book;
// Parse mandatory currency.
if (!taker_pays.isMember ("currency")
|| !to_currency (
pay_currency, taker_pays["currency"].asString ()))
book.in.currency, taker_pays["currency"].asString ()))
{
WriteLog (lsINFO, RPCHandler) << "Bad taker_pays currency.";
return rpcError (rpcSRC_CUR_MALFORMED);
}
// Parse optional issuer.
else if (((taker_pays.isMember ("issuer"))
&& (!taker_pays["issuer"].isString ()
|| !to_issuer (
pay_issuer, taker_pays["issuer"].asString ())))
book.in.account, taker_pays["issuer"].asString ())))
// Don't allow illegal issuers.
|| (!pay_currency != !pay_issuer)
|| noAccount() == pay_issuer)
|| !isConsistent (book.in)
|| noAccount() == book.in.account)
{
WriteLog (lsINFO, RPCHandler) << "Bad taker_pays issuer.";
@@ -162,7 +157,7 @@ Json::Value doUnsubscribe (RPC::Context& context)
// Parse mandatory currency.
if (!taker_gets.isMember ("currency")
|| !to_currency (get_currency,
|| !to_currency (book.out.currency,
taker_gets["currency"].asString ()))
{
WriteLog (lsINFO, RPCHandler) << "Bad taker_pays currency.";
@@ -172,26 +167,24 @@ Json::Value doUnsubscribe (RPC::Context& context)
// Parse optional issuer.
else if (((taker_gets.isMember ("issuer"))
&& (!taker_gets["issuer"].isString ()
|| !to_issuer (get_issuer,
|| !to_issuer (book.out.account,
taker_gets["issuer"].asString ())))
// Don't allow illegal issuers.
|| (!get_currency != !get_issuer)
|| noAccount() == get_issuer)
|| !isConsistent (book.out)
|| noAccount() == book.out.account)
{
WriteLog (lsINFO, RPCHandler) << "Bad taker_gets issuer.";
return rpcError (rpcDST_ISR_MALFORMED);
}
if (pay_currency == get_currency
&& pay_issuer == get_issuer)
if (book.in == book.out)
{
WriteLog (lsINFO, RPCHandler) << "taker_gets same as taker_pays.";
WriteLog (lsINFO, RPCHandler)
<< "taker_gets same as taker_pays.";
return rpcError (rpcBAD_MARKET);
}
Book book{{pay_currency, pay_issuer}, {get_currency, get_issuer}};
context.netOps_.unsubBook (ispSub->getSeq (), book);
if (bBoth)

View File

@@ -25,65 +25,66 @@ namespace RPC {
// --> strIdent: public key, account ID, or regular seed.
// --> bStrict: Only allow account id or public key.
// <-- bIndex: true if iIndex > 0 and used the index.
Json::Value accountFromString (Ledger::ref lrLedger, RippleAddress& naAccount,
bool& bIndex, std::string const& strIdent,
const int iIndex, const bool bStrict, NetworkOPs& netOps)
Json::Value accountFromString (
Ledger::ref lrLedger,
RippleAddress& naAccount,
bool& bIndex,
std::string const& strIdent,
int const iIndex,
bool const bStrict,
NetworkOPs& netOps)
{
RippleAddress naSeed;
if (naAccount.setAccountPublic (strIdent) || naAccount.setAccountID (strIdent))
if (naAccount.setAccountPublic (strIdent) ||
naAccount.setAccountID (strIdent))
{
// Got the account.
bIndex = false;
bIndex = false;
return Json::Value (Json::objectValue);
}
else if (bStrict)
if (bStrict)
{
return naAccount.setAccountID (strIdent, Base58::getBitcoinAlphabet ())
? rpcError (rpcACT_BITCOIN)
: rpcError (rpcACT_MALFORMED);
auto success = naAccount.setAccountID (
strIdent, Base58::getBitcoinAlphabet ());
return rpcError (success ? rpcACT_BITCOIN : rpcACT_MALFORMED);
}
// Must be a seed.
else if (!naSeed.setSeedGeneric (strIdent))
{
// Otherwise, it must be a seed.
if (!naSeed.setSeedGeneric (strIdent))
return rpcError (rpcBAD_SEED);
}
else
// We allow the use of the seeds to access #0.
// This is poor practice and merely for debugging convenience.
RippleAddress naRegular0Public;
RippleAddress naRegular0Private;
auto naGenerator = RippleAddress::createGeneratorPublic (naSeed);
naRegular0Public.setAccountPublic (naGenerator, 0);
naRegular0Private.setAccountPrivate (naGenerator, naSeed, 0);
SLE::pointer sleGen = netOps.getGenerator (
lrLedger, naRegular0Public.getAccountID ());
if (sleGen)
{
// We allow the use of the seeds to access #0.
// This is poor practice and merely for debuging convenience.
RippleAddress naRegular0Public;
RippleAddress naRegular0Private;
// Found master public key.
Blob vucCipher = sleGen->getFieldVL (sfGenerator);
Blob vucMasterGenerator = naRegular0Private.accountPrivateDecrypt (
naRegular0Public, vucCipher);
RippleAddress naGenerator = RippleAddress::createGeneratorPublic (naSeed);
if (vucMasterGenerator.empty ())
rpcError (rpcNO_GEN_DECRYPT);
naRegular0Public.setAccountPublic (naGenerator, 0);
naRegular0Private.setAccountPrivate (naGenerator, naSeed, 0);
// Account uGeneratorID = naRegular0Public.getAccountID();
SLE::pointer sleGen = netOps.getGenerator (lrLedger, naRegular0Public.getAccountID ());
if (!sleGen)
{
// Didn't find a generator map, assume it is a master generator.
}
else
{
// Found master public key.
Blob vucCipher = sleGen->getFieldVL (sfGenerator);
Blob vucMasterGenerator = naRegular0Private.accountPrivateDecrypt (naRegular0Public, vucCipher);
if (vucMasterGenerator.empty ())
{
rpcError (rpcNO_GEN_DECRYPT);
}
naGenerator.setGenerator (vucMasterGenerator);
}
bIndex = !iIndex;
naAccount.setAccountPublic (naGenerator, iIndex);
naGenerator.setGenerator (vucMasterGenerator);
}
// Otherwise, if we didn't find a generator map, assume it is a master
// generator.
bIndex = !iIndex;
naAccount.setAccountPublic (naGenerator, iIndex);
return Json::Value (Json::objectValue);
}

View File

@@ -40,8 +40,9 @@ public:
void add (std::string const& method, handler_type&& handler)
{
m_map.emplace (std::piecewise_construct, std::forward_as_tuple (method),
std::forward_as_tuple (std::move (handler)));
m_map.emplace (std::piecewise_construct,
std::forward_as_tuple (method),
std::forward_as_tuple (std::move (handler)));
}
bool dispatch (Request& req)
@@ -63,7 +64,6 @@ Manager::~Manager ()
std::unique_ptr <Manager> make_Manager (beast::Journal journal)
{
std::unique_ptr <Manager> m (std::make_unique <ManagerImp> (journal));
m->add <DoPrint> ("print");
return m;

View File

@@ -24,24 +24,21 @@ namespace RPC {
hash_set<RippleAddress> parseAccountIds (Json::Value const& jvArray)
{
hash_set<RippleAddress> usnaResult;
hash_set<RippleAddress> result;
for (Json::Value::const_iterator it = jvArray.begin (); it != jvArray.end (); it++)
for (auto const& jv: jvArray)
{
RippleAddress naString;
RippleAddress address;
if (! (*it).isString () || !naString.setAccountID ((*it).asString ()))
if (!(jv.isString () && address.setAccountID ((jv.asString ()))))
{
usnaResult.clear ();
result.clear ();
break;
}
else
{
(void) usnaResult.insert (naString);
}
result.insert (address);
}
return usnaResult;
return result;
}
} // RPC

View File

@@ -27,23 +27,10 @@
namespace ripple {
//
// Carries out the RPC.
//
RPCHandler::RPCHandler (NetworkOPs& netOps)
: mNetOps (&netOps)
, mRole (Config::FORBID)
{
assert (mNetOps);
}
RPCHandler::RPCHandler (NetworkOPs& netOps, InfoSub::pointer infoSub)
: mNetOps (&netOps)
, mInfoSub (infoSub)
, mRole (Config::FORBID)
: netOps_ (netOps)
, infoSub_ (infoSub)
{
assert (mNetOps);
}
// Provide the JSON-RPC "result" value.
@@ -52,8 +39,10 @@ RPCHandler::RPCHandler (NetworkOPs& netOps, InfoSub::pointer infoSub)
// transport for a command and a request object. The command is the method. The
// request object is supplied as the first element of the params.
Json::Value RPCHandler::doRpcCommand (
std::string const& strMethod, Json::Value const& jvParams,
Config::Role iRole, Resource::Charge& loadType)
const std::string& strMethod,
Json::Value const& jvParams,
Config::Role role,
Resource::Charge& loadType)
{
WriteLog (lsTRACE, RPCHandler)
<< "doRpcCommand:" << strMethod << ":" << jvParams;
@@ -61,16 +50,16 @@ Json::Value RPCHandler::doRpcCommand (
if (!jvParams.isArray () || jvParams.size () > 1)
return logRPCError (rpcError (rpcINVALID_PARAMS));
Json::Value params = jvParams.size () ? jvParams[0u]
Json::Value params = jvParams.size () ? jvParams[0u]
: Json::Value (Json::objectValue);
if (!params.isObject ())
return logRPCError (rpcError (rpcINVALID_PARAMS));
// Provide the JSON-RPC method as the field "command" in the request.
params[jss::command] = strMethod;
params[jss::command] = strMethod;
Json::Value jvResult = doCommand (params, iRole, loadType);
Json::Value jvResult = doCommand (params, role, loadType);
// Always report "status". On an error report the request as received.
if (jvResult.isMember ("error"))
@@ -86,22 +75,12 @@ Json::Value RPCHandler::doRpcCommand (
return logRPCError (jvResult);
}
// TODO(tom): this should go with the other handlers.
Json::Value doInternal (RPC::Context& context)
{
// Used for debug or special-purpose RPC commands
if (!context.params_.isMember ("internal_command"))
return rpcError (rpcINVALID_PARAMS);
return RPCInternalHandler::runHandler (
context.params_["internal_command"].asString (),
context.params_["params"]);
}
Json::Value RPCHandler::doCommand (
Json::Value const& params, Config::Role iRole, Resource::Charge& loadType)
const Json::Value& params,
Config::Role role,
Resource::Charge& loadType)
{
if (iRole != Config::ADMIN)
if (role != Config::ADMIN)
{
// VFALCO NOTE Should we also add up the jtRPC jobs?
//
@@ -121,22 +100,22 @@ Json::Value RPCHandler::doCommand (
WriteLog (lsTRACE, RPCHandler) << "COMMAND:" << strCommand;
WriteLog (lsTRACE, RPCHandler) << "REQUEST:" << params;
mRole = iRole;
role_ = role;
const RPC::Handler* handler = RPC::getHandler(strCommand);
auto handler = RPC::getHandler(strCommand);
if (!handler)
return rpcError (rpcUNKNOWN_COMMAND);
if (handler->role_ == Config::ADMIN && mRole != Config::ADMIN)
if (handler->role_ == Config::ADMIN && role_ != Config::ADMIN)
return rpcError (rpcNO_PERMISSION);
if ((handler->condition_ & RPC::NEEDS_NETWORK_CONNECTION) &&
(mNetOps->getOperatingMode () < NetworkOPs::omSYNCING))
(netOps_.getOperatingMode () < NetworkOPs::omSYNCING))
{
WriteLog (lsINFO, RPCHandler)
<< "Insufficient network mode for RPC: "
<< mNetOps->strOperatingMode ();
<< netOps_.strOperatingMode ();
return rpcError (rpcNO_NETWORK);
}
@@ -150,16 +129,16 @@ Json::Value RPCHandler::doCommand (
}
if ((handler->condition_ & RPC::NEEDS_CLOSED_LEDGER) &&
!mNetOps->getClosedLedger ())
!netOps_.getClosedLedger ())
{
return rpcError (rpcNO_CLOSED);
return rpcError (rpcNO_CLOSED);
}
try
{
LoadEvent::autoptr ev = getApp().getJobQueue().getLoadEventAP(
jtGENERIC, "cmd:" + strCommand);
RPC::Context context{params, loadType, *mNetOps, mInfoSub, mRole};
RPC::Context context {params, loadType, netOps_, infoSub_, role_};
Json::Value jvRaw = handler->method_(context);
// Regularize result.
@@ -183,36 +162,4 @@ Json::Value RPCHandler::doCommand (
}
}
RPCInternalHandler* RPCInternalHandler::sHeadHandler = nullptr;
RPCInternalHandler::RPCInternalHandler (
std::string const& name, handler_t Handler)
: mName (name),
mHandler (Handler)
{
mNextHandler = sHeadHandler;
sHeadHandler = this;
}
Json::Value RPCInternalHandler::runHandler (
std::string const& name, Json::Value const& params)
{
for (RPCInternalHandler* h = sHeadHandler; h != nullptr; )
{
if (name == h->mName)
{
WriteLog (lsWARNING, RPCHandler)
<< "Internal command " << name << ": " << params;
Json::Value ret = h->mHandler (params);
WriteLog (lsWARNING, RPCHandler)
<< "Internal command returns: " << ret;
return ret;
}
h = h->mNextHandler;
}
return rpcError (rpcBAD_SYNTAX);
}
} // ripple

View File

@@ -20,10 +20,13 @@
#include <ripple/module/app/main/RPCHTTPServer.h>
#include <ripple/module/rpc/RPCHandler.h>
#include <ripple/module/rpc/RPCServerHandler.h>
#include <ripple/module/rpc/Tuning.h>
namespace ripple {
RPCServerHandler::RPCServerHandler (NetworkOPs& networkOPs, Resource::Manager& resourceManager)
RPCServerHandler::RPCServerHandler (
NetworkOPs& networkOPs,
Resource::Manager& resourceManager)
: m_networkOPs (networkOPs)
, m_resourceManager (resourceManager)
{
@@ -42,14 +45,15 @@ bool RPCServerHandler::isAuthorized (
return HTTPAuthorized (headers);
}
std::string RPCServerHandler::processRequest (std::string const& request,
beast::IP::Endpoint const& remoteIPAddress)
std::string RPCServerHandler::processRequest (
std::string const& request,
beast::IP::Endpoint const& remoteIPAddress)
{
Json::Value jsonRequest;
{
Json::Reader reader;
if ((request.size() > 1000000) ||
if ((request.size() > RPC::MAX_REQUEST_SIZE) ||
! reader.parse (request, jsonRequest) ||
jsonRequest.isNull () ||
! jsonRequest.isObject ())
@@ -58,14 +62,19 @@ std::string RPCServerHandler::processRequest (std::string const& request,
}
}
Config::Role const role (getConfig ().getAdminRole (jsonRequest, remoteIPAddress));
auto const role = getConfig ().getAdminRole (jsonRequest, remoteIPAddress);
Resource::Consumer usage;
if (role == Config::ADMIN)
usage = m_resourceManager.newAdminEndpoint (remoteIPAddress.to_string());
{
usage = m_resourceManager.newAdminEndpoint (
remoteIPAddress.to_string());
}
else
{
usage = m_resourceManager.newInboundEndpoint (remoteIPAddress);
}
if (usage.disconnect ())
return createResponse (503, "Server is overloaded");
@@ -75,19 +84,17 @@ std::string RPCServerHandler::processRequest (std::string const& request,
// VFALCO NOTE Except that "id" isn't included in the following errors...
//
Json::Value const& id = jsonRequest ["id"];
Json::Value const& method = jsonRequest ["method"];
if (method.isNull ())
{
return createResponse (400, "Null method");
}
else if (! method.isString ())
{
return createResponse (400, "method is not string");
}
std::string strMethod = method.asString ();
if (! method.isString ())
return createResponse (400, "method is not string");
auto strMethod = method.asString ();
if (strMethod.empty())
return createResponse (400, "method is empty");
if (jsonRequest["params"].isNull())
jsonRequest["params"] = Json::Value (Json::arrayValue);
@@ -149,7 +156,6 @@ std::string RPCServerHandler::processRequest (std::string const& request,
usage.charge (fee);
WriteLog (lsDEBUG, RPCServer) << "Reply: " << result;
response = JSONRPCReply (result, Json::Value (), id);
return createResponse (200, response);

View File

@@ -47,8 +47,11 @@ namespace RPC {
@param result A JSON object for injecting error results, if any
@param admin `true` if this is called by an administrative endpoint.
*/
static void autofill_fee (Json::Value& request,
Ledger::pointer ledger, Json::Value& result, bool admin)
static void autofill_fee (
Json::Value& request,
Ledger::pointer ledger,
Json::Value& result,
bool admin)
{
Json::Value& tx (request["tx_json"]);
if (tx.isMember ("Fee"))
@@ -88,7 +91,6 @@ static void autofill_fee (Json::Value& request,
tx ["Fee"] = static_cast<int>(fee);
}
static Json::Value signPayment(
Json::Value const& params,
Json::Value& tx_json,
@@ -150,12 +152,20 @@ static Json::Value signPayment(
bool bValid;
auto cache = std::make_shared<RippleLineCache> (lSnapshot);
Pathfinder pf (cache, raSrcAddressID, dstAccountID,
saSendMax.getCurrency (), saSendMax.getIssuer (),
amount, bValid);
Pathfinder pf (
cache,
raSrcAddressID,
dstAccountID,
saSendMax.getCurrency (),
saSendMax.getIssuer (),
amount, bValid);
STPath extraPath;
if (!bValid || !pf.findPaths (getConfig ().PATH_SEARCH_OLD, 4, spsPaths, extraPath))
if (!bValid ||
!pf.findPaths (getConfig ().PATH_SEARCH_OLD,
4,
spsPaths,
extraPath))
{
WriteLog (lsDEBUG, RPCHandler)
<< "transactionSign: build_path: No paths found.";
@@ -179,7 +189,10 @@ static Json::Value signPayment(
// submit the tranaction
//
Json::Value transactionSign (
Json::Value params, bool bSubmit, bool bFailHard, NetworkOPs& netOps,
Json::Value params,
bool bSubmit,
bool bFailHard,
NetworkOPs& netOps,
int role)
{
Json::Value jvResult;
@@ -242,8 +255,9 @@ Json::Value transactionSign (
{
// If not offline and did not find account, error.
WriteLog (lsDEBUG, RPCHandler)
<< "transactionSign: Failed to find source account in current ledger: "
<< raSrcAddressID.humanAccountID ();
<< "transactionSign: Failed to find source account "
<< "in current ledger: "
<< raSrcAddressID.humanAccountID ();
return rpcError (rpcSRC_ACT_NOT_FOUND);
}
@@ -255,7 +269,12 @@ Json::Value transactionSign (
if ("Payment" == sType)
{
auto e = signPayment(params, tx_json, raSrcAddressID, lSnapshot, role);
auto e = signPayment(
params,
tx_json,
raSrcAddressID,
lSnapshot,
role);
if (contains_error(e))
return e;
}
@@ -287,12 +306,12 @@ Json::Value transactionSign (
return rpcError (rpcSRC_ACT_NOT_FOUND);
}
RippleAddress naSecret = RippleAddress::createSeedGeneric (
RippleAddress secret = RippleAddress::createSeedGeneric (
params["secret"].asString ());
RippleAddress naMasterGenerator = RippleAddress::createGeneratorPublic (
naSecret);
RippleAddress masterGenerator = RippleAddress::createGeneratorPublic (
secret);
RippleAddress masterAccountPublic = RippleAddress::createAccountPublic (
naMasterGenerator, 0);
masterGenerator, 0);
if (verify)
{
@@ -323,7 +342,9 @@ Json::Value transactionSign (
return jvResult;
}
std::unique_ptr<STObject> sopTrans = std::move(parsed.object);
sopTrans->setFieldVL (sfSigningPubKey, masterAccountPublic.getAccountPublic ());
sopTrans->setFieldVL (
sfSigningPubKey,
masterAccountPublic.getAccountPublic ());
SerializedTransaction::pointer stpTrans;
@@ -348,9 +369,10 @@ Json::Value transactionSign (
jvResult["tx_signing_hash"] = to_string (stpTrans->getSigningHash ());
}
// FIXME: For performance, transactions should not be signed in this code path.
// FIXME: For performance, transactions should not be signed in this code
// path.
RippleAddress naAccountPrivate = RippleAddress::createAccountPrivate (
naMasterGenerator, naSecret, 0);
masterGenerator, secret, 0);
stpTrans->sign (naAccountPrivate);
@@ -358,7 +380,7 @@ Json::Value transactionSign (
try
{
tpTrans = std::make_shared<Transaction> (stpTrans, false);
tpTrans = std::make_shared<Transaction> (stpTrans, false);
}
catch (std::exception&)
{
@@ -416,9 +438,12 @@ class JSONRPC_test : public beast::unit_test::suite
public:
void testAutoFillFees ()
{
RippleAddress rootSeedMaster = RippleAddress::createSeedGeneric ("masterpassphrase");
RippleAddress rootGeneratorMaster = RippleAddress::createGeneratorPublic (rootSeedMaster);
RippleAddress rootAddress = RippleAddress::createAccountPublic (rootGeneratorMaster, 0);
RippleAddress rootSeedMaster
= RippleAddress::createSeedGeneric ("masterpassphrase");
RippleAddress rootGeneratorMaster
= RippleAddress::createGeneratorPublic (rootSeedMaster);
RippleAddress rootAddress
= RippleAddress::createAccountPublic (rootGeneratorMaster, 0);
std::uint64_t startAmount (100000);
Ledger::pointer ledger (std::make_shared <Ledger> (
rootAddress, startAmount));

View File

@@ -53,6 +53,7 @@
#include <ripple/module/rpc/handlers/Feature.cpp>
#include <ripple/module/rpc/handlers/FetchInfo.cpp>
#include <ripple/module/rpc/handlers/GetCounts.cpp>
#include <ripple/module/rpc/handlers/Internal.cpp>
#include <ripple/module/rpc/handlers/Ledger.cpp>
#include <ripple/module/rpc/handlers/LedgerAccept.cpp>
#include <ripple/module/rpc/handlers/LedgerCleaner.cpp>
@@ -69,7 +70,6 @@
#include <ripple/module/rpc/handlers/Peers.cpp>
#include <ripple/module/rpc/handlers/Ping.cpp>
#include <ripple/module/rpc/handlers/Print.cpp>
#include <ripple/module/rpc/handlers/Profile.cpp>
#include <ripple/module/rpc/handlers/ProofCreate.cpp>
#include <ripple/module/rpc/handlers/ProofSolve.cpp>
#include <ripple/module/rpc/handlers/ProofVerify.cpp>