Satoshi MailBeta Open in Satoshi Mail

new getwork

Commit by Satoshi Nakamoto (s_nakamoto) on 23 November 2010 · SVN r189 · release v0.3.17 · 10 files, +469 −254

Open in Satoshi Mail View on GitHub

Files changed

coding.txt
@@ -0,0 +1,41 @@
+Please be consistent with the existing coding style.
+
+Block style:
+
+bool Function(char* psz, int n)
+{
+    // Comment summarising what this section of code does
+    for (int i = 0; i < n; i++)
+    {
+        // When something fails, return early
+        if (!Something())
+            return false;
+        ...
+    }
+
+    // Success return is usually at the end
+    return true;
+}
+
+- ANSI/Allman block style
+- 4 space indenting, no tabs
+- No extra spaces inside parenthesis; please don't do ( this )
+- No space after function names, one space after if, for and while
+
+Variable names begin with the type in lowercase, like nSomeVariable.
+Please don't put the first word of the variable name in lowercase like
+someVariable.
+
+Common types:
+n       integer number: short, unsigned short, int, unsigned int,
+            int64, uint64, sometimes char if used as a number
+d       double, float
+f       flag
+hash    uint256
+p       pointer or array, one p for each level of indirection
+psz     pointer to null terminated string
+str     string object
+v       vector or similar list objects
+map     map or multimap
+set     set or multiset
+bn      CBigNum
db.cpp
@@ -961,7 +961,7 @@ void CWalletDB::ReturnKey(int64 nIndex)
     printf("keypool return %"PRI64d"\n", nIndex);
 }
 
-vector<unsigned char> CWalletDB::GetKeyFromKeyPool()
+vector<unsigned char> GetKeyFromKeyPool()
 {
     CWalletDB walletdb;
     int64 nIndex = 0;
@@ -971,7 +971,7 @@ vector<unsigned char> CWalletDB::GetKeyFromKeyPool()
     return keypool.vchPubKey;
 }
 
-int64 CWalletDB::GetOldestKeyPoolTime()
+int64 GetOldestKeyPoolTime()
 {
     CWalletDB walletdb;
     int64 nIndex = 0;
db.h
@@ -26,6 +26,8 @@ extern DbEnv dbenv;
 
 
 extern void DBFlush(bool fShutdown);
+extern vector<unsigned char> GetKeyFromKeyPool();
+extern int64 GetOldestKeyPoolTime();
 
 
 
@@ -440,9 +442,8 @@ protected:
     void KeepKey(int64 nIndex);
     static void ReturnKey(int64 nIndex);
     friend class CReserveKey;
-public:
-    vector<unsigned char> GetKeyFromKeyPool();
-    int64 GetOldestKeyPoolTime();
+    friend vector<unsigned char> GetKeyFromKeyPool();
+    friend int64 GetOldestKeyPoolTime();
 };
 
 bool LoadWallet(bool& fFirstRunRet);
main.cpp
@@ -159,7 +159,7 @@ bool AddToWallet(const CWalletTx& wtxIn)
             if (txout.scriptPubKey == scriptDefaultKey)
             {
                 CWalletDB walletdb;
-                vchDefaultKey = walletdb.GetKeyFromKeyPool();
+                vchDefaultKey = GetKeyFromKeyPool();
                 walletdb.WriteDefaultKey(vchDefaultKey);
                 walletdb.WriteName(PubKeyToAddress(vchDefaultKey), "");
             }
@@ -1557,31 +1557,25 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock)
 
     // Preliminary checks
     if (!pblock->CheckBlock())
-    {
-        delete pblock;
         return error("ProcessBlock() : CheckBlock FAILED");
-    }
 
     // If don't already have its previous block, shunt it off to holding area until we get it
     if (!mapBlockIndex.count(pblock->hashPrevBlock))
     {
         printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,20).c_str());
-        mapOrphanBlocks.insert(make_pair(hash, pblock));
-        mapOrphanBlocksByPrev.insert(make_pair(pblock->hashPrevBlock, pblock));
+        CBlock* pblock2 = new CBlock(*pblock);
+        mapOrphanBlocks.insert(make_pair(hash, pblock2));
+        mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrevBlock, pblock2));
 
         // Ask this guy to fill in what we're missing
         if (pfrom)
