diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index caef05f5c0..50c6f73dad 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -547,7 +547,10 @@ Ledger::pointer Ledger::loadByIndex(uint32 ledgerIndex) ledger = getSQL1(&pSt); } if (ledger) + { Ledger::getSQL2(ledger); + ledger->setFull(); + } return ledger; } @@ -570,6 +573,7 @@ Ledger::pointer Ledger::loadByHash(const uint256& ledgerHash) { assert(ledger->getHash() == ledgerHash); Ledger::getSQL2(ledger); + ledger->setFull(); } return ledger; } diff --git a/src/cpp/ripple/Ledger.h b/src/cpp/ripple/Ledger.h index 6b33999688..381bd658cf 100644 --- a/src/cpp/ripple/Ledger.h +++ b/src/cpp/ripple/Ledger.h @@ -133,6 +133,7 @@ public: bool isAccepted() { return mAccepted; } bool isImmutable() { return mImmutable; } bool isFixed() { return mClosed || mImmutable; } + void setFull() { mTransactionMap->setLedgerSeq(mLedgerSeq); mAccountStateMap->setLedgerSeq(mLedgerSeq); } // ledger signature operations void addRaw(Serializer &s) const; diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 291ed70dda..795f518327 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -2124,4 +2124,12 @@ void NetworkOPs::gotFetchPack(bool progress, uint32 seq) boost::bind(&LedgerAcquireMaster::gotFetchPack, &theApp->getMasterLedgerAcquire(), _1)); } +void NetworkOPs::missingNodeInLedger(uint32 seq) +{ + cLog(lsWARNING) << "We are missing a node in ledger " << seq; + uint256 hash = theApp->getLedgerMaster().getHashBySeq(seq); + if (hash.isNonZero()) + theApp->getMasterLedgerAcquire().findCreate(hash, seq); +} + // vim:ts=4 diff --git a/src/cpp/ripple/NetworkOPs.h b/src/cpp/ripple/NetworkOPs.h index 6db090981f..24a212c82e 100644 --- a/src/cpp/ripple/NetworkOPs.h +++ b/src/cpp/ripple/NetworkOPs.h @@ -183,6 +183,7 @@ public: Ledger::ref getCurrentLedger() { return mLedgerMaster->getCurrentLedger(); } Ledger::pointer getLedgerByHash(const uint256& hash) { return mLedgerMaster->getLedgerByHash(hash); } Ledger::pointer getLedgerBySeq(const uint32 seq); + void missingNodeInLedger(const uint32 seq); uint256 getClosedLedgerHash() { return mLedgerMaster->getClosedLedger()->getHash(); } diff --git a/src/cpp/ripple/SHAMap.cpp b/src/cpp/ripple/SHAMap.cpp index d4d4648e74..7ac25fe968 100644 --- a/src/cpp/ripple/SHAMap.cpp +++ b/src/cpp/ripple/SHAMap.cpp @@ -54,7 +54,7 @@ std::size_t hash_value(const uint160& u) } -SHAMap::SHAMap(SHAMapType t, uint32 seq) : mSeq(seq), mState(smsModifying), mType(t) +SHAMap::SHAMap(SHAMapType t, uint32 seq) : mSeq(seq), mLedgerSeq(0), mState(smsModifying), mType(t) { if (t == smtSTATE) mTNByID.rehash(STATE_MAP_BUCKETS); @@ -63,7 +63,7 @@ SHAMap::SHAMap(SHAMapType t, uint32 seq) : mSeq(seq), mState(smsModifying), mTyp mTNByID[*root] = root; } -SHAMap::SHAMap(SHAMapType t, const uint256& hash) : mSeq(1), mState(smsSynching), mType(t) +SHAMap::SHAMap(SHAMapType t, const uint256& hash) : mSeq(1), mLedgerSeq(0), mState(smsSynching), mType(t) { // FIXME: Need to acquire root node if (t == smtSTATE) mTNByID.rehash(STATE_MAP_BUCKETS); @@ -723,6 +723,11 @@ SHAMapTreeNode::pointer SHAMap::fetchNodeExternal(const SHAMapNode& id, const ui if (!obj) { // cLog(lsTRACE) << "fetchNodeExternal: missing " << hash; + if (mLedgerSeq != 0) + { + theApp->getOPs().missingNodeInLedger(mLedgerSeq); + mLedgerSeq = 0; + } throw SHAMapMissingNode(mType, id, hash); } diff --git a/src/cpp/ripple/SHAMap.h b/src/cpp/ripple/SHAMap.h index 789c13f715..b60c8827c8 100644 --- a/src/cpp/ripple/SHAMap.h +++ b/src/cpp/ripple/SHAMap.h @@ -345,6 +345,7 @@ public: protected: uint32 mSeq; + uint32 mLedgerSeq; // sequence number of ledger this is part of mutable boost::recursive_mutex mLock; boost::unordered_map mTNByID; @@ -395,6 +396,8 @@ public: // Remove nodes from memory void dropCache(); + void setLedgerSeq(uint32 lseq) { mLedgerSeq = lseq; } + // hold the map stable across operations ScopedLock Lock() const { return ScopedLock(mLock); }