Fabcoin Core  0.16.2
P2P Digital Currency
Debug.cpp
Go to the documentation of this file.
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>
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 
14 Debug::Debug(eth::Client const& _eth):
15  m_eth(_eth)
16 {}
17 
19 {
21  if (!_json.isObject() || _json.empty())
22  return op;
23  if (!_json["disableStorage"].empty())
24  op.disableStorage = _json["disableStorage"].asBool();
25  if (!_json["disableMemory"].empty())
26  op.disableMemory = _json["disableMemory"].asBool();
27  if (!_json["disableStack"].empty())
28  op.disableStack =_json["disableStack"].asBool();
29  if (!_json["fullStorage"].empty())
30  op.fullStorage = _json["fullStorage"].asBool();
31  return op;
32 }
33 
34 h256 Debug::blockHash(string const& _blockNumberOrHash) const
35 {
36  if (isHash<h256>(_blockNumberOrHash))
37  return h256(_blockNumberOrHash.substr(_blockNumberOrHash.size() - 64, 64));
38  try
39  {
40  return m_eth.blockChain().numberHash(stoul(_blockNumberOrHash));
41  }
42  catch (...)
43  {
44  throw jsonrpc::JsonRpcException("Invalid argument");
45  }
46 }
47 
49 {
50  Json::Value trace;
51  StandardTrace st;
52  st.setShowMnemonics();
53  st.setOptions(debugOptions(_json));
54  _e.initialize(_t);
55  if (!_e.execute())
56  _e.go(st.onOp());
57  _e.finalize();
58  Json::Reader().parse(st.json(), trace);
59  return trace;
60 }
61 
62 Json::Value Debug::traceBlock(Block const& _block, Json::Value const& _json)
63 {
64  Json::Value traces(Json::arrayValue);
65  for (unsigned k = 0; k < _block.pending().size(); k++)
66  {
67  Transaction t = _block.pending()[k];
68  State s(State::Null);
70  Executive e(s, _block, k, m_eth.blockChain());
71  e.setResultRecipient(er);
72  traces.append(traceTransaction(e, t, _json));
73  }
74  return traces;
75 }
76 
77 Json::Value Debug::debug_traceTransaction(string const& _txHash, Json::Value const& _json)
78 {
79  Json::Value ret;
80  try
81  {
83  Block block = m_eth.block(t.blockHash());
84  State s(State::Null);
86  Executive e(s, block, t.transactionIndex(), m_eth.blockChain());
87  e.setResultRecipient(er);
88  Json::Value trace = traceTransaction(e, t, _json);
89  ret["gas"] = toHex(t.gas(), HexPrefix::Add);
90  ret["return"] = toHex(er.output, 2, HexPrefix::Add);
91  ret["structLogs"] = trace;
92  }
93  catch(Exception const& _e)
94  {
95  cwarn << diagnostic_information(_e);
96  }
97  return ret;
98 }
99 
100 Json::Value Debug::debug_traceBlock(string const& _blockRLP, Json::Value const& _json)
101 {
102  bytes bytes = fromHex(_blockRLP);
103  BlockHeader blockHeader(bytes);
104  return debug_traceBlockByHash(blockHeader.hash().hex(), _json);
105 }
106 
107 Json::Value Debug::debug_traceBlockByHash(string const& _blockHash, Json::Value const& _json)
108 {
109  Json::Value ret;
110  Block block = m_eth.block(h256(_blockHash));
111  ret["structLogs"] = traceBlock(block, _json);
112  return ret;
113 }
114 
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 
123 Json::Value Debug::debug_storageRangeAt(string const& _blockHashOrNumber, int _txIndex, string const& _address, string const& _begin, int _maxResults)
124 {
125  Json::Value ret(Json::objectValue);
126  ret["complete"] = true;
127  ret["storage"] = Json::Value(Json::arrayValue);
128 
129  if (_txIndex < 0)
130  throw jsonrpc::JsonRpcException("Negative index");
131  if (_maxResults <= 0)
132  throw jsonrpc::JsonRpcException("Nonpositive maxResults");
133 
134  try
135  {
136  Block block = m_eth.block(blockHash(_blockHashOrNumber));
137 
138  unsigned const i = ((unsigned)_txIndex < block.pending().size()) ? (unsigned)_txIndex : block.pending().size();
139  State state = block.fromPending(i);
140 
141  map<h256, pair<u256, u256>> const storage(state.storage(Address(_address)));
142 
143  // begin is inclusive
144  auto itBegin = storage.lower_bound(h256fromHex(_begin));
145 
146  for (auto it = itBegin; it != storage.end(); ++it)
147  {
148  if (ret["storage"].size() == static_cast<unsigned>(_maxResults))
149  {
150  ret["complete"] = false;
151  break;
152  }
153 
154  Json::Value keyValue(Json::objectValue);
155  keyValue["hashedKey"] = toCompactHex(it->first, HexPrefix::Add, 1);
156  keyValue["key"] = toCompactHex(it->second.first, HexPrefix::Add, 1);
157  keyValue["value"] = toCompactHex(it->second.second, HexPrefix::Add, 1);
158 
159  ret["storage"].append(keyValue);
160  }
161  }
162  catch (Exception const& _e)
163  {
164  cwarn << diagnostic_information(_e);
165  throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_RPC_INVALID_PARAMS);
166  }
167 
168  return ret;
169 }
170 
171 std::string Debug::debug_preimage(std::string const& _hashedKey)
172 {
173  h256 const hashedKey(h256fromHex(_hashedKey));
174  bytes const key = m_eth.stateDB().lookupAux(hashedKey);
175 
176  return key.empty() ? std::string() : toCompactHex(u256(h256(key)), HexPrefix::Add, 1);
177 }
178 
179 Json::Value Debug::debug_traceCall(Json::Value const& _call, std::string const& _blockNumber, Json::Value const& _options)
180 {
181  Json::Value ret;
182  try
183  {
184  Block temp = m_eth.block(jsToBlockNumber(_blockNumber));
186  if (!ts.from) {
187  ts.from = Address();
188  }
189  u256 nonce = temp.transactionsFrom(ts.from);
190  u256 gas = ts.gas == Invalid256 ? m_eth.gasLimitRemaining() : ts.gas;
191  u256 gasPrice = ts.gasPrice == Invalid256 ? m_eth.gasBidPrice() : ts.gasPrice;
192  temp.mutableState().addBalance(ts.from, gas * gasPrice + ts.value);
193  Transaction transaction(ts.value, gasPrice, gas, ts.to, ts.data, nonce);
194  transaction.forceSender(ts.from);
196  Executive e(temp);
197  e.setResultRecipient(er);
198  Json::Value trace = traceTransaction(e, transaction, _options);
199  ret["gas"] = toHex(transaction.gas(), HexPrefix::Add);
200  ret["return"] = toHex(er.output, 2, HexPrefix::Add);
201  ret["structLogs"] = trace;
202  }
203  catch(Exception const& _e)
204  {
205  cwarn << diagnostic_information(_e);
206  }
207  return ret;
208 }
unsigned transactionIndex() const
Definition: Transaction.h:139
std::string toCompactHex(u256 val, HexPrefix prefix=HexPrefix::DontAdd, unsigned _min=0)
Definition: CommonData.h:175
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
std::string toHex(T const &_data, int _w=2, HexPrefix _prefix=HexPrefix::DontAdd)
Definition: CommonData.h:54
virtual Json::Value debug_traceCall(Json::Value const &_call, std::string const &_blockNumber, Json::Value const &_options) override
Definition: Debug.cpp:179
State fromPending(unsigned _i) const
Get the State immediately after the given number of pending transactions have been applied...
Definition: Block.cpp:832
dev::eth::Block block(h256 const &_blockHash, PopulationStatistics *o_stats) const
Get the block.
Definition: Client.cpp:760
Json::Value traceTransaction(dev::eth::Executive &_e, dev::eth::Transaction const &_t, Json::Value const &_json)
Definition: Debug.cpp:48
h256 hash(IncludeSeal _i=WithSeal) const
Definition: BlockHeader.cpp:64
Encapsulation of a block header.
Definition: BlockHeader.h:95
virtual Json::Value debug_traceBlockByNumber(int _blockNumber, Json::Value const &_json) override
Definition: Debug.cpp:115
h160 Address
An Ethereum address: 20 bytes.
Definition: Common.h:62
virtual u256 gasLimitRemaining() const override
Get the remaining gas limit in this block.
Definition: Client.h:108
OverlayDB const & stateDB() const
Get the block queue.
Definition: Client.h:133
std::hash for asio::adress
Definition: Common.h:323
u256 transactionsFrom(Address const &_address) const
Get the number of transactions a particular address has sent (used for the transaction nonce)...
Definition: Block.h:132
Description of the result of executing a transaction.
Definition: Transaction.h:69
virtual Json::Value debug_traceTransaction(std::string const &_txHash, Json::Value const &_json) override
Definition: Debug.cpp:77
Model of an Ethereum state, essentially a facade for the trie.
Definition: State.h:161
bool go(OnOpFunc const &_onOp=OnOpFunc())
Executes (or continues execution of) the VM.
Definition: Executive.cpp:386
TransactionSkeleton toTransactionSkeleton(Json::Value const &_json)
Definition: JsonHelper.cpp:354
virtual std::string debug_preimage(std::string const &_hashedKey) override
Definition: Debug.cpp:171
BlockNumber jsToBlockNumber(std::string const &_js)
Convert to a block number, a bit like jsToInt, except that it correctly recognises "pending" and "lat...
Definition: CommonJS.cpp:62
Active model of a block within the block chain.
Definition: Block.h:73
bytes fromHex(std::string const &_s, WhenError _throw=WhenError::DontThrow)
Definition: CommonData.cpp:99
std::string json(bool _styled=false) const
Definition: Executive.cpp:150
Base class for all exceptions.
Definition: Exceptions.h:39
Config::Value_type Value
BlockChain const & blockChain() const
Get the object representing the current canonical blockchain.
Definition: Client.h:125
h256 numberHash(unsigned _i) const
Get the hash for a given block&#39;s number.
Definition: BlockChain.h:183
void finalize()
Finalise a transaction previously set up with initialize().
Definition: Executive.cpp:466
std::vector< byte > bytes
Definition: Common.h:75
const u256 Invalid256
Definition: Common.cpp:38
u256 storage(Address const &_contract, u256 const &_memory) const
Get the value of a storage position of an account.
Definition: State.cpp:353
bytes lookupAux(h256 const &_h) const
Definition: OverlayDB.cpp:98
Main API hub for interfacing with Ethereum.
Definition: Client.h:75
FixedHash< 32 > h256
Definition: FixedHash.h:340
#define cwarn
Definition: Log.h:304
Message-call/contract-creation executor; useful for executing transactions.
Definition: Executive.h:106
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
Definition: Common.h:125
virtual Json::Value debug_traceBlock(std::string const &_blockRlp, Json::Value const &_json)
Definition: Debug.cpp:100
Transactions const & pending() const
Get the list of pending transactions.
Definition: Block.h:188
Encodes a transaction, ready to be exported to or freshly imported from RLP.
Definition: Transaction.h:84
virtual Json::Value debug_traceBlockByHash(std::string const &_blockHash, Json::Value const &_json) override
Definition: Debug.cpp:107
h256 blockHash(std::string const &_blockHashOrNumber) const
Definition: Debug.cpp:34
void initialize(bytesConstRef _transaction)
Initializes the executive for evaluating a transaction. You must call finalize() at some point follow...
Definition: Executive.h:135
eth::Client const & m_eth
Definition: Debug.h:39
h256 const & blockHash() const
Definition: Transaction.h:138
State & mutableState()
Get a mutable State object which is backing this block.
Definition: Block.h:180
uint8_t const size_t const size
Definition: sha3.h:20
bool execute()
Begins execution of a transaction.
Definition: Executive.cpp:247
void forceSender(Address const &_a)
Force the sender to a particular value. This will result in an invalid transaction RLP...
Definition: Transaction.h:87
virtual void addBalance(Address const &_id, u256 const &_amount)
Add some amount to balance.
Definition: State.cpp:286
#define e(i)
Definition: sha.cpp:733
virtual Json::Value debug_storageRangeAt(std::string const &_blockHashOrNumber, int _txIndex, std::string const &_address, std::string const &_begin, int _maxResults) override
Definition: Debug.cpp:123
virtual LocalisedTransaction localisedTransaction(h256 const &_transactionHash) const override
Definition: ClientBase.cpp:391
h256 h256fromHex(string const &_s)
Definition: JsonHelper.cpp:545
StandardTrace::DebugOptions debugOptions(Json::Value const &_json)
Definition: Debug.cpp:18
virtual u256 gasBidPrice() const override
Get the gas bid price.
Definition: Client.h:110
void setOptions(DebugOptions _options)
Definition: Executive.h:69
void setResultRecipient(ExecutionResult &_res)
Collect execution results in the result storage provided.
Definition: Executive.h:184
std::string hex() const
Definition: FixedHash.h:130
Json::Value traceBlock(dev::eth::Block const &_block, Json::Value const &_json)
Definition: Debug.cpp:62