rpcblockchain.cpp 10 KB

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