From b03f73067f7af485b9d880125b987d4ce31247b4 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sat, 14 Jul 2012 12:52:19 -0700 Subject: [PATCH 1/7] Add clang support to SConstruct. --- SConstruct | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SConstruct b/SConstruct index 34908985e5..18178dafe3 100644 --- a/SConstruct +++ b/SConstruct @@ -14,6 +14,10 @@ env = Environment( tools = ['default', 'protoc'] ) +# Use clang +#env.Replace(CC = 'clang') +#env.Replace(CXX = 'clang++') + # # Builder for CTags # From 520a8039b46cb2bcd056856abb6084bfb63b8722 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sat, 14 Jul 2012 12:52:51 -0700 Subject: [PATCH 2/7] Remove "none" support from accountID. --- src/NewcoinAddress.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/NewcoinAddress.cpp b/src/NewcoinAddress.cpp index 70eca319c7..2cdaa0515b 100644 --- a/src/NewcoinAddress.cpp +++ b/src/NewcoinAddress.cpp @@ -302,16 +302,7 @@ std::string NewcoinAddress::humanAccountID() const bool NewcoinAddress::setAccountID(const std::string& strAccountID) { - if (strAccountID == "none") - { - SetData(VER_ACCOUNT_ID, std::vector()); - - return true; - } - else - { - return SetString(strAccountID.c_str(), VER_ACCOUNT_ID); - } + return SetString(strAccountID.c_str(), VER_ACCOUNT_ID); } void NewcoinAddress::setAccountID(const uint160& hash160) From f6fcef9101e4915d5ed99d7464b04a3467956a78 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sat, 14 Jul 2012 12:53:07 -0700 Subject: [PATCH 3/7] Misc fixes. --- src/Amount.cpp | 3 +- src/ConnectionPool.cpp | 4 +- src/NewcoinAddress.cpp | 13 +- src/RPCServer.cpp | 3 +- src/SerializedLedger.h | 2 +- src/TransactionEngine.cpp | 331 +++++++++++++++++++------------------- src/TransactionEngine.h | 1 + 7 files changed, 184 insertions(+), 173 deletions(-) diff --git a/src/Amount.cpp b/src/Amount.cpp index 068e1f8e43..a5ba86d145 100644 --- a/src/Amount.cpp +++ b/src/Amount.cpp @@ -55,7 +55,6 @@ std::string STAmount::getCurrencyHuman() const } else { - uint160 uReserved = mCurrency; Serializer s(160/8); s.add160(mCurrency); @@ -123,7 +122,7 @@ bool STAmount::setValue(const std::string& sAmount, const std::string& sCurrency // ^1 2 0 2 -1 // 123^ 4 3 1 0 // 1^23 4 1 3 -2 - iOffset = -(sAmount.size()-uDecimal-1); + iOffset = -int(sAmount.size()-uDecimal-1); // Issolate integer and fraction. diff --git a/src/ConnectionPool.cpp b/src/ConnectionPool.cpp index 6497ede5f6..2a7f38bb7e 100644 --- a/src/ConnectionPool.cpp +++ b/src/ConnectionPool.cpp @@ -463,8 +463,8 @@ bool ConnectionPool::peerScanSet(const std::string& strIp, int iPort) else { // Scan connection terminated, already scheduled for retry. - boost::posix_time::ptime tpNow = boost::posix_time::second_clock::universal_time(); - boost::posix_time::ptime tpNext = ptFromSeconds(db->getInt("ScanNext")); + // boost::posix_time::ptime tpNow = boost::posix_time::second_clock::universal_time(); + // boost::posix_time::ptime tpNext = ptFromSeconds(db->getInt("ScanNext")); //Log(lsINFO) << str(boost::format("Pool: Scan: schedule exists: %s %s (next %s, delay=%d)") // % mScanIp % mScanPort % tpNext % (tpNext-tpNow).total_seconds()); diff --git a/src/NewcoinAddress.cpp b/src/NewcoinAddress.cpp index 2cdaa0515b..29b87fe378 100644 --- a/src/NewcoinAddress.cpp +++ b/src/NewcoinAddress.cpp @@ -139,7 +139,7 @@ std::string NewcoinAddress::humanNodePublic() const bool NewcoinAddress::setNodePublic(const std::string& strPublic) { - return SetString(strPublic.c_str(), VER_NODE_PUBLIC); + return SetString(strPublic.c_str(), VER_NODE_PUBLIC); } void NewcoinAddress::setNodePublic(const std::vector& vPublic) @@ -302,7 +302,16 @@ std::string NewcoinAddress::humanAccountID() const bool NewcoinAddress::setAccountID(const std::string& strAccountID) { - return SetString(strAccountID.c_str(), VER_ACCOUNT_ID); + if (strAccountID.empty()) + { + setAccountID(uint160()); + + return true; + } + else + { + return SetString(strAccountID.c_str(), VER_ACCOUNT_ID); + } } void NewcoinAddress::setAccountID(const uint160& hash160) diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index d91a13e0cd..623dc1d94d 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -1504,9 +1504,10 @@ Json::Value RPCServer::doAccountTransactions(const Json::Value& params) else maxLedger = minLedger; - if ((maxLedger < minLedger) || (minLedger < 0) || (maxLedger == 0)) + if ((maxLedger < minLedger) || (maxLedger == 0)) { std::cerr << "minL=" << minLedger << ", maxL=" << maxLedger << std::endl; + return RPCError(rpcLGR_IDXS_INVALID); } diff --git a/src/SerializedLedger.h b/src/SerializedLedger.h index 0388e3c49d..6df79d7e88 100644 --- a/src/SerializedLedger.h +++ b/src/SerializedLedger.h @@ -65,7 +65,7 @@ public: void setIFieldU8(SOE_Field field, unsigned char v) { return mObject.setValueFieldU8(field, v); } void setIFieldU16(SOE_Field field, uint16 v) { return mObject.setValueFieldU16(field, v); } void setIFieldU32(SOE_Field field, uint32 v) { return mObject.setValueFieldU32(field, v); } - void setIFieldU64(SOE_Field field, uint32 v) { return mObject.setValueFieldU64(field, v); } + void setIFieldU64(SOE_Field field, uint64 v) { return mObject.setValueFieldU64(field, v); } void setIFieldH128(SOE_Field field, const uint128& v) { return mObject.setValueFieldH128(field, v); } void setIFieldH160(SOE_Field field, const uint160& v) { return mObject.setValueFieldH160(field, v); } void setIFieldH256(SOE_Field field, const uint256& v) { return mObject.setValueFieldH256(field, v); } diff --git a/src/TransactionEngine.cpp b/src/TransactionEngine.cpp index 436fa8f9ae..b05208d012 100644 --- a/src/TransactionEngine.cpp +++ b/src/TransactionEngine.cpp @@ -15,7 +15,8 @@ #include "utils.h" #include "Log.h" -#define DIR_NODE_MAX 32 +// Small for testing, should likely be 32 or 64. +#define DIR_NODE_MAX 2 bool transResultInfo(TransactionEngineResult terCode, std::string& strToken, std::string& strHuman) { @@ -170,32 +171,26 @@ TransactionEngineResult TransactionEngine::dirAdd( if (!sleRoot) { // No root, make it. + sleRoot = entryCreate(ltDIR_NODE, uRootIndex); + + sleNode = sleRoot; uNodeDir = 0; - - sleRoot = entryCreate(ltDIR_NODE, uRootIndex); - - sleNode = sleRoot; } else { uNodeDir = sleRoot->getIFieldU64(sfIndexPrevious); // Get index to last directory node. - uint64 uNodePrevious = uNodeDir; - uint256 uNodeIndex; // Index of node. - if (uNodeDir) { // Try adding to non-root. - uNodeIndex = Ledger::getDirNodeIndex(uRootIndex, uNodeDir); lspRoot = lepNONE; - sleNode = mLedger->getDirNode(lspRoot, uNodeIndex); + sleNode = mLedger->getDirNode(lspRoot, Ledger::getDirNodeIndex(uRootIndex, uNodeDir)); assert(sleNode); } else { - // Try adding to root. - uNodeIndex = uRootIndex; + // Try adding to root. Didn't have a previous set. sleNode = sleRoot; } @@ -213,24 +208,33 @@ TransactionEngineResult TransactionEngine::dirAdd( } else { + // Have old last point to new node, if it was not root. + if (uNodeDir == 1) + { + // Previous node is root node. + + sleRoot->setIFieldU64(sfIndexNext, uNodeDir); + } + else + { + // Previous node is not root node. + + lspRoot = lepNONE; + SLE::pointer slePrevious = mLedger->getDirNode(lspRoot, Ledger::getDirNodeIndex(uRootIndex, uNodeDir-1)); + + slePrevious->setIFieldU64(sfIndexNext, uNodeDir); + entryModify(slePrevious); + + sleNode->setIFieldU64(sfIndexPrevious, uNodeDir-1); + } + // Have root point to new node. sleRoot->setIFieldU64(sfIndexPrevious, uNodeDir); entryModify(sleRoot); - // Have old last point to new node, if it was not root. - if (uNodePrevious) - { - // Previous node is not root node. - sleNode->setIFieldU64(sfIndexNext, uNodeDir); - entryModify(sleNode); - } - // Create the new node. + sleNode = entryCreate(ltDIR_NODE, Ledger::getDirNodeIndex(uRootIndex, uNodeDir)); svIndexes = STVector256(); - sleNode = entryCreate(ltDIR_NODE, uNodeIndex); - - if (uNodePrevious) - sleNode->setIFieldU64(sfIndexPrevious, uNodePrevious); } } @@ -245,19 +249,20 @@ TransactionEngineResult TransactionEngine::dirAdd( return terSUCCESS; } +// --> bKeepRoot: True, if we never completely clean up, after we overflow the root node. // --> uNodeDir: Node containing entry. // --> uRootIndex: The index of the base of the directory. Nodes are based off of this. // --> uLedgerIndex: Value to add to directory. // Ledger must be in a state for this to work. TransactionEngineResult TransactionEngine::dirDelete( + bool bKeepRoot, const uint64& uNodeDir, const uint256& uRootIndex, const uint256& uLedgerIndex) { uint64 uNodeCur = uNodeDir; - uint256 uNodeIndex = Ledger::getDirNodeIndex(uRootIndex, uNodeCur); LedgerStateParms lspNode = lepNONE; - SLE::pointer sleNode = mLedger->getDirNode(lspNode, uNodeIndex); + SLE::pointer sleNode = mLedger->getDirNode(lspNode, uNodeCur ? Ledger::getDirNodeIndex(uRootIndex, uNodeCur) : uRootIndex); assert(sleNode); @@ -267,163 +272,154 @@ TransactionEngineResult TransactionEngine::dirDelete( return terBAD_LEDGER; } - else + + STVector256 svIndexes = sleNode->getIFieldV256(sfIndexes); + std::vector& vuiIndexes = svIndexes.peekValue(); + std::vector::iterator it; + + it = std::find(vuiIndexes.begin(), vuiIndexes.end(), uLedgerIndex); + + assert(vuiIndexes.end() != it); + if (vuiIndexes.end() == it) { - STVector256 svIndexes = sleNode->getIFieldV256(sfIndexes); - std::vector& vuiIndexes = svIndexes.peekValue(); - std::vector::iterator it; + assert(false); - it = std::find(vuiIndexes.begin(), vuiIndexes.end(), uLedgerIndex); + Log(lsWARNING) << "dirDelete: node not mentioned"; - assert(vuiIndexes.end() != it); - if (vuiIndexes.end() == it) + return terBAD_LEDGER; + } + + // Remove the element. + if (vuiIndexes.size() > 1) + *it = vuiIndexes[vuiIndexes.size()-1]; + + vuiIndexes.resize(vuiIndexes.size()-1); + + sleNode->setIFieldV256(sfIndexes, svIndexes); + entryModify(sleNode); + + if (vuiIndexes.empty()) + { + // May be able to delete nodes. + uint64 uNodePrevious = sleNode->getIFieldU64(sfIndexPrevious); + uint64 uNodeNext = sleNode->getIFieldU64(sfIndexNext); + + if (!uNodeCur) { - Log(lsWARNING) << "dirDelete: node not mentioned"; + // Just emptied root node. - return terBAD_LEDGER; - } - else - { - // Remove the element. - if (vuiIndexes.size() > 1) - *it = vuiIndexes[vuiIndexes.size()-1]; - - vuiIndexes.resize(vuiIndexes.size()-1); - - if (vuiIndexes.size() > 0) + if (!uNodePrevious) { - // Node is not being deleted. - sleNode->setIFieldV256(sfIndexes, svIndexes); - entryModify(sleNode); + // Never overflowed the root node. Delete it. + entryDelete(sleNode); + } + // Root overflowed. + else if (bKeepRoot) + { + // Not allowed to delete root node, if it ever overflowed. + + nothing(); + } + else if (uNodePrevious != uNodeNext) + { + // Have multiple other nodes. Can't delete root node. + + nothing(); } else { - bool bRootDirty = false; - SLE::pointer sleRoot; + // Have only a root node and a last node. + LedgerStateParms lspLast = lepNONE; + SLE::pointer sleLast = mLedger->getDirNode(lspLast, Ledger::getDirNodeIndex(uRootIndex, uNodeNext)); - // May be able to delete nodes. - if (uNodeCur) + assert(sleLast); + + if (sleLast->getIFieldV256(sfIndexes).peekValue().empty()) { - uint64 uNodePrevious = sleNode->getIFieldU64(sfIndexPrevious); - uint64 uNodeNext = sleNode->getIFieldU64(sfIndexNext); + // Both nodes are empty. - entryDelete(sleNode); - - // Fix previous link. - if (uNodePrevious) - { - LedgerStateParms lspPrevious = lepNONE; - SLE::pointer slePrevious = mLedger->getDirNode(lspPrevious, Ledger::getDirNodeIndex(uRootIndex, uNodePrevious)); - - assert(slePrevious); - if (!slePrevious) - { - Log(lsWARNING) << "dirDelete: previous node is missing"; - - return terBAD_LEDGER; - } - else if (uNodeNext) - { - slePrevious->setIFieldU64(sfIndexNext, uNodeNext); - } - else - { - slePrevious->makeIFieldAbsent(sfIndexNext); - } - entryModify(slePrevious); - } - else - { - // Read root. - bRootDirty = true; - - sleRoot = mLedger->getDirNode(lspNode, uRootIndex); - - if (uNodeNext) - { - sleRoot->setIFieldU64(sfIndexNext, uNodeNext); - } - else - { - sleRoot->makeIFieldAbsent(sfIndexNext); - } - } - - // Fix next link. - if (uNodeNext) - { - LedgerStateParms lspNext = lepNONE; - SLE::pointer sleNext = mLedger->getDirNode(lspNext, Ledger::getDirNodeIndex(uRootIndex, uNodeNext)); - - assert(sleNext); - if (!sleNext) - { - Log(lsWARNING) << "dirDelete: next node is missing"; - - return terBAD_LEDGER; - } - else if (uNodeNext) - { - sleNext->setIFieldU64(sfIndexNext, uNodeNext); - } - else - { - sleNext->makeIFieldAbsent(sfIndexNext); - } - entryModify(sleNext); - } - else - { - // Read root. - bRootDirty = true; - - sleRoot = mLedger->getDirNode(lspNode, uRootIndex); - - if (uNodePrevious) - { - sleRoot->setIFieldU64(sfIndexPrevious, uNodePrevious); - } - else - { - sleRoot->makeIFieldAbsent(sfIndexPrevious); - } - } - - if (bRootDirty) - { - // Need to update sleRoot; - uNodeCur = 0; - - // If we might be able to delete root, load it. - if (!uNodePrevious && !uNodeNext) - vuiIndexes = svIndexes.peekValue(); - } + entryDelete(sleNode); // Delete root. + entryDelete(sleLast); // Delete last. } else { - bRootDirty = true; - } + // Have an entry, can't delete. - if (!uNodeCur) - { - // Looking at root node. - uint64 uRootPrevious = sleNode->getIFieldU64(sfIndexPrevious); - uint64 uRootNext = sleNode->getIFieldU64(sfIndexNext); - - if (!uRootPrevious && !uRootNext && vuiIndexes.empty()) - { - entryDelete(sleRoot); - } - else if (bRootDirty) - { - entryModify(sleRoot); - } + nothing(); } } } + // Just emptied a non-root node. + else if (uNodeNext) + { + // Not root and not last node. Can delete node. - return terSUCCESS; + LedgerStateParms lspPrevious = lepNONE; + SLE::pointer slePrevious = mLedger->getDirNode(lspPrevious, uNodePrevious ? Ledger::getDirNodeIndex(uRootIndex, uNodePrevious) : uRootIndex); + + assert(slePrevious); + + LedgerStateParms lspNext = lepNONE; + SLE::pointer sleNext = mLedger->getDirNode(lspNext, uNodeNext ? Ledger::getDirNodeIndex(uRootIndex, uNodeNext) : uRootIndex); + + assert(sleNext); + + if (!slePrevious) + { + Log(lsWARNING) << "dirDelete: previous node is missing"; + + return terBAD_LEDGER; + } + + assert(sleNext); + if (!sleNext) + { + Log(lsWARNING) << "dirDelete: next node is missing"; + + return terBAD_LEDGER; + } + + // Fix previous to point to its new next. + slePrevious->setIFieldU64(sfIndexNext, uNodeNext); + entryModify(slePrevious); + + // Fix next to point to its new previous. + sleNext->setIFieldU64(sfIndexPrevious, uNodePrevious); + entryModify(sleNext); + } + // Last node. + else if (bKeepRoot || uNodePrevious) + { + // Not allowed to delete last node as root was overflowed. + // Or, have pervious entries preventing complete delete. + + nothing(); + } + else + { + // Last and only node besides the root. + LedgerStateParms lspRoot = lepNONE; + SLE::pointer sleRoot = mLedger->getDirNode(lspRoot, uRootIndex); + + assert(sleRoot); + + if (sleRoot->getIFieldV256(sfIndexes).peekValue().empty()) + { + // Both nodes are empty. + + entryDelete(sleRoot); // Delete root. + entryDelete(sleNode); // Delete last. + } + else + { + // Root has an entry, can't delete. + + nothing(); + } + } } + + return terSUCCESS; } // Set the authorized public ket for an account. May also set the generator map. @@ -498,6 +494,8 @@ bool TransactionEngine::entryExists(SLE::pointer sleEntry) SLE::pointer TransactionEngine::entryCreate(LedgerEntryType letType, const uint256& uIndex) { + assert(!uIndex.isZero()); + SLE::pointer sleNew = boost::make_shared(letType); sleNew->setIndex(uIndex); @@ -509,6 +507,7 @@ SLE::pointer TransactionEngine::entryCreate(LedgerEntryType letType, const uint2 void TransactionEngine::entryDelete(SLE::pointer sleEntry) { + assert(sleEntry); entryMap::const_iterator it = mEntries.find(sleEntry); switch (it == mEntries.end() ? taaNONE : it->second) @@ -531,6 +530,7 @@ void TransactionEngine::entryDelete(SLE::pointer sleEntry) void TransactionEngine::entryModify(SLE::pointer sleEntry) { + assert(sleEntry); entryMap::const_iterator it = mEntries.find(sleEntry); switch (it == mEntries.end() ? taaNONE : it->second) @@ -553,6 +553,7 @@ void TransactionEngine::entryModify(SLE::pointer sleEntry) void TransactionEngine::entryUnfunded(SLE::pointer sleEntry) { + assert(sleEntry); entryMap::const_iterator it = mEntries.find(sleEntry); switch (it == mEntries.end() ? taaNONE : it->second) @@ -1216,7 +1217,7 @@ TransactionEngineResult TransactionEngine::doCreditSet(const SerializedTransacti // Zero balance and eliminating last limit. bDelIndex = true; - terResult = dirDelete(uSrcRef, Ledger::getRippleDirIndex(uSrcAccountID), sleRippleState->getIndex()); + terResult = dirDelete(true, uSrcRef, Ledger::getRippleDirIndex(uSrcAccountID), sleRippleState->getIndex()); } } #endif @@ -2236,11 +2237,11 @@ TransactionEngineResult TransactionEngine::doOfferCancel(const SerializedTransac uint64 uBookNode = sleOffer->getIFieldU64(sfBookNode); uint256 uDirectory = sleOffer->getIFieldH256(sfDirectory); - terResult = dirDelete(uOwnerNode, Ledger::getOwnerDirIndex(uSrcAccountID), uLedgerIndex); + terResult = dirDelete(true, uOwnerNode, Ledger::getOwnerDirIndex(uSrcAccountID), uLedgerIndex); // if (terSUCCESS == terResult) // { -// terResult = dirDelete(uBookNode, uDirectory, uLedgerIndex); +// terResult = dirDelete(false, uBookNode, uDirectory, uLedgerIndex); // } entryDelete(sleOffer); diff --git a/src/TransactionEngine.h b/src/TransactionEngine.h index 498bdcc0ac..99f7444f5c 100644 --- a/src/TransactionEngine.h +++ b/src/TransactionEngine.h @@ -114,6 +114,7 @@ private: const uint256& uLedgerIndex); TransactionEngineResult dirDelete( + bool bKeepRoot, const uint64& uNodeDir, // Node item is mentioned in. const uint256& uRootIndex, const uint256& uLedgerIndex); // Item being deleted From d6af13330a60e0f81e877efe6a0f53470d248253 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sat, 14 Jul 2012 16:15:09 -0700 Subject: [PATCH 4/7] Fix for doOfferCancel. --- src/TransactionEngine.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/TransactionEngine.cpp b/src/TransactionEngine.cpp index b05208d012..34ae6c6033 100644 --- a/src/TransactionEngine.cpp +++ b/src/TransactionEngine.cpp @@ -2239,10 +2239,10 @@ TransactionEngineResult TransactionEngine::doOfferCancel(const SerializedTransac terResult = dirDelete(true, uOwnerNode, Ledger::getOwnerDirIndex(uSrcAccountID), uLedgerIndex); -// if (terSUCCESS == terResult) -// { -// terResult = dirDelete(false, uBookNode, uDirectory, uLedgerIndex); -// } + if (terSUCCESS == terResult) + { + terResult = dirDelete(false, uBookNode, uDirectory, uLedgerIndex); + } entryDelete(sleOffer); } From 6feb16709e2982c561dc8136d42031510539af09 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sat, 14 Jul 2012 17:21:43 -0700 Subject: [PATCH 5/7] Add RPC owner_info. --- src/LedgerIndex.cpp | 2 +- src/NetworkOPs.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/NetworkOPs.h | 6 ++++++ src/RPCServer.cpp | 35 +++++++++++++++++++++++++++++++++++ src/RPCServer.h | 1 + 5 files changed, 88 insertions(+), 1 deletion(-) diff --git a/src/LedgerIndex.cpp b/src/LedgerIndex.cpp index 1bcf17062f..94728cdf75 100644 --- a/src/LedgerIndex.cpp +++ b/src/LedgerIndex.cpp @@ -49,7 +49,7 @@ uint256 Ledger::getBookBase(const uint160& uCurrencyIn, const uint160& uAccountI assert(!bInNative || !bOutNative); // Stamps to stamps not allowed. assert(bInNative == uAccountIn.isZero()); // Make sure issuer is specified as needed. - assert(bOutNative == uAccountOut.isZero()); // Make sure issuer is specified as needed. + assert(bOutNative == uAccountOut.isZero()); // Make sure issuer is specified as needed. assert(uCurrencyIn != uCurrencyOut || uAccountIn != uAccountOut); // Currencies or accounts must differ. Serializer s(82); diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index c5d89decab..aed15e198e 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -215,6 +215,51 @@ NicknameState::pointer NetworkOPs::getNicknameState(const uint256& uLedger, cons return mLedgerMaster->getLedgerByHash(uLedger)->getNicknameState(strNickname); } +// +// Owner functions +// + +Json::Value NetworkOPs::getOwnerInfo(const uint256& uLedger, const NewcoinAddress& naAccount) +{ + Json::Value jvObjects(Json::arrayValue); + + Ledger::pointer lpLedger = mLedgerMaster->getLedgerByHash(uLedger); + uint256 uRootIndex = lpLedger->getOwnerDirIndex(naAccount.getAccountID()); + + LedgerStateParms lspNode = lepNONE; + SLE::pointer sleNode = lpLedger->getDirNode(lspNode, uRootIndex); + + if (sleNode) + { + uint64 uNodeDir; + + do + { + STVector256 svIndexes = sleNode->getIFieldV256(sfIndexes); + std::vector& vuiIndexes = svIndexes.peekValue(); + + BOOST_FOREACH(uint256& uDirEntry, vuiIndexes) + { + LedgerStateParms lspOffer = lepNONE; + SLE::pointer sleOffer = lpLedger->getOffer(lspOffer, uDirEntry); + + jvObjects.append(sleOffer->getJson(0)); + } + + uNodeDir = sleNode->getIFieldU64(sfIndexNext); + if (uNodeDir) + { + lspNode = lepNONE; + sleNode = lpLedger->getDirNode(lspNode, Ledger::getDirNodeIndex(uRootIndex, uNodeDir)); + + assert(sleNode); + } + } while (uNodeDir); + } + + return jvObjects; +} + // // Ripple functions // diff --git a/src/NetworkOPs.h b/src/NetworkOPs.h index 9458af50b3..15f5b0355f 100644 --- a/src/NetworkOPs.h +++ b/src/NetworkOPs.h @@ -118,6 +118,12 @@ public: NicknameState::pointer getNicknameState(const uint256& uLedger, const std::string& strNickname); + // + // Owner functions + // + + Json::Value getOwnerInfo(const uint256& uLedger, const NewcoinAddress& naAccount); + // // Ripple functions // diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 623dc1d94d..39ecbba081 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -948,6 +948,40 @@ Json::Value RPCServer::doOfferCancel(const Json::Value ¶ms) return obj; } +// owner_info || +Json::Value RPCServer::doOwnerInfo(const Json::Value& params) +{ + std::string strIdent = params[0u].asString(); + bool bIndex; + int iIndex = 2 == params.size()? lexical_cast_s(params[1u].asString()) : 0; + NewcoinAddress naAccount; + + Json::Value ret; + + // Get info on account. + + uint256 uAccepted = mNetOps->getClosedLedger(); + Json::Value jAccepted = accountFromString(uAccepted, naAccount, bIndex, strIdent, iIndex); + + if (jAccepted.empty()) + { + jAccepted["offers"] = mNetOps->getOwnerInfo(uAccepted, naAccount); + } + + ret["accepted"] = jAccepted; + + uint256 uCurrent = mNetOps->getCurrentLedger(); + Json::Value jCurrent = accountFromString(uCurrent, naAccount, bIndex, strIdent, iIndex); + + if (jCurrent.empty()) + { + jCurrent["offers"] = mNetOps->getOwnerInfo(uCurrent, naAccount); + } + + ret["current"] = jCurrent; + + return ret; +} // password_fund [] // YYY Make making account default to first account for seed. Json::Value RPCServer::doPasswordFund(const Json::Value ¶ms) @@ -2105,6 +2139,7 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params { "nickname_set", &RPCServer::doNicknameSet, 2, 3, false, optCurrent }, { "offer_create", &RPCServer::doOfferCreate, 9, 10, false, optCurrent }, { "offer_cancel", &RPCServer::doOfferCancel, 3, 3, false, optCurrent }, + { "owner_info", &RPCServer::doOwnerInfo, 1, 2, false, optCurrent }, { "password_fund", &RPCServer::doPasswordFund, 2, 3, false, optCurrent }, { "password_set", &RPCServer::doPasswordSet, 2, 3, false, optNetwork }, { "peers", &RPCServer::doPeers, 0, 0, true }, diff --git a/src/RPCServer.h b/src/RPCServer.h index eda4e403b8..6f62b4e570 100644 --- a/src/RPCServer.h +++ b/src/RPCServer.h @@ -139,6 +139,7 @@ private: Json::Value doNicknameSet(const Json::Value& params); Json::Value doOfferCreate(const Json::Value& params); Json::Value doOfferCancel(const Json::Value& params); + Json::Value doOwnerInfo(const Json::Value& params); Json::Value doPasswordFund(const Json::Value& params); Json::Value doPasswordSet(const Json::Value& params); Json::Value doPeers(const Json::Value& params); From 8bcb9c00412172cd466083431eb93ae8e342df94 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sat, 14 Jul 2012 19:16:58 -0700 Subject: [PATCH 6/7] Add get first/last/next SLE functions. --- src/Ledger.h | 3 +++ src/LedgerNode.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/Ledger.h b/src/Ledger.h index 66f351c42f..0bf03f49b7 100644 --- a/src/Ledger.h +++ b/src/Ledger.h @@ -156,6 +156,9 @@ public: static Ledger::pointer loadByHash(const uint256& ledgerHash); // next/prev function + SLE::pointer getSLE(const uint256& uHash); + SLE::pointer getFirstSLE(); + SLE::pointer getLastSLE(); SLE::pointer getNextSLE(const uint256& uHash); // first node >hash SLE::pointer getNextSLE(const uint256& uHash, const uint256& uEnd); // first node >hash, peekItem(); + if (!node) + return SLE::pointer(); + return boost::make_shared(node->peekSerializer(), node->getTag()); +} + +SLE::pointer Ledger::getFirstSLE() +{ + SHAMapItem::pointer node = mAccountStateMap->peekFirstItem(); + if (!node) + return SLE::pointer(); + return boost::make_shared(node->peekSerializer(), node->getTag()); +} + +SLE::pointer Ledger::getLastSLE() +{ + SHAMapItem::pointer node = mAccountStateMap->peekLastItem(); + if (!node) + return SLE::pointer(); + return boost::make_shared(node->peekSerializer(), node->getTag()); +} + SLE::pointer Ledger::getNextSLE(const uint256& uHash) { SHAMapItem::pointer node = mAccountStateMap->peekNextItem(uHash); From 0b0cf71d41dce88c0ebf01b63cf18247a4d7ad01 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sat, 14 Jul 2012 19:18:04 -0700 Subject: [PATCH 7/7] Cleanups. --- src/LedgerNode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LedgerNode.cpp b/src/LedgerNode.cpp index 727634081d..07f4edc5bd 100644 --- a/src/LedgerNode.cpp +++ b/src/LedgerNode.cpp @@ -48,7 +48,7 @@ LedgerStateParms Ledger::writeBack(LedgerStateParms parms, SLE::pointer entry) SLE::pointer Ledger::getSLE(const uint256& uHash) { - SHAMapItem::pointer node = mAccountStateMap->peekItem(); + SHAMapItem::pointer node = mAccountStateMap->peekItem(uHash); if (!node) return SLE::pointer(); return boost::make_shared(node->peekSerializer(), node->getTag());