Browse Source

CALL_STATELESS

cl-refactor
Gav Wood 10 years ago
parent
commit
69126fe1b7
  1. 6
      libethereum/ExtVM.h
  2. 6
      libethereum/State.cpp
  3. 2
      libethereum/State.h
  4. 6
      libevm/ExtVMFace.h
  5. 11
      libevm/VM.h
  6. 2
      libevmface/Instruction.cpp
  7. 1
      libevmface/Instruction.h
  8. 2
      test/vm.cpp

6
libethereum/ExtVM.h

@ -62,12 +62,12 @@ public:
return ret; return ret;
} }
/// Create a new message call. Leave _myAddressOverride at he default to use the present address as caller. /// Create a new message call. Leave _myAddressOverride as the default to use the present address as caller.
bool call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256* _gas, bytesRef _out, OnOpFunc const& _onOp = OnOpFunc(), Address _myAddressOverride = Address()) bool call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256* _gas, bytesRef _out, OnOpFunc const& _onOp = OnOpFunc(), Address _myAddressOverride = Address(), Address _codeAddressOverride = Address())
{ {
if (m_ms) if (m_ms)
m_ms->internal.resize(m_ms->internal.size() + 1); m_ms->internal.resize(m_ms->internal.size() + 1);
auto ret = m_s.call(_receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, _gas, _out, origin, &suicides, &posts, m_ms ? &(m_ms->internal.back()) : nullptr, _onOp, level + 1); auto ret = m_s.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, _gas, _out, origin, &suicides, &posts, m_ms ? &(m_ms->internal.back()) : nullptr, _onOp, level + 1);
if (m_ms && !m_ms->internal.back().from) if (m_ms && !m_ms->internal.back().from)
m_ms->internal.pop_back(); m_ms->internal.pop_back();
return ret; return ret;

6
libethereum/State.cpp

@ -1037,7 +1037,7 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit)
return e.gasUsed(); return e.gasUsed();
} }
bool State::call(Address _receiveAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256* _gas, bytesRef _out, Address _originAddress, std::set<Address>* o_suicides, PostList* o_posts, Manifest* o_ms, OnOpFunc const& _onOp, unsigned _level) bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256* _gas, bytesRef _out, Address _originAddress, std::set<Address>* o_suicides, PostList* o_posts, Manifest* o_ms, OnOpFunc const& _onOp, unsigned _level)
{ {
if (!_originAddress) if (!_originAddress)
_originAddress = _senderAddress; _originAddress = _senderAddress;
@ -1053,10 +1053,10 @@ bool State::call(Address _receiveAddress, Address _senderAddress, u256 _value, u
o_ms->input = _data.toBytes(); o_ms->input = _data.toBytes();
} }
if (addressHasCode(_receiveAddress)) if (addressHasCode(_codeAddress))
{ {
VM vm(*_gas); VM vm(*_gas);
ExtVM evm(*this, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &code(_receiveAddress), o_ms, _level); ExtVM evm(*this, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &code(_codeAddress), o_ms, _level);
bool revert = false; bool revert = false;
try try

2
libethereum/State.h

@ -275,7 +275,7 @@ private:
/// Execute a call. /// Execute a call.
/// @a _gas points to the amount of gas to use for the call, and will lower it accordingly. /// @a _gas points to the amount of gas to use for the call, and will lower it accordingly.
/// @returns false if the call ran out of gas before completion. true otherwise. /// @returns false if the call ran out of gas before completion. true otherwise.
bool call(Address _myAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256* _gas, bytesRef _out, Address _originAddress = Address(), std::set<Address>* o_suicides = nullptr, PostList* o_posts = nullptr, Manifest* o_ms = nullptr, OnOpFunc const& _onOp = OnOpFunc(), unsigned _level = 0); bool call(Address _myAddress, Address _codeAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256* _gas, bytesRef _out, Address _originAddress = Address(), std::set<Address>* o_suicides = nullptr, PostList* o_posts = nullptr, Manifest* o_ms = nullptr, OnOpFunc const& _onOp = OnOpFunc(), unsigned _level = 0);
/// Sets m_currentBlock to a clean state, (i.e. no change from m_previousBlock). /// Sets m_currentBlock to a clean state, (i.e. no change from m_previousBlock).
void resetCurrent(); void resetCurrent();

6
libevm/ExtVMFace.h

@ -40,6 +40,8 @@ struct Post
using PostList = std::list<Post>; using PostList = std::list<Post>;
using OnOpFunc = std::function<void(uint64_t /*steps*/, Instruction /*instr*/, bigint /*newMemSize*/, bigint /*gasCost*/, void/*VM*/*, void/*ExtVM*/ const*)>;
/** /**
* @brief A null implementation of the class for specifying VM externalities. * @brief A null implementation of the class for specifying VM externalities.
*/ */
@ -77,7 +79,7 @@ public:
h160 create(u256, u256*, bytesConstRef, bytesConstRef) { return h160(); } h160 create(u256, u256*, bytesConstRef, bytesConstRef) { return h160(); }
/// Make a new message call. /// Make a new message call.
bool call(Address, u256, bytesConstRef, u256*, bytesRef) { return false; } bool call(Address, u256, bytesConstRef, u256*, bytesRef, OnOpFunc const&, Address, Address) { return false; }
/// Post a new message call. /// Post a new message call.
void post(Address _to, u256 _value, bytesConstRef _data, u256 _gas) { posts.push_back(Post({myAddress, _to, _value, _data.toBytes(), _gas})); } void post(Address _to, u256 _value, bytesConstRef _data, u256 _gas) { posts.push_back(Post({myAddress, _to, _value, _data.toBytes(), _gas})); }
@ -101,6 +103,4 @@ public:
std::list<Post> posts; ///< Any posts that have been made. std::list<Post> posts; ///< Any posts that have been made.
}; };
typedef std::function<void(uint64_t /*steps*/, Instruction /*instr*/, bigint /*newMemSize*/, bigint /*gasCost*/, void/*VM*/*, void/*ExtVM*/ const*)> OnOpFunc;
} }