-            pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock));
+            pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock2));
         return true;
     }
 
     // Store to disk
     if (!pblock->AcceptBlock())
-    {
-        delete pblock;
         return error("ProcessBlock() : AcceptBlock FAILED");
-    }
-    delete pblock;
 
     // Recursively process any orphan blocks that depended on this one
     vector<uint256> vWorkQueue;
@@ -2504,7 +2498,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
         CInv inv(MSG_BLOCK, pblock->GetHash());
         pfrom->AddInventoryKnown(inv);
 
-        if (ProcessBlock(pfrom, pblock.release()))
+        if (ProcessBlock(pfrom, pblock.get()))
             mapAlreadyAskedFor.erase(inv);
     }
 
@@ -2549,7 +2543,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
 
         // Keep giving the same key to the same ip until they use it
         if (!mapReuseKey.count(pfrom->addr.ip))
-            mapReuseKey[pfrom->addr.ip] = CWalletDB().GetKeyFromKeyPool();
+            mapReuseKey[pfrom->addr.ip] = GetKeyFromKeyPool();
 
         // Send back approval of order and pubkey to use
         CScript scriptPubKey;
@@ -3000,19 +2994,19 @@ inline void SHA256Transform(void* pstate, void* pinput, const void* pinit)
 // ScanHash scans nonces looking for a hash with at least some zero bits.
 // It operates on big endian data.  Caller does the byte reversing.
 // All input buffers are 16-byte aligned.  nNonce is usually preserved
-// between calls, but periodically or if nNonce is above 0xff000000,
+// between calls, but periodically or if nNonce is 0xffff0000 or above,
 // the block is rebuilt and nNonce starts over at zero.
 //
