From 62f6d030c6665537c43405961cc6f12da5ad3180 Mon Sep 17 00:00:00 2001 From: jed Date: Thu, 31 Jan 2013 10:59:19 -0800 Subject: [PATCH 1/2] still working --- src/cpp/ripple/Application.cpp | 2 ++ src/cpp/ripple/Application.h | 3 +++ src/cpp/ripple/NetworkOPs.cpp | 1 + src/cpp/ripple/NetworkOPs.h | 2 ++ src/cpp/ripple/OrderBook.h | 7 +++++ src/cpp/ripple/OrderBookDB.cpp | 44 +++++++++++++++++++++++++++++++- src/cpp/ripple/OrderBookDB.h | 9 ++++++- src/cpp/ripple/Pathfinder.cpp | 8 +++--- src/cpp/ripple/Pathfinder.h | 3 +-- src/cpp/ripple/TransactionMeta.h | 1 + src/js/sjcl | 2 +- 11 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/cpp/ripple/Application.cpp b/src/cpp/ripple/Application.cpp index a2d608279c..17c37c3f43 100644 --- a/src/cpp/ripple/Application.cpp +++ b/src/cpp/ripple/Application.cpp @@ -147,6 +147,8 @@ void Application::setup() else startNewLedger(); + mOrderBookDB.setup(theApp->getLedgerMaster().getCurrentLedger()); // TODO: We need to update this if the ledger jumps + // // Begin validation and ip maintenance. // - Wallet maintains local information: including identity and network connection persistence information. diff --git a/src/cpp/ripple/Application.h b/src/cpp/ripple/Application.h index 7ba1003ce5..343c9d26c2 100644 --- a/src/cpp/ripple/Application.h +++ b/src/cpp/ripple/Application.h @@ -24,6 +24,7 @@ #include "ProofOfWork.h" #include "LoadManager.h" #include "TransactionQueue.h" +#include "OrderBookDB.h" class RPCDoor; class PeerDoor; @@ -66,6 +67,7 @@ class Application LoadManager mLoadMgr; LoadFeeTrack mFeeTrack; TXQueue mTxnQueue; + OrderBookDB mOrderBookDB; DatabaseCon *mRpcDB, *mTxnDB, *mLedgerDB, *mWalletDB, *mHashNodeDB, *mNetNodeDB; @@ -115,6 +117,7 @@ public: LoadFeeTrack& getFeeTrack() { return mFeeTrack; } TXQueue& getTxnQueue() { return mTxnQueue; } PeerDoor& getPeerDoor() { return *mPeerDoor; } + OrderBookDB& getOrderBookDB() { return mOrderBookDB; } bool isNew(const uint256& s) { return mSuppressions.addSuppression(s); } diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 3fbf0768b2..92a47fa5fc 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -1316,6 +1316,7 @@ void NetworkOPs::pubAcceptedTransaction(Ledger::ref lpCurrent, const SerializedT ispListener->send(jvObj); } } + theApp->getOrderBookDB().processTxn(stTxn, terResult, meta, jvObj); pubAccountTransaction(lpCurrent, stTxn, terResult, true, meta); } diff --git a/src/cpp/ripple/NetworkOPs.h b/src/cpp/ripple/NetworkOPs.h index 0979671fb7..c03edae49f 100644 --- a/src/cpp/ripple/NetworkOPs.h +++ b/src/cpp/ripple/NetworkOPs.h @@ -71,6 +71,7 @@ protected: typedef boost::unordered_map >::iterator subInfoMapIterator; typedef boost::unordered_map > subSubmitMapType; + //typedef boost::unordered_map > subOrderMap; typedef boost::unordered_map subRpcMapType; @@ -103,6 +104,7 @@ protected: subInfoMapType mSubAccount; subInfoMapType mSubRTAccount; subSubmitMapType mSubmitMap; // TODO: probably dump this + subRpcMapType mRpcSubMap; diff --git a/src/cpp/ripple/OrderBook.h b/src/cpp/ripple/OrderBook.h index b4556f01d9..c805040849 100644 --- a/src/cpp/ripple/OrderBook.h +++ b/src/cpp/ripple/OrderBook.h @@ -1,5 +1,7 @@ #include "SerializedLedger.h" +#include "NetworkOPs.h" #include + /* Encapsulates the SLE for an orderbook */ @@ -12,6 +14,8 @@ class OrderBook uint160 mIssuerIn; uint160 mIssuerOut; + boost::unordered_set mListeners; + //SerializedLedgerEntry::pointer mLedgerEntry; OrderBook(SerializedLedgerEntry::pointer ledgerEntry); // For accounts in a ledger public: @@ -30,6 +34,9 @@ public: // looks through the best offers to see how much it would cost to take the given amount STAmount& getTakePrice(STAmount& takeAmount); + + void addSubscriber(InfoSub* sub); + void removeSubscriber(InfoSub* sub); }; // vim:ts=4 diff --git a/src/cpp/ripple/OrderBookDB.cpp b/src/cpp/ripple/OrderBookDB.cpp index 192cab703b..0f6956f8c5 100644 --- a/src/cpp/ripple/OrderBookDB.cpp +++ b/src/cpp/ripple/OrderBookDB.cpp @@ -3,8 +3,13 @@ #include +OrderBookDB::OrderBookDB() +{ + +} + // TODO: this would be way faster if we could just look under the order dirs -OrderBookDB::OrderBookDB(Ledger::pointer ledger) +void OrderBookDB::setup(Ledger::pointer ledger) { // walk through the entire ledger looking for orderbook entries uint256 currentIndex=ledger->getFirstLedgerIndex(); @@ -53,4 +58,41 @@ void OrderBookDB::getBooks(const uint160& issuerID, const uint160& currencyID, s } } } +} + +OrderBook::pointer OrderBookDB::getBook(uint160 mCurrencyIn, uint160 mCurrencyOut, uint160 mIssuerIn, uint160 mIssuerOut) +{ + +} + +/* +"CreatedNode" : { +"LedgerEntryType" : "Offer", +"LedgerIndex" : "F353BF8A7DCE35EA2985596F4C8421E30EF3B9A21618566BFE0ED00B62A8A5AB", +"NewFields" : { +"Account" : "rB5TihdPbKgMrkFqrqUC3yLdE8hhv4BdeY", +"BookDirectory" : "FF26BE244767D0EA9EFD523941439009E4185E4CBB918F714C08E1BC9BF04000", +"Sequence" : 112, +"TakerGets" : "400000000", +"TakerPays" : { +"currency" : "BTC", +"issuer" : "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV", +"value" : "1" +} +} +}*/ + +void OrderBookDB::processTxn(const SerializedTransaction& stTxn, TER terResult,TransactionMetaSet::pointer& meta,Json::Value& jvObj) +{ + // check if this is an offer or an offer cancel or a payment that consumes an offer + //check to see what the meta looks like + BOOST_FOREACH(STObject& node,meta->getNodes()) + { + if(node.getFieldU16(sfLedgerEntryType)==ltOFFER) + { + + } + } + + } \ No newline at end of file diff --git a/src/cpp/ripple/OrderBookDB.h b/src/cpp/ripple/OrderBookDB.h index ded3562ae4..dc3983a36e 100644 --- a/src/cpp/ripple/OrderBookDB.h +++ b/src/cpp/ripple/OrderBookDB.h @@ -11,11 +11,13 @@ class OrderBookDB std::vector mEmptyVector; std::vector mXRPOrders; std::map > mIssuerMap; + //std::vector mAllOrderBooks; std::map mKnownMap; public: - OrderBookDB(Ledger::pointer ledger); + OrderBookDB(); + void setup(Ledger::pointer ledger); // return list of all orderbooks that want XRP std::vector& getXRPInBooks(){ return mXRPOrders; } @@ -27,6 +29,11 @@ public: // returns the best rate we can find float getPrice(uint160& currencyIn,uint160& currencyOut); + + OrderBook::pointer getBook(uint160 mCurrencyIn, uint160 mCurrencyOut, uint160 mIssuerIn, uint160 mIssuerOut); + // see if this txn effects any orderbook + void processTxn(const SerializedTransaction& stTxn, TER terResult,TransactionMetaSet::pointer& meta,Json::Value& jvObj); + }; // vim:ts=4 diff --git a/src/cpp/ripple/Pathfinder.cpp b/src/cpp/ripple/Pathfinder.cpp index a7f03cc1cf..efa070a189 100644 --- a/src/cpp/ripple/Pathfinder.cpp +++ b/src/cpp/ripple/Pathfinder.cpp @@ -269,7 +269,7 @@ bool Pathfinder::findPaths(const unsigned int iMaxSteps, const unsigned int iMax else if (!speEnd.mCurrencyID) { // Last element is for XRP, continue with qualifying books. - BOOST_FOREACH(OrderBook::ref book, mOrderBook.getXRPInBooks()) + BOOST_FOREACH(OrderBook::ref book, theApp->getOrderBookDB().getXRPInBooks()) { // XXX Don't allow looping through same order books. @@ -357,7 +357,7 @@ bool Pathfinder::findPaths(const unsigned int iMaxSteps, const unsigned int iMax // Every book that wants the source currency. std::vector books; - mOrderBook.getBooks(spPath.mCurrentAccount, spPath.mCurrencyID, books); + theApp->getOrderBookDB().getBooks(spPath.mCurrentAccount, spPath.mCurrencyID, books); BOOST_FOREACH(OrderBook::ref book,books) { @@ -499,7 +499,7 @@ void Pathfinder::addOptions(PathOption::pointer tail) { if (!tail->mCurrencyID) { // source XRP - BOOST_FOREACH(OrderBook::ref book, mOrderBook.getXRPInBooks()) + BOOST_FOREACH(OrderBook::ref book, theApp->getOrderBookDB().getXRPInBooks()) { PathOption::pointer pathOption(new PathOption(tail)); @@ -533,7 +533,7 @@ void Pathfinder::addOptions(PathOption::pointer tail) // every offer that wants the source currency std::vector books; - mOrderBook.getBooks(tail->mCurrentAccount, tail->mCurrencyID, books); + theApp->getOrderBookDB().getBooks(tail->mCurrentAccount, tail->mCurrencyID, books); BOOST_FOREACH(OrderBook::ref book,books) { diff --git a/src/cpp/ripple/Pathfinder.h b/src/cpp/ripple/Pathfinder.h index 5682778e49..e624d51675 100644 --- a/src/cpp/ripple/Pathfinder.h +++ b/src/cpp/ripple/Pathfinder.h @@ -3,7 +3,6 @@ #include "SerializedTypes.h" #include "RippleAddress.h" -#include "OrderBookDB.h" #include "RippleCalc.h" #include @@ -42,7 +41,7 @@ class Pathfinder uint160 mSrcIssuerID; STAmount mSrcAmount; - OrderBookDB mOrderBook; + //OrderBookDB mOrderBook; Ledger::pointer mLedger; PathState::pointer mPsDefault; diff --git a/src/cpp/ripple/TransactionMeta.h b/src/cpp/ripple/TransactionMeta.h index 5386b96b87..fd07635c8c 100644 --- a/src/cpp/ripple/TransactionMeta.h +++ b/src/cpp/ripple/TransactionMeta.h @@ -56,6 +56,7 @@ public: void addRaw(Serializer&, TER, uint32 index); STObject getAsObject() const; + STArray& getNodes(){ return(mNodes); } static bool thread(STObject& node, const uint256& prevTxID, uint32 prevLgrID); }; diff --git a/src/js/sjcl b/src/js/sjcl index dbdef434e7..d04d0bdccd 160000 --- a/src/js/sjcl +++ b/src/js/sjcl @@ -1 +1 @@ -Subproject commit dbdef434e76c3f16835f3126a7ff1c717b1ce8af +Subproject commit d04d0bdccd986e434b98fe393e1e01286c10fc36 From eb27240610fc28fac2cb6c212e31f235ef0d2469 Mon Sep 17 00:00:00 2001 From: jed Date: Tue, 5 Feb 2013 13:04:38 -0800 Subject: [PATCH 2/2] first draft --- src/cpp/ripple/NetworkOPs.cpp | 14 ++++ src/cpp/ripple/NetworkOPs.h | 3 + src/cpp/ripple/OrderBook.cpp | 2 + src/cpp/ripple/OrderBook.h | 5 -- src/cpp/ripple/OrderBookDB.cpp | 129 +++++++++++++++++++++++++++++++-- src/cpp/ripple/OrderBookDB.h | 21 +++++- src/cpp/ripple/Pathfinder.cpp | 6 +- src/cpp/ripple/RPCHandler.cpp | 34 +++++++++ test/send-test.js | 6 +- 9 files changed, 200 insertions(+), 20 deletions(-) diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 92a47fa5fc..aa9bcd9204 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -1447,6 +1447,20 @@ void NetworkOPs::unsubAccount(InfoSub* ispListener, const boost::unordered_setgetOrderBookDB().makeBookListeners(currencyIn, currencyOut, issuerIn, issuerOut); + if(listeners) listeners->addSubscriber(ispListener); + return(true); +} + +bool NetworkOPs::unsubBook(InfoSub* ispListener, uint160 currencyIn, uint160 currencyOut, uint160 issuerIn, uint160 issuerOut) +{ + BookListeners::pointer listeners=theApp->getOrderBookDB().getBookListeners(currencyIn, currencyOut, issuerIn, issuerOut); + if(listeners) listeners->removeSubscriber(ispListener); + return(true); +} + void NetworkOPs::newLCL(int proposers, int convergeTime, const uint256& ledgerHash) { assert(convergeTime); diff --git a/src/cpp/ripple/NetworkOPs.h b/src/cpp/ripple/NetworkOPs.h index c03edae49f..ae6bff9b08 100644 --- a/src/cpp/ripple/NetworkOPs.h +++ b/src/cpp/ripple/NetworkOPs.h @@ -284,6 +284,9 @@ public: bool subServer(InfoSub* ispListener, Json::Value& jvResult); bool unsubServer(InfoSub* ispListener); + bool subBook(InfoSub* ispListener, uint160 currencyIn, uint160 currencyOut, uint160 issuerIn, uint160 issuerOut); + bool unsubBook(InfoSub* ispListener, uint160 currencyIn, uint160 currencyOut, uint160 issuerIn, uint160 issuerOut); + bool subTransactions(InfoSub* ispListener); bool unsubTransactions(InfoSub* ispListener); diff --git a/src/cpp/ripple/OrderBook.cpp b/src/cpp/ripple/OrderBook.cpp index 2cf716257e..300ebcd31b 100644 --- a/src/cpp/ripple/OrderBook.cpp +++ b/src/cpp/ripple/OrderBook.cpp @@ -20,4 +20,6 @@ OrderBook::OrderBook(SerializedLedgerEntry::pointer ledgerEntry) mBookBase=Ledger::getBookBase(mCurrencyOut,mIssuerOut,mCurrencyIn,mIssuerIn); } + + // vim:ts=4 diff --git a/src/cpp/ripple/OrderBook.h b/src/cpp/ripple/OrderBook.h index c805040849..813709d3b5 100644 --- a/src/cpp/ripple/OrderBook.h +++ b/src/cpp/ripple/OrderBook.h @@ -14,8 +14,6 @@ class OrderBook uint160 mIssuerIn; uint160 mIssuerOut; - boost::unordered_set mListeners; - //SerializedLedgerEntry::pointer mLedgerEntry; OrderBook(SerializedLedgerEntry::pointer ledgerEntry); // For accounts in a ledger public: @@ -34,9 +32,6 @@ public: // looks through the best offers to see how much it would cost to take the given amount STAmount& getTakePrice(STAmount& takeAmount); - - void addSubscriber(InfoSub* sub); - void removeSubscriber(InfoSub* sub); }; // vim:ts=4 diff --git a/src/cpp/ripple/OrderBookDB.cpp b/src/cpp/ripple/OrderBookDB.cpp index 0f6956f8c5..74faa3b12a 100644 --- a/src/cpp/ripple/OrderBookDB.cpp +++ b/src/cpp/ripple/OrderBookDB.cpp @@ -2,6 +2,7 @@ #include "Log.h" #include +SETUP_LOG(); OrderBookDB::OrderBookDB() { @@ -11,6 +12,10 @@ OrderBookDB::OrderBookDB() // TODO: this would be way faster if we could just look under the order dirs void OrderBookDB::setup(Ledger::pointer ledger) { + mXRPOrders.clear(); + mIssuerMap.clear(); + mKnownMap.clear(); + // walk through the entire ledger looking for orderbook entries uint256 currentIndex=ledger->getFirstLedgerIndex(); while(currentIndex.isNonZero()) @@ -60,9 +65,37 @@ void OrderBookDB::getBooks(const uint160& issuerID, const uint160& currencyID, s } } -OrderBook::pointer OrderBookDB::getBook(uint160 mCurrencyIn, uint160 mCurrencyOut, uint160 mIssuerIn, uint160 mIssuerOut) +BookListeners::pointer OrderBookDB::makeBookListeners(uint160 currencyIn, uint160 currencyOut, uint160 issuerIn, uint160 issuerOut) { + BookListeners::pointer ret=getBookListeners(currencyIn, currencyOut, issuerIn, issuerOut); + if(!ret) + { + ret=BookListeners::pointer(new BookListeners); + mListeners[issuerIn][issuerOut][currencyIn][currencyOut]=ret; + } + return(ret); +} +BookListeners::pointer OrderBookDB::getBookListeners(uint160 currencyIn, uint160 currencyOut, uint160 issuerIn, uint160 issuerOut) +{ + std::map > > >::iterator it0=mListeners.find(issuerIn); + if(it0 != mListeners.end()) + { + std::map > >::iterator it1=(*it0).second.find(issuerOut); + if(it1 != (*it0).second.end()) + { + std::map >::iterator it2=(*it1).second.find(currencyIn); + if(it2 != (*it1).second.end()) + { + std::map::iterator it3=(*it2).second.find(currencyOut); + if(it3 != (*it2).second.end()) + { + return( (*it3).second ); + } + } + } + } + return(BookListeners::pointer()); } /* @@ -80,19 +113,101 @@ OrderBook::pointer OrderBookDB::getBook(uint160 mCurrencyIn, uint160 mCurrencyOu "value" : "1" } } -}*/ +} +"ModifiedNode" : { +"FinalFields" : { +"Account" : "rHTxKLzRbniScyQFGMb3NodmxA848W8dKM", +"BookDirectory" : "407AF8FFDE71114B1981574FDDA9B0334572D56FC579735B4B0BD7A625405555", +"BookNode" : "0000000000000000", +"Flags" : 0, +"OwnerNode" : "0000000000000000", +"Sequence" : 32, +"TakerGets" : "149900000000", +"TakerPays" : { +"currency" : "USD", +"issuer" : "r9vbV3EHvXWjSkeQ6CAcYVPGeq7TuiXY2X", +"value" : "49.96666666666667" +} +}, +"LedgerEntryType" : "Offer", +"LedgerIndex" : "C60F8CC514208FA5F7BD03CF1B64B38B7183CD52318FCBBD3726350D4FE693B0", +"PreviousFields" : { +"TakerGets" : "150000000000", +"TakerPays" : { +"currency" : "USD", +"issuer" : "r9vbV3EHvXWjSkeQ6CAcYVPGeq7TuiXY2X", +"value" : "50" +} +}, +"PreviousTxnID" : "1A6AAE3F1AC5A8A7554A5ABC395D17FED5BF62CD90181AA8E4315EDFED4EDEB3", +"PreviousTxnLgrSeq" : 140734 +} + +*/ +// Based on the meta, send the meta to the streams that are listening +// We need to determine which streams a given meta effects void OrderBookDB::processTxn(const SerializedTransaction& stTxn, TER terResult,TransactionMetaSet::pointer& meta,Json::Value& jvObj) { - // check if this is an offer or an offer cancel or a payment that consumes an offer - //check to see what the meta looks like - BOOST_FOREACH(STObject& node,meta->getNodes()) + if(terResult==tesSUCCESS) { - if(node.getFieldU16(sfLedgerEntryType)==ltOFFER) + // check if this is an offer or an offer cancel or a payment that consumes an offer + //check to see what the meta looks like + BOOST_FOREACH(STObject& node,meta->getNodes()) { + try{ + if(node.getFieldU16(sfLedgerEntryType)==ltOFFER) + { + SField* field=NULL; + if(node.getFName() == sfModifiedNode) + { + field=&sfPreviousFields; + }else if(node.getFName() == sfCreatedNode) + { + field=&sfNewFields; + } + + const STObject* previous = dynamic_cast(node.peekAtPField(*field)); + if(previous) + { + STAmount& takerGets = previous->getFieldAmount(sfTakerGets); + uint160 currencyOut=takerGets.getCurrency(); + uint160 issuerOut=takerGets.getIssuer(); + + STAmount& takerPays = previous->getFieldAmount(sfTakerPays); + uint160 currencyIn=takerPays.getCurrency(); + uint160 issuerIn=takerPays.getIssuer(); + + // determine the OrderBook + BookListeners::pointer book=getBookListeners(currencyIn,currencyOut,issuerIn,issuerOut); + if(book) book->publish(jvObj); + } + } + }catch(...) + { + cLog(lsINFO) << "Fields not found in OrderBookDB::processTxn"; + } } } - +} +void BookListeners::addSubscriber(InfoSub* sub) +{ + mListeners.insert(sub); +} + +void BookListeners::removeSubscriber(InfoSub* sub) +{ + mListeners.erase(sub); +} + +void BookListeners::publish(Json::Value& jvObj) +{ + //Json::Value jvObj=node.getJson(0); + + BOOST_FOREACH(InfoSub* sub,mListeners) + { + sub->send(jvObj); + } } \ No newline at end of file diff --git a/src/cpp/ripple/OrderBookDB.h b/src/cpp/ripple/OrderBookDB.h index dc3983a36e..1461e500c9 100644 --- a/src/cpp/ripple/OrderBookDB.h +++ b/src/cpp/ripple/OrderBookDB.h @@ -1,11 +1,24 @@ #include "Ledger.h" #include "OrderBook.h" +#include + /* we can eventually make this cached and just update it as transactions come in. But for now it is probably faster to just generate it each time */ +class BookListeners +{ + boost::unordered_set mListeners; +public: + typedef boost::shared_ptr pointer; + + void addSubscriber(InfoSub* sub); + void removeSubscriber(InfoSub* sub); + void publish(Json::Value& jvObj); +}; + class OrderBookDB { std::vector mEmptyVector; @@ -13,6 +26,9 @@ class OrderBookDB std::map > mIssuerMap; //std::vector mAllOrderBooks; + // issuerIn, issuerOut, currencyIn, currencyOut + std::map > > > mListeners; + std::map mKnownMap; public: @@ -30,10 +46,11 @@ public: float getPrice(uint160& currencyIn,uint160& currencyOut); - OrderBook::pointer getBook(uint160 mCurrencyIn, uint160 mCurrencyOut, uint160 mIssuerIn, uint160 mIssuerOut); + BookListeners::pointer getBookListeners(uint160 currencyIn, uint160 currencyOut, uint160 issuerIn, uint160 issuerOut); + BookListeners::pointer makeBookListeners(uint160 currencyIn, uint160 currencyOut, uint160 issuerIn, uint160 issuerOut); + // see if this txn effects any orderbook void processTxn(const SerializedTransaction& stTxn, TER terResult,TransactionMetaSet::pointer& meta,Json::Value& jvObj); - }; // vim:ts=4 diff --git a/src/cpp/ripple/Pathfinder.cpp b/src/cpp/ripple/Pathfinder.cpp index efa070a189..eaba5e6688 100644 --- a/src/cpp/ripple/Pathfinder.cpp +++ b/src/cpp/ripple/Pathfinder.cpp @@ -12,8 +12,6 @@ SETUP_LOG(); /* -JED: V IIII - we just need to find a succession of the highest quality paths there until we find enough width Don't do branching within each path @@ -133,11 +131,13 @@ bool Pathfinder::bDefaultPath(const STPath& spPath) // functionality is left to the future. // Pathfinder::Pathfinder(const RippleAddress& uSrcAccountID, const RippleAddress& uDstAccountID, const uint160& uSrcCurrencyID, const uint160& uSrcIssuerID, const STAmount& saDstAmount) - : mSrcAccountID(uSrcAccountID.getAccountID()), mDstAccountID(uDstAccountID.getAccountID()), mDstAmount(saDstAmount), mSrcCurrencyID(uSrcCurrencyID), mSrcIssuerID(uSrcIssuerID), mOrderBook(theApp->getLedgerMaster().getCurrentLedger()) + : mSrcAccountID(uSrcAccountID.getAccountID()), mDstAccountID(uDstAccountID.getAccountID()), mDstAmount(saDstAmount), mSrcCurrencyID(uSrcCurrencyID), mSrcIssuerID(uSrcIssuerID) { mLedger = theApp->getLedgerMaster().getCurrentLedger(); mSrcAmount = STAmount(uSrcCurrencyID, uSrcIssuerID, 1, 0, true); // -1/uSrcIssuerID/uSrcIssuerID + theApp->getOrderBookDB().setup( theApp->getLedgerMaster().getCurrentLedger()); // TODO: have the orderbook update itself rather than rebuild it from scratch each time + // Construct the default path for later comparison. PathState::pointer psDefault = boost::make_shared(mDstAmount, mSrcAmount, mLedger); diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index e6a245aad6..7f2045779b 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -2449,6 +2449,25 @@ Json::Value RPCHandler::doSubscribe(Json::Value jvRequest) } } + if (jvRequest.isMember("books")) + { + for (Json::Value::iterator it = jvRequest["books"].begin(); it != jvRequest["books"].end(); it++) + { + uint160 currencyOut; + STAmount::issuerFromString(currencyOut,(*it)["CurrencyOut"].asString()); + uint160 issuerOut=RippleAddress::createNodePublic( (*it)["IssuerOut"].asString() ).getAccountID(); + uint160 currencyIn; + STAmount::issuerFromString(currencyOut,(*it)["CurrencyIn"].asString()); + uint160 issuerIn=RippleAddress::createNodePublic( (*it)["IssuerIn"].asString() ).getAccountID(); + + mNetOps->subBook(ispSub,currencyIn,currencyOut,issuerIn,issuerOut); + if((*it)["StateNow"].asBool()) + { + + } + } + } + return jvResult; } @@ -2546,6 +2565,21 @@ Json::Value RPCHandler::doUnsubscribe(Json::Value jvRequest) } } + if (jvRequest.isMember("books")) + { + for (Json::Value::iterator it = jvRequest["books"].begin(); it != jvRequest["books"].end(); it++) + { + uint160 currencyOut; + STAmount::issuerFromString(currencyOut,(*it)["CurrencyOut"].asString()); + uint160 issuerOut=RippleAddress::createNodePublic( (*it)["IssuerOut"].asString() ).getAccountID(); + uint160 currencyIn; + STAmount::issuerFromString(currencyOut,(*it)["CurrencyIn"].asString()); + uint160 issuerIn=RippleAddress::createNodePublic( (*it)["IssuerIn"].asString() ).getAccountID(); + + mNetOps->unsubBook(ispSub,currencyIn,currencyOut,issuerIn,issuerOut); + } + } + return jvResult; } diff --git a/test/send-test.js b/test/send-test.js index d2fe9c7f32..98bf63d0e0 100644 --- a/test/send-test.js +++ b/test/send-test.js @@ -40,8 +40,8 @@ buster.testCase("Fee Changes", { */ buster.testCase("Sending", { - 'setUp' : testutils.build_setup(), - // 'setUp' : testutils.build_setup({verbose: true , no_server: true}), + //'setUp' : testutils.build_setup(), + 'setUp' : testutils.build_setup({verbose: true , no_server: true}), 'tearDown' : testutils.build_teardown(), "send XRP to non-existent account with insufficent fee" : @@ -975,7 +975,7 @@ buster.testCase("Indirect ripple", { }); }, - "indirect ripple with path" : + "=> indirect ripple with path" : function (done) { var self = this;