Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff -Nurp src/bitcoinrpc.cpp src2/bitcoinrpc.cpp
- --- src/bitcoinrpc.cpp 2012-04-26 18:04:42.161964416 -0700
- +++ src2/bitcoinrpc.cpp 2012-04-26 18:08:55.443529152 -0700
- @@ -1786,6 +1786,59 @@ Value validateaddress(const Array& param
- return ret;
- }
- +static boost::recursive_mutex mGetWork;
- +static map<uint256, pair<CBlock*, CScript> > mapGetWorkNewBlock;
- +static CReserveKey *pGetWorkReserveKey = NULL;
- +
- +void GetWorkBlock(char *pmidstate, char *pdata, char *phash1, uint256 &hashTarget)
- +{ // Fill the buffers with a correct work unit
- + boost::unique_lock<boost::recursive_mutex> lock(mGetWork);
- + static vector<CBlock*> vNewBlock;
- + static unsigned int nTransactionsUpdatedLast;
- + static CBlockIndex* pindexPrev;
- + static int64 nStart;
- + static CBlock* pblock;
- +
- + while (pindexPrev != pindexBest ||
- + (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
- + {
- + if (pindexPrev != pindexBest)
- + {
- + // Deallocate old blocks since they're obsolete now
- + mapGetWorkNewBlock.clear();
- + BOOST_FOREACH(CBlock* pblock, vNewBlock)
- + delete pblock;
- + vNewBlock.clear();
- + }
- + nTransactionsUpdatedLast = nTransactionsUpdated;
- + pindexPrev = pindexBest;
- + nStart = GetTime();
- +
- + // Create new block
- + if (pGetWorkReserveKey == NULL)
- + pGetWorkReserveKey = new CReserveKey(pwalletMain);
- + pblock = CreateNewBlock(*pGetWorkReserveKey);
- + 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;
- + IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
- +
- + // Save
- + mapGetWorkNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);
- +
- + // Prebuild hash buffers
- + FormatHashBuffers(pblock, pmidstate, pdata, phash1);
- + hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
- +}
- +
- Value getwork(const Array& params, bool fHelp)
- {
- if (fHelp || params.size() > 1)
- @@ -1804,64 +1857,21 @@ Value getwork(const Array& params, bool
- if (IsInitialBlockDownload())
- throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
- - typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
- - static mapNewBlock_t mapNewBlock;
- - static vector<CBlock*> vNewBlock;
- - static CReserveKey reservekey(pwalletMain);
- -
- 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();
- - BOOST_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->UpdateTime(pindexPrev);
- - pblock->nNonce = 0;
- -
- - // Update nExtraNonce
- - static unsigned int nExtraNonce = 0;
- - IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
- -
- - // Save
- - mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig);
- -
- - // Prebuild hash buffers
- char pmidstate[32];
- char pdata[128];
- char phash1[64];
- - FormatHashBuffers(pblock, pmidstate, pdata, phash1);
- + char hexbuf[512];
- + uint256 hashTarget;
- - uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
- + GetWorkBlock(pmidstate, pdata, phash1, hashTarget);
- Object result;
- - result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated
- - result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata))));
- - result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); // deprecated
- - result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget))));
- + result.push_back(Pair("midstate", ToHex(pmidstate, 32, hexbuf))); // deprecated
- + result.push_back(Pair("data", ToHex(pdata, 128, hexbuf)));
- + result.push_back(Pair("hash1", ToHex(phash1, 64, hexbuf))); // deprecated
- + result.push_back(Pair("target", ToHex((const char *) &hashTarget, sizeof(hashTarget), hexbuf)));
- return result;
- }
- else
- @@ -1877,19 +1887,48 @@ Value getwork(const Array& params, bool
- ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]);
- // Get saved block
- - if (!mapNewBlock.count(pdata->hashMerkleRoot))
- + if (!mapGetWorkNewBlock.count(pdata->hashMerkleRoot))
- return false;
- - CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first;
- + CBlock* pblock = mapGetWorkNewBlock[pdata->hashMerkleRoot].first;
- pblock->nTime = pdata->nTime;
- pblock->nNonce = pdata->nNonce;
- - pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second;
- + pblock->vtx[0].vin[0].scriptSig = mapGetWorkNewBlock[pdata->hashMerkleRoot].second;
- pblock->hashMerkleRoot = pblock->BuildMerkleTree();
- - return CheckWork(pblock, *pwalletMain, reservekey);
- + return CheckWork(pblock, *pwalletMain, *pGetWorkReserveKey);
- }
- }
- +std::string FastGetWork(const std::string id)
- +{ // bypass JSON in the most common case
- + if (vNodes.empty())
- + throw JSONRPCError(-9, "Bitcoin is not connected!");
- +
- + if (IsInitialBlockDownload())
- + throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
- +
- + char pmidstate[32];
- + char pdata[128];
- + char phash1[64];
- + char hexbuf[512];
- + uint256 hashTarget;
- +
- + GetWorkBlock(pmidstate, pdata, phash1, hashTarget);
- +
- + std::string result = "{\"result\":{\"midstate\" : \"";
- + result += ToHex(pmidstate, 32, hexbuf);
- + result += "\",\"data\":\"";
- + result += ToHex(pdata, 128, hexbuf);
- + result += "\",\"hash1\":\"";
- + result += ToHex(phash1, 64, hexbuf);
- + result += "\",\"target\":\"";
- + result += ToHex((const char *) &hashTarget, sizeof(hashTarget), hexbuf);
- + result += "\"},\"error\":null,\"id\":\"";
- + result += id;
- + result += "\"}\n";
- + return result;
- +}
- Value getmemorypool(const Array& params, bool fHelp)
- {
- @@ -2546,6 +2585,33 @@ void ThreadRPCServer3(void* parg)
- if (mapHeaders["connection"] == "close")
- fRun = false;
- + if ((strRequest.find("\"getwork\"") != std::string::npos) && strRequest.find("[]") != std::string::npos)
- + { // This is imperfect code
- + std::string id;
- + size_t p = strRequest.find("\"id\":");
- + if (p != std::string::npos)
- + {
- + size_t ep = strRequest.find(" ", p+5), e;
- + if((e=strRequest.find(",", p+5))<ep) ep = e;
- + if((e=strRequest.find("}", p+5))<ep) ep = e;
- + id = strRequest.substr(p+5, ep-p-5);
- + }
- + try
- + {
- + conn->stream << HTTPReply(200, FastGetWork(id), fRun) << std::flush;
- + }
- + catch (std::exception& e)
- + {
- + ErrorReply(conn->stream, JSONRPCError(-1, e.what()), id);
- + fRun = false;
- + }
- + catch (Object& e)
- + {
- + ErrorReply(conn->stream, e, id);
- + fRun = false;
- + }
- + continue;
- + }
- Value id = Value::null;
- try
- @@ -2560,17 +2626,39 @@ void ThreadRPCServer3(void* parg)
- id = find_value(request, "id");
- // Parse method
- + Value valParams = find_value(request, "params");
- Value valMethod = find_value(request, "method");
- if (valMethod.type() == null_type)
- throw JSONRPCError(-32600, "Missing method");
- if (valMethod.type() != str_type)
- throw JSONRPCError(-32600, "Method must be a string");
- string strMethod = valMethod.get_str();
- - if (strMethod != "getwork" && strMethod != "getmemorypool")
- + bool bGetWork = strMethod == "getwork";
- + if (!bGetWork && strMethod != "getmemorypool")
- printf("ThreadRPCServer method=%s\n", strMethod.c_str());
- + else if (bGetWork)
- + { // is a getwork request
- + if( (valParams.type() == array_type) && valParams.get_array().size() == 0 )
- + {
- + try
- + {
- + conn->stream << HTTPReply(200, FastGetWork(id.type()==str_type ? id.get_str() : ""), fRun) << std::flush;
- + }
- + catch (std::exception& e)
- + {
- + ErrorReply(conn->stream, JSONRPCError(-1, e.what()), id);
- + fRun = false;
- + }
- + catch (Object& e)
- + {
- + ErrorReply(conn->stream, e, id);
- + fRun = false;
- + }
- + continue;
- + }
- + }
- // Parse params
- - Value valParams = find_value(request, "params");
- Array params;
- if (valParams.type() == array_type)
- params = valParams.get_array();
- diff -Nurp src/util.cpp src2/util.cpp
- --- src/util.cpp 2012-04-26 18:04:42.161964416 -0700
- +++ src2/util.cpp 2012-04-26 18:08:55.443529152 -0700
- @@ -474,6 +474,25 @@ vector<unsigned char> ParseHex(const cha
- return vch;
- }
- +char* ToHex(const char *ptr, int len, char *outbuf)
- +{
- + static char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
- + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
- + char *outptr = outbuf;
- + unsigned char *iptr = (unsigned char *) ptr;
- +
- + while (len-- > 0)
- + {
- + *outptr++ = hexmap[*iptr>>4];
- + *outptr++ = hexmap[*iptr&15];
- + iptr++;
- + }
- +
- + *outptr=0;
- + return outbuf;
- +}
- +
- +
- vector<unsigned char> ParseHex(const string& str)
- {
- return ParseHex(str.c_str());
- diff -Nurp src/util.h src2/util.h
- --- src/util.h 2012-04-26 18:04:42.161964416 -0700
- +++ src2/util.h 2012-04-26 18:08:55.443529152 -0700
- @@ -146,6 +146,7 @@ void ParseString(const std::string& str,
- std::string FormatMoney(int64 n, bool fPlus=false);
- bool ParseMoney(const std::string& str, int64& nRet);
- bool ParseMoney(const char* pszIn, int64& nRet);
- +char* ToHex(const char *ptr, int len, char *outbuf);
- std::vector<unsigned char> ParseHex(const char* psz);
- std::vector<unsigned char> ParseHex(const std::string& str);
- bool IsHex(const std::string& str);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement