Browse Source

Refactor state to use executive for calls.

cl-refactor
Gav Wood 10 years ago
parent
commit
daa6b8f849
  1. 11
      libethereum/Executive.cpp
  2. 3
      libethereum/Executive.h
  3. 32
      libethereum/State.cpp
  4. 2
      libethereum/State.h

11
libethereum/Executive.cpp

@ -98,7 +98,7 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen
// cnote << "Transferring" << formatBalance(_value) << "to receiver.";
m_s.addBalance(_receiveAddress, _value);
auto it = !(_receiveAddress & ~h160(0xffffffff)) ? State::precompiled().find((unsigned)(u160)_receiveAddress) : State::precompiled().end();
auto it = !(_codeAddress & ~h160(0xffffffff)) ? State::precompiled().find((unsigned)(u160)_codeAddress) : State::precompiled().end();
if (it != State::precompiled().end())
{
bigint g = it->second.gas(_data);
@ -110,13 +110,14 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen
else
{
m_endGas = (u256)(_gas - g);
it->second.exec(_data, bytesRef());
m_precompiledOut = it->second.exec(_data);
m_out = &m_precompiledOut;
}
}
else if (m_s.addressHasCode(_codeAddress))
{
m_vm = VMFactory::create(_gas);
bytes const& c = m_s.code(_receiveAddress);
bytes const& c = m_s.code(_codeAddress);
m_ext = make_shared<ExtVM>(m_s, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &c, m_depth);
}
else
@ -166,7 +167,7 @@ bool Executive::go(OnOpFunc const& _onOp)
if (m_vm)
{
boost::timer t;
auto sgas = m_vm->gas();
// auto sgas = m_vm->gas();
try
{
m_out = m_vm->go(*m_ext, _onOp);
@ -203,7 +204,7 @@ bool Executive::go(OnOpFunc const& _onOp)
// TODO: AUDIT: check that this can never reasonably happen. Consider what to do if it does.
cwarn << "Unexpected std::exception in VM. This is probably unrecoverable. " << _e.what();
}
cnote << "VM took:" << t.elapsed() << "; gas used: " << (sgas - m_endGas);
// cnote << "VM took:" << t.elapsed() << "; gas used: " << (sgas - m_endGas);
}
return true;
}

3
libethereum/Executive.h

@ -74,7 +74,8 @@ private:
State& m_s;
std::shared_ptr<ExtVM> m_ext;
std::unique_ptr<VMFace> m_vm;
bytesConstRef m_out;
bytes m_precompiledOut; ///< Used for the output when there is no VM for a contract (i.e. precompiled).
bytesConstRef m_out; ///< Holds the copyable output.
Address m_newAddress;
Transaction m_t;

32
libethereum/State.cpp

@ -42,7 +42,7 @@ using namespace dev::eth;
static const u256 c_blockReward = 1500 * finney;
void ecrecoverCode(bytesConstRef _in, bytesRef _out)
bytes ecrecoverCode(bytesConstRef _in)
{
struct inType
{
@ -54,38 +54,35 @@ void ecrecoverCode(bytesConstRef _in, bytesRef _out)
memcpy(&in, _in.data(), min(_in.size(), sizeof(in)));
memset(_out.data(), 0, _out.size());
h256 ret;
if ((u256)in.v > 28)
return;
return ret.asBytes();
SignatureStruct sig{in.r, in.s, (byte)((int)(u256)in.v - 27)};
if (!sig.isValid())
return;
return ret.asBytes();
h256 ret;
byte pubkey[65];
int pubkeylen = 65;
secp256k1_start();
if (secp256k1_ecdsa_recover_compact(in.hash.data(), 32, in.r.data(), pubkey, &pubkeylen, 0, (int)(u256)in.v - 27))
ret = dev::sha3(bytesConstRef(&(pubkey[1]), 64));
memset(ret.data(), 0, 12);
memcpy(_out.data(), &ret, min(_out.size(), sizeof(ret)));
return ret.asBytes();
}
void sha256Code(bytesConstRef _in, bytesRef _out)
bytes sha256Code(bytesConstRef _in)
{
h256 ret;
sha256(_in, bytesRef(ret.data(), 32));
memcpy(_out.data(), &ret, min(_out.size(), sizeof(ret)));
return ret.asBytes();
}
void ripemd160Code(bytesConstRef _in, bytesRef _out)
bytes ripemd160Code(bytesConstRef _in)
{
h256 ret;
ripemd160(_in, bytesRef(ret.data(), 32));
memset(_out.data(), 0, std::min<int>(12, _out.size()));
if (_out.size() > 12)
memcpy(_out.data() + 12, &ret, min(_out.size() - 12, sizeof(ret)));
return ret.asBytes();
}
const std::map<unsigned, PrecompiledAddress> State::c_precompiled =
@ -1176,24 +1173,19 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit)
bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256& io_gas, bytesRef _out, Address _originAddress, SubState& io_sub, OnOpFunc const& _onOp, unsigned _level)
{
#if 0
#if 1
// TODO: TEST TEST TEST!!!
Executive e(*this, _level);
if (!e.call(_receiveAddress, _codeAddress, _senderAddress, _value, _gasPrice, _data, io_gas, _originAddress))
{
e.go(_onOp);
io_sub += e.ext().sub;
}
e.out().copyTo(_out);
io_gas = e.endGas();
e.out().copyTo(_out);
return !e.excepted();
#else
if (!_originAddress)
_originAddress = _senderAddress;
// cnote << "Transferring" << formatBalance(_value) << "to receiver.";
addBalance(_receiveAddress, _value);

2
libethereum/State.h

@ -55,7 +55,7 @@ struct StateDetail: public LogChannel { static const char* name() { return "/S/"
struct PrecompiledAddress
{
std::function<bigint(bytesConstRef)> gas;
std::function<void(bytesConstRef, bytesRef)> exec;
std::function<bytes(bytesConstRef)> exec;
};
/**

Loading…
Cancel
Save