ExtVMFace.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  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 ExtVMFace.h
  15. * @author Gav Wood <i@gavwood.com>
  16. * @date 2014
  17. */
  18. #pragma once
  19. #include <set>
  20. #include <functional>
  21. #include <libdevcore/Common.h>
  22. #include <libdevcore/CommonData.h>
  23. #include <libdevcore/RLP.h>
  24. #include <libdevcore/SHA3.h>
  25. #include <libevmcore/Instruction.h>
  26. #include <libethcore/Common.h>
  27. #include <libethcore/BlockHeader.h>
  28. #include <libethcore/ChainOperationParams.h>
  29. namespace dev
  30. {
  31. namespace eth
  32. {
  33. enum class BlockPolarity
  34. {
  35. Unknown,
  36. Dead,
  37. Live
  38. };
  39. struct LogEntry
  40. {
  41. LogEntry() {}
  42. LogEntry(RLP const& _r) { address = (Address)_r[0]; topics = _r[1].toVector<h256>(); data = _r[2].toBytes(); }
  43. LogEntry(Address const& _address, h256s const& _ts, bytes&& _d): address(_address), topics(_ts), data(std::move(_d)) {}
  44. void streamRLP(RLPStream& _s) const { _s.appendList(3) << address << topics << data; }
  45. LogBloom bloom() const
  46. {
  47. LogBloom ret;
  48. ret.shiftBloom<3>(sha3(address.ref()));
  49. for (auto t: topics)
  50. ret.shiftBloom<3>(sha3(t.ref()));
  51. return ret;
  52. }
  53. Address address;
  54. h256s topics;
  55. bytes data;
  56. };
  57. using LogEntries = std::vector<LogEntry>;
  58. struct LocalisedLogEntry: public LogEntry
  59. {
  60. LocalisedLogEntry() {}
  61. explicit LocalisedLogEntry(LogEntry const& _le): LogEntry(_le) {}
  62. explicit LocalisedLogEntry(
  63. LogEntry const& _le,
  64. h256 _special
  65. ):
  66. LogEntry(_le),
  67. isSpecial(true),
  68. special(_special)
  69. {}
  70. explicit LocalisedLogEntry(
  71. LogEntry const& _le,
  72. h256 const& _blockHash,
  73. BlockNumber _blockNumber,
  74. h256 const& _transactionHash,
  75. unsigned _transactionIndex,
  76. unsigned _logIndex,
  77. BlockPolarity _polarity = BlockPolarity::Unknown
  78. ):
  79. LogEntry(_le),
  80. blockHash(_blockHash),
  81. blockNumber(_blockNumber),
  82. transactionHash(_transactionHash),
  83. transactionIndex(_transactionIndex),
  84. logIndex(_logIndex),
  85. polarity(_polarity),
  86. mined(true)
  87. {}
  88. h256 blockHash;
  89. BlockNumber blockNumber = 0;
  90. h256 transactionHash;
  91. unsigned transactionIndex = 0;
  92. unsigned logIndex = 0;
  93. BlockPolarity polarity = BlockPolarity::Unknown;
  94. bool mined = false;
  95. bool isSpecial = false;
  96. h256 special;
  97. };
  98. using LocalisedLogEntries = std::vector<LocalisedLogEntry>;
  99. inline LogBloom bloom(LogEntries const& _logs)
  100. {
  101. LogBloom ret;
  102. for (auto const& l: _logs)
  103. ret |= l.bloom();
  104. return ret;
  105. }
  106. struct SubState
  107. {
  108. std::set<Address> suicides; ///< Any accounts that have suicided.
  109. LogEntries logs; ///< Any logs.
  110. u256 refunds; ///< Refund counter of SSTORE nonzero->zero.
  111. SubState& operator+=(SubState const& _s)
  112. {
  113. suicides += _s.suicides;
  114. refunds += _s.refunds;
  115. logs += _s.logs;
  116. return *this;
  117. }
  118. void clear()
  119. {
  120. suicides.clear();
  121. logs.clear();
  122. refunds = 0;
  123. }
  124. };
  125. class ExtVMFace;
  126. class VM;
  127. using LastHashes = std::vector<h256>;
  128. using OnOpFunc = std::function<void(uint64_t /*steps*/, uint64_t /* PC */, Instruction /*instr*/, bigint /*newMemSize*/, bigint /*gasCost*/, bigint /*gas*/, VM*, ExtVMFace const*)>;
  129. struct CallParameters
  130. {
  131. Address senderAddress;
  132. Address codeAddress;
  133. Address receiveAddress;
  134. u256 valueTransfer;
  135. u256 apparentValue;
  136. u256 gas;
  137. bytesConstRef data;
  138. bytesRef out;
  139. OnOpFunc onOp;
  140. };
  141. class EnvInfo
  142. {
  143. public:
  144. EnvInfo() {}
  145. EnvInfo(BlockHeader const& _current, LastHashes const& _lh = LastHashes(), u256 const& _gasUsed = u256()):
  146. m_number(_current.number()),
  147. m_author(_current.author()),
  148. m_timestamp(_current.timestamp()),
  149. m_difficulty(_current.difficulty()),
  150. // Trim gas limit to int64. convert_to used explicitly instead of
  151. // static_cast to be noticed when BlockHeader::gasLimit() will be
  152. // changed to int64 too.
  153. m_gasLimit(_current.gasLimit().convert_to<int64_t>()),
  154. m_lastHashes(_lh),
  155. m_gasUsed(_gasUsed)
  156. {}
  157. EnvInfo(BlockHeader const& _current, LastHashes&& _lh, u256 const& _gasUsed = u256()):
  158. m_number(_current.number()),
  159. m_author(_current.author()),
  160. m_timestamp(_current.timestamp()),
  161. m_difficulty(_current.difficulty()),
  162. // Trim gas limit to int64. convert_to used explicitly instead of
  163. // static_cast to be noticed when BlockHeader::gasLimit() will be
  164. // changed to int64 too.
  165. m_gasLimit(_current.gasLimit().convert_to<int64_t>()),
  166. m_lastHashes(_lh),
  167. m_gasUsed(_gasUsed)
  168. {}
  169. u256 const& number() const { return m_number; }
  170. Address const& author() const { return m_author; }
  171. u256 const& timestamp() const { return m_timestamp; }
  172. u256 const& difficulty() const { return m_difficulty; }
  173. int64_t gasLimit() const { return m_gasLimit; }
  174. LastHashes const& lastHashes() const { return m_lastHashes; }
  175. u256 const& gasUsed() const { return m_gasUsed; }
  176. void setNumber(u256 const& _v) { m_number = _v; }
  177. void setAuthor(Address const& _v) { m_author = _v; }
  178. void setTimestamp(u256 const& _v) { m_timestamp = _v; }
  179. void setDifficulty(u256 const& _v) { m_difficulty = _v; }
  180. void setGasLimit(int64_t _v) { m_gasLimit = _v; }
  181. void setLastHashes(LastHashes const& _lh) { m_lastHashes = _lh; }
  182. void setLastHashes(LastHashes&& _lh) { m_lastHashes = _lh; }
  183. void setGasUsed(u256 const& _v) { m_gasUsed = _v; }
  184. private:
  185. u256 m_number;
  186. Address m_author;
  187. u256 m_timestamp;
  188. u256 m_difficulty;
  189. int64_t m_gasLimit;
  190. LastHashes m_lastHashes;
  191. u256 m_gasUsed;
  192. };
  193. /**
  194. * @brief Interface and null implementation of the class for specifying VM externalities.
  195. */
  196. class ExtVMFace
  197. {
  198. public:
  199. /// Null constructor.
  200. ExtVMFace() = default;
  201. /// Full constructor.
  202. ExtVMFace(EnvInfo const& _envInfo, Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes _code, h256 const& _codeHash, unsigned _depth);
  203. virtual ~ExtVMFace() = default;
  204. ExtVMFace(ExtVMFace const&) = delete;
  205. void operator=(ExtVMFace) = delete;
  206. /// Read storage location.
  207. virtual u256 store(u256) { return 0; }
  208. /// Write a value in storage.
  209. virtual void setStore(u256, u256) {}
  210. /// Read address's balance.
  211. virtual u256 balance(Address) { return 0; }
  212. /// Read address's code.
  213. virtual bytes const& codeAt(Address) { return NullBytes; }
  214. /// @returns the size of the code in bytes at the given address.
  215. virtual size_t codeSizeAt(Address) { return 0; }
  216. /// Does the account exist?
  217. virtual bool exists(Address) { return false; }
  218. /// Suicide the associated contract and give proceeds to the given address.
  219. virtual void suicide(Address) { sub.suicides.insert(myAddress); }
  220. /// Create a new (contract) account.
  221. virtual h160 create(u256, u256&, bytesConstRef, OnOpFunc const&) { return h160(); }
  222. /// Make a new message call.
  223. virtual bool call(CallParameters&) { return false; }
  224. /// Revert any changes made (by any of the other calls).
  225. virtual void log(h256s&& _topics, bytesConstRef _data) { sub.logs.push_back(LogEntry(myAddress, std::move(_topics), _data.toBytes())); }
  226. /// Revert any changes made (by any of the other calls).
  227. virtual void revert() {}
  228. /// Hash of a block if within the last 256 blocks, or h256() otherwise.
  229. h256 blockHash(u256 _number) { return _number < envInfo().number() && _number >= (std::max<u256>(256, envInfo().number()) - 256) ? envInfo().lastHashes()[(unsigned)(envInfo().number() - 1 - _number)] : h256(); }
  230. /// Get the code at the given location in code ROM.
  231. byte getCode(u256 _n) const { return _n < code.size() ? code[(size_t)_n] : 0; }
  232. /// Get the execution environment information.
  233. EnvInfo const& envInfo() const { return m_envInfo; }
  234. /// Return the EVM gas-price schedule for this execution context.
  235. virtual EVMSchedule const& evmSchedule() const { return DefaultSchedule; }
  236. private:
  237. EnvInfo const& m_envInfo;
  238. public:
  239. // TODO: make private
  240. Address myAddress; ///< Address associated with executing code (a contract, or contract-to-be).
  241. Address caller; ///< Address which sent the message (either equal to origin or a contract).
  242. Address origin; ///< Original transactor.
  243. u256 value; ///< Value (in Wei) that was passed to this address.
  244. u256 gasPrice; ///< Price of gas (that we already paid).
  245. bytesConstRef data; ///< Current input data.
  246. bytes code; ///< Current code that is executing.
  247. h256 codeHash; ///< SHA3 hash of the executing code
  248. SubState sub; ///< Sub-band VM state (suicides, refund counter, logs).
  249. unsigned depth = 0; ///< Depth of the present call.
  250. };
  251. }
  252. }