diff --git a/newcoin.vcxproj b/newcoin.vcxproj index 6a20b4ec24..5b3889f069 100644 --- a/newcoin.vcxproj +++ b/newcoin.vcxproj @@ -95,6 +95,7 @@ + @@ -129,6 +130,7 @@ + @@ -148,10 +150,10 @@ - + @@ -199,6 +201,7 @@ + @@ -232,6 +235,7 @@ + @@ -251,7 +255,6 @@ - diff --git a/newcoin.vcxproj.filters b/newcoin.vcxproj.filters index 8b4cedd1e3..f8070562c7 100644 --- a/newcoin.vcxproj.filters +++ b/newcoin.vcxproj.filters @@ -189,9 +189,6 @@ Source Files - - Source Files - Source Files @@ -345,6 +342,15 @@ Source Files + + Source Files + + + Source Files + + + Source Files + @@ -509,9 +515,6 @@ Header Files - - Header Files - Header Files @@ -647,6 +650,12 @@ Header Files + + Header Files + + + Header Files + diff --git a/src/cpp/ripple/AccountItems.cpp b/src/cpp/ripple/AccountItems.cpp new file mode 100644 index 0000000000..b10937e23e --- /dev/null +++ b/src/cpp/ripple/AccountItems.cpp @@ -0,0 +1,57 @@ +#include "AccountItems.h" + +#include + +#include "Application.h" +#include "Log.h" + +SETUP_LOG(); + +AccountItem::AccountItem(SerializedLedgerEntry::pointer ledger) : mLedgerEntry(ledger) +{ + +} + +AccountItems::AccountItems(uint160& accountID, Ledger::ref ledger, AccountItem::pointer ofType) +{ + mOfType=ofType; + fillItems(accountID, ledger); +} + +// looks in the current ledger +AccountItems::AccountItems(uint160& accountID, AccountItem::pointer ofType ) +{ + mOfType=ofType; + fillItems(accountID,theApp->getLedgerMaster().getClosedLedger()); +} + +void AccountItems::fillItems(uint160& accountID, Ledger::ref ledger) +{ + uint256 rootIndex = Ledger::getOwnerDirIndex(accountID); + uint256 currentIndex = rootIndex; + + LedgerStateParms lspNode = lepNONE; + + while (1) + { + SLE::pointer ownerDir=ledger->getDirNode(lspNode, currentIndex); + if (!ownerDir) return; + + STVector256 svOwnerNodes = ownerDir->getFieldV256(sfIndexes); + BOOST_FOREACH(uint256& uNode, svOwnerNodes.peekValue()) + { + SLE::pointer sleCur = ledger->getSLE(uNode); + + AccountItem::pointer item=mOfType->makeItem(accountID, sleCur); + if(item) + { + mItems.push_back(item); + } + } + + uint64 uNodeNext = ownerDir->getFieldU64(sfIndexNext); + if (!uNodeNext) return; + + currentIndex = Ledger::getDirNodeIndex(rootIndex, uNodeNext); + } +} \ No newline at end of file diff --git a/src/cpp/ripple/AccountItems.h b/src/cpp/ripple/AccountItems.h new file mode 100644 index 0000000000..4d30161892 --- /dev/null +++ b/src/cpp/ripple/AccountItems.h @@ -0,0 +1,42 @@ +#ifndef __ACCOUNT_ITEMS__ +#define __ACCOUNT_ITEMS__ + +#include "Ledger.h" +#include "SerializedLedger.h" + +/* +Way to fetch ledger entries from an account's owner dir +*/ +class AccountItem +{ +protected: + SerializedLedgerEntry::pointer mLedgerEntry; +public: + typedef boost::shared_ptr pointer; + AccountItem(){ } + AccountItem(SerializedLedgerEntry::pointer ledger); + virtual AccountItem::pointer makeItem(uint160& accountID, SerializedLedgerEntry::pointer ledgerEntry)=0; + virtual LedgerEntryType getType()=0; + + SerializedLedgerEntry::pointer getSLE() { return mLedgerEntry; } + const SerializedLedgerEntry& peekSLE() const { return *mLedgerEntry; } + SerializedLedgerEntry& peekSLE() { return *mLedgerEntry; } + + std::vector getRaw() const; +}; + +class AccountItems +{ + AccountItem::pointer mOfType; + + std::vector mItems; + void fillItems(uint160& accountID, Ledger::ref ledger); +public: + + AccountItems(uint160& accountID, Ledger::ref ledger, AccountItem::pointer ofType); + AccountItems(uint160& accountID, AccountItem::pointer ofType ); // looks in the current ledger + + std::vector& getItems() { return(mItems); } +}; + +#endif diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index 9b5b4c8267..b9b5cb529e 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -217,8 +217,9 @@ Json::Value RPCParser::parseOwnerInfo(const Json::Value& jvParams) return parseAccountInfo(jvParams); } -// ripple_lines_get || [] -Json::Value RPCParser::parseRippleLinesGet(const Json::Value& jvParams) +// account_lines || [] +// account_offers || [] +Json::Value RPCParser::parseAccountItems(const Json::Value& jvParams) { std::string strIdent = jvParams[0u].asString(); bool bIndex = 2 == jvParams.size(); @@ -237,6 +238,7 @@ Json::Value RPCParser::parseRippleLinesGet(const Json::Value& jvParams) return jvRequest; } + // submit any transaction to the network // submit private_key json Json::Value RPCParser::parseSubmit(const Json::Value& jvParams) @@ -407,7 +409,8 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) { "owner_info", &RPCParser::parseOwnerInfo, 1, 2 }, { "peers", &RPCParser::parseAsIs, 0, 0 }, // { "profile", &RPCParser::parseProfile, 1, 9 }, - { "ripple_lines_get", &RPCParser::parseRippleLinesGet, 1, 2 }, + { "account_lines", &RPCParser::parseAccountItems, 1, 2 }, + { "account_offers", &RPCParser::parseAccountItems, 1, 2 }, // { "ripple_path_find", &RPCParser::parseRipplePathFind, -1, -1 }, { "submit", &RPCParser::parseSubmit, 2, 2 }, { "server_info", &RPCParser::parseAsIs, 0, 0 }, diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index a109a73d57..4654533bcb 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -23,7 +23,7 @@ protected: Json::Value parseLedger(const Json::Value& jvParams); Json::Value parseLogin(const Json::Value& jvParams); Json::Value parseOwnerInfo(const Json::Value& jvParams); - Json::Value parseRippleLinesGet(const Json::Value& jvParams); + Json::Value parseAccountItems(const Json::Value& jvParams); Json::Value parseSubmit(const Json::Value& jvParams); Json::Value parseTx(const Json::Value& jvParams); Json::Value parseTxHistory(const Json::Value& jvParams); diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index 8e3c47c6b4..bddd92a877 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -210,21 +210,6 @@ NicknameState::pointer Ledger::getNicknameState(const uint256& uNickname) return boost::make_shared(sle); } -RippleState::pointer Ledger::accessRippleState(const uint256& uNode) -{ - ScopedLock l(mAccountStateMap->Lock()); - SHAMapItem::pointer item = mAccountStateMap->peekItem(uNode); - if (!item) - { - return RippleState::pointer(); - } - - SerializedLedgerEntry::pointer sle = - boost::make_shared(item->peekSerializer(), item->getTag()); - if (sle->getType() != ltRIPPLE_STATE) return RippleState::pointer(); - return boost::make_shared(sle); -} - bool Ledger::addTransaction(const uint256& txID, const Serializer& txn) { // low-level - just add to table SHAMapItem::pointer item = boost::make_shared(txID, txn.peekData()); diff --git a/src/cpp/ripple/Ledger.h b/src/cpp/ripple/Ledger.h index a9b5605710..bfbe405342 100644 --- a/src/cpp/ripple/Ledger.h +++ b/src/cpp/ripple/Ledger.h @@ -13,7 +13,6 @@ #include "Transaction.h" #include "TransactionMeta.h" #include "AccountState.h" -#include "RippleState.h" #include "NicknameState.h" #include "types.h" #include "BitcoinUtil.h" @@ -291,8 +290,6 @@ public: static uint256 getRippleStateIndex(const uint160& uiA, const uint160& uiB, const uint160& uCurrency) { return getRippleStateIndex(RippleAddress::createAccountID(uiA), RippleAddress::createAccountID(uiB), uCurrency); } - RippleState::pointer accessRippleState(const uint256& uNode); - SLE::pointer getRippleState(LedgerStateParms& parms, const uint256& uNode); SLE::pointer getRippleState(const uint256& uNode) diff --git a/src/cpp/ripple/Offer.cpp b/src/cpp/ripple/Offer.cpp new file mode 100644 index 0000000000..8df29139b7 --- /dev/null +++ b/src/cpp/ripple/Offer.cpp @@ -0,0 +1,15 @@ +#include "Offer.h" + +AccountItem::pointer Offer::makeItem(uint160& ,SerializedLedgerEntry::pointer ledgerEntry) +{ + if (!mLedgerEntry || mLedgerEntry->getType() != ltOFFER) return(AccountItem::pointer()); + Offer* offer=new Offer(ledgerEntry); + return(AccountItem::pointer(offer)); +} + +Offer::Offer(SerializedLedgerEntry::pointer ledgerEntry) : AccountItem(ledgerEntry) +{ + mAccount=mLedgerEntry->getFieldAccount(sfAccount); + mTakerGets = mLedgerEntry->getFieldAmount(sfTakerGets); + mTakerPays = mLedgerEntry->getFieldAmount(sfTakerPays); +} \ No newline at end of file diff --git a/src/cpp/ripple/Offer.h b/src/cpp/ripple/Offer.h new file mode 100644 index 0000000000..6b2693bda5 --- /dev/null +++ b/src/cpp/ripple/Offer.h @@ -0,0 +1,21 @@ +#include "AccountItems.h" + + +class Offer : public AccountItem +{ + RippleAddress mAccount; + STAmount mTakerGets; + STAmount mTakerPays; + + + Offer(SerializedLedgerEntry::pointer ledgerEntry); // For accounts in a ledger +public: + Offer(){} + AccountItem::pointer makeItem(uint160&, SerializedLedgerEntry::pointer ledgerEntry); + LedgerEntryType getType(){ return(ltOFFER); } + + STAmount getTakerPays(){ return(mTakerPays); } + STAmount getTakerGets(){ return(mTakerGets); } + RippleAddress getAccount(){ return(mAccount); } + +}; \ No newline at end of file diff --git a/src/cpp/ripple/Pathfinder.cpp b/src/cpp/ripple/Pathfinder.cpp index 52d1b96f7d..d8739fb092 100644 --- a/src/cpp/ripple/Pathfinder.cpp +++ b/src/cpp/ripple/Pathfinder.cpp @@ -1,6 +1,6 @@ #include "Pathfinder.h" #include "Application.h" -#include "RippleLines.h" +#include "AccountItems.h" #include "Log.h" #include @@ -221,10 +221,12 @@ bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet // Last element is for non-XRP continue by adding ripple lines and order books. // Create new paths for each outbound account not already in the path. - RippleLines rippleLines(ele.mAccountID); + AccountItems rippleLines(ele.mAccountID, AccountItem::pointer(new RippleState())); - BOOST_FOREACH(RippleState::pointer line, rippleLines.getLines()) + BOOST_FOREACH(AccountItem::pointer item, rippleLines.getItems()) { + RippleState* line=(RippleState*)item.get(); + if (!path.hasSeen(line->getAccountIDPeer().getAccountID())) { STPath new_path(path); diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 318b19034f..59577ead69 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -6,7 +6,7 @@ #include "NetworkOPs.h" #include "RPCHandler.h" #include "Application.h" -#include "RippleLines.h" +#include "AccountItems.h" #include "Wallet.h" #include "RippleAddress.h" #include "RippleCalc.h" @@ -14,6 +14,7 @@ #include "AccountState.h" #include "NicknameState.h" #include "InstanceCounter.h" +#include "Offer.h" #include "Pathfinder.h" #include @@ -566,7 +567,7 @@ Json::Value RPCHandler::doProfile(Json::Value params) // account: || [] // index: // optional, defaults to 0. // } -Json::Value RPCHandler::doRippleLinesGet(Json::Value jvRequest) +Json::Value RPCHandler::doAccountLines(Json::Value jvRequest) { std::string strIdent = jvRequest["account"].asString(); bool bIndex = jvRequest.isMember("index"); @@ -597,17 +598,18 @@ Json::Value RPCHandler::doRippleLinesGet(Json::Value jvRequest) // XXX This is wrong, we do access the current ledger and do need to worry about changes. // We access a committed ledger and need not worry about changes. - RippleLines rippleLines(raAccount.getAccountID()); - BOOST_FOREACH(RippleState::pointer line, rippleLines.getLines()) + AccountItems rippleLines(raAccount.getAccountID(), AccountItem::pointer(new RippleState())); + BOOST_FOREACH(AccountItem::pointer item, rippleLines.getItems()) { + RippleState* line=(RippleState*)item.get(); + STAmount saBalance = line->getBalance(); STAmount saLimit = line->getLimit(); STAmount saLimitPeer = line->getLimitPeer(); Json::Value jPeer = Json::Value(Json::objectValue); - //jPeer["node"] = uNode.ToString(); - + jPeer["account"] = line->getAccountIDPeer().humanAccountID(); // Amount reported is positive if current account holds other account's IOUs. // Amount reported is negative if other account holds current account's IOUs. @@ -630,6 +632,63 @@ Json::Value RPCHandler::doRippleLinesGet(Json::Value jvRequest) return jvResult; } +// { +// account: || [] +// index: // optional, defaults to 0. +// } +Json::Value RPCHandler::doAccountOffers(Json::Value jvRequest) +{ + std::string strIdent = jvRequest["account"].asString(); + bool bIndex = jvRequest.isMember("index"); + int iIndex = bIndex ? jvRequest["index"].asUInt() : 0; + + RippleAddress raAccount; + + Json::Value jvResult; + + jvResult = accountFromString(uint256(0), raAccount, bIndex, strIdent, iIndex); + + if (!jvResult.empty()) + return jvResult; + + // Get info on account. + + jvResult["account"] = raAccount.humanAccountID(); + if (bIndex) + jvResult["index"] = iIndex; + + AccountState::pointer as = mNetOps->getAccountState(uint256(0), raAccount); + if (as) + { + Json::Value jsonLines(Json::arrayValue); + + AccountItems offers(raAccount.getAccountID(), AccountItem::pointer(new Offer())); + BOOST_FOREACH(AccountItem::pointer item, offers.getItems()) + { + Offer* offer=(Offer*)item.get(); + + STAmount takerPays = offer->getTakerPays(); + STAmount takerGets = offer->getTakerGets(); + //RippleAddress account = offer->getAccount(); + + Json::Value obj = Json::Value(Json::objectValue); + + //obj["account"] = account.humanAccountID(); + obj["taker_pays"] = takerPays.getJson(0); + obj["taker_gets"] = takerGets.getJson(0); + + jsonLines.append(obj); + } + jvResult["offers"] = jsonLines; + } + else + { + jvResult = rpcError(rpcACT_NOT_FOUND); + } + + return jvResult; +} + // TODO: // - Add support for specifying non-endpoint issuer. // - Return fully expanded path with proof. @@ -2218,7 +2277,8 @@ Json::Value RPCHandler::doCommand(Json::Value& jvRequest, int iRole) { "owner_info", &RPCHandler::doOwnerInfo, false, false, optCurrent }, { "peers", &RPCHandler::doPeers, true, false, optNone }, // { "profile", &RPCHandler::doProfile, false, false, optCurrent }, - { "ripple_lines_get", &RPCHandler::doRippleLinesGet, false, false, optCurrent }, + { "account_lines", &RPCHandler::doAccountLines, false, false, optCurrent }, + { "account_offers", &RPCHandler::doAccountOffers, false, false, optCurrent }, { "ripple_path_find", &RPCHandler::doRipplePathFind, false, false, optCurrent }, { "submit", &RPCHandler::doSubmit, false, false, optCurrent }, { "server_info", &RPCHandler::doServerInfo, true, false, optNone }, diff --git a/src/cpp/ripple/RPCHandler.h b/src/cpp/ripple/RPCHandler.h index 080defe65f..31b90e1f6f 100644 --- a/src/cpp/ripple/RPCHandler.h +++ b/src/cpp/ripple/RPCHandler.h @@ -53,7 +53,8 @@ class RPCHandler Json::Value doProfile(Json::Value params); Json::Value doPeers(Json::Value params); - Json::Value doRippleLinesGet(Json::Value params); + Json::Value doAccountLines(Json::Value params); + Json::Value doAccountOffers(Json::Value params); Json::Value doRipplePathFind(Json::Value jvRequest); Json::Value doServerInfo(Json::Value params); Json::Value doSessionClose(Json::Value params); diff --git a/src/cpp/ripple/RippleLines.cpp b/src/cpp/ripple/RippleLines.cpp deleted file mode 100644 index 8d0a79af50..0000000000 --- a/src/cpp/ripple/RippleLines.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "RippleLines.h" - -#include - -#include "Application.h" -#include "Log.h" - -SETUP_LOG(); - -RippleLines::RippleLines(const uint160& accountID, Ledger::ref ledger) -{ - fillLines(accountID, ledger); -} - -void RippleLines::printRippleLines() -{ - for (unsigned int i =0; i < mLines.size(); i++) { - std::cerr << i << ": " << mLines[i]->getAccountID().humanAccountID() << std::endl; - } - std::cerr << std::endl; -} - -RippleLines::RippleLines(const uint160& accountID ) -{ - fillLines(accountID,theApp->getLedgerMaster().getCurrentLedger()); -} - -void RippleLines::fillLines(const uint160& accountID, Ledger::ref ledger) -{ - uint256 rootIndex = Ledger::getOwnerDirIndex(accountID); - uint256 currentIndex = rootIndex; - - LedgerStateParms lspNode = lepNONE; - - while (1) - { - SLE::pointer rippleDir=ledger->getDirNode(lspNode, currentIndex); - if (!rippleDir) return; - - STVector256 svOwnerNodes = rippleDir->getFieldV256(sfIndexes); - BOOST_FOREACH(uint256& uNode, svOwnerNodes.peekValue()) - { - SLE::pointer sleCur = ledger->getSLE(uNode); - - if (ltRIPPLE_STATE == sleCur->getType()) - { - RippleState::pointer rsLine = ledger->accessRippleState(uNode); - if (rsLine) - { - rsLine->setViewAccount(accountID); - mLines.push_back(rsLine); - } - else - { - cLog(lsWARNING) << "doRippleLinesGet: Bad index: " << uNode.ToString(); - } - } - } - - uint64 uNodeNext = rippleDir->getFieldU64(sfIndexNext); - if (!uNodeNext) return; - - currentIndex = Ledger::getDirNodeIndex(rootIndex, uNodeNext); - } -} -// vim:ts=4 diff --git a/src/cpp/ripple/RippleLines.h b/src/cpp/ripple/RippleLines.h deleted file mode 100644 index 5ddd47e04d..0000000000 --- a/src/cpp/ripple/RippleLines.h +++ /dev/null @@ -1,20 +0,0 @@ -#include "Ledger.h" -#include "RippleState.h" - -/* -This pulls all the ripple lines of a given account out of the ledger. -It provides a vector so you to easily iterate through them -*/ - -class RippleLines -{ - std::vector mLines; - void fillLines(const uint160& accountID, Ledger::ref ledger); -public: - - RippleLines(const uint160& accountID, Ledger::ref ledger); - RippleLines(const uint160& accountID ); // looks in the current ledger - - std::vector& getLines() { return(mLines); } - void printRippleLines(); -}; diff --git a/src/cpp/ripple/RippleState.cpp b/src/cpp/ripple/RippleState.cpp index ad814d3760..c7bb2b4993 100644 --- a/src/cpp/ripple/RippleState.cpp +++ b/src/cpp/ripple/RippleState.cpp @@ -1,12 +1,19 @@ #include "RippleState.h" -RippleState::RippleState(SerializedLedgerEntry::pointer ledgerEntry) : - mLedgerEntry(ledgerEntry), + +AccountItem::pointer RippleState::makeItem(uint160& accountID, SerializedLedgerEntry::pointer ledgerEntry) +{ + if (!mLedgerEntry || mLedgerEntry->getType() != ltRIPPLE_STATE) return(AccountItem::pointer()); + RippleState* rs=new RippleState(ledgerEntry); + rs->setViewAccount(accountID); + + return(AccountItem::pointer(rs)); +} + +RippleState::RippleState(SerializedLedgerEntry::pointer ledgerEntry) : AccountItem(ledgerEntry), mValid(false), mViewLowest(true) { - if (!mLedgerEntry || mLedgerEntry->getType() != ltRIPPLE_STATE) return; - mLowLimit = mLedgerEntry->getFieldAmount(sfLowLimit); mHighLimit = mLedgerEntry->getFieldAmount(sfHighLimit); diff --git a/src/cpp/ripple/RippleState.h b/src/cpp/ripple/RippleState.h index 047c661dfa..7886e905f5 100644 --- a/src/cpp/ripple/RippleState.h +++ b/src/cpp/ripple/RippleState.h @@ -7,17 +7,16 @@ // #include "SerializedLedger.h" +#include "AccountItems.h" #include -class RippleState +class RippleState : public AccountItem { public: typedef boost::shared_ptr pointer; private: - SerializedLedgerEntry::pointer mLedgerEntry; - RippleAddress mLowID; RippleAddress mHighID; @@ -34,8 +33,11 @@ private: bool mValid; bool mViewLowest; -public: RippleState(SerializedLedgerEntry::pointer ledgerEntry); // For accounts in a ledger +public: + RippleState(){ } + AccountItem::pointer makeItem(uint160& accountID, SerializedLedgerEntry::pointer ledgerEntry); + LedgerEntryType getType(){ return(ltRIPPLE_STATE); } void setViewAccount(const uint160& accountID); diff --git a/src/cpp/ripple/main.cpp b/src/cpp/ripple/main.cpp index 7089b20329..34d262f4d9 100644 --- a/src/cpp/ripple/main.cpp +++ b/src/cpp/ripple/main.cpp @@ -40,6 +40,8 @@ void printHelp(const po::options_description& desc) cerr << "Commands: " << endl; cerr << " account_domain_set []" << endl; cerr << " account_email_set []" << endl; + cerr << " account_lines || []" << endl; + cerr << " account_offers || []" << endl; cerr << " account_info |" << endl; cerr << " account_info || []" << endl; cerr << " account_message_set " << endl; @@ -60,7 +62,6 @@ void printHelp(const po::options_description& desc) cerr << " password_set []" << endl; cerr << " peers" << endl; cerr << " ripple ..." << endl; - cerr << " ripple_lines_get || []" << endl; cerr << " ripple_line_set [] []" << endl; cerr << " send [] [] []" << endl; cerr << " stop" << endl; diff --git a/src/js/remote.js b/src/js/remote.js index b88b6f0ecc..07d15b2c0b 100644 --- a/src/js/remote.js +++ b/src/js/remote.js @@ -698,11 +698,11 @@ Remote.prototype.request_transaction_entry = function (hash) { .tx_hash(hash); }; -Remote.prototype.request_ripple_lines_get = function (accountID, index) { +Remote.prototype.request_account_lines = function (accountID, index) { // XXX Does this require the server to be trusted? //utils.assert(this.trusted); - var request = new Request(this, 'ripple_lines_get'); + var request = new Request(this, 'account_lines'); request.message.account = accountID;