-unsigned int ScanHash_CryptoPP(char* pmidstate, char* pblock, char* phash1, char* phash, unsigned int& nHashesDone)
+unsigned int ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1, char* phash, unsigned int& nHashesDone)
 {
-    unsigned int& nNonce = *(unsigned int*)(pblock + 12);
+    unsigned int& nNonce = *(unsigned int*)(pdata + 12);
     for (;;)
     {
         // Crypto++ SHA-256
-        // Hash pblock using pmidstate as the starting state into
+        // Hash pdata using pmidstate as the starting state into
         // preformatted buffer phash1, then hash phash1 into phash
         nNonce++;
-        SHA256Transform(phash1, pblock, pmidstate);
+        SHA256Transform(phash1, pdata, pmidstate);
         SHA256Transform(phash, phash1, pSHA256InitState);
 
         // Return the nonce if the hash has at least some zero bits,
@@ -3055,6 +3049,262 @@ public:
 };
 
 
+CBlock* CreateNewBlock(CReserveKey& reservekey)
+{
+    CBlockIndex* pindexPrev = pindexBest;
+
+    // Create new block
+    auto_ptr<CBlock> pblock(new CBlock());
+    if (!pblock.get())
+        return NULL;
+
+    // Create coinbase tx
+    CTransaction txNew;
+    txNew.vin.resize(1);
+    txNew.vin[0].prevout.SetNull();
+    txNew.vout.resize(1);
+    txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG;
+
+    // Add our coinbase tx as first transaction
+    pblock->vtx.push_back(txNew);
+
+    // Collect memory pool transactions into the block
+    int64 nFees = 0;
+    CRITICAL_BLOCK(cs_main)
+    CRITICAL_BLOCK(cs_mapTransactions)
+    {
+        CTxDB txdb("r");
+
+        // Priority order to process transactions
+        list<COrphan> vOrphan; // list memory doesn't move
+        map<uint256, vector<COrphan*> > mapDependers;
+        multimap<double, CTransaction*> mapPriority;
+        for (map<uint256, CTransaction>::iterator mi = mapTransactions.begin(); mi != mapTransactions.end(); ++mi)
+        {
+            CTransaction& tx = (*mi).second;
+            if (tx.IsCoinBase() || !tx.IsFinal())
+                continue;
+
+            COrphan* porphan = NULL;
+            double dPriority = 0;
+            foreach(const CTxIn& txin, tx.vin)
+            {
+                // Read prev transaction
+                CTransaction txPrev;
+                CTxIndex txindex;
+                if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
+                {
+                    // Has to wait for dependencies
+                    if (!porphan)
+                    {
+                        // Use list for automatic deletion
+                        vOrphan.push_back(COrphan(&tx));
+                        porphan = &vOrphan.back();
+                    }
+                    mapDependers[txin.prevout.hash].push_back(porphan);
+                    porphan->setDependsOn.insert(txin.prevout.hash);
+                    continue;
+                }
+                int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
+
+                // Read block header
+                int nConf = 0;
+                CBlock block;
+                if (block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
+                {
+                    map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(block.GetHash());
+                    if (it != mapBlockIndex.end())
+                    {
+                        CBlockIndex* pindex = (*it).second;
+                        if (pindex->IsInMainChain())
+                            nConf = 1 + nBestHeight - pindex->nHeight;
+                    }
+                }
+
+                dPriority += (double)nValueIn * nConf;
+
+                if (fDebug && mapArgs.count("-printpriority"))
+                    printf("priority     nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
+            }
+
+            // Priority is sum(valuein * age) / txsize
+            dPriority /= ::GetSerializeSize(tx, SER_NETWORK);
+
+            if (porphan)
+                porphan->dPriority = dPriority;
+            else
+                mapPriority.insert(make_pair(-dPriority, &(*mi).second));
+
+            if (fDebug && mapArgs.count("-printpriority"))
+            {
+                printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().substr(0,10).c_str(), tx.ToString().c_str());
+                if (porphan)
+                    porphan->print();
+                printf("\n");
+            }
+        }
+
+        // Collect transactions into block
+        map<uint256, CTxIndex> mapTestPool;
+        uint64 nBlockSize = 1000;
+        int nBlockSigOps = 100;
+        while (!mapPriority.empty())
+        {
+            // Take highest priority transaction off priority queue
+            double dPriority = -(*mapPriority.begin()).first;
+            CTransaction& tx = *(*mapPriority.begin()).second;
+            mapPriority.erase(mapPriority.begin());
+
+            // Size limits
+            unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK);
+            if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN)
+                continue;
+            int nTxSigOps = tx.GetSigOpCount();
+            if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
+                continue;
+
+            // Transaction fee required depends on block size
+            bool fAllowFree = (nBlockSize + nTxSize < 4000 || dPriority > COIN * 144 / 250);
+            int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree);
+
+            // Connecting shouldn't fail due to dependency on other memory pool transactions
+            // because we're already processing them in order of dependency
+            map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
+            if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, nFees, false, true, nMinFee))
+                continue;
+            swap(mapTestPool, mapTestPoolTmp);
+
+            // Added
+            pblock->vtx.push_back(tx);
+            nBlockSize += nTxSize;
+            nBlockSigOps += nTxSigOps;
+
+            // Add transactions that depend on this one to the priority queue
+            uint256 hash = tx.GetHash();
+            if (mapDependers.count(hash))
+            {
+                foreach(COrphan* porphan, mapDependers[hash])
+                {
+                    if (!porphan->setDependsOn.empty())
+                    {
+                        porphan->setDependsOn.erase(hash);
+                        if (porphan->setDependsOn.empty())
+                            mapPriority.insert(make_pair(-porphan->dPriority, porphan->ptx));
+                    }
+                }
+            }
+        }
+    }
+    pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees);
+
+    // Fill in header
+    pblock->hashPrevBlock  = pindexPrev->GetBlockHash();
+    pblock->hashMerkleRoot = pblock->BuildMerkleTree();
+    pblock->nTime          = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+    pblock->nBits          = GetNextWorkRequired(pindexPrev);
+    pblock->nNonce         = 0;
+
+    return pblock.release();
+}
+
+
+void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce, int64& nPrevTime)
+{
+    // Update nExtraNonce
+    int64 nNow = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+    if (++nExtraNonce >= 0x7f && nNow > nPrevTime+1)
+    {
+        nExtraNonce = 1;
+        nPrevTime = nNow;
+    }
+    pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nBits << CBigNum(nExtraNonce);
+    pblock->hashMerkleRoot = pblock->BuildMerkleTree();
+}
+
+
+void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1)
+{
+    //
+    // Prebuild hash buffers
+    //
+    struct
+    {
+        struct unnamed2
+        {
+            int nVersion;
+            uint256 hashPrevBlock;
+            uint256 hashMerkleRoot;
+            unsigned int nTime;
+            unsigned int nBits;
+            unsigned int nNonce;
+        }
+        block;
+        unsigned char pchPadding0[64];
+        uint256 hash1;
+        unsigned char pchPadding1[64];
+    }
+    tmp;
+    memset(&tmp, 0, sizeof(tmp));
+
+    tmp.block.nVersion       = pblock->nVersion;
+    tmp.block.hashPrevBlock  = pblock->hashPrevBlock;
+    tmp.block.hashMerkleRoot = pblock->hashMerkleRoot;
+    tmp.block.nTime          = pblock->nTime;
+    tmp.block.nBits          = pblock->nBits;
+    tmp.block.nNonce         = pblock->nNonce;
+
+    FormatHashBlocks(&tmp.block, sizeof(tmp.block));
+    FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));
+
+    // Byte swap all the input buffer
main.h
@@ -83,6 +83,10 @@ string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAs
 string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
 void GenerateBitcoins(bool fGenerate);
 void ThreadBitcoinMiner(void* parg);
