From 68c8434a2bf726b29ffec38c0641a97437eaf2c5 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Wed, 30 May 2012 00:41:10 -0700 Subject: [PATCH] Rework RPCServer to go through NetworkOPs. --- src/AccountState.h | 14 ++++- src/Application.cpp | 4 +- src/Application.h | 4 +- src/Ledger.cpp | 15 +++++ src/Ledger.h | 38 ++++++------ src/LedgerMaster.h | 2 +- src/LedgerNode.cpp | 6 +- src/NetworkOPs.cpp | 97 +++++++++++++++++++++++++------ src/NetworkOPs.h | 42 ++++++++++---- src/Peer.h | 1 - src/RPCServer.cpp | 137 +++++++++++++++++++++++--------------------- src/RPCServer.h | 8 +-- src/RippleState.cpp | 32 +++++++++++ src/RippleState.h | 51 +++++++++++++++++ 14 files changed, 330 insertions(+), 121 deletions(-) create mode 100644 src/RippleState.cpp create mode 100644 src/RippleState.h diff --git a/src/AccountState.h b/src/AccountState.h index 793f1b96a5..0711d049a1 100644 --- a/src/AccountState.h +++ b/src/AccountState.h @@ -1,7 +1,9 @@ #ifndef __ACCOUNTSTATE__ #define __ACCOUNTSTATE__ -// An account's state +// +// Provide abstract access to an account's state, such that access to the serialized format is hidden. +// #include @@ -29,6 +31,16 @@ public: AccountState(const NewcoinAddress& AccountID); // For new accounts AccountState(SerializedLedgerEntry::pointer ledgerEntry); // For accounts in a ledger + bool bHaveAuthorizedKey() + { + return mLedgerEntry->getIFieldPresent(sfAuthorizedKey); + } + + uint160 getAuthorizedKey() + { + return mLedgerEntry->getIFieldH160(sfAuthorizedKey); + } + const NewcoinAddress& getAccountID() const { return mAccountID; } STAmount getBalance() const { return mLedgerEntry->getIValueFieldAmount(sfBalance); } uint32 getSeq() const { return mLedgerEntry->getIFieldU32(sfSequence); } diff --git a/src/Application.cpp b/src/Application.cpp index 63f53e3521..5f131c1bf3 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -30,7 +30,9 @@ DatabaseCon::~DatabaseCon() delete mDatabase; } -Application::Application() : mNetOps(mIOService), mUNL(mIOService), +Application::Application() : + mUNL(mIOService), + mNetOps(mIOService, &mMasterLedger), mTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL), mHashNodeDB(NULL), mNetNodeDB(NULL), mConnectionPool(mIOService), mPeerDoor(NULL), mRPCDoor(NULL) { diff --git a/src/Application.h b/src/Application.h index beb928994a..30bfc26241 100644 --- a/src/Application.h +++ b/src/Application.h @@ -1,10 +1,10 @@ #ifndef __APPLICATION__ #define __APPLICATION__ +#include "LedgerMaster.h" #include "UniqueNodeList.h" #include "ConnectionPool.h" #include "ScopedLock.h" -#include "LedgerMaster.h" #include "LedgerAcquire.h" #include "TransactionMaster.h" #include "Wallet.h" @@ -34,12 +34,12 @@ class Application { boost::asio::io_service mIOService; - NetworkOPs mNetOps; Wallet mWallet; UniqueNodeList mUNL; LedgerMaster mMasterLedger; LedgerAcquireMaster mMasterLedgerAcquire; TransactionMaster mMasterTransaction; + NetworkOPs mNetOps; DatabaseCon* mTxnDB, *mLedgerDB, *mWalletDB, *mHashNodeDB, *mNetNodeDB; diff --git a/src/Ledger.cpp b/src/Ledger.cpp index 3de3f5e4db..30656cd218 100644 --- a/src/Ledger.cpp +++ b/src/Ledger.cpp @@ -142,6 +142,21 @@ AccountState::pointer Ledger::getAccountState(const NewcoinAddress& accountID) return boost::make_shared(sle); } +RippleState::pointer Ledger::getRippleState(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(Transaction::pointer trans) { // low-level - just add to table, debit fee assert(!mAccepted); diff --git a/src/Ledger.h b/src/Ledger.h index 61b4e47aaa..89af8b9b28 100644 --- a/src/Ledger.h +++ b/src/Ledger.h @@ -12,6 +12,7 @@ #include "Transaction.h" #include "AccountState.h" +#include "RippleState.h" #include "types.h" #include "BitcoinUtil.h" #include "SHAMap.h" @@ -75,7 +76,7 @@ protected: static Ledger::pointer getSQL(const std::string& sqlStatement); - SerializedLedgerEntry::pointer getASNode(LedgerStateParms& parms, const uint256& nodeID, + SLE::pointer getASNode(LedgerStateParms& parms, const uint256& nodeID, LedgerEntryType let); public: @@ -127,11 +128,11 @@ public: // high-level functions AccountState::pointer getAccountState(const NewcoinAddress& acctID); - LedgerStateParms writeBack(LedgerStateParms parms, SerializedLedgerEntry::pointer); - SerializedLedgerEntry::pointer getAccountRoot(LedgerStateParms& parms, const uint160& accountID); - SerializedLedgerEntry::pointer getAccountRoot(LedgerStateParms& parms, const NewcoinAddress& naAccountID); - SerializedLedgerEntry::pointer getNickname(LedgerStateParms& parms, const std::string& nickname); - SerializedLedgerEntry::pointer getNickname(LedgerStateParms& parms, const uint256& nickHash); + LedgerStateParms writeBack(LedgerStateParms parms, SLE::pointer); + SLE::pointer getAccountRoot(LedgerStateParms& parms, const uint160& accountID); + SLE::pointer getAccountRoot(LedgerStateParms& parms, const NewcoinAddress& naAccountID); + SLE::pointer getNickname(LedgerStateParms& parms, const std::string& nickname); + SLE::pointer getNickname(LedgerStateParms& parms, const uint256& nickHash); // database functions static void saveAcceptedLedger(Ledger::pointer); @@ -149,7 +150,7 @@ public: // Generator Map functions // - SerializedLedgerEntry::pointer getGenerator(LedgerStateParms& parms, const uint160& uGeneratorID); + SLE::pointer getGenerator(LedgerStateParms& parms, const uint160& uGeneratorID); static uint256 getGeneratorIndex(const uint160& uGeneratorID) { return uint160extend256(uGeneratorID, lnsGenerator); } // Index is the generator ID extended to 256 bits in namespace 1 @@ -165,31 +166,34 @@ public: static uint256 getRippleStateIndex(const NewcoinAddress& naA, const NewcoinAddress& naB) { return getRippleStateIndex(naA, naB, uint160()); } - static uint160 getOfferBase(const uint160& currencyIn, const uint160& accountIn, - const uint160& currencyOut, const uint160& accountOut); + RippleState::pointer getRippleState(const uint256& uNode); + SLE::pointer getRippleState(LedgerStateParms& parms, const uint256& uNode); + + SLE::pointer getRippleState(LedgerStateParms& parms, const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency) + { return getRippleState(parms, getRippleStateIndex(naA, naB, uCurrency)); } + + SLE::pointer getRippleState(LedgerStateParms& parms, const uint160& uiA, const uint160& uiB, const uint160& uCurrency) + { return getRippleState(parms, getRippleStateIndex(NewcoinAddress::createAccountID(uiA), NewcoinAddress::createAccountID(uiB), uCurrency)); } // // Offer functions // + static uint160 getOfferBase(const uint160& currencyIn, const uint160& accountIn, + const uint160& currencyOut, const uint160& accountOut); + static uint256 getOfferIndex(const uint160& offerBase, uint64 rate, int skip = 0); static int getOfferSkip(const uint256& offerId); - SerializedLedgerEntry::pointer getRippleState(LedgerStateParms& parms, const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency); - SerializedLedgerEntry::pointer getRippleState(LedgerStateParms& parms, const uint160& uiA, const uint160& uiB, const uint160& uCurrency) - { - return getRippleState(parms, NewcoinAddress::createAccountID(uiA), NewcoinAddress::createAccountID(uiB), uCurrency); - } - // // Directory functions // static uint256 getDirIndex(const uint256& uBase, const LedgerEntryType letKind, const uint64 uNodeDir=0); - SerializedLedgerEntry::pointer getDirRoot(LedgerStateParms& parms, const uint256& uRootIndex); - SerializedLedgerEntry::pointer getDirNode(LedgerStateParms& parms, const uint256& uNodeIndex); + SLE::pointer getDirRoot(LedgerStateParms& parms, const uint256& uRootIndex); + SLE::pointer getDirNode(LedgerStateParms& parms, const uint256& uNodeIndex); // // Misc diff --git a/src/LedgerMaster.h b/src/LedgerMaster.h index 53d7eba42f..22958af5f6 100644 --- a/src/LedgerMaster.h +++ b/src/LedgerMaster.h @@ -51,7 +51,7 @@ public: { if (mCurrentLedger && (mCurrentLedger->getLedgerSeq()==index)) return mCurrentLedger; if (mFinalizedLedger && (mFinalizedLedger->getLedgerSeq()==index)) return mFinalizedLedger; - return mLedgerHistory.getLedgerBySeq(index); + return mLedgerHistory.getLedgerBySeq(index); } Ledger::pointer getLedgerByHash(const uint256& hash) diff --git a/src/LedgerNode.cpp b/src/LedgerNode.cpp index 61418484ca..4d607073dd 100644 --- a/src/LedgerNode.cpp +++ b/src/LedgerNode.cpp @@ -141,15 +141,13 @@ SerializedLedgerEntry::pointer Ledger::getGenerator(LedgerStateParms& parms, con // Ripple State // -SerializedLedgerEntry::pointer Ledger::getRippleState(LedgerStateParms& parms, const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency) +SerializedLedgerEntry::pointer Ledger::getRippleState(LedgerStateParms& parms, const uint256& uNode) { - uint256 nodeID=getRippleStateIndex(naA, naB, uCurrency); - ScopedLock l(mAccountStateMap->Lock()); try { - return getASNode(parms, nodeID, ltRIPPLE_STATE); + return getASNode(parms, uNode, ltRIPPLE_STATE); } catch (...) { diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 2f7fe62a0e..a9e4ed9901 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -21,7 +21,10 @@ // code assumes this node is synched (and will continue to do so until // there's a functional network. -NetworkOPs::NetworkOPs(boost::asio::io_service& io_service) : mMode(omDISCONNECTED), mNetTimer(io_service) +NetworkOPs::NetworkOPs(boost::asio::io_service& io_service, LedgerMaster* pLedgerMaster) : + mMode(omDISCONNECTED), + mNetTimer(io_service), + mLedgerMaster(pLedgerMaster) { } @@ -37,7 +40,7 @@ uint64 NetworkOPs::getNetworkTimeNC() uint32 NetworkOPs::getCurrentLedgerID() { - return theApp->getMasterLedger().getCurrentLedger()->getLedgerSeq(); + return mLedgerMaster->getCurrentLedger()->getLedgerSeq(); } Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans, Peer* source) @@ -54,7 +57,7 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans, return trans; } - TransactionEngineResult r = theApp->getMasterLedger().doTransaction(*trans->getSTransaction(), tepNONE); + TransactionEngineResult r = mLedgerMaster->doTransaction(*trans->getSTransaction(), tepNONE); if (r == tenFAILED) throw Fault(IO_ERROR); if (r == terPRE_SEQ) @@ -64,7 +67,7 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans, #endif trans->setStatus(HELD); theApp->getMasterTransaction().canonicalize(trans, true); - theApp->getMasterLedger().addHeldTransaction(trans); + mLedgerMaster->addHeldTransaction(trans); return trans; } if ((r == terPAST_SEQ) || (r == terPAST_LEDGER)) @@ -117,10 +120,10 @@ Transaction::pointer NetworkOPs::findTransactionByID(const uint256& transactionI return Transaction::load(transactionID); } -int NetworkOPs::findTransactionsBySource(std::list& txns, +int NetworkOPs::findTransactionsBySource(const uint256& uLedger, std::list& txns, const NewcoinAddress& sourceAccount, uint32 minSeq, uint32 maxSeq) { - AccountState::pointer state = getAccountState(sourceAccount); + AccountState::pointer state = getAccountState(uLedger, sourceAccount); if (!state) return 0; if (minSeq > state->getSeq()) return 0; if (maxSeq > state->getSeq()) maxSeq = state->getSeq(); @@ -146,14 +149,76 @@ int NetworkOPs::findTransactionsByDestination(std::list& t return 0; } -AccountState::pointer NetworkOPs::getAccountState(const NewcoinAddress& accountID) +// +// Account functions +// + +AccountState::pointer NetworkOPs::getAccountState(const uint256& uLedger, const NewcoinAddress& accountID) { - return theApp->getMasterLedger().getCurrentLedger()->getAccountState(accountID); + return mLedgerMaster->getLedgerByHash(uLedger)->getAccountState(accountID); } +SLE::pointer NetworkOPs::getGenerator(const uint256& uLedger, const uint160& uGeneratorID) +{ + LedgerStateParms qry = lepNONE; + + return mLedgerMaster->getLedgerByHash(uLedger)->getGenerator(qry, uGeneratorID); +} + +// +// Directory functions +// + +// <-- false : no entrieS +bool NetworkOPs::getDirInfo( + const uint256& uLedger, + const uint256& uBase, + const LedgerEntryType letKind, + uint256& uDirLineNodeFirst, + uint256& uDirLineNodeLast) +{ + uint256 uRootIndex = Ledger::getDirIndex(uBase, letKind); + LedgerStateParms lspRoot = lepNONE; + SLE::pointer sleRoot = mLedgerMaster->getLedgerByHash(uLedger)->getDirRoot(lspRoot, uRootIndex); + + if (sleRoot) + { + uDirLineNodeFirst = uRootIndex | sleRoot->getIFieldU64(sfFirstNode); + uDirLineNodeLast = uRootIndex | sleRoot->getIFieldU64(sfLastNode); + } + + return !!sleRoot; +} + +STVector256 NetworkOPs::getDirNode(const uint256& uLedger, const uint256& uDirLineNode) +{ + STVector256 svIndexes; + + LedgerStateParms lspNode = lepNONE; + SLE::pointer sleNode = mLedgerMaster->getLedgerByHash(uLedger)->getDirNode(lspNode, uDirLineNode); + + if (sleNode) + svIndexes = sleNode->getIFieldV256(sfIndexes); + + return svIndexes; +} + +// +// Ripple functions +// + +RippleState::pointer NetworkOPs::getRippleState(const uint256& uLedger, const uint256& uIndex) +{ + return mLedgerMaster->getLedgerByHash(uLedger)->getRippleState(uIndex); +} + +// +// Other +// + void NetworkOPs::setStateTimer(int sec) { // set timer early if ledger is closing - uint64 closedTime = theApp->getMasterLedger().getCurrentLedger()->getCloseTimeNC(); + uint64 closedTime = mLedgerMaster->getCurrentLedger()->getCloseTimeNC(); uint64 now = getNetworkTimeNC(); if ((mMode == omFULL) && !mConsensus) @@ -236,7 +301,7 @@ void NetworkOPs::checkState(const boost::system::error_code& result) } } - Ledger::pointer currentClosed = theApp->getMasterLedger().getClosedLedger(); + Ledger::pointer currentClosed = mLedgerMaster->getClosedLedger(); uint256 closedLedger = currentClosed->getHash(); ValidationCount& vc = ledgers[closedLedger]; if ((vc.nodesUsing == 0) || (theApp->getWallet().getNodePublic() > vc.highNode)) @@ -265,7 +330,7 @@ void NetworkOPs::checkState(const boost::system::error_code& result) std::cerr << "Net LCL " << closedLedger.GetHex() << std::endl; #endif if ((mMode == omTRACKING) || (mMode == omFULL)) mMode = omTRACKING; - Ledger::pointer consensus = theApp->getMasterLedger().getLedgerByHash(closedLedger); + Ledger::pointer consensus = mLedgerMaster->getLedgerByHash(closedLedger); if (!consensus) { #ifdef DEBUG @@ -316,7 +381,7 @@ void NetworkOPs::checkState(const boost::system::error_code& result) return; } - Ledger::pointer currentLedger = theApp->getMasterLedger().getCurrentLedger(); + Ledger::pointer currentLedger = mLedgerMaster->getCurrentLedger(); if (getNetworkTimeNC() >= currentLedger->getCloseTimeNC()) { setStateTimer(beginConsensus(currentLedger, false)); @@ -342,7 +407,7 @@ void NetworkOPs::switchLastClosedLedger(Ledger::pointer newLedger) newLedger->setClosed(); Ledger::pointer openLedger = boost::make_shared(newLedger); - theApp->getMasterLedger().switchLedgers(newLedger, openLedger); + mLedgerMaster->switchLedgers(newLedger, openLedger); if (getNetworkTimeNC() > openLedger->getCloseTimeNC()) { // this ledger has already closed @@ -356,7 +421,7 @@ int NetworkOPs::beginConsensus(Ledger::pointer closingLedger, bool isEarly) #ifdef DEBUG std::cerr << "Ledger close time for ledger " << closingLedger->getLedgerSeq() << std::endl; #endif - Ledger::pointer prevLedger = theApp->getMasterLedger().getLedgerByHash(closingLedger->getParentHash()); + Ledger::pointer prevLedger = mLedgerMaster->getLedgerByHash(closingLedger->getParentHash()); if (!prevLedger) { // this shouldn't happen if we jump ledgers mMode = omTRACKING; @@ -364,7 +429,7 @@ int NetworkOPs::beginConsensus(Ledger::pointer closingLedger, bool isEarly) } // Create a new ledger to be the open ledger - theApp->getMasterLedger().pushLedger(boost::make_shared(closingLedger)); + mLedgerMaster->pushLedger(boost::make_shared(closingLedger)); // Create a consensus object to get consensus on this ledger if (!!mConsensus) mConsensus->abort(); @@ -404,7 +469,7 @@ bool NetworkOPs::proposeLedger(uint32 closingSeq, uint32 proposeSeq, const uint2 // Is this node on our UNL? // WRITEME - Ledger::pointer currentLedger = theApp->getMasterLedger().getCurrentLedger(); + Ledger::pointer currentLedger = mLedgerMaster->getCurrentLedger(); if (!mConsensus) { diff --git a/src/NetworkOPs.h b/src/NetworkOPs.h index 536dcbffd5..51202459b6 100644 --- a/src/NetworkOPs.h +++ b/src/NetworkOPs.h @@ -1,11 +1,11 @@ #ifndef __NETWORK_OPS__ #define __NETWORK_OPS__ -#include - -#include "Transaction.h" +#include "LedgerMaster.h" #include "AccountState.h" -#include "Ledger.h" +#include "RippleState.h" + +// #include // Operations that clients may wish to perform against the network // Master operational handler, server sequencer, network tracker @@ -35,8 +35,10 @@ protected: boost::asio::deadline_timer mNetTimer; boost::shared_ptr mConsensus; + LedgerMaster* mLedgerMaster; + public: - NetworkOPs(boost::asio::io_service& io_service); + NetworkOPs(boost::asio::io_service& io_service, LedgerMaster* pLedgerMaster); // network information uint64 getNetworkTimeNC(); @@ -44,25 +46,45 @@ public: uint32 getCurrentLedgerID(); OperatingMode getOperatingMode() { return mMode; } inline bool available() { + // XXX don't consider network available till have a closed ledger. return omDISCONNECTED != mMode; } + uint256 getClosedLedger() + { return mLedgerMaster->getClosedLedger()->getHash(); } + // transaction operations Transaction::pointer processTransaction(Transaction::pointer transaction, Peer* source = NULL); Transaction::pointer findTransactionByID(const uint256& transactionID); - int findTransactionsBySource(std::list&, const NewcoinAddress& sourceAccount, + int findTransactionsBySource(const uint256& uLedger, std::list&, const NewcoinAddress& sourceAccount, uint32 minSeq, uint32 maxSeq); int findTransactionsByDestination(std::list&, const NewcoinAddress& destinationAccount, uint32 startLedgerSeq, uint32 endLedgerSeq, int maxTransactions); - // account operations - AccountState::pointer getAccountState(const NewcoinAddress& accountID); + // + // Account functions + // + + AccountState::pointer getAccountState(const uint256& uLedger, const NewcoinAddress& accountID); + SLE::pointer getGenerator(const uint256& uLedger, const uint160& uGeneratorID); + + // + // Directory functions + // + + bool getDirInfo(const uint256& uLedger, const uint256& uBase, + const LedgerEntryType letKind, + uint256& uDirNodeFirst, uint256& uDirNodeLast); + STVector256 getDirNode(const uint256& uLedger, const uint256& uDirLineNode); // // Ripple functions // - bool getDirLineInfo(const NewcoinAddress& naAccount, uint64& uDirLineNodeFirst, uint64& uDirLineNodeLast) { return false; } - std::vector getDirLineNode(const uint64 uDirLineNode) { std::vector empty; return empty; } + + bool getDirLineInfo(const uint256& uLedger, const NewcoinAddress& naAccount, uint256& uDirLineNodeFirst, uint256& uDirLineNodeLast) + { return getDirInfo(uLedger, uint160extend256(naAccount.getAccountID(), 0), ltRIPPLE_STATE, uDirLineNodeFirst, uDirLineNodeLast); } + + RippleState::pointer getRippleState(const uint256& uLedger, const uint256& uIndex); // raw object operations bool findRawLedger(const uint256& ledgerHash, std::vector& rawLedger); diff --git a/src/Peer.h b/src/Peer.h index b8a33378c6..7e457fd053 100644 --- a/src/Peer.h +++ b/src/Peer.h @@ -11,7 +11,6 @@ #include "PackedMessage.h" #include "Ledger.h" #include "Transaction.h" -#include "NetworkOPs.h" enum PeerPunish { diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index c72bc01c86..afb51b7ad7 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -171,20 +171,18 @@ bool RPCServer::extractString(std::string& param, const Json::Value& params, int } // Given a seed and a source account get the public and private key for authorizing transactions for the account. -Json::Value RPCServer::authorize(const NewcoinAddress& naSeed, const NewcoinAddress& naSrcAccountID, +Json::Value RPCServer::authorize(const uint256& uLedger, + const NewcoinAddress& naSeed, const NewcoinAddress& naSrcAccountID, NewcoinAddress& naAccountPublic, NewcoinAddress& naAccountPrivate, - SLE::pointer& sleSrc) + AccountState::pointer& asSrc) { - Ledger::pointer ledger = theApp->getMasterLedger().getCurrentLedger(); - LedgerStateParms qry = lepNONE; - - sleSrc = ledger->getAccountRoot(qry, naSrcAccountID); - if (!sleSrc) + asSrc = mNetOps->getAccountState(uLedger, naSrcAccountID); + if (!asSrc) { return JSONRPCError(500, "source account does not exist"); } - if (!sleSrc->getIFieldPresent(sfAuthorizedKey)) + if (!asSrc->bHaveAuthorizedKey()) { return JSONRPCError(500, "source account has not been claimed"); } @@ -197,8 +195,7 @@ Json::Value RPCServer::authorize(const NewcoinAddress& naSeed, const NewcoinAddr na0Public.setAccountPublic(naGenerator, 0); na0Private.setAccountPrivate(naGenerator, naSeed, 0); - qry = lepNONE; - SLE::pointer sleGen = ledger->getGenerator(qry, na0Public.getAccountID()); + SLE::pointer sleGen = mNetOps->getGenerator(uLedger, na0Public.getAccountID()); if (!sleGen) { @@ -234,10 +231,10 @@ Json::Value RPCServer::authorize(const NewcoinAddress& naSeed, const NewcoinAddr naAccountPublic.setAccountPublic(naGenerator, iIndex); naAccountPrivate.setAccountPrivate(naGenerator, naSeed, iIndex); - if (sleSrc->getIFieldH160(sfAuthorizedKey) != naAccountPublic.getAccountID()) + if (asSrc->getAuthorizedKey() != naAccountPublic.getAccountID()) { std::cerr << "iIndex: " << iIndex << std::endl; - std::cerr << "sfAuthorizedKey: " << strHex(sleSrc->getIFieldH160(sfAuthorizedKey)) << std::endl; + std::cerr << "sfAuthorizedKey: " << strHex(asSrc->getAuthorizedKey()) << std::endl; std::cerr << "naAccountPublic: " << strHex(naAccountPublic.getAccountID()) << std::endl; return JSONRPCError(500, "wrong password (changed)"); @@ -247,7 +244,7 @@ Json::Value RPCServer::authorize(const NewcoinAddress& naSeed, const NewcoinAddr } // <-- bIndex: true if iIndex > 0 and used the index. -Json::Value RPCServer::accountFromString(NewcoinAddress& naAccount, bool& bIndex, const std::string& strIdent, const int iIndex) +Json::Value RPCServer::accountFromString(const uint256& uLedger, NewcoinAddress& naAccount, bool& bIndex, const std::string& strIdent, const int iIndex) { NewcoinAddress naSeed; @@ -275,10 +272,7 @@ Json::Value RPCServer::accountFromString(NewcoinAddress& naAccount, bool& bIndex naRegular0Private.setAccountPrivate(naGenerator, naSeed, 0); uint160 uGeneratorID = naRegular0Public.getAccountID(); - - Ledger::pointer ledger = theApp->getMasterLedger().getCurrentLedger(); - LedgerStateParms qry = lepNONE; - SLE::pointer sleGen = ledger->getGenerator(qry, naRegular0Public.getAccountID()); + SLE::pointer sleGen = mNetOps->getGenerator(uLedger, naRegular0Public.getAccountID()); if (!sleGen) { // Didn't find a generator map, assume it is a master generator. @@ -325,7 +319,9 @@ Json::Value RPCServer::doAccountInfo(Json::Value ¶ms) Json::Value ret; - ret = accountFromString(naAccount, bIndex, strIdent, iIndex); + uint256 uLedger = mNetOps->getClosedLedger(); + + ret = accountFromString(uLedger, naAccount, bIndex, strIdent, iIndex); if (!ret.empty()) return ret; @@ -333,7 +329,7 @@ Json::Value RPCServer::doAccountInfo(Json::Value ¶ms) // Get info on account. ret = Json::Value(Json::objectValue); - AccountState::pointer as=mNetOps->getAccountState(naAccount); + AccountState::pointer as = mNetOps->getAccountState(uLedger, naAccount); if (as) { as->addJson(ret); @@ -365,11 +361,14 @@ Json::Value RPCServer::doAccountLines(Json::Value ¶ms) std::string strIdent = params[0u].asString(); bool bIndex; int iIndex = 2 == params.size()? boost::lexical_cast(params[1u].asString()) : 0; + uint256 uLedger = mNetOps->getClosedLedger(); + NewcoinAddress naAccount; Json::Value ret; - ret = accountFromString(naAccount, bIndex, strIdent, iIndex); + // This needs to use a ledger. + ret = accountFromString(uLedger, naAccount, bIndex, strIdent, iIndex); if (!ret.empty()) return ret; @@ -383,47 +382,48 @@ Json::Value RPCServer::doAccountLines(Json::Value ¶ms) if (bIndex) ret["index"] = iIndex; - AccountState::pointer as = mNetOps->getAccountState(naAccount); + AccountState::pointer as = mNetOps->getAccountState(uLedger, naAccount); if (as) { ret["account"] = naAccount.humanAccountID(); // We access a committed ledger and need not worry about changes. - uint64 uDirLineNodeFirst; - uint64 uDirLineNodeLast; + // XXX We need to get the ID of the commited ledger for a conistent view. + uint256 uDirLineNodeFirst; + uint256 uDirLineNodeLast; - if (!mNetOps->getDirLineInfo(naAccount, uDirLineNodeFirst, uDirLineNodeLast)) + if (!mNetOps->getDirLineInfo(uLedger, naAccount, uDirLineNodeFirst, uDirLineNodeLast)) { ret["lines"] = Json::Value(Json::objectValue); } - else if (uDirLineNodeFirst) + else { Json::Value jsonLines = Json::Value(Json::objectValue); for (; uDirLineNodeFirst <= uDirLineNodeLast; uDirLineNodeFirst++) { - std::vector vuRippleNodes = mNetOps->getDirLineNode(uDirLineNodeFirst); + STVector256 svRippleNodes = mNetOps->getDirNode(uLedger, uDirLineNodeFirst); - BOOST_FOREACH(uint256& uNode, vuRippleNodes) + BOOST_FOREACH(uint256& uNode, svRippleNodes.peekValue()) { NewcoinAddress naAccountPeer; - uint64 uBalance = 0; - // uint160 uCurrency; + STAmount saBalance; STAmount saLimit; STAmount saLimitPeer; -#if 0 - RippleState::pointer rsLine = mNetOps->getRippleState(uNode); + + RippleState::pointer rsLine = mNetOps->getRippleState(uLedger, uNode); rsLine->setViewAccount(naAccount); - rsLine->getAccountPeer(naAccountPeer); - // ->getBalance(iBalance); - // ->getCurrency(uCurrency); - rsLine->getLimit(saLimit) - rsLine->getLimitPeer(saPeerLimit); -#endif + + naAccountPeer = rsLine->getAccountIDPeer(); + saBalance = rsLine->getBalance(); + saLimit = rsLine->getLimit(); + saLimitPeer = rsLine->getLimitPeer(); + Json::Value jPeer = Json::Value(Json::objectValue); - jPeer["balance"] = Json::Value::UInt(uBalance); // XXX Raw number. + jPeer["balance"] = saBalance.getText(); + jPeer["currency"] = saBalance.getCurrencyHuman(); jPeer["limit"] = saLimit.getJson(0); jPeer["limit_peer"] = saLimitPeer.getJson(0); @@ -514,15 +514,16 @@ Json::Value RPCServer::doCreditSet(Json::Value& params) } else { - NewcoinAddress naAccountPublic; - NewcoinAddress naAccountPrivate; - SLE::pointer sleSrc; - Json::Value obj = authorize(naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, sleSrc); + NewcoinAddress naAccountPublic; + NewcoinAddress naAccountPrivate; + AccountState::pointer asSrc; + uint256 uLedger = mNetOps->getClosedLedger(); + Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, asSrc); if (!obj.empty()) return obj; - STAmount saSrcBalance = sleSrc->getIValueFieldAmount(sfBalance); + STAmount saSrcBalance = asSrc->getBalance(); if (saSrcBalance < theConfig.FEE_DEFAULT) { @@ -533,7 +534,7 @@ Json::Value RPCServer::doCreditSet(Json::Value& params) Transaction::pointer trans = Transaction::sharedCreditSet( naAccountPublic, naAccountPrivate, naSrcAccountID, - sleSrc->getIFieldU32(sfSequence), + asSrc->getSeq(), theConfig.FEE_DEFAULT, 0, // YYY No source tag naDstAccountID, @@ -601,10 +602,11 @@ Json::Value RPCServer::doSend(Json::Value& params) } else { - NewcoinAddress naAccountPublic; - NewcoinAddress naAccountPrivate; - SLE::pointer sleSrc; - Json::Value obj = authorize(naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, sleSrc); + NewcoinAddress naAccountPublic; + NewcoinAddress naAccountPrivate; + AccountState::pointer asSrc; + uint256 uLedger = mNetOps->getClosedLedger(); + Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, asSrc); if (!obj.empty()) { @@ -616,7 +618,7 @@ Json::Value RPCServer::doSend(Json::Value& params) // XXX Confirm saSrcAmount >= saDstAmount. - STAmount saSrcBalance = sleSrc->getIValueFieldAmount(sfBalance); + STAmount saSrcBalance = asSrc->getBalance(); if (saSrcBalance < theConfig.FEE_DEFAULT) { @@ -628,7 +630,7 @@ Json::Value RPCServer::doSend(Json::Value& params) Transaction::pointer trans = Transaction::sharedPayment( naAccountPublic, naAccountPrivate, naSrcAccountID, - sleSrc->getIFieldU32(sfSequence), + asSrc->getSeq(), theConfig.FEE_DEFAULT, 0, // YYY No source tag naDstAccountID, @@ -691,17 +693,18 @@ Json::Value RPCServer::doTransitSet(Json::Value& params) } else { - NewcoinAddress naAccountPublic; - NewcoinAddress naAccountPrivate; - SLE::pointer sleSrc; - Json::Value obj = authorize(naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, sleSrc); + NewcoinAddress naAccountPublic; + NewcoinAddress naAccountPrivate; + AccountState::pointer asSrc; + uint256 uLedger = mNetOps->getClosedLedger(); + Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, asSrc); if (!obj.empty()) { return obj; } - STAmount saSrcBalance = sleSrc->getIValueFieldAmount(sfBalance); + STAmount saSrcBalance = asSrc->getBalance(); uTransitRate = 0; uTransitStart = 0; @@ -716,7 +719,7 @@ Json::Value RPCServer::doTransitSet(Json::Value& params) Transaction::pointer trans = Transaction::sharedTransitSet( naAccountPublic, naAccountPrivate, naSrcAccountID, - sleSrc->getIFieldU32(sfSequence), + asSrc->getSeq(), theConfig.FEE_DEFAULT, 0, // YYY No source tag uTransitRate, @@ -980,6 +983,7 @@ Json::Value RPCServer::doWalletCreate(Json::Value& params) NewcoinAddress naSrcAccountID; NewcoinAddress naDstAccountID; NewcoinAddress naSeed; + uint256 uLedger; if (params.size() < 3 || params.size() > 4) { @@ -1001,7 +1005,11 @@ Json::Value RPCServer::doWalletCreate(Json::Value& params) // We require access to the paying account's sequence number and key information. return JSONRPCError(503, "network not available"); } - else if (mNetOps->getAccountState(naDstAccountID)) + else if ((uLedger = mNetOps->getClosedLedger()).isZero()) + { + return JSONRPCError(503, "no closed ledger"); + } + else if (mNetOps->getAccountState(uLedger, naDstAccountID)) { return "account already exists"; } @@ -1010,13 +1018,14 @@ Json::Value RPCServer::doWalletCreate(Json::Value& params) // Trying to build: // peer_wallet_create [] [] - NewcoinAddress naAccountPublic; - NewcoinAddress naAccountPrivate; - SLE::pointer sleSrc; - Json::Value obj = authorize(naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, sleSrc); + NewcoinAddress naAccountPublic; + NewcoinAddress naAccountPrivate; + AccountState::pointer asSrc; + uint256 uLedger = mNetOps->getClosedLedger(); + Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, asSrc); - STAmount saSrcBalance = sleSrc->getIValueFieldAmount(sfBalance); - STAmount saInitialFunds = (params.size() < 4) ? 0 : boost::lexical_cast(params[3u].asString()); + STAmount saSrcBalance = asSrc->getBalance(); + STAmount saInitialFunds = (params.size() < 4) ? 0 : boost::lexical_cast(params[3u].asString()); if (!obj.empty()) { @@ -1031,7 +1040,7 @@ Json::Value RPCServer::doWalletCreate(Json::Value& params) Transaction::pointer trans = Transaction::sharedCreate( naAccountPublic, naAccountPrivate, naSrcAccountID, - sleSrc->getIFieldU32(sfSequence), + asSrc->getSeq(), theConfig.FEE_CREATE, 0, // YYY No source tag naDstAccountID, diff --git a/src/RPCServer.h b/src/RPCServer.h index 86994cbf31..f05600faa3 100644 --- a/src/RPCServer.h +++ b/src/RPCServer.h @@ -8,8 +8,8 @@ #include "HttpRequest.h" #include "RequestParser.h" #include "NewcoinAddress.h" -#include "SerializedLedger.h" #include "NetworkOPs.h" +#include "SerializedLedger.h" class RPCServer : public boost::enable_shared_from_this { @@ -36,11 +36,11 @@ private: int getParamCount(const Json::Value& params); bool extractString(std::string& param, const Json::Value& params, int index); - Json::Value authorize(const NewcoinAddress& naSeed, const NewcoinAddress& naSrcAccountID, + Json::Value authorize(const uint256& uLedger, const NewcoinAddress& naSeed, const NewcoinAddress& naSrcAccountID, NewcoinAddress& naAccountPublic, NewcoinAddress& naAccountPrivate, - SerializedLedgerEntry::pointer& sleSrc); + AccountState::pointer& asSrc); - Json::Value accountFromString(NewcoinAddress& naAccount, bool& bIndex, const std::string& strIdent, const int iIndex); + Json::Value accountFromString(const uint256& uLedger, NewcoinAddress& naAccount, bool& bIndex, const std::string& strIdent, const int iIndex); Json::Value doAccountInfo(Json::Value& params); Json::Value doAccountLines(Json::Value ¶ms); diff --git a/src/RippleState.cpp b/src/RippleState.cpp new file mode 100644 index 0000000000..59bd7dbcab --- /dev/null +++ b/src/RippleState.cpp @@ -0,0 +1,32 @@ +#include "RippleState.h" + +RippleState::RippleState(SerializedLedgerEntry::pointer ledgerEntry) : + mLedgerEntry(ledgerEntry), + mValid(false), + mViewLowest(true) +{ + if (!mLedgerEntry || mLedgerEntry->getType() != ltRIPPLE_STATE) return; + + mLowID = mLedgerEntry->getIValueFieldAccount(sfLowID); + mHighID = mLedgerEntry->getIValueFieldAccount(sfHighID); + + mLowLimit = mLedgerEntry->getIValueFieldAmount(sfLowLimit); + mHighLimit = mLedgerEntry->getIValueFieldAmount(sfHighLimit); + + // YYY Should never fail. + if (mLowID.isValid() && mHighID.isValid()) + mValid = true; +} + +void RippleState::setViewAccount(const NewcoinAddress& naView) +{ + bool bViewLowestNew = mLowID.getAccountID() == naView.getAccountID(); + + if (bViewLowestNew != mViewLowest) + { + mViewLowest = bViewLowestNew; + mBalance.changeSign(); + } +} + +// vim:ts=4 diff --git a/src/RippleState.h b/src/RippleState.h new file mode 100644 index 0000000000..0f0281a28d --- /dev/null +++ b/src/RippleState.h @@ -0,0 +1,51 @@ +#ifndef __RIPPLESTATE__ +#define __RIPPLESTATE__ + +// +// A ripple line's state. +// + +#include "SerializedLedger.h" + +#include + +class RippleState +{ +public: + typedef boost::shared_ptr pointer; + +private: + SerializedLedgerEntry::pointer mLedgerEntry; + + NewcoinAddress mLowID; + NewcoinAddress mHighID; + + STAmount mLowLimit; + STAmount mHighLimit; + + STAmount mBalance; + + bool mValid; + bool mViewLowest; + +public: + RippleState(SerializedLedgerEntry::pointer ledgerEntry); // For accounts in a ledger + + void setViewAccount(const NewcoinAddress& naView); + + const NewcoinAddress getAccountID() const { return mViewLowest ? mLowID : mHighID; } + const NewcoinAddress getAccountIDPeer() const { return mViewLowest ? mHighID : mLowID; } + + STAmount getBalance() const { return mBalance; } + + STAmount getLimit() const { return mViewLowest ? mLowLimit : mHighLimit; } + STAmount getLimitPeer() const { return mViewLowest ? mHighLimit : mLowLimit; } + + SerializedLedgerEntry::pointer getSLE() { return mLedgerEntry; } + const SerializedLedgerEntry& peekSLE() const { return *mLedgerEntry; } + SerializedLedgerEntry& peekSLE() { return *mLedgerEntry; } + + std::vector getRaw() const; +}; +#endif +// vim:ts=4