Debug.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #include <jsonrpccpp/common/exception.h>
  2. #include <libdevcore/CommonIO.h>
  3. #include <libdevcore/CommonJS.h>
  4. #include <libethcore/CommonJS.h>
  5. #include <libethereum/Client.h>
  6. #include <libethereum/Executive.h>
  7. #include "Debug.h"
  8. #include "JsonHelper.h"
  9. using namespace std;
  10. using namespace dev;
  11. using namespace dev::rpc;
  12. using namespace dev::eth;
  13. Debug::Debug(eth::Client const& _eth):
  14. m_eth(_eth)
  15. {}
  16. StandardTrace::DebugOptions debugOptions(Json::Value const& _json)
  17. {
  18. StandardTrace::DebugOptions op;
  19. if (!_json.isObject() || _json.empty())
  20. return op;
  21. if (!_json["disableStorage"].empty())
  22. op.disableStorage = _json["disableStorage"].asBool();
  23. if (!_json["disableMemory"].empty())
  24. op.disableMemory = _json["disableMemory"].asBool();
  25. if (!_json["disableStack"].empty())
  26. op.disableStack =_json["disableStack"].asBool();
  27. if (!_json["fullStorage"].empty())
  28. op.fullStorage = _json["fullStorage"].asBool();
  29. return op;
  30. }
  31. h256 Debug::blockHash(string const& _blockNumberOrHash) const
  32. {
  33. if (isHash<h256>(_blockNumberOrHash))
  34. return h256(_blockNumberOrHash.substr(_blockNumberOrHash.size() - 64, 64));
  35. try
  36. {
  37. return m_eth.blockChain().numberHash(stoul(_blockNumberOrHash));
  38. }
  39. catch (...)
  40. {
  41. throw jsonrpc::JsonRpcException("Invalid argument");
  42. }
  43. }
  44. Json::Value Debug::traceTransaction(Executive& _e, Transaction const& _t, Json::Value const& _json)
  45. {
  46. Json::Value trace;
  47. StandardTrace st;
  48. st.setShowMnemonics();
  49. st.setOptions(debugOptions(_json));
  50. _e.initialize(_t);
  51. if (!_e.execute())
  52. _e.go(st.onOp());
  53. _e.finalize();
  54. //builder["collectComments"] = false;
  55. //Value value;
  56. JSONCPP_STRING errs;
  57. //using namespace Json;
  58. Json::CharReaderBuilder builder;
  59. Json::CharReader* reader = builder.newCharReader();
  60. reader->parse(st.json().c_str(), (new string(st.json().c_str()+st.json().size()))->c_str(), &trace, &errs);
  61. delete reader;
  62. // Json::parseFromStream(builder, , &trace, &errs);
  63. //Json::Reader().parse(st.json(), trace);
  64. return trace;
  65. }
  66. Json::Value Debug::traceBlock(Block const& _block, Json::Value const& _json)
  67. {
  68. Json::Value traces(Json::arrayValue);
  69. for (unsigned k = 0; k < _block.pending().size(); k++)
  70. {
  71. Transaction t = _block.pending()[k];
  72. State s(State::Null);
  73. eth::ExecutionResult er;
  74. Executive e(s, _block, k, m_eth.blockChain());
  75. e.setResultRecipient(er);
  76. traces.append(traceTransaction(e, t, _json));
  77. }
  78. return traces;
  79. }
  80. Json::Value Debug::debug_traceTransaction(string const& _txHash, Json::Value const& _json)
  81. {
  82. Json::Value ret;
  83. try
  84. {
  85. LocalisedTransaction t = m_eth.localisedTransaction(h256(_txHash));
  86. Block block = m_eth.block(t.blockHash());
  87. State s(State::Null);
  88. eth::ExecutionResult er;
  89. Executive e(s, block, t.transactionIndex(), m_eth.blockChain());
  90. e.setResultRecipient(er);
  91. Json::Value trace = traceTransaction(e, t, _json);
  92. ret["gas"] = toHex(t.gas(), HexPrefix::Add);
  93. ret["return"] = toHex(er.output, 2, HexPrefix::Add);
  94. ret["structLogs"] = trace;
  95. }
  96. catch(Exception const& _e)
  97. {
  98. cwarn << diagnostic_information(_e);
  99. }
  100. return ret;
  101. }
  102. Json::Value Debug::debug_traceBlock(string const& _blockRLP, Json::Value const& _json)
  103. {
  104. bytes bytes = fromHex(_blockRLP);
  105. BlockHeader blockHeader(bytes);
  106. return debug_traceBlockByHash(blockHeader.hash().hex(), _json);
  107. }
  108. Json::Value Debug::debug_traceBlockByHash(string const& _blockHash, Json::Value const& _json)
  109. {
  110. Json::Value ret;
  111. Block block = m_eth.block(h256(_blockHash));
  112. ret["structLogs"] = traceBlock(block, _json);
  113. return ret;
  114. }
  115. Json::Value Debug::debug_traceBlockByNumber(int _blockNumber, Json::Value const& _json)
  116. {
  117. Json::Value ret;
  118. Block block = m_eth.block(blockHash(std::to_string(_blockNumber)));
  119. ret["structLogs"] = traceBlock(block, _json);
  120. return ret;
  121. }
  122. Json::Value Debug::debug_storageRangeAt(string const& _blockHashOrNumber, int _txIndex, string const& _address, string const& _begin, string const& _end, int _maxResults)
  123. {
  124. Json::Value ret(Json::objectValue);
  125. ret["complete"] = true;
  126. ret["storage"] = Json::Value(Json::objectValue);
  127. if (_txIndex < 0)
  128. throw jsonrpc::JsonRpcException("Negative index");
  129. if (_maxResults <= 0)
  130. throw jsonrpc::JsonRpcException("Nonpositive maxResults");
  131. u256 const begin(u256fromHex(_begin));
  132. u256 const end(u256fromHex(_end));
  133. if (begin > end)
  134. throw jsonrpc::JsonRpcException("Begin is greater than end");
  135. try
  136. {
  137. Block block = m_eth.block(blockHash(_blockHashOrNumber));
  138. unsigned const i = ((unsigned)_txIndex < block.pending().size()) ? (unsigned)_txIndex : block.pending().size();
  139. State state = block.fromPending(i);
  140. map<u256, u256> const storage(state.storage(Address(_address)));
  141. // begin is inclusive
  142. auto itBegin = storage.lower_bound(begin);
  143. // end is inclusive, too, so find the element following it
  144. auto itEnd = storage.upper_bound(end);
  145. for (auto it = itBegin; it != itEnd; ++it)
  146. {
  147. if (ret["storage"].size() == static_cast<unsigned>(_maxResults))
  148. {
  149. ret["complete"] = false;
  150. break;
  151. }
  152. ret["storage"][toCompactHex(it->first, HexPrefix::Add, 1)] = toCompactHex(it->second, HexPrefix::Add, 1);
  153. }
  154. }
  155. catch (Exception const& _e)
  156. {
  157. cwarn << diagnostic_information(_e);
  158. throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_RPC_INVALID_PARAMS);
  159. }
  160. return ret;
  161. }
  162. Json::Value Debug::debug_traceCall(Json::Value const& _call, std::string const& _blockNumber, Json::Value const& _options)
  163. {
  164. Json::Value ret;
  165. try
  166. {
  167. Block temp = m_eth.block(jsToBlockNumber(_blockNumber));
  168. TransactionSkeleton ts = toTransactionSkeleton(_call);
  169. if (!ts.from) {
  170. ts.from = Address();
  171. }
  172. u256 nonce = temp.transactionsFrom(ts.from);
  173. u256 gas = ts.gas == Invalid256 ? m_eth.gasLimitRemaining() : ts.gas;
  174. u256 gasPrice = ts.gasPrice == Invalid256 ? m_eth.gasBidPrice() : ts.gasPrice;
  175. temp.mutableState().addBalance(ts.from, gas * gasPrice + ts.value);
  176. Transaction transaction(ts.value, gasPrice, gas, ts.to, ts.data, nonce);
  177. transaction.forceSender(ts.from);
  178. eth::ExecutionResult er;
  179. Executive e(temp);
  180. e.setResultRecipient(er);
  181. Json::Value trace = traceTransaction(e, transaction, _options);
  182. ret["gas"] = toHex(transaction.gas(), HexPrefix::Add);
  183. ret["return"] = toHex(er.output, 2, HexPrefix::Add);
  184. ret["structLogs"] = trace;
  185. }
  186. catch(Exception const& _e)
  187. {
  188. cwarn << diagnostic_information(_e);
  189. }
  190. return ret;
  191. }