+CBlock* CreateNewBlock(CReserveKey& reservekey);
+void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce, int64& nPrevTime);
+void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
+bool CheckWork(CBlock* pblock, CReserveKey& reservekey);
 void BitcoinMiner();
 bool CheckProofOfWork(uint256 hash, unsigned int nBits);
 bool IsInitialBlockDownload();
@@ -753,21 +757,28 @@ public:
 
     void Init()
     {
+        vtxPrev.clear();
+        mapValue.clear();
+        vOrderForm.clear();
         nTimeReceived = 0;
         fFromMe = false;
         fSpent = false;
         fTimeReceivedIsTxTime = false;
         fUnused = false;
+        strFromAccount.clear();
         fDebitCached = false;
         fCreditCached = false;
         nDebitCached = 0;
         nCreditCached = 0;
         nTimeDisplayed = 0;
         nLinesDisplayed = 0;
+        fConfirmedDisplayed = false;
     }
 
     IMPLEMENT_SERIALIZE
     (
+        if (fRead)
+            const_cast<CWalletTx*>(this)->Init();
         nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion, ser_action);
         READWRITE(vtxPrev);
         READWRITE(mapValue);
rpc.cpp
@@ -3,6 +3,7 @@
 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
 
 #include "headers.h"
+#include "cryptopp/sha.h"
 #undef printf
 #include <boost/asio.hpp>
 #include <boost/iostreams/concepts.hpp>
@@ -50,6 +51,7 @@ void PrintConsole(const char* format, ...)
         ret = limit - 1;
         buffer[limit-1] = 0;
     }
+    printf("%s", buffer);
 #if defined(__WXMSW__) && defined(GUI)
     MyMessageBox(buffer, "Bitcoin", wxOK | wxICON_EXCLAMATION);
 #else
@@ -263,7 +265,7 @@ Value getinfo(const Array& params, bool fHelp)
     obj.push_back(Pair("difficulty",    (double)GetDifficulty()));
     obj.push_back(Pair("hashespersec",  gethashespersec(params, false)));
     obj.push_back(Pair("testnet",       fTestNet));
-    obj.push_back(Pair("keypoololdest", (boost::int64_t)CWalletDB().GetOldestKeyPoolTime()));
+    obj.push_back(Pair("keypoololdest", (boost::int64_t)GetOldestKeyPoolTime()));
     obj.push_back(Pair("paytxfee",      (double)nTransactionFee / (double)COIN));
     obj.push_back(Pair("errors",        GetWarnings("statusbar")));
     return obj;
@@ -285,7 +287,7 @@ Value getnewaddress(const Array& params, bool fHelp)
         strAccount = params[0].get_str();
 
     // Generate a new key that is added to wallet
