diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rpc/blockchain.cpp | 29 | ||||
-rw-r--r-- | src/txdb.cpp | 6 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 4 |
3 files changed, 24 insertions, 15 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 88f6278b2a..5de2394e24 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -815,17 +815,30 @@ UniValue getchaintips(const UniValue& params, bool fHelp) LOCK(cs_main); - /* Build up a list of chain tips. We start with the list of all - known blocks, and successively remove blocks that appear as pprev - of another block. */ + /* + * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them. + * Algorithm: + * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers. + * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip. + * - add chainActive.Tip() + */ std::set<const CBlockIndex*, CompareBlocksByHeight> setTips; - BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) - setTips.insert(item.second); + std::set<const CBlockIndex*> setOrphans; + std::set<const CBlockIndex*> setPrevs; + BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) { - const CBlockIndex* pprev = item.second->pprev; - if (pprev) - setTips.erase(pprev); + if (!chainActive.Contains(item.second)) { + setOrphans.insert(item.second); + setPrevs.insert(item.second->pprev); + } + } + + for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it) + { + if (setPrevs.erase(*it) == 0) { + setTips.insert(*it); + } } // Always report the currently active tip. diff --git a/src/txdb.cpp b/src/txdb.cpp index be86cceeb3..19ca178654 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -134,12 +134,8 @@ bool CCoinsViewDBCursor::Valid() const void CCoinsViewDBCursor::Next() { pcursor->Next(); - if (pcursor->Valid()) { - bool ok = pcursor->GetKey(keyTmp); - assert(ok); // If GetKey fails here something must be wrong with underlying database, we cannot handle that here - } else { + if (!pcursor->Valid() || !pcursor->GetKey(keyTmp)) keyTmp.first = 0; // Invalidate cached key after last record so that Valid() and GetKey() return false - } } bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo) { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3078cebd48..d1e201ec11 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2443,7 +2443,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n" "The inputs added will not be signed, use signrawtransaction for that.\n" "Note that all existing inputs must have their previous output transaction be in the wallet.\n" - "Note that all inputs selected must be of standard form and P2SH scripts must be" + "Note that all inputs selected must be of standard form and P2SH scripts must be\n" "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n" "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n" "\nArguments:\n" @@ -2455,7 +2455,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n" " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n" " }\n" - " for backward compatibility: passing in a true instzead of an object will result in {\"includeWatching\":true}\n" + " for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n" "\nResult:\n" "{\n" " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n" |