@ -36,33 +36,35 @@ FakeExtVM::FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const&
h160 FakeExtVM : : create ( u256 _endowment , u256 * _gas , bytesConstRef _init , OnOpFunc const & )
h160 FakeExtVM : : create ( u256 _endowment , u256 * _gas , bytesConstRef _init , OnOpFunc const & )
{
{
Address na = right160 ( sha3 ( rlpList ( myAddress , get < 1 > ( addresses [ myAddress ] ) ) ) ) ;
Transaction t ;
Transaction t ;
t . value = _endowment ;
t . value = _endowment ;
t . gasPrice = gasPrice ;
t . gasPrice = gasPrice ;
t . gas = * _gas ;
t . gas = * _gas ;
t . data = _init . toBytes ( ) ;
t . data = _init . toBytes ( ) ;
m_s . noteSending ( myAddress ) ;
// m_s.noteSending(myAddress);
m_ms . internal . resize ( m_ms . internal . size ( ) + 1 ) ;
// m_ms.internal.resize(m_ms.internal.size() + 1);
auto ret = m_s . create ( myAddress , _endowment , gasPrice , _gas , _init , origin , & sub , & m_ms ? & ( m_ms . internal . back ( ) ) : nullptr , { } , 1 ) ;
// auto ret = m_s.create(myAddress, _endowment, gasPrice, _gas, _init, origin, &sub, &m_ms ? &(m_ms.internal.back()) : nullptr, {}, 1);
if ( ! m_ms . internal . back ( ) . from )
// if (!m_ms.internal.back().from)
m_ms . internal . pop_back ( ) ;
// m_ms.internal.pop_back();
if ( get < 0 > ( addresses [ myAddress ] ) > = _endowment )
// if (get<0>(addresses[myAddress]) >= _endowment)
{
// {
get < 1 > ( addresses [ myAddress ] ) + + ;
// get<1>(addresses[myAddress])++;
get < 0 > ( addresses [ ret ] ) = _endowment ;
// get<0>(addresses[ret]) = _endowment;
get < 3 > ( addresses [ ret ] ) = m_s . code ( ret ) ;
// //get<3>(addresses[ret]) = m_s.code(ret);
}
// }
t . type = eth : : Transaction : : ContractCreation ;
t . type = eth : : Transaction : : ContractCreation ;
callcreates . push_back ( t ) ;
callcreates . push_back ( t ) ;
return ret ;
return na ;
}
}
bool FakeExtVM : : call ( Address _receiveAddress , u256 _value , bytesConstRef _data , u256 * _gas , bytesRef _out , OnOpFunc const & , Address _myAddressOverride , Address _codeAddressOverride )
bool FakeExtVM : : call ( Address _receiveAddress , u256 _value , bytesConstRef _data , u256 * _gas , bytesRef _out , OnOpFunc const & , Address _myAddressOverride , Address _codeAddressOverride )
{
{
u256 contractgas = 0xffff ;
// u256 contractgas = 0xffff;
Transaction t ;
Transaction t ;
t . value = _value ;
t . value = _value ;
@ -72,101 +74,103 @@ bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data,
t . type = eth : : Transaction : : MessageCall ;
t . type = eth : : Transaction : : MessageCall ;
t . receiveAddress = _receiveAddress ;
t . receiveAddress = _receiveAddress ;
callcreates . push_back ( t ) ;
callcreates . push_back ( t ) ;
( void ) _out ;
string codeOf_CodeAddress = _codeAddressOverride ? toHex ( get < 3 > ( addresses [ _codeAddressOverride ] ) ) : toHex ( get < 3 > ( addresses [ _receiveAddress ] ) ) ;
string sizeOfCode = toHex ( toCompactBigEndian ( ( codeOf_CodeAddress . size ( ) + 1 ) / 2 ) ) ;
string codeOf_SenderAddress = toHex ( get < 3 > ( addresses [ myAddress ] ) ) ;
string sizeOfSenderCode = toHex ( toCompactBigEndian ( ( codeOf_SenderAddress . size ( ) + 1 ) / 2 ) ) ;
if ( codeOf_SenderAddress . size ( ) )
{
// create init code that returns given contract code
string initStringHex = " { (CODECOPY 0 (- (CODESIZE) 0x " + sizeOfSenderCode + " ) 0x " + sizeOfSenderCode + " ) (RETURN 0 0x " + sizeOfSenderCode + " )} " ;
bytes initBytes = compileLLL ( initStringHex , true , NULL ) ;
initBytes + = fromHex ( codeOf_SenderAddress ) ;
bytesConstRef init ( & initBytes ) ;
if ( ! m_s . addresses ( ) . count ( myAddress ) )
{
m_ms . internal . resize ( m_ms . internal . size ( ) + 1 ) ;
auto na = m_s . createNewAddress ( myAddress , myAddress , balance ( myAddress ) , gasPrice , & contractgas , init , origin , & sub , & m_ms ? & ( m_ms . internal . back ( ) ) : nullptr , { } , 1 ) ;
if ( ! m_ms . internal . back ( ) . from )
m_ms . internal . pop_back ( ) ;
if ( na ! = myAddress )
{
cnote < < " not able to call to : " < < myAddress < < " \n " ;
cnote < < " in FakeExtVM you can only make a call to " < < na < < " \n " ;
BOOST_THROW_EXCEPTION ( FakeExtVMFailure ( ) < < errinfo_comment ( " Address not callable in FakeExtVM \n " ) < < errinfo_wrongAddress ( toString ( myAddress ) ) ) ;
return false ;
}
}
}
if ( codeOf_CodeAddress . size ( ) )
{
// create init code that returns given contract code
string initStringHex = " { (CODECOPY 0 (- (CODESIZE) 0x " + sizeOfCode + " ) 0x " + sizeOfCode + " ) (RETURN 0 0x " + sizeOfCode + " )} " ;
bytes initBytes = compileLLL ( initStringHex , true , NULL ) ;
initBytes + = fromHex ( codeOf_CodeAddress ) ;
bytesConstRef init ( & initBytes ) ;
if ( ! m_s . addresses ( ) . count ( _codeAddressOverride ? _codeAddressOverride : _receiveAddress ) )
{
m_s . noteSending ( myAddress ) ;
m_ms . internal . resize ( m_ms . internal . size ( ) + 1 ) ;
auto na = m_s . createNewAddress ( _codeAddressOverride ? _codeAddressOverride : _receiveAddress , myAddress , balance ( _codeAddressOverride ? _codeAddressOverride : _receiveAddress ) , gasPrice , & contractgas , init , origin , & sub , & m_ms ? & ( m_ms . internal . back ( ) ) : nullptr , OnOpFunc ( ) , 1 ) ;
if ( ! m_ms . internal . back ( ) . from )
m_ms . internal . pop_back ( ) ;
if ( na ! = ( _codeAddressOverride ? _codeAddressOverride : _receiveAddress ) )
{
cnote < < " not able to call to : " < < ( _codeAddressOverride ? _codeAddressOverride : _receiveAddress ) < < " \n " ;
cnote < < " in FakeExtVM you can only make a call to " < < na < < " \n " ;
BOOST_THROW_EXCEPTION ( FakeExtVMFailure ( ) < < errinfo_comment ( " Address not callable in FakeExtVM \n " ) < < errinfo_wrongAddress ( toString ( _codeAddressOverride ? _codeAddressOverride : _receiveAddress ) ) ) ;
return false ;
}
}
m_ms . internal . resize ( m_ms . internal . size ( ) + 1 ) ;
auto ret = m_s . call ( _receiveAddress , _codeAddressOverride ? _codeAddressOverride : _receiveAddress , _myAddressOverride ? _myAddressOverride : myAddress , _value , gasPrice , _data , _gas , _out , origin , & sub , & ( m_ms . internal . back ( ) ) , Executive : : simpleTrace ( ) , 1 ) ;
if ( ! m_ms . internal . back ( ) . from )
m_ms . internal . pop_back ( ) ;
// get correct balances, (also for sucicides in the call function)
for ( auto const & f : addresses )
{
if ( m_s . addressInUse ( f . first ) )
get < 0 > ( addresses [ f . first ] ) = m_s . balance ( f . first ) ;
}
if ( ! ret )
return false ;
// TODO: @CJentzsch refund SSTORE stuff.
// TODO: @CJentzsch test logs.
// do suicides
for ( auto const & f : sub . suicides )
addresses . erase ( f ) ;
// get storage
if ( ( get < 0 > ( addresses [ myAddress ] ) > = _value ) & & ( sub . suicides . find ( _receiveAddress ) = = sub . suicides . end ( ) ) )
{
for ( auto const & j : m_s . storage ( _receiveAddress ) )
{
u256 adr ( j . first ) ;
if ( ( j . second ! = 0 ) )
get < 2 > ( addresses [ _receiveAddress ] ) [ adr ] = j . second ;
}
}
}
else
addresses . erase ( _receiveAddress ) ; // for the sake of comparison
return true ;
return true ;
// string codeOf_CodeAddress = _codeAddressOverride ? toHex(get<3>(addresses[_codeAddressOverride])) : toHex(get<3>(addresses[_receiveAddress]) );
// string sizeOfCode = toHex(toCompactBigEndian((codeOf_CodeAddress.size()+1)/2));
// string codeOf_SenderAddress = toHex(get<3>(addresses[myAddress]) );
// string sizeOfSenderCode = toHex(toCompactBigEndian((codeOf_SenderAddress.size()+1)/2));
// if (codeOf_SenderAddress.size())
// {
// // create init code that returns given contract code
// string initStringHex = "{ (CODECOPY 0 (- (CODESIZE) 0x" + sizeOfSenderCode + " ) 0x" + sizeOfSenderCode + ") (RETURN 0 0x" + sizeOfSenderCode +")}";
// bytes initBytes = compileLLL(initStringHex, true, NULL);
// initBytes += fromHex(codeOf_SenderAddress);
// bytesConstRef init(&initBytes);
// if (!m_s.addresses().count(myAddress))
// {
// m_ms.internal.resize(m_ms.internal.size() + 1);
// auto na = m_s.createNewAddress(myAddress, myAddress, balance(myAddress), gasPrice, &contractgas, init, origin, &sub, &m_ms ? &(m_ms.internal.back()) : nullptr, {}, 1);
// if (!m_ms.internal.back().from)
// m_ms.internal.pop_back();
// if (na != myAddress)
// {
// cnote << "not able to call to : " << myAddress << "\n";
// cnote << "in FakeExtVM you can only make a call to " << na << "\n";
// BOOST_THROW_EXCEPTION(FakeExtVMFailure() << errinfo_comment("Address not callable in FakeExtVM\n") << errinfo_wrongAddress(toString(myAddress)));
// return false;
// }
// }
// }
// if (codeOf_CodeAddress.size())
// {
// // create init code that returns given contract code
// string initStringHex = "{ (CODECOPY 0 (- (CODESIZE) 0x" + sizeOfCode + " ) 0x" + sizeOfCode + ") (RETURN 0 0x" + sizeOfCode +")}";
// bytes initBytes = compileLLL(initStringHex, true, NULL);
// initBytes += fromHex(codeOf_CodeAddress);
// bytesConstRef init(&initBytes);
// if (!m_s.addresses().count(_codeAddressOverride ? _codeAddressOverride : _receiveAddress))
// {
// m_s.noteSending(myAddress);
// m_ms.internal.resize(m_ms.internal.size() + 1);
// auto na = m_s.createNewAddress(_codeAddressOverride ? _codeAddressOverride : _receiveAddress, myAddress, balance(_codeAddressOverride ? _codeAddressOverride : _receiveAddress), gasPrice, &contractgas, init, origin, &sub, &m_ms ? &(m_ms.internal.back()) : nullptr, OnOpFunc(), 1);
// if (!m_ms.internal.back().from)
// m_ms.internal.pop_back();
// if (na != (_codeAddressOverride ? _codeAddressOverride : _receiveAddress))
// {
// cnote << "not able to call to : " << (_codeAddressOverride ? _codeAddressOverride : _receiveAddress) << "\n";
// cnote << "in FakeExtVM you can only make a call to " << na << "\n";
// BOOST_THROW_EXCEPTION(FakeExtVMFailure() << errinfo_comment("Address not callable in FakeExtVM\n") << errinfo_wrongAddress(toString(_codeAddressOverride ? _codeAddressOverride : _receiveAddress)));
// return false;
// }
// }
// m_ms.internal.resize(m_ms.internal.size() + 1);
// auto ret = m_s.call(_receiveAddress,_codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _value, gasPrice, _data, _gas, _out, origin, &sub, &(m_ms.internal.back()), Executive::simpleTrace(), 1);
// if (!m_ms.internal.back().from)
// m_ms.internal.pop_back();
// // get correct balances, (also for sucicides in the call function)
// for (auto const& f: addresses)
// {
// if (m_s.addressInUse(f.first))
// get<0>(addresses[f.first]) = m_s.balance(f.first);
// }
// if (!ret)
// return false;
// // TODO: @CJentzsch refund SSTORE stuff.
// // TODO: @CJentzsch test logs.
// // do suicides
// for (auto const& f: sub.suicides)
// addresses.erase(f);
// // get storage
// if ((get<0>(addresses[myAddress]) >= _value) && (sub.suicides.find(_receiveAddress) == sub.suicides.end()))
// {
// for (auto const& j: m_s.storage(_receiveAddress))
// {
// u256 adr(j.first);
// if ((j.second != 0) )
// get<2>(addresses[_receiveAddress])[adr] = j.second;
// }
// }
// }
// else
// addresses.erase(_receiveAddress); // for the sake of comparison
// return true;
}
}
void FakeExtVM : : setTransaction ( Address _caller , u256 _value , u256 _gasPrice , bytes const & _data )
void FakeExtVM : : setTransaction ( Address _caller , u256 _value , u256 _gasPrice , bytes const & _data )
@ -435,8 +439,8 @@ eth::OnOpFunc FakeExtVM::simpleTrace()
o < < " MEMORY " < < std : : endl < < memDump ( vm . memory ( ) ) ;
o < < " MEMORY " < < std : : endl < < memDump ( vm . memory ( ) ) ;
o < < " STORAGE " < < std : : endl ;
o < < " STORAGE " < < std : : endl ;
for ( auto const & i : ext . state ( ) . storage ( ext . myAddress ) )
// for (auto const& i: ext.state().storage(ext.myAddress))
o < < std : : showbase < < std : : hex < < i . first < < " : " < < i . second < < std : : endl ;
// o << std::showbase << std::hex << i.first << ": " << i.second << std::endl;
for ( auto const & i : std : : get < 2 > ( ext . addresses . find ( ext . myAddress ) - > second ) )
for ( auto const & i : std : : get < 2 > ( ext . addresses . find ( ext . myAddress ) - > second ) )
o < < std : : showbase < < std : : hex < < i . first < < " : " < < i . second < < std : : endl ;
o < < std : : showbase < < std : : hex < < i . first < < " : " < < i . second < < std : : endl ;
@ -454,70 +458,70 @@ eth::OnOpFunc FakeExtVM::simpleTrace()
} ;
} ;
}
}
// THIS IS BROKEN AND NEEDS TO BE REMOVED.
//// THIS IS BROKEN AND NEEDS TO BE REMOVED.
h160 FakeState : : createNewAddress ( Address _newAddress , Address _sender , u256 _endowment , u256 _gasPrice , u256 * _gas , bytesConstRef _code , Address _origin , SubState * o_sub , Manifest * o_ms , OnOpFunc const & _onOp , unsigned _level )
//h160 FakeState::createNewAddress(Address _newAddress, Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, Address _origin, SubState* o_sub, Manifest* o_ms, OnOpFunc const& _onOp, unsigned _level)
{
//{
( void ) o_sub ;
// (void)o_sub;
if ( ! _origin )
// if (!_origin)
_origin = _sender ;
// _origin = _sender;
if ( o_ms )
// if (o_ms)
{
// {
o_ms - > from = _sender ;
// o_ms->from = _sender;
o_ms - > to = Address ( ) ;
// o_ms->to = Address();
o_ms - > value = _endowment ;
// o_ms->value = _endowment;
o_ms - > input = _code . toBytes ( ) ;
// o_ms->input = _code.toBytes();
}
// }
// Set up new account...
// // Set up new account...
m_cache [ _newAddress ] = AddressState ( 0 , balance ( _newAddress ) + _endowment , h256 ( ) , h256 ( ) ) ;
// m_cache[_newAddress] = AddressState(0, balance(_newAddress) + _endowment, h256(), h256());
// Execute init code.
// // Execute init code.
VM vm ( * _gas ) ;
// VM vm(*_gas);
ExtVM evm ( * this , _newAddress , _sender , _origin , _endowment , _gasPrice , bytesConstRef ( ) , _code , o_ms , _level ) ;
// ExtVM evm(*this, _newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _code, o_ms, _level);
bool revert = false ;
// bool revert = false;
bytesConstRef out ;
// bytesConstRef out;
try
// try
{
// {
out = vm . go ( evm , _onOp ) ;
// out = vm.go(evm, _onOp);
if ( o_ms )
// if (o_ms)
o_ms - > output = out . toBytes ( ) ;
// o_ms->output = out.toBytes();
// TODO: deal with evm.sub
// // TODO: deal with evm.sub
}
// }
catch ( OutOfGas const & /*_e*/ )
// catch (OutOfGas const& /*_e*/)
{
// {
clog ( StateChat ) < < " Out of Gas! Reverting. " ;
// clog(StateChat) << "Out of Gas! Reverting.";
revert = true ;
// revert = true;
}
// }
catch ( VMException const & _e )
// catch (VMException const& _e)
{
// {
clog ( StateChat ) < < " VM Exception: " < < diagnostic_information ( _e ) ;
// clog(StateChat) << "VM Exception: " << diagnostic_information(_e);
}
// }
catch ( Exception const & _e )
// catch (Exception const& _e)
{
// {
clog ( StateChat ) < < " Exception in VM: " < < diagnostic_information ( _e ) ;
// clog(StateChat) << "Exception in VM: " << diagnostic_information(_e);
}
// }
catch ( std : : exception const & _e )
// catch (std::exception const& _e)
{
// {
clog ( StateChat ) < < " std::exception in VM: " < < _e . what ( ) ;
// clog(StateChat) << "std::exception in VM: " << _e.what();
}
// }
// TODO: CHECK: IS THIS CORRECT?! (esp. given account created prior to revertion init.)
// // TODO: CHECK: IS THIS CORRECT?! (esp. given account created prior to revertion init.)
// Write state out only in the case of a non-out-of-gas transaction.
// // Write state out only in the case of a non-out-of-gas transaction.
if ( revert )
// if (revert)
evm . revert ( ) ;
// evm.revert();
// Set code.
// // Set code.
if ( addressInUse ( _newAddress ) )
// if (addressInUse(_newAddress))
m_cache [ _newAddress ] . setCode ( out ) ;
// m_cache[_newAddress].setCode(out);
* _gas = vm . gas ( ) ;
// *_gas = vm.gas();
return _newAddress ;
// return _newAddress;
}
//}
namespace dev { namespace test {
namespace dev { namespace test {
@ -654,34 +658,6 @@ void doTests(json_spirit::mValue& v, bool _fillin)
}
}
}
}
/*string makeTestCase()
{
json_spirit : : mObject o ;
VM vm ;
BlockInfo pb ;
pb . hash = sha3 ( " previousHash " ) ;
pb . nonce = sha3 ( " previousNonce " ) ;
BlockInfo cb = pb ;
cb . difficulty = 256 ;
cb . timestamp = 1 ;
cb . coinbaseAddress = toAddress ( sha3 ( " coinbase " ) ) ;
FakeExtVM fev ( pb , cb , 0 ) ;
bytes init ;
fev . setContract ( toAddress ( sha3 ( " contract " ) ) , ether , 0 , compileLisp ( " (suicide (txsender)) " , false , init ) , map < u256 , u256 > ( ) ) ;
o [ " env " ] = fev . exportEnv ( ) ;
o [ " pre " ] = fev . exportState ( ) ;
fev . setTransaction ( toAddress ( sha3 ( " sender " ) ) , ether , finney , bytes ( ) ) ;
mArray execs ;
execs . push_back ( fev . exportExec ( ) ) ;
o [ " exec " ] = execs ;
vm . go ( fev ) ;
o [ " post " ] = fev . exportState ( ) ;
o [ " txs " ] = fev . exportTxs ( ) ;
return json_spirit : : write_string ( json_spirit : : mValue ( o ) , true ) ;
} */
void executeTests ( const string & _name )
void executeTests ( const string & _name )
{
{
const char * ptestPath = getenv ( " ETHEREUM_TEST_PATH " ) ;
const char * ptestPath = getenv ( " ETHEREUM_TEST_PATH " ) ;