-    string strAddress = PubKeyToAddress(CWalletDB().GetKeyFromKeyPool());
+    string strAddress = PubKeyToAddress(GetKeyFromKeyPool());
 
     SetAddressBookName(strAddress, strAccount);
     return strAddress;
@@ -329,7 +331,7 @@ Value getaccountaddress(const Array& params, bool fHelp)
         // Generate a new key
         if (account.vchPubKey.empty())
         {
-            account.vchPubKey = CWalletDB().GetKeyFromKeyPool();
+            account.vchPubKey = GetKeyFromKeyPool();
             string strAddress = PubKeyToAddress(account.vchPubKey);
             SetAddressBookName(strAddress, strAccount);
             walletdb.WriteAccount(strAccount, account);
@@ -925,6 +927,112 @@ Value validateaddress(const Array& params, bool fHelp)
 }
 
 
+Value getwork(const Array& params, bool fHelp)
+{
+    if (fHelp || params.size() > 1)
+        throw runtime_error(
+            "getwork [data]\n"
+            "If [data] is not specified, returns formatted hash data to work on:\n"
+            "  \"midstate\" : precomputed hash state after hashing the first half of the data\n"
+            "  \"data\" : block data\n"
+            "  \"hash1\" : formatted hash buffer for second hash\n"
+            "  \"target\" : little endian hash target\n"
+            "If [data] is specified, tries to solve the block and returns true if it was successful.");
+
+    if (vNodes.empty())
+        throw JSONRPCError(-9, "Bitcoin is not connected!");
+
+    if (IsInitialBlockDownload())
+        throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
+
+    static map<uint256, pair<CBlock*, unsigned int> > mapNewBlock;
+    static vector<CBlock*> vNewBlock;
+    static CReserveKey reservekey;
+
+    if (params.size() == 0)
+    {
+        // Update block
+        static unsigned int nTransactionsUpdatedLast;
+        static CBlockIndex* pindexPrev;
+        static int64 nStart;
+        static CBlock* pblock;
+        if (pindexPrev != pindexBest ||
+            (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
+        {
+            if (pindexPrev != pindexBest)
+            {
+                // Deallocate old blocks since they're obsolete now
+                mapNewBlock.clear();
+                foreach(CBlock* pblock, vNewBlock)
+                    delete pblock;
+                vNewBlock.clear();
+            }
+            nTransactionsUpdatedLast = nTransactionsUpdated;
+            pindexPrev = pindexBest;
+            nStart = GetTime();
+
+            // Create new block
+            pblock = CreateNewBlock(reservekey);
+            if (!pblock)
+                throw JSONRPCError(-7, "Out of memory");
+            vNewBlock.push_back(pblock);
+        }
+
+        // Update nTime
+        pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+        pblock->nNonce = 0;
+
+        // Update nExtraNonce
+        static unsigned int nExtraNonce = 0;
+        static int64 nPrevTime = 0;
+        IncrementExtraNonce(pblock, pindexPrev, nExtraNonce, nPrevTime);
+
+        // Save
+        mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, nExtraNonce);
+
+        // Prebuild hash buffers
+        char pmidstate[32];
+        char pdata[128];
+        char phash1[64];
+        FormatHashBuffers(pblock, pmidstate, pdata, phash1);
+
+        uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
+
+        Object result;
+        result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate))));
+        result.push_back(Pair("data",     HexStr(BEGIN(pdata), END(pdata))));
+        result.push_back(Pair("hash1",    HexStr(BEGIN(phash1), END(phash1))));
+        result.push_back(Pair("target",   HexStr(BEGIN(hashTarget), END(hashTarget))));
+        return result;
+    }
+    else
+    {
+        // Parse parameters
+        vector<unsigned char> vchData = ParseHex(params[0].get_str());
+        if (vchData.size() != 128)
+            throw JSONRPCError(-8, "Invalid parameter");
+        CBlock* pdata = (CBlock*)&vchData[0];
+
+        // Byte reverse
+        for (int i = 0; i < 128/4; i++)
+            ((unsigned int*)pdata)[i] = CryptoPP::ByteReverse(((unsigned int*)pdata)[i]);
+
+        // Get saved block
+        if (!mapNewBlock.count(pdata->hashMerkleRoot))
+            return false;
+        CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first;
+        unsigned int nExtraNonce = mapNewBlock[pdata->hashMerkleRoot].second;
+
+        pblock->nTime = pdata->nTime;
+        pblock->nNonce = pdata->nNonce;
+        pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nBits << CBigNum(nExtraNonce);
+        pblock->hashMerkleRoot = pblock->BuildMerkleTree();
+
+        return CheckWork(pblock, reservekey);
+    }
+}
+
+
 
 
 
