mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
@@ -109,6 +109,7 @@
|
||||
<ClCompile Include="src\cpp\ripple\DBInit.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\DeterministicKeys.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\ECIES.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\FeatureTable.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\FieldNames.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\HashedObject.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\HTTPRequest.cpp" />
|
||||
@@ -295,8 +296,9 @@
|
||||
<None Include="html\newcoin.html">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
<None Include="newcoind.cfg" />
|
||||
<None Include="README" />
|
||||
<None Include="ripple-example.txt" />
|
||||
<None Include="rippled-example.cfg" />
|
||||
<None Include="SConstruct" />
|
||||
<CustomBuild Include="src\cpp\ripple\ripple.proto">
|
||||
<FileType>Document</FileType>
|
||||
@@ -307,7 +309,7 @@
|
||||
<None Include="test\server.js" />
|
||||
<None Include="test\standalone-test.js" />
|
||||
<None Include="test\utils.js" />
|
||||
<None Include="validators.txt" />
|
||||
<None Include="validators-example.txt" />
|
||||
<None Include="wallet.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -26,7 +26,9 @@ Application* theApp = NULL;
|
||||
|
||||
DatabaseCon::DatabaseCon(const std::string& strName, const char *initStrings[], int initCount)
|
||||
{
|
||||
boost::filesystem::path pPath = theConfig.RUN_STANDALONE ? "" : theConfig.DATA_DIR / strName;
|
||||
boost::filesystem::path pPath = (theConfig.RUN_STANDALONE && (!theConfig.START_UP != Config::LOAD))
|
||||
? "" // Use temporary files.
|
||||
: (theConfig.DATA_DIR / strName); // Use regular db files.
|
||||
|
||||
mDatabase = new SqliteDatabase(pPath.string().c_str());
|
||||
mDatabase->connect();
|
||||
@@ -43,7 +45,7 @@ DatabaseCon::~DatabaseCon()
|
||||
Application::Application() :
|
||||
mIOWork(mIOService), mAuxWork(mAuxService), mUNL(mIOService), mNetOps(mIOService, &mLedgerMaster),
|
||||
mTempNodeCache("NodeCache", 16384, 90), mHashedObjectStore(16384, 300), mSLECache("LedgerEntryCache", 4096, 120),
|
||||
mSNTPClient(mAuxService), mRPCHandler(&mNetOps), mFeeTrack(),
|
||||
mSNTPClient(mAuxService), mFeeTrack(),
|
||||
mRpcDB(NULL), mTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL), mHashNodeDB(NULL), mNetNodeDB(NULL),
|
||||
mConnectionPool(mIOService), mPeerDoor(NULL), mRPCDoor(NULL), mWSPublicDoor(NULL), mWSPrivateDoor(NULL),
|
||||
mSweepTimer(mAuxService), mShutdown(false)
|
||||
|
||||
@@ -64,7 +64,6 @@ class Application
|
||||
SLECache mSLECache;
|
||||
SNTPClient mSNTPClient;
|
||||
JobQueue mJobQueue;
|
||||
RPCHandler mRPCHandler;
|
||||
ProofOfWorkGenerator mPOWGen;
|
||||
LoadManager mLoadMgr;
|
||||
LoadFeeTrack mFeeTrack;
|
||||
@@ -114,7 +113,6 @@ public:
|
||||
ValidationCollection& getValidations() { return mValidations; }
|
||||
JobQueue& getJobQueue() { return mJobQueue; }
|
||||
SuppressionTable& getSuppression() { return mSuppressions; }
|
||||
RPCHandler& getRPCHandler() { return mRPCHandler; }
|
||||
boost::recursive_mutex& getMasterLock() { return mMasterLock; }
|
||||
ProofOfWorkGenerator& getPowGen() { return mPOWGen; }
|
||||
LoadManager& getLoadManager() { return mLoadMgr; }
|
||||
|
||||
@@ -442,16 +442,23 @@ Json::Value RPCParser::parseAccountItems(const Json::Value& jvParams)
|
||||
return jvRequest;
|
||||
}
|
||||
|
||||
// ripple_path_find json
|
||||
// ripple_path_find <json> [<ledger>]
|
||||
Json::Value RPCParser::parseRipplePathFind(const Json::Value& jvParams)
|
||||
{
|
||||
Json::Value txJSON;
|
||||
Json::Reader reader;
|
||||
Json::Value jvRequest;
|
||||
bool bLedger = 2 == jvParams.size();
|
||||
|
||||
cLog(lsTRACE) << "RPC json:" << jvParams[0u];
|
||||
if (reader.parse(jvParams[0u].asString(), txJSON))
|
||||
cLog(lsTRACE) << "RPC json: " << jvParams[0u];
|
||||
|
||||
if (bLedger)
|
||||
{
|
||||
return txJSON;
|
||||
jvParseLedger(jvRequest, jvParams[1u].asString());
|
||||
}
|
||||
|
||||
if (reader.parse(jvParams[0u].asString(), jvRequest))
|
||||
{
|
||||
return jvRequest;
|
||||
}
|
||||
|
||||
return rpcError(rpcINVALID_PARAMS);
|
||||
@@ -652,7 +659,7 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams)
|
||||
{ "ping", &RPCParser::parseAsIs, 0, 0 },
|
||||
// { "profile", &RPCParser::parseProfile, 1, 9 },
|
||||
{ "random", &RPCParser::parseAsIs, 0, 0 },
|
||||
{ "ripple_path_find", &RPCParser::parseRipplePathFind, 1, 1 },
|
||||
{ "ripple_path_find", &RPCParser::parseRipplePathFind, 1, 2 },
|
||||
{ "sign", &RPCParser::parseSignSubmit, 2, 2 },
|
||||
{ "submit", &RPCParser::parseSignSubmit, 1, 2 },
|
||||
{ "server_info", &RPCParser::parseAsIs, 0, 0 },
|
||||
|
||||
@@ -61,14 +61,20 @@ public:
|
||||
static const int lsfOutbound = 2; // outbound connection
|
||||
|
||||
protected:
|
||||
int mBalance;
|
||||
int mFlags;
|
||||
int mLastUpdate;
|
||||
int mLastWarning;
|
||||
std::string mName;
|
||||
int mBalance;
|
||||
int mFlags;
|
||||
int mLastUpdate;
|
||||
int mLastWarning;
|
||||
|
||||
public:
|
||||
LoadSource() : mBalance(0), mFlags(0), mLastWarning(0)
|
||||
{ mLastUpdate = upTime(); }
|
||||
LoadSource(bool admin) : mBalance(0), mFlags(admin ? lsfPrivileged : 0), mLastUpdate(upTime()), mLastWarning(0)
|
||||
{ ; }
|
||||
LoadSource(const std::string& name) : mName(name), mBalance(0), mFlags(0), mLastUpdate(upTime()), mLastWarning(0)
|
||||
{ ; }
|
||||
|
||||
void rename(const std::string& name)
|
||||
{ mName = name; }
|
||||
|
||||
bool isPrivileged() const { return (mFlags & lsfPrivileged) != 0; }
|
||||
void setPrivileged() { mFlags |= lsfPrivileged; }
|
||||
|
||||
@@ -38,6 +38,7 @@ TER OfferCreateTransactor::takeOffers(
|
||||
|
||||
cLog(lsINFO) << "takeOffers: against book: " << uBookBase.ToString();
|
||||
|
||||
LedgerEntrySet& lesActive = mEngine->getNodes();
|
||||
uint256 uTipIndex = uBookBase;
|
||||
const uint256 uBookEnd = Ledger::getQualityNext(uBookBase);
|
||||
const uint64 uTakeQuality = STAmount::getRate(saTakerGets, saTakerPays);
|
||||
@@ -46,7 +47,6 @@ TER OfferCreateTransactor::takeOffers(
|
||||
const uint160 uTakerGetsAccountID = saTakerGets.getIssuer();
|
||||
TER terResult = temUNCERTAIN;
|
||||
|
||||
boost::unordered_set<uint256> usOfferUnfundedFound; // Offers found unfunded.
|
||||
boost::unordered_set<uint256> usOfferUnfundedBecame; // Offers that became unfunded.
|
||||
boost::unordered_set<uint160> usAccountTouched; // Accounts touched.
|
||||
|
||||
@@ -58,7 +58,7 @@ TER OfferCreateTransactor::takeOffers(
|
||||
{
|
||||
SLE::pointer sleOfferDir;
|
||||
uint64 uTipQuality = 0;
|
||||
STAmount saTakerFunds = mEngine->getNodes().accountFunds(uTakerAccountID, saTakerPays);
|
||||
STAmount saTakerFunds = lesActive.accountFunds(uTakerAccountID, saTakerPays);
|
||||
STAmount saSubTakerPays = saTakerPays-saTakerPaid; // How much more to spend.
|
||||
STAmount saSubTakerGets = saTakerGets-saTakerGot; // How much more is wanted.
|
||||
|
||||
@@ -131,7 +131,7 @@ TER OfferCreateTransactor::takeOffers(
|
||||
unsigned int uBookEntry;
|
||||
uint256 uOfferIndex;
|
||||
|
||||
mEngine->getNodes().dirFirst(uTipIndex, sleBookNode, uBookEntry, uOfferIndex);
|
||||
lesActive.dirFirst(uTipIndex, sleBookNode, uBookEntry, uOfferIndex);
|
||||
|
||||
SLE::pointer sleOffer = mEngine->entryCache(ltOFFER, uOfferIndex);
|
||||
|
||||
@@ -153,7 +153,7 @@ TER OfferCreateTransactor::takeOffers(
|
||||
// Would take own offer. Consider old offer expired. Delete it.
|
||||
cLog(lsINFO) << "takeOffers: encountered taker's own old offer";
|
||||
|
||||
usOfferUnfundedFound.insert(uOfferIndex);
|
||||
usOfferUnfundedBecame.insert(uOfferIndex);
|
||||
}
|
||||
else if (!saOfferGets.isPositive() || !saOfferPays.isPositive())
|
||||
{
|
||||
@@ -169,7 +169,7 @@ TER OfferCreateTransactor::takeOffers(
|
||||
|
||||
cLog(lsINFO) << "takeOffers: saOfferPays=" << saOfferPays.getFullText();
|
||||
|
||||
STAmount saOfferFunds = mEngine->getNodes().accountFunds(uOfferOwnerID, saOfferPays);
|
||||
STAmount saOfferFunds = lesActive.accountFunds(uOfferOwnerID, saOfferPays);
|
||||
SLE::pointer sleOfferAccount; // Owner of offer.
|
||||
|
||||
if (!saOfferFunds.isPositive()) // Includes zero.
|
||||
@@ -210,8 +210,8 @@ TER OfferCreateTransactor::takeOffers(
|
||||
cLog(lsINFO) << "takeOffers: applyOffer: saTakerGets: " << saTakerGets.getFullText();
|
||||
|
||||
bool bOfferDelete = STAmount::applyOffer(
|
||||
mEngine->getNodes().rippleTransferRate(uTakerAccountID, uOfferOwnerID, uTakerPaysAccountID),
|
||||
mEngine->getNodes().rippleTransferRate(uOfferOwnerID, uTakerAccountID, uTakerGetsAccountID),
|
||||
lesActive.rippleTransferRate(uTakerAccountID, uOfferOwnerID, uTakerPaysAccountID),
|
||||
lesActive.rippleTransferRate(uOfferOwnerID, uTakerAccountID, uTakerGetsAccountID),
|
||||
saOfferRate,
|
||||
saOfferFunds,
|
||||
saTakerFunds,
|
||||
@@ -274,10 +274,10 @@ TER OfferCreateTransactor::takeOffers(
|
||||
{
|
||||
// Distribute funds. The sends charge appropriate fees which are implied by offer.
|
||||
|
||||
terResult = mEngine->getNodes().accountSend(uOfferOwnerID, uTakerAccountID, saSubTakerGot); // Offer owner pays taker.
|
||||
terResult = lesActive.accountSend(uOfferOwnerID, uTakerAccountID, saSubTakerGot); // Offer owner pays taker.
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
terResult = mEngine->getNodes().accountSend(uTakerAccountID, uOfferOwnerID, saSubTakerPaid); // Taker pays offer owner.
|
||||
terResult = lesActive.accountSend(uTakerAccountID, uOfferOwnerID, saSubTakerPaid); // Taker pays offer owner.
|
||||
|
||||
// Reduce amount considered paid by taker's rate (not actual cost).
|
||||
STAmount saTakerCould = saTakerPays - saTakerPaid; // Taker could pay.
|
||||
@@ -304,20 +304,6 @@ TER OfferCreateTransactor::takeOffers(
|
||||
|
||||
cLog(lsINFO) << "takeOffers: " << transToken(terResult);
|
||||
|
||||
// On storing meta data, delete offers that were found unfunded to prevent encountering them in future.
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
BOOST_FOREACH(const uint256& uOfferIndex, usOfferUnfundedFound)
|
||||
{
|
||||
|
||||
cLog(lsINFO) << "takeOffers: found unfunded: " << uOfferIndex.ToString();
|
||||
|
||||
terResult = mEngine->getNodes().offerDelete(uOfferIndex);
|
||||
if (tesSUCCESS != terResult)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
// On success, delete offers that became unfunded.
|
||||
@@ -325,7 +311,7 @@ TER OfferCreateTransactor::takeOffers(
|
||||
{
|
||||
cLog(lsINFO) << "takeOffers: became unfunded: " << uOfferIndex.ToString();
|
||||
|
||||
terResult = mEngine->getNodes().offerDelete(uOfferIndex);
|
||||
terResult = lesActive.offerDelete(uOfferIndex);
|
||||
if (tesSUCCESS != terResult)
|
||||
break;
|
||||
}
|
||||
@@ -369,6 +355,12 @@ TER OfferCreateTransactor::doApply()
|
||||
uint64 uOwnerNode;
|
||||
uint64 uBookNode;
|
||||
|
||||
LedgerEntrySet& lesActive = mEngine->getNodes();
|
||||
LedgerEntrySet lesCheckpoint = lesActive; // Checkpoint with just fees paid.
|
||||
lesActive.bumpSeq(); // Begin ledger variance.
|
||||
|
||||
SLE::pointer sleCreator = mEngine->entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(mTxnAccountID));
|
||||
|
||||
if (uTxFlags & tfOfferCreateMask)
|
||||
{
|
||||
cLog(lsINFO) << "OfferCreate: Malformed transaction: Invalid flags set.";
|
||||
@@ -417,7 +409,7 @@ TER OfferCreateTransactor::doApply()
|
||||
|
||||
terResult = temBAD_ISSUER;
|
||||
}
|
||||
else if (!mEngine->getNodes().accountFunds(mTxnAccountID, saTakerGets).isPositive())
|
||||
else if (!lesActive.accountFunds(mTxnAccountID, saTakerGets).isPositive())
|
||||
{
|
||||
cLog(lsWARNING) << "OfferCreate: delay: Offers must be at least partially funded.";
|
||||
|
||||
@@ -458,7 +450,7 @@ TER OfferCreateTransactor::doApply()
|
||||
bPassive,
|
||||
uTakeBookBase,
|
||||
mTxnAccountID,
|
||||
mTxnAccount,
|
||||
sleCreator,
|
||||
saTakerGets, // Reverse as we are the taker for taking.
|
||||
saTakerPays,
|
||||
saPaid, // How much would have spent at full price.
|
||||
@@ -482,7 +474,7 @@ TER OfferCreateTransactor::doApply()
|
||||
cLog(lsWARNING) << "OfferCreate: takeOffers: saTakerPays=" << saTakerPays.getFullText();
|
||||
cLog(lsWARNING) << "OfferCreate: takeOffers: saTakerGets=" << saTakerGets.getFullText();
|
||||
cLog(lsWARNING) << "OfferCreate: takeOffers: mTxnAccountID=" << RippleAddress::createHumanAccountID(mTxnAccountID);
|
||||
cLog(lsWARNING) << "OfferCreate: takeOffers: FUNDS=" << mEngine->getNodes().accountFunds(mTxnAccountID, saTakerGets).getFullText();
|
||||
cLog(lsWARNING) << "OfferCreate: takeOffers: FUNDS=" << lesActive.accountFunds(mTxnAccountID, saTakerGets).getFullText();
|
||||
|
||||
// cLog(lsWARNING) << "OfferCreate: takeOffers: uPaysIssuerID=" << RippleAddress::createHumanAccountID(uPaysIssuerID);
|
||||
// cLog(lsWARNING) << "OfferCreate: takeOffers: uGetsIssuerID=" << RippleAddress::createHumanAccountID(uGetsIssuerID);
|
||||
@@ -500,19 +492,19 @@ TER OfferCreateTransactor::doApply()
|
||||
else if (bFillOrKill && (saTakerPays || saTakerGets))
|
||||
{
|
||||
// Fill or kill and have leftovers.
|
||||
terResult = tecKILL;
|
||||
lesActive.swapWith(lesCheckpoint); // Restore with just fees paid.
|
||||
}
|
||||
else if (
|
||||
!saTakerPays // Wants nothing more.
|
||||
|| !saTakerGets // Offering nothing more.
|
||||
|| bImmediateOrCancel // Do not persist.
|
||||
|| !mEngine->getNodes().accountFunds(mTxnAccountID, saTakerGets).isPositive() // Not funded.
|
||||
|| bImmediateOrCancel // Do not persist.
|
||||
|| !lesActive.accountFunds(mTxnAccountID, saTakerGets).isPositive() // Not funded.
|
||||
|| bUnfunded) // Consider unfunded.
|
||||
{
|
||||
// Complete as is.
|
||||
nothing();
|
||||
}
|
||||
else if (mPriorBalance.getNValue() < mEngine->getLedger()->getReserve(mTxnAccount->getFieldU32(sfOwnerCount)+1))
|
||||
else if (mPriorBalance.getNValue() < mEngine->getLedger()->getReserve(sleCreator->getFieldU32(sfOwnerCount)+1))
|
||||
{
|
||||
if (bOpenLedger) // Ledger is not final, can vote no.
|
||||
{
|
||||
@@ -541,14 +533,14 @@ TER OfferCreateTransactor::doApply()
|
||||
% saTakerGets.getFullText());
|
||||
|
||||
// Add offer to owner's directory.
|
||||
terResult = mEngine->getNodes().dirAdd(uOwnerNode, Ledger::getOwnerDirIndex(mTxnAccountID), uLedgerIndex,
|
||||
terResult = lesActive.dirAdd(uOwnerNode, Ledger::getOwnerDirIndex(mTxnAccountID), uLedgerIndex,
|
||||
boost::bind(&Ledger::qualityDirDescriber, _1, saTakerPays.getCurrency(), uPaysIssuerID,
|
||||
saTakerGets.getCurrency(), uGetsIssuerID, uRate));
|
||||
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
mEngine->getNodes().ownerCountAdjust(mTxnAccountID, 1, mTxnAccount); // Update owner count.
|
||||
lesActive.ownerCountAdjust(mTxnAccountID, 1, sleCreator); // Update owner count.
|
||||
|
||||
uint256 uBookBase = Ledger::getBookBase(uPaysCurrency, uPaysIssuerID, uGetsCurrency, uGetsIssuerID);
|
||||
|
||||
@@ -562,7 +554,7 @@ TER OfferCreateTransactor::doApply()
|
||||
uDirectory = Ledger::getQualityIndex(uBookBase, uRate); // Use original rate.
|
||||
|
||||
// Add offer to order book.
|
||||
terResult = mEngine->getNodes().dirAdd(uBookNode, uDirectory, uLedgerIndex,
|
||||
terResult = lesActive.dirAdd(uBookNode, uDirectory, uLedgerIndex,
|
||||
boost::bind(&Ledger::qualityDirDescriber, _1, saTakerPays.getCurrency(), uPaysIssuerID,
|
||||
saTakerGets.getCurrency(), uGetsIssuerID, uRate));
|
||||
}
|
||||
@@ -599,6 +591,20 @@ TER OfferCreateTransactor::doApply()
|
||||
}
|
||||
}
|
||||
|
||||
// On storing meta data, delete offers that were found unfunded to prevent encountering them in future.
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
BOOST_FOREACH(const uint256& uOfferIndex, usOfferUnfundedFound)
|
||||
{
|
||||
|
||||
cLog(lsINFO) << "takeOffers: found unfunded: " << uOfferIndex.ToString();
|
||||
|
||||
terResult = lesActive.offerDelete(uOfferIndex);
|
||||
if (tesSUCCESS != terResult)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tLog(tesSUCCESS != terResult, lsINFO) << boost::str(boost::format("OfferCreate: final terResult=%s") % transToken(terResult));
|
||||
|
||||
if (isTesSuccess(terResult))
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
class OfferCreateTransactor : public Transactor
|
||||
{
|
||||
protected:
|
||||
TER takeOffers(
|
||||
const bool bOpenLedger,
|
||||
const bool bPassive,
|
||||
@@ -17,6 +18,8 @@ class OfferCreateTransactor : public Transactor
|
||||
STAmount& saTakerGot,
|
||||
bool& bUnfunded);
|
||||
|
||||
boost::unordered_set<uint256> usOfferUnfundedFound; // Offers found unfunded.
|
||||
|
||||
public:
|
||||
OfferCreateTransactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine) : Transactor(txn,params,engine) {}
|
||||
TER doApply();
|
||||
|
||||
@@ -34,6 +34,8 @@ Peer::Peer(boost::asio::io_service& io_service, boost::asio::ssl::context& ctx,
|
||||
mActive(2),
|
||||
mCluster(false),
|
||||
mPeerId(peerID),
|
||||
mPrivate(false),
|
||||
mLoad(""),
|
||||
mSocketSsl(io_service, ctx),
|
||||
mActivityTimer(io_service)
|
||||
{
|
||||
@@ -77,6 +79,7 @@ void Peer::handleWrite(const boost::system::error_code& error, size_t bytes_tran
|
||||
void Peer::setIpPort(const std::string& strIP, int iPort)
|
||||
{
|
||||
mIpPort = make_pair(strIP, iPort);
|
||||
mLoad.rename(strIP);
|
||||
|
||||
cLog(lsDEBUG) << "Peer: Set: "
|
||||
<< ADDRESS(this) << "> "
|
||||
|
||||
@@ -63,12 +63,13 @@ int iAdminGet(const Json::Value& jvRequest, const std::string& strRemoteIp)
|
||||
return iRole;
|
||||
}
|
||||
|
||||
RPCHandler::RPCHandler(NetworkOPs* netOps)
|
||||
RPCHandler::RPCHandler(NetworkOPs* netOps, LoadSource &ls) : mLoadSource(ls)
|
||||
{
|
||||
mNetOps = netOps;
|
||||
}
|
||||
|
||||
RPCHandler::RPCHandler(NetworkOPs* netOps, InfoSub::pointer infoSub) : mInfoSub(infoSub)
|
||||
RPCHandler::RPCHandler(NetworkOPs* netOps, InfoSub::pointer infoSub, LoadSource& ls)
|
||||
: mInfoSub(infoSub), mLoadSource(ls)
|
||||
{
|
||||
mNetOps = netOps;
|
||||
}
|
||||
@@ -885,7 +886,6 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest)
|
||||
if (!lpLedger)
|
||||
return jvResult;
|
||||
|
||||
|
||||
if (!jvRequest.isMember("account"))
|
||||
return rpcError(rpcINVALID_PARAMS);
|
||||
|
||||
@@ -1153,10 +1153,14 @@ Json::Value RPCHandler::doRandom(Json::Value jvRequest)
|
||||
// - From a trusted server, allows clients to use path without manipulation.
|
||||
Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest)
|
||||
{
|
||||
Json::Value jvResult(Json::objectValue);
|
||||
RippleAddress raSrc;
|
||||
RippleAddress raDst;
|
||||
STAmount saDstAmount;
|
||||
Ledger::pointer lpLedger;
|
||||
Json::Value jvResult = lookupLedger(jvRequest, lpLedger);
|
||||
|
||||
if (!lpLedger)
|
||||
return jvResult;
|
||||
|
||||
if (theApp->getJobQueue().getJobCountGE(jtCLIENT) > 200)
|
||||
{
|
||||
@@ -1201,7 +1205,6 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest)
|
||||
}
|
||||
else
|
||||
{
|
||||
Ledger::pointer lpCurrent = mNetOps->getCurrentLedger();
|
||||
Json::Value jvSrcCurrencies;
|
||||
|
||||
if (jvRequest.isMember("source_currencies"))
|
||||
@@ -1210,7 +1213,7 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest)
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::unordered_set<uint160> usCurrencies = usAccountSourceCurrencies(raSrc, lpCurrent);
|
||||
boost::unordered_set<uint160> usCurrencies = usAccountSourceCurrencies(raSrc, lpLedger);
|
||||
|
||||
// Add XRP as a source currency.
|
||||
// YYY Only bother if they are above reserve.
|
||||
@@ -1228,7 +1231,7 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest)
|
||||
}
|
||||
}
|
||||
|
||||
Ledger::pointer lSnapShot = boost::make_shared<Ledger>(boost::ref(*lpCurrent), false);
|
||||
Ledger::pointer lSnapShot = boost::make_shared<Ledger>(boost::ref(*lpLedger), false);
|
||||
LedgerEntrySet lesSnapshot(lSnapShot);
|
||||
|
||||
ScopedUnlock su(theApp->getMasterLock()); // As long as we have a locked copy of the ledger, we can unlock.
|
||||
@@ -2020,7 +2023,7 @@ Json::Value RPCHandler::doGetCounts(Json::Value jvRequest)
|
||||
int s = upTime();
|
||||
textTime(uptime, s, "year", 365*24*60*60);
|
||||
textTime(uptime, s, "day", 24*60*60);
|
||||
textTime(uptime, s, "hour", 24*60);
|
||||
textTime(uptime, s, "hour", 60*60);
|
||||
textTime(uptime, s, "minute", 60);
|
||||
textTime(uptime, s, "second", 1);
|
||||
ret["uptime"] = uptime;
|
||||
|
||||
@@ -18,6 +18,7 @@ class RPCHandler
|
||||
NetworkOPs* mNetOps;
|
||||
InfoSub::pointer mInfoSub;
|
||||
int mRole;
|
||||
LoadSource& mLoadSource;
|
||||
|
||||
typedef Json::Value (RPCHandler::*doFuncPtr)(Json::Value params);
|
||||
enum {
|
||||
@@ -113,8 +114,8 @@ public:
|
||||
|
||||
enum { GUEST, USER, ADMIN, FORBID };
|
||||
|
||||
RPCHandler(NetworkOPs* netOps);
|
||||
RPCHandler(NetworkOPs* netOps, InfoSub::pointer infoSub);
|
||||
RPCHandler(NetworkOPs* netOps, LoadSource&);
|
||||
RPCHandler(NetworkOPs* netOps, InfoSub::pointer infoSub, LoadSource&);
|
||||
|
||||
Json::Value doCommand(const Json::Value& jvRequest, int role);
|
||||
Json::Value doRpcCommand(const std::string& strCommand, Json::Value& jvParams, int iRole);
|
||||
|
||||
@@ -24,7 +24,7 @@ SETUP_LOG();
|
||||
#endif
|
||||
|
||||
RPCServer::RPCServer(boost::asio::io_service& io_service , NetworkOPs* nopNetwork)
|
||||
: mNetOps(nopNetwork), mSocket(io_service)
|
||||
: mNetOps(nopNetwork), mLoadSource("rpc"), mSocket(io_service)
|
||||
{
|
||||
mRole = RPCHandler::GUEST;
|
||||
}
|
||||
@@ -51,7 +51,7 @@ void RPCServer::handle_read_req(const boost::system::error_code& e)
|
||||
if (!HTTPAuthorized(mHTTPRequest.peekHeaders()))
|
||||
mReplyStr = HTTPReply(403, "Forbidden");
|
||||
else
|
||||
mReplyStr = handleRequest(req);
|
||||
mReplyStr = handleRequest(req, mLoadSource);
|
||||
|
||||
boost::asio::async_write(mSocket, boost::asio::buffer(mReplyStr),
|
||||
boost::bind(&RPCServer::handle_write, shared_from_this(), boost::asio::placeholders::error));
|
||||
@@ -110,7 +110,7 @@ void RPCServer::handle_read_line(const boost::system::error_code& e)
|
||||
}
|
||||
}
|
||||
|
||||
std::string RPCServer::handleRequest(const std::string& requestStr)
|
||||
std::string RPCServer::handleRequest(const std::string& requestStr, LoadSource& ls)
|
||||
{
|
||||
cLog(lsTRACE) << "handleRequest " << requestStr;
|
||||
|
||||
@@ -154,7 +154,7 @@ std::string RPCServer::handleRequest(const std::string& requestStr)
|
||||
return HTTPReply(403, "Forbidden");
|
||||
}
|
||||
|
||||
RPCHandler mRPCHandler(mNetOps);
|
||||
RPCHandler mRPCHandler(mNetOps, mLoadSource);
|
||||
|
||||
cLog(lsTRACE) << valParams;
|
||||
Json::Value result = mRPCHandler.doRpcCommand(strMethod, valParams, mRole);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "NetworkOPs.h"
|
||||
#include "SerializedLedger.h"
|
||||
#include "RPCHandler.h"
|
||||
#include "LoadManager.h"
|
||||
|
||||
class RPCServer : public boost::enable_shared_from_this<RPCServer>
|
||||
{
|
||||
@@ -23,6 +24,7 @@ public:
|
||||
private:
|
||||
|
||||
NetworkOPs* mNetOps;
|
||||
LoadSource mLoadSource;
|
||||
|
||||
boost::asio::ip::tcp::socket mSocket;
|
||||
|
||||
@@ -44,7 +46,7 @@ private:
|
||||
void handle_read_line(const boost::system::error_code& ec);
|
||||
void handle_read_req(const boost::system::error_code& ec);
|
||||
|
||||
std::string handleRequest(const std::string& requestStr);
|
||||
std::string handleRequest(const std::string& requestStr, LoadSource& ls);
|
||||
|
||||
public:
|
||||
static pointer create(boost::asio::io_service& io_service, NetworkOPs* mNetOps)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// TODO:
|
||||
// - Do automatic bridging via XRP.
|
||||
//
|
||||
// OPTIMIZE: When calculating path increment, note if increment consumes all liquidity. No need to revesit path in the future if
|
||||
// OPTIMIZE: When calculating path increment, note if increment consumes all liquidity. No need to revisit path in the future if
|
||||
// all liquidity is used.
|
||||
//
|
||||
|
||||
@@ -270,7 +270,7 @@ TER PathState::pushNode(
|
||||
|
||||
// Insert intermediary issuer account if needed.
|
||||
terResult = pushImply(
|
||||
ACCOUNT_XRP, // Rippling, but offer's don't have an account.
|
||||
ACCOUNT_XRP, // Rippling, but offers don't have an account.
|
||||
pnPrv.uCurrencyID,
|
||||
pnPrv.uIssuerID);
|
||||
}
|
||||
@@ -384,7 +384,7 @@ void PathState::setExpanded(
|
||||
|
||||
if (tesSUCCESS == terStatus
|
||||
&& !!uOutCurrencyID // Next is not XRP
|
||||
&& uOutIssuerID != uReceiverID // Out issuer is not reciever
|
||||
&& uOutIssuerID != uReceiverID // Out issuer is not receiver
|
||||
&& (pnPrv.uCurrencyID != uOutCurrencyID // Previous will be an offer.
|
||||
|| pnPrv.uAccountID != uOutIssuerID)) // Need the implied issuer.
|
||||
{
|
||||
@@ -427,12 +427,7 @@ void PathState::setExpanded(
|
||||
{
|
||||
const PaymentNode& pnCur = vpnNodes[uNode];
|
||||
|
||||
if (!!pnCur.uAccountID)
|
||||
{
|
||||
// Source is a ripple line
|
||||
nothing();
|
||||
}
|
||||
else if (!umForward.insert(std::make_pair(boost::make_tuple(pnCur.uAccountID, pnCur.uCurrencyID, pnCur.uIssuerID), uNode)).second)
|
||||
if (!umForward.insert(std::make_pair(boost::make_tuple(pnCur.uAccountID, pnCur.uCurrencyID, pnCur.uIssuerID), uNode)).second)
|
||||
{
|
||||
// Failed to insert. Have a loop.
|
||||
cLog(lsDEBUG) << boost::str(boost::format("PathState: loop detected: %s")
|
||||
@@ -472,7 +467,7 @@ void PathState::setExpanded(
|
||||
// Optimization:
|
||||
// - An XRP output implies an offer node or destination node is next.
|
||||
// - A change in currency implies an offer node.
|
||||
// - A change in issuer...
|
||||
// - A change in issuer...
|
||||
void PathState::setCanonical(
|
||||
const PathState& psExpanded
|
||||
)
|
||||
@@ -496,7 +491,7 @@ void PathState::setCanonical(
|
||||
uint160 uCurrencyID = uMaxCurrencyID;
|
||||
uint160 uIssuerID = uMaxIssuerID;
|
||||
|
||||
// Node 0 is a composit of the sending account and saInAct.
|
||||
// Node 0 is a composite of the sending account and saInAct.
|
||||
++uNode; // skip node 0
|
||||
|
||||
// Last node is implied: Always skip last node
|
||||
@@ -829,8 +824,8 @@ TER RippleCalc::calcNodeAdvance(
|
||||
uDirectEnd = Ledger::getQualityNext(uDirectTip);
|
||||
|
||||
sleDirectDir = lesActive.entryCache(ltDIR_NODE, uDirectTip);
|
||||
bDirectAdvance = !sleDirectDir;
|
||||
bDirectDirDirty = true;
|
||||
bDirectDirDirty = !!sleDirectDir; // Associated vars are dirty, if found it.
|
||||
bDirectAdvance = !sleDirectDir; // Advance, if didn't find it. Normal not to be unable to lookup firstdirectory. Maybe even skip this lookup.
|
||||
|
||||
cLog(lsTRACE) << boost::str(boost::format("calcNodeAdvance: Initialize node: uDirectTip=%s uDirectEnd=%s bDirectAdvance=%d") % uDirectTip % uDirectEnd % bDirectAdvance);
|
||||
}
|
||||
@@ -879,6 +874,7 @@ TER RippleCalc::calcNodeAdvance(
|
||||
{
|
||||
if (bFundsDirty)
|
||||
{
|
||||
// We were called again probably merely to update structure variables.
|
||||
saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
|
||||
saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
|
||||
|
||||
@@ -897,22 +893,27 @@ TER RippleCalc::calcNodeAdvance(
|
||||
{
|
||||
// Failed to find an entry in directory.
|
||||
|
||||
uOfferIndex = 0;
|
||||
|
||||
// Do another cur directory iff bMultiQuality
|
||||
if (bMultiQuality)
|
||||
{
|
||||
// We are allowed to process multiple qualities if this is the only path.
|
||||
cLog(lsTRACE) << boost::str(boost::format("calcNodeAdvance: next quality"));
|
||||
bDirectAdvance = true;
|
||||
|
||||
bDirectAdvance = true; // Process next quality.
|
||||
}
|
||||
else if (!bReverse)
|
||||
{
|
||||
cLog(lsWARNING) << boost::str(boost::format("calcNodeAdvance: unreachable: ran out of offers"));
|
||||
assert(false); // Can't run out of offers in forward direction.
|
||||
terResult = tefEXCEPTION;
|
||||
terResult = tefEXCEPTION;
|
||||
}
|
||||
else
|
||||
bEntryAdvance = false;
|
||||
{
|
||||
// Ran off end of offers.
|
||||
|
||||
bEntryAdvance = false; // Done.
|
||||
uOfferIndex = 0; // Report nore more entries.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -932,20 +933,38 @@ TER RippleCalc::calcNodeAdvance(
|
||||
cLog(lsTRACE) << "calcNodeAdvance: expired offer";
|
||||
|
||||
assert(musUnfundedFound.find(uOfferIndex) != musUnfundedFound.end()); // Verify reverse found it too.
|
||||
bEntryAdvance = true;
|
||||
// Just skip it. It will be deleted.
|
||||
// bEntryAdvance = true; // Already set
|
||||
continue;
|
||||
}
|
||||
else if (!saTakerPays.isPositive() || !saTakerGets.isPositive())
|
||||
{
|
||||
// Offer is has bad amounts.
|
||||
cLog(lsWARNING) << boost::str(boost::format("calcNodeAdvance: NON-POSITIVE: saTakerPays=%s saTakerGets=%s")
|
||||
% saTakerPays % saTakerGets);
|
||||
// Offer has bad amounts. Offers should never have a bad amounts.
|
||||
|
||||
// assert(musUnfundedFound.find(uOfferIndex) != musUnfundedFound.end()); // Verify reverse found it too.
|
||||
bEntryAdvance = true;
|
||||
if (musUnfundedFound.find(uOfferIndex) != musUnfundedFound.end())
|
||||
{
|
||||
// An internal error, offer was found failed to place this in musUnfundedFound.
|
||||
cLog(lsWARNING) << boost::str(boost::format("calcNodeAdvance: PAST INTERNAL ERROR: OFFER NON-POSITIVE: saTakerPays=%s saTakerGets=%s")
|
||||
% saTakerPays % saTakerGets);
|
||||
|
||||
// Just skip it. It will be deleted.
|
||||
// bEntryAdvance = true; // Already set
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reverse should have previously put bad offer in list.
|
||||
// An internal error previously left a bad offer.
|
||||
cLog(lsWARNING) << boost::str(boost::format("calcNodeAdvance: INTERNAL ERROR: OFFER NON-POSITIVE: saTakerPays=%s saTakerGets=%s")
|
||||
% saTakerPays % saTakerGets);
|
||||
//assert(false);
|
||||
// Don't process at all, things are in an unexpected state for this transactions.
|
||||
terResult = tefEXCEPTION;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
bEntryAdvance = false;
|
||||
|
||||
// Allowed to access source from this node?
|
||||
// XXX This can get called multiple times for same source in a row, caching result would be nice.
|
||||
// XXX Going forward could we fund something with a worse quality which was previously skipped? Might need to check
|
||||
@@ -953,6 +972,8 @@ TER RippleCalc::calcNodeAdvance(
|
||||
curIssuerNodeConstIterator itForward = psCur.umForward.find(asLine);
|
||||
const bool bFoundForward = itForward != psCur.umForward.end();
|
||||
|
||||
// Only a allow a source to be used once, in the first node encountered from initial path scan.
|
||||
// This prevents conflicting uses of the same balance when going reverse vs forward.
|
||||
if (bFoundForward && itForward->second != uNode)
|
||||
{
|
||||
// Temporarily unfunded. Another node uses this source, ignore in this offer.
|
||||
@@ -962,21 +983,12 @@ TER RippleCalc::calcNodeAdvance(
|
||||
continue;
|
||||
}
|
||||
|
||||
curIssuerNodeConstIterator itPast = mumSource.find(asLine);
|
||||
bool bFoundPast = itPast != mumSource.end();
|
||||
|
||||
if (bFoundPast && itPast->second != uNode)
|
||||
{
|
||||
// Temporarily unfunded. Another node uses this source, ignore in this offer.
|
||||
cLog(lsTRACE) << "calcNodeAdvance: temporarily unfunded offer (past)";
|
||||
|
||||
bEntryAdvance = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// This is overly strict. For contributions to past. We should only count source if actually used.
|
||||
curIssuerNodeConstIterator itReverse = psCur.umReverse.find(asLine);
|
||||
bool bFoundReverse = itReverse != psCur.umReverse.end();
|
||||
|
||||
// For this quality increment, only allow a source to be used from a single node, in the first node encountered from applying offers
|
||||
// in reverse.
|
||||
if (bFoundReverse && itReverse->second != uNode)
|
||||
{
|
||||
// Temporarily unfunded. Another node uses this source, ignore in this offer.
|
||||
@@ -986,7 +998,23 @@ TER RippleCalc::calcNodeAdvance(
|
||||
continue;
|
||||
}
|
||||
|
||||
saOfferFunds = lesActive.accountFunds(uOfrOwnerID, saTakerGets); // Funds left.
|
||||
curIssuerNodeConstIterator itPast = mumSource.find(asLine);
|
||||
bool bFoundPast = itPast != mumSource.end();
|
||||
|
||||
// Determine if used in past.
|
||||
// XXX Restriction seems like a misunderstanding.
|
||||
if (bFoundPast && itPast->second != uNode)
|
||||
{
|
||||
// Temporarily unfunded. Another node uses this source, ignore in this offer.
|
||||
cLog(lsTRACE) << "calcNodeAdvance: temporarily unfunded offer (past)";
|
||||
|
||||
bEntryAdvance = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only the current node is allowed to use the source.
|
||||
|
||||
saOfferFunds = lesActive.accountFunds(uOfrOwnerID, saTakerGets); // Funds held.
|
||||
|
||||
if (!saOfferFunds.isPositive())
|
||||
{
|
||||
@@ -995,9 +1023,17 @@ TER RippleCalc::calcNodeAdvance(
|
||||
|
||||
if (bReverse && !bFoundReverse && !bFoundPast)
|
||||
{
|
||||
// Never mentioned before: found unfunded.
|
||||
// Never mentioned before, clearly just: found unfunded.
|
||||
// That is, even if this offer fails due to fill or kill still do deletions.
|
||||
musUnfundedFound.insert(uOfferIndex); // Mark offer for always deletion.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Moving forward, don't need to check again.
|
||||
// Or source was used this reverse
|
||||
// Or source was previously used
|
||||
// XXX
|
||||
}
|
||||
|
||||
// YYY Could verify offer is correct place for unfundeds.
|
||||
bEntryAdvance = true;
|
||||
@@ -1301,9 +1337,16 @@ TER RippleCalc::calcNodeDeliverFwd(
|
||||
saInAct.zero(saInReq);
|
||||
saInFees.zero(saInReq);
|
||||
|
||||
int loopCount = 0;
|
||||
while (tesSUCCESS == terResult
|
||||
&& saInAct + saInFees != saInReq) // Did not deliver all funds.
|
||||
{
|
||||
if (++loopCount > 40)
|
||||
{
|
||||
cLog(lsWARNING) << "max loops cndf";
|
||||
return mOpenLedger ? telFAILED_PROCESSING : tecFAILED_PROCESSING;
|
||||
}
|
||||
|
||||
// Determine values for pass to adjust saInAct, saInFees, and saCurDeliverAct
|
||||
terResult = calcNodeAdvance(uNode, psCur, bMultiQuality, false); // If needed, advance to next funded offer.
|
||||
|
||||
@@ -2427,7 +2470,7 @@ void RippleCalc::pathNext(PathState::ref psrCur, const bool bMultiQuality, const
|
||||
assert(psrCur->vpnNodes.size() >= 2);
|
||||
|
||||
lesCurrent = lesCheckpoint; // Restore from checkpoint.
|
||||
lesCurrent.bumpSeq(); // Begin ledger varance.
|
||||
lesCurrent.bumpSeq(); // Begin ledger variance.
|
||||
|
||||
psrCur->terStatus = calcNodeRev(uLast, *psrCur, bMultiQuality);
|
||||
|
||||
@@ -2437,7 +2480,7 @@ void RippleCalc::pathNext(PathState::ref psrCur, const bool bMultiQuality, const
|
||||
{
|
||||
// Do forward.
|
||||
lesCurrent = lesCheckpoint; // Restore from checkpoint.
|
||||
lesCurrent.bumpSeq(); // Begin ledger varance.
|
||||
lesCurrent.bumpSeq(); // Begin ledger variance.
|
||||
|
||||
psrCur->terStatus = calcNodeFwd(0, *psrCur, bMultiQuality);
|
||||
}
|
||||
@@ -2895,7 +2938,7 @@ void TransactionEngine::calcOfferBridgeNext(
|
||||
{
|
||||
// Offer fully funded.
|
||||
|
||||
// Account transfering funds in to offer always pays inbound fees.
|
||||
// Account transferring funds in to offer always pays inbound fees.
|
||||
|
||||
saOfferIn = saOfferGets; // XXX Add in fees?
|
||||
|
||||
@@ -2934,26 +2977,26 @@ void TransactionEngine::calcOfferBridgeNext(
|
||||
// - reverse: prv is maximum to pay in (including fee) - cur is what is wanted: generally, minimizing prv
|
||||
// - forward: prv is actual amount to pay in (including fee) - cur is what is wanted: generally, minimizing cur
|
||||
// Value in is may be rippled or credited from limbo. Value out is put in limbo.
|
||||
// If next is an offer, the amount needed is in cur reedem.
|
||||
// If next is an offer, the amount needed is in cur redeem.
|
||||
// XXX What about account mentioned multiple times via offers?
|
||||
void TransactionEngine::calcNodeOffer(
|
||||
bool bForward,
|
||||
bool bMultiQuality, // True, if this is the only active path: we can do multiple qualities in this pass.
|
||||
const uint160& uPrvAccountID, // If 0, then funds from previous offer's limbo
|
||||
const uint160& uPrvAccountID, // If 0, then funds from previous offers limbo
|
||||
const uint160& uPrvCurrencyID,
|
||||
const uint160& uPrvIssuerID,
|
||||
const uint160& uCurCurrencyID,
|
||||
const uint160& uCurIssuerID,
|
||||
|
||||
const STAmount& uPrvRedeemReq, // --> In limit.
|
||||
STAmount& uPrvRedeemAct, // <-> In limit achived.
|
||||
STAmount& uPrvRedeemAct, // <-> In limit achieved.
|
||||
const STAmount& uCurRedeemReq, // --> Out limit. Driver when uCurIssuerID == uNxtIssuerID (offer would redeem to next)
|
||||
STAmount& uCurRedeemAct, // <-> Out limit achived.
|
||||
STAmount& uCurRedeemAct, // <-> Out limit achieved.
|
||||
|
||||
const STAmount& uCurIssueReq, // --> In limit.
|
||||
STAmount& uCurIssueAct, // <-> In limit achived.
|
||||
STAmount& uCurIssueAct, // <-> In limit achieved.
|
||||
const STAmount& uCurIssueReq, // --> Out limit. Driver when uCurIssueReq != uNxtIssuerID (offer would effectively issue or transfer to next)
|
||||
STAmount& uCurIssueAct, // <-> Out limit achived.
|
||||
STAmount& uCurIssueAct, // <-> Out limit achieved.
|
||||
|
||||
STAmount& saPay,
|
||||
STAmount& saGot
|
||||
@@ -3007,13 +3050,13 @@ void TransactionEngine::calcNodeOffer(
|
||||
bool bRedeeming = false;
|
||||
bool bIssuing = false;
|
||||
|
||||
// The price varies as we change between issuing and transfering, so unless bMultiQuality, we must stick with a mode once it
|
||||
// The price varies as we change between issuing and transferring, so unless bMultiQuality, we must stick with a mode once it
|
||||
// is determined.
|
||||
|
||||
if (bBridge && (bInNext || bOutNext))
|
||||
{
|
||||
// Bridging and need to calculate next bridge rate.
|
||||
// A bridge can consist of multiple offers. As offer's are consumed, the effective rate changes.
|
||||
// A bridge can consist of multiple offers. As offers are consumed, the effective rate changes.
|
||||
|
||||
if (bInNext)
|
||||
{
|
||||
|
||||
@@ -123,7 +123,6 @@ enum TER // aka TransactionEngineResult
|
||||
tecUNFUNDED_OFFER = 103,
|
||||
tecUNFUNDED_PAYMENT = 104,
|
||||
tecFAILED_PROCESSING = 105,
|
||||
tecKILL = 106, // tesSUCCESS is not retryable.
|
||||
tecDIR_FULL = 121,
|
||||
tecINSUF_RESERVE_LINE = 122,
|
||||
tecINSUF_RESERVE_OFFER = 123,
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "CallRPC.h"
|
||||
#include "InstanceCounter.h"
|
||||
#include "Log.h"
|
||||
#include "LoadManager.h"
|
||||
#include "RPCErr.h"
|
||||
|
||||
DEFINE_INSTANCE(WebSocketConnection);
|
||||
@@ -45,6 +46,7 @@ protected:
|
||||
weak_connection_ptr mConnection;
|
||||
NetworkOPs& mNetwork;
|
||||
std::string mRemoteIP;
|
||||
LoadSource mLoadSource;
|
||||
|
||||
boost::asio::deadline_timer mPingTimer;
|
||||
bool mPinged;
|
||||
@@ -56,9 +58,9 @@ public:
|
||||
|
||||
WSConnection(WSServerHandler<endpoint_type>* wshpHandler, const connection_ptr& cpConnection)
|
||||
: mHandler(wshpHandler), mConnection(cpConnection), mNetwork(theApp->getOPs()),
|
||||
mPingTimer(cpConnection->get_io_service()), mPinged(false)
|
||||
mRemoteIP(cpConnection->get_socket().lowest_layer().remote_endpoint().address().to_string()),
|
||||
mLoadSource(mRemoteIP), mPingTimer(cpConnection->get_io_service()), mPinged(false)
|
||||
{
|
||||
mRemoteIP = cpConnection->get_socket().lowest_layer().remote_endpoint().address().to_string();
|
||||
cLog(lsDEBUG) << "Websocket connection from " << mRemoteIP;
|
||||
setPingTimer();
|
||||
}
|
||||
@@ -103,7 +105,8 @@ public:
|
||||
return jvResult;
|
||||
}
|
||||
|
||||
RPCHandler mRPCHandler(&mNetwork, boost::shared_polymorphic_downcast<InfoSub>(this->shared_from_this()));
|
||||
RPCHandler mRPCHandler(&mNetwork,
|
||||
boost::shared_polymorphic_downcast<InfoSub>(this->shared_from_this()), mLoadSource);
|
||||
Json::Value jvResult(Json::objectValue);
|
||||
|
||||
int iRole = mHandler->getPublic()
|
||||
|
||||
@@ -43,7 +43,8 @@ void startServer()
|
||||
if (!theConfig.QUIET)
|
||||
std::cerr << "Startup RPC: " << jvCommand << std::endl;
|
||||
|
||||
RPCHandler rhHandler(&theApp->getOPs());
|
||||
LoadSource ls(true);
|
||||
RPCHandler rhHandler(&theApp->getOPs(), ls);
|
||||
|
||||
Json::Value jvResult = rhHandler.doCommand(jvCommand, RPCHandler::ADMIN);
|
||||
|
||||
@@ -92,6 +93,7 @@ void printHelp(const po::options_description& desc)
|
||||
cerr << " peers" << endl;
|
||||
cerr << " random" << endl;
|
||||
cerr << " ripple ..." << endl;
|
||||
cerr << " ripple_path_find <json> [<ledger>]" << endl;
|
||||
// cerr << " send <seed> <paying_account> <account_id> <amount> [<currency>] [<send_max>] [<send_currency>]" << endl;
|
||||
cerr << " stop" << endl;
|
||||
cerr << " tx <id>" << endl;
|
||||
|
||||
Submodule src/js/sjcl updated: dbdef434e7...d04d0bdccd
Reference in New Issue
Block a user