AdminEth.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. #include <jsonrpccpp/common/exception.h>
  2. #include <libdevcore/CommonJS.h>
  3. #include <libethcore/KeyManager.h>
  4. #include <libethcore/ICAP.h>
  5. #include <libethereum/Client.h>
  6. #include <libethereum/Executive.h>
  7. #include <libethashseal/EthashClient.h>
  8. #include "AdminEth.h"
  9. #include "SessionManager.h"
  10. #include "JsonHelper.h"
  11. using namespace std;
  12. using namespace dev;
  13. using namespace dev::rpc;
  14. using namespace dev::eth;
  15. AdminEth::AdminEth(eth::Client& _eth, eth::TrivialGasPricer& _gp, eth::KeyManager& _keyManager, SessionManager& _sm):
  16. m_eth(_eth),
  17. m_gp(_gp),
  18. m_keyManager(_keyManager),
  19. m_sm(_sm)
  20. {}
  21. bool AdminEth::admin_eth_setMining(bool _on, string const& _session)
  22. {
  23. RPC_ADMIN;
  24. if (_on)
  25. m_eth.startSealing();
  26. else
  27. m_eth.stopSealing();
  28. return true;
  29. }
  30. Json::Value AdminEth::admin_eth_blockQueueStatus(string const& _session)
  31. {
  32. RPC_ADMIN;
  33. Json::Value ret;
  34. BlockQueueStatus bqs = m_eth.blockQueue().status();
  35. ret["importing"] = (int)bqs.importing;
  36. ret["verified"] = (int)bqs.verified;
  37. ret["verifying"] = (int)bqs.verifying;
  38. ret["unverified"] = (int)bqs.unverified;
  39. ret["future"] = (int)bqs.future;
  40. ret["unknown"] = (int)bqs.unknown;
  41. ret["bad"] = (int)bqs.bad;
  42. return ret;
  43. }
  44. bool AdminEth::admin_eth_setAskPrice(string const& _wei, string const& _session)
  45. {
  46. RPC_ADMIN;
  47. m_gp.setAsk(jsToU256(_wei));
  48. return true;
  49. }
  50. bool AdminEth::admin_eth_setBidPrice(string const& _wei, string const& _session)
  51. {
  52. RPC_ADMIN;
  53. m_gp.setBid(jsToU256(_wei));
  54. return true;
  55. }
  56. Json::Value AdminEth::admin_eth_findBlock(string const& _blockHash, string const& _session)
  57. {
  58. RPC_ADMIN;
  59. h256 h(_blockHash);
  60. if (m_eth.blockChain().isKnown(h))
  61. return toJson(m_eth.blockChain().info(h));
  62. switch(m_eth.blockQueue().blockStatus(h))
  63. {
  64. case QueueStatus::Ready:
  65. return "ready";
  66. case QueueStatus::Importing:
  67. return "importing";
  68. case QueueStatus::UnknownParent:
  69. return "unknown parent";
  70. case QueueStatus::Bad:
  71. return "bad";
  72. default:
  73. return "unknown";
  74. }
  75. }
  76. string AdminEth::admin_eth_blockQueueFirstUnknown(string const& _session)
  77. {
  78. RPC_ADMIN;
  79. return m_eth.blockQueue().firstUnknown().hex();
  80. }
  81. bool AdminEth::admin_eth_blockQueueRetryUnknown(string const& _session)
  82. {
  83. RPC_ADMIN;
  84. m_eth.retryUnknown();
  85. return true;
  86. }
  87. Json::Value AdminEth::admin_eth_allAccounts(string const& _session)
  88. {
  89. RPC_ADMIN;
  90. Json::Value ret;
  91. u256 total = 0;
  92. u256 pendingtotal = 0;
  93. Address beneficiary;
  94. for (auto const& address: m_keyManager.accounts())
  95. {
  96. auto pending = m_eth.balanceAt(address, PendingBlock);
  97. auto latest = m_eth.balanceAt(address, LatestBlock);
  98. Json::Value a;
  99. if (address == beneficiary)
  100. a["beneficiary"] = true;
  101. a["address"] = toJS(address);
  102. a["balance"] = toJS(latest);
  103. a["nicebalance"] = formatBalance(latest);
  104. a["pending"] = toJS(pending);
  105. a["nicepending"] = formatBalance(pending);
  106. ret["accounts"][m_keyManager.accountName(address)] = a;
  107. total += latest;
  108. pendingtotal += pending;
  109. }
  110. ret["total"] = toJS(total);
  111. ret["nicetotal"] = formatBalance(total);
  112. ret["pendingtotal"] = toJS(pendingtotal);
  113. ret["nicependingtotal"] = formatBalance(pendingtotal);
  114. return ret;
  115. }
  116. Json::Value AdminEth::admin_eth_newAccount(Json::Value const& _info, string const& _session)
  117. {
  118. RPC_ADMIN;
  119. if (!_info.isMember("name"))
  120. throw jsonrpc::JsonRpcException("No member found: name");
  121. string name = _info["name"].asString();
  122. auto s = ICAP::createDirect();
  123. h128 uuid;
  124. if (_info.isMember("password"))
  125. {
  126. string password = _info["password"].asString();
  127. string hint = _info["passwordHint"].asString();
  128. uuid = m_keyManager.import(s, name, password, hint);
  129. }
  130. else
  131. uuid = m_keyManager.import(s, name);
  132. Json::Value ret;
  133. ret["account"] = toJS(toAddress(s));
  134. ret["uuid"] = toUUID(uuid);
  135. return ret;
  136. }
  137. bool AdminEth::admin_eth_setMiningBenefactor(string const& _uuidOrAddress, string const& _session)
  138. {
  139. RPC_ADMIN;
  140. return miner_setEtherbase(_uuidOrAddress);
  141. }
  142. Json::Value AdminEth::admin_eth_inspect(string const& _address, string const& _session)
  143. {
  144. RPC_ADMIN;
  145. if (!isHash<Address>(_address))
  146. throw jsonrpc::JsonRpcException("Invalid address given.");
  147. Json::Value ret;
  148. auto h = Address(fromHex(_address));
  149. ret["storage"] = toJson(m_eth.storageAt(h, PendingBlock));
  150. ret["balance"] = toJS(m_eth.balanceAt(h, PendingBlock));
  151. ret["nonce"] = toJS(m_eth.countAt(h, PendingBlock));
  152. ret["code"] = toJS(m_eth.codeAt(h, PendingBlock));
  153. return ret;
  154. }
  155. h256 AdminEth::blockHash(string const& _blockNumberOrHash) const
  156. {
  157. if (isHash<h256>(_blockNumberOrHash))
  158. return h256(_blockNumberOrHash.substr(_blockNumberOrHash.size() - 64, 64));
  159. try
  160. {
  161. return m_eth.blockChain().numberHash(stoul(_blockNumberOrHash));
  162. }
  163. catch (...)
  164. {
  165. throw jsonrpc::JsonRpcException("Invalid argument");
  166. }
  167. }
  168. Json::Value AdminEth::admin_eth_reprocess(string const& _blockNumberOrHash, string const& _session)
  169. {
  170. RPC_ADMIN;
  171. Json::Value ret;
  172. PopulationStatistics ps;
  173. m_eth.block(blockHash(_blockNumberOrHash), &ps);
  174. ret["enact"] = ps.enact;
  175. ret["verify"] = ps.verify;
  176. ret["total"] = ps.verify + ps.enact;
  177. return ret;
  178. }
  179. Json::Value AdminEth::admin_eth_vmTrace(string const& _blockNumberOrHash, int _txIndex, string const& _session)
  180. {
  181. RPC_ADMIN;
  182. Json::Value ret;
  183. if (_txIndex < 0)
  184. throw jsonrpc::JsonRpcException("Negative index");
  185. Block block = m_eth.block(blockHash(_blockNumberOrHash));
  186. if ((unsigned)_txIndex < block.pending().size())
  187. {
  188. Transaction t = block.pending()[_txIndex];
  189. State s(State::Null);
  190. Executive e(s, block, _txIndex, m_eth.blockChain());
  191. try
  192. {
  193. StandardTrace st;
  194. st.setShowMnemonics();
  195. e.initialize(t);
  196. if (!e.execute())
  197. e.go(st.onOp());
  198. e.finalize();
  199. // Json::CharReaderBuilder builder;
  200. //builder["collectComments"] = false;
  201. //Value value;
  202. //JSONCPP_STRING errs;
  203. //parseFromStream(builder, std::cin, &value, &errs);
  204. //std::cout << "reimplement Json::Reader().parse(st.json(), ret); here\n";
  205. //throw Exception(); //this needs to be implemented better
  206. JSONCPP_STRING errs;
  207. //using namespace Json;
  208. Json::CharReaderBuilder builder;
  209. Json::CharReader* reader = builder.newCharReader();
  210. reader->parse(st.json().c_str(), (new string(st.json().c_str()+st.json().size()))->c_str(), &ret, &errs);
  211. delete reader;
  212. }
  213. catch(Exception const& _e)
  214. {
  215. cwarn << diagnostic_information(_e);
  216. }
  217. }
  218. return ret;
  219. }
  220. Json::Value AdminEth::admin_eth_getReceiptByHashAndIndex(string const& _blockNumberOrHash, int _txIndex, string const& _session)
  221. {
  222. RPC_ADMIN;
  223. if (_txIndex < 0)
  224. throw jsonrpc::JsonRpcException("Negative index");
  225. auto h = blockHash(_blockNumberOrHash);
  226. if (!m_eth.blockChain().isKnown(h))
  227. throw jsonrpc::JsonRpcException("Invalid/unknown block.");
  228. auto rs = m_eth.blockChain().receipts(h);
  229. if ((unsigned)_txIndex >= rs.receipts.size())
  230. throw jsonrpc::JsonRpcException("Index too large.");
  231. return toJson(rs.receipts[_txIndex]);
  232. }
  233. bool AdminEth::miner_start(int)
  234. {
  235. m_eth.startSealing();
  236. return true;
  237. }
  238. bool AdminEth::miner_stop()
  239. {
  240. m_eth.stopSealing();
  241. return true;
  242. }
  243. bool AdminEth::miner_setEtherbase(string const& _uuidOrAddress)
  244. {
  245. Address a;
  246. h128 uuid = fromUUID(_uuidOrAddress);
  247. if (uuid)
  248. a = m_keyManager.address(uuid);
  249. else if (isHash<Address>(_uuidOrAddress))
  250. a = Address(_uuidOrAddress);
  251. else
  252. throw jsonrpc::JsonRpcException("Invalid UUID or address");
  253. if (m_setMiningBenefactor)
  254. m_setMiningBenefactor(a);
  255. else
  256. m_eth.setAuthor(a);
  257. return true;
  258. }
  259. bool AdminEth::miner_setExtra(string const& _extraData)
  260. {
  261. m_eth.setExtraData(asBytes(_extraData));
  262. return true;
  263. }
  264. bool AdminEth::miner_setGasPrice(string const& _gasPrice)
  265. {
  266. m_gp.setAsk(jsToU256(_gasPrice));
  267. return true;
  268. }
  269. string AdminEth::miner_hashrate()
  270. {
  271. EthashClient const* client = nullptr;
  272. try
  273. {
  274. client = asEthashClient(&m_eth);
  275. }
  276. catch (...)
  277. {
  278. throw jsonrpc::JsonRpcException("Hashrate not available - blockchain does not support mining.");
  279. }
  280. return toJS(client->hashrate());
  281. }