11
libevm/VM.h

@ -166,6 +166,12 @@ template <class Ext> eth::bytesConstRef eth::VM::go(Ext& _ext, OnOpFunc const& _
newTempSize = std::max(memNeed(m_stack[m_stack.size() - 6], m_stack[m_stack.size() - 7]), memNeed(m_stack[m_stack.size() - 4], m_stack[m_stack.size() - 5])); newTempSize = std::max(memNeed(m_stack[m_stack.size() - 6], m_stack[m_stack.size() - 7]), memNeed(m_stack[m_stack.size() - 4], m_stack[m_stack.size() - 5]));
break; break;
case Instruction::CALLSTATELESS:
require(7);
runGas = c_callGas + m_stack[m_stack.size() - 1];
newTempSize = std::max(memNeed(m_stack[m_stack.size() - 6], m_stack[m_stack.size() - 7]), memNeed(m_stack[m_stack.size() - 4], m_stack[m_stack.size() - 5]));
break;
case Instruction::POST: case Instruction::POST:
require(5); require(5);
runGas = c_callGas + m_stack[m_stack.size() - 1]; runGas = c_callGas + m_stack[m_stack.size() - 1];
@ -580,12 +586,13 @@ template <class Ext> eth::bytesConstRef eth::VM::go(Ext& _ext, OnOpFunc const& _
break; break;
} }
case Instruction::CALL: case Instruction::CALL:
case Instruction::CALLSTATELESS:
{ {
require(7); require(7);
u256 gas = m_stack.back(); u256 gas = m_stack.back();
m_stack.pop_back(); m_stack.pop_back();
u160 receiveAddress = asAddress(m_stack.back()); Address receiveAddress = asAddress(m_stack.back());
m_stack.pop_back(); m_stack.pop_back();
u256 value = m_stack.back(); u256 value = m_stack.back();
m_stack.pop_back(); m_stack.pop_back();
@ -602,7 +609,7 @@ template <class Ext> eth::bytesConstRef eth::VM::go(Ext& _ext, OnOpFunc const& _
if (_ext.balance(_ext.myAddress) >= value) if (_ext.balance(_ext.myAddress) >= value)
{ {
_ext.subBalance(value); _ext.subBalance(value);
m_stack.push_back(_ext.call(receiveAddress, value, bytesConstRef(m_temp.data() + inOff, inSize), &gas, bytesRef(m_temp.data() + outOff, outSize), _onOp)); m_stack.push_back(_ext.call(receiveAddress, value, bytesConstRef(m_temp.data() + inOff, inSize), &gas, bytesRef(m_temp.data() + outOff, outSize), _onOp, Address(), inst == Instruction::CALL ? receiveAddress : _ext.myAddress));
} }
else else
m_stack.push_back(0); m_stack.push_back(0);

2
libevmface/Instruction.cpp

@ -144,6 +144,7 @@ const std::map<std::string, Instruction> eth::c_instructions =
{ "SWAP16", Instruction::SWAP16 }, { "SWAP16", Instruction::SWAP16 },
{ "CREATE", Instruction::CREATE }, { "CREATE", Instruction::CREATE },
{ "CALL", Instruction::CALL }, { "CALL", Instruction::CALL },
{ "CALLSTATELESS", Instruction::CALLSTATELESS },
{ "RETURN", Instruction::RETURN }, { "RETURN", Instruction::RETURN },
{ "POST", Instruction::POST }, { "POST", Instruction::POST },
{ "SUICIDE", Instruction::SUICIDE } { "SUICIDE", Instruction::SUICIDE }
@ -268,6 +269,7 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::SWAP16, { "SWAP16", 0, 17, 17 } }, { Instruction::SWAP16, { "SWAP16", 0, 17, 17 } },
{ Instruction::CREATE, { "CREATE", 0, 3, 1 } }, { Instruction::CREATE, { "CREATE", 0, 3, 1 } },
{ Instruction::CALL, { "CALL", 0, 7, 1 } }, { Instruction::CALL, { "CALL", 0, 7, 1 } },
{ Instruction::CALLSTATELESS, { "CALLSTATELESS",0, 7, 1 } },
{ Instruction::RETURN, { "RETURN", 0, 2, 0 } }, { Instruction::RETURN, { "RETURN", 0, 2, 0 } },
{ Instruction::POST, { "POST", 0, 5, 0 } }, { Instruction::POST, { "POST", 0, 5, 0 } },
{ Instruction::SUICIDE, { "SUICIDE", 0, 1, 0} } { Instruction::SUICIDE, { "SUICIDE", 0, 1, 0} }

1
libevmface/Instruction.h

@ -163,6 +163,7 @@ enum class Instruction: uint8_t
CALL, CALL,
RETURN, RETURN,
POST, POST,
CALLSTATELESS,
SUICIDE = 0xff SUICIDE = 0xff
}; };

2
test/vm.cpp

@ -80,7 +80,7 @@ public:
return na; return na;
} }
bool call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256* _gas, bytesRef _out, OnOpFunc) bool call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256* _gas, bytesRef _out, OnOpFunc, Address, Address)
{ {
/* if (get<0>(addresses[myAddress]) >= _value) /* if (get<0>(addresses[myAddress]) >= _value)
{ {

Loading…
Cancel
Save