@@ -972,6 +1080,7 @@ pair<string, rpcfn_type> pCallTable[] =
     make_pair("getbalance",            &getbalance),
     make_pair("move",                  &movecmd),
     make_pair("sendfrom",              &sendfrom),
+    make_pair("getwork",               &getwork),
 };
 map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
 
@@ -996,6 +1105,7 @@ string pAllowInSafeMode[] =
     "getaddressesbylabel", // deprecated
     "backupwallet",
     "validateaddress",
+    "getwork",
 };
 set<string> setAllowInSafeMode(pAllowInSafeMode, pAllowInSafeMode + sizeof(pAllowInSafeMode)/sizeof(pAllowInSafeMode[0]));
 
@@ -1418,7 +1528,8 @@ void ThreadRPCServer2(void* parg)
             if (valMethod.type() != str_type)
                 throw JSONRPCError(-32600, "Method must be a string");
             string strMethod = valMethod.get_str();
-            printf("ThreadRPCServer method=%s\n", strMethod.c_str());
+            if (strMethod != "getwork")
+                printf("ThreadRPCServer method=%s\n", strMethod.c_str());
 
             // Parse params
             Value valParams = find_value(request, "params");
serialize.h
@@ -22,7 +22,7 @@ class CDataStream;
 class CAutoFile;
 static const unsigned int MAX_SIZE = 0x02000000;
 
-static const int VERSION = 31600;
+static const int VERSION = 31601;
 static const char* pszSubVer = "";
 
 
sha256.cpp
@@ -110,15 +110,15 @@ static const unsigned int pSHA256InitState[8] =
 {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
 
 
-unsigned int ScanHash_4WaySSE2(char* pmidstate, char* pblock, char* phash1, char* phash, unsigned int& nHashesDone)
+unsigned int ScanHash_4WaySSE2(char* pmidstate, char* pdata, char* phash1, char* phash, unsigned int& nHashesDone)
 {
-    unsigned int& nNonce = *(unsigned int*)(pblock + 12);
+    unsigned int& nNonce = *(unsigned int*)(pdata + 12);
     for (;;)
     {
         nNonce += NPAR;
         unsigned int thashbuf[9][NPAR];
         unsigned int (&thash)[9][NPAR] = *alignup<16>(&thashbuf);
-        DoubleBlockSHA256(pblock, phash1, pmidstate, thash, pSHA256InitState);
+        DoubleBlockSHA256(pdata, phash1, pmidstate, thash, pSHA256InitState);
 
         for (int j = 0; j < NPAR; j++)
         {
ui.cpp
@@ -1171,7 +1171,7 @@ void CMainFrame::OnButtonNew(wxCommandEvent& event)
     string strName = dialog.GetValue();
 
     // Generate new key
-    string strAddress = PubKeyToAddress(CWalletDB().GetKeyFromKeyPool());
+    string strAddress = PubKeyToAddress(GetKeyFromKeyPool());
 
     // Save
     SetAddressBookName(strAddress, strName);
@@ -2575,7 +2575,7 @@ void CAddressBookDialog::OnButtonNew(wxCommandEvent& event)
         strName = dialog.GetValue();
 
         // Generate new key
-        strAddress = PubKeyToAddress(CWalletDB().GetKeyFromKeyPool());
+        strAddress = PubKeyToAddress(GetKeyFromKeyPool());
     }
 
     // Add to list and select it
util.cpp
@@ -175,6 +175,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
             va_start(arg_ptr, pszFormat);
             ret = vfprintf(fileout, pszFormat, arg_ptr);
             va_end(arg_ptr);
+            fflush(fileout);
         }
     }