1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
7 #include "bitcoinrpc.h"
9 using namespace json_spirit;
12 extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, json_spirit::Object& entry);
13 extern enum Checkpoints::CPMode CheckpointsMode;
15 double GetDifficulty(const CBlockIndex* blockindex)
17 // Floating point number that is a multiple of the minimum difficulty,
18 // minimum difficulty = 1.0.
19 if (blockindex == NULL)
21 if (pindexBest == NULL)
24 blockindex = GetLastBlockIndex(pindexBest, false);
27 int nShift = (blockindex->nBits >> 24) & 0xff;
30 (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);
46 double GetPoWMHashPS()
48 int nPoWInterval = 72;
49 int64 nTargetSpacingWorkMin = 30, nTargetSpacingWork = 30;
51 CBlockIndex* pindex = pindexGenesisBlock;
52 CBlockIndex* pindexPrevWork = pindexGenesisBlock;
56 if (pindex->IsProofOfWork())
58 int64 nActualSpacingWork = pindex->GetBlockTime() - pindexPrevWork->GetBlockTime();
59 nTargetSpacingWork = ((nPoWInterval - 1) * nTargetSpacingWork + nActualSpacingWork + nActualSpacingWork) / (nPoWInterval + 1);
60 nTargetSpacingWork = max(nTargetSpacingWork, nTargetSpacingWorkMin);
61 pindexPrevWork = pindex;
64 pindex = pindex->pnext;
67 return GetDifficulty() * 4294.967296 / nTargetSpacingWork;
70 double GetPoSKernelPS()
72 int nPoSInterval = 72;
73 double dStakeKernelsTriedAvg = 0;
74 int nStakesHandled = 0, nStakesTime = 0;
76 CBlockIndex* pindex = pindexBest;;
77 CBlockIndex* pindexPrevStake = NULL;
79 while (pindex && nStakesHandled < nPoSInterval)
81 if (pindex->IsProofOfStake())
83 dStakeKernelsTriedAvg += GetDifficulty(pindex) * 4294967296.0;
84 nStakesTime += pindexPrevStake ? (pindexPrevStake->nTime - pindex->nTime) : 0;
85 pindexPrevStake = pindex;
89 pindex = pindex->pprev;
92 return dStakeKernelsTriedAvg / nStakesTime;
95 Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPrintTransactionDetail)
98 result.push_back(Pair("hash", block.GetHash().GetHex()));
99 CMerkleTx txGen(block.vtx[0]);
100 txGen.SetMerkleBranch(&block);
101 result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain()));
102 result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
103 result.push_back(Pair("height", blockindex->nHeight));
104 result.push_back(Pair("version", block.nVersion));
105 result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
106 result.push_back(Pair("mint", ValueFromAmount(blockindex->nMint)));
107 result.push_back(Pair("time", (boost::int64_t)block.GetBlockTime()));
108 result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce));
109 result.push_back(Pair("bits", HexBits(block.nBits)));
110 result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
111 result.push_back(Pair("blocktrust", leftTrim(blockindex->GetBlockTrust().GetHex(), '0')));
112 result.push_back(Pair("chaintrust", leftTrim(blockindex->nChainTrust.GetHex(), '0')));
113 if (blockindex->pprev)
114 result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
115 if (blockindex->pnext)
116 result.push_back(Pair("nextblockhash", blockindex->pnext->GetBlockHash().GetHex()));
118 result.push_back(Pair("flags", strprintf("%s%s", blockindex->IsProofOfStake()? "proof-of-stake" : "proof-of-work", blockindex->GeneratedStakeModifier()? " stake-modifier": "")));
119 result.push_back(Pair("proofhash", blockindex->IsProofOfStake()? blockindex->hashProofOfStake.GetHex() : blockindex->GetBlockHash().GetHex()));
120 result.push_back(Pair("entropybit", (int)blockindex->GetStakeEntropyBit()));
121 result.push_back(Pair("modifier", strprintf("%016"PRI64x, blockindex->nStakeModifier)));
122 result.push_back(Pair("modifierchecksum", strprintf("%08x", blockindex->nStakeModifierChecksum)));
124 BOOST_FOREACH (const CTransaction& tx, block.vtx)
126 if (fPrintTransactionDetail)
130 entry.push_back(Pair("txid", tx.GetHash().GetHex()));
131 TxToJSON(tx, 0, entry);
133 txinfo.push_back(entry);
136 txinfo.push_back(tx.GetHash().GetHex());
139 result.push_back(Pair("tx", txinfo));
141 if ( block.IsProofOfStake() )
144 block.GetGenerator(key);
145 result.push_back(Pair("generator", HexStr(key.GetPubKey().Raw())));
146 result.push_back(Pair("signature", HexStr(block.vchBlockSig)));
152 Value getbestblockhash(const Array& params, bool fHelp)
154 if (fHelp || params.size() != 0)
157 "Returns the hash of the best block in the longest block chain.");
159 return hashBestChain.GetHex();
162 Value getblockcount(const Array& params, bool fHelp)
164 if (fHelp || params.size() != 0)
167 "Returns the number of blocks in the longest block chain.");
173 Value getdifficulty(const Array& params, bool fHelp)
175 if (fHelp || params.size() != 0)
178 "Returns the difficulty as a multiple of the minimum difficulty.");
181 obj.push_back(Pair("proof-of-work", GetDifficulty()));
182 obj.push_back(Pair("proof-of-stake", GetDifficulty(GetLastBlockIndex(pindexBest, true))));
183 obj.push_back(Pair("search-interval", (int)nLastCoinStakeSearchInterval));
188 Value settxfee(const Array& params, bool fHelp)
190 if (fHelp || params.size() < 1 || params.size() > 1 || AmountFromValue(params[0]) < MIN_TX_FEE)
192 "settxfee <amount>\n"
193 "<amount> is a real and is rounded to the nearest 0.01");
195 nTransactionFee = AmountFromValue(params[0]);
196 nTransactionFee = (nTransactionFee / CENT) * CENT; // round to cent
201 Value getrawmempool(const Array& params, bool fHelp)
203 if (fHelp || params.size() != 0)
206 "Returns all transaction ids in memory pool.");
208 vector<uint256> vtxid;
209 mempool.queryHashes(vtxid);
212 BOOST_FOREACH(const uint256& hash, vtxid)
213 a.push_back(hash.ToString());
218 Value getblockhash(const Array& params, bool fHelp)
220 if (fHelp || params.size() != 1)
222 "getblockhash <index>\n"
223 "Returns hash of block in best-block-chain at <index>.");
225 int nHeight = params[0].get_int();
226 if (nHeight < 0 || nHeight > nBestHeight)
227 throw runtime_error("Block number out of range.");
229 CBlockIndex* pblockindex = FindBlockByHeight(nHeight);
230 return pblockindex->phashBlock->GetHex();
233 Value getblock(const Array& params, bool fHelp)
235 if (fHelp || params.size() < 1 || params.size() > 2)
237 "getblock <hash> [txinfo]\n"
238 "txinfo optional to print more detailed tx info\n"
239 "Returns details of a block with given block-hash.");
241 std::string strHash = params[0].get_str();
242 uint256 hash(strHash);
244 if (mapBlockIndex.count(hash) == 0)
245 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
248 CBlockIndex* pblockindex = mapBlockIndex[hash];
249 block.ReadFromDisk(pblockindex, true);
251 return blockToJSON(block, pblockindex, params.size() > 1 ? params[1].get_bool() : false);
254 Value getblockbynumber(const Array& params, bool fHelp)
256 if (fHelp || params.size() < 1 || params.size() > 2)
258 "getblock <number> [txinfo]\n"
259 "txinfo optional to print more detailed tx info\n"
260 "Returns details of a block with given block-number.");
262 int nHeight = params[0].get_int();
263 if (nHeight < 0 || nHeight > nBestHeight)
264 throw runtime_error("Block number out of range.");
267 CBlockIndex* pblockindex = mapBlockIndex[hashBestChain];
268 while (pblockindex->nHeight > nHeight)
269 pblockindex = pblockindex->pprev;
271 uint256 hash = *pblockindex->phashBlock;
273 pblockindex = mapBlockIndex[hash];
274 block.ReadFromDisk(pblockindex, true);
276 return blockToJSON(block, pblockindex, params.size() > 1 ? params[1].get_bool() : false);
279 // ppcoin: get information of sync-checkpoint
280 Value getcheckpoint(const Array& params, bool fHelp)
282 if (fHelp || params.size() != 0)
285 "Show info of synchronized checkpoint.\n");
288 CBlockIndex* pindexCheckpoint;
290 result.push_back(Pair("synccheckpoint", Checkpoints::hashSyncCheckpoint.ToString().c_str()));
291 pindexCheckpoint = mapBlockIndex[Checkpoints::hashSyncCheckpoint];
292 result.push_back(Pair("height", pindexCheckpoint->nHeight));
293 result.push_back(Pair("timestamp", DateTimeStrFormat(pindexCheckpoint->GetBlockTime()).c_str()));
295 // Check that the block satisfies synchronized checkpoint
296 if (CheckpointsMode == Checkpoints::STRICT)
297 result.push_back(Pair("policy", "strict"));
299 if (CheckpointsMode == Checkpoints::ADVISORY)
300 result.push_back(Pair("policy", "advisory"));
302 if (CheckpointsMode == Checkpoints::PERMISSIVE)
303 result.push_back(Pair("policy", "permissive"));
305 if (mapArgs.count("-checkpointkey"))
306 result.push_back(Pair("checkpointmaster", true));
311 Value gettxoutsetinfo(const Array& params, bool fHelp)
313 if (fHelp || params.size() != 0)
316 "Returns statistics about the unspent transaction output set.");
321 if (pcoinsTip->GetStats(stats)) {
322 ret.push_back(Pair("bestblock", pcoinsTip->GetBestBlock()->GetBlockHash().GetHex()));
323 ret.push_back(Pair("transactions", (boost::int64_t)stats.nTransactions));
324 ret.push_back(Pair("txouts", (boost::int64_t)stats.nTransactionOutputs));
325 ret.push_back(Pair("bytes_serialized", (boost::int64_t)stats.nSerializedSize));
330 Value gettxout(const Array& params, bool fHelp)
332 if (fHelp || params.size() < 2 || params.size() > 3)
334 "gettxout <txid> <n> [includemempool=true]\n"
335 "Returns details about an unspent transaction output.");
339 std::string strHash = params[0].get_str();
340 uint256 hash(strHash);
341 int n = params[1].get_int();
342 bool fMempool = true;
343 if (params.size() > 2)
344 fMempool = params[2].get_bool();
349 CCoinsViewMemPool view(*pcoinsTip, mempool);
350 if (!view.GetCoins(hash, coins))
352 mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
354 if (!pcoinsTip->GetCoins(hash, coins))
357 if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
360 ret.push_back(Pair("bestblock", pcoinsTip->GetBestBlock()->GetBlockHash().GetHex()));
361 if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
362 ret.push_back(Pair("confirmations", 0));
364 ret.push_back(Pair("confirmations", pcoinsTip->GetBestBlock()->nHeight - coins.nHeight + 1));
365 ret.push_back(Pair("amount", (boost::int64_t)coins.vout[n].nValue));
367 o.push_back(Pair("asm", coins.vout[n].scriptPubKey.ToString()));
368 o.push_back(Pair("hex", HexStr(coins.vout[n].scriptPubKey.begin(), coins.vout[n].scriptPubKey.end())));
369 ret.push_back(Pair("scriptPubKey", o));
370 ret.push_back(Pair("version", coins.nVersion));
371 ret.push_back(Pair("coinbase", coins.fCoinBase));
372 ret.push_back(Pair("coinstake", coins.fCoinStake));
373 ret.push_back(Pair("time", (boost::int64_t)coins.nTime));
374 ret.push_back(Pair("blocktime", (boost::int64_t)coins.nBlockTime));