1 // Aleth: Ethereum C++ client, tools and libraries.
2 // Copyright 2015-2019 Aleth Authors.
3 // Licensed under the GNU General Public License, Version 3.
4
5
6 #include "Eth.h"
7 #include "AccountHolder.h"
8 #include <jsonrpccpp/common/exception.h>
9 #include <libdevcore/CommonData.h>
10 #include <libethashseal/Ethash.h>
11 #include <libethcore/CommonJS.h>
12 #include <libethereum/Client.h>
13 #include <libweb3jsonrpc/JsonHelper.h>
14 #include <libwebthree/WebThree.h>
15 #include <csignal>
16
17 using namespace std;
18 using namespace jsonrpc;
19 using namespace dev;
20 using namespace eth;
21 using namespace shh;
22 using namespace dev::rpc;
23
Eth(eth::Interface & _eth,eth::AccountHolder & _ethAccounts)24 Eth::Eth(eth::Interface& _eth, eth::AccountHolder& _ethAccounts):
25 m_eth(_eth),
26 m_ethAccounts(_ethAccounts)
27 {
28 }
29
eth_protocolVersion()30 string Eth::eth_protocolVersion()
31 {
32 return toJS(eth::c_protocolVersion);
33 }
34
eth_coinbase()35 string Eth::eth_coinbase()
36 {
37 return toJS(client()->author());
38 }
39
eth_hashrate()40 string Eth::eth_hashrate()
41 {
42 try
43 {
44 return toJS(getEthash().hashrate());
45 }
46 catch (InvalidSealEngine const&)
47 {
48 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
49 }
50 catch (std::exception const&)
51 {
52 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INTERNAL_ERROR));
53 }
54 }
55
eth_mining()56 bool Eth::eth_mining()
57 {
58 try
59 {
60 return getEthash().isMining();
61 }
62 catch (InvalidSealEngine const&)
63 {
64 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
65 }
66 catch (std::exception const&)
67 {
68 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INTERNAL_ERROR));
69 }
70 }
71
eth_gasPrice()72 string Eth::eth_gasPrice()
73 {
74 return toJS(client()->gasBidPrice());
75 }
76
eth_accounts()77 Json::Value Eth::eth_accounts()
78 {
79 return toJson(m_ethAccounts.allAccounts());
80 }
81
eth_blockNumber()82 string Eth::eth_blockNumber()
83 {
84 return toJS(client()->number());
85 }
86
87
eth_getBalance(string const & _address,string const & _blockNumber)88 string Eth::eth_getBalance(string const& _address, string const& _blockNumber)
89 {
90 try
91 {
92 return toJS(client()->balanceAt(jsToAddress(_address), jsToBlockNumber(_blockNumber)));
93 }
94 catch (...)
95 {
96 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
97 }
98 }
99
eth_getStorageAt(string const & _address,string const & _position,string const & _blockNumber)100 string Eth::eth_getStorageAt(string const& _address, string const& _position, string const& _blockNumber)
101 {
102 try
103 {
104 return toJS(toCompactBigEndian(client()->stateAt(jsToAddress(_address), jsToU256(_position), jsToBlockNumber(_blockNumber)), 32));
105 }
106 catch (...)
107 {
108 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
109 }
110 }
111
eth_getStorageRoot(string const & _address,string const & _blockNumber)112 string Eth::eth_getStorageRoot(string const& _address, string const& _blockNumber)
113 {
114 try
115 {
116 return toString(client()->stateRootAt(jsToAddress(_address), jsToBlockNumber(_blockNumber)));
117 }
118 catch (...)
119 {
120 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
121 }
122 }
123
eth_pendingTransactions()124 Json::Value 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
140 return toJson(ours);
141 }
142
eth_getTransactionCount(string const & _address,string const & _blockNumber)143 string Eth::eth_getTransactionCount(string const& _address, string const& _blockNumber)
144 {
145 try
146 {
147 return toString(client()->countAt(jsToAddress(_address), jsToBlockNumber(_blockNumber)));
148 }
149 catch (...)
150 {
151 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
152 }
153 }
154
eth_getBlockTransactionCountByHash(string const & _blockHash)155 Json::Value Eth::eth_getBlockTransactionCountByHash(string const& _blockHash)
156 {
157 try
158 {
159 h256 blockHash = jsToFixed<32>(_blockHash);
160 if (!client()->isKnown(blockHash))
161 return Json::Value(Json::nullValue);
162
163 return toJS(client()->transactionCount(blockHash));
164 }
165 catch (...)
166 {
167 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
168 }
169 }
170
eth_getBlockTransactionCountByNumber(string const & _blockNumber)171 Json::Value Eth::eth_getBlockTransactionCountByNumber(string const& _blockNumber)
172 {
173 try
174 {
175 BlockNumber blockNumber = jsToBlockNumber(_blockNumber);
176 if (!client()->isKnown(blockNumber))
177 return Json::Value(Json::nullValue);
178
179 return toJS(client()->transactionCount(jsToBlockNumber(_blockNumber)));
180 }
181 catch (...)
182 {
183 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
184 }
185 }
186
eth_getUncleCountByBlockHash(string const & _blockHash)187 Json::Value Eth::eth_getUncleCountByBlockHash(string const& _blockHash)
188 {
189 try
190 {
191 h256 blockHash = jsToFixed<32>(_blockHash);
192 if (!client()->isKnown(blockHash))
193 return Json::Value(Json::nullValue);
194
195 return toJS(client()->uncleCount(blockHash));
196 }
197 catch (...)
198 {
199 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
200 }
201 }
202
eth_getUncleCountByBlockNumber(string const & _blockNumber)203 Json::Value Eth::eth_getUncleCountByBlockNumber(string const& _blockNumber)
204 {
205 try
206 {
207 BlockNumber blockNumber = jsToBlockNumber(_blockNumber);
208 if (!client()->isKnown(blockNumber))
209 return Json::Value(Json::nullValue);
210
211 return toJS(client()->uncleCount(blockNumber));
212 }
213 catch (...)
214 {
215 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
216 }
217 }
218
eth_getCode(string const & _address,string const & _blockNumber)219 string Eth::eth_getCode(string const& _address, string const& _blockNumber)
220 {
221 try
222 {
223 return toJS(client()->codeAt(jsToAddress(_address), jsToBlockNumber(_blockNumber)));
224 }
225 catch (...)
226 {
227 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
228 }
229 }
230
setTransactionDefaults(TransactionSkeleton & _t)231 void Eth::setTransactionDefaults(TransactionSkeleton& _t)
232 {
233 if (!_t.from)
234 _t.from = m_ethAccounts.defaultTransactAccount();
235 }
236
eth_sendTransaction(Json::Value const & _json)237 string Eth::eth_sendTransaction(Json::Value const& _json)
238 {
239 try
240 {
241 TransactionSkeleton t = toTransactionSkeleton(_json);
242 setTransactionDefaults(t);
243 pair<bool, Secret> ar = m_ethAccounts.authenticate(t);
244 if (!ar.first)
245 {
246 h256 txHash = client()->submitTransaction(t, ar.second);
247 return toJS(txHash);
248 }
249 else
250 {
251 m_ethAccounts.queueTransaction(t);
252 h256 emptyHash;
253 return toJS(emptyHash); // TODO: give back something more useful than an empty hash.
254 }
255 }
256 catch (Exception const&)
257 {
258 throw JsonRpcException(exceptionToErrorMessage());
259 }
260 }
261
eth_signTransaction(Json::Value const & _json)262 Json::Value Eth::eth_signTransaction(Json::Value const& _json)
263 {
264 try
265 {
266 TransactionSkeleton ts = toTransactionSkeleton(_json);
267 setTransactionDefaults(ts);
268 ts = client()->populateTransactionWithDefaults(ts);
269 pair<bool, Secret> ar = m_ethAccounts.authenticate(ts);
270 Transaction t(ts, ar.second);
271 RLPStream s;
272 t.streamRLP(s);
273 return toJson(t, s.out());
274 }
275 catch (Exception const&)
276 {
277 throw JsonRpcException(exceptionToErrorMessage());
278 }
279 }
280
eth_inspectTransaction(std::string const & _rlp)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
eth_sendRawTransaction(std::string const & _rlp)293 string Eth::eth_sendRawTransaction(std::string const& _rlp)
294 {
295 try
296 {
297 // Don't need to check the transaction signature (CheckTransaction::None) since it will
298 // be checked as a part of transaction import
299 Transaction t(jsToBytes(_rlp, OnFailed::Throw), CheckTransaction::None);
300 return toJS(client()->importTransaction(t));
301 }
302 catch (Exception const&)
303 {
304 throw JsonRpcException(exceptionToErrorMessage());
305 }
306 }
307
eth_call(Json::Value const & _json,string const & _blockNumber)308 string Eth::eth_call(Json::Value const& _json, string const& _blockNumber)
309 {
310 try
311 {
312 TransactionSkeleton t = toTransactionSkeleton(_json);
313 setTransactionDefaults(t);
314 ExecutionResult er = client()->call(t.from, t.value, t.to, t.data, t.gas, t.gasPrice, jsToBlockNumber(_blockNumber), FudgeFactor::Lenient);
315 return toJS(er.output);
316 }
317 catch (...)
318 {
319 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
320 }
321 }
322
eth_estimateGas(Json::Value const & _json)323 string Eth::eth_estimateGas(Json::Value const& _json)
324 {
325 try
326 {
327 TransactionSkeleton t = toTransactionSkeleton(_json);
328 setTransactionDefaults(t);
329 int64_t gas = static_cast<int64_t>(t.gas);
330 return toJS(client()->estimateGas(t.from, t.value, t.to, t.data, gas, t.gasPrice, PendingBlock).first);
331 }
332 catch (...)
333 {
334 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
335 }
336 }
337
eth_flush()338 bool Eth::eth_flush()
339 {
340 client()->flushTransactions();
341 return true;
342 }
343
eth_getBlockByHash(string const & _blockHash,bool _includeTransactions)344 Json::Value Eth::eth_getBlockByHash(string const& _blockHash, bool _includeTransactions)
345 {
346 try
347 {
348 h256 const h = jsToFixed<32>(_blockHash);
349 if (!client()->isKnown(h))
350 return Json::Value(Json::nullValue);
351
352 Json::Value ret;
353 auto const blockDetails = client()->blockDetails(h);
354 auto const blockHeader = client()->blockInfo(h);
355 auto const uncleHashes = client()->uncleHashes(h);
356 auto* sealEngine = client()->sealEngine();
357 if (_includeTransactions)
358 ret = toJson(
359 blockHeader, blockDetails, uncleHashes, client()->transactions(h), sealEngine);
360 else
361 ret = toJson(
362 blockHeader, blockDetails, uncleHashes, client()->transactionHashes(h), sealEngine);
363 return ret;
364 }
365 catch (...)
366 {
367 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
368 }
369 }
370
eth_getBlockByNumber(string const & _blockNumber,bool _includeTransactions)371 Json::Value Eth::eth_getBlockByNumber(string const& _blockNumber, bool _includeTransactions)
372 {
373 try
374 {
375 BlockNumber const h = jsToBlockNumber(_blockNumber);
376 if (!client()->isKnown(h))
377 return Json::Value(Json::nullValue);
378
379 Json::Value ret;
380 auto const blockDetails = client()->blockDetails(h);
381 auto const blockHeader = client()->blockInfo(h);
382 auto const uncleHashes = client()->uncleHashes(h);
383 auto* sealEngine = client()->sealEngine();
384 if (_includeTransactions)
385 ret = toJson(
386 blockHeader, blockDetails, uncleHashes, client()->transactions(h), sealEngine);
387 else
388 ret = toJson(
389 blockHeader, blockDetails, uncleHashes, client()->transactionHashes(h), sealEngine);
390 return ret;
391 }
392 catch (...)
393 {
394 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
395 }
396 }
397
eth_getTransactionByHash(string const & _transactionHash)398 Json::Value Eth::eth_getTransactionByHash(string const& _transactionHash)
399 {
400 try
401 {
402 h256 h = jsToFixed<32>(_transactionHash);
403 if (!client()->isKnownTransaction(h))
404 return Json::Value(Json::nullValue);
405
406 return toJson(client()->localisedTransaction(h));
407 }
408 catch (...)
409 {
410 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
411 }
412 }
413
eth_getTransactionByBlockHashAndIndex(string const & _blockHash,string const & _transactionIndex)414 Json::Value Eth::eth_getTransactionByBlockHashAndIndex(string const& _blockHash, string const& _transactionIndex)
415 {
416 try
417 {
418 h256 bh = jsToFixed<32>(_blockHash);
419 unsigned ti = jsToInt(_transactionIndex);
420 if (!client()->isKnownTransaction(bh, ti))
421 return Json::Value(Json::nullValue);
422
423 return toJson(client()->localisedTransaction(bh, ti));
424 }
425 catch (...)
426 {
427 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
428 }
429 }
430
eth_getTransactionByBlockNumberAndIndex(string const & _blockNumber,string const & _transactionIndex)431 Json::Value Eth::eth_getTransactionByBlockNumberAndIndex(string const& _blockNumber, string const& _transactionIndex)
432 {
433 try
434 {
435 BlockNumber bn = jsToBlockNumber(_blockNumber);
436 h256 bh = client()->hashFromNumber(bn);
437 unsigned ti = jsToInt(_transactionIndex);
438 if (!client()->isKnownTransaction(bh, ti))
439 return Json::Value(Json::nullValue);
440
441 return toJson(client()->localisedTransaction(bh, ti));
442 }
443 catch (...)
444 {
445 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
446 }
447 }
448
eth_getTransactionReceipt(string const & _transactionHash)449 Json::Value Eth::eth_getTransactionReceipt(string const& _transactionHash)
450 {
451 try
452 {
453 h256 h = jsToFixed<32>(_transactionHash);
454 if (!client()->isKnownTransaction(h))
455 return Json::Value(Json::nullValue);
456
457 return toJson(client()->localisedTransactionReceipt(h));
458 }
459 catch (...)
460 {
461 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
462 }
463 }
464
eth_getUncleByBlockHashAndIndex(string const & _blockHash,string const & _uncleIndex)465 Json::Value Eth::eth_getUncleByBlockHashAndIndex(string const& _blockHash, string const& _uncleIndex)
466 {
467 try
468 {
469 return toJson(client()->uncle(jsToFixed<32>(_blockHash), jsToInt(_uncleIndex)), client()->sealEngine());
470 }
471 catch (...)
472 {
473 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
474 }
475 }
476
eth_getUncleByBlockNumberAndIndex(string const & _blockNumber,string const & _uncleIndex)477 Json::Value Eth::eth_getUncleByBlockNumberAndIndex(string const& _blockNumber, string const& _uncleIndex)
478 {
479 try
480 {
481 return toJson(client()->uncle(jsToBlockNumber(_blockNumber), jsToInt(_uncleIndex)), client()->sealEngine());
482 }
483 catch (...)
484 {
485 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
486 }
487 }
488
eth_newFilter(Json::Value const & _json)489 string Eth::eth_newFilter(Json::Value const& _json)
490 {
491 try
492 {
493 return toJS(client()->installWatch(toLogFilter(_json, *client())));
494 }
495 catch (...)
496 {
497 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
498 }
499 }
500
eth_newFilterEx(Json::Value const & _json)501 string Eth::eth_newFilterEx(Json::Value const& _json)
502 {
503 try
504 {
505 return toJS(client()->installWatch(toLogFilter(_json)));
506 }
507 catch (...)
508 {
509 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
510 }
511 }
512
eth_newBlockFilter()513 string Eth::eth_newBlockFilter()
514 {
515 h256 filter = dev::eth::ChainChangedFilter;
516 return toJS(client()->installWatch(filter));
517 }
518
eth_newPendingTransactionFilter()519 string Eth::eth_newPendingTransactionFilter()
520 {
521 h256 filter = dev::eth::PendingChangedFilter;
522 return toJS(client()->installWatch(filter));
523 }
524
eth_uninstallFilter(string const & _filterId)525 bool Eth::eth_uninstallFilter(string const& _filterId)
526 {
527 try
528 {
529 return client()->uninstallWatch(jsToInt(_filterId));
530 }
531 catch (...)
532 {
533 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
534 }
535 }
536
eth_getFilterChanges(string const & _filterId)537 Json::Value Eth::eth_getFilterChanges(string const& _filterId)
538 {
539 try
540 {
541 int id = jsToInt(_filterId);
542 auto entries = client()->checkWatch(id);
543 // if (entries.size())
544 // cnote << "FIRING WATCH" << id << entries.size();
545 return toJson(entries);
546 }
547 catch (...)
548 {
549 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
550 }
551 }
552
eth_getFilterChangesEx(string const & _filterId)553 Json::Value Eth::eth_getFilterChangesEx(string const& _filterId)
554 {
555 try
556 {
557 int id = jsToInt(_filterId);
558 auto entries = client()->checkWatch(id);
559 // if (entries.size())
560 // cnote << "FIRING WATCH" << id << entries.size();
561 return toJsonByBlock(entries);
562 }
563 catch (...)
564 {
565 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
566 }
567 }
568
eth_getFilterLogs(string const & _filterId)569 Json::Value Eth::eth_getFilterLogs(string const& _filterId)
570 {
571 try
572 {
573 return toJson(client()->logs(jsToInt(_filterId)));
574 }
575 catch (...)
576 {
577 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
578 }
579 }
580
eth_getFilterLogsEx(string const & _filterId)581 Json::Value Eth::eth_getFilterLogsEx(string const& _filterId)
582 {
583 try
584 {
585 return toJsonByBlock(client()->logs(jsToInt(_filterId)));
586 }
587 catch (...)
588 {
589 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
590 }
591 }
592
eth_getLogs(Json::Value const & _json)593 Json::Value Eth::eth_getLogs(Json::Value const& _json)
594 {
595 try
596 {
597 return toJson(client()->logs(toLogFilter(_json, *client())));
598 }
599 catch (...)
600 {
601 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
602 }
603 }
604
eth_getLogsEx(Json::Value const & _json)605 Json::Value Eth::eth_getLogsEx(Json::Value const& _json)
606 {
607 try
608 {
609 return toJsonByBlock(client()->logs(toLogFilter(_json)));
610 }
611 catch (...)
612 {
613 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
614 }
615 }
616
eth_getWork()617 Json::Value Eth::eth_getWork()
618 {
619 try
620 {
621 Json::Value ret(Json::arrayValue);
622 auto r = client()->getWork();
623 ret.append(toJS(get<0>(r)));
624 ret.append(toJS(get<1>(r)));
625 ret.append(toJS(get<2>(r)));
626 return ret;
627 }
628 catch (...)
629 {
630 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
631 }
632 }
633
eth_syncing()634 Json::Value Eth::eth_syncing()
635 {
636 dev::eth::SyncStatus sync = client()->syncStatus();
637 if (sync.state == SyncState::Idle || !sync.majorSyncing)
638 return Json::Value(false);
639
640 Json::Value info(Json::objectValue);
641 info["startingBlock"] = sync.startBlockNumber;
642 info["highestBlock"] = sync.highestBlockNumber;
643 info["currentBlock"] = sync.currentBlockNumber;
644 return info;
645 }
646
eth_chainId()647 string Eth::eth_chainId()
648 {
649 return toJS(client()->chainId());
650 }
651
eth_submitWork(string const & _nonce,string const &,string const & _mixHash)652 bool Eth::eth_submitWork(string const& _nonce, string const&, string const& _mixHash)
653 {
654 try
655 {
656 return getEthash().submitEthashWork(
657 jsToFixed<32>(_mixHash), jsToFixed<Nonce::size>(_nonce));
658 }
659 catch (...)
660 {
661 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
662 }
663 }
664
eth_submitHashrate(string const & _hashes,string const & _id)665 bool Eth::eth_submitHashrate(string const& _hashes, string const& _id)
666 {
667 try
668 {
669 getEthash().submitExternalHashrate(jsToInt<32>(_hashes), jsToFixed<32>(_id));
670 return true;
671 }
672 catch (...)
673 {
674 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
675 }
676 }
677
eth_register(string const & _address)678 string Eth::eth_register(string const& _address)
679 {
680 try
681 {
682 return toJS(m_ethAccounts.addProxyAccount(jsToAddress(_address)));
683 }
684 catch (...)
685 {
686 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
687 }
688 }
689
eth_unregister(string const & _accountId)690 bool Eth::eth_unregister(string const& _accountId)
691 {
692 try
693 {
694 return m_ethAccounts.removeProxyAccount(jsToInt(_accountId));
695 }
696 catch (...)
697 {
698 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
699 }
700 }
701
eth_fetchQueuedTransactions(string const & _accountId)702 Json::Value Eth::eth_fetchQueuedTransactions(string const& _accountId)
703 {
704 try
705 {
706 auto id = jsToInt(_accountId);
707 Json::Value ret(Json::arrayValue);
708 // TODO: throw an error on no account with given id
709 for (TransactionSkeleton const& t: m_ethAccounts.queuedTransactions(id))
710 ret.append(toJson(t));
711 m_ethAccounts.clearQueue(id);
712 return ret;
713 }
714 catch (...)
715 {
716 BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
717 }
718 }
719
exceptionToErrorMessage()720 string dev::rpc::exceptionToErrorMessage()
721 {
722 string ret;
723 try
724 {
725 throw;
726 }
727 // Transaction submission exceptions
728 catch (ZeroSignatureTransaction const&)
729 {
730 ret = "Zero signature transaction.";
731 }
732 catch (GasPriceTooLow const&)
733 {
734 ret = "Pending transaction with same nonce but higher gas price exists.";
735 }
736 catch (OutOfGasIntrinsic const&)
737 {
738 ret = "Transaction gas amount is less than the intrinsic gas amount for this transaction type.";
739 }
740 catch (BlockGasLimitReached const& _ex)
741 {
742 string errorString = "Block gas limit reached! ";
743 cwarn << errorString + _ex.what();
744 ret = errorString;
745 }
746 catch (InvalidNonce const&)
747 {
748 ret = "Invalid transaction nonce.";
749 }
750 catch (PendingTransactionAlreadyExists const&)
751 {
752 ret = "Same transaction already exists in the pending transaction queue.";
753 }
754 catch (TransactionAlreadyInChain const&)
755 {
756 ret = "Transaction is already in the blockchain.";
757 }
758 catch (NotEnoughCash const&)
759 {
760 ret = "Account balance is too low (balance < value + gas * gas price).";
761 }
762 catch (InvalidSignature const&)
763 {
764 ret = "Invalid transaction signature.";
765 }
766 // Acount holder exceptions
767 catch (AccountLocked const&)
768 {
769 ret = "Account is locked.";
770 }
771 catch (UnknownAccount const&)
772 {
773 ret = "Unknown account.";
774 }
775 catch (TransactionRefused const&)
776 {
777 ret = "Transaction rejected by user.";
778 }
779 catch (...)
780 {
781 ret = "Invalid RPC parameters.";
782 }
783 return ret;
784 }
785
getEthash()786 Ethash& Eth::getEthash()
787 {
788 return asEthash(*client()->sealEngine());
789 }
790