From 00913f838fb6e6cf9b9d8716333192bb993946c0 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sun, 17 Mar 2013 22:04:34 -0700 Subject: [PATCH] Fix the 'getAccountHash() == mAccountStateMap->getHash()' bug. 'getNeededHashes' can do the wrong thing (report no needed hashes when we need them all) if we have a ledger's root node but not the root node of the tree we're querying. --- src/cpp/ripple/Ledger.cpp | 26 ++++++++++++++++++++++++++ src/cpp/ripple/Ledger.h | 3 +++ src/cpp/ripple/LedgerAcquire.cpp | 11 +++++++---- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index ddb4bc441..d9fdab4ca 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -1614,6 +1614,32 @@ uint64 Ledger::scaleFeeLoad(uint64 fee) return theApp->getFeeTrack().scaleFeeLoad(fee, mBaseFee, mReferenceFeeUnits); } +std::vector Ledger::getNeededTransactionHashes(int max) +{ + std::vector ret; + if (mTransHash.isNonZero()) + { + if (mTransactionMap->getHash().isZero()) + ret.push_back(mTransHash); + else + ret = mTransactionMap->getNeededHashes(max); + } + return ret; +} + +std::vector Ledger::getNeededAccountStateHashes(int max) +{ + std::vector ret; + if (mAccountHash.isNonZero()) + { + if (mAccountStateMap->getHash().isZero()) + ret.push_back(mAccountHash); + else + ret = mAccountStateMap->getNeededHashes(max); + } + return ret; +} + BOOST_AUTO_TEST_SUITE(quality) BOOST_AUTO_TEST_CASE( getquality ) diff --git a/src/cpp/ripple/Ledger.h b/src/cpp/ripple/Ledger.h index c260a0443..5dda84880 100644 --- a/src/cpp/ripple/Ledger.h +++ b/src/cpp/ripple/Ledger.h @@ -222,6 +222,9 @@ public: static uint256 getLedgerFeatureIndex(); static uint256 getLedgerFeeIndex(); + std::vector getNeededTransactionHashes(int max); + std::vector getNeededAccountStateHashes(int max); + // index calculation functions static uint256 getAccountRootIndex(const uint160& uAccountID); diff --git a/src/cpp/ripple/LedgerAcquire.cpp b/src/cpp/ripple/LedgerAcquire.cpp index 9e9e307e7..e345dc18c 100644 --- a/src/cpp/ripple/LedgerAcquire.cpp +++ b/src/cpp/ripple/LedgerAcquire.cpp @@ -139,7 +139,7 @@ bool LedgerAcquire::tryLocal() { mLedger->peekTransactionMap()->fetchRoot(mLedger->getTransHash()); cLog(lsDEBUG) << "Got root txn map locally"; - std::vector h = mLedger->peekTransactionMap()->getNeededHashes(1); + std::vector h = mLedger->getNeededTransactionHashes(1); if (h.empty()) { cLog(lsDEBUG) << "Had full txn map locally"; @@ -155,14 +155,17 @@ bool LedgerAcquire::tryLocal() if (!mHaveState) { if (mLedger->getAccountHash().isZero()) + { + cLog(lsFATAL) << "We are acquiring a ledger with a zero account hash"; mHaveState = true; + } else { try { mLedger->peekAccountStateMap()->fetchRoot(mLedger->getAccountHash()); cLog(lsDEBUG) << "Got root AS map locally"; - std::vector h = mLedger->peekAccountStateMap()->getNeededHashes(1); + std::vector h = mLedger->getNeededAccountStateHashes(1); if (h.empty()) { cLog(lsDEBUG) << "Had full AS map locally"; @@ -783,13 +786,13 @@ std::vector LedgerAcquire::getNeededHashes() } if (!mHaveState) { - std::vector v = mLedger->peekAccountStateMap()->getNeededHashes(16); + std::vector v = mLedger->getNeededAccountStateHashes(16); BOOST_FOREACH(const uint256& h, v) ret.push_back(std::make_pair(ripple::TMGetObjectByHash::otSTATE_NODE, h)); } if (!mHaveTransactions) { - std::vector v = mLedger->peekTransactionMap()->getNeededHashes(16); + std::vector v = mLedger->getNeededAccountStateHashes(16); BOOST_FOREACH(const uint256& h, v) ret.push_back(std::make_pair(ripple::TMGetObjectByHash::otTRANSACTION_NODE, h)); }