Ethereum  PoC-8
The C++ Implementation of Ethereum
ExtVMFace.h
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #pragma once
19 
20 #include "Instruction.h"
21 
22 #include <libethcore/BlockHeader.h>
24 #include <libethcore/Common.h>
25 #include <libethcore/LogEntry.h>
26 #include <libdevcore/Common.h>
27 #include <libdevcore/CommonData.h>
28 #include <libdevcore/SHA3.h>
29 
30 #include <evmc/evmc.h>
31 #include <evmc/helpers.h>
32 
33 #include <boost/optional.hpp>
34 #include <functional>
35 #include <set>
36 
37 namespace dev
38 {
39 namespace eth
40 {
41 
57 class owning_bytes_ref: public vector_ref<byte const>
58 {
59 public:
60  owning_bytes_ref() = default;
61 
65  owning_bytes_ref(bytes&& _bytes, size_t _begin, size_t _size):
66  m_bytes(std::move(_bytes))
67  {
68  // Set the reference *after* the buffer is moved to avoid
69  // pointer invalidation.
70  retarget(&m_bytes[_begin], _size);
71  }
72 
73  owning_bytes_ref(owning_bytes_ref const&) = delete;
77 
80  {
81  reset(); // Reset reference just in case.
82  return std::move(m_bytes);
83  }
84 
85 private:
86  bytes m_bytes;
87 };
88 
89 struct SubState
90 {
91  std::set<Address> suicides;
93  int64_t refunds = 0;
94 
96  {
97  suicides += _s.suicides;
98  refunds += _s.refunds;
99  logs += _s.logs;
100  return *this;
101  }
102 
103  void clear()
104  {
105  suicides.clear();
106  logs.clear();
107  refunds = 0;
108  }
109 };
110 
111 class ExtVMFace;
112 class LastBlockHashesFace;
113 class VMFace;
114 
115 using OnOpFunc = std::function<void(uint64_t /*steps*/, uint64_t /* PC */, Instruction /*instr*/, bigint /*newMemSize*/, bigint /*gasCost*/, bigint /*gas*/, VMFace const*, ExtVMFace const*)>;
116 
118 {
119  CallParameters() = default;
121  Address _senderAddress,
122  Address _codeAddress,
123  Address _receiveAddress,
124  u256 _valueTransfer,
125  u256 _apparentValue,
126  u256 _gas,
127  bytesConstRef _data,
128  OnOpFunc _onOpFunc
129  ): senderAddress(_senderAddress), codeAddress(_codeAddress), receiveAddress(_receiveAddress),
130  valueTransfer(_valueTransfer), apparentValue(_apparentValue), gas(_gas), data(_data), onOp(_onOpFunc) {}
138  bool staticCall = false;
140 };
141 
142 class EnvInfo
143 {
144 public:
145  EnvInfo(BlockHeader const& _current, LastBlockHashesFace const& _lh, u256 const& _gasUsed):
146  m_headerInfo(_current),
147  m_lastHashes(_lh),
148  m_gasUsed(_gasUsed)
149  {}
150  // Constructor with custom gasLimit - used in some synthetic scenarios like eth_estimateGas RPC method
151  EnvInfo(BlockHeader const& _current, LastBlockHashesFace const& _lh, u256 const& _gasUsed, u256 const& _gasLimit):
152  EnvInfo(_current, _lh, _gasUsed)
153  {
154  m_headerInfo.setGasLimit(_gasLimit);
155  }
156 
157  BlockHeader const& header() const { return m_headerInfo; }
158 
159  int64_t number() const { return m_headerInfo.number(); }
160  Address const& author() const { return m_headerInfo.author(); }
161  int64_t timestamp() const { return m_headerInfo.timestamp(); }
162  u256 const& difficulty() const { return m_headerInfo.difficulty(); }
163  u256 const& gasLimit() const { return m_headerInfo.gasLimit(); }
164  LastBlockHashesFace const& lastHashes() const { return m_lastHashes; }
165  u256 const& gasUsed() const { return m_gasUsed; }
166 
167 private:
168  BlockHeader m_headerInfo;
169  LastBlockHashesFace const& m_lastHashes;
170  u256 m_gasUsed;
171 };
172 
177 {
178  evmc_status_code status;
180 
182  : status{status}, output{std::move(output)}
183  {}
184 };
185 
190 {
191  evmc_status_code status;
194 
195  CreateResult(evmc_status_code status, owning_bytes_ref&& output, h160 const& address)
196  : status{status}, output{std::move(output)}, address{address}
197  {}
198 };
199 
203 class ExtVMFace: public evmc_context
204 {
205 public:
207  ExtVMFace(EnvInfo const& _envInfo, Address _myAddress, Address _caller, Address _origin,
208  u256 _value, u256 _gasPrice, bytesConstRef _data, bytes _code, h256 const& _codeHash,
209  unsigned _depth, bool _isCreate, bool _staticCall);
210 
211  virtual ~ExtVMFace() = default;
212 
213  ExtVMFace(ExtVMFace const&) = delete;
214  ExtVMFace& operator=(ExtVMFace const&) = delete;
215 
217  virtual u256 store(u256) { return 0; }
218 
220  virtual void setStore(u256, u256) {}
221 
223  virtual u256 originalStorageValue(u256 const&) { return 0; }
224 
226  virtual u256 balance(Address) { return 0; }
227 
229  virtual bytes const& codeAt(Address) { return NullBytes; }
230 
232  virtual size_t codeSizeAt(Address) { return 0; }
233 
235  virtual h256 codeHashAt(Address) { return h256{}; }
236 
238  virtual bool exists(Address) { return false; }
239 
241  virtual void suicide(Address) { sub.suicides.insert(myAddress); }
242 
245 
247  virtual CallResult call(CallParameters&) = 0;
248 
250  virtual void log(h256s&& _topics, bytesConstRef _data) { sub.logs.push_back(LogEntry(myAddress, std::move(_topics), _data.toBytes())); }
251 
253  virtual h256 blockHash(u256 _number) = 0;
254 
256  EnvInfo const& envInfo() const { return m_envInfo; }
257 
259  virtual EVMSchedule const& evmSchedule() const { return DefaultSchedule; }
260 
261 private:
262  EnvInfo const& m_envInfo;
263 
264 public:
265  // TODO: make private
276  unsigned depth = 0;
277  bool isCreate = false;
278  bool staticCall = false;
279 };
280 
281 inline evmc_address toEvmC(Address const& _addr)
282 {
283  return reinterpret_cast<evmc_address const&>(_addr);
284 }
285 
286 inline evmc_uint256be toEvmC(h256 const& _h)
287 {
288  return reinterpret_cast<evmc_uint256be const&>(_h);
289 }
290 
291 inline u256 fromEvmC(evmc_uint256be const& _n)
292 {
293  return fromBigEndian<u256>(_n.bytes);
294 }
295 
296 inline Address fromEvmC(evmc_address const& _addr)
297 {
298  return reinterpret_cast<Address const&>(_addr);
299 }
300 }
301 }
virtual bytes const & codeAt(Address)
Read address&#39;s code.
Definition: ExtVMFace.h:229
Definition: Address.cpp:20
SubState & operator+=(SubState const &_s)
Definition: ExtVMFace.h:95
std::function< void(uint64_t, uint64_t, Instruction, bigint, bigint, bigint, VMFace const *, ExtVMFace const *)> OnOpFunc
Definition: ExtVMFace.h:115
u256 const & difficulty() const
Definition: BlockHeader.h:170
ExtVMFace & operator=(ExtVMFace const &)=delete
Encapsulation of a block header. Class to contain all of a block header&#39;s data. It is able to parse a...
Definition: BlockHeader.h:96
LogEntries logs
Any logs.
Definition: ExtVMFace.h:92
virtual ~ExtVMFace()=default
virtual size_t codeSizeAt(Address)
Definition: ExtVMFace.h:232
std::vector< unsigned char > toBytes() const
Definition: vector_ref.h:43
u256 value
Value (in Wei) that was passed to this address.
Definition: ExtVMFace.h:269
owning_bytes_ref(bytes &&_bytes, size_t _begin, size_t _size)
Definition: ExtVMFace.h:65
virtual h256 codeHashAt(Address)
Definition: ExtVMFace.h:235
virtual CallResult call(CallParameters &)=0
Make a new message call.
virtual EVMSchedule const & evmSchedule() const
Return the EVM gas-price schedule for this execution context.
Definition: ExtVMFace.h:259
Interface for getting a list of recent block hashes .
evmc_address toEvmC(Address const &_addr)
Definition: ExtVMFace.h:281
Definition: FixedHash.h:390
u256 fromEvmC(evmc_uint256be const &_n)
Definition: ExtVMFace.h:291
Address const & author() const
Definition: BlockHeader.h:161
h256 codeHash
SHA3 hash of the executing code.
Definition: ExtVMFace.h:273
int64_t number() const
Definition: BlockHeader.h:166
virtual h256 blockHash(u256 _number)=0
Hash of a block if within the last 256 blocks, or h256() otherwise.
ExtVMFace(EnvInfo const &_envInfo, Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes _code, h256 const &_codeHash, unsigned _depth, bool _isCreate, bool _staticCall)
Full constructor.
Definition: ExtVMFace.cpp:298
BlockHeader const & header() const
Definition: ExtVMFace.h:157
Address const & author() const
Definition: ExtVMFace.h:160
void retarget(byte const *_d, size_t _s)
Definition: vector_ref.h:63
bool staticCall
Throw on state changing.
Definition: ExtVMFace.h:278
EnvInfo(BlockHeader const &_current, LastBlockHashesFace const &_lh, u256 const &_gasUsed)
Definition: ExtVMFace.h:145
boost::multiprecision::number< boost::multiprecision::cpp_int_backend<> > bigint
Definition: Common.h:118
int64_t timestamp() const
Definition: BlockHeader.h:160
Address caller
Address which sent the message (either equal to origin or a contract).
Definition: ExtVMFace.h:267
owning_bytes_ref output
Definition: ExtVMFace.h:192
virtual bool exists(Address)
Does the account exist?
Definition: ExtVMFace.h:238
bytes const NullBytes
Definition: Common.cpp:33
virtual u256 originalStorageValue(u256 const &)
Read original storage value (before modifications in the current transaction).
Definition: ExtVMFace.h:223
std::vector< byte > bytes
Definition: Common.h:72
unsigned depth
Depth of the present call.
Definition: ExtVMFace.h:276
u256 const & gasLimit() const
Definition: ExtVMFace.h:163
owning_bytes_ref output
Definition: ExtVMFace.h:179
void setGasLimit(u256 const &_v)
Definition: BlockHeader.h:150
EVM Virtual Machine interface.
Definition: VMFace.h:63
u256 const & gasUsed() const
Definition: ExtVMFace.h:165
Instruction
Virtual machine bytecode instruction.
Definition: Instruction.h:28
virtual void setStore(u256, u256)
Write a value in storage.
Definition: ExtVMFace.h:220
virtual CreateResult create(u256, u256 &, bytesConstRef, Instruction, u256, OnOpFunc const &)=0
Create a new (contract) account.
u256 gasPrice
Price of gas (that we already paid).
Definition: ExtVMFace.h:270
std::set< Address > suicides
Any accounts that have suicided.
Definition: ExtVMFace.h:91
Interface and null implementation of the class for specifying VM externalities.
Definition: ExtVMFace.h:203
int64_t number() const
Definition: ExtVMFace.h:159
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void > > u256
Definition: Common.h:121
bytes code
Current code that is executing.
Definition: ExtVMFace.h:272
LastBlockHashesFace const & lastHashes() const
Definition: ExtVMFace.h:164
Address myAddress
Address associated with executing code (a contract, or contract-to-be).
Definition: ExtVMFace.h:266
u256 const & difficulty() const
Definition: ExtVMFace.h:162
Address origin
Original transactor.
Definition: ExtVMFace.h:268
bool isCreate
Is this a CREATE call?
Definition: ExtVMFace.h:277
u256 salt
Values used in new address construction by CREATE2.
Definition: ExtVMFace.h:274
CreateResult(evmc_status_code status, owning_bytes_ref &&output, h160 const &address)
Definition: ExtVMFace.h:195
evmc_status_code status
Definition: ExtVMFace.h:191
owning_bytes_ref & operator=(owning_bytes_ref const &)=delete
int64_t refunds
Refund counter for storage changes.
Definition: ExtVMFace.h:93
EnvInfo const & envInfo() const
Get the execution environment information.
Definition: ExtVMFace.h:256
virtual void suicide(Address)
Suicide the associated contract and give proceeds to the given address.
Definition: ExtVMFace.h:241
evmc_status_code status
Definition: ExtVMFace.h:178
EnvInfo(BlockHeader const &_current, LastBlockHashesFace const &_lh, u256 const &_gasUsed, u256 const &_gasLimit)
Definition: ExtVMFace.h:151
SubState sub
Sub-band VM state (suicides, refund counter, logs).
Definition: ExtVMFace.h:275
virtual void log(h256s &&_topics, bytesConstRef _data)
Revert any changes made (by any of the other calls).
Definition: ExtVMFace.h:250
bytesConstRef data
Definition: ExtVMFace.h:137
u256 const & gasLimit() const
Definition: BlockHeader.h:167
virtual u256 balance(Address)
Read address&#39;s balance.
Definition: ExtVMFace.h:226
bytesConstRef data
Current input data.
Definition: ExtVMFace.h:271
CallResult(evmc_status_code status, owning_bytes_ref &&output)
Definition: ExtVMFace.h:181
virtual u256 store(u256)
Read storage location.
Definition: ExtVMFace.h:217
bytes && takeBytes()
Moves the bytes vector out of here. The object cannot be used any more.
Definition: ExtVMFace.h:79
CallParameters(Address _senderAddress, Address _codeAddress, Address _receiveAddress, u256 _valueTransfer, u256 _apparentValue, u256 _gas, bytesConstRef _data, OnOpFunc _onOpFunc)
Definition: ExtVMFace.h:120
int64_t timestamp() const
Definition: ExtVMFace.h:161
std::vector< h256 > h256s
Definition: FixedHash.h:359
std::vector< LogEntry > LogEntries
Definition: LogEntry.h:51
Definition: LogEntry.h:34