mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-05 16:57:56 +00:00
Work toward ripple_path_find.
This commit is contained in:
@@ -92,8 +92,12 @@ bool STAmount::bSetJson(const Json::Value& jvSource)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
|
cLog(lsINFO)
|
||||||
|
<< boost::str(boost::format("bSetJson(): caught: %s")
|
||||||
|
% e.what());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
SETUP_LOG();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
JED: V IIII
|
JED: V IIII
|
||||||
|
|
||||||
@@ -41,7 +43,7 @@ Test USD to EUR
|
|||||||
// length of path
|
// length of path
|
||||||
// width of path
|
// width of path
|
||||||
// correct currency at the end
|
// correct currency at the end
|
||||||
|
#if 0
|
||||||
bool sortPathOptions(PathOption::pointer first, PathOption::pointer second)
|
bool sortPathOptions(PathOption::pointer first, PathOption::pointer second)
|
||||||
{
|
{
|
||||||
if (first->mTotalCost<second->mTotalCost) return(true);
|
if (first->mTotalCost<second->mTotalCost) return(true);
|
||||||
@@ -71,7 +73,7 @@ PathOption::PathOption(PathOption::pointer other)
|
|||||||
{
|
{
|
||||||
// TODO:
|
// TODO:
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Pathfinder::Pathfinder(RippleAddress& srcAccountID, RippleAddress& dstAccountID, uint160& srcCurrencyID, STAmount dstAmount) :
|
Pathfinder::Pathfinder(RippleAddress& srcAccountID, RippleAddress& dstAccountID, uint160& srcCurrencyID, STAmount dstAmount) :
|
||||||
mSrcAccountID(srcAccountID.getAccountID()), mDstAccountID(dstAccountID.getAccountID()), mDstAmount(dstAmount), mSrcCurrencyID(srcCurrencyID), mOrderBook(theApp->getMasterLedger().getCurrentLedger())
|
mSrcAccountID(srcAccountID.getAccountID()), mDstAccountID(dstAccountID.getAccountID()), mDstAmount(dstAmount), mSrcCurrencyID(srcCurrencyID), mOrderBook(theApp->getMasterLedger().getCurrentLedger())
|
||||||
@@ -88,7 +90,7 @@ bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet
|
|||||||
std::queue<STPath> pqueue;
|
std::queue<STPath> pqueue;
|
||||||
STPathElement ele(mSrcAccountID,
|
STPathElement ele(mSrcAccountID,
|
||||||
mSrcCurrencyID,
|
mSrcCurrencyID,
|
||||||
uint160());
|
uint160()); // XXX Might add source issuer.
|
||||||
STPath path;
|
STPath path;
|
||||||
|
|
||||||
path.addElement(ele); // Add the source.
|
path.addElement(ele); // Add the source.
|
||||||
@@ -103,11 +105,19 @@ bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet
|
|||||||
ele = path.mPath.back(); // Get the last node from the path.
|
ele = path.mPath.back(); // Get the last node from the path.
|
||||||
|
|
||||||
// Determine if path is solved.
|
// Determine if path is solved.
|
||||||
|
|
||||||
|
// Done, if dest wants XRP and last element produces XRP.
|
||||||
|
// Done, if dest wants non-XRP and last element is dest.
|
||||||
|
|
||||||
|
if (!ele.mCurrencyID) {
|
||||||
|
}
|
||||||
if (ele.mAccountID == mDstAccountID) {
|
if (ele.mAccountID == mDstAccountID) {
|
||||||
// Found a path to the destination.
|
// Found a path to the destination.
|
||||||
|
|
||||||
if (2 == path.mPath.size()) {
|
if (2 == path.mPath.size()) {
|
||||||
// Empty path is default. Drop it.
|
// Empty path is default. Drop it.
|
||||||
|
// XXX Don't drop empty path - we still want an estimate.
|
||||||
|
cLog(lsDEBUG) << "findPaths: dropping empty path.";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,9 +194,10 @@ bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
bool Pathfinder::checkComplete(STPathSet& retPathSet)
|
bool Pathfinder::checkComplete(STPathSet& retPathSet)
|
||||||
{
|
{
|
||||||
if(mCompletePaths.size())
|
if (mCompletePaths.size())
|
||||||
{ // TODO: look through these and pick the most promising
|
{ // TODO: look through these and pick the most promising
|
||||||
int count=0;
|
int count=0;
|
||||||
BOOST_FOREACH(PathOption::pointer pathOption,mCompletePaths)
|
BOOST_FOREACH(PathOption::pointer pathOption,mCompletePaths)
|
||||||
@@ -279,4 +290,6 @@ void Pathfinder::addPathOption(PathOption::pointer pathOption)
|
|||||||
mBuildingPaths.push_back(pathOption);
|
mBuildingPaths.push_back(pathOption);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// vim:ts=4
|
// vim:ts=4
|
||||||
|
|||||||
@@ -3,9 +3,13 @@
|
|||||||
#include "OrderBookDB.h"
|
#include "OrderBookDB.h"
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
/* this is a very simple implementation. This can be made way better.
|
#if 0
|
||||||
We are simply flooding from the start. And doing an exhaustive search of all paths under maxSearchSteps. An easy improvement would be to flood from both directions
|
//
|
||||||
*/
|
// This is a very simple implementation. This can be made way better.
|
||||||
|
// We are simply flooding from the start. And doing an exhaustive search of all paths under maxSearchSteps. An easy improvement would
|
||||||
|
be to flood from both directions.
|
||||||
|
//
|
||||||
|
|
||||||
class PathOption
|
class PathOption
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -22,6 +26,7 @@ public:
|
|||||||
PathOption(uint160& srcAccount,uint160& srcCurrencyID,const uint160& dstCurrencyID);
|
PathOption(uint160& srcAccount,uint160& srcCurrencyID,const uint160& dstCurrencyID);
|
||||||
PathOption(PathOption::pointer other);
|
PathOption(PathOption::pointer other);
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
class Pathfinder
|
class Pathfinder
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
//
|
||||||
|
// carries out the RPC
|
||||||
|
//
|
||||||
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "NetworkOPs.h"
|
#include "NetworkOPs.h"
|
||||||
#include "RPCHandler.h"
|
#include "RPCHandler.h"
|
||||||
@@ -12,14 +16,9 @@
|
|||||||
#include "Pathfinder.h"
|
#include "Pathfinder.h"
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <openssl/md5.h>
|
#include <openssl/md5.h>
|
||||||
/*
|
|
||||||
carries out the RPC
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
SETUP_LOG();
|
SETUP_LOG();
|
||||||
|
|
||||||
|
|
||||||
Json::Value RPCHandler::rpcError(int iError)
|
Json::Value RPCHandler::rpcError(int iError)
|
||||||
{
|
{
|
||||||
static struct {
|
static struct {
|
||||||
@@ -706,24 +705,36 @@ Json::Value RPCHandler::doRipplePathFind(const Json::Value& jvRequest)
|
|||||||
// Parse raSrc.
|
// Parse raSrc.
|
||||||
!jvRequest.isMember("source_account")
|
!jvRequest.isMember("source_account")
|
||||||
|| !jvRequest["source_account"].isString()
|
|| !jvRequest["source_account"].isString()
|
||||||
|| !raSrc.setAccountID(jvRequest["source_account"].asString())
|
|| !raSrc.setAccountID(jvRequest["source_account"].asString()))
|
||||||
|
{
|
||||||
|
cLog(lsINFO) << "Bad source_account.";
|
||||||
|
jvResult = rpcError(rpcINVALID_PARAMS);
|
||||||
|
}
|
||||||
|
else if (
|
||||||
// Parse raDst.
|
// Parse raDst.
|
||||||
|| !jvRequest.isMember("destination_account")
|
!jvRequest.isMember("destination_account")
|
||||||
|| !jvRequest["destination_account"].isString()
|
|| !jvRequest["destination_account"].isString()
|
||||||
|| !raDst.setAccountID(jvRequest["destination_account"].asString())
|
|| !raDst.setAccountID(jvRequest["destination_account"].asString()))
|
||||||
|
{
|
||||||
|
cLog(lsINFO) << "Bad destination_account.";
|
||||||
|
jvResult = rpcError(rpcINVALID_PARAMS);
|
||||||
|
}
|
||||||
|
else if (
|
||||||
// Parse saDst.
|
// Parse saDst.
|
||||||
|| !jvRequest.isMember("destination_amount")
|
!jvRequest.isMember("destination_amount")
|
||||||
|| !saDst.bSetJson("destination_amount")
|
|| !saDst.bSetJson(jvRequest["destination_amount"]))
|
||||||
|
{
|
||||||
|
cLog(lsINFO) << "Bad destination_amount.";
|
||||||
|
jvResult = rpcError(rpcINVALID_PARAMS);
|
||||||
|
}
|
||||||
|
else if (
|
||||||
// Checks on source_currencies.
|
// Checks on source_currencies.
|
||||||
|| !jvRequest.isMember("source_currencies")
|
!jvRequest.isMember("source_currencies")
|
||||||
|| !jvRequest["source_currencies"].isArray()
|
|| !jvRequest["source_currencies"].isArray()
|
||||||
|| jvRequest["source_currencies"].size()
|
|| !jvRequest["source_currencies"].size()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
cLog(lsINFO) << "Bad source_currencies.";
|
||||||
jvResult = rpcError(rpcINVALID_PARAMS);
|
jvResult = rpcError(rpcINVALID_PARAMS);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -742,10 +753,20 @@ Json::Value RPCHandler::doRipplePathFind(const Json::Value& jvRequest)
|
|||||||
&& (!jvSource["issuer"].isString()
|
&& (!jvSource["issuer"].isString()
|
||||||
|| !STAmount::issuerFromString(srcIssuerID, jvSource["issuer"].asString()))))
|
|| !STAmount::issuerFromString(srcIssuerID, jvSource["issuer"].asString()))))
|
||||||
{
|
{
|
||||||
|
cLog(lsINFO) << "Bad currency/issuer.";
|
||||||
return rpcError(rpcINVALID_PARAMS);
|
return rpcError(rpcINVALID_PARAMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX Add some results.
|
STPathSet spsPaths;
|
||||||
|
|
||||||
|
// XXX Need to add support for srcIssuerID.
|
||||||
|
Pathfinder pf(raSrc, raDst, srcCurrencyID, saDst);
|
||||||
|
|
||||||
|
if (!spsPaths.isEmpty())
|
||||||
|
{
|
||||||
|
// XXX Also need to check liquidity.
|
||||||
|
jvSource.append(spsPaths.getJson(0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jvResult["results"] = jvArray;
|
jvResult["results"] = jvArray;
|
||||||
@@ -1410,7 +1431,7 @@ Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& param
|
|||||||
{ "peers", &RPCHandler::doPeers, 0, 0, true, false, optNone },
|
{ "peers", &RPCHandler::doPeers, 0, 0, true, false, optNone },
|
||||||
{ "profile", &RPCHandler::doProfile, 1, 9, false, false, optCurrent },
|
{ "profile", &RPCHandler::doProfile, 1, 9, false, false, optCurrent },
|
||||||
{ "ripple_lines_get", &RPCHandler::doRippleLinesGet, 1, 2, false, false, optCurrent },
|
{ "ripple_lines_get", &RPCHandler::doRippleLinesGet, 1, 2, false, false, optCurrent },
|
||||||
{ "path_find", &RPCHandler::doRipplePathFind, -1, -1, false, false, optCurrent },
|
{ "ripple_path_find", &RPCHandler::doRipplePathFind, -1, -1, false, false, optCurrent },
|
||||||
{ "submit", &RPCHandler::doSubmit, 2, 2, false, false, optCurrent },
|
{ "submit", &RPCHandler::doSubmit, 2, 2, false, false, optCurrent },
|
||||||
{ "submit_json", &RPCHandler::doSubmitJson, -1, -1, false, false, optCurrent },
|
{ "submit_json", &RPCHandler::doSubmitJson, -1, -1, false, false, optCurrent },
|
||||||
{ "server_info", &RPCHandler::doServerInfo, 0, 0, true, false, optNone },
|
{ "server_info", &RPCHandler::doServerInfo, 0, 0, true, false, optNone },
|
||||||
|
|||||||
@@ -937,7 +937,29 @@ Remote.prototype.request_ripple_balance = function (account, issuer, currency, c
|
|||||||
'account_limit' : accountLimit // Limit set by account with dst as issuer.
|
'account_limit' : accountLimit // Limit set by account with dst as issuer.
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
Remote.prototype.request_ripple_path_find = function (src_account, dst_account, dst_amount, source_currencies) {
|
||||||
|
var self = this;
|
||||||
|
var request = new Request(this, 'ripple_path_find');
|
||||||
|
|
||||||
|
request.message.source_account = UInt160.json_rewrite(src_account);
|
||||||
|
request.message.destination_account = UInt160.json_rewrite(dst_account);
|
||||||
|
request.message.destination_amount = Amount.json_rewrite(dst_amount);
|
||||||
|
request.message.source_currencies = source_currencies.map(function (ci) {
|
||||||
|
var ci_new = {};
|
||||||
|
|
||||||
|
if ('issuer' in ci)
|
||||||
|
ci_new.issuer = UInt160.json_rewrite(ci.issuer);
|
||||||
|
|
||||||
|
if ('currency' in ci)
|
||||||
|
ci_new.currency = Currency.json_rewrite(ci.currency);
|
||||||
|
|
||||||
|
return ci_new;
|
||||||
|
});
|
||||||
|
|
||||||
|
return request;
|
||||||
|
};
|
||||||
|
|
||||||
Remote.prototype.request_unl_list = function () {
|
Remote.prototype.request_unl_list = function () {
|
||||||
return new Request(this, 'unl_list');
|
return new Request(this, 'unl_list');
|
||||||
|
|||||||
Reference in New Issue
Block a user