diff --git a/rippled-example.cfg b/rippled-example.cfg index 0bbd0f5dd1..7234df1a12 100644 --- a/rippled-example.cfg +++ b/rippled-example.cfg @@ -109,6 +109,12 @@ # Examples: RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE # shfArahZT9Q9ckTf3s1psJ7C7qzVN # +# [ledger_history]: +# To serve clients, servers need historical ledger data. This sets the number of +# past ledgers to acquire on server startup and the minimum to maintain while +# running. Servers that don't need to serve clients can set this to "none". +# Servers that want complete history can set this to "full". +# The default is 256 ledgers [peer_ip] 0.0.0.0 diff --git a/src/cpp/ripple/Config.cpp b/src/cpp/ripple/Config.cpp index 0304de7b47..4701634fbd 100644 --- a/src/cpp/ripple/Config.cpp +++ b/src/cpp/ripple/Config.cpp @@ -296,9 +296,9 @@ void Config::load() if (sectionSingleB(secConfig, SECTION_LEDGER_HISTORY, strTemp)) { boost::to_lower(strTemp); - if ((strTemp == "no") || (strTemp == "none") || (strTemp == "off") || (strTemp == "false")) + if (strTemp == "none") LEDGER_HISTORY = 0; - else if ((strTemp == "yes") || (strTemp == "full") || (strTemp == "on") || (strTemp == "-1")) + else if (strTemp == "full") LEDGER_HISTORY = 1000000000u; else LEDGER_HISTORY = boost::lexical_cast(strTemp); diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index c91662aa03..a498fee1c6 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -1180,4 +1180,22 @@ void Ledger::decPendingSaves() --sPendingSaves; } +void Ledger::ownerDirDescriber(SLE::ref sle, const uint160& owner) +{ + sle->setFieldAccount(sfOwner, owner); +} + +void Ledger::qualityDirDescriber(SLE::ref sle, + const uint160& uTakerPaysCurrency, const uint160& uTakerPaysIssuer, + const uint160& uTakerGetsCurrency, const uint160& uTakerGetsIssuer, + const uint64& uRate) +{ + sle->setFieldH160(sfTakerPaysCurrency, uTakerPaysCurrency); + sle->setFieldH160(sfTakerPaysIssuer, uTakerPaysIssuer); + sle->setFieldH160(sfTakerGetsCurrency, uTakerGetsCurrency); + sle->setFieldH160(sfTakerGetsIssuer, uTakerGetsIssuer); + sle->setFieldU64(sfExchangeRate, uRate); +} + + // vim:ts=4 diff --git a/src/cpp/ripple/Ledger.h b/src/cpp/ripple/Ledger.h index d9ddc14cb4..23292254b3 100644 --- a/src/cpp/ripple/Ledger.h +++ b/src/cpp/ripple/Ledger.h @@ -262,7 +262,8 @@ public: // Directories are doubly linked lists of nodes. // Given a directory root and and index compute the index of a node. - static uint256 getDirNodeIndex(const uint256& uDirRoot, const uint64 uNodeIndex=0); + static uint256 getDirNodeIndex(const uint256& uDirRoot, const uint64 uNodeIndex = 0); + static void ownerDirDescriber(SLE::ref, const uint160& owner); // Return a node: root or normal SLE::pointer getDirNode(LedgerStateParms& parms, const uint256& uNodeIndex); @@ -271,9 +272,13 @@ public: // Quality // - static uint256 getQualityIndex(const uint256& uBase, const uint64 uNodeDir=0); + static uint256 getQualityIndex(const uint256& uBase, const uint64 uNodeDir = 0); static uint256 getQualityNext(const uint256& uBase); static uint64 getQuality(const uint256& uBase); + static void qualityDirDescriber(SLE::ref, + const uint160& uTakerPaysCurrency, const uint160& uTakerPaysIssuer, + const uint160& uTakerGetsCurrency, const uint160& uTakerGetsIssuer, + const uint64& uRate); // // Ripple functions : credit lines diff --git a/src/cpp/ripple/LedgerEntrySet.cpp b/src/cpp/ripple/LedgerEntrySet.cpp index b2cca2b713..5edd8944b5 100644 --- a/src/cpp/ripple/LedgerEntrySet.cpp +++ b/src/cpp/ripple/LedgerEntrySet.cpp @@ -492,9 +492,10 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, TER result, uint32 index) // We only append. This allow for things that watch append only structure to just monitor from the last node on ward. // Within a node with no deletions order of elements is sequential. Otherwise, order of elements is random. TER LedgerEntrySet::dirAdd( - uint64& uNodeDir, - const uint256& uRootIndex, - const uint256& uLedgerIndex) + uint64& uNodeDir, + const uint256& uRootIndex, + const uint256& uLedgerIndex, + boost::function fDescriber) { SLE::pointer sleNode; STVector256 svIndexes; @@ -505,6 +506,7 @@ TER LedgerEntrySet::dirAdd( // No root, make it. sleRoot = entryCreate(ltDIR_NODE, uRootIndex); sleRoot->setFieldH256(sfRootIndex, uRootIndex); + fDescriber(sleRoot); sleNode = sleRoot; uNodeDir = 0; @@ -566,6 +568,8 @@ TER LedgerEntrySet::dirAdd( // Create the new node. sleNode = entryCreate(ltDIR_NODE, Ledger::getDirNodeIndex(uRootIndex, uNodeDir)); sleNode->setFieldH256(sfRootIndex, uRootIndex); + fDescriber(sleNode); + svIndexes = STVector256(); } } diff --git a/src/cpp/ripple/LedgerEntrySet.h b/src/cpp/ripple/LedgerEntrySet.h index 754b31a586..ea91ff9fbb 100644 --- a/src/cpp/ripple/LedgerEntrySet.h +++ b/src/cpp/ripple/LedgerEntrySet.h @@ -2,6 +2,7 @@ #define __LEDGERENTRYSET__ #include +#include #include "SerializedLedger.h" #include "TransactionMeta.h" @@ -86,9 +87,10 @@ public: // Directory functions. TER dirAdd( - uint64& uNodeDir, // Node of entry. - const uint256& uRootIndex, - const uint256& uLedgerIndex); + uint64& uNodeDir, // Node of entry. + const uint256& uRootIndex, + const uint256& uLedgerIndex, + boost::function fDescriber); TER dirDelete( const bool bKeepRoot, diff --git a/src/cpp/ripple/LedgerFormats.cpp b/src/cpp/ripple/LedgerFormats.cpp index 5605cd0413..98c70857a7 100644 --- a/src/cpp/ripple/LedgerFormats.cpp +++ b/src/cpp/ripple/LedgerFormats.cpp @@ -46,6 +46,12 @@ static bool LEFInit() ; DECLARE_LEF(DirectoryNode, ltDIR_NODE) + << SOElement(sfOwner, SOE_OPTIONAL) // for owner directories + << SOElement(sfTakerPaysCurrency, SOE_OPTIONAL) // for order book directories + << SOElement(sfTakerPaysIssuer, SOE_OPTIONAL) // for order book directories + << SOElement(sfTakerGetsCurrency, SOE_OPTIONAL) // for order book directories + << SOElement(sfTakerGetsIssuer, SOE_OPTIONAL) // for order book directories + << SOElement(sfExchangeRate, SOE_OPTIONAL) // for order book directories << SOElement(sfIndexes, SOE_REQUIRED) << SOElement(sfRootIndex, SOE_REQUIRED) << SOElement(sfIndexNext, SOE_OPTIONAL) diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index d36d004539..9a39d31265 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -24,6 +24,7 @@ // there's a functional network. SETUP_LOG(); +DECLARE_INSTANCE(InfoSub); NetworkOPs::NetworkOPs(boost::asio::io_service& io_service, LedgerMaster* pLedgerMaster) : mMode(omDISCONNECTED), mNeedNetworkLedger(false), mNetTimer(io_service), mLedgerMaster(pLedgerMaster), @@ -1079,6 +1080,7 @@ Json::Value NetworkOPs::transJson(const SerializedTransaction& stTxn, TER terRes if (bAccepted) { jvObj["ledger_index"] = lpCurrent->getLedgerSeq(); jvObj["ledger_hash"] = lpCurrent->getHash().ToString(); + jvObj["transaction"]["date"] = lpCurrent->getCloseTimeNC(); } else { diff --git a/src/cpp/ripple/NetworkOPs.h b/src/cpp/ripple/NetworkOPs.h index 8e5730df55..4f8accb567 100644 --- a/src/cpp/ripple/NetworkOPs.h +++ b/src/cpp/ripple/NetworkOPs.h @@ -20,7 +20,9 @@ class Peer; class LedgerConsensus; -class InfoSub +DEFINE_INSTANCE(InfoSub); + +class InfoSub : public IS_INSTANCE(InfoSub) { public: diff --git a/src/cpp/ripple/OfferCreateTransactor.cpp b/src/cpp/ripple/OfferCreateTransactor.cpp index 185e4fedb9..9e1bb20fe5 100644 --- a/src/cpp/ripple/OfferCreateTransactor.cpp +++ b/src/cpp/ripple/OfferCreateTransactor.cpp @@ -1,5 +1,7 @@ #include "OfferCreateTransactor.h" + #include +#include // Take as much as possible. Adjusts account balances. Charges fees on top to taker. // --> uBookBase: The order book to take against. @@ -393,7 +395,9 @@ TER OfferCreateTransactor::doApply() % saTakerGets.getFullText()); // Add offer to owner's directory. - terResult = mEngine->getNodes().dirAdd(uOwnerNode, Ledger::getOwnerDirIndex(mTxnAccountID), uLedgerIndex); + terResult = mEngine->getNodes().dirAdd(uOwnerNode, Ledger::getOwnerDirIndex(mTxnAccountID), uLedgerIndex, + boost::bind(&Ledger::qualityDirDescriber, _1, saTakerPays.getCurrency(), uPaysIssuerID, + saTakerGets.getCurrency(), uGetsIssuerID, uRate)); if (tesSUCCESS == terResult) { @@ -409,7 +413,9 @@ TER OfferCreateTransactor::doApply() uDirectory = Ledger::getQualityIndex(uBookBase, uRate); // Use original rate. // Add offer to order book. - terResult = mEngine->getNodes().dirAdd(uBookNode, uDirectory, uLedgerIndex); + terResult = mEngine->getNodes().dirAdd(uBookNode, uDirectory, uLedgerIndex, + boost::bind(&Ledger::qualityDirDescriber, _1, saTakerPays.getCurrency(), uPaysIssuerID, + saTakerGets.getCurrency(), uGetsIssuerID, uRate)); } if (tesSUCCESS == terResult) diff --git a/src/cpp/ripple/SerializeProto.h b/src/cpp/ripple/SerializeProto.h index 006abd0282..a10ab314be 100644 --- a/src/cpp/ripple/SerializeProto.h +++ b/src/cpp/ripple/SerializeProto.h @@ -65,6 +65,7 @@ FIELD(BookNode, UINT64, 3) FIELD(OwnerNode, UINT64, 4) FIELD(BaseFee, UINT64, 5) + FIELD(ExchangeRate, UINT64, 6) // 128-bit FIELD(EmailHash, HASH128, 1) @@ -84,6 +85,12 @@ FIELD(InvoiceID, HASH256, 17) FIELD(Nickname, HASH256, 18) + // 160-bit (common) + FIELD(TakerPaysCurrency, HASH160, 1) + FIELD(TakerPaysIssuer, HASH160, 2) + FIELD(TakerGetsCurrency, HASH160, 3) + FIELD(TakerGetsIssuer, HASH160, 4) + // currency amount (common) FIELD(Amount, AMOUNT, 1) FIELD(Balance, AMOUNT, 2) diff --git a/src/cpp/ripple/TrustSetTransactor.cpp b/src/cpp/ripple/TrustSetTransactor.cpp index 1d287fda97..3403c40389 100644 --- a/src/cpp/ripple/TrustSetTransactor.cpp +++ b/src/cpp/ripple/TrustSetTransactor.cpp @@ -1,5 +1,7 @@ #include "TrustSetTransactor.h" +#include + TER TrustSetTransactor::doApply() { TER terResult = tesSUCCESS; @@ -135,10 +137,18 @@ TER TrustSetTransactor::doApply() uint64 uSrcRef; // Ignored, dirs never delete. - terResult = mEngine->getNodes().dirAdd(uSrcRef, Ledger::getOwnerDirIndex(mTxnAccountID), sleRippleState->getIndex()); + terResult = mEngine->getNodes().dirAdd( + uSrcRef, + Ledger::getOwnerDirIndex(mTxnAccountID), + sleRippleState->getIndex(), + boost::bind(&Ledger::ownerDirDescriber, _1, mTxnAccountID)); if (tesSUCCESS == terResult) - terResult = mEngine->getNodes().dirAdd(uSrcRef, Ledger::getOwnerDirIndex(uDstAccountID), sleRippleState->getIndex()); + terResult = mEngine->getNodes().dirAdd( + uSrcRef, + Ledger::getOwnerDirIndex(uDstAccountID), + sleRippleState->getIndex(), + boost::bind(&Ledger::ownerDirDescriber, _1, uDstAccountID)); } Log(lsINFO) << "doTrustSet<";