diff --git a/src/cpp/ripple/Application.cpp b/src/cpp/ripple/Application.cpp index 61b6005a2d..16fcada6ad 100644 --- a/src/cpp/ripple/Application.cpp +++ b/src/cpp/ripple/Application.cpp @@ -134,13 +134,6 @@ void Application::run() else startNewLedger(); - if (theConfig.FULL_HISTORY && (theConfig.START_UP != Config::LOAD)) - { - Ledger::pointer ledger = Ledger::getLastFullLedger(); - if (ledger) - mLedgerMaster.setLedgerRangePresent(0, ledger->getLedgerSeq()); - } - // // Begin validation and ip maintenance. // - Wallet maintains local information: including identity and network connection persistence information. diff --git a/src/cpp/ripple/Config.cpp b/src/cpp/ripple/Config.cpp index 18c60c235b..0304de7b47 100644 --- a/src/cpp/ripple/Config.cpp +++ b/src/cpp/ripple/Config.cpp @@ -3,6 +3,7 @@ #include "utils.h" #include +#include #include #include #include @@ -14,7 +15,7 @@ #define SECTION_FEE_NICKNAME_CREATE "fee_nickname_create" #define SECTION_FEE_OFFER "fee_offer" #define SECTION_FEE_OPERATION "fee_operation" -#define SECTION_FULL_HISTORY "full_history" +#define SECTION_LEDGER_HISTORY "ledger_history" #define SECTION_IPS "ips" #define SECTION_NETWORK_QUORUM "network_quorum" #define SECTION_PEER_CONNECT_LOW_WATER "peer_connect_low_water" @@ -157,7 +158,7 @@ void Config::setup(const std::string& strConf) FEE_DEFAULT = DEFAULT_FEE_DEFAULT; FEE_CONTRACT_OPERATION = DEFAULT_FEE_OPERATION; - FULL_HISTORY = false; + LEDGER_HISTORY = 256; ACCOUNT_PROBE_MAX = 10; @@ -292,8 +293,16 @@ void Config::load() if (sectionSingleB(secConfig, SECTION_FEE_OPERATION, strTemp)) FEE_CONTRACT_OPERATION = boost::lexical_cast(strTemp); - if (sectionSingleB(secConfig, SECTION_FULL_HISTORY, strTemp)) - FULL_HISTORY = boost::lexical_cast(strTemp); + if (sectionSingleB(secConfig, SECTION_LEDGER_HISTORY, strTemp)) + { + boost::to_lower(strTemp); + if ((strTemp == "no") || (strTemp == "none") || (strTemp == "off") || (strTemp == "false")) + LEDGER_HISTORY = 0; + else if ((strTemp == "yes") || (strTemp == "full") || (strTemp == "on") || (strTemp == "-1")) + LEDGER_HISTORY = 1000000000u; + else + LEDGER_HISTORY = boost::lexical_cast(strTemp); + } if (sectionSingleB(secConfig, SECTION_ACCOUNT_PROBE_MAX, strTemp)) ACCOUNT_PROBE_MAX = boost::lexical_cast(strTemp); diff --git a/src/cpp/ripple/Config.h b/src/cpp/ripple/Config.h index 53d91f6921..9704396f72 100644 --- a/src/cpp/ripple/Config.h +++ b/src/cpp/ripple/Config.h @@ -108,7 +108,7 @@ public: int FEE_CONTRACT_OPERATION; // fee for each contract operation // Node storage configuration - bool FULL_HISTORY; + uint32 LEDGER_HISTORY; // Client behavior int ACCOUNT_PROBE_MAX; // How far to scan for accounts. diff --git a/src/cpp/ripple/LedgerMaster.cpp b/src/cpp/ripple/LedgerMaster.cpp index 6c3a2ebc97..52468b743e 100644 --- a/src/cpp/ripple/LedgerMaster.cpp +++ b/src/cpp/ripple/LedgerMaster.cpp @@ -152,8 +152,19 @@ void LedgerMaster::missingAcquireComplete(LedgerAcquire::pointer acq) } } -void LedgerMaster::setFullLedger(Ledger::ref ledger) +static bool shouldAcquire(uint32 currentLedger, uint32 ledgerHistory, uint32 candidateLedger) { + bool ret; + if (candidateLedger >= currentLedger) + ret = true; + else ret = (currentLedger - candidateLedger) <= ledgerHistory; + cLog(lsDEBUG) << "Missing ledger " << candidateLedger << (ret ? "will" : "will NOT") << " be acquired"; + return ret; +} + +void LedgerMaster::setFullLedger(Ledger::ref ledger) +{ // A new ledger has been accepted as part of the trusted chain + boost::recursive_mutex::scoped_lock ml(mLock); mCompleteLedgers.setValue(ledger->getLedgerSeq()); @@ -161,7 +172,12 @@ void LedgerMaster::setFullLedger(Ledger::ref ledger) if ((ledger->getLedgerSeq() != 0) && mCompleteLedgers.hasValue(ledger->getLedgerSeq() - 1)) { // we think we have the previous ledger, double check Ledger::pointer prevLedger = getLedgerBySeq(ledger->getLedgerSeq() - 1); - if (prevLedger && (prevLedger->getHash() != ledger->getParentHash())) + if (!prevLedger) + { + cLog(lsWARNING) << "Ledger " << ledger->getLedgerSeq() - 1 << " missing"; + mCompleteLedgers.clearValue(ledger->getLedgerSeq() - 1); + } + else if (prevLedger->getHash() != ledger->getParentHash()) { cLog(lsWARNING) << "Ledger " << ledger->getLedgerSeq() << " invalidates prior ledger"; mCompleteLedgers.clearValue(prevLedger->getLedgerSeq()); @@ -171,7 +187,7 @@ void LedgerMaster::setFullLedger(Ledger::ref ledger) if (mMissingLedger && mMissingLedger->isComplete()) mMissingLedger.reset(); - if (mMissingLedger || !theConfig.FULL_HISTORY) + if (mMissingLedger || !theConfig.LEDGER_HISTORY) return; if (Ledger::getPendingSaves() > 3) @@ -183,13 +199,17 @@ void LedgerMaster::setFullLedger(Ledger::ref ledger) // see if there's a ledger gap we need to fill if (!mCompleteLedgers.hasValue(ledger->getLedgerSeq() - 1)) { + if (!shouldAcquire(mCurrentLedger->getLedgerSeq(), theConfig.LEDGER_HISTORY, ledger->getLedgerSeq() - 1)) + return; cLog(lsINFO) << "We need the ledger before the ledger we just accepted"; acquireMissingLedger(ledger->getParentHash(), ledger->getLedgerSeq() - 1); } else { uint32 prevMissing = mCompleteLedgers.prevMissing(ledger->getLedgerSeq()); - if (prevMissing != RangeSet::RangeSetAbsent) + if (prevMissing == RangeSet::RangeSetAbsent) + return; + if (shouldAcquire(mCurrentLedger->getLedgerSeq(), theConfig.LEDGER_HISTORY, prevMissing)) { cLog(lsINFO) << "Ledger " << prevMissing << " is missing"; assert(!mCompleteLedgers.hasValue(prevMissing));