From 57092ed9e7edb3c60adc75823dd922ad67ddec62 Mon Sep 17 00:00:00 2001
From: "Wladimir J. van der Laan" <laanwj@gmail.com>
Date: Wed, 22 Oct 2014 09:25:08 +0200
Subject: [PATCH] rpc: make `gettxoutsettinfo` run lock-free

For leveldb "An iterator operates on a snapshot of the database taken
when the iterator is created". This means that it is unnecessary to
lock out other threads while computing statistics, and neither to hold
cs_main for the whole time. Let the thread run free.
---
 src/rpcblockchain.cpp | 2 --
 src/txdb.cpp          | 5 ++++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp
index e45368cb9..85229e985 100644
--- a/src/rpcblockchain.cpp
+++ b/src/rpcblockchain.cpp
@@ -345,8 +345,6 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp)
             + HelpExampleRpc("gettxoutsetinfo", "")
         );
 
-    LOCK(cs_main);
-
     UniValue ret(UniValue::VOBJ);
 
     CCoinsStats stats;
diff --git a/src/txdb.cpp b/src/txdb.cpp
index df9ff8d8c..935b78467 100644
--- a/src/txdb.cpp
+++ b/src/txdb.cpp
@@ -147,7 +147,10 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const {
             return error("%s: Deserialize or I/O error - %s", __func__, e.what());
         }
     }
-    stats.nHeight = mapBlockIndex.find(GetBestBlock())->second->nHeight;
+    {
+        LOCK(cs_main);
+        stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight;
+    }
     stats.hashSerialized = ss.GetHash();
     stats.nTotalAmount = nTotalAmount;
     return true;