fae3e45c139a7f1506bc20223323722533aa60a0
[novacoin.git] / src / rpcblockchain.cpp
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.
5
6 #include "main.h"
7 #include "bitcoinrpc.h"
8
9 using namespace json_spirit;
10 using namespace std;
11
12 extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, json_spirit::Object& entry);
13
14 double GetDifficulty(const CBlockIndex* blockindex)
15 {
16     // Floating point number that is a multiple of the minimum difficulty,
17     // minimum difficulty = 1.0.
18     if (blockindex == NULL)
19     {
20         if (pindexBest == NULL)
21             return 1.0;
22         else
23             blockindex = GetLastBlockIndex(pindexBest, false);
24     }
25
26     int nShift = (blockindex->nBits >> 24) & 0xff;
27
28     double dDiff =
29         (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);
30
31     while (nShift < 29)
32     {
33         dDiff *= 256.0;
34         nShift++;
35     }
36     while (nShift > 29)
37     {
38         dDiff /= 256.0;
39         nShift--;
40     }
41
42     return dDiff;
43 }
44
45
46 Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPrintTransactionDetail)
47 {
48     Object result;
49     result.push_back(Pair("hash", block.GetHash().GetHex()));
50     CMerkleTx txGen(block.vtx[0]);
51     txGen.SetMerkleBranch(&block);
52     result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain()));
53     result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
54     result.push_back(Pair("height", blockindex->nHeight));
55     result.push_back(Pair("version", block.nVersion));
56     result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
57     result.push_back(Pair("mint", ValueFromAmount(blockindex->nMint)));
58     result.push_back(Pair("time", (boost::int64_t)block.GetBlockTime()));
59     result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce));
60     result.push_back(Pair("bits", HexBits(block.nBits)));
61     result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
62     result.push_back(Pair("blocktrust", blockindex->GetBlockTrust().GetHex()));
63     result.push_back(Pair("chaintrust", blockindex->nChainTrust.GetHex()));
64     if (blockindex->pprev)
65         result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
66     if (blockindex->pnext)
67         result.push_back(Pair("nextblockhash", blockindex->pnext->GetBlockHash().GetHex()));
68
69     result.push_back(Pair("flags", strprintf("%s%s", blockindex->IsProofOfStake()? "proof-of-stake" : "proof-of-work", blockindex->GeneratedStakeModifier()? " stake-modifier": "")));
70     result.push_back(Pair("proofhash", blockindex->IsProofOfStake()? blockindex->hashProofOfStake.GetHex() : blockindex->GetBlockHash().GetHex()));
71     result.push_back(Pair("entropybit", (int)blockindex->GetStakeEntropyBit()));
72     result.push_back(Pair("modifier", strprintf("%016"PRI64x, blockindex->nStakeModifier)));
73     result.push_back(Pair("modifierchecksum", strprintf("%08x", blockindex->nStakeModifierChecksum)));
74     Array txinfo;
75     BOOST_FOREACH (const CTransaction& tx, block.vtx)
76     {
77         if (fPrintTransactionDetail)
78         {
79             Object entry;
80
81             entry.push_back(Pair("txid", tx.GetHash().GetHex()));
82             TxToJSON(tx, 0, entry);
83
84             txinfo.push_back(entry);
85         }
86         else
87             txinfo.push_back(tx.GetHash().GetHex());
88     }
89
90     result.push_back(Pair("tx", txinfo));
91
92     if ( block.IsProofOfStake() || (!fTestNet && block.GetBlockTime() < CHAINCHECKS_SWITCH_TIME) )
93         result.push_back(Pair("signature", HexStr(block.vchBlockSig.begin(), block.vchBlockSig.end())));
94
95     return result;
96 }
97
98 Value getbestblockhash(const Array& params, bool fHelp)
99 {
100     if (fHelp || params.size() != 0)
101         throw runtime_error(
102             "getbestblockhash\n"
103             "Returns the hash of the best block in the longest block chain.");
104
105     return hashBestChain.GetHex();
106 }
107
108 Value getblockcount(const Array& params, bool fHelp)
109 {
110     if (fHelp || params.size() != 0)
111         throw runtime_error(
112             "getblockcount\n"
113             "Returns the number of blocks in the longest block chain.");
114
115     return nBestHeight;
116 }
117
118
119 Value getdifficulty(const Array& params, bool fHelp)
120 {
121     if (fHelp || params.size() != 0)
122         throw runtime_error(
123             "getdifficulty\n"
124             "Returns the difficulty as a multiple of the minimum difficulty.");
125
126     Object obj;
127     obj.push_back(Pair("proof-of-work",        GetDifficulty()));
128     obj.push_back(Pair("proof-of-stake",       GetDifficulty(GetLastBlockIndex(pindexBest, true))));
129     obj.push_back(Pair("search-interval",      (int)nLastCoinStakeSearchInterval));
130     return obj;
131 }
132
133
134 Value settxfee(const Array& params, bool fHelp)
135 {
136     if (fHelp || params.size() < 1 || params.size() > 1 || AmountFromValue(params[0]) < MIN_TX_FEE)
137         throw runtime_error(
138             "settxfee <amount>\n"
139             "<amount> is a real and is rounded to the nearest 0.01");
140
141     nTransactionFee = AmountFromValue(params[0]);
142     nTransactionFee = (nTransactionFee / CENT) * CENT;  // round to cent
143
144     return true;
145 }
146
147 Value getrawmempool(const Array& params, bool fHelp)
148 {
149     if (fHelp || params.size() != 0)
150         throw runtime_error(
151             "getrawmempool\n"
152             "Returns all transaction ids in memory pool.");
153
154     vector<uint256> vtxid;
155     mempool.queryHashes(vtxid);
156
157     Array a;
158     BOOST_FOREACH(const uint256& hash, vtxid)
159         a.push_back(hash.ToString());
160
161     return a;
162 }
163
164 Value getblockhash(const Array& params, bool fHelp)
165 {
166     if (fHelp || params.size() != 1)
167         throw runtime_error(
168             "getblockhash <index>\n"
169             "Returns hash of block in best-block-chain at <index>.");
170
171     int nHeight = params[0].get_int();
172     if (nHeight < 0 || nHeight > nBestHeight)
173         throw runtime_error("Block number out of range.");
174
175     CBlockIndex* pblockindex = FindBlockByHeight(nHeight);
176     return pblockindex->phashBlock->GetHex();
177 }
178
179 Value getblock(const Array& params, bool fHelp)
180 {
181     if (fHelp || params.size() < 1 || params.size() > 2)
182         throw runtime_error(
183             "getblock <hash> [txinfo]\n"
184             "txinfo optional to print more detailed tx info\n"
185             "Returns details of a block with given block-hash.");
186
187     std::string strHash = params[0].get_str();
188     uint256 hash(strHash);
189
190     if (mapBlockIndex.count(hash) == 0)
191         throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
192
193     CBlock block;
194     CBlockIndex* pblockindex = mapBlockIndex[hash];
195     block.ReadFromDisk(pblockindex, true);
196
197     return blockToJSON(block, pblockindex, params.size() > 1 ? params[1].get_bool() : false);
198 }
199
200 Value getblockbynumber(const Array& params, bool fHelp)
201 {
202     if (fHelp || params.size() < 1 || params.size() > 2)
203         throw runtime_error(
204             "getblock <number> [txinfo]\n"
205             "txinfo optional to print more detailed tx info\n"
206             "Returns details of a block with given block-number.");
207
208     int nHeight = params[0].get_int();
209     if (nHeight < 0 || nHeight > nBestHeight)
210         throw runtime_error("Block number out of range.");
211
212     CBlock block;
213     CBlockIndex* pblockindex = mapBlockIndex[hashBestChain];
214     while (pblockindex->nHeight > nHeight)
215         pblockindex = pblockindex->pprev;
216
217     uint256 hash = *pblockindex->phashBlock;
218
219     pblockindex = mapBlockIndex[hash];
220     block.ReadFromDisk(pblockindex, true);
221
222     return blockToJSON(block, pblockindex, params.size() > 1 ? params[1].get_bool() : false);
223 }
224
225 // ppcoin: get information of sync-checkpoint
226 Value getcheckpoint(const Array& params, bool fHelp)
227 {
228     if (fHelp || params.size() != 0)
229         throw runtime_error(
230             "getcheckpoint\n"
231             "Show info of synchronized checkpoint.\n");
232
233     Object result;
234     CBlockIndex* pindexCheckpoint;
235
236     result.push_back(Pair("synccheckpoint", Checkpoints::hashSyncCheckpoint.ToString().c_str()));
237     pindexCheckpoint = mapBlockIndex[Checkpoints::hashSyncCheckpoint];
238     result.push_back(Pair("height", pindexCheckpoint->nHeight));
239     result.push_back(Pair("timestamp", DateTimeStrFormat(pindexCheckpoint->GetBlockTime()).c_str()));
240     result.push_back(Pair("policy", GetArg("-cppolicy", "strict").c_str()));
241     if (mapArgs.count("-checkpointkey"))
242         result.push_back(Pair("checkpointmaster", true));
243
244     return result;
245 }