Fix rpc-hanging deadlocks
[novacoin.git] / src / script.cpp
index 652240f..6e7bcb5 100644 (file)
@@ -1,4 +1,5 @@
 // Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2011 The Bitcoin developers
 // Distributed under the MIT/X11 software license, see the accompanying
 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
 #include "headers.h"
@@ -1032,48 +1033,45 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash
         return false;
 
     // Compile solution
-    CRITICAL_BLOCK(keystore.cs_KeyStore)
+    BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
     {
-        BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
+        if (item.first == OP_PUBKEY)
         {
-            if (item.first == OP_PUBKEY)
+            // Sign
+            const valtype& vchPubKey = item.second;
+            CKey key;
+            if (!keystore.GetKey(Hash160(vchPubKey), key))
+                return false;
+            if (key.GetPubKey() != vchPubKey)
+                return false;
+            if (hash != 0)
             {
-                // Sign
-                const valtype& vchPubKey = item.second;
-                CKey key;
-                if (!keystore.GetKey(Hash160(vchPubKey), key))
-                    return false;
-                if (key.GetPubKey() != vchPubKey)
+                vector<unsigned char> vchSig;
+                if (!key.Sign(hash, vchSig))
                     return false;
-                if (hash != 0)
-                {
-                    vector<unsigned char> vchSig;
-                    if (!key.Sign(hash, vchSig))
-                        return false;
-                    vchSig.push_back((unsigned char)nHashType);
-                    scriptSigRet << vchSig;
-                }
+                vchSig.push_back((unsigned char)nHashType);
+                scriptSigRet << vchSig;
             }
-            else if (item.first == OP_PUBKEYHASH)
+        }
+        else if (item.first == OP_PUBKEYHASH)
+        {
+            // Sign and give pubkey
+            CKey key;
+            if (!keystore.GetKey(uint160(item.second), key))
+                return false;
+            if (hash != 0)
             {
-                // Sign and give pubkey
-                CKey key;
-                if (!keystore.GetKey(uint160(item.second), key))
+                vector<unsigned char> vchSig;
+                if (!key.Sign(hash, vchSig))
                     return false;
-                if (hash != 0)
-                {
-                    vector<unsigned char> vchSig;
-                    if (!key.Sign(hash, vchSig))
-                        return false;
-                    vchSig.push_back((unsigned char)nHashType);
-                    scriptSigRet << vchSig << key.GetPubKey();
-                }
-            }
-            else
-            {
-                return false;
+                vchSig.push_back((unsigned char)nHashType);
+                scriptSigRet << vchSig << key.GetPubKey();
             }
         }
+        else
+        {
+            return false;
+        }
     }
 
     return true;
@@ -1094,58 +1092,60 @@ bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
         return false;
 
     // Compile solution
-    CRITICAL_BLOCK(keystore.cs_KeyStore)
+    BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
     {
-        BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
+        if (item.first == OP_PUBKEY)
         {
-            if (item.first == OP_PUBKEY)
-            {
-                const valtype& vchPubKey = item.second;
-                vector<unsigned char> vchPubKeyFound;
-                if (!keystore.GetPubKey(Hash160(vchPubKey), vchPubKeyFound))
-                    return false;
-                if (vchPubKeyFound != vchPubKey)
-                    return false;
-            }
-            else if (item.first == OP_PUBKEYHASH)
-            {
-                if (!keystore.HaveKey(uint160(item.second)))
-                    return false;
-            }
-            else
-            {
+            const valtype& vchPubKey = item.second;
+            vector<unsigned char> vchPubKeyFound;
+            if (!keystore.GetPubKey(Hash160(vchPubKey), vchPubKeyFound))
                 return false;
-            }
+            if (vchPubKeyFound != vchPubKey)
+                return false;
+        }
+        else if (item.first == OP_PUBKEYHASH)
+        {
+            if (!keystore.HaveKey(uint160(item.second)))
+                return false;
+        }
+        else
+        {
+            return false;
         }
     }
 
     return true;
 }
 
-
-bool ExtractAddress(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet)
+bool static ExtractAddressInner(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet)
 {
     vector<pair<opcodetype, valtype> > vSolution;
     if (!Solver(scriptPubKey, vSolution))
         return false;
 
-    CRITICAL_BLOCK(keystore->cs_KeyStore)
+    BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
     {
-        BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
-        {
-            uint160 hash160;
-            if (item.first == OP_PUBKEY)
-                addressRet.SetPubKey(item.second);
-            else if (item.first == OP_PUBKEYHASH)
-                addressRet.SetHash160((uint160)item.second);
-            if (keystore == NULL || keystore->HaveKey(addressRet))
-                return true;
-        }
+        if (item.first == OP_PUBKEY)
+            addressRet.SetPubKey(item.second);
+        else if (item.first == OP_PUBKEYHASH)
+            addressRet.SetHash160((uint160)item.second);
+        if (keystore == NULL || keystore->HaveKey(addressRet))
+            return true;
     }
     return false;
 }
 
 
+bool ExtractAddress(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet)
+{
+    if (keystore)
+        return ExtractAddressInner(scriptPubKey, keystore, addressRet);
+    else
+        return ExtractAddressInner(scriptPubKey, NULL, addressRet);
+    return false;
+}
+
+
 bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int nHashType)
 {
     vector<vector<unsigned char> > stack;