diff --git a/bitcoin-qt.pro b/bitcoin-qt.pro index 2770f6650..ed84cbd03 100644 --- a/bitcoin-qt.pro +++ b/bitcoin-qt.pro @@ -211,6 +211,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/rpcnet.cpp \ src/rpcmining.cpp \ src/rpcwallet.cpp \ + src/rpcblockchain.cpp \ src/rpcrawtransaction.cpp \ src/qt/overviewpage.cpp \ src/qt/csvmodelwriter.cpp \ diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 903d66e33..d59deacd8 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -3,8 +3,6 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "main.h" -#include "net.h" #include "init.h" #include "util.h" #include "sync.h" @@ -87,38 +85,6 @@ void RPCTypeCheck(const Object& o, } } -double GetDifficulty(const CBlockIndex* blockindex = NULL) -{ - // Floating point number that is a multiple of the minimum difficulty, - // minimum difficulty = 1.0. - if (blockindex == NULL) - { - if (pindexBest == NULL) - return 1.0; - else - blockindex = pindexBest; - } - - int nShift = (blockindex->nBits >> 24) & 0xff; - - double dDiff = - (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff); - - while (nShift < 29) - { - dDiff *= 256.0; - nShift++; - } - while (nShift > 29) - { - dDiff /= 256.0; - nShift--; - } - - return dDiff; -} - - int64 AmountFromValue(const Value& value) { double dAmount = value.get_real(); @@ -146,34 +112,6 @@ HexBits(unsigned int nBits) return HexStr(BEGIN(uBits.cBits), END(uBits.cBits)); } -Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex) -{ - Object result; - result.push_back(Pair("hash", block.GetHash().GetHex())); - CMerkleTx txGen(block.vtx[0]); - txGen.SetMerkleBranch(&block); - result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain())); - result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); - result.push_back(Pair("height", blockindex->nHeight)); - result.push_back(Pair("version", block.nVersion)); - result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); - Array txs; - BOOST_FOREACH(const CTransaction&tx, block.vtx) - txs.push_back(tx.GetHash().GetHex()); - result.push_back(Pair("tx", txs)); - result.push_back(Pair("time", (boost::int64_t)block.GetBlockTime())); - result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce)); - result.push_back(Pair("bits", HexBits(block.nBits))); - result.push_back(Pair("difficulty", GetDifficulty(blockindex))); - - if (blockindex->pprev) - result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); - if (blockindex->pnext) - result.push_back(Pair("nextblockhash", blockindex->pnext->GetBlockHash().GetHex())); - return result; -} - - /// @@ -243,131 +181,6 @@ Value stop(const Array& params, bool fHelp) } -Value getblockcount(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "getblockcount\n" - "Returns the number of blocks in the longest block chain."); - - return nBestHeight; -} - - -Value getdifficulty(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "getdifficulty\n" - "Returns the proof-of-work difficulty as a multiple of the minimum difficulty."); - - return GetDifficulty(); -} - - -Value getinfo(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "getinfo\n" - "Returns an object containing various state info."); - - CService addrProxy; - GetProxy(NET_IPV4, addrProxy); - - Object obj; - obj.push_back(Pair("version", (int)CLIENT_VERSION)); - obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION)); - obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); - obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); - obj.push_back(Pair("blocks", (int)nBestHeight)); - obj.push_back(Pair("connections", (int)vNodes.size())); - obj.push_back(Pair("proxy", (addrProxy.IsValid() ? addrProxy.ToStringIPPort() : string()))); - obj.push_back(Pair("difficulty", (double)GetDifficulty())); - obj.push_back(Pair("testnet", fTestNet)); - obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime())); - obj.push_back(Pair("keypoolsize", pwalletMain->GetKeyPoolSize())); - obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee))); - if (pwalletMain->IsCrypted()) - obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime / 1000)); - obj.push_back(Pair("errors", GetWarnings("statusbar"))); - return obj; -} - - -Value settxfee(const Array& params, bool fHelp) -{ - if (fHelp || params.size() < 1 || params.size() > 1) - throw runtime_error( - "settxfee \n" - " is a real and is rounded to the nearest 0.00000001"); - - // Amount - int64 nAmount = 0; - if (params[0].get_real() != 0.0) - nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts - - nTransactionFee = nAmount; - return true; -} - -Value getrawmempool(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "getrawmempool\n" - "Returns all transaction ids in memory pool."); - - vector vtxid; - mempool.queryHashes(vtxid); - - Array a; - BOOST_FOREACH(const uint256& hash, vtxid) - a.push_back(hash.ToString()); - - return a; -} - -Value getblockhash(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 1) - throw runtime_error( - "getblockhash \n" - "Returns hash of block in best-block-chain at ."); - - int nHeight = params[0].get_int(); - if (nHeight < 0 || nHeight > nBestHeight) - throw runtime_error("Block number out of range."); - - CBlockIndex* pblockindex = FindBlockByHeight(nHeight); - return pblockindex->phashBlock->GetHex(); -} - -Value getblock(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 1) - throw runtime_error( - "getblock \n" - "Returns details of a block with given block-hash."); - - std::string strHash = params[0].get_str(); - uint256 hash(strHash); - - if (mapBlockIndex.count(hash) == 0) - throw JSONRPCError(-5, "Block not found"); - - CBlock block; - CBlockIndex* pblockindex = mapBlockIndex[hash]; - block.ReadFromDisk(pblockindex, true); - - return blockToJSON(block, pblockindex); -} - - - - - - // // Call Table diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 5120b71a2..c845f1bc1 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -10,6 +10,8 @@ #include #include +class CBlockIndex; + #include "json/json_spirit_reader_template.h" #include "json/json_spirit_writer_template.h" #include "json/json_spirit_utils.h" @@ -73,6 +75,10 @@ extern const CRPCTable tableRPC; extern int64 nWalletUnlockTime; extern int64 AmountFromValue(const json_spirit::Value& value); extern json_spirit::Value ValueFromAmount(int64 amount); +extern double GetDifficulty(const CBlockIndex* blockindex = NULL); +extern std::string HexBits(unsigned int nBits); +extern std::string HelpRequiringPassphrase(); +extern void EnsureWalletIsUnlocked(); extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp); @@ -115,6 +121,7 @@ extern json_spirit::Value walletpassphrasechange(const json_spirit::Array& param extern json_spirit::Value walletlock(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value encryptwallet(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value validateaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getinfo(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp); @@ -123,4 +130,11 @@ extern json_spirit::Value decoderawtransaction(const json_spirit::Array& params, extern json_spirit::Value signrawtransaction(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value sendrawtransaction(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getblockcount(const json_spirit::Array& params, bool fHelp); // in rpcblockchain.cpp +extern json_spirit::Value getdifficulty(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value settxfee(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp); + #endif diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw index 86db4ee16..e22a9f38e 100644 --- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -64,6 +64,7 @@ OBJS= \ obj/rpcnet.o \ obj/rpcmining.o \ obj/rpcwallet.o \ + obj/rpcblockchain.o \ obj/rpcrawtransaction.o \ obj/script.o \ obj/sync.o \ diff --git a/src/makefile.mingw b/src/makefile.mingw index 84543df2f..74897656a 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -60,6 +60,7 @@ OBJS= \ obj/rpcnet.o \ obj/rpcmining.o \ obj/rpcwallet.o \ + obj/rpcblockchain.o \ obj/rpcrawtransaction.o \ obj/script.o \ obj/sync.o \ diff --git a/src/makefile.osx b/src/makefile.osx index fec1c6cb2..977878398 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -87,6 +87,7 @@ OBJS= \ obj/rpcnet.o \ obj/rpcmining.o \ obj/rpcwallet.o \ + obj/rpcblockchain.o \ obj/rpcrawtransaction.o \ obj/script.o \ obj/sync.o \ diff --git a/src/makefile.unix b/src/makefile.unix index e9200ac4d..de067f4eb 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -112,6 +112,7 @@ OBJS= \ obj/rpcnet.o \ obj/rpcmining.o \ obj/rpcwallet.o \ + obj/rpcblockchain.o \ obj/rpcrawtransaction.o \ obj/script.o \ obj/sync.o \ diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp new file mode 100644 index 000000000..5469dd295 --- /dev/null +++ b/src/rpcblockchain.cpp @@ -0,0 +1,165 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "main.h" +#include "bitcoinrpc.h" + +using namespace json_spirit; +using namespace std; + +double GetDifficulty(const CBlockIndex* blockindex) +{ + // Floating point number that is a multiple of the minimum difficulty, + // minimum difficulty = 1.0. + if (blockindex == NULL) + { + if (pindexBest == NULL) + return 1.0; + else + blockindex = pindexBest; + } + + int nShift = (blockindex->nBits >> 24) & 0xff; + + double dDiff = + (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff); + + while (nShift < 29) + { + dDiff *= 256.0; + nShift++; + } + while (nShift > 29) + { + dDiff /= 256.0; + nShift--; + } + + return dDiff; +} + + +Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex) +{ + Object result; + result.push_back(Pair("hash", block.GetHash().GetHex())); + CMerkleTx txGen(block.vtx[0]); + txGen.SetMerkleBranch(&block); + result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain())); + result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); + result.push_back(Pair("height", blockindex->nHeight)); + result.push_back(Pair("version", block.nVersion)); + result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); + Array txs; + BOOST_FOREACH(const CTransaction&tx, block.vtx) + txs.push_back(tx.GetHash().GetHex()); + result.push_back(Pair("tx", txs)); + result.push_back(Pair("time", (boost::int64_t)block.GetBlockTime())); + result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce)); + result.push_back(Pair("bits", HexBits(block.nBits))); + result.push_back(Pair("difficulty", GetDifficulty(blockindex))); + + if (blockindex->pprev) + result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + if (blockindex->pnext) + result.push_back(Pair("nextblockhash", blockindex->pnext->GetBlockHash().GetHex())); + return result; +} + + +Value getblockcount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getblockcount\n" + "Returns the number of blocks in the longest block chain."); + + return nBestHeight; +} + + +Value getdifficulty(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getdifficulty\n" + "Returns the proof-of-work difficulty as a multiple of the minimum difficulty."); + + return GetDifficulty(); +} + + +Value settxfee(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 1) + throw runtime_error( + "settxfee \n" + " is a real and is rounded to the nearest 0.00000001"); + + // Amount + int64 nAmount = 0; + if (params[0].get_real() != 0.0) + nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts + + nTransactionFee = nAmount; + return true; +} + +Value getrawmempool(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getrawmempool\n" + "Returns all transaction ids in memory pool."); + + vector vtxid; + mempool.queryHashes(vtxid); + + Array a; + BOOST_FOREACH(const uint256& hash, vtxid) + a.push_back(hash.ToString()); + + return a; +} + +Value getblockhash(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getblockhash \n" + "Returns hash of block in best-block-chain at ."); + + int nHeight = params[0].get_int(); + if (nHeight < 0 || nHeight > nBestHeight) + throw runtime_error("Block number out of range."); + + CBlockIndex* pblockindex = FindBlockByHeight(nHeight); + return pblockindex->phashBlock->GetHex(); +} + +Value getblock(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getblock \n" + "Returns details of a block with given block-hash."); + + std::string strHash = params[0].get_str(); + uint256 hash(strHash); + + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(-5, "Block not found"); + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + block.ReadFromDisk(pblockindex, true); + + return blockToJSON(block, pblockindex); +} + + + + + diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index fa6fdd6d3..d2cb31f51 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -11,9 +11,6 @@ using namespace json_spirit; using namespace std; -extern double GetDifficulty(const CBlockIndex* blockindex = NULL); -extern std::string HexBits(unsigned int nBits); - Value getgenerate(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 56a49fd4d..a6b855389 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -18,13 +18,6 @@ using namespace boost; using namespace boost::assign; using namespace json_spirit; -// These are all in bitcoinrpc.cpp: -extern Object JSONRPCError(int code, const string& message); -extern int64 AmountFromValue(const Value& value); -extern Value ValueFromAmount(int64 amount); -extern std::string HelpRequiringPassphrase(); -extern void EnsureWalletIsUnlocked(); - void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out) { diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index b9b3f52f0..f74f3cb3a 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -53,6 +53,37 @@ string AccountFromValue(const Value& value) return strAccount; } +Value getinfo(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getinfo\n" + "Returns an object containing various state info."); + + CService addrProxy; + GetProxy(NET_IPV4, addrProxy); + + Object obj; + obj.push_back(Pair("version", (int)CLIENT_VERSION)); + obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION)); + obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); + obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); + obj.push_back(Pair("blocks", (int)nBestHeight)); + obj.push_back(Pair("connections", (int)vNodes.size())); + obj.push_back(Pair("proxy", (addrProxy.IsValid() ? addrProxy.ToStringIPPort() : string()))); + obj.push_back(Pair("difficulty", (double)GetDifficulty())); + obj.push_back(Pair("testnet", fTestNet)); + obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime())); + obj.push_back(Pair("keypoolsize", pwalletMain->GetKeyPoolSize())); + obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee))); + if (pwalletMain->IsCrypted()) + obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime / 1000)); + obj.push_back(Pair("errors", GetWarnings("statusbar"))); + return obj; +} + + + Value getnewaddress(const Array& params, bool fHelp) { if (fHelp || params.size() > 1)