Fabcoin Core  0.16.2
P2P Digital Currency
ExtVM.cpp
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 */
22 #include "ExtVM.h"
23 #include <exception>
24 #include <boost/thread.hpp>
25 
26 using namespace dev;
27 using namespace dev::eth;
28 
29 namespace // anonymous
30 {
31 
32 static unsigned const c_depthLimit = 1024;
33 
35 static size_t const c_singleExecutionStackSize = 14 * 1024;
36 
38 static size_t const c_defaultStackSize =
39 #if defined(__linux)
40  8 * 1024 * 1024;
41 #elif defined(_WIN32)
42  16 * 1024 * 1024;
43 #else
44  512 * 1024; // OSX and other OSs
45 #endif
46 
48 static size_t const c_entryOverhead = 128 * 1024;
49 
51 static unsigned const c_offloadPoint = (c_defaultStackSize - c_entryOverhead) / c_singleExecutionStackSize;
52 
53 void goOnOffloadedStack(Executive& _e, OnOpFunc const& _onOp)
54 {
55  // Set new stack size enouth to handle the rest of the calls up to the limit.
56  boost::thread::attributes attrs;
57  attrs.set_stack_size((c_depthLimit - c_offloadPoint) * c_singleExecutionStackSize);
58 
59  // Create new thread with big stack and join immediately.
60  // TODO: It is possible to switch the implementation to Boost.Context or similar when the API is stable.
61  boost::exception_ptr exception;
62  boost::thread{attrs, [&]{
63  try
64  {
65  _e.go(_onOp);
66  }
67  catch (...)
68  {
69  exception = boost::current_exception(); // Catch all exceptions to be rethrown in parent thread.
70  }
71  }}.join();
72  if (exception)
73  boost::rethrow_exception(exception);
74 }
75 
76 void go(unsigned _depth, Executive& _e, OnOpFunc const& _onOp)
77 {
78  // If in the offloading point we need to switch to additional separated stack space.
79  // Current stack is too small to handle more CALL/CREATE executions.
80  // It needs to be done only once as newly allocated stack space it enough to handle
81  // the rest of the calls up to the depth limit (c_depthLimit).
82 
83  if (_depth == c_offloadPoint)
84  {
85  cnote << "Stack offloading (depth: " << c_offloadPoint << ")";
86  goOnOffloadedStack(_e, _onOp);
87  }
88  else
89  _e.go(_onOp);
90 }
91 
92 } // anonymous namespace
93 
94 
95 boost::optional<owning_bytes_ref> ExtVM::call(CallParameters& _p)
96 {
98  if (!e.call(_p, gasPrice, origin))
99  {
100  go(depth, e, _p.onOp);
101  e.accrueSubState(sub);
102  }
103  _p.gas = e.gas();
104 
105  if (e.excepted())
106  return {};
107 
108  return e.takeOutput();
109 }
110 
112 {
113  return m_s.codeSize(_a);
114 }
115 
117 {
118  m_s.setStorage(myAddress, _n, _v);
119 }
120 
121 h160 ExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp)
122 {
124  if (!e.create(myAddress, _endowment, gasPrice, io_gas, _code, origin))
125  {
126  go(depth, e, _onOp);
127  e.accrueSubState(sub);
128  }
129  io_gas = e.gas();
130  return e.newAddress();
131 }
132 
134 {
135  // TODO: Why transfer is no used here?
136  // m_s.addBalance(_a, m_s.balance(myAddress));
137  // m_s.subBalance(myAddress, m_s.balance(myAddress));
138  if(!m_s.addressInUse(_a)){
139  m_sealEngine.deleteAddresses.insert(_a);
140  }
142  ExtVMFace::suicide(_a);
143 }
bool addressInUse(Address const &_address) const
Check if the address is in use.
Definition: State.cpp:245
u256 balance(Address const &_id) const
Get an account&#39;s balance.
Definition: State.cpp:266
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
virtual boost::optional< owning_bytes_ref > call(CallParameters &_params) overridefinal
Create a new message call. Leave _myAddressOverride as the default to use the present address as call...
Definition: ExtVM.cpp:95
State & m_s
A reference to the base state.
Definition: ExtVM.h:94
virtual void suicide(Address _a) overridefinal
Suicide the associated contract to the given address.
Definition: ExtVM.cpp:133
EnvInfo const & envInfo() const
Get the execution environment information.
Definition: ExtVMFace.h:313
bool go(OnOpFunc const &_onOp=OnOpFunc())
Executes (or continues execution of) the VM.
Definition: Executive.cpp:386
virtual h160 create(u256 _endowment, u256 &io_gas, bytesConstRef _code, OnOpFunc const &_onOp={}) overridefinal
Create a new contract.
Definition: ExtVM.cpp:121
virtual size_t codeSizeAt(Address _a) overridefinal
Definition: ExtVM.cpp:111
Fixed-size raw-byte array container type, with an API optimised for storing hashes.
Definition: FixedHash.h:47
std::function< void(uint64_t, uint64_t, Instruction, bigint, bigint, bigint, VM *, ExtVMFace const *)> OnOpFunc
Definition: ExtVMFace.h:193
unsigned depth
Depth of the present call.
Definition: ExtVMFace.h:332
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
SealEngineFace const & m_sealEngine
Definition: ExtVM.h:95
u256 gasPrice
Price of gas (that we already paid).
Definition: ExtVMFace.h:327
Address myAddress
Address associated with executing code (a contract, or contract-to-be).
Definition: ExtVMFace.h:323
void setStorage(Address const &_contract, u256 const &_location, u256 const &_value)
Set the value of a storage position of an account.
Definition: State.cpp:372
#define cnote
Definition: Log.h:303
Address origin
Original transactor.
Definition: ExtVMFace.h:325
std::set< Address > deleteAddresses
Definition: SealEngine.h:96
virtual void transferBalance(Address const &_from, Address const &_to, u256 const &_value)
Transfers "the balance _value between two accounts.
Definition: State.h:240
virtual void suicide(Address)
Suicide the associated contract and give proceeds to the given address.
Definition: ExtVMFace.h:298
#define e(i)
Definition: sha.cpp:733
SubState sub
Sub-band VM state (suicides, refund counter, logs).
Definition: ExtVMFace.h:331
size_t codeSize(Address const &_contract) const
Get the byte-size of the code of an account.
Definition: State.cpp:454
virtual void setStore(u256 _n, u256 _v) overridefinal
Write a value in storage.
Definition: ExtVM.cpp:116