diff options
Diffstat (limited to 'src/bitcoinrpc.cpp')
-rw-r--r-- | src/bitcoinrpc.cpp | 374 |
1 files changed, 9 insertions, 365 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index b20191b45c..d6805e7ee3 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -5,7 +5,6 @@ #include "main.h" #include "wallet.h" -#include "db.h" #include "walletdb.h" #include "net.h" #include "init.h" @@ -46,6 +45,15 @@ extern Value getconnectioncount(const Array& params, bool fHelp); // in rpcnet.c extern Value getpeerinfo(const Array& params, bool fHelp); extern Value dumpprivkey(const Array& params, bool fHelp); // in rpcdump.cpp extern Value importprivkey(const Array& params, bool fHelp); + +extern Value getgenerate(const Array& params, bool fHelp); // in rpcmining.cpp +extern Value setgenerate(const Array& params, bool fHelp); +extern Value gethashespersec(const Array& params, bool fHelp); +extern Value getmininginfo(const Array& params, bool fHelp); +extern Value getwork(const Array& params, bool fHelp); +extern Value getblocktemplate(const Array& params, bool fHelp); +extern Value submitblock(const Array& params, bool fHelp); + extern Value getrawtransaction(const Array& params, bool fHelp); // in rcprawtransaction.cpp extern Value listunspent(const Array& params, bool fHelp); extern Value createrawtransaction(const Array& params, bool fHelp); @@ -318,56 +326,6 @@ Value getdifficulty(const Array& params, bool fHelp) } -Value getgenerate(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "getgenerate\n" - "Returns true or false."); - - return GetBoolArg("-gen"); -} - - -Value setgenerate(const Array& params, bool fHelp) -{ - if (fHelp || params.size() < 1 || params.size() > 2) - throw runtime_error( - "setgenerate <generate> [genproclimit]\n" - "<generate> is true or false to turn generation on or off.\n" - "Generation is limited to [genproclimit] processors, -1 is unlimited."); - - bool fGenerate = true; - if (params.size() > 0) - fGenerate = params[0].get_bool(); - - if (params.size() > 1) - { - int nGenProcLimit = params[1].get_int(); - mapArgs["-genproclimit"] = itostr(nGenProcLimit); - if (nGenProcLimit == 0) - fGenerate = false; - } - mapArgs["-gen"] = (fGenerate ? "1" : "0"); - - GenerateBitcoins(fGenerate, pwalletMain); - return Value::null; -} - - -Value gethashespersec(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "gethashespersec\n" - "Returns a recent hashes per second performance measurement while generating."); - - if (GetTimeMillis() - nHPSTimerStart > 8000) - return (boost::int64_t)0; - return (boost::int64_t)dHashesPerSec; -} - - Value getinfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -398,28 +356,6 @@ Value getinfo(const Array& params, bool fHelp) } -Value getmininginfo(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "getmininginfo\n" - "Returns an object containing mining-related information."); - - Object obj; - obj.push_back(Pair("blocks", (int)nBestHeight)); - obj.push_back(Pair("currentblocksize",(uint64_t)nLastBlockSize)); - obj.push_back(Pair("currentblocktx",(uint64_t)nLastBlockTx)); - obj.push_back(Pair("difficulty", (double)GetDifficulty())); - obj.push_back(Pair("errors", GetWarnings("statusbar"))); - obj.push_back(Pair("generate", GetBoolArg("-gen"))); - obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1))); - obj.push_back(Pair("hashespersec", gethashespersec(params, false))); - obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); - obj.push_back(Pair("testnet", fTestNet)); - return obj; -} - - Value getnewaddress(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) @@ -1810,298 +1746,6 @@ Value validateaddress(const Array& params, bool fHelp) return ret; } -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 (DEPRECATED)\n" // deprecated - " \"data\" : block data\n" - " \"hash1\" : formatted hash buffer for second hash (DEPRECATED)\n" // deprecated - " \"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..."); - - typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t; - static mapNewBlock_t mapNewBlock; // FIXME: thread safety - 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(); - } - - // Clear pindexPrev so future getworks make a new block, despite any failures from here on - pindexPrev = NULL; - - // Store the pindexBest used before CreateNewBlock, to avoid races - nTransactionsUpdatedLast = nTransactionsUpdated; - CBlockIndex* pindexPrevNew = pindexBest; - nStart = GetTime(); - - // Create new block - pblock = CreateNewBlock(reservekey); - if (!pblock) - throw JSONRPCError(-7, "Out of memory"); - vNewBlock.push_back(pblock); - - // Need to update only after we know CreateNewBlock succeeded - pindexPrev = pindexPrevNew; - } - - // 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); - - // Pre-build 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)))); // 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)))); - 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] = ByteReverse(((unsigned int*)pdata)[i]); - - // Get saved block - if (!mapNewBlock.count(pdata->hashMerkleRoot)) - return false; - CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first; - - pblock->nTime = pdata->nTime; - pblock->nNonce = pdata->nNonce; - pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second; - pblock->hashMerkleRoot = pblock->BuildMerkleTree(); - - return CheckWork(pblock, *pwalletMain, reservekey); - } -} - - -Value getblocktemplate(const Array& params, bool fHelp) -{ - if (fHelp || params.size() > 1) - throw runtime_error( - "getblocktemplate [params]\n" - "Returns data needed to construct a block to work on:\n" - " \"version\" : block version\n" - " \"previousblockhash\" : hash of current highest block\n" - " \"transactions\" : contents of non-coinbase transactions that should be included in the next block\n" - " \"coinbaseaux\" : data that should be included in coinbase\n" - " \"coinbasevalue\" : maximum allowable input to coinbase transaction, including the generation award and transaction fees\n" - " \"target\" : hash target\n" - " \"mintime\" : minimum timestamp appropriate for next block\n" - " \"curtime\" : current timestamp\n" - " \"mutable\" : list of ways the block template may be changed\n" - " \"noncerange\" : range of valid nonces\n" - " \"sigoplimit\" : limit of sigops in blocks\n" - " \"sizelimit\" : limit of block size\n" - " \"bits\" : compressed target of next block\n" - " \"height\" : height of the next block\n" - "See https://en.bitcoin.it/wiki/BIP_0022 for full specification."); - - std::string strMode = "template"; - if (params.size() > 0) - { - const Object& oparam = params[0].get_obj(); - const Value& modeval = find_value(oparam, "mode"); - if (modeval.type() == str_type) - strMode = modeval.get_str(); - else - throw JSONRPCError(-8, "Invalid mode"); - } - - if (strMode != "template") - throw JSONRPCError(-8, "Invalid mode"); - - if (vNodes.empty()) - throw JSONRPCError(-9, "Bitcoin is not connected!"); - - if (IsInitialBlockDownload()) - throw JSONRPCError(-10, "Bitcoin is downloading blocks..."); - - static CReserveKey reservekey(pwalletMain); - - // Update block - static unsigned int nTransactionsUpdatedLast; - static CBlockIndex* pindexPrev; - static int64 nStart; - static CBlock* pblock; - if (pindexPrev != pindexBest || - (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5)) - { - // Clear pindexPrev so future calls make a new block, despite any failures from here on - pindexPrev = NULL; - - // Store the pindexBest used before CreateNewBlock, to avoid races - nTransactionsUpdatedLast = nTransactionsUpdated; - CBlockIndex* pindexPrevNew = pindexBest; - nStart = GetTime(); - - // Create new block - if(pblock) - { - delete pblock; - pblock = NULL; - } - pblock = CreateNewBlock(reservekey); - if (!pblock) - throw JSONRPCError(-7, "Out of memory"); - - // Need to update only after we know CreateNewBlock succeeded - pindexPrev = pindexPrevNew; - } - - // Update nTime - pblock->UpdateTime(pindexPrev); - pblock->nNonce = 0; - - Array transactions; - map<uint256, int64_t> setTxIndex; - int i = 0; - CTxDB txdb("r"); - BOOST_FOREACH (CTransaction& tx, pblock->vtx) - { - uint256 txHash = tx.GetHash(); - setTxIndex[txHash] = i++; - - if (tx.IsCoinBase()) - continue; - - Object entry; - - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); - ssTx << tx; - entry.push_back(Pair("data", HexStr(ssTx.begin(), ssTx.end()))); - - entry.push_back(Pair("hash", txHash.GetHex())); - - MapPrevTx mapInputs; - map<uint256, CTxIndex> mapUnused; - bool fInvalid = false; - if (tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid)) - { - entry.push_back(Pair("fee", (int64_t)(tx.GetValueIn(mapInputs) - tx.GetValueOut()))); - - Array deps; - BOOST_FOREACH (MapPrevTx::value_type& inp, mapInputs) - { - if (setTxIndex.count(inp.first)) - deps.push_back(setTxIndex[inp.first]); - } - entry.push_back(Pair("depends", deps)); - - int64_t nSigOps = tx.GetLegacySigOpCount(); - nSigOps += tx.GetP2SHSigOpCount(mapInputs); - entry.push_back(Pair("sigops", nSigOps)); - } - - transactions.push_back(entry); - } - - Object aux; - aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); - - uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); - - static Array aMutable; - if (aMutable.empty()) - { - aMutable.push_back("time"); - aMutable.push_back("transactions"); - aMutable.push_back("prevblock"); - } - - Object result; - result.push_back(Pair("version", pblock->nVersion)); - result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); - result.push_back(Pair("transactions", transactions)); - result.push_back(Pair("coinbaseaux", aux)); - result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue)); - result.push_back(Pair("target", hashTarget.GetHex())); - result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); - result.push_back(Pair("mutable", aMutable)); - result.push_back(Pair("noncerange", "00000000ffffffff")); - result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS)); - result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE)); - result.push_back(Pair("curtime", (int64_t)pblock->nTime)); - result.push_back(Pair("bits", HexBits(pblock->nBits))); - result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); - - return result; -} - -Value submitblock(const Array& params, bool fHelp) -{ - if (fHelp || params.size() < 1 || params.size() > 2) - throw runtime_error( - "submitblock <hex data> [optional-params-obj]\n" - "[optional-params-obj] parameter is currently ignored.\n" - "Attempts to submit new block to network.\n" - "See https://en.bitcoin.it/wiki/BIP_0022 for full specification."); - - vector<unsigned char> blockData(ParseHex(params[0].get_str())); - CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION); - CBlock block; - try { - ssBlock >> block; - } - catch (std::exception &e) { - throw JSONRPCError(-22, "Block decode failed"); - } - - bool fAccepted = ProcessBlock(NULL, &block); - if (!fAccepted) - throw JSONRPCError(-23, "Block rejected"); - - return true; -} - Value getrawmempool(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) |