@ -40,10 +40,8 @@ namespace dev
namespace mix
{
// TODO: merge as much as possible with the Client.cpp into a mutually inherited base class.
const Secret c_defaultUserAccountSecret = Secret ( " cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074 " ) ;
const u256 c_mixGenesisDifficulty = c_minimumDifficulty ; //TODO: make it lower for Mix somehow
Secret const c_defaultUserAccountSecret = Secret ( " cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074 " ) ;
u256 const c_mixGenesisDifficulty = c_minimumDifficulty ; //TODO: make it lower for Mix somehow
bytes MixBlockChain : : createGenesisBlock ( h256 _stateRoot )
{
@ -100,9 +98,18 @@ void MixClient::resetState(std::map<Secret, u256> _accounts)
m_executions . clear ( ) ;
}
void MixClient : : executeTransaction ( Transaction const & _t , State & _state , bool _call )
Transaction MixClient : : replaceGas ( Transaction const & _t , Secret const & _secret , u256 const & _gas )
{
if ( _t . isCreation ( ) )
return Transaction ( _t . value ( ) , _t . gasPrice ( ) , _gas , _t . data ( ) , _t . nonce ( ) , _secret ) ;
else
return Transaction ( _t . value ( ) , _t . gasPrice ( ) , _gas , _t . receiveAddress ( ) , _t . data ( ) , _t . nonce ( ) , _secret ) ;
}
void MixClient : : executeTransaction ( Transaction const & _t , State & _state , bool _call , bool _gasAuto , Secret const & _secret )
{
bytes rlp = _t . rlp ( ) ;
Transaction t = _gasAuto ? replaceGas ( _t , _secret , m_state . gasLimitRemaining ( ) ) : _t ;
bytes rlp = t . rlp ( ) ;
// do debugging run first
LastHashes lastHashes ( 256 ) ;
@ -167,6 +174,31 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c
execution . go ( onOp ) ;
execution . finalize ( ) ;
dev : : eth : : ExecutionResult er = execution . executionResult ( ) ;
switch ( er . excepted )
{
case TransactionException : : None :
break ;
case TransactionException : : NotEnoughCash :
BOOST_THROW_EXCEPTION ( Exception ( ) < < errinfo_comment ( " Insufficient balance for contract deployment " ) ) ;
case TransactionException : : OutOfGasBase :
case TransactionException : : OutOfGas :
BOOST_THROW_EXCEPTION ( OutOfGas ( ) < < errinfo_comment ( " Not enough gas " ) ) ;
case TransactionException : : BlockGasLimitReached :
BOOST_THROW_EXCEPTION ( OutOfGas ( ) < < errinfo_comment ( " Block gas limit reached " ) ) ;
case TransactionException : : OutOfStack :
BOOST_THROW_EXCEPTION ( Exception ( ) < < errinfo_comment ( " Out of stack " ) ) ;
case TransactionException : : StackUnderflow :
BOOST_THROW_EXCEPTION ( Exception ( ) < < errinfo_comment ( " Stack underflow " ) ) ;
//these should not happen in mix
case TransactionException : : Unknown :
case TransactionException : : BadInstruction :
case TransactionException : : BadJumpDestination :
case TransactionException : : InvalidSignature :
case TransactionException : : InvalidNonce :
BOOST_THROW_EXCEPTION ( Exception ( ) < < errinfo_comment ( " Internal execution error " ) ) ;
} ;
ExecutionResult d ;
d . result = execution . executionResult ( ) ;
@ -176,6 +208,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c
d . address = _t . receiveAddress ( ) ;
d . sender = _t . sender ( ) ;
d . value = _t . value ( ) ;
d . gasUsed = er . gasUsed + er . gasRefunded ;
if ( _t . isCreation ( ) )
d . contractAddress = right160 ( sha3 ( rlpList ( _t . sender ( ) , _t . nonce ( ) ) ) ) ;
if ( ! _call )
@ -185,9 +218,11 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c
// execute on a state
if ( ! _call )
{
dev : : eth : : ExecutionResult er = _state . execute ( lastHashes , _t ) ;
if ( _t . isCreation ( ) & & _state . code ( d . contractAddress ) . empty ( ) )
t = _gasAuto ? replaceGas ( _t , _secret , d . gasUsed ) : _t ;
er = _state . execute ( lastHashes , t ) ;
if ( t . isCreation ( ) & & _state . code ( d . contractAddress ) . empty ( ) )
BOOST_THROW_EXCEPTION ( OutOfGas ( ) < < errinfo_comment ( " Not enough gas for contract deployment " ) ) ;
d . gasUsed = er . gasUsed + er . gasRefunded + er . gasForDeposit ;
// collect watches
h256Set changed ;
Guard l ( x_filtersWatches ) ;
@ -242,25 +277,25 @@ State MixClient::asOf(h256 const& _block) const
return State ( m_stateDB , bc ( ) , _block ) ;
}
void MixClient : : submitTransaction ( Secret _secret , u256 _value , Address _dest , bytes const & _data , u256 _gas , u256 _gasPrice )
void MixClient : : submitTransaction ( Secret _secret , u256 _value , Address _dest , bytes const & _data , u256 _gas , u256 _gasPrice , bool _gasAuto )
{
WriteGuard l ( x_state ) ;
u256 n = m_state . transactionsFrom ( toAddress ( _secret ) ) ;
Transaction t ( _value , _gasPrice , _gas , _dest , _data , n , _secret ) ;
executeTransaction ( t , m_state , false ) ;
executeTransaction ( t , m_state , false , _gasAuto , _secret ) ;
}
Address MixClient : : submitTransaction ( Secret _secret , u256 _endowment , bytes const & _init , u256 _gas , u256 _gasPrice )
Address MixClient : : submitTransaction ( Secret _secret , u256 _endowment , bytes const & _init , u256 _gas , u256 _gasPrice , bool _gasAuto )
{
WriteGuard l ( x_state ) ;
u256 n = m_state . transactionsFrom ( toAddress ( _secret ) ) ;
eth : : Transaction t ( _endowment , _gasPrice , _gas , _init , n , _secret ) ;
executeTransaction ( t , m_state , false ) ;
executeTransaction ( t , m_state , false , _gasAuto , _secret ) ;
Address address = right160 ( sha3 ( rlpList ( t . sender ( ) , t . nonce ( ) ) ) ) ;
return address ;
}
dev : : eth : : ExecutionResult MixClient : : call ( Secret _secret , u256 _value , Address _dest , bytes const & _data , u256 _gas , u256 _gasPrice , BlockNumber _blockNumber )
dev : : eth : : ExecutionResult MixClient : : call ( Secret _secret , u256 _value , Address _dest , bytes const & _data , u256 _gas , u256 _gasPrice , BlockNumber _blockNumber , bool _gasAuto )
{
( void ) _blockNumber ;
State temp = asOf ( eth : : PendingBlock ) ;
@ -268,10 +303,25 @@ dev::eth::ExecutionResult MixClient::call(Secret _secret, u256 _value, Address _
Transaction t ( _value , _gasPrice , _gas , _dest , _data , n , _secret ) ;
bytes rlp = t . rlp ( ) ;
WriteGuard lw ( x_state ) ; //TODO: lock is required only for last execution state
executeTransaction ( t , temp , true ) ;
executeTransaction ( t , temp , true , _gasAuto , _secret ) ;
return lastExecution ( ) . result ;
}
void MixClient : : submitTransaction ( Secret _secret , u256 _value , Address _dest , bytes const & _data , u256 _gas , u256 _gasPrice )
{
submitTransaction ( _secret , _value , _dest , _data , _gas , _gasPrice , false ) ;
}
Address MixClient : : submitTransaction ( Secret _secret , u256 _endowment , bytes const & _init , u256 _gas , u256 _gasPrice )
{
return submitTransaction ( _secret , _endowment , _init , _gas , _gasPrice , false ) ;
}
dev : : eth : : ExecutionResult MixClient : : call ( Secret _secret , u256 _value , Address _dest , bytes const & _data , u256 _gas , u256 _gasPrice , BlockNumber _blockNumber )
{
return call ( _secret , _value , _dest , _data , _gas , _gasPrice , _blockNumber , false ) ;
}
dev : : eth : : ExecutionResult MixClient : : create ( Secret _secret , u256 _value , bytes const & _data , u256 _gas , u256 _gasPrice , BlockNumber _blockNumber )
{
( void ) _blockNumber ;
@ -285,7 +335,7 @@ dev::eth::ExecutionResult MixClient::create(Secret _secret, u256 _value, bytes c
Transaction t ( _value , _gasPrice , _gas , _data , n , _secret ) ;
bytes rlp = t . rlp ( ) ;
WriteGuard lw ( x_state ) ; //TODO: lock is required only for last execution state
executeTransaction ( t , temp , true ) ;
executeTransaction ( t , temp , true , false , _secret ) ;
return lastExecution ( ) . result ;
}