Eth.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. /*
  2. This file is part of cpp-ethereum.
  3. cpp-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. cpp-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /** @file Eth.cpp
  15. * @authors:
  16. * Gav Wood <i@gavwood.com>
  17. * Marek Kotewicz <marek@ethdev.com>
  18. * @date 2014
  19. */
  20. #include <csignal>
  21. #include <jsonrpccpp/common/exception.h>
  22. #include <libdevcore/CommonData.h>
  23. #include <libevmcore/Instruction.h>
  24. #include <libethereum/Client.h>
  25. #include <libethashseal/EthashClient.h>
  26. #include <libwebthree/WebThree.h>
  27. #include <libethcore/CommonJS.h>
  28. #include <libweb3jsonrpc/JsonHelper.h>
  29. #include "Eth.h"
  30. #include "AccountHolder.h"
  31. #include "JsonHelper.h"
  32. using namespace std;
  33. using namespace jsonrpc;
  34. using namespace dev;
  35. using namespace eth;
  36. using namespace shh;
  37. using namespace dev::rpc;
  38. #if ETH_DEBUG
  39. const unsigned dev::SensibleHttpThreads = 1;
  40. #else
  41. const unsigned dev::SensibleHttpThreads = 4;
  42. #endif
  43. const unsigned dev::SensibleHttpPort = 8545;
  44. Eth::Eth(eth::Interface& _eth, eth::AccountHolder& _ethAccounts):
  45. m_eth(_eth),
  46. m_ethAccounts(_ethAccounts)
  47. {
  48. }
  49. string Eth::eth_protocolVersion()
  50. {
  51. return toJS(eth::c_protocolVersion);
  52. }
  53. string Eth::eth_coinbase()
  54. {
  55. return toJS(client()->author());
  56. }
  57. string Eth::eth_hashrate()
  58. {
  59. try
  60. {
  61. return toJS(asEthashClient(client())->hashrate());
  62. }
  63. catch (InvalidSealEngine&)
  64. {
  65. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  66. }
  67. }
  68. bool Eth::eth_mining()
  69. {
  70. try
  71. {
  72. return asEthashClient(client())->isMining();
  73. }
  74. catch (InvalidSealEngine&)
  75. {
  76. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  77. }
  78. }
  79. string Eth::eth_gasPrice()
  80. {
  81. return toJS(client()->gasBidPrice());
  82. }
  83. Json::Value Eth::eth_accounts()
  84. {
  85. return toJson(m_ethAccounts.allAccounts());
  86. }
  87. string Eth::eth_blockNumber()
  88. {
  89. return toJS(client()->number());
  90. }
  91. string Eth::eth_getBalance(string const& _address, string const& _blockNumber)
  92. {
  93. try
  94. {
  95. return toJS(client()->balanceAt(jsToAddress(_address), jsToBlockNumber(_blockNumber)));
  96. }
  97. catch (...)
  98. {
  99. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  100. }
  101. }
  102. string Eth::eth_getStorageAt(string const& _address, string const& _position, string const& _blockNumber)
  103. {
  104. try
  105. {
  106. return toJS(toCompactBigEndian(client()->stateAt(jsToAddress(_address), jsToU256(_position), jsToBlockNumber(_blockNumber)), 32));
  107. }
  108. catch (...)
  109. {
  110. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  111. }
  112. }
  113. string Eth::eth_getStorageRoot(string const& _address, string const& _blockNumber)
  114. {
  115. try
  116. {
  117. return toString(client()->stateRootAt(jsToAddress(_address), jsToBlockNumber(_blockNumber)));
  118. }
  119. catch (...)
  120. {
  121. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  122. }
  123. }
  124. string Eth::eth_pendingTransactions()
  125. {
  126. //Return list of transaction that being sent by local accounts
  127. Transactions ours;
  128. for (Transaction const& pending:client()->pending())
  129. {
  130. for (Address const& account:m_ethAccounts.allAccounts())
  131. {
  132. if (pending.sender() == account)
  133. {
  134. ours.push_back(pending);
  135. break;
  136. }
  137. }
  138. }
  139. return toJS(ours);
  140. }
  141. string Eth::eth_getTransactionCount(string const& _address, string const& _blockNumber)
  142. {
  143. try
  144. {
  145. return toJS(client()->countAt(jsToAddress(_address), jsToBlockNumber(_blockNumber)));
  146. }
  147. catch (...)
  148. {
  149. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  150. }
  151. }
  152. Json::Value Eth::eth_getBlockTransactionCountByHash(string const& _blockHash)
  153. {
  154. try
  155. {
  156. h256 blockHash = jsToFixed<32>(_blockHash);
  157. if (!client()->isKnown(blockHash))
  158. return Json::Value(Json::nullValue);
  159. return toJS(client()->transactionCount(blockHash));
  160. }
  161. catch (...)
  162. {
  163. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  164. }
  165. }
  166. Json::Value Eth::eth_getBlockTransactionCountByNumber(string const& _blockNumber)
  167. {
  168. try
  169. {
  170. BlockNumber blockNumber = jsToBlockNumber(_blockNumber);
  171. if (!client()->isKnown(blockNumber))
  172. return Json::Value(Json::nullValue);
  173. return toJS(client()->transactionCount(jsToBlockNumber(_blockNumber)));
  174. }
  175. catch (...)
  176. {
  177. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  178. }
  179. }
  180. Json::Value Eth::eth_getUncleCountByBlockHash(string const& _blockHash)
  181. {
  182. try
  183. {
  184. h256 blockHash = jsToFixed<32>(_blockHash);
  185. if (!client()->isKnown(blockHash))
  186. return Json::Value(Json::nullValue);
  187. return toJS(client()->uncleCount(blockHash));
  188. }
  189. catch (...)
  190. {
  191. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  192. }
  193. }
  194. Json::Value Eth::eth_getUncleCountByBlockNumber(string const& _blockNumber)
  195. {
  196. try
  197. {
  198. BlockNumber blockNumber = jsToBlockNumber(_blockNumber);
  199. if (!client()->isKnown(blockNumber))
  200. return Json::Value(Json::nullValue);
  201. return toJS(client()->uncleCount(blockNumber));
  202. }
  203. catch (...)
  204. {
  205. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  206. }
  207. }
  208. string Eth::eth_getCode(string const& _address, string const& _blockNumber)
  209. {
  210. try
  211. {
  212. return toJS(client()->codeAt(jsToAddress(_address), jsToBlockNumber(_blockNumber)));
  213. }
  214. catch (...)
  215. {
  216. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  217. }
  218. }
  219. void Eth::setTransactionDefaults(TransactionSkeleton& _t)
  220. {
  221. if (!_t.from)
  222. _t.from = m_ethAccounts.defaultTransactAccount();
  223. }
  224. string Eth::eth_sendTransaction(Json::Value const& _json)
  225. {
  226. try
  227. {
  228. TransactionSkeleton t = toTransactionSkeleton(_json);
  229. setTransactionDefaults(t);
  230. TransactionNotification n = m_ethAccounts.authenticate(t);
  231. switch (n.r)
  232. {
  233. case TransactionRepercussion::Success:
  234. return toJS(n.hash);
  235. case TransactionRepercussion::ProxySuccess:
  236. return toJS(n.hash);// TODO: give back something more useful than an empty hash.
  237. case TransactionRepercussion::UnknownAccount:
  238. BOOST_THROW_EXCEPTION(JsonRpcException("Account unknown."));
  239. case TransactionRepercussion::Locked:
  240. BOOST_THROW_EXCEPTION(JsonRpcException("Account is locked."));
  241. case TransactionRepercussion::Refused:
  242. BOOST_THROW_EXCEPTION(JsonRpcException("Transaction rejected by user."));
  243. case TransactionRepercussion::Unknown:
  244. BOOST_THROW_EXCEPTION(JsonRpcException("Unknown reason."));
  245. }
  246. }
  247. catch (JsonRpcException&)
  248. {
  249. throw;
  250. }
  251. catch (...)
  252. {
  253. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  254. }
  255. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  256. return string();
  257. }
  258. string Eth::eth_signTransaction(Json::Value const& _json)
  259. {
  260. try
  261. {
  262. TransactionSkeleton t = toTransactionSkeleton(_json);
  263. setTransactionDefaults(t);
  264. TransactionNotification n = m_ethAccounts.authenticate(t);
  265. switch (n.r)
  266. {
  267. case TransactionRepercussion::Success:
  268. return toJS(n.hash);
  269. case TransactionRepercussion::ProxySuccess:
  270. return toJS(n.hash);// TODO: give back something more useful than an empty hash.
  271. default:
  272. // TODO: provide more useful information in the exception.
  273. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  274. }
  275. }
  276. catch (...)
  277. {
  278. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  279. }
  280. }
  281. Json::Value Eth::eth_inspectTransaction(std::string const& _rlp)
  282. {
  283. try
  284. {
  285. return toJson(Transaction(jsToBytes(_rlp, OnFailed::Throw), CheckTransaction::Everything));
  286. }
  287. catch (...)
  288. {
  289. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  290. }
  291. }
  292. string Eth::eth_sendRawTransaction(std::string const& _rlp)
  293. {
  294. try
  295. {
  296. if (client()->injectTransaction(jsToBytes(_rlp, OnFailed::Throw)) == ImportResult::Success)
  297. {
  298. Transaction tx(jsToBytes(_rlp, OnFailed::Throw), CheckTransaction::None);
  299. return toJS(tx.sha3());
  300. }
  301. else
  302. return toJS(h256());
  303. }
  304. catch (...)
  305. {
  306. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  307. }
  308. }
  309. string Eth::eth_call(Json::Value const& _json, string const& _blockNumber)
  310. {
  311. try
  312. {
  313. TransactionSkeleton t = toTransactionSkeleton(_json);
  314. setTransactionDefaults(t);
  315. ExecutionResult er = client()->call(t.from, t.value, t.to, t.data, t.gas, t.gasPrice, jsToBlockNumber(_blockNumber), FudgeFactor::Lenient);
  316. return toJS(er.output);
  317. }
  318. catch (...)
  319. {
  320. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  321. }
  322. }
  323. string Eth::eth_estimateGas(Json::Value const& _json)
  324. {
  325. try
  326. {
  327. TransactionSkeleton t = toTransactionSkeleton(_json);
  328. setTransactionDefaults(t);
  329. return toJS(client()->estimateGas(t.from, t.value, t.to, t.data, t.gas, t.gasPrice, PendingBlock).first);
  330. }
  331. catch (...)
  332. {
  333. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  334. }
  335. }
  336. bool Eth::eth_flush()
  337. {
  338. client()->flushTransactions();
  339. return true;
  340. }
  341. Json::Value Eth::eth_getBlockByHash(string const& _blockHash, bool _includeTransactions)
  342. {
  343. try
  344. {
  345. h256 h = jsToFixed<32>(_blockHash);
  346. if (!client()->isKnown(h))
  347. return Json::Value(Json::nullValue);
  348. if (_includeTransactions)
  349. return toJson(client()->blockInfo(h), client()->blockDetails(h), client()->uncleHashes(h), client()->transactions(h), client()->sealEngine());
  350. else
  351. return toJson(client()->blockInfo(h), client()->blockDetails(h), client()->uncleHashes(h), client()->transactionHashes(h), client()->sealEngine());
  352. }
  353. catch (...)
  354. {
  355. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  356. }
  357. }
  358. Json::Value Eth::eth_getBlockByNumber(string const& _blockNumber, bool _includeTransactions)
  359. {
  360. try
  361. {
  362. BlockNumber h = jsToBlockNumber(_blockNumber);
  363. if (!client()->isKnown(h))
  364. return Json::Value(Json::nullValue);
  365. if (_includeTransactions)
  366. return toJson(client()->blockInfo(h), client()->blockDetails(h), client()->uncleHashes(h), client()->transactions(h), client()->sealEngine());
  367. else
  368. return toJson(client()->blockInfo(h), client()->blockDetails(h), client()->uncleHashes(h), client()->transactionHashes(h), client()->sealEngine());
  369. }
  370. catch (...)
  371. {
  372. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  373. }
  374. }
  375. Json::Value Eth::eth_getTransactionByHash(string const& _transactionHash)
  376. {
  377. try
  378. {
  379. h256 h = jsToFixed<32>(_transactionHash);
  380. if (!client()->isKnownTransaction(h))
  381. return Json::Value(Json::nullValue);
  382. return toJson(client()->localisedTransaction(h));
  383. }
  384. catch (...)
  385. {
  386. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  387. }
  388. }
  389. Json::Value Eth::eth_getTransactionByBlockHashAndIndex(string const& _blockHash, string const& _transactionIndex)
  390. {
  391. try
  392. {
  393. h256 bh = jsToFixed<32>(_blockHash);
  394. unsigned ti = jsToInt(_transactionIndex);
  395. if (!client()->isKnownTransaction(bh, ti))
  396. return Json::Value(Json::nullValue);
  397. return toJson(client()->localisedTransaction(bh, ti));
  398. }
  399. catch (...)
  400. {
  401. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  402. }
  403. }
  404. Json::Value Eth::eth_getTransactionByBlockNumberAndIndex(string const& _blockNumber, string const& _transactionIndex)
  405. {
  406. try
  407. {
  408. BlockNumber bn = jsToBlockNumber(_blockNumber);
  409. h256 bh = client()->hashFromNumber(bn);
  410. unsigned ti = jsToInt(_transactionIndex);
  411. if (!client()->isKnownTransaction(bh, ti))
  412. return Json::Value(Json::nullValue);
  413. return toJson(client()->localisedTransaction(bh, ti));
  414. }
  415. catch (...)
  416. {
  417. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  418. }
  419. }
  420. Json::Value Eth::eth_getTransactionReceipt(string const& _transactionHash)
  421. {
  422. try
  423. {
  424. h256 h = jsToFixed<32>(_transactionHash);
  425. if (!client()->isKnownTransaction(h))
  426. return Json::Value(Json::nullValue);
  427. return toJson(client()->localisedTransactionReceipt(h));
  428. }
  429. catch (...)
  430. {
  431. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  432. }
  433. }
  434. Json::Value Eth::eth_getUncleByBlockHashAndIndex(string const& _blockHash, string const& _uncleIndex)
  435. {
  436. try
  437. {
  438. return toJson(client()->uncle(jsToFixed<32>(_blockHash), jsToInt(_uncleIndex)), client()->sealEngine());
  439. }
  440. catch (...)
  441. {
  442. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  443. }
  444. }
  445. Json::Value Eth::eth_getUncleByBlockNumberAndIndex(string const& _blockNumber, string const& _uncleIndex)
  446. {
  447. try
  448. {
  449. return toJson(client()->uncle(jsToBlockNumber(_blockNumber), jsToInt(_uncleIndex)), client()->sealEngine());
  450. }
  451. catch (...)
  452. {
  453. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  454. }
  455. }
  456. string Eth::eth_newFilter(Json::Value const& _json)
  457. {
  458. try
  459. {
  460. return toJS(client()->installWatch(toLogFilter(_json, *client())));
  461. }
  462. catch (...)
  463. {
  464. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  465. }
  466. }
  467. string Eth::eth_newFilterEx(Json::Value const& _json)
  468. {
  469. try
  470. {
  471. return toJS(client()->installWatch(toLogFilter(_json)));
  472. }
  473. catch (...)
  474. {
  475. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  476. }
  477. }
  478. string Eth::eth_newBlockFilter()
  479. {
  480. h256 filter = dev::eth::ChainChangedFilter;
  481. return toJS(client()->installWatch(filter));
  482. }
  483. string Eth::eth_newPendingTransactionFilter()
  484. {
  485. h256 filter = dev::eth::PendingChangedFilter;
  486. return toJS(client()->installWatch(filter));
  487. }
  488. bool Eth::eth_uninstallFilter(string const& _filterId)
  489. {
  490. try
  491. {
  492. return client()->uninstallWatch(jsToInt(_filterId));
  493. }
  494. catch (...)
  495. {
  496. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  497. }
  498. }
  499. Json::Value Eth::eth_getFilterChanges(string const& _filterId)
  500. {
  501. try
  502. {
  503. int id = jsToInt(_filterId);
  504. auto entries = client()->checkWatch(id);
  505. // if (entries.size())
  506. // cnote << "FIRING WATCH" << id << entries.size();
  507. return toJson(entries);
  508. }
  509. catch (...)
  510. {
  511. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  512. }
  513. }
  514. Json::Value Eth::eth_getFilterChangesEx(string const& _filterId)
  515. {
  516. try
  517. {
  518. int id = jsToInt(_filterId);
  519. auto entries = client()->checkWatch(id);
  520. // if (entries.size())
  521. // cnote << "FIRING WATCH" << id << entries.size();
  522. return toJsonByBlock(entries);
  523. }
  524. catch (...)
  525. {
  526. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  527. }
  528. }
  529. Json::Value Eth::eth_getFilterLogs(string const& _filterId)
  530. {
  531. try
  532. {
  533. return toJson(client()->logs(jsToInt(_filterId)));
  534. }
  535. catch (...)
  536. {
  537. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  538. }
  539. }
  540. Json::Value Eth::eth_getFilterLogsEx(string const& _filterId)
  541. {
  542. try
  543. {
  544. return toJsonByBlock(client()->logs(jsToInt(_filterId)));
  545. }
  546. catch (...)
  547. {
  548. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  549. }
  550. }
  551. Json::Value Eth::eth_getLogs(Json::Value const& _json)
  552. {
  553. try
  554. {
  555. return toJson(client()->logs(toLogFilter(_json, *client())));
  556. }
  557. catch (...)
  558. {
  559. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  560. }
  561. }
  562. Json::Value Eth::eth_getLogsEx(Json::Value const& _json)
  563. {
  564. try
  565. {
  566. return toJsonByBlock(client()->logs(toLogFilter(_json)));
  567. }
  568. catch (...)
  569. {
  570. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  571. }
  572. }
  573. Json::Value Eth::eth_getWork()
  574. {
  575. try
  576. {
  577. Json::Value ret(Json::arrayValue);
  578. auto r = asEthashClient(client())->getEthashWork();
  579. ret.append(toJS(get<0>(r)));
  580. ret.append(toJS(get<1>(r)));
  581. ret.append(toJS(get<2>(r)));
  582. return ret;
  583. }
  584. catch (...)
  585. {
  586. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  587. }
  588. }
  589. Json::Value Eth::eth_syncing()
  590. {
  591. dev::eth::SyncStatus sync = client()->syncStatus();
  592. if (sync.state == SyncState::Idle || !sync.majorSyncing)
  593. return Json::Value(false);
  594. Json::Value info(Json::objectValue);
  595. info["startingBlock"] = sync.startBlockNumber;
  596. info["highestBlock"] = sync.highestBlockNumber;
  597. info["currentBlock"] = sync.currentBlockNumber;
  598. return info;
  599. }
  600. bool Eth::eth_submitWork(string const& _nonce, string const&, string const& _mixHash)
  601. {
  602. try
  603. {
  604. return asEthashClient(client())->submitEthashWork(jsToFixed<32>(_mixHash), jsToFixed<Nonce::size>(_nonce));
  605. }
  606. catch (...)
  607. {
  608. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  609. }
  610. }
  611. bool Eth::eth_submitHashrate(string const& _hashes, string const& _id)
  612. {
  613. try
  614. {
  615. asEthashClient(client())->submitExternalHashrate(jsToInt<32>(_hashes), jsToFixed<32>(_id));
  616. return true;
  617. }
  618. catch (...)
  619. {
  620. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  621. }
  622. }
  623. string Eth::eth_register(string const& _address)
  624. {
  625. try
  626. {
  627. return toJS(m_ethAccounts.addProxyAccount(jsToAddress(_address)));
  628. }
  629. catch (...)
  630. {
  631. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  632. }
  633. }
  634. bool Eth::eth_unregister(string const& _accountId)
  635. {
  636. try
  637. {
  638. return m_ethAccounts.removeProxyAccount(jsToInt(_accountId));
  639. }
  640. catch (...)
  641. {
  642. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  643. }
  644. }
  645. Json::Value Eth::eth_fetchQueuedTransactions(string const& _accountId)
  646. {
  647. try
  648. {
  649. auto id = jsToInt(_accountId);
  650. Json::Value ret(Json::arrayValue);
  651. // TODO: throw an error on no account with given id
  652. for (TransactionSkeleton const& t: m_ethAccounts.queuedTransactions(id))
  653. ret.append(toJson(t));
  654. m_ethAccounts.clearQueue(id);
  655. return ret;
  656. }
  657. catch (...)
  658. {
  659. BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
  660. }